├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── COPYING ├── README ├── SUMS ├── i40e.7 ├── i40e.spec ├── pci.updates ├── scripts ├── check_aux_bus ├── dump_tables ├── set_irq_affinity └── virt_perf_default ├── security.md └── src ├── Makefile ├── Module.supported ├── auxiliary.c ├── auxiliary_compat.h ├── common.mk ├── i40e.h ├── i40e_adminq.c ├── i40e_adminq.h ├── i40e_adminq_cmd.h ├── i40e_alloc.h ├── i40e_client.c ├── i40e_client.h ├── i40e_common.c ├── i40e_dcb.c ├── i40e_dcb.h ├── i40e_dcb_nl.c ├── i40e_ddp.c ├── i40e_debugfs.c ├── i40e_devids.h ├── i40e_diag.c ├── i40e_diag.h ├── i40e_ethtool.c ├── i40e_ethtool_stats.h ├── i40e_filters.c ├── i40e_filters.h ├── i40e_helper.h ├── i40e_hmc.c ├── i40e_hmc.h ├── i40e_lan_hmc.c ├── i40e_lan_hmc.h ├── i40e_main.c ├── i40e_nvm.c ├── i40e_osdep.h ├── i40e_prototype.h ├── i40e_ptp.c ├── i40e_register.h ├── i40e_status.h ├── i40e_trace.h ├── i40e_txrx.c ├── i40e_txrx.h ├── i40e_txrx_common.h ├── i40e_type.h ├── i40e_virtchnl_pf.c ├── i40e_virtchnl_pf.h ├── i40e_xsk.c ├── i40e_xsk.h ├── kcompat-generator.sh ├── kcompat-lib.sh ├── kcompat.c ├── kcompat.h ├── kcompat_cleanup.h ├── kcompat_defs.h ├── kcompat_gcc.h ├── kcompat_impl.h ├── kcompat_overflow.h ├── kcompat_packing.c ├── kcompat_packing.h ├── kcompat_rhel_defs.h ├── kcompat_sigil.h ├── kcompat_sles_defs.h ├── kcompat_std_defs.h ├── kcompat_ubuntu_defs.h ├── kcompat_vfd.c ├── kcompat_vfd.h ├── kcompat_xarray.c ├── kcompat_xarray.h ├── linux └── auxiliary_bus.h └── virtchnl.h /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, caste, color, religion, or sexual 10 | identity and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the overall 26 | community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or advances of 31 | any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email address, 35 | without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | CommunityCodeOfConduct AT intel DOT com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series of 86 | actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or permanent 93 | ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within the 113 | community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.1, available at 119 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 120 | 121 | Community Impact Guidelines were inspired by 122 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 123 | 124 | For answers to common questions about this code of conduct, see the FAQ at 125 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 126 | [https://www.contributor-covenant.org/translations][translations]. 127 | 128 | [homepage]: https://www.contributor-covenant.org 129 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 130 | [Mozilla CoC]: https://github.com/mozilla/diversity 131 | [FAQ]: https://www.contributor-covenant.org/faq 132 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ### License 4 | 5 | The ethernet-linux-i40e is licensed under the terms in [COPYING](./COPYING). 6 | By contributing to the project, you agree to the license and copyright 7 | terms therein and release your contribution under these terms. 8 | 9 | ### Sign your work 10 | 11 | Please use the sign-off line at the end of the patch. Your signature certifies 12 | that you wrote the patch or otherwise have the right to pass it on as an 13 | open-source patch. The rules are pretty simple: if you can certify the below 14 | (from [developercertificate.org](http://developercertificate.org/)): 15 | 16 | ``` 17 | Developer Certificate of Origin 18 | Version 1.1 19 | 20 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 21 | 660 York Street, Suite 102, 22 | San Francisco, CA 94110 USA 23 | 24 | Everyone is permitted to copy and distribute verbatim copies of this 25 | license document, but changing it is not allowed. 26 | 27 | Developer's Certificate of Origin 1.1 28 | 29 | By making a contribution to this project, I certify that: 30 | 31 | (a) The contribution was created in whole or in part by me and I 32 | have the right to submit it under the open source license 33 | indicated in the file; or 34 | 35 | (b) The contribution is based upon previous work that, to the best 36 | of my knowledge, is covered under an appropriate open source 37 | license and I have the right under that license to submit that 38 | work with modifications, whether created in whole or in part 39 | by me, under the same open source license (unless I am 40 | permitted to submit under a different license), as indicated 41 | in the file; or 42 | 43 | (c) The contribution was provided directly to me by some other 44 | person who certified (a), (b) or (c) and I have not modified 45 | it. 46 | 47 | (d) I understand and agree that this project and the contribution 48 | are public and that a record of the contribution (including all 49 | personal information I submit with it, including my sign-off) is 50 | maintained indefinitely and may be redistributed consistent with 51 | this project or the open source license(s) involved. 52 | ``` 53 | 54 | Then you just add a line to every git commit message: 55 | 56 | Signed-off-by: Joe Smith 57 | 58 | Use your real name (sorry, no pseudonyms or anonymous contributions.) 59 | 60 | If you set your `user.name` and `user.email` git configs, you can sign your 61 | commit automatically with `git commit -s`. 62 | -------------------------------------------------------------------------------- /SUMS: -------------------------------------------------------------------------------- 1 | 43452 4 i40e-2.28.5/src/linux/auxiliary_bus.h 2 | 02702 532 i40e-2.28.5/src/i40e_main.c 3 | 48878 229 i40e-2.28.5/src/i40e_ethtool.c 4 | 13160 51 i40e-2.28.5/src/i40e.h 5 | 01090 247 i40e-2.28.5/src/i40e_virtchnl_pf.c 6 | 43345 7 i40e-2.28.5/src/i40e_client.h 7 | 51404 79 i40e-2.28.5/src/i40e_debugfs.c 8 | 59521 8 i40e-2.28.5/src/i40e_virtchnl_pf.h 9 | 30067 22 i40e-2.28.5/src/i40e_client.c 10 | 58606 2 i40e-2.28.5/src/i40e_filters.c 11 | 45599 1 i40e-2.28.5/src/i40e_filters.h 12 | 22342 6 i40e-2.28.5/src/i40e_txrx_common.h 13 | 12535 3 i40e-2.28.5/src/i40e_osdep.h 14 | 47004 134 i40e-2.28.5/src/i40e_txrx.c 15 | 55806 22 i40e-2.28.5/src/i40e_txrx.h 16 | 21721 2 i40e-2.28.5/src/i40e_helper.h 17 | 23345 10 i40e-2.28.5/src/i40e_ethtool_stats.h 18 | 46542 3 i40e-2.28.5/src/i40e_xsk.h 19 | 11996 11 i40e-2.28.5/src/i40e_trace.h 20 | 45696 38 i40e-2.28.5/src/i40e_xsk.c 21 | 42204 30 i40e-2.28.5/src/i40e_dcb_nl.c 22 | 36808 215 i40e-2.28.5/src/i40e_common.c 23 | 65049 54 i40e-2.28.5/src/i40e_ptp.c 24 | 15574 34 i40e-2.28.5/src/i40e_adminq.c 25 | 53945 4 i40e-2.28.5/src/i40e_adminq.h 26 | 63427 91 i40e-2.28.5/src/i40e_adminq_cmd.h 27 | 33980 369 i40e-2.28.5/src/i40e_register.h 28 | 30053 3 i40e-2.28.5/src/i40e_status.h 29 | 36769 50 i40e-2.28.5/src/i40e_type.h 30 | 09009 1 i40e-2.28.5/src/i40e_diag.h 31 | 40972 10 i40e-2.28.5/src/i40e_hmc.c 32 | 44006 4 i40e-2.28.5/src/i40e_diag.c 33 | 05890 34 i40e-2.28.5/src/i40e_lan_hmc.c 34 | 54125 5 i40e-2.28.5/src/i40e_lan_hmc.h 35 | 48564 2 i40e-2.28.5/src/i40e_alloc.h 36 | 16731 8 i40e-2.28.5/src/i40e_hmc.h 37 | 33388 26 i40e-2.28.5/src/i40e_prototype.h 38 | 14745 52 i40e-2.28.5/src/i40e_nvm.c 39 | 56487 14 i40e-2.28.5/src/i40e_ddp.c 40 | 21398 2 i40e-2.28.5/src/i40e_devids.h 41 | 12913 58 i40e-2.28.5/src/i40e_dcb.c 42 | 31844 9 i40e-2.28.5/src/i40e_dcb.h 43 | 19383 5 i40e-2.28.5/src/kcompat_gcc.h 44 | 64355 210 i40e-2.28.5/src/kcompat.h 45 | 41360 102 i40e-2.28.5/src/kcompat_impl.h 46 | 46407 12 i40e-2.28.5/src/kcompat-lib.sh 47 | 35263 31 i40e-2.28.5/src/kcompat-generator.sh 48 | 51423 1 i40e-2.28.5/src/kcompat_defs.h 49 | 41918 2 i40e-2.28.5/src/kcompat_sigil.h 50 | 18741 7 i40e-2.28.5/src/kcompat_sles_defs.h 51 | 36528 5 i40e-2.28.5/src/kcompat_rhel_defs.h 52 | 18755 2 i40e-2.28.5/src/kcompat_ubuntu_defs.h 53 | 14309 8 i40e-2.28.5/src/kcompat_std_defs.h 54 | 29743 72 i40e-2.28.5/src/kcompat.c 55 | 52920 12 i40e-2.28.5/src/kcompat_cleanup.h 56 | 20093 17 i40e-2.28.5/src/kcompat_overflow.h 57 | 45552 59 i40e-2.28.5/src/kcompat_xarray.h 58 | 02025 61 i40e-2.28.5/src/kcompat_xarray.c 59 | 36413 76 i40e-2.28.5/src/kcompat_vfd.c 60 | 20920 17 i40e-2.28.5/src/kcompat_packing.h 61 | 12523 85 i40e-2.28.5/src/virtchnl.h 62 | 52135 17 i40e-2.28.5/src/kcompat_packing.c 63 | 22580 5 i40e-2.28.5/src/auxiliary_compat.h 64 | 18177 8 i40e-2.28.5/src/kcompat_vfd.h 65 | 42782 8 i40e-2.28.5/src/auxiliary.c 66 | 59768 7 i40e-2.28.5/src/Makefile 67 | 53080 18 i40e-2.28.5/src/common.mk 68 | 18182 1 i40e-2.28.5/src/Module.supported 69 | 58887 9 i40e-2.28.5/scripts/set_irq_affinity 70 | 42001 5 i40e-2.28.5/scripts/virt_perf_default 71 | 21632 8 i40e-2.28.5/scripts/check_aux_bus 72 | 60555 2 i40e-2.28.5/scripts/dump_tables 73 | 06161 9 i40e-2.28.5/pci.updates 74 | 12529 18 i40e-2.28.5/COPYING 75 | 27626 1 i40e-2.28.5/security.md 76 | 10947 96 i40e-2.28.5/README 77 | 33556 112 i40e-2.28.5/i40e.7 78 | 21159 13 i40e-2.28.5/i40e.spec 79 | -------------------------------------------------------------------------------- /pci.updates: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-only 2 | # Copyright (C) 2013-2025 Intel Corporation 3 | 4 | # updates for the system pci.ids file 5 | # 6 | # IMPORTANT! Entries in this list must be sorted as they 7 | # would appear in the system pci.ids file. Entries 8 | # are sorted by ven, dev, subven, subdev 9 | # (numerical order). Also, no OEM names in strings. 10 | # The oem vendor id will sub into the name when 11 | # the string is consumed by the tools using it. 12 | # 13 | 8086 Intel Corporation 14 | 0dd2 Ethernet Network Adapter I710 15 | 1137 0000 I710T4LG 4x1 GbE RJ45 PCIe NIC 16 | 1137 02e3 I710T4LG 4x1 GbE RJ45 PCIe NIC 17 | 8086 0000 Ethernet Network Adapter I710-T4L 18 | 8086 000d Ethernet Network Adapter I710-T4L 19 | 8086 0010 Ethernet Network Adapter I710-T4L for OCP 3.0 20 | 8086 401a Ethernet Network Adapter I710-T4L 21 | 8086 401b Ethernet Network Adapter I710-T4L for OCP 3.0 22 | 0dda Ethernet Connection X722 for 10GbE SFP+ 23 | 1bd4 0076 Ethernet Connection F102IX722 for 10GbE SFP 24 | 1572 Ethernet Controller X710 for 10GbE SFP+ 25 | 1028 0000 Ethernet 10G X710 rNDC 26 | 1028 1f99 Ethernet 10G 4P X710/I350 rNDC 27 | 1028 1f9c Ethernet 10G 4P X710 SFP+ rNDC 28 | 103c 0000 Ethernet 10Gb 562SFP+ Adapter 29 | 103c 22fc Ethernet 10Gb 2-port 562FLR-SFP+ Adapter 30 | 103c 22fd Ethernet 10Gb 2-port 562SFP+ Adapter 31 | 1137 0000 Ethernet Converged NIC X710-DA 32 | 1137 013b Ethernet Converged NIC X710-DA4 33 | 1137 020a Ethernet Converged NIC X710-DA2 34 | 17aa 0000 ThinkServer X710 AnyFabric for 10GbE SFP+ 35 | 17aa 4001 ThinkServer X710-4 AnyFabric for 10GbE SFP+ 36 | 17aa 4002 ThinkServer X710-2 AnyFabric for 10GbE SFP+ 37 | 8086 0000 Ethernet Converged Network Adapter X710 38 | 8086 0001 Ethernet Converged Network Adapter X710-4 39 | 8086 0002 Ethernet Converged Network Adapter X710-4 40 | 8086 0004 Ethernet Converged Network Adapter X710-4 41 | 8086 0005 Ethernet Converged Network Adapter X710 42 | 8086 0006 Ethernet Converged Network Adapter X710 43 | 8086 0007 Ethernet Converged Network Adapter X710-2 44 | 8086 0008 Ethernet Converged Network Adapter X710-2 45 | 8086 0009 Ethernet Controller X710 for 10GbE SFP+ 46 | 8086 000a Ethernet Controller X710 for 10GbE SFP+ 47 | 8086 000b Ethernet Server Adapter X710-DA2 for OCP 48 | 8086 000d Ethernet Controller X710 for 10GbE SFP+ 49 | 8086 000e Ethernet Server Adapter OCP X710-2 50 | 8086 000f Ethernet Server Adapter OCP X710-2 51 | 8086 4005 Ethernet Controller X710 for 10GbE SFP+ 52 | 8086 4006 Ethernet Controller X710 for 10GbE SFP+ 53 | 8086 4007 Ethernet Controller X710 for 10GbE SFP+ 54 | 1574 Ethernet Controller XL710 Emulation 55 | 1580 Ethernet Controller XL710 for 40GbE backplane 56 | 1581 Ethernet Controller X710 for 10GbE backplane 57 | 1028 0000 Ethernet 10G X710-k bNDC 58 | 1028 1f98 Ethernet 10G 4P X710-k bNDC 59 | 1028 1f9e Ethernet 10G 2P X710-k bNDC 60 | 1590 0000 Ethernet 10Gb 2-port 563i Adapter 61 | 1590 00f8 Ethernet 10Gb 2-port 563i Adapter 62 | 8086 0000 Ethernet Converged Network Adapter XL710-Q2 63 | 1583 Ethernet Controller XL710 for 40GbE QSFP+ 64 | 1028 0000 Ethernet 40G 2P XL710 QSFP+ rNDC 65 | 1028 1f9f Ethernet 40G 2P XL710 QSFP+ rNDC 66 | 108e 0000 10Gb/40Gb Ethernet Adapter 67 | 108e 7b1d 10Gb/40Gb Ethernet Adapter 68 | 1137 0000 Ethernet Converged NIC XL710-QDA2 69 | 1137 013c Ethernet Converged NIC XL710-QDA2 70 | 8086 0000 Ethernet Converged Network Adapter XL710-Q2 71 | 8086 0001 Ethernet Converged Network Adapter XL710-Q2 72 | 8086 0002 Ethernet Converged Network Adapter XL710-Q2 73 | 8086 0003 Ethernet I/O Module XL710-Q2 74 | 8086 0004 Ethernet Server Adapter XL710-Q2OCP 75 | 8086 0006 Ethernet Converged Network Adapter XL710-Q2 76 | 1584 Ethernet Controller XL710 for 40GbE QSFP+ 77 | 8086 0000 Ethernet Converged Network Adapter XL710-Q1 78 | 8086 0001 Ethernet Converged Network Adapter XL710-Q1 79 | 8086 0002 Ethernet Converged Network Adapter XL710-Q1 80 | 8086 0003 Ethernet I/O Module XL710-Q1 81 | 8086 0004 Ethernet Server Adapter XL710-Q1OCP 82 | 1585 Ethernet Controller X710 for 10GbE QSFP+ 83 | 1586 Ethernet Controller X710 for 10GBASE-T 84 | 108e 0000 Ethernet Controller X710 for 10GBASE-T 85 | 108e 4857 Ethernet Controller X710 for 10GBASE-T 86 | 1587 Ethernet Controller XL710 for 20GbE backplane 87 | 103c 0000 Eth 10/20Gb 2p 660FLB Adptr 88 | 103c 22fe Eth 10/20Gb 2p 660FLB Adptr 89 | 1588 Ethernet Controller XL710 for 20GbE backplane 90 | 103c 0000 Eth 10/20Gb 2p 660M Adptr 91 | 103c 22ff Eth 10/20Gb 2p 660M Adptr 92 | 1589 Ethernet Controller X710/X557-AT 10GBASE-T 93 | 108e 0000 Quad Port 10GBase-T Adapter 94 | 108e 7b1c Quad Port 10GBase-T Adapter 95 | 8086 0000 Ethernet Converged Network Adapter X710-T 96 | 8086 0001 Ethernet Converged Network Adapter X710-T4 97 | 8086 0002 Ethernet Converged Network Adapter X710-T4 98 | 8086 0003 Ethernet Converged Network Adapter X710-T 99 | 8086 00a0 Ethernet Converged Network Adapter X710-T4 100 | 158a Ethernet Controller XXV710 for 25GbE backplane 101 | 1590 0000 10/25Gb Ethernet Adapter 102 | 1590 0286 Synergy 4610C 10/25Gb Ethernet Adapter 103 | 8086 0000 Ethernet Controller XXV710 for 25GbE backplane 104 | 8086 000a Ethernet 25G 2P XXV710 Mezz 105 | 158b Ethernet Controller XXV710 for 25GbE SFP28 106 | 1590 0000 Ethernet Network Adapter XXV710-2 107 | 1590 0253 Ethernet 10/25/Gb 2-port 661SFP28 Adapter 108 | 8086 0000 Ethernet Network Adapter XXV710 109 | 8086 0001 Ethernet Network Adapter XXV710-2 110 | 8086 0002 Ethernet Network Adapter XXV710-2 111 | 8086 0003 Ethernet Network Adapter XXV710-1 112 | 8086 0004 Ethernet Network Adapter XXV710-1 113 | 8086 0005 Ethernet Network Adapter OCP XXV710-2 114 | 8086 0006 Ethernet Network Adapter OCP XXV710-2 115 | 8086 0007 Ethernet Network Adapter OCP XXV710-1 116 | 8086 0008 Ethernet Network Adapter OCP XXV710-1 117 | 8086 0009 Ethernet 25G 2P XXV710 Adapter 118 | 8086 000c Ethernet Network Adapter XXV710-DA2 for OCP 3.0 119 | 8086 000d Ethernet 25G 2P XXV710 OCP 120 | 8086 4001 Ethernet Network Adapter XXV710-2 121 | 15ff Ethernet Controller X710 for 10GBASE-T 122 | 108e 0000 Oracle Quad Port 10GBase-T Adapter - CP 123 | 108e 7b1f Oracle Quad Port 10GBase-T Adapter - CP 124 | 1137 02c1 Ethernet Network Adapter X710-T2L 125 | 8086 0000 Ethernet Network Adapter X710-TL 126 | 8086 0001 Ethernet Network Adapter X710-T4L 127 | 8086 0002 Ethernet Network Adapter X710-T4L 128 | 8086 0003 Ethernet Network Adapter X710-T2L 129 | 8086 0004 Ethernet Network Adapter X710-T2L 130 | 8086 0005 Ethernet 10G 2P X710-T2L-t Adapter 131 | 8086 0006 Ethernet 10G 4P X710-T4L-t Adapter 132 | 8086 0007 Ethernet 10G 2P X710-T2L-t OCP 133 | 8086 0008 Ethernet 10G 4P X710-T4L-t OCP 134 | 8086 0009 Ethernet Network Adapter X710-T4L for OCP 3.0 135 | 8086 000a Ethernet Network Adapter X710-T4L for OCP 3.0 136 | 8086 000b Ethernet Network Adapter X710-T2L for OCP 3.0 137 | 8086 000c Ethernet Network Adapter X710-T2L for OCP 3.0 138 | 8086 000d Ethernet 10G 2P X710-T2L-t OCP 139 | 8086 000f Ethernet Network Adapter X710-T2L for OCP 3.0 140 | 8086 4009 Ethernet Network Adapter X710-T2L 141 | 8086 4012 Ethernet Network Adapter X710-T4L for OCP 3.0 142 | 8086 4018 Ethernet Network Adapter X710-T2L for OCP 3.0 143 | 8086 4019 Ethernet Network Adapter X710-T4L 144 | 37ce Ethernet Connection X722 for 10GbE backplane 145 | 1590 0215 Ethernet 10Gb 2-port 568i Adapter 146 | 17aa 4023 Ethernet Connection X722 for 10GbE backplane 147 | 37cf Ethernet Connection X722 for 10GbE QSFP+ 148 | 37d0 Ethernet Connection X722 for 10GbE SFP+ 149 | 8086 0001 Ethernet Network Adapter X722-2 150 | 8086 0002 Ethernet Network Adapter X722-2 151 | 8086 0003 Ethernet Network Adapter X722-4 152 | 8086 0004 Ethernet Network Adapter X722-4 153 | 37d1 Ethernet Connection X722 for 1GbE 154 | 1590 0216 Ethernet 1Gb 2-port 368i Adapter 155 | 1590 0217 Ethernet 1Gb 2-port 368FLR-MMT Adapter 156 | 1590 0247 Ethernet 1Gb 4-port 369i Adapter 157 | 17aa 4020 Ethernet Connection X722 for 1GbE 158 | 17aa 4021 Ethernet Connection X722 for 1GbE 159 | 17aa 4022 Ethernet Connection X722 for 1GbE 160 | 17aa 4024 Ethernet Connection X722 for 1GbE 161 | 37d2 Ethernet Connection X722 for 10GBASE-T 162 | 1590 0218 Ethernet 10Gb 2-port 568FLR-MMT Adapter 163 | 17aa 4020 Ethernet Connection X722 for 10GBASE-T 164 | 17aa 4021 Ethernet Connection X722 for 10GBASE-T 165 | 17aa 4024 Ethernet Connection X722 for 10GBASE-T 166 | 37d3 Ethernet Connection X722 for 10GbE SFP+ 167 | 1590 0219 Ethernet 10Gb 2-port 568FLR-MMSFP+ Adapter 168 | 17aa 4020 Ethernet Connection X722 for 10GbE SFP+ 169 | 17aa 4021 Ethernet Connection X722 for 10GbE SFP+ 170 | -------------------------------------------------------------------------------- /scripts/check_aux_bus: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # Copyright (C) 2021 - 2023 Intel Corporation 4 | # 5 | # Helper script to detect if auxiliary bus support. This script 6 | # 7 | # returns 0 when: 8 | # - CONFIG_AUXILIARY_BUS=y 9 | # - auxiliary_bus.h was found 10 | # 11 | # Returning 0 means the driver build/install doesn't need OOT 12 | # auxiliary bus 13 | # 14 | # returns 1 when: 15 | # - CONFIG_AUXILIARY_BUS=n (or any value that's not "=y") 16 | # - kernel configuration was incorrect 17 | # - kernel configuration file was not found 18 | # 19 | # Returning 1 means something bad/unexpected happened and the 20 | # driver build/install should treat this as a failure 21 | # 22 | # returns 2 when: 23 | # - When OOT auxiliary is needed regardless if a previous OOT 24 | # auxiliary was already. This is done because the driver 25 | # always needs to build against auxiliary.o to avoid 26 | # warnings/errors since auxiliary.o is built-in to the 27 | # driver's makefile 28 | # 29 | # Returning 2 means the driver build/install needs OOT auxiliary 30 | # bus 31 | # 32 | # returns 3 when: 33 | # - A file and/or directory does not exist 34 | # 35 | # Returning 3 means something bad/unexpected happened and the 36 | # driver build/install should treat this as a failure 37 | # 38 | # Note: when ksrc and build-kernel are both specified on the 39 | # command line and build-kernel is not in the same location 40 | # as ksrc, then ksrc takes precedence. For example: 41 | # ./check_aux_bus --ksrc=/lib/modules/5.8.0/source --build-kernel=5.10.0 42 | # 43 | # In this case the kernel config file won't be searched for and 44 | # the script will only check to see if the in-tree/OOT auxiliary_bus.h 45 | # file exists at ksrc. 46 | 47 | msg() 48 | { 49 | if [ $verbose == 1 ]; then 50 | echo -e $1 51 | fi 52 | } 53 | 54 | exit_builtin_auxiliary_enabled() { exit 0; } 55 | exit_kconfig_invalid() { exit 1; } 56 | exit_need_oot_auxiliary() { exit 2; } 57 | exit_not_found_failure() { exit 3; } 58 | 59 | find_aux_bus_inc() 60 | { 61 | aux_bus_inc=$(find -L ${ksrc} -name "auxiliary_bus.h") 62 | msg "auxiliary_bus.h location: ${aux_bus_inc}" 63 | } 64 | 65 | LINUX_INCLUDE_DIR="include/linux" 66 | 67 | set_build_kernel() 68 | { 69 | build_kernel=$(uname -r) 70 | } 71 | 72 | find_kernel_source() 73 | { 74 | # All the default places to look for kernel source 75 | test_dirs=(/lib/modules/${build_kernel}/source \ 76 | /lib/modules/${build_kernel}/build \ 77 | /usr/src/linux-${build_kernel} \ 78 | /usr/src/linux-$(echo ${build_kernel} | sed 's/-.*//') \ 79 | /usr/src/kernel-headers-${build_kernel} \ 80 | /usr/src/kernel-source-${build_kernel} \ 81 | /usr/src/linux-$(echo ${build_kernel} | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/') \ 82 | /usr/src/linux \ 83 | /usr/src/kernels/${build_kernel} \ 84 | /usr/src/kernels) 85 | 86 | # Save the first valid kernel source path 87 | for dir in "${test_dirs[@]}"; do 88 | if [ -d ${dir}/${LINUX_INCLUDE_DIR} ]; then 89 | ksrc=${dir} 90 | break 91 | fi 92 | done 93 | 94 | if [ -z ${ksrc} ]; then 95 | echo "*** Kernel header files not in any of the expected locations." 96 | echo "*** Install the appropriate kernel development package, e.g." 97 | echo "kernel-devel, for building kernel modules and try again" 98 | exit_not_found_failure 99 | fi 100 | } 101 | 102 | find_config_file() 103 | { 104 | # only search for kernel .config file if build_kernel is pointing 105 | # in the same tree as ksrc (see not about ksrc and build_kernel 106 | # both set in the scripts header comment) 107 | if [[ "$ksrc" != *"/lib/modules/${build_kernel}"* ]]; then 108 | msg "ksrc=$ksrc not the same as location generated from build_kernel=\"/lib/modules/${build_kernel}\", not searching for kernel .config file" 109 | else 110 | kbuild_dir="/lib/modules/${build_kernel}/build" 111 | 112 | file_locations=(${kbuild_dir}/include/generated/autoconf.h \ 113 | ${kbuild_dir}/include/linux/autoconf.h \ 114 | /boot/bmlinux.autoconf.h) 115 | 116 | for file in "${file_locations[@]}"; do 117 | if [ -f ${file} ]; then 118 | kconfig=${file} 119 | break 120 | fi 121 | done 122 | 123 | if [ -z ${kconfig} ]; then 124 | msg "Kernel config file not found at any of the expected locations." 125 | fi 126 | fi 127 | } 128 | 129 | get_config_auxiliary_bus() 130 | { 131 | # CONFIG_AUXILIARY_BUS=0 corresponds to CONFIG_AUXILIARY_BUS=n 132 | # CONFIG_AUXILIARY_BUS=1 corresponds to CONFIG_AUXILIARY_BUS=y 133 | # CONFIG_AUXILIARY_BUS= corresponds to CONFIG_AUXILIARY_BUS not available in the kernel 134 | CONFIG_AUXILIARY_BUS=$(grep CONFIG_AUXILIARY_BUS ${kconfig} | awk -F" " '{print $3}') 135 | msg "CONFIG_AUXILIARY_BUS=${CONFIG_AUXILIARY_BUS}" 136 | } 137 | 138 | ksrc="" 139 | build_kernel="" 140 | verbose=0 141 | 142 | usage() 143 | { 144 | script=$(basename $0) 145 | echo -e "usage:" 146 | echo -e "\t$script [options]" 147 | echo -e "\n\toptions:" 148 | echo -e "\t -v, --verbose" 149 | echo -e "\t -h, --help" 150 | echo -e "\n\trun script against specified kernel source" 151 | echo -e "\t -k, --ksrc \"/lib/modules/5.12.0/source\"" 152 | echo -e "\n\trun script with kernel version (kernel version used to find kernel source programatically)" 153 | echo -e "\t -b, --build-kernel \"5.8.0\"" 154 | } 155 | 156 | options=$(getopt -o "k:b:vh" --long ksrc:,build-kernel:,verbose,help -- "$@") 157 | eval set -- "$options" 158 | while :; do 159 | case $1 in 160 | -k|--ksrc) ksrc=$2; shift;; 161 | -b|--build-kernel) build_kernel=$2; shift;; 162 | -v|--verbose) verbose=1 ;; 163 | -h|--help) usage && exit 0;; 164 | --) shift; break;; 165 | esac 166 | shift 167 | done 168 | 169 | if [ $verbose == 1 ]; then 170 | set -x 171 | fi 172 | 173 | # both build_kernel and ksrc are unset so programatically determine build_kernel 174 | if [ -z $build_kernel ] && [ -z $ksrc ]; then 175 | set_build_kernel 176 | fi 177 | 178 | # only programatically search for kernel source if ksrc not set on command line 179 | if [ -z $ksrc ]; then 180 | find_kernel_source 181 | fi 182 | 183 | find_config_file 184 | 185 | if [ ! -z $kconfig ]; then 186 | # if we found the kernel .config file then exit the script based on various 187 | # conditions that depend on the CONFIG_AUXILIARY_BUS string being found 188 | get_config_auxiliary_bus 189 | 190 | if [ -z "$CONFIG_AUXILIARY_BUS" ]; then 191 | msg "CONFIG_AUXILIARY_BUS not found in ${kconfig}." 192 | # CONFIG_AUXILIARY_BUS string was not found, so OOT auxiliary is needed 193 | exit_need_oot_auxiliary 194 | elif [ "$CONFIG_AUXILIARY_BUS" = "1" ]; then 195 | msg "CONFIG_AUXILIARY_BUS=y in ${kconfig}." 196 | # CONFIG_AUXILIARY_BUS=y, so OOT auxiliary is not needed 197 | exit_builtin_auxiliary_enabled 198 | else 199 | msg "" 200 | msg "kernel $build_kernel supports auxiliary bus, but CONFIG_AUXILIARY_BUS" 201 | msg "is not set in ${kconfig}. Rebuild your kernel with" 202 | msg "CONFIG_AUXILIARY_BUS=y" 203 | msg "" 204 | # CONFIG_AUXILIARY_BUS is not "=y", but the string was found, so report 205 | # the failure so it can be used to fail build/install 206 | exit_kconfig_invalid 207 | fi 208 | else 209 | if [ ! -d ${ksrc}/${LINUX_INCLUDE_DIR} ] && [ ! -d ${ksrc}/source/${LINUX_INCLUDE_DIR} ]; then 210 | echo "${ksrc}/${LINUX_INCLUDE_DIR} and ${ksrc}/source/${LINUX_INCLUDE_DIR} do not exist" 211 | exit_not_found_failure 212 | fi 213 | 214 | # We didn't find a kernel .config file, so check to see if auxiliary_bus.h 215 | # is found in the kernel source include directory 216 | find_aux_bus_inc 217 | 218 | if [ -f "$aux_bus_inc" ]; then 219 | # AUXILIARY_MODULE_PREFIX is defined only in out-of-tree auxiliary bus 220 | if [ $(grep -c AUXILIARY_MODULE_PREFIX $aux_bus_inc) -eq 0 ]; then 221 | msg "in-tree auxiliary_bus.h found at ${ksrc}/${LINUX_INCLUDE_DIR}" 222 | # If auxiliary_bus.h is included at ${ksrc} and it isn't our OOT version, then 223 | # don't build OOT auxiliary as part of the driver makefile 224 | exit_builtin_auxiliary_enabled 225 | else 226 | msg "OOT auxiliary_bus.h found at ${ksrc}/${LINUX_INCLUDE_DIR}" 227 | # If auxiliary bus is included at ${ksrc} and it is our OOT version, then 228 | # build OOT auxiliary as part of the driver makefile 229 | exit_need_oot_auxiliary 230 | fi 231 | else 232 | msg "auxiliary_bus.h not found at ${ksrc}/${LINUX_INCLUDE_DIR}" 233 | exit_need_oot_auxiliary 234 | fi 235 | fi 236 | -------------------------------------------------------------------------------- /scripts/dump_tables: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Dump Tables script 3 | # Copyright (C) 2015 - 2023 Intel Corporation 4 | # 5 | # This script is used to generate a dump of the hardware state for 6 | # sending to linux.nics@intel.com for debugging purposes. This 7 | # script will generate a dump_tables.gz output file that can be 8 | # uploaded or emailed. 9 | 10 | # Usage: dump_tables eth1 11 | 12 | DEV=$1 13 | . /sys/class/net/$DEV/device/uevent 14 | # DRIVER=i40e 15 | # PCI_CLASS=20000 16 | # PCI_ID=8086:1583 17 | # PCI_SUBSYS_ID=8086:0002 18 | # PCI_SLOT_NAME=0000:06:00.0 19 | # MODALIAS=pci:v00008086d00001583sv00008086sd00000002bc02sc00i00 20 | 21 | if [ "$DEV" == "" ]; then 22 | echo Usage: $0 "" 23 | exit -1 24 | fi 25 | 26 | if [ "$PCI_SLOT_NAME" == "" ]; then 27 | echo kernel version `uname -r` is not supported, please report the bug at e1000.sourceforge.net 28 | exit -2 29 | fi 30 | 31 | CLUSTER=1 32 | TABLE=0 33 | INDEX=0 34 | 35 | OUTFILE=`mktemp` 36 | TMPFILE=`mktemp` 37 | 38 | # check for the debugfs directory being mounted 39 | if [ -d "/sys/kernel/debug/i40e" ]; then 40 | echo debugfs found 41 | else 42 | echo -n "mounting debugfs as /sys/kernel/debug: " 43 | mount -t debugfs none /sys/kernel/debug && echo Success || (echo Failure ; exit -3) 44 | fi 45 | 46 | dmesg -c > /dev/null 47 | until [ "$TABLE" == "0xff" ]; do 48 | until [ "$INDEX" == "0xffffffff" ]; do 49 | echo dump debug fwdata $CLUSTER $TABLE $INDEX > /sys/kernel/debug/i40e/$PCI_SLOT_NAME/command 50 | # check output, exit if no good 51 | dmesg | grep -q unknown && (echo error encountered, see log; exit -4) 52 | # store it, without modification 53 | dmesg >> $OUTFILE 54 | # erase it and prepare for parse 55 | dmesg -c > $TMPFILE 56 | TABLE=`grep rlen $TMPFILE | sed -e 's/.*next_table=\(.*\) .*\$/\1/'` 57 | INDEX=`grep rlen $TMPFILE | sed -e 's/.*next_index=\(.*\)\$/\1/'` 58 | echo -n . 59 | done 60 | INDEX=0 61 | done 62 | 63 | gzip $OUTFILE 64 | cp $OUTFILE.gz dump_tables.gz 65 | 66 | rm $OUTFILE.gz 67 | rm $TMPFILE 68 | 69 | echo Please send the file dump_tables.gz to linux.nics@intel.com or your Intel Support representative. 70 | -------------------------------------------------------------------------------- /scripts/set_irq_affinity: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # Copyright (C) 2015 - 2023 Intel Corporation 4 | # 5 | # Affinitize interrupts to cores 6 | # 7 | # typical usage is (as root): 8 | # set_irq_affinity -x local eth1 9 | # set_irq_affinity -s eth1 10 | # 11 | # to get help: 12 | # set_irq_affinity 13 | 14 | usage() 15 | { 16 | echo 17 | echo "Usage: option -s to show current settings only" 18 | echo "Usage: $0 [-x|-X] [all|local|remote []|one |custom|] ..." 19 | echo " Options: " 20 | echo " -s Shows current affinity settings" 21 | echo " -x Configure XPS as well as smp_affinity" 22 | echo " -X Disable XPS but set smp_affinity" 23 | echo " [all] is the default value" 24 | echo " [remote []] can be followed by a specific node number" 25 | echo " Examples:" 26 | echo " $0 -s eth1 # Show settings on eth1" 27 | 28 | echo " $0 all eth1 eth2 # eth1 and eth2 to all cores" 29 | echo " $0 one 2 eth1 # eth1 to core 2 only" 30 | echo " $0 local eth1 # eth1 to local cores only" 31 | echo " $0 remote eth1 # eth1 to remote cores only" 32 | echo " $0 custom eth1 # prompt for eth1 interface" 33 | echo " $0 0-7,16-23 eth0 # eth1 to cores 0-7 and 16-23" 34 | echo 35 | exit 1 36 | } 37 | 38 | usageX() 39 | { 40 | echo "options -x and -X cannot both be specified, pick one" 41 | exit 1 42 | } 43 | 44 | if [ "$1" == "-x" ]; then 45 | XPS_ENA=1 46 | shift 47 | fi 48 | 49 | if [ "$1" == "-s" ]; then 50 | SHOW=1 51 | echo Show affinity settings 52 | shift 53 | fi 54 | 55 | if [ "$1" == "-X" ]; then 56 | if [ -n "$XPS_ENA" ]; then 57 | usageX 58 | fi 59 | XPS_DIS=2 60 | shift 61 | fi 62 | 63 | if [ "$1" == -x ]; then 64 | usageX 65 | fi 66 | 67 | if [ -n "$XPS_ENA" ] && [ -n "$XPS_DIS" ]; then 68 | usageX 69 | fi 70 | 71 | if [ -z "$XPS_ENA" ]; then 72 | XPS_ENA=$XPS_DIS 73 | fi 74 | 75 | SED=`which sed` 76 | if [[ ! -x $SED ]]; then 77 | echo " $0: ERROR: sed not found in path, this script requires sed" 78 | exit 1 79 | fi 80 | 81 | num='^[0-9]+$' 82 | 83 | # search helpers 84 | NOZEROCOMMA="s/^[0,]*//" 85 | # Vars 86 | AFF=$1 87 | shift 88 | 89 | case "$AFF" in 90 | remote) [[ $1 =~ $num ]] && rnode=$1 && shift ;; 91 | one) [[ $1 =~ $num ]] && cnt=$1 && shift ;; 92 | all) ;; 93 | local) ;; 94 | custom) ;; 95 | [0-9]*) ;; 96 | -h|--help) usage ;; 97 | "") usage ;; 98 | *) IFACES=$AFF && AFF=all ;; # Backwards compat mode 99 | esac 100 | 101 | # append the interfaces listed to the string with spaces 102 | while [ "$#" -ne "0" ] ; do 103 | IFACES+=" $1" 104 | shift 105 | done 106 | 107 | # for now the user must specify interfaces 108 | if [ -z "$IFACES" ]; then 109 | usage 110 | exit 2 111 | fi 112 | 113 | notfound() 114 | { 115 | echo $MYIFACE: not found 116 | exit 15 117 | } 118 | 119 | # check the interfaces exist 120 | for MYIFACE in $IFACES; do 121 | grep -q $MYIFACE /proc/net/dev || notfound 122 | done 123 | 124 | # support functions 125 | 126 | build_mask() 127 | { 128 | VEC=$core 129 | if [ $VEC -ge 32 ] 130 | then 131 | MASK_FILL="" 132 | MASK_ZERO="00000000" 133 | let "IDX = $VEC / 32" 134 | for ((i=1; i<=$IDX;i++)) 135 | do 136 | MASK_FILL="${MASK_FILL},${MASK_ZERO}" 137 | done 138 | 139 | let "VEC -= 32 * $IDX" 140 | MASK_TMP=$((1<<$VEC)) 141 | MASK=$(printf "%X%s" $MASK_TMP $MASK_FILL) 142 | else 143 | MASK_TMP=$((1<<$VEC)) 144 | MASK=$(printf "%X" $MASK_TMP) 145 | fi 146 | } 147 | 148 | show_affinity() 149 | { 150 | # returns the MASK variable 151 | build_mask 152 | 153 | SMP_I=`sed -E "${NOZEROCOMMA}" /proc/irq/$IRQ/smp_affinity` 154 | HINT=`sed -E "${NOZEROCOMMA}" /proc/irq/$IRQ/affinity_hint` 155 | printf "ACTUAL %s %d %s <- /proc/irq/$IRQ/smp_affinity\n" $IFACE $core $SMP_I 156 | printf "HINT %s %d %s <- /proc/irq/$IRQ/affinity_hint\n" $IFACE $core $HINT 157 | IRQ_CHECK=`grep '[-,]' /proc/irq/$IRQ/smp_affinity_list` 158 | if [ ! -z $IRQ_CHECK ]; then 159 | printf " WARNING -- SMP_AFFINITY is assigned to multiple cores $IRQ_CHECK\n" 160 | fi 161 | if [ "$SMP_I" != "$HINT" ]; then 162 | printf " WARNING -- SMP_AFFINITY VALUE does not match AFFINITY_HINT \n" 163 | fi 164 | printf "NODE %s %d %s <- /proc/irq/$IRQ/node\n" $IFACE $core `cat /proc/irq/$IRQ/node` 165 | printf "LIST %s %d [%s] <- /proc/irq/$IRQ/smp_affinity_list\n" $IFACE $core `cat /proc/irq/$IRQ/smp_affinity_list` 166 | printf "XPS %s %d %s <- /sys/class/net/%s/queues/tx-%d/xps_cpus\n" $IFACE $core `cat /sys/class/net/$IFACE/queues/tx-$((n-1))/xps_cpus` $IFACE $((n-1)) 167 | if [ -z `ls /sys/class/net/$IFACE/queues/tx-$((n-1))/xps_rxqs` ]; then 168 | echo "WARNING: xps rxqs not supported on $IFACE" 169 | else 170 | printf "XPSRXQs %s %d %s <- /sys/class/net/%s/queues/tx-%d/xps_rxqs\n" $IFACE $core `cat /sys/class/net/$IFACE/queues/tx-$((n-1))/xps_rxqs` $IFACE $((n-1)) 171 | fi 172 | printf "TX_MAX %s %d %s <- /sys/class/net/%s/queues/tx-%d/tx_maxrate\n" $IFACE $core `cat /sys/class/net/$IFACE/queues/tx-$((n-1))/tx_maxrate` $IFACE $((n-1)) 173 | printf "BQLIMIT %s %d %s <- /sys/class/net/%s/queues/tx-%d/byte_queue_limits/limit\n" $IFACE $core `cat /sys/class/net/$IFACE/queues/tx-$((n-1))/byte_queue_limits/limit` $IFACE $((n-1)) 174 | printf "BQL_MAX %s %d %s <- /sys/class/net/%s/queues/tx-%d/byte_queue_limits/limit_max\n" $IFACE $core `cat /sys/class/net/$IFACE/queues/tx-$((n-1))/byte_queue_limits/limit_max` $IFACE $((n-1)) 175 | printf "BQL_MIN %s %d %s <- /sys/class/net/%s/queues/tx-%d/byte_queue_limits/limit_min\n" $IFACE $core `cat /sys/class/net/$IFACE/queues/tx-$((n-1))/byte_queue_limits/limit_min` $IFACE $((n-1)) 176 | if [ -z `ls /sys/class/net/$IFACE/queues/rx-$((n-1))/rps_flow_cnt` ]; then 177 | echo "WARNING: aRFS is not supported on $IFACE" 178 | else 179 | printf "RPSFCNT %s %d %s <- /sys/class/net/%s/queues/rx-%d/rps_flow_cnt\n" $IFACE $core `cat /sys/class/net/$IFACE/queues/rx-$((n-1))/rps_flow_cnt` $IFACE $((n-1)) 180 | fi 181 | if [ -z `ls /sys/class/net/$IFACE/queues/rx-$((n-1))/rps_cpus` ]; then 182 | echo "WARNING: rps_cpus is not available on $IFACE" 183 | else 184 | printf "RPSCPU %s %d %s <- /sys/class/net/%s/queues/rx-%d/rps_cpus\n" $IFACE $core `cat /sys/class/net/$IFACE/queues/rx-$((n-1))/rps_cpus` $IFACE $((n-1)) 185 | fi 186 | echo 187 | } 188 | 189 | set_affinity() 190 | { 191 | # returns the MASK variable 192 | build_mask 193 | 194 | printf "%s" $MASK > /proc/irq/$IRQ/smp_affinity 195 | printf "%s %d %s -> /proc/irq/$IRQ/smp_affinity\n" $IFACE $core $MASK 196 | SMP_I=`sed -E "${NOZEROCOMMA}" /proc/irq/$IRQ/smp_affinity` 197 | if [ "$SMP_I" != "$MASK" ]; then 198 | printf " ACTUAL\t%s %d %s <- /proc/irq/$IRQ/smp_affinity\n" $IFACE $core $SMP_I 199 | printf " WARNING -- SMP_AFFINITY setting failed\n" 200 | fi 201 | case "$XPS_ENA" in 202 | 1) 203 | printf "%s %d %s -> /sys/class/net/%s/queues/tx-%d/xps_cpus\n" $IFACE $core $MASK $IFACE $((n-1)) 204 | printf "%s" $MASK > /sys/class/net/$IFACE/queues/tx-$((n-1))/xps_cpus 205 | ;; 206 | 2) 207 | MASK=0 208 | printf "%s %d %s -> /sys/class/net/%s/queues/tx-%d/xps_cpus\n" $IFACE $core $MASK $IFACE $((n-1)) 209 | printf "%s" $MASK > /sys/class/net/$IFACE/queues/tx-$((n-1))/xps_cpus 210 | ;; 211 | *) 212 | esac 213 | } 214 | 215 | # Allow usage of , or - 216 | # 217 | parse_range () { 218 | RANGE=${@//,/ } 219 | RANGE=${RANGE//-/..} 220 | LIST="" 221 | for r in $RANGE; do 222 | # eval lets us use vars in {#..#} range 223 | [[ $r =~ '..' ]] && r="$(eval echo {$r})" 224 | LIST+=" $r" 225 | done 226 | echo $LIST 227 | } 228 | 229 | # Affinitize interrupts 230 | # 231 | doaff() 232 | { 233 | CORES=$(parse_range $CORES) 234 | ncores=$(echo $CORES | wc -w) 235 | n=1 236 | 237 | # this script only supports interrupt vectors in pairs, 238 | # modification would be required to support a single Tx or Rx queue 239 | # per interrupt vector 240 | 241 | queues="${IFACE}-.*TxRx" 242 | 243 | irqs=$(grep "$queues" /proc/interrupts | cut -f1 -d:) 244 | [ -z "$irqs" ] && irqs=$(grep $IFACE /proc/interrupts | cut -f1 -d:) 245 | [ -z "$irqs" ] && irqs=$(for i in `ls -1 /sys/class/net/${IFACE}/device/msi_irqs | sort -n` ;do grep -w $i: /proc/interrupts | egrep -v 'fdir|async|misc|ctrl' | cut -f 1 -d :; done) 246 | [ -z "$irqs" ] && echo "Error: Could not find interrupts for $IFACE" 247 | 248 | if [ "$SHOW" == "1" ] ; then 249 | echo "TYPE IFACE CORE MASK -> FILE" 250 | echo "============================" 251 | else 252 | echo "IFACE CORE MASK -> FILE" 253 | echo "=======================" 254 | fi 255 | 256 | for IRQ in $irqs; do 257 | [ "$n" -gt "$ncores" ] && n=1 258 | j=1 259 | # much faster than calling cut for each 260 | for i in $CORES; do 261 | [ $((j++)) -ge $n ] && break 262 | done 263 | core=$i 264 | if [ "$SHOW" == "1" ] ; then 265 | show_affinity 266 | else 267 | set_affinity 268 | fi 269 | ((n++)) 270 | done 271 | } 272 | 273 | # these next 2 lines would allow script to auto-determine interfaces 274 | #[ -z "$IFACES" ] && IFACES=$(ls /sys/class/net) 275 | #[ -z "$IFACES" ] && echo "Error: No interfaces up" && exit 1 276 | 277 | # echo IFACES is $IFACES 278 | 279 | CORES=$(" 35 | echo " Ex: $0 eth0" 36 | echo 37 | exit 1 38 | } 39 | 40 | num='^[0-9]+$' 41 | # Vars 42 | AFF=$1 43 | shift 44 | 45 | case "$AFF" in 46 | [0-9]*) ;; 47 | -h|--help) usage ;; 48 | "") usage ;; 49 | *) IFACES=$AFF && AFF=all ;; # Backwards compat mode 50 | esac 51 | 52 | # append the interfaces listed to the string with spaces 53 | while [ "$#" -ne "0" ] ; do 54 | IFACES+=" $1" 55 | shift 56 | done 57 | 58 | # for now the user must specify interfaces 59 | if [ -z "$IFACES" ]; then 60 | usage 61 | exit 1 62 | fi 63 | 64 | # support functions 65 | 66 | disable_xps() 67 | { 68 | VEC=$core 69 | if [ $VEC -ge 32 ] 70 | then 71 | MASK_FILL="" 72 | MASK_ZERO="00000000" 73 | let "IDX = $VEC / 32" 74 | for ((i=1; i<=$IDX;i++)) 75 | do 76 | MASK_FILL="${MASK_FILL},${MASK_ZERO}" 77 | done 78 | 79 | let "VEC -= 32 * $IDX" 80 | MASK_TMP=$((1<<$VEC)) 81 | MASK=$(printf "%X%s" $MASK_TMP $MASK_FILL) 82 | else 83 | MASK_TMP=$((1<<$VEC)) 84 | MASK=$(printf "%X" $MASK_TMP) 85 | fi 86 | 87 | MASK=0 88 | printf "%s %d %s -> /sys/class/net/%s/queues/tx-%d/xps_cpus\n" $IFACE $core $MASK $IFACE $((n-1)) 89 | printf "%s" $MASK > /sys/class/net/$IFACE/queues/tx-$((n-1))/xps_cpus 90 | } 91 | 92 | # Allow usage of , or - 93 | # 94 | parse_range () { 95 | RANGE=${@//,/ } 96 | RANGE=${RANGE//-/..} 97 | LIST="" 98 | for r in $RANGE; do 99 | # eval lets us use vars in {#..#} range 100 | [[ $r =~ '..' ]] && r="$(eval echo {$r})" 101 | LIST+=" $r" 102 | done 103 | echo $LIST 104 | } 105 | 106 | # Affinitize interrupts 107 | # 108 | setaff() 109 | { 110 | CORES=$(parse_range $CORES) 111 | ncores=$(echo $CORES | wc -w) 112 | n=1 113 | 114 | # this script only supports interrupt vectors in pairs, 115 | # modification would be required to support a single Tx or Rx queue 116 | # per interrupt vector 117 | 118 | queues="${IFACE}-.*TxRx" 119 | 120 | irqs=$(grep "$queues" /proc/interrupts | cut -f1 -d:) 121 | [ -z "$irqs" ] && irqs=$(grep $IFACE /proc/interrupts | cut -f1 -d:) 122 | [ -z "$irqs" ] && irqs=$(for i in `ls -Ux /sys/class/net/$IFACE/device/msi_irqs` ;\ 123 | do grep "$i:.*TxRx" /proc/interrupts | grep -v fdir | cut -f 1 -d : ;\ 124 | done) 125 | [ -z "$irqs" ] && echo "Error: Could not find interrupts for $IFACE" 126 | 127 | echo "IFACE CORE MASK -> FILE" 128 | echo "=======================" 129 | for IRQ in $irqs; do 130 | [ "$n" -gt "$ncores" ] && n=1 131 | j=1 132 | # much faster than calling cut for each 133 | for i in $CORES; do 134 | [ $((j++)) -ge $n ] && break 135 | done 136 | core=$i 137 | disable_xps 138 | ((n++)) 139 | done 140 | } 141 | 142 | # now the actual useful bits of code 143 | 144 | # these next 2 lines would allow script to auto-determine interfaces 145 | #[ -z "$IFACES" ] && IFACES=$(ls /sys/class/net) 146 | #[ -z "$IFACES" ] && echo "Error: No interfaces up" && exit 1 147 | 148 | # echo IFACES is $IFACES 149 | 150 | CORES=$(/dev/null) 77 | 78 | # Enable higher warning level 79 | checkwarnings: clean 80 | @+$(call kernelbuild,modules,W=1) 81 | 82 | # Run sparse static analyzer 83 | sparse: clean 84 | @+$(call kernelbuild,modules,C=2 CF="-D__CHECK_ENDIAN__ -Wbitwise -Wcontext") 85 | 86 | # Run coccicheck static analyzer 87 | ccc: clean 88 | @+$(call kernelbuild,modules,coccicheck MODE=report) 89 | 90 | # Build manfiles 91 | manfile: 92 | @gzip -c ../${DRIVER}.${MANSECTION} > ${DRIVER}.${MANSECTION}.gz 93 | # Clean the module subdirectories 94 | clean: 95 | @+$(call kernelbuild,clean) 96 | @-rm -rf *.${MANSECTION}.gz *.ko 97 | sign: 98 | @echo "Signing driver..." 99 | @$(call info_signed_modules) 100 | @$(call sign_driver) 101 | 102 | mandocs_install: manfile 103 | @echo "Copying manpages..." 104 | @install -D -m 644 ${DRIVER}.${MANSECTION}.gz ${INSTALL_MOD_PATH}${MANDIR}/man${MANSECTION}/${DRIVER}.${MANSECTION}.gz 105 | # Install kernel module files. It is not expected to modify files outside of 106 | # the build root. Thus, it must not update initramfs, or run depmod. 107 | modules_install: default 108 | @echo "Installing modules..." 109 | @+$(call kernelbuild,modules_install) 110 | $(MAKE) auxiliary_install 111 | # Install kernel module files without auxiliary. This target is called by the 112 | # RPM specfile when generating binary RPMs, and is not expected to modify 113 | # files outside of the build root. Thus, it must not update initramfs, or run depmod. 114 | modules_install_no_aux: 115 | @echo "Installing modules..." 116 | @+$(call kernelbuild,modules_install) 117 | 118 | # After installing all the files, perform necessary work to ensure the system 119 | # will use the new modules. This includes running depmod to update module 120 | # dependencies and updating the initramfs image in case the module is loaded 121 | # during early boot. 122 | install: modules_install 123 | $(call cmd_depmod) 124 | $(call cmd_initramfs) 125 | $(MAKE) mandocs_install 126 | # Target used by rpmbuild spec file 127 | rpm: modules_install 128 | $(MAKE) mandocs_install 129 | mandocs_uninstall: 130 | if [ -e ${INSTALL_MOD_PATH}${MANDIR}/man${MANSECTION}/${DRIVER}.${MANSECTION}.gz ] ; then \ 131 | rm -f ${INSTALL_MOD_PATH}${MANDIR}/man${MANSECTION}/${DRIVER}.${MANSECTION}.gz ; \ 132 | fi; 133 | 134 | # Remove installed module files. This target is called by the RPM specfile when 135 | # generating binary RPMs, and is not expected to modify files outside of the 136 | # build root. Thus, it must not update the initramfs image or run depmod. 137 | modules_uninstall: 138 | rm -f ${INSTALL_MOD_PATH}/lib/modules/${KVER}/${INSTALL_MOD_DIR}/${DRIVER}.ko; 139 | $(MAKE) auxiliary_uninstall 140 | # After uninstalling all the files, perform necessary work to restore the 141 | # system back to using the default kernel modules. This includes running depmod 142 | # to update module dependencies and updating the initramfs image. 143 | uninstall: modules_uninstall mandocs_uninstall 144 | $(call cmd_depmod) 145 | $(call cmd_initramfs) 146 | 147 | auxiliary_info: 148 | @../scripts/check_aux_bus --verbose --ksrc="${KSRC}" --build-kernel="${BUILD_KERNEL}" 149 | auxiliary_install: 150 | @echo "Installing auxiliary..." 151 | ${auxiliary_post_install} 152 | 153 | auxiliary_uninstall: 154 | ${auxiliary_post_uninstall} 155 | 156 | ifeq (${NEED_AUX_BUS},1) 157 | default: auxiliary_info 158 | endif 159 | ######## 160 | # Help # 161 | ######## 162 | help: 163 | @echo 'Build targets:' 164 | @echo ' default - Build module(s) with standard verbosity' 165 | @echo ' noisy - Build module(s) with V=1 verbosity -- very noisy' 166 | @echo ' silent - Build module(s), squelching all output' 167 | @echo '' 168 | @echo 'Static Analysis:' 169 | @echo ' checkwarnings - Clean, then build module(s) with W=1 warnings enabled' 170 | @echo ' sparse - Clean, then check module(s) using sparse' 171 | @echo ' ccc - Clean, then check module(s) using coccicheck' 172 | @echo '' 173 | @echo 'Cleaning targets:' 174 | @echo ' clean - Clean files generated by kernel module build' 175 | @echo '' 176 | @echo 'Other targets:' 177 | @echo ' manfile - Generate a gzipped manpage' 178 | @echo ' modules_install - install the module(s) only' 179 | @echo ' mandocs_install - install the manpage only' 180 | @echo ' install - Build then install the module(s) and manpage, and update initramfs' 181 | @echo ' modules_uninstall - uninstall the module(s) only' 182 | @echo ' mandocs_uninstall - uninstall the manpage only' 183 | @echo ' uninstall - Uninstall the module(s) and manpage, and update initramfs' 184 | @echo ' auxiliary_info - Print information about the auxiliary module' 185 | @echo ' auxiliary_install - Install compiled auxiliary module' 186 | @echo ' auxiliary_uninstall - Uninstall auxiliary module' 187 | @echo ' help - Display this help message' 188 | @echo '' 189 | @echo 'Variables:' 190 | @echo ' LINUX_VERSION - Debug tool to force kernel LINUX_VERSION_CODE. Use at your own risk.' 191 | @echo ' W=N - Kernel variable for setting warning levels' 192 | @echo ' V=N - Kernel variable for setting output verbosity' 193 | @echo ' INSTALL_MOD_PATH - Add prefix for the module and manpage installation path' 194 | @echo ' INSTALL_MOD_DIR - Use module directory other than updates/drivers/net/ethernet/intel/${DRIVER}' 195 | @echo ' KSRC - Specifies the full path to the kernel tree to build against' 196 | @echo ' Other variables may be available for tuning make process, see' 197 | @echo ' Kernel Kbuild documentation for more information' 198 | .PHONY: default noisy clean manfile silent sparse ccc install uninstall help auxiliary_info 199 | endif # ifneq($(KERNELRELEASE),) 200 | -------------------------------------------------------------------------------- /src/Module.supported: -------------------------------------------------------------------------------- 1 | i40e.ko external 2 | intel_auxiliary.ko external 3 | -------------------------------------------------------------------------------- /src/auxiliary.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "linux/auxiliary_bus.h" 14 | 15 | static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id, 16 | const struct auxiliary_device *auxdev) 17 | { 18 | for (; id->name[0]; id++) { 19 | const char *p = strrchr(dev_name(&auxdev->dev), '.'); 20 | size_t match_size; 21 | 22 | if (!p) 23 | continue; 24 | match_size = p - dev_name(&auxdev->dev); 25 | 26 | /* use dev_name(&auxdev->dev) prefix before last '.' char to match to */ 27 | if (strlen(id->name) == match_size && 28 | !strncmp(dev_name(&auxdev->dev), id->name, match_size)) 29 | return id; 30 | } 31 | return NULL; 32 | } 33 | 34 | static int auxiliary_match(struct device *dev, struct device_driver *drv) 35 | { 36 | struct auxiliary_device *auxdev = to_auxiliary_dev(dev); 37 | struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv); 38 | 39 | return !!auxiliary_match_id(auxdrv->id_table, auxdev); 40 | } 41 | 42 | static int auxiliary_uevent(struct device *dev, struct kobj_uevent_env *env) 43 | { 44 | const char *name, *p; 45 | 46 | name = dev_name(dev); 47 | p = strrchr(name, '.'); 48 | 49 | return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX, 50 | (int)(p - name), name); 51 | } 52 | 53 | static const struct dev_pm_ops auxiliary_dev_pm_ops = { 54 | SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL) 55 | SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume) 56 | }; 57 | 58 | static int auxiliary_bus_probe(struct device *dev) 59 | { 60 | struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); 61 | struct auxiliary_device *auxdev = to_auxiliary_dev(dev); 62 | int ret; 63 | 64 | ret = dev_pm_domain_attach(dev, true); 65 | if (ret != -EPROBE_DEFER) { 66 | if (auxdrv->probe) { 67 | ret = auxdrv->probe(auxdev, 68 | auxiliary_match_id(auxdrv->id_table, 69 | auxdev)); 70 | if (ret) 71 | dev_pm_domain_detach(dev, true); 72 | } else { 73 | /* don't fail if just dev_pm_domain_attach failed */ 74 | ret = 0; 75 | } 76 | } 77 | 78 | return ret; 79 | } 80 | 81 | static int auxiliary_bus_remove(struct device *dev) 82 | { 83 | struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); 84 | struct auxiliary_device *auxdev = to_auxiliary_dev(dev); 85 | 86 | if (auxdrv->remove) 87 | auxdrv->remove(auxdev); 88 | dev_pm_domain_detach(dev, true); 89 | 90 | return 0; 91 | } 92 | 93 | static void auxiliary_bus_shutdown(struct device *dev) 94 | { 95 | struct auxiliary_driver *auxdrv = NULL; 96 | struct auxiliary_device *auxdev; 97 | 98 | if (dev->driver) { 99 | auxdrv = to_auxiliary_drv(dev->driver); 100 | auxdev = to_auxiliary_dev(dev); 101 | } 102 | 103 | if (auxdrv && auxdrv->shutdown) 104 | auxdrv->shutdown(auxdev); 105 | } 106 | 107 | static struct bus_type auxiliary_bus_type = { 108 | .name = "intel_auxiliary", 109 | .probe = auxiliary_bus_probe, 110 | .remove = auxiliary_bus_remove, 111 | .shutdown = auxiliary_bus_shutdown, 112 | .match = auxiliary_match, 113 | .uevent = auxiliary_uevent, 114 | .pm = &auxiliary_dev_pm_ops, 115 | }; 116 | 117 | /** 118 | * auxiliary_device_init - check auxiliary_device and initialize 119 | * @auxdev: auxiliary device struct 120 | * 121 | * This is the first step in the two-step process to register an 122 | * auxiliary_device. 123 | * 124 | * When this function returns an error code, then the device_initialize will 125 | * *not* have been performed, and the caller will be responsible to free any 126 | * memory allocated for the auxiliary_device in the error path directly. 127 | * 128 | * It returns 0 on success. On success, the device_initialize has been 129 | * performed. After this point any error unwinding will need to include a call 130 | * to auxiliary_device_uninit(). In this post-initialize error scenario, a call 131 | * to the device's .release callback will be triggered, and all memory clean-up 132 | * is expected to be handled there. 133 | */ 134 | int auxiliary_device_init(struct auxiliary_device *auxdev) 135 | { 136 | struct device *dev = &auxdev->dev; 137 | 138 | if (!dev->parent) { 139 | pr_err("auxiliary_device has a NULL dev->parent\n"); 140 | return -EINVAL; 141 | } 142 | 143 | if (!auxdev->name) { 144 | pr_err("auxiliary_device has a NULL name\n"); 145 | return -EINVAL; 146 | } 147 | 148 | dev->bus = &auxiliary_bus_type; 149 | device_initialize(&auxdev->dev); 150 | return 0; 151 | } 152 | EXPORT_SYMBOL_GPL(auxiliary_device_init); 153 | 154 | /** 155 | * __auxiliary_device_add - add an auxiliary bus device 156 | * @auxdev: auxiliary bus device to add to the bus 157 | * @modname: name of the parent device's driver module 158 | * 159 | * This is the second step in the two-step process to register an 160 | * auxiliary_device. 161 | * 162 | * This function must be called after a successful call to 163 | * auxiliary_device_init(), which will perform the device_initialize. This 164 | * means that if this returns an error code, then a call to 165 | * auxiliary_device_uninit() must be performed so that the .release callback 166 | * will be triggered to free the memory associated with the auxiliary_device. 167 | * 168 | * The expectation is that users will call the "auxiliary_device_add" macro so 169 | * that the caller's KBUILD_MODNAME is automatically inserted for the modname 170 | * parameter. Only if a user requires a custom name would this version be 171 | * called directly. 172 | */ 173 | int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname) 174 | { 175 | struct device *dev = &auxdev->dev; 176 | int ret; 177 | 178 | if (!modname) { 179 | dev_err(dev, "auxiliary device modname is NULL\n"); 180 | return -EINVAL; 181 | } 182 | 183 | ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id); 184 | if (ret) { 185 | dev_err(dev, "auxiliary device dev_set_name failed: %d\n", ret); 186 | return ret; 187 | } 188 | 189 | ret = device_add(dev); 190 | if (ret) 191 | dev_err(dev, "adding auxiliary device failed!: %d\n", ret); 192 | 193 | return ret; 194 | } 195 | EXPORT_SYMBOL_GPL(__auxiliary_device_add); 196 | 197 | /** 198 | * auxiliary_find_device - auxiliary device iterator for locating a particular device. 199 | * @start: Device to begin with 200 | * @data: Data to pass to match function 201 | * @match: Callback function to check device 202 | * 203 | * This function returns a reference to a device that is 'found' 204 | * for later use, as determined by the @match callback. 205 | * 206 | * The callback should return 0 if the device doesn't match and non-zero 207 | * if it does. If the callback returns non-zero, this function will 208 | * return to the caller and not iterate over any more devices. 209 | */ 210 | struct auxiliary_device *auxiliary_find_device(struct device *start, 211 | const void *data, 212 | int (*match)(struct device *dev, const void *data)) 213 | { 214 | struct device *dev; 215 | 216 | dev = bus_find_device(&auxiliary_bus_type, start, data, match); 217 | if (!dev) 218 | return NULL; 219 | 220 | return to_auxiliary_dev(dev); 221 | } 222 | EXPORT_SYMBOL_GPL(auxiliary_find_device); 223 | 224 | /** 225 | * __auxiliary_driver_register - register a driver for auxiliary bus devices 226 | * @auxdrv: auxiliary_driver structure 227 | * @owner: owning module/driver 228 | * @modname: KBUILD_MODNAME for parent driver 229 | */ 230 | int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, 231 | struct module *owner, const char *modname) 232 | { 233 | int ret; 234 | 235 | if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) 236 | return -EINVAL; 237 | 238 | if (auxdrv->name) 239 | auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, 240 | auxdrv->name); 241 | else 242 | auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname); 243 | if (!auxdrv->driver.name) 244 | return -ENOMEM; 245 | 246 | auxdrv->driver.owner = owner; 247 | auxdrv->driver.bus = &auxiliary_bus_type; 248 | auxdrv->driver.mod_name = modname; 249 | 250 | ret = driver_register(&auxdrv->driver); 251 | if (ret) 252 | kfree(auxdrv->driver.name); 253 | 254 | return ret; 255 | } 256 | EXPORT_SYMBOL_GPL(__auxiliary_driver_register); 257 | 258 | /** 259 | * auxiliary_driver_unregister - unregister a driver 260 | * @auxdrv: auxiliary_driver structure 261 | */ 262 | void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv) 263 | { 264 | driver_unregister(&auxdrv->driver); 265 | kfree(auxdrv->driver.name); 266 | } 267 | EXPORT_SYMBOL_GPL(auxiliary_driver_unregister); 268 | 269 | static int __init auxiliary_bus_init(void) 270 | { 271 | return bus_register(&auxiliary_bus_type); 272 | } 273 | 274 | static void __exit auxiliary_bus_exit(void) 275 | { 276 | bus_unregister(&auxiliary_bus_type); 277 | } 278 | 279 | module_init(auxiliary_bus_init); 280 | module_exit(auxiliary_bus_exit); 281 | 282 | MODULE_LICENSE("GPL v2"); 283 | MODULE_DESCRIPTION("Auxiliary Bus Standalone"); 284 | MODULE_AUTHOR("linux.nics@intel.com"); 285 | -------------------------------------------------------------------------------- /src/auxiliary_compat.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _AUXILIARY_COMPAT_H_ 5 | #define _AUXILIARY_COMPAT_H_ 6 | 7 | /* This file contains only the minimal set of kernel compatibility backports 8 | * required by auxiliary.c to build. It is similar to the kcompat.h file, but 9 | * reduced to an absolute minimum in order to reduce the risk of generating 10 | * different kernel symbol CRC values at build time. 11 | * 12 | * For a detailed discussion of kernel symbol CRCs, please read: 13 | * 14 | * Documentation/kernel-symbol-crc.rst 15 | * 16 | * Include only the minimum required kernel compatibility implementations from 17 | * kcompat_generated_defs.h and kcompat_impl.h. If a new fix is required, 18 | * please first implement it as part of the kcompat project before porting it 19 | * to this file. 20 | * 21 | * The current list of required implementations is: 22 | * 23 | * NEED_BUS_FIND_DEVICE_CONST_DATA 24 | * NEED_DEV_PM_DOMAIN_ATTACH 25 | * NEED_DEV_PM_DOMAIN_DETACH 26 | * 27 | * Note that kernels since v5.11 support auxiliary as a built-in config 28 | * option. Using this is always preferred to using an out-of-tree module when 29 | * available. 30 | */ 31 | 32 | #include "kcompat_generated_defs.h" 33 | 34 | /**************************** 35 | * Backport implementations * 36 | ****************************/ 37 | 38 | #ifdef NEED_BUS_FIND_DEVICE_CONST_DATA 39 | /* NEED_BUS_FIND_DEVICE_CONST_DATA 40 | * 41 | * bus_find_device() was updated in upstream commit 418e3ea157ef 42 | * ("bus_find_device: Unify the match callback with class_find_device") 43 | * to take a const void *data parameter and also have the match() function 44 | * passed in take a const void *data parameter. 45 | * 46 | * all of the kcompat below makes it so the caller can always just call 47 | * bus_find_device() according to the upstream kernel without having to worry 48 | * about const vs. non-const arguments. 49 | */ 50 | struct _kc_bus_find_device_custom_data { 51 | const void *real_data; 52 | int (*real_match)(struct device *dev, const void *data); 53 | }; 54 | 55 | static inline int _kc_bus_find_device_wrapped_match(struct device *dev, void *data) 56 | { 57 | struct _kc_bus_find_device_custom_data *custom_data = data; 58 | 59 | return custom_data->real_match(dev, custom_data->real_data); 60 | } 61 | 62 | static inline struct device * 63 | _kc_bus_find_device(struct bus_type *type, struct device *start, 64 | const void *data, 65 | int (*match)(struct device *dev, const void *data)) 66 | { 67 | struct _kc_bus_find_device_custom_data custom_data = {}; 68 | 69 | custom_data.real_data = data; 70 | custom_data.real_match = match; 71 | 72 | return bus_find_device(type, start, &custom_data, 73 | _kc_bus_find_device_wrapped_match); 74 | } 75 | 76 | /* force callers of bus_find_device() to call _kc_bus_find_device() on kernels 77 | * where NEED_BUS_FIND_DEVICE_CONST_DATA is defined 78 | */ 79 | #define bus_find_device(type, start, data, match) \ 80 | _kc_bus_find_device(type, start, data, match) 81 | #endif /* NEED_BUS_FIND_DEVICE_CONST_DATA */ 82 | 83 | #if defined(NEED_DEV_PM_DOMAIN_ATTACH) && defined(NEED_DEV_PM_DOMAIN_DETACH) 84 | #include 85 | /* NEED_DEV_PM_DOMAIN_ATTACH and NEED_DEV_PM_DOMAIN_DETACH 86 | * 87 | * dev_pm_domain_attach() and dev_pm_domain_detach() were added in upstream 88 | * commit 46420dd73b80 ("PM / Domains: Add APIs to attach/detach a PM domain for 89 | * a device"). To support older kernels and OSVs that don't have these API, just 90 | * implement how older versions worked by directly calling acpi_dev_pm_attach() 91 | * and acpi_dev_pm_detach(). 92 | */ 93 | static inline int dev_pm_domain_attach(struct device *dev, bool power_on) 94 | { 95 | if (dev->pm_domain) 96 | return 0; 97 | 98 | if (ACPI_HANDLE(dev)) 99 | return acpi_dev_pm_attach(dev, true); 100 | 101 | return 0; 102 | } 103 | 104 | static inline void dev_pm_domain_detach(struct device *dev, bool power_off) 105 | { 106 | if (ACPI_HANDLE(dev)) 107 | acpi_dev_pm_detach(dev, true); 108 | } 109 | #else /* NEED_DEV_PM_DOMAIN_ATTACH && NEED_DEV_PM_DOMAIN_DETACH */ 110 | /* it doesn't make sense to compat only one of these functions, and it is 111 | * likely either a failure in kcompat-generator.sh or a failed distribution 112 | * backport if this occurs. Don't try to support it. 113 | */ 114 | #ifdef NEED_DEV_PM_DOMAIN_ATTACH 115 | #error "NEED_DEV_PM_DOMAIN_ATTACH defined but NEED_DEV_PM_DOMAIN_DETACH not defined???" 116 | #endif /* NEED_DEV_PM_DOMAIN_ATTACH */ 117 | #ifdef NEED_DEV_PM_DOMAIN_DETACH 118 | #error "NEED_DEV_PM_DOMAIN_DETACH defined but NEED_DEV_PM_DOMAIN_ATTACH not defined???" 119 | #endif /* NEED_DEV_PM_DOMAIN_DETACH */ 120 | #endif /* NEED_DEV_PM_DOMAIN_ATTACH && NEED_DEV_PM_DOMAIN_DETACH */ 121 | 122 | #endif /* _AUXILIARY_COMPAT_H_ */ 123 | -------------------------------------------------------------------------------- /src/i40e_adminq.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_ADMINQ_H_ 5 | #define _I40E_ADMINQ_H_ 6 | 7 | #include "i40e_osdep.h" 8 | #include "i40e_status.h" 9 | #include "i40e_adminq_cmd.h" 10 | 11 | #define I40E_ADMINQ_DESC(R, i) \ 12 | (&(((struct i40e_aq_desc *)((R).desc_buf.va))[i])) 13 | 14 | #define I40E_ADMINQ_DESC_ALIGNMENT 4096 15 | 16 | struct i40e_adminq_ring { 17 | struct i40e_virt_mem dma_head; /* space for dma structures */ 18 | struct i40e_dma_mem desc_buf; /* descriptor ring memory */ 19 | struct i40e_virt_mem cmd_buf; /* command buffer memory */ 20 | 21 | union { 22 | struct i40e_dma_mem *asq_bi; 23 | struct i40e_dma_mem *arq_bi; 24 | } r; 25 | 26 | u16 count; /* Number of descriptors */ 27 | u16 rx_buf_len; /* Admin Receive Queue buffer length */ 28 | 29 | /* used for interrupt processing */ 30 | u16 next_to_use; 31 | u16 next_to_clean; 32 | 33 | /* used for queue tracking */ 34 | u32 head; 35 | u32 tail; 36 | u32 len; 37 | u32 bah; 38 | u32 bal; 39 | }; 40 | 41 | /* ASQ transaction details */ 42 | struct i40e_asq_cmd_details { 43 | void *callback; /* cast from type I40E_ADMINQ_CALLBACK */ 44 | u64 cookie; 45 | u16 flags_ena; 46 | u16 flags_dis; 47 | bool async; 48 | bool postpone; 49 | struct i40e_aq_desc *wb_desc; 50 | }; 51 | 52 | #define I40E_ADMINQ_DETAILS(R, i) \ 53 | (&(((struct i40e_asq_cmd_details *)((R).cmd_buf.va))[i])) 54 | 55 | /* ARQ event information */ 56 | struct i40e_arq_event_info { 57 | struct i40e_aq_desc desc; 58 | u16 msg_len; 59 | u16 buf_len; 60 | u8 *msg_buf; 61 | }; 62 | 63 | /* Admin Queue information */ 64 | struct i40e_adminq_info { 65 | struct i40e_adminq_ring arq; /* receive queue */ 66 | struct i40e_adminq_ring asq; /* send queue */ 67 | u32 asq_cmd_timeout; /* send queue cmd write back timeout*/ 68 | u16 num_arq_entries; /* receive queue depth */ 69 | u16 num_asq_entries; /* send queue depth */ 70 | u16 arq_buf_size; /* receive queue buffer size */ 71 | u16 asq_buf_size; /* send queue buffer size */ 72 | u16 fw_maj_ver; /* firmware major version */ 73 | u16 fw_min_ver; /* firmware minor version */ 74 | u32 fw_build; /* firmware build number */ 75 | u16 api_maj_ver; /* api major version */ 76 | u16 api_min_ver; /* api minor version */ 77 | 78 | struct i40e_spinlock asq_spinlock; /* Send queue spinlock */ 79 | struct i40e_spinlock arq_spinlock; /* Receive queue spinlock */ 80 | 81 | /* last status values on send and receive queues */ 82 | enum i40e_admin_queue_err asq_last_status; 83 | enum i40e_admin_queue_err arq_last_status; 84 | }; 85 | 86 | /** 87 | * i40e_aq_rc_to_posix - convert errors to user-land codes 88 | * aq_ret: AdminQ handler error code can override aq_rc 89 | * aq_rc: AdminQ firmware error code to convert 90 | **/ 91 | static INLINE int i40e_aq_rc_to_posix(int aq_ret, int aq_rc) 92 | { 93 | int aq_to_posix[] = { 94 | 0, /* I40E_AQ_RC_OK */ 95 | -EPERM, /* I40E_AQ_RC_EPERM */ 96 | -ENOENT, /* I40E_AQ_RC_ENOENT */ 97 | -ESRCH, /* I40E_AQ_RC_ESRCH */ 98 | -EINTR, /* I40E_AQ_RC_EINTR */ 99 | -EIO, /* I40E_AQ_RC_EIO */ 100 | -ENXIO, /* I40E_AQ_RC_ENXIO */ 101 | -E2BIG, /* I40E_AQ_RC_E2BIG */ 102 | -EAGAIN, /* I40E_AQ_RC_EAGAIN */ 103 | -ENOMEM, /* I40E_AQ_RC_ENOMEM */ 104 | -EACCES, /* I40E_AQ_RC_EACCES */ 105 | -EFAULT, /* I40E_AQ_RC_EFAULT */ 106 | -EBUSY, /* I40E_AQ_RC_EBUSY */ 107 | -EEXIST, /* I40E_AQ_RC_EEXIST */ 108 | -EINVAL, /* I40E_AQ_RC_EINVAL */ 109 | -ENOTTY, /* I40E_AQ_RC_ENOTTY */ 110 | -ENOSPC, /* I40E_AQ_RC_ENOSPC */ 111 | -ENOSYS, /* I40E_AQ_RC_ENOSYS */ 112 | -ERANGE, /* I40E_AQ_RC_ERANGE */ 113 | -EPIPE, /* I40E_AQ_RC_EFLUSHED */ 114 | -ESPIPE, /* I40E_AQ_RC_BAD_ADDR */ 115 | -EROFS, /* I40E_AQ_RC_EMODE */ 116 | -EFBIG, /* I40E_AQ_RC_EFBIG */ 117 | }; 118 | 119 | /* aq_rc is invalid if AQ timed out */ 120 | if (aq_ret == I40E_ERR_ADMIN_QUEUE_TIMEOUT) 121 | return -EAGAIN; 122 | 123 | if (!((u32)aq_rc < (sizeof(aq_to_posix) / sizeof((aq_to_posix)[0])))) 124 | return -ERANGE; 125 | 126 | return aq_to_posix[aq_rc]; 127 | } 128 | 129 | /* general information */ 130 | #define I40E_AQ_LARGE_BUF 512 131 | #define I40E_ASQ_CMD_TIMEOUT 250000 /* usecs */ 132 | 133 | void i40e_fill_default_direct_cmd_desc(struct i40e_aq_desc *desc, 134 | u16 opcode); 135 | 136 | #endif /* _I40E_ADMINQ_H_ */ 137 | -------------------------------------------------------------------------------- /src/i40e_alloc.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_ALLOC_H_ 5 | #define _I40E_ALLOC_H_ 6 | 7 | struct i40e_hw; 8 | 9 | /* Memory allocation types */ 10 | enum i40e_memory_type { 11 | i40e_mem_arq_buf = 0, /* ARQ indirect command buffer */ 12 | i40e_mem_asq_buf = 1, 13 | i40e_mem_atq_buf = 2, /* ATQ indirect command buffer */ 14 | i40e_mem_arq_ring = 3, /* ARQ descriptor ring */ 15 | i40e_mem_atq_ring = 4, /* ATQ descriptor ring */ 16 | i40e_mem_pd = 5, /* Page Descriptor */ 17 | i40e_mem_bp = 6, /* Backing Page - 4KB */ 18 | i40e_mem_bp_jumbo = 7, /* Backing Page - > 4KB */ 19 | i40e_mem_reserved 20 | }; 21 | 22 | /* prototype for functions used for dynamic memory allocation */ 23 | i40e_status i40e_allocate_dma_mem(struct i40e_hw *hw, 24 | struct i40e_dma_mem *mem, 25 | enum i40e_memory_type type, 26 | u64 size, u32 alignment); 27 | i40e_status i40e_free_dma_mem(struct i40e_hw *hw, 28 | struct i40e_dma_mem *mem); 29 | i40e_status i40e_allocate_virt_mem(struct i40e_hw *hw, 30 | struct i40e_virt_mem *mem, 31 | u32 size); 32 | i40e_status i40e_free_virt_mem(struct i40e_hw *hw, 33 | struct i40e_virt_mem *mem); 34 | 35 | #endif /* _I40E_ALLOC_H_ */ 36 | -------------------------------------------------------------------------------- /src/i40e_client.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_CLIENT_H_ 5 | #define _I40E_CLIENT_H_ 6 | 7 | #ifdef USE_INTEL_AUX_BUS 8 | #include "linux/auxiliary_bus.h" 9 | #else 10 | #include 11 | #endif /* USE_INTEL_AUX_BUS */ 12 | 13 | #define I40E_PEER_RDMA_NAME "i40e_rdma" 14 | #define I40E_PEER_RDMA_ID PLATFORM_DEVID_AUTO 15 | 16 | #define I40E_CLIENT_STR_LENGTH 10 17 | /* Client interface version should be updated anytime there is a change in the 18 | * existing APIs or data structures. 19 | * Note that in-tree i40e has major version of 0 and the structures are not 20 | * identical. For example struct i40e_info and i40e_ops are different. 21 | */ 22 | #define I40E_CLIENT_VERSION_MAJOR 1 23 | #define I40E_CLIENT_VERSION_MINOR 01 24 | #define I40E_CLIENT_VERSION_BUILD 00 25 | #define I40E_CLIENT_VERSION_STR \ 26 | __stringify(I40E_CLIENT_VERSION_MAJOR) "." \ 27 | __stringify(I40E_CLIENT_VERSION_MINOR) "." \ 28 | __stringify(I40E_CLIENT_VERSION_BUILD) 29 | 30 | struct i40e_client_version { 31 | u8 major; 32 | u8 minor; 33 | u8 build; 34 | u8 rsvd; 35 | }; 36 | 37 | enum i40e_client_state { 38 | __I40E_CLIENT_NULL, 39 | __I40E_CLIENT_REGISTERED 40 | }; 41 | 42 | enum i40e_client_instance_state { 43 | __I40E_CLIENT_INSTANCE_NONE, 44 | __I40E_CLIENT_INSTANCE_OPENED, 45 | }; 46 | 47 | struct i40e_ops; 48 | struct i40e_client; 49 | 50 | /* HW does not define a type value for AEQ; only for RX/TX and CEQ. 51 | * In order for us to keep the interface simple, SW will define a 52 | * unique type value for AEQ. 53 | */ 54 | #define I40E_QUEUE_TYPE_PE_AEQ 0x80 55 | #define I40E_QUEUE_INVALID_IDX 0xFFFF 56 | 57 | struct i40e_qv_info { 58 | u32 v_idx; /* msix_vector */ 59 | u16 ceq_idx; 60 | u16 aeq_idx; 61 | u8 itr_idx; 62 | }; 63 | 64 | struct i40e_qvlist_info { 65 | u32 num_vectors; 66 | struct i40e_qv_info qv_info[1]; 67 | }; 68 | 69 | #define I40E_CLIENT_MSIX_ALL 0xFFFFFFFF 70 | 71 | /* set of LAN parameters useful for clients managed by LAN */ 72 | 73 | /* Struct to hold per priority info */ 74 | struct i40e_prio_qos_params { 75 | u16 qs_handle; /* qs handle for prio */ 76 | u8 tc; /* TC mapped to prio */ 77 | u8 reserved; 78 | }; 79 | 80 | #define I40E_CLIENT_MAX_USER_PRIORITY 8 81 | /* Struct to hold Client QoS */ 82 | struct i40e_qos_params { 83 | struct i40e_prio_qos_params prio_qos[I40E_CLIENT_MAX_USER_PRIORITY]; 84 | }; 85 | 86 | struct i40e_params { 87 | struct i40e_qos_params qos; 88 | u16 mtu; 89 | }; 90 | 91 | /* Structure to hold Lan device info for a client device */ 92 | struct i40e_info { 93 | struct i40e_client_version version; 94 | u8 lanmac[6]; 95 | struct net_device *netdev; 96 | struct pci_dev *pcidev; 97 | struct auxiliary_device *aux_dev; 98 | u8 __iomem *hw_addr; 99 | u8 fid; /* function id, PF id or VF id */ 100 | #define I40E_CLIENT_FTYPE_PF 0 101 | #define I40E_CLIENT_FTYPE_VF 1 102 | u8 ftype; /* function type, PF or VF */ 103 | void *pf; 104 | 105 | /* All L2 params that could change during the life span of the PF 106 | * and needs to be communicated to the client when they change 107 | */ 108 | struct i40e_qvlist_info *qvlist_info; 109 | struct i40e_params params; 110 | struct i40e_ops *ops; 111 | 112 | u16 msix_count; /* number of msix vectors*/ 113 | /* Array down below will be dynamically allocated based on msix_count */ 114 | struct msix_entry *msix_entries; 115 | u16 itr_index; /* Which ITR index the PE driver is suppose to use */ 116 | u16 fw_maj_ver; /* firmware major version */ 117 | u16 fw_min_ver; /* firmware minor version */ 118 | u32 fw_build; /* firmware build number */ 119 | struct i40e_client *client; 120 | }; 121 | 122 | struct i40e_auxiliary_device { 123 | struct auxiliary_device aux_dev; 124 | struct i40e_info *ldev; 125 | }; 126 | 127 | #define I40E_CLIENT_RESET_LEVEL_PF 1 128 | #define I40E_CLIENT_RESET_LEVEL_CORE 2 129 | #define I40E_CLIENT_VSI_FLAG_TCP_ENABLE BIT(1) 130 | 131 | struct i40e_ops { 132 | /* setup_q_vector_list enables queues with a particular vector */ 133 | int (*setup_qvlist)(struct i40e_info *ldev, struct i40e_client *client, 134 | struct i40e_qvlist_info *qv_info); 135 | 136 | int (*virtchnl_send)(struct i40e_info *ldev, struct i40e_client *client, 137 | u32 vf_id, u8 *msg, u16 len); 138 | 139 | /* If the PE Engine is unresponsive, RDMA driver can request a reset. 140 | * The level helps determine the level of reset being requested. 141 | */ 142 | void (*request_reset)(struct i40e_info *ldev, 143 | struct i40e_client *client, u32 level); 144 | 145 | /* API for the RDMA driver to set certain VSI flags that control 146 | * PE Engine. 147 | */ 148 | int (*update_vsi_ctxt)(struct i40e_info *ldev, 149 | struct i40e_client *client, 150 | bool is_vf, u32 vf_id, 151 | u32 flag, u32 valid_flag); 152 | 153 | int (*client_device_register)(struct i40e_info *ldev); 154 | 155 | void (*client_device_unregister)(struct i40e_info *ldev); 156 | }; 157 | 158 | struct i40e_client_ops { 159 | /* Should be called from register_client() or whenever PF is ready 160 | * to create a specific client instance. 161 | */ 162 | int (*open)(struct i40e_info *ldev, struct i40e_client *client); 163 | 164 | /* Should be called when netdev is unavailable or when unregister 165 | * call comes in. If the close is happenening due to a reset being 166 | * triggered set the reset bit to true. 167 | */ 168 | void (*close)(struct i40e_info *ldev, struct i40e_client *client, 169 | bool reset); 170 | 171 | /* called when some l2 managed parameters changes - mtu */ 172 | void (*l2_param_change)(struct i40e_info *ldev, 173 | struct i40e_client *client, 174 | struct i40e_params *params); 175 | 176 | int (*virtchnl_receive)(struct i40e_info *ldev, 177 | struct i40e_client *client, u32 vf_id, 178 | u8 *msg, u16 len); 179 | 180 | /* called when a VF is reset by the PF */ 181 | void (*vf_reset)(struct i40e_info *ldev, 182 | struct i40e_client *client, u32 vf_id); 183 | 184 | /* called when the number of VFs changes */ 185 | void (*vf_enable)(struct i40e_info *ldev, 186 | struct i40e_client *client, u32 num_vfs); 187 | 188 | /* returns true if VF is capable of specified offload */ 189 | int (*vf_capable)(struct i40e_info *ldev, 190 | struct i40e_client *client, u32 vf_id); 191 | }; 192 | 193 | /* Client device */ 194 | struct i40e_client_instance { 195 | struct list_head list; 196 | struct i40e_info lan_info; 197 | struct i40e_client *client; 198 | unsigned long state; 199 | }; 200 | 201 | struct i40e_client { 202 | struct list_head list; /* list of registered clients */ 203 | char name[I40E_CLIENT_STR_LENGTH]; 204 | struct i40e_client_version version; 205 | unsigned long state; /* client state */ 206 | atomic_t ref_cnt; /* Count of all the client devices of this kind */ 207 | u32 flags; 208 | #define I40E_CLIENT_FLAGS_LAUNCH_ON_PROBE BIT(0) 209 | #define I40E_TX_FLAGS_NOTIFY_OTHER_EVENTS BIT(2) 210 | u8 type; 211 | #define I40E_CLIENT_IWARP 0 212 | /* client ops provided by the client */ 213 | const struct i40e_client_ops *ops; 214 | }; 215 | 216 | static inline bool i40e_client_is_registered(struct i40e_client *client) 217 | { 218 | return test_bit(__I40E_CLIENT_REGISTERED, &client->state); 219 | } 220 | 221 | #endif /* _I40E_CLIENT_H_ */ 222 | 223 | -------------------------------------------------------------------------------- /src/i40e_dcb.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_DCB_H_ 5 | #define _I40E_DCB_H_ 6 | 7 | #include "i40e_type.h" 8 | 9 | #define I40E_DCBX_STATUS_NOT_STARTED 0 10 | #define I40E_DCBX_STATUS_IN_PROGRESS 1 11 | #define I40E_DCBX_STATUS_DONE 2 12 | #define I40E_DCBX_STATUS_MULTIPLE_PEERS 3 13 | #define I40E_DCBX_STATUS_DISABLED 7 14 | 15 | #define I40E_TLV_TYPE_END 0 16 | #define I40E_TLV_TYPE_ORG 127 17 | 18 | #define I40E_IEEE_8021QAZ_OUI 0x0080C2 19 | #define I40E_IEEE_SUBTYPE_ETS_CFG 9 20 | #define I40E_IEEE_SUBTYPE_ETS_REC 10 21 | #define I40E_IEEE_SUBTYPE_PFC_CFG 11 22 | #define I40E_IEEE_SUBTYPE_APP_PRI 12 23 | 24 | #define I40E_CEE_DCBX_OUI 0x001b21 25 | #define I40E_CEE_DCBX_TYPE 2 26 | 27 | #define I40E_CEE_SUBTYPE_CTRL 1 28 | #define I40E_CEE_SUBTYPE_PG_CFG 2 29 | #define I40E_CEE_SUBTYPE_PFC_CFG 3 30 | #define I40E_CEE_SUBTYPE_APP_PRI 4 31 | 32 | #define I40E_CEE_MAX_FEAT_TYPE 3 33 | #define I40E_LLDP_CURRENT_STATUS_XL710_OFFSET 0x2B 34 | #define I40E_LLDP_CURRENT_STATUS_X722_OFFSET 0x31 35 | #define I40E_LLDP_CURRENT_STATUS_OFFSET 1 36 | #define I40E_LLDP_CURRENT_STATUS_SIZE 1 37 | 38 | /* Defines for LLDP TLV header */ 39 | #define I40E_LLDP_TLV_LEN_SHIFT 0 40 | #define I40E_LLDP_TLV_LEN_MASK (0x01FF << I40E_LLDP_TLV_LEN_SHIFT) 41 | #define I40E_LLDP_TLV_TYPE_SHIFT 9 42 | #define I40E_LLDP_TLV_TYPE_MASK (0x7F << I40E_LLDP_TLV_TYPE_SHIFT) 43 | #define I40E_LLDP_TLV_SUBTYPE_SHIFT 0 44 | #define I40E_LLDP_TLV_SUBTYPE_MASK (0xFF << I40E_LLDP_TLV_SUBTYPE_SHIFT) 45 | #define I40E_LLDP_TLV_OUI_SHIFT 8 46 | #define I40E_LLDP_TLV_OUI_MASK (0xFFFFFF << I40E_LLDP_TLV_OUI_SHIFT) 47 | 48 | /* Defines for IEEE ETS TLV */ 49 | #define I40E_IEEE_ETS_MAXTC_SHIFT 0 50 | #define I40E_IEEE_ETS_MAXTC_MASK (0x7 << I40E_IEEE_ETS_MAXTC_SHIFT) 51 | #define I40E_IEEE_ETS_CBS_SHIFT 6 52 | #define I40E_IEEE_ETS_CBS_MASK BIT(I40E_IEEE_ETS_CBS_SHIFT) 53 | #define I40E_IEEE_ETS_WILLING_SHIFT 7 54 | #define I40E_IEEE_ETS_WILLING_MASK BIT(I40E_IEEE_ETS_WILLING_SHIFT) 55 | #define I40E_IEEE_ETS_PRIO_0_SHIFT 0 56 | #define I40E_IEEE_ETS_PRIO_0_MASK (0x7 << I40E_IEEE_ETS_PRIO_0_SHIFT) 57 | #define I40E_IEEE_ETS_PRIO_1_SHIFT 4 58 | #define I40E_IEEE_ETS_PRIO_1_MASK (0x7 << I40E_IEEE_ETS_PRIO_1_SHIFT) 59 | #define I40E_CEE_PGID_PRIO_0_SHIFT 0 60 | #define I40E_CEE_PGID_PRIO_0_MASK (0xF << I40E_CEE_PGID_PRIO_0_SHIFT) 61 | #define I40E_CEE_PGID_PRIO_1_SHIFT 4 62 | #define I40E_CEE_PGID_PRIO_1_MASK (0xF << I40E_CEE_PGID_PRIO_1_SHIFT) 63 | #define I40E_CEE_PGID_STRICT 15 64 | 65 | /* Defines for IEEE TSA types */ 66 | #define I40E_IEEE_TSA_STRICT 0 67 | #define I40E_IEEE_TSA_ETS 2 68 | 69 | /* Defines for IEEE PFC TLV */ 70 | #define I40E_IEEE_PFC_CAP_SHIFT 0 71 | #define I40E_IEEE_PFC_CAP_MASK (0xF << I40E_IEEE_PFC_CAP_SHIFT) 72 | #define I40E_IEEE_PFC_MBC_SHIFT 6 73 | #define I40E_IEEE_PFC_MBC_MASK BIT(I40E_IEEE_PFC_MBC_SHIFT) 74 | #define I40E_IEEE_PFC_WILLING_SHIFT 7 75 | #define I40E_IEEE_PFC_WILLING_MASK BIT(I40E_IEEE_PFC_WILLING_SHIFT) 76 | 77 | /* Defines for IEEE APP TLV */ 78 | #define I40E_IEEE_APP_SEL_SHIFT 0 79 | #define I40E_IEEE_APP_SEL_MASK (0x7 << I40E_IEEE_APP_SEL_SHIFT) 80 | #define I40E_IEEE_APP_PRIO_SHIFT 5 81 | #define I40E_IEEE_APP_PRIO_MASK (0x7 << I40E_IEEE_APP_PRIO_SHIFT) 82 | 83 | /* TLV definitions for preparing MIB */ 84 | #define I40E_TLV_ID_CHASSIS_ID 0 85 | #define I40E_TLV_ID_PORT_ID 1 86 | #define I40E_TLV_ID_TIME_TO_LIVE 2 87 | #define I40E_IEEE_TLV_ID_ETS_CFG 3 88 | #define I40E_IEEE_TLV_ID_ETS_REC 4 89 | #define I40E_IEEE_TLV_ID_PFC_CFG 5 90 | #define I40E_IEEE_TLV_ID_APP_PRI 6 91 | #define I40E_TLV_ID_END_OF_LLDPPDU 7 92 | #define I40E_TLV_ID_START I40E_IEEE_TLV_ID_ETS_CFG 93 | 94 | #define I40E_IEEE_ETS_TLV_LENGTH 25 95 | #define I40E_IEEE_PFC_TLV_LENGTH 6 96 | #define I40E_IEEE_APP_TLV_LENGTH 11 97 | 98 | /* IEEE 802.1AB LLDP Organization specific TLV */ 99 | struct i40e_lldp_org_tlv { 100 | __be16 typelength; 101 | __be32 ouisubtype; 102 | u8 tlvinfo[1]; 103 | } __packed; 104 | 105 | struct i40e_cee_tlv_hdr { 106 | __be16 typelen; 107 | u8 operver; 108 | u8 maxver; 109 | }; 110 | 111 | struct i40e_cee_ctrl_tlv { 112 | struct i40e_cee_tlv_hdr hdr; 113 | __be32 seqno; 114 | __be32 ackno; 115 | }; 116 | 117 | struct i40e_cee_feat_tlv { 118 | struct i40e_cee_tlv_hdr hdr; 119 | u8 en_will_err; /* Bits: |En|Will|Err|Reserved(5)| */ 120 | #define I40E_CEE_FEAT_TLV_ENABLE_MASK 0x80 121 | #define I40E_CEE_FEAT_TLV_WILLING_MASK 0x40 122 | #define I40E_CEE_FEAT_TLV_ERR_MASK 0x20 123 | u8 subtype; 124 | u8 tlvinfo[1]; 125 | }; 126 | 127 | struct i40e_cee_app_prio { 128 | __be16 protocol; 129 | u8 upper_oui_sel; /* Bits: |Upper OUI(6)|Selector(2)| */ 130 | #define I40E_CEE_APP_SELECTOR_MASK 0x03 131 | __be16 lower_oui; 132 | u8 prio_map; 133 | } __packed; 134 | 135 | enum i40e_get_fw_lldp_status_resp { 136 | I40E_GET_FW_LLDP_STATUS_DISABLED = 0, 137 | I40E_GET_FW_LLDP_STATUS_ENABLED = 1 138 | }; 139 | 140 | /* Data structures to pass for SW DCBX */ 141 | struct i40e_rx_pb_config { 142 | u32 shared_pool_size; 143 | u32 shared_pool_high_wm; 144 | u32 shared_pool_low_wm; 145 | u32 shared_pool_high_thresh[I40E_MAX_TRAFFIC_CLASS]; 146 | u32 shared_pool_low_thresh[I40E_MAX_TRAFFIC_CLASS]; 147 | u32 tc_pool_size[I40E_MAX_TRAFFIC_CLASS]; 148 | u32 tc_pool_high_wm[I40E_MAX_TRAFFIC_CLASS]; 149 | u32 tc_pool_low_wm[I40E_MAX_TRAFFIC_CLASS]; 150 | }; 151 | 152 | enum i40e_dcb_arbiter_mode { 153 | I40E_DCB_ARB_MODE_STRICT_PRIORITY = 0, 154 | I40E_DCB_ARB_MODE_ROUND_ROBIN = 1 155 | }; 156 | 157 | #define I40E_DEFAULT_PAUSE_TIME 0xffff 158 | #define I40E_MAX_FRAME_SIZE 4608 /* 4.5 KB */ 159 | 160 | #define I40E_DEVICE_RPB_SIZE 968000 /* 968 KB */ 161 | 162 | /* BitTimes (BT) conversion */ 163 | #define I40E_BT2KB(BT) ((BT + (8 * 1024 - 1)) / (8 * 1024)) 164 | #define I40E_B2BT(BT) (BT * 8) 165 | #define I40E_BT2B(BT) ((BT + (8 - 1)) / (8)) 166 | 167 | /* Max Frame(TC) = MFS(max) + MFS(TC) */ 168 | #define I40E_MAX_FRAME_TC(mfs_max, mfs_tc) I40E_B2BT(mfs_max + mfs_tc) 169 | 170 | /* EEE Tx LPI Exit time in Bit Times */ 171 | #define I40E_EEE_TX_LPI_EXIT_TIME 142500 172 | 173 | /* PCI Round Trip Time in Bit Times */ 174 | #define I40E_PCIRTT_LINK_SPEED_10G 20000 175 | #define I40E_PCIRTT_BYTE_LINK_SPEED_20G 40000 176 | #define I40E_PCIRTT_BYTE_LINK_SPEED_40G 80000 177 | 178 | /* PFC Frame Delay Bit Times */ 179 | #define I40E_PFC_FRAME_DELAY 672 180 | 181 | /* Worst case Cable (10GBase-T) Delay Bit Times */ 182 | #define I40E_CABLE_DELAY 5556 183 | 184 | /* Higher Layer Delay @10G Bit Times */ 185 | #define I40E_HIGHER_LAYER_DELAY_10G 6144 186 | 187 | /* Interface Delays in Bit Times */ 188 | /* TODO: Add for other link speeds 20G/40G/etc. */ 189 | #define I40E_INTERFACE_DELAY_10G_MAC_CONTROL 8192 190 | #define I40E_INTERFACE_DELAY_10G_MAC 8192 191 | #define I40E_INTERFACE_DELAY_10G_RS 8192 192 | 193 | #define I40E_INTERFACE_DELAY_XGXS 2048 194 | #define I40E_INTERFACE_DELAY_XAUI 2048 195 | 196 | #define I40E_INTERFACE_DELAY_10G_BASEX_PCS 2048 197 | #define I40E_INTERFACE_DELAY_10G_BASER_PCS 3584 198 | #define I40E_INTERFACE_DELAY_LX4_PMD 512 199 | #define I40E_INTERFACE_DELAY_CX4_PMD 512 200 | #define I40E_INTERFACE_DELAY_SERIAL_PMA 512 201 | #define I40E_INTERFACE_DELAY_PMD 512 202 | 203 | #define I40E_INTERFACE_DELAY_10G_BASET 25600 204 | 205 | /* delay values for with 10G BaseT in Bit Times */ 206 | #define I40E_INTERFACE_DELAY_10G_COPPER \ 207 | (I40E_INTERFACE_DELAY_10G_MAC + (2 * I40E_INTERFACE_DELAY_XAUI) \ 208 | + I40E_INTERFACE_DELAY_10G_BASET) 209 | #define I40E_DV_TC(mfs_max, mfs_tc) \ 210 | ((2 * I40E_MAX_FRAME_TC(mfs_max, mfs_tc)) \ 211 | + I40E_PFC_FRAME_DELAY \ 212 | + (2 * I40E_CABLE_DELAY) \ 213 | + (2 * I40E_INTERFACE_DELAY_10G_COPPER) \ 214 | + I40E_HIGHER_LAYER_DELAY_10G) 215 | #define I40E_STD_DV_TC(mfs_max, mfs_tc) \ 216 | (I40E_DV_TC(mfs_max, mfs_tc) + I40E_B2BT(mfs_max)) 217 | 218 | i40e_status i40e_process_lldp_event(struct i40e_hw *hw, 219 | struct i40e_arq_event_info *e); 220 | /* APIs for SW DCBX */ 221 | void i40e_dcb_hw_rx_fifo_config(struct i40e_hw *hw, 222 | enum i40e_dcb_arbiter_mode ets_mode, 223 | enum i40e_dcb_arbiter_mode non_ets_mode, 224 | u32 max_exponent, u8 lltc_map); 225 | void i40e_dcb_hw_rx_cmd_monitor_config(struct i40e_hw *hw, 226 | u8 num_tc, u8 num_ports); 227 | void i40e_dcb_hw_pfc_config(struct i40e_hw *hw, 228 | u8 pfc_en, u8 *prio_tc); 229 | void i40e_dcb_hw_set_num_tc(struct i40e_hw *hw, u8 num_tc); 230 | u8 i40e_dcb_hw_get_num_tc(struct i40e_hw *hw); 231 | void i40e_dcb_hw_rx_ets_bw_config(struct i40e_hw *hw, u8 *bw_share, 232 | u8 *mode, u8 *prio_type); 233 | void i40e_dcb_hw_rx_up2tc_config(struct i40e_hw *hw, u8 *prio_tc); 234 | void i40e_dcb_hw_calculate_pool_sizes(struct i40e_hw *hw, 235 | u8 num_ports, bool eee_enabled, 236 | u8 pfc_en, u32 *mfs_tc, 237 | struct i40e_rx_pb_config *pb_cfg); 238 | void i40e_dcb_hw_rx_pb_config(struct i40e_hw *hw, 239 | struct i40e_rx_pb_config *old_pb_cfg, 240 | struct i40e_rx_pb_config *new_pb_cfg); 241 | i40e_status i40e_get_dcbx_status(struct i40e_hw *hw, 242 | u16 *status); 243 | i40e_status i40e_lldp_to_dcb_config(u8 *lldpmib, 244 | struct i40e_dcbx_config *dcbcfg); 245 | i40e_status i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type, 246 | u8 bridgetype, 247 | struct i40e_dcbx_config *dcbcfg); 248 | i40e_status i40e_get_dcb_config(struct i40e_hw *hw); 249 | i40e_status i40e_init_dcb(struct i40e_hw *hw, 250 | bool enable_mib_change); 251 | enum i40e_status_code 252 | i40e_get_fw_lldp_status(struct i40e_hw *hw, 253 | enum i40e_get_fw_lldp_status_resp *lldp_status); 254 | i40e_status i40e_set_dcb_config(struct i40e_hw *hw); 255 | i40e_status i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen, 256 | struct i40e_dcbx_config *dcbcfg); 257 | #endif /* _I40E_DCB_H_ */ 258 | -------------------------------------------------------------------------------- /src/i40e_devids.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #define _I40E_DEVIDS_H_ 5 | 6 | /* Device IDs */ 7 | #define I40E_DEV_ID_X710_N3000 0x0CF8 8 | #define I40E_DEV_ID_XXV710_N3000 0x0D58 9 | #define I40E_DEV_ID_SFP_XL710 0x1572 10 | #define I40E_DEV_ID_QEMU 0x1574 11 | #define I40E_DEV_ID_KX_B 0x1580 12 | #define I40E_DEV_ID_KX_C 0x1581 13 | #define I40E_DEV_ID_QSFP_A 0x1583 14 | #define I40E_DEV_ID_QSFP_B 0x1584 15 | #define I40E_DEV_ID_QSFP_C 0x1585 16 | #define I40E_DEV_ID_10G_BASE_T 0x1586 17 | #define I40E_DEV_ID_20G_KR2 0x1587 18 | #define I40E_DEV_ID_20G_KR2_A 0x1588 19 | #define I40E_DEV_ID_10G_BASE_T4 0x1589 20 | #define I40E_DEV_ID_25G_B 0x158A 21 | #define I40E_DEV_ID_25G_SFP28 0x158B 22 | #define I40E_DEV_ID_10G_BASE_T_BC 0x15FF 23 | #define I40E_DEV_ID_10G_B 0x104F 24 | #define I40E_DEV_ID_10G_SFP 0x104E 25 | #define I40E_DEV_ID_5G_BASE_T_BC 0x101F 26 | #define I40E_DEV_ID_1G_BASE_T_BC 0x0DD2 27 | #define I40E_IS_X710TL_DEVICE(d) \ 28 | (((d) == I40E_DEV_ID_10G_BASE_T_BC) || \ 29 | ((d) == I40E_DEV_ID_5G_BASE_T_BC) || \ 30 | ((d) == I40E_DEV_ID_1G_BASE_T_BC)) 31 | #define I40E_DEV_ID_KX_X722 0x37CE 32 | #define I40E_DEV_ID_QSFP_X722 0x37CF 33 | #define I40E_DEV_ID_SFP_X722 0x37D0 34 | #define I40E_DEV_ID_1G_BASE_T_X722 0x37D1 35 | #define I40E_DEV_ID_10G_BASE_T_X722 0x37D2 36 | #define I40E_DEV_ID_SFP_I_X722 0x37D3 37 | #define I40E_DEV_ID_SFP_X722_A 0x0DDA 38 | 39 | #define i40e_is_40G_device(d) ((d) == I40E_DEV_ID_QSFP_A || \ 40 | (d) == I40E_DEV_ID_QSFP_B || \ 41 | (d) == I40E_DEV_ID_QSFP_C) 42 | 43 | #define i40e_is_25G_device(d) ((d) == I40E_DEV_ID_25G_B || \ 44 | (d) == I40E_DEV_ID_25G_SFP28 || \ 45 | (d) == I40E_DEV_ID_XXV710_N3000) 46 | 47 | -------------------------------------------------------------------------------- /src/i40e_diag.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #include "i40e_diag.h" 5 | #include "i40e_prototype.h" 6 | 7 | /** 8 | * i40e_diag_reg_pattern_test 9 | * @hw: pointer to the hw struct 10 | * @reg: reg to be tested 11 | * @mask: bits to be touched 12 | **/ 13 | static i40e_status i40e_diag_reg_pattern_test(struct i40e_hw *hw, 14 | u32 reg, u32 mask) 15 | { 16 | const u32 patterns[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; 17 | u32 pat, val, orig_val; 18 | int i; 19 | 20 | orig_val = rd32(hw, reg); 21 | for (i = 0; i < ARRAY_SIZE(patterns); i++) { 22 | pat = patterns[i]; 23 | wr32(hw, reg, (pat & mask)); 24 | val = rd32(hw, reg); 25 | if ((val & mask) != (pat & mask)) { 26 | #ifdef ETHTOOL_TEST 27 | i40e_debug(hw, I40E_DEBUG_DIAG, 28 | "%s: reg pattern test failed - reg 0x%08x pat 0x%08x val 0x%08x\n", 29 | __func__, reg, pat, val); 30 | #endif 31 | return I40E_ERR_DIAG_TEST_FAILED; 32 | } 33 | } 34 | 35 | wr32(hw, reg, orig_val); 36 | val = rd32(hw, reg); 37 | if (val != orig_val) { 38 | #ifdef ETHTOOL_TEST 39 | i40e_debug(hw, I40E_DEBUG_DIAG, 40 | "%s: reg restore test failed - reg 0x%08x orig_val 0x%08x val 0x%08x\n", 41 | __func__, reg, orig_val, val); 42 | #endif 43 | return I40E_ERR_DIAG_TEST_FAILED; 44 | } 45 | 46 | return I40E_SUCCESS; 47 | } 48 | 49 | const struct i40e_diag_reg_test_info i40e_reg_list[] = { 50 | /* offset mask elements stride */ 51 | {I40E_QTX_CTL(0), 0x0000FFBF, 1, I40E_QTX_CTL(1) - I40E_QTX_CTL(0)}, 52 | {I40E_PFINT_ITR0(0), 0x00000FFF, 3, I40E_PFINT_ITR0(1) - I40E_PFINT_ITR0(0)}, 53 | {I40E_PFINT_ITRN(0, 0), 0x00000FFF, 1, I40E_PFINT_ITRN(0, 1) - I40E_PFINT_ITRN(0, 0)}, 54 | {I40E_PFINT_ITRN(1, 0), 0x00000FFF, 1, I40E_PFINT_ITRN(1, 1) - I40E_PFINT_ITRN(1, 0)}, 55 | {I40E_PFINT_ITRN(2, 0), 0x00000FFF, 1, I40E_PFINT_ITRN(2, 1) - I40E_PFINT_ITRN(2, 0)}, 56 | {I40E_PFINT_STAT_CTL0, 0x0000000C, 1, 0}, 57 | {I40E_PFINT_LNKLST0, 0x00001FFF, 1, 0}, 58 | {I40E_PFINT_LNKLSTN(0), 0x000007FF, 1, I40E_PFINT_LNKLSTN(1) - I40E_PFINT_LNKLSTN(0)}, 59 | {I40E_QINT_TQCTL(0), 0x000000FF, 1, I40E_QINT_TQCTL(1) - I40E_QINT_TQCTL(0)}, 60 | {I40E_QINT_RQCTL(0), 0x000000FF, 1, I40E_QINT_RQCTL(1) - I40E_QINT_RQCTL(0)}, 61 | {I40E_PFINT_ICR0_ENA, 0xF7F20000, 1, 0}, 62 | { 0 } 63 | }; 64 | 65 | /** 66 | * i40e_diag_reg_test 67 | * @hw: pointer to the hw struct 68 | * 69 | * Perform registers diagnostic test 70 | **/ 71 | i40e_status i40e_diag_reg_test(struct i40e_hw *hw) 72 | { 73 | i40e_status ret_code = I40E_SUCCESS; 74 | u32 reg, mask; 75 | u32 elements; 76 | u32 i, j; 77 | 78 | for (i = 0; i40e_reg_list[i].offset != 0 && 79 | ret_code == I40E_SUCCESS; i++) { 80 | 81 | elements = i40e_reg_list[i].elements; 82 | /* set actual reg range for dynamically allocated resources */ 83 | if (i40e_reg_list[i].offset == I40E_QTX_CTL(0) && 84 | hw->func_caps.num_tx_qp != 0) 85 | elements = hw->func_caps.num_tx_qp; 86 | if ((i40e_reg_list[i].offset == I40E_PFINT_ITRN(0, 0) || 87 | i40e_reg_list[i].offset == I40E_PFINT_ITRN(1, 0) || 88 | i40e_reg_list[i].offset == I40E_PFINT_ITRN(2, 0) || 89 | i40e_reg_list[i].offset == I40E_QINT_TQCTL(0) || 90 | i40e_reg_list[i].offset == I40E_QINT_RQCTL(0)) && 91 | hw->func_caps.num_msix_vectors != 0) 92 | elements = hw->func_caps.num_msix_vectors - 1; 93 | 94 | /* test register access */ 95 | mask = i40e_reg_list[i].mask; 96 | for (j = 0; j < elements && ret_code == I40E_SUCCESS; j++) { 97 | reg = i40e_reg_list[i].offset 98 | + (j * i40e_reg_list[i].stride); 99 | ret_code = i40e_diag_reg_pattern_test(hw, reg, mask); 100 | } 101 | } 102 | 103 | return ret_code; 104 | } 105 | 106 | /** 107 | * i40e_diag_eeprom_test 108 | * @hw: pointer to the hw struct 109 | * 110 | * Perform EEPROM diagnostic test 111 | **/ 112 | i40e_status i40e_diag_eeprom_test(struct i40e_hw *hw) 113 | { 114 | i40e_status ret_code; 115 | u16 reg_val; 116 | 117 | /* read NVM control word and if NVM valid, validate EEPROM checksum*/ 118 | ret_code = i40e_read_nvm_word(hw, I40E_SR_NVM_CONTROL_WORD, ®_val); 119 | if ((ret_code == I40E_SUCCESS) && 120 | ((reg_val & I40E_SR_CONTROL_WORD_1_MASK) == 121 | BIT(I40E_SR_CONTROL_WORD_1_SHIFT))) 122 | return i40e_validate_nvm_checksum(hw, NULL); 123 | else 124 | return I40E_ERR_DIAG_TEST_FAILED; 125 | } 126 | 127 | -------------------------------------------------------------------------------- /src/i40e_diag.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_DIAG_H_ 5 | #define _I40E_DIAG_H_ 6 | 7 | #include "i40e_type.h" 8 | 9 | enum i40e_lb_mode { 10 | I40E_LB_MODE_NONE = 0x0, 11 | I40E_LB_MODE_PHY_LOCAL = I40E_AQ_LB_PHY_LOCAL, 12 | I40E_LB_MODE_PHY_REMOTE = I40E_AQ_LB_PHY_REMOTE, 13 | I40E_LB_MODE_MAC_LOCAL = I40E_AQ_LB_MAC_LOCAL, 14 | }; 15 | 16 | struct i40e_diag_reg_test_info { 17 | u32 offset; /* the base register */ 18 | u32 mask; /* bits that can be tested */ 19 | u32 elements; /* number of elements if array */ 20 | u32 stride; /* bytes between each element */ 21 | }; 22 | 23 | extern const struct i40e_diag_reg_test_info i40e_reg_list[]; 24 | 25 | i40e_status i40e_diag_reg_test(struct i40e_hw *hw); 26 | i40e_status i40e_diag_eeprom_test(struct i40e_hw *hw); 27 | 28 | #endif /* _I40E_DIAG_H_ */ 29 | -------------------------------------------------------------------------------- /src/i40e_ethtool_stats.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | /* ethtool statistics helpers */ 5 | 6 | /** 7 | * struct i40e_stats - definition for an ethtool statistic 8 | * @stat_string: statistic name to display in ethtool -S output 9 | * @sizeof_stat: the sizeof() the stat, must be no greater than sizeof(u64) 10 | * @stat_offset: offsetof() the stat from a base pointer 11 | * 12 | * This structure defines a statistic to be added to the ethtool stats buffer. 13 | * It defines a statistic as offset from a common base pointer. Stats should 14 | * be defined in constant arrays using the I40E_STAT macro, with every element 15 | * of the array using the same _type for calculating the sizeof_stat and 16 | * stat_offset. 17 | * 18 | * The sizeof_stat is expected to be sizeof(u8), sizeof(u16), sizeof(u32) or 19 | * sizeof(u64). Other sizes are not expected and will produce a WARN_ONCE from 20 | * the i40e_add_ethtool_stat() helper function. 21 | * 22 | * The stat_string is interpreted as a format string, allowing formatted 23 | * values to be inserted while looping over multiple structures for a given 24 | * statistics array. Thus, every statistic string in an array should have the 25 | * same type and number of format specifiers, to be formatted by variadic 26 | * arguments to the i40e_add_stat_string() helper function. 27 | **/ 28 | struct i40e_stats { 29 | char stat_string[ETH_GSTRING_LEN]; 30 | int sizeof_stat; 31 | int stat_offset; 32 | }; 33 | 34 | /* Helper macro to define an i40e_stat structure with proper size and type. 35 | * Use this when defining constant statistics arrays. Note that @_type expects 36 | * only a type name and is used multiple times. 37 | */ 38 | #define I40E_STAT(_type, _name, _stat) { \ 39 | .stat_string = _name, \ 40 | .sizeof_stat = sizeof_field(_type, _stat), \ 41 | .stat_offset = offsetof(_type, _stat) \ 42 | } 43 | 44 | /* Helper macro for defining some statistics directly copied from the netdev 45 | * stats structure. 46 | */ 47 | #ifdef HAVE_NDO_GET_STATS64 48 | #define I40E_NETDEV_STAT(_net_stat) \ 49 | I40E_STAT(struct rtnl_link_stats64, #_net_stat, _net_stat) 50 | #else 51 | #define I40E_NETDEV_STAT(_net_stat) \ 52 | I40E_STAT(struct net_device_stats, #_net_stat, _net_stat) 53 | #endif 54 | 55 | /* Helper macro for defining some statistics related to queues */ 56 | #define I40E_QUEUE_STAT(_name, _stat) \ 57 | I40E_STAT(struct i40e_ring, _name, _stat) 58 | 59 | /* Stats associated with a Tx or Rx ring */ 60 | static const struct i40e_stats i40e_gstrings_queue_stats[] = { 61 | I40E_QUEUE_STAT("%s-%u.packets", stats.packets), 62 | I40E_QUEUE_STAT("%s-%u.bytes", stats.bytes), 63 | }; 64 | 65 | #ifdef HAVE_XDP_SUPPORT 66 | /* Stats associated with Rx ring's XDP prog */ 67 | static const struct i40e_stats i40e_gstrings_rx_queue_xdp_stats[] = { 68 | I40E_QUEUE_STAT("%s-%u.xdp.pass", xdp_stats.xdp_pass), 69 | I40E_QUEUE_STAT("%s-%u.xdp.drop", xdp_stats.xdp_drop), 70 | I40E_QUEUE_STAT("%s-%u.xdp.tx", xdp_stats.xdp_tx), 71 | I40E_QUEUE_STAT("%s-%u.xdp.unknown", xdp_stats.xdp_unknown), 72 | I40E_QUEUE_STAT("%s-%u.xdp.redirect", xdp_stats.xdp_redirect), 73 | I40E_QUEUE_STAT("%s-%u.xdp.redirect_fail", xdp_stats.xdp_redirect_fail), 74 | }; 75 | #endif 76 | 77 | /** 78 | * i40e_add_one_ethtool_stat - copy the stat into the supplied buffer 79 | * @data: location to store the stat value 80 | * @pointer: basis for where to copy from 81 | * @stat: the stat definition 82 | * 83 | * Copies the stat data defined by the pointer and stat structure pair into 84 | * the memory supplied as data. Used to implement i40e_add_ethtool_stats and 85 | * i40e_add_queue_stats. If the pointer is null, data will be zero'd. 86 | */ 87 | static void 88 | i40e_add_one_ethtool_stat(u64 *data, void *pointer, 89 | const struct i40e_stats *stat) 90 | { 91 | char *p; 92 | 93 | if (!pointer) { 94 | /* ensure that the ethtool data buffer is zero'd for any stats 95 | * which don't have a valid pointer. 96 | */ 97 | *data = 0; 98 | return; 99 | } 100 | 101 | p = (char *)pointer + stat->stat_offset; 102 | switch (stat->sizeof_stat) { 103 | case sizeof(u64): 104 | *data = *((u64 *)p); 105 | break; 106 | case sizeof(u32): 107 | *data = *((u32 *)p); 108 | break; 109 | case sizeof(u16): 110 | *data = *((u16 *)p); 111 | break; 112 | case sizeof(u8): 113 | *data = *((u8 *)p); 114 | break; 115 | default: 116 | WARN_ONCE(1, "unexpected stat size for %s", 117 | stat->stat_string); 118 | *data = 0; 119 | } 120 | } 121 | 122 | /** 123 | * __i40e_add_ethtool_stats - copy stats into the ethtool supplied buffer 124 | * @data: ethtool stats buffer 125 | * @pointer: location to copy stats from 126 | * @stats: array of stats to copy 127 | * @size: the size of the stats definition 128 | * 129 | * Copy the stats defined by the stats array using the pointer as a base into 130 | * the data buffer supplied by ethtool. Updates the data pointer to point to 131 | * the next empty location for successive calls to __i40e_add_ethtool_stats. 132 | * If pointer is null, set the data values to zero and update the pointer to 133 | * skip these stats. 134 | **/ 135 | static void 136 | __i40e_add_ethtool_stats(u64 **data, void *pointer, 137 | const struct i40e_stats stats[], 138 | const unsigned int size) 139 | { 140 | unsigned int i; 141 | 142 | for (i = 0; i < size; i++) 143 | i40e_add_one_ethtool_stat((*data)++, pointer, &stats[i]); 144 | } 145 | 146 | /** 147 | * i40e_add_ethtool_stats - copy stats into ethtool supplied buffer 148 | * @data: ethtool stats buffer 149 | * @pointer: location where stats are stored 150 | * @stats: static const array of stat definitions 151 | * 152 | * Macro to ease the use of __i40e_add_ethtool_stats by taking a static 153 | * constant stats array and passing the ARRAY_SIZE(). This avoids typos by 154 | * ensuring that we pass the size associated with the given stats array. 155 | * 156 | * The parameter stats is evaluated twice, so parameters with side effects 157 | * should be avoided. 158 | **/ 159 | #define i40e_add_ethtool_stats(data, pointer, stats) \ 160 | __i40e_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats)) 161 | 162 | /** 163 | * i40e_add_queue_stats - copy queue statistics into supplied buffer 164 | * @data: ethtool stats buffer 165 | * @ring: the ring to copy 166 | * 167 | * Queue statistics must be copied while protected by 168 | * u64_stats_fetch_begin, so we can't directly use i40e_add_ethtool_stats. 169 | * Assumes that queue stats are defined in i40e_gstrings_queue_stats. If the 170 | * ring pointer is null, zero out the queue stat values and update the data 171 | * pointer. Otherwise safely copy the stats from the ring into the supplied 172 | * buffer and update the data pointer when finished. 173 | * 174 | * This function expects to be called while under rcu_read_lock(). 175 | **/ 176 | static void 177 | i40e_add_queue_stats(u64 **data, struct i40e_ring *ring) 178 | { 179 | const unsigned int size = ARRAY_SIZE(i40e_gstrings_queue_stats); 180 | const struct i40e_stats *stats = i40e_gstrings_queue_stats; 181 | #ifdef HAVE_NDO_GET_STATS64 182 | unsigned int start; 183 | #endif 184 | unsigned int i; 185 | 186 | /* To avoid invalid statistics values, ensure that we keep retrying 187 | * the copy until we get a consistent value according to 188 | * u64_stats_fetch_retry. But first, make sure our ring is 189 | * non-null before attempting to access its syncp. 190 | */ 191 | #ifdef HAVE_NDO_GET_STATS64 192 | do { 193 | start = !ring ? 0 : u64_stats_fetch_begin(&ring->syncp); 194 | for (i = 0; i < size; i++) 195 | i40e_add_one_ethtool_stat(&(*data)[i], ring, &stats[i]); 196 | } while (ring && u64_stats_fetch_retry(&ring->syncp, start)); 197 | #else 198 | for (i = 0; i < size; i++) 199 | i40e_add_one_ethtool_stat(&(*data)[i], ring, &stats[i]); 200 | #endif 201 | 202 | /* Once we successfully copy the stats in, update the data pointer */ 203 | *data += size; 204 | } 205 | 206 | #ifdef HAVE_XDP_SUPPORT 207 | /** 208 | * i40e_add_rx_queue_xdp_stats - copy XDP statistics into supplied buffer 209 | * @data: ethtool stats buffer 210 | * @rx_ring: the rx ring to copy 211 | * 212 | * RX queue XDP statistics must be copied while protected by 213 | * u64_stats_fetch_begin, so we can't directly use i40e_add_ethtool_stats. 214 | * Assumes that queue stats are defined in i40e_gstrings_rx_queue_xdp_stats. If 215 | * the ring pointer is null, zero out the queue stat values and update the data 216 | * pointer. Otherwise safely copy the stats from the ring into the supplied 217 | * buffer and update the data pointer when finished. 218 | * 219 | * This function expects to be called while under rcu_read_lock(). 220 | **/ 221 | static void 222 | i40e_add_rx_queue_xdp_stats(u64 **data, struct i40e_ring *rx_ring) 223 | { 224 | const unsigned int xdp_size = 225 | ARRAY_SIZE(i40e_gstrings_rx_queue_xdp_stats); 226 | const struct i40e_stats *xdp_stats = i40e_gstrings_rx_queue_xdp_stats; 227 | #ifdef HAVE_NDO_GET_STATS64 228 | unsigned int start; 229 | #endif 230 | unsigned int i; 231 | 232 | /* To avoid invalid statistics values, ensure that we keep retrying 233 | * the copy until we get a consistent value according to 234 | * u64_stats_fetch_retry. But first, make sure our ring is 235 | * non-null before attempting to access its syncp. 236 | */ 237 | #ifdef HAVE_NDO_GET_STATS64 238 | do { 239 | start = !rx_ring ? 0 : 240 | u64_stats_fetch_begin(&rx_ring->syncp); 241 | #endif 242 | for (i = 0; i < xdp_size; i++) { 243 | i40e_add_one_ethtool_stat(&(*data)[i], rx_ring, 244 | &xdp_stats[i]); 245 | } 246 | #ifdef HAVE_NDO_GET_STATS64 247 | } while (rx_ring && u64_stats_fetch_retry(&rx_ring->syncp, start)); 248 | #endif 249 | 250 | /* Once we successfully copy the stats in, update the data pointer */ 251 | *data += xdp_size; 252 | } 253 | #endif 254 | 255 | /** 256 | * __i40e_add_stat_strings - copy stat strings into ethtool buffer 257 | * @p: ethtool supplied buffer 258 | * @stats: stat definitions array 259 | * @size: size of the stats array 260 | * 261 | * Format and copy the strings described by stats into the buffer pointed at 262 | * by p. 263 | **/ 264 | static void __i40e_add_stat_strings(u8 **p, const struct i40e_stats stats[], 265 | const unsigned int size, ...) 266 | { 267 | unsigned int i; 268 | 269 | for (i = 0; i < size; i++) { 270 | va_list args; 271 | 272 | va_start(args, size); 273 | vsnprintf((char *)*p, ETH_GSTRING_LEN, stats[i].stat_string, args); 274 | *p += ETH_GSTRING_LEN; 275 | va_end(args); 276 | } 277 | } 278 | 279 | /** 280 | * i40e_add_stat_strings - copy stat strings into ethtool buffer 281 | * @p: ethtool supplied buffer 282 | * @stats: stat definitions array 283 | * 284 | * Format and copy the strings described by the const static stats value into 285 | * the buffer pointed at by p. 286 | * 287 | * The parameter stats is evaluated twice, so parameters with side effects 288 | * should be avoided. Additionally, stats must be an array such that 289 | * ARRAY_SIZE can be called on it. 290 | **/ 291 | #define i40e_add_stat_strings(p, stats, ...) \ 292 | __i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__) 293 | -------------------------------------------------------------------------------- /src/i40e_filters.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #include "i40e_filters.h" 5 | 6 | /** 7 | * __i40e_del_filter - Remove a specific filter from the VSI 8 | * @vsi: VSI to remove from 9 | * @f: the filter to remove from the list 10 | * 11 | * This function should be called instead of i40e_del_filter only if you know 12 | * the exact filter you will remove already, such as via i40e_find_filter or 13 | * i40e_find_mac. 14 | * 15 | * NOTE: This function is expected to be called with mac_filter_hash_lock 16 | * being held. 17 | * ANOTHER NOTE: This function MUST be called from within the context of 18 | * the "safe" variants of any list iterators, e.g. list_for_each_entry_safe() 19 | * instead of list_for_each_entry(). 20 | **/ 21 | void __i40e_del_filter(struct i40e_vsi *vsi, struct i40e_mac_filter *f) 22 | { 23 | if (!f) 24 | return; 25 | 26 | /* If the filter was never added to firmware then we can just delete it 27 | * directly and we don't want to set the status to remove or else an 28 | * admin queue command will unnecessarily fire. 29 | */ 30 | if (f->state == I40E_FILTER_FAILED || f->state == I40E_FILTER_NEW) { 31 | hash_del(&f->hlist); 32 | kfree(f); 33 | } else { 34 | f->state = I40E_FILTER_REMOVE; 35 | } 36 | 37 | vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED; 38 | set_bit(__I40E_MACVLAN_SYNC_PENDING, vsi->back->state); 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/i40e_filters.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_FILTERS_H_ 5 | #define _I40E_FILTERS_H_ 6 | 7 | #include "i40e.h" 8 | 9 | void __i40e_del_filter(struct i40e_vsi *vsi, struct i40e_mac_filter *f); 10 | 11 | #endif /* _I40E_FILTERS_H_ */ 12 | -------------------------------------------------------------------------------- /src/i40e_helper.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_HELPER_H_ 5 | #define _I40E_HELPER_H_ 6 | 7 | #include "i40e_alloc.h" 8 | 9 | void i40e_client_device_register(struct i40e_info *ldev, struct i40e_client *client); 10 | void i40e_client_device_unregister(struct i40e_info *ldev); 11 | 12 | /* prototype */ 13 | inline void i40e_destroy_spinlock_d(struct i40e_spinlock *sp); 14 | inline void i40e_acquire_spinlock_d(struct i40e_spinlock *sp); 15 | inline void i40e_release_spinlock_d(struct i40e_spinlock *sp); 16 | 17 | /** 18 | * i40e_init_spinlock_d - OS specific spinlock init for shared code 19 | * @sp: pointer to a spinlock declared in driver space 20 | **/ 21 | static inline void i40e_init_spinlock_d(struct i40e_spinlock *sp) 22 | { 23 | mutex_init((struct mutex *)sp); 24 | } 25 | 26 | /** 27 | * i40e_acquire_spinlock_d - OS specific spinlock acquire for shared code 28 | * @sp: pointer to a spinlock declared in driver space 29 | **/ 30 | inline void i40e_acquire_spinlock_d(struct i40e_spinlock *sp) 31 | { 32 | mutex_lock((struct mutex *)sp); 33 | } 34 | 35 | /** 36 | * i40e_release_spinlock_d - OS specific spinlock release for shared code 37 | * @sp: pointer to a spinlock declared in driver space 38 | **/ 39 | inline void i40e_release_spinlock_d(struct i40e_spinlock *sp) 40 | { 41 | mutex_unlock((struct mutex *)sp); 42 | } 43 | 44 | /** 45 | * i40e_destroy_spinlock_d - OS specific spinlock destroy for shared code 46 | * @sp: pointer to a spinlock declared in driver space 47 | **/ 48 | inline void i40e_destroy_spinlock_d(struct i40e_spinlock *sp) 49 | { 50 | mutex_destroy((struct mutex *)sp); 51 | } 52 | #endif /* _I40E_HELPER_H_ */ 53 | -------------------------------------------------------------------------------- /src/i40e_hmc.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #include "i40e_osdep.h" 5 | #include "i40e_register.h" 6 | #include "i40e_status.h" 7 | #include "i40e_alloc.h" 8 | #include "i40e_hmc.h" 9 | #ifndef I40E_NO_TYPE_HEADER 10 | #include "i40e_type.h" 11 | #endif 12 | 13 | /** 14 | * i40e_add_sd_table_entry - Adds a segment descriptor to the table 15 | * @hw: pointer to our hw struct 16 | * @hmc_info: pointer to the HMC configuration information struct 17 | * @sd_index: segment descriptor index to manipulate 18 | * @type: what type of segment descriptor we're manipulating 19 | * @direct_mode_sz: size to alloc in direct mode 20 | **/ 21 | i40e_status i40e_add_sd_table_entry(struct i40e_hw *hw, 22 | struct i40e_hmc_info *hmc_info, 23 | u32 sd_index, 24 | enum i40e_sd_entry_type type, 25 | u64 direct_mode_sz) 26 | { 27 | i40e_status ret_code = I40E_SUCCESS; 28 | struct i40e_hmc_sd_entry *sd_entry; 29 | enum i40e_memory_type mem_type; 30 | bool dma_mem_alloc_done = false; 31 | struct i40e_dma_mem mem; 32 | u64 alloc_len; 33 | 34 | if (NULL == hmc_info->sd_table.sd_entry) { 35 | ret_code = I40E_ERR_BAD_PTR; 36 | hw_dbg(hw, "i40e_add_sd_table_entry: bad sd_entry\n"); 37 | goto exit; 38 | } 39 | 40 | if (sd_index >= hmc_info->sd_table.sd_cnt) { 41 | ret_code = I40E_ERR_INVALID_SD_INDEX; 42 | hw_dbg(hw, "i40e_add_sd_table_entry: bad sd_index\n"); 43 | goto exit; 44 | } 45 | 46 | sd_entry = &hmc_info->sd_table.sd_entry[sd_index]; 47 | if (!sd_entry->valid) { 48 | if (I40E_SD_TYPE_PAGED == type) { 49 | mem_type = i40e_mem_pd; 50 | alloc_len = I40E_HMC_PAGED_BP_SIZE; 51 | } else { 52 | mem_type = i40e_mem_bp_jumbo; 53 | alloc_len = direct_mode_sz; 54 | } 55 | 56 | /* allocate a 4K pd page or 2M backing page */ 57 | ret_code = i40e_allocate_dma_mem(hw, &mem, mem_type, alloc_len, 58 | I40E_HMC_PD_BP_BUF_ALIGNMENT); 59 | if (ret_code) 60 | goto exit; 61 | dma_mem_alloc_done = true; 62 | if (I40E_SD_TYPE_PAGED == type) { 63 | ret_code = i40e_allocate_virt_mem(hw, 64 | &sd_entry->u.pd_table.pd_entry_virt_mem, 65 | sizeof(struct i40e_hmc_pd_entry) * 512); 66 | if (ret_code) 67 | goto exit; 68 | sd_entry->u.pd_table.pd_entry = 69 | (struct i40e_hmc_pd_entry *) 70 | sd_entry->u.pd_table.pd_entry_virt_mem.va; 71 | i40e_memcpy(&sd_entry->u.pd_table.pd_page_addr, 72 | &mem, sizeof(struct i40e_dma_mem), 73 | I40E_NONDMA_TO_NONDMA); 74 | } else { 75 | i40e_memcpy(&sd_entry->u.bp.addr, 76 | &mem, sizeof(struct i40e_dma_mem), 77 | I40E_NONDMA_TO_NONDMA); 78 | sd_entry->u.bp.sd_pd_index = sd_index; 79 | } 80 | /* initialize the sd entry */ 81 | hmc_info->sd_table.sd_entry[sd_index].entry_type = type; 82 | 83 | /* increment the ref count */ 84 | I40E_INC_SD_REFCNT(&hmc_info->sd_table); 85 | } 86 | /* Increment backing page reference count */ 87 | if (I40E_SD_TYPE_DIRECT == sd_entry->entry_type) 88 | I40E_INC_BP_REFCNT(&sd_entry->u.bp); 89 | exit: 90 | if (I40E_SUCCESS != ret_code) 91 | if (dma_mem_alloc_done) 92 | i40e_free_dma_mem(hw, &mem); 93 | 94 | return ret_code; 95 | } 96 | 97 | /** 98 | * i40e_add_pd_table_entry - Adds page descriptor to the specified table 99 | * @hw: pointer to our HW structure 100 | * @hmc_info: pointer to the HMC configuration information structure 101 | * @pd_index: which page descriptor index to manipulate 102 | * @rsrc_pg: if not NULL, use preallocated page instead of allocating new one. 103 | * 104 | * This function: 105 | * 1. Initializes the pd entry 106 | * 2. Adds pd_entry in the pd_table 107 | * 3. Mark the entry valid in i40e_hmc_pd_entry structure 108 | * 4. Initializes the pd_entry's ref count to 1 109 | * assumptions: 110 | * 1. The memory for pd should be pinned down, physically contiguous and 111 | * aligned on 4K boundary and zeroed memory. 112 | * 2. It should be 4K in size. 113 | **/ 114 | i40e_status i40e_add_pd_table_entry(struct i40e_hw *hw, 115 | struct i40e_hmc_info *hmc_info, 116 | u32 pd_index, 117 | struct i40e_dma_mem *rsrc_pg) 118 | { 119 | i40e_status ret_code = I40E_SUCCESS; 120 | struct i40e_hmc_pd_table *pd_table; 121 | struct i40e_hmc_pd_entry *pd_entry; 122 | struct i40e_dma_mem mem; 123 | struct i40e_dma_mem *page = &mem; 124 | u32 sd_idx, rel_pd_idx; 125 | u64 *pd_addr; 126 | u64 page_desc; 127 | 128 | if (pd_index / I40E_HMC_PD_CNT_IN_SD >= hmc_info->sd_table.sd_cnt) { 129 | ret_code = I40E_ERR_INVALID_PAGE_DESC_INDEX; 130 | hw_dbg(hw, "i40e_add_pd_table_entry: bad pd_index\n"); 131 | goto exit; 132 | } 133 | 134 | /* find corresponding sd */ 135 | sd_idx = (pd_index / I40E_HMC_PD_CNT_IN_SD); 136 | if (I40E_SD_TYPE_PAGED != 137 | hmc_info->sd_table.sd_entry[sd_idx].entry_type) 138 | goto exit; 139 | 140 | rel_pd_idx = (pd_index % I40E_HMC_PD_CNT_IN_SD); 141 | pd_table = &hmc_info->sd_table.sd_entry[sd_idx].u.pd_table; 142 | pd_entry = &pd_table->pd_entry[rel_pd_idx]; 143 | if (!pd_entry->valid) { 144 | if (rsrc_pg) { 145 | pd_entry->rsrc_pg = true; 146 | page = rsrc_pg; 147 | } else { 148 | /* allocate a 4K backing page */ 149 | ret_code = i40e_allocate_dma_mem(hw, page, i40e_mem_bp, 150 | I40E_HMC_PAGED_BP_SIZE, 151 | I40E_HMC_PD_BP_BUF_ALIGNMENT); 152 | if (ret_code) 153 | goto exit; 154 | pd_entry->rsrc_pg = false; 155 | } 156 | 157 | i40e_memcpy(&pd_entry->bp.addr, page, 158 | sizeof(struct i40e_dma_mem), I40E_NONDMA_TO_NONDMA); 159 | pd_entry->bp.sd_pd_index = pd_index; 160 | pd_entry->bp.entry_type = I40E_SD_TYPE_PAGED; 161 | /* Set page address and valid bit */ 162 | page_desc = page->pa | 0x1; 163 | 164 | pd_addr = (u64 *)pd_table->pd_page_addr.va; 165 | pd_addr += rel_pd_idx; 166 | 167 | /* Add the backing page physical address in the pd entry */ 168 | i40e_memcpy(pd_addr, &page_desc, sizeof(u64), 169 | I40E_NONDMA_TO_DMA); 170 | 171 | pd_entry->sd_index = sd_idx; 172 | pd_entry->valid = true; 173 | I40E_INC_PD_REFCNT(pd_table); 174 | } 175 | I40E_INC_BP_REFCNT(&pd_entry->bp); 176 | exit: 177 | return ret_code; 178 | } 179 | 180 | /** 181 | * i40e_remove_pd_bp - remove a backing page from a page descriptor 182 | * @hw: pointer to our HW structure 183 | * @hmc_info: pointer to the HMC configuration information structure 184 | * @idx: the page index 185 | * 186 | * This function: 187 | * 1. Marks the entry in pd tabe (for paged address mode) or in sd table 188 | * (for direct address mode) invalid. 189 | * 2. Write to register PMPDINV to invalidate the backing page in FV cache 190 | * 3. Decrement the ref count for the pd _entry 191 | * assumptions: 192 | * 1. Caller can deallocate the memory used by backing storage after this 193 | * function returns. 194 | **/ 195 | i40e_status i40e_remove_pd_bp(struct i40e_hw *hw, 196 | struct i40e_hmc_info *hmc_info, 197 | u32 idx) 198 | { 199 | i40e_status ret_code = I40E_SUCCESS; 200 | struct i40e_hmc_pd_entry *pd_entry; 201 | struct i40e_hmc_pd_table *pd_table; 202 | struct i40e_hmc_sd_entry *sd_entry; 203 | u32 sd_idx, rel_pd_idx; 204 | u64 *pd_addr; 205 | 206 | /* calculate index */ 207 | sd_idx = idx / I40E_HMC_PD_CNT_IN_SD; 208 | rel_pd_idx = idx % I40E_HMC_PD_CNT_IN_SD; 209 | if (sd_idx >= hmc_info->sd_table.sd_cnt) { 210 | ret_code = I40E_ERR_INVALID_PAGE_DESC_INDEX; 211 | hw_dbg(hw, "i40e_remove_pd_bp: bad idx\n"); 212 | goto exit; 213 | } 214 | sd_entry = &hmc_info->sd_table.sd_entry[sd_idx]; 215 | if (I40E_SD_TYPE_PAGED != sd_entry->entry_type) { 216 | ret_code = I40E_ERR_INVALID_SD_TYPE; 217 | hw_dbg(hw, "i40e_remove_pd_bp: wrong sd_entry type\n"); 218 | goto exit; 219 | } 220 | /* get the entry and decrease its ref counter */ 221 | pd_table = &hmc_info->sd_table.sd_entry[sd_idx].u.pd_table; 222 | pd_entry = &pd_table->pd_entry[rel_pd_idx]; 223 | I40E_DEC_BP_REFCNT(&pd_entry->bp); 224 | if (pd_entry->bp.ref_cnt) 225 | goto exit; 226 | 227 | /* mark the entry invalid */ 228 | pd_entry->valid = false; 229 | I40E_DEC_PD_REFCNT(pd_table); 230 | pd_addr = (u64 *)pd_table->pd_page_addr.va; 231 | pd_addr += rel_pd_idx; 232 | i40e_memset(pd_addr, 0, sizeof(u64), I40E_DMA_MEM); 233 | I40E_INVALIDATE_PF_HMC_PD(hw, sd_idx, idx); 234 | 235 | /* free memory here */ 236 | if (!pd_entry->rsrc_pg) 237 | ret_code = i40e_free_dma_mem(hw, &(pd_entry->bp.addr)); 238 | if (I40E_SUCCESS != ret_code) 239 | goto exit; 240 | if (!pd_table->ref_cnt) 241 | i40e_free_virt_mem(hw, &pd_table->pd_entry_virt_mem); 242 | exit: 243 | return ret_code; 244 | } 245 | 246 | /** 247 | * i40e_prep_remove_sd_bp - Prepares to remove a backing page from a sd entry 248 | * @hmc_info: pointer to the HMC configuration information structure 249 | * @idx: the page index 250 | **/ 251 | i40e_status i40e_prep_remove_sd_bp(struct i40e_hmc_info *hmc_info, 252 | u32 idx) 253 | { 254 | i40e_status ret_code = I40E_SUCCESS; 255 | struct i40e_hmc_sd_entry *sd_entry; 256 | 257 | /* get the entry and decrease its ref counter */ 258 | sd_entry = &hmc_info->sd_table.sd_entry[idx]; 259 | I40E_DEC_BP_REFCNT(&sd_entry->u.bp); 260 | if (sd_entry->u.bp.ref_cnt) { 261 | ret_code = I40E_ERR_NOT_READY; 262 | goto exit; 263 | } 264 | I40E_DEC_SD_REFCNT(&hmc_info->sd_table); 265 | 266 | /* mark the entry invalid */ 267 | sd_entry->valid = false; 268 | exit: 269 | return ret_code; 270 | } 271 | 272 | /** 273 | * i40e_remove_sd_bp_new - Removes a backing page from a segment descriptor 274 | * @hw: pointer to our hw struct 275 | * @hmc_info: pointer to the HMC configuration information structure 276 | * @idx: the page index 277 | * @is_pf: used to distinguish between VF and PF 278 | **/ 279 | i40e_status i40e_remove_sd_bp_new(struct i40e_hw *hw, 280 | struct i40e_hmc_info *hmc_info, 281 | u32 idx, bool is_pf) 282 | { 283 | struct i40e_hmc_sd_entry *sd_entry; 284 | 285 | if (!is_pf) 286 | return I40E_NOT_SUPPORTED; 287 | 288 | /* get the entry and decrease its ref counter */ 289 | sd_entry = &hmc_info->sd_table.sd_entry[idx]; 290 | I40E_CLEAR_PF_SD_ENTRY(hw, idx, I40E_SD_TYPE_DIRECT); 291 | 292 | return i40e_free_dma_mem(hw, &(sd_entry->u.bp.addr)); 293 | } 294 | 295 | /** 296 | * i40e_prep_remove_pd_page - Prepares to remove a PD page from sd entry. 297 | * @hmc_info: pointer to the HMC configuration information structure 298 | * @idx: segment descriptor index to find the relevant page descriptor 299 | **/ 300 | i40e_status i40e_prep_remove_pd_page(struct i40e_hmc_info *hmc_info, 301 | u32 idx) 302 | { 303 | i40e_status ret_code = I40E_SUCCESS; 304 | struct i40e_hmc_sd_entry *sd_entry; 305 | 306 | sd_entry = &hmc_info->sd_table.sd_entry[idx]; 307 | 308 | if (sd_entry->u.pd_table.ref_cnt) { 309 | ret_code = I40E_ERR_NOT_READY; 310 | goto exit; 311 | } 312 | 313 | /* mark the entry invalid */ 314 | sd_entry->valid = false; 315 | 316 | I40E_DEC_SD_REFCNT(&hmc_info->sd_table); 317 | exit: 318 | return ret_code; 319 | } 320 | 321 | /** 322 | * i40e_remove_pd_page_new - Removes a PD page from sd entry. 323 | * @hw: pointer to our hw struct 324 | * @hmc_info: pointer to the HMC configuration information structure 325 | * @idx: segment descriptor index to find the relevant page descriptor 326 | * @is_pf: used to distinguish between VF and PF 327 | **/ 328 | i40e_status i40e_remove_pd_page_new(struct i40e_hw *hw, 329 | struct i40e_hmc_info *hmc_info, 330 | u32 idx, bool is_pf) 331 | { 332 | struct i40e_hmc_sd_entry *sd_entry; 333 | 334 | if (!is_pf) 335 | return I40E_NOT_SUPPORTED; 336 | 337 | sd_entry = &hmc_info->sd_table.sd_entry[idx]; 338 | I40E_CLEAR_PF_SD_ENTRY(hw, idx, I40E_SD_TYPE_PAGED); 339 | 340 | return i40e_free_dma_mem(hw, &(sd_entry->u.pd_table.pd_page_addr)); 341 | } 342 | -------------------------------------------------------------------------------- /src/i40e_hmc.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_HMC_H_ 5 | #define _I40E_HMC_H_ 6 | 7 | #define I40E_HMC_MAX_BP_COUNT 512 8 | 9 | /* forward-declare the HW struct for the compiler */ 10 | struct i40e_hw; 11 | 12 | #define I40E_HMC_INFO_SIGNATURE 0x484D5347 /* HMSG */ 13 | #define I40E_HMC_PD_CNT_IN_SD 512 14 | #define I40E_HMC_DIRECT_BP_SIZE 0x200000 /* 2M */ 15 | #define I40E_HMC_PAGED_BP_SIZE 4096 16 | #define I40E_HMC_PD_BP_BUF_ALIGNMENT 4096 17 | #define I40E_FIRST_VF_FPM_ID 16 18 | 19 | struct i40e_hmc_obj_info { 20 | u64 base; /* base addr in FPM */ 21 | u32 max_cnt; /* max count available for this hmc func */ 22 | u32 cnt; /* count of objects driver actually wants to create */ 23 | u64 size; /* size in bytes of one object */ 24 | }; 25 | 26 | enum i40e_sd_entry_type { 27 | I40E_SD_TYPE_INVALID = 0, 28 | I40E_SD_TYPE_PAGED = 1, 29 | I40E_SD_TYPE_DIRECT = 2 30 | }; 31 | 32 | struct i40e_hmc_bp { 33 | enum i40e_sd_entry_type entry_type; 34 | struct i40e_dma_mem addr; /* populate to be used by hw */ 35 | u32 sd_pd_index; 36 | u32 ref_cnt; 37 | }; 38 | 39 | struct i40e_hmc_pd_entry { 40 | struct i40e_hmc_bp bp; 41 | u32 sd_index; 42 | bool rsrc_pg; 43 | bool valid; 44 | }; 45 | 46 | struct i40e_hmc_pd_table { 47 | struct i40e_dma_mem pd_page_addr; /* populate to be used by hw */ 48 | struct i40e_hmc_pd_entry *pd_entry; /* [512] for sw book keeping */ 49 | struct i40e_virt_mem pd_entry_virt_mem; /* virt mem for pd_entry */ 50 | 51 | u32 ref_cnt; 52 | u32 sd_index; 53 | }; 54 | 55 | struct i40e_hmc_sd_entry { 56 | enum i40e_sd_entry_type entry_type; 57 | bool valid; 58 | 59 | union { 60 | struct i40e_hmc_pd_table pd_table; 61 | struct i40e_hmc_bp bp; 62 | } u; 63 | }; 64 | 65 | struct i40e_hmc_sd_table { 66 | struct i40e_virt_mem addr; /* used to track sd_entry allocations */ 67 | u32 sd_cnt; 68 | u32 ref_cnt; 69 | struct i40e_hmc_sd_entry *sd_entry; /* (sd_cnt*512) entries max */ 70 | }; 71 | 72 | struct i40e_hmc_info { 73 | u32 signature; 74 | /* equals to pci func num for PF and dynamically allocated for VFs */ 75 | u8 hmc_fn_id; 76 | u16 first_sd_index; /* index of the first available SD */ 77 | 78 | /* hmc objects */ 79 | struct i40e_hmc_obj_info *hmc_obj; 80 | struct i40e_virt_mem hmc_obj_virt_mem; 81 | struct i40e_hmc_sd_table sd_table; 82 | }; 83 | 84 | #define I40E_INC_SD_REFCNT(sd_table) ((sd_table)->ref_cnt++) 85 | #define I40E_INC_PD_REFCNT(pd_table) ((pd_table)->ref_cnt++) 86 | #define I40E_INC_BP_REFCNT(bp) ((bp)->ref_cnt++) 87 | 88 | #define I40E_DEC_SD_REFCNT(sd_table) ((sd_table)->ref_cnt--) 89 | #define I40E_DEC_PD_REFCNT(pd_table) ((pd_table)->ref_cnt--) 90 | #define I40E_DEC_BP_REFCNT(bp) ((bp)->ref_cnt--) 91 | 92 | /** 93 | * I40E_SET_PF_SD_ENTRY - marks the sd entry as valid in the hardware 94 | * @hw: pointer to our hw struct 95 | * @pa: pointer to physical address 96 | * @sd_index: segment descriptor index 97 | * @type: if sd entry is direct or paged 98 | **/ 99 | #define I40E_SET_PF_SD_ENTRY(hw, pa, sd_index, type) \ 100 | { \ 101 | u32 val1, val2, val3; \ 102 | val1 = (u32)(upper_32_bits(pa)); \ 103 | val2 = (u32)(pa) | (I40E_HMC_MAX_BP_COUNT << \ 104 | I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) | \ 105 | ((((type) == I40E_SD_TYPE_PAGED) ? 0 : 1) << \ 106 | I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT) | \ 107 | BIT(I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT); \ 108 | val3 = (sd_index) | BIT_ULL(I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \ 109 | wr32((hw), I40E_PFHMC_SDDATAHIGH, val1); \ 110 | wr32((hw), I40E_PFHMC_SDDATALOW, val2); \ 111 | wr32((hw), I40E_PFHMC_SDCMD, val3); \ 112 | } 113 | 114 | /** 115 | * I40E_CLEAR_PF_SD_ENTRY - marks the sd entry as invalid in the hardware 116 | * @hw: pointer to our hw struct 117 | * @sd_index: segment descriptor index 118 | * @type: if sd entry is direct or paged 119 | **/ 120 | #define I40E_CLEAR_PF_SD_ENTRY(hw, sd_index, type) \ 121 | { \ 122 | u32 val2, val3; \ 123 | val2 = (I40E_HMC_MAX_BP_COUNT << \ 124 | I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) | \ 125 | ((((type) == I40E_SD_TYPE_PAGED) ? 0 : 1) << \ 126 | I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT); \ 127 | val3 = (sd_index) | BIT_ULL(I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \ 128 | wr32((hw), I40E_PFHMC_SDDATAHIGH, 0); \ 129 | wr32((hw), I40E_PFHMC_SDDATALOW, val2); \ 130 | wr32((hw), I40E_PFHMC_SDCMD, val3); \ 131 | } 132 | 133 | /** 134 | * I40E_INVALIDATE_PF_HMC_PD - Invalidates the pd cache in the hardware 135 | * @hw: pointer to our hw struct 136 | * @sd_idx: segment descriptor index 137 | * @pd_idx: page descriptor index 138 | **/ 139 | #define I40E_INVALIDATE_PF_HMC_PD(hw, sd_idx, pd_idx) \ 140 | wr32((hw), I40E_PFHMC_PDINV, \ 141 | (((sd_idx) << I40E_PFHMC_PDINV_PMSDIDX_SHIFT) | \ 142 | ((pd_idx) << I40E_PFHMC_PDINV_PMPDIDX_SHIFT))) 143 | 144 | /** 145 | * I40E_FIND_SD_INDEX_LIMIT - finds segment descriptor index limit 146 | * @hmc_info: pointer to the HMC configuration information structure 147 | * @type: type of HMC resources we're searching 148 | * @index: starting index for the object 149 | * @cnt: number of objects we're trying to create 150 | * @sd_idx: pointer to return index of the segment descriptor in question 151 | * @sd_limit: pointer to return the maximum number of segment descriptors 152 | * 153 | * This function calculates the segment descriptor index and index limit 154 | * for the resource defined by i40e_hmc_rsrc_type. 155 | **/ 156 | #define I40E_FIND_SD_INDEX_LIMIT(hmc_info, type, index, cnt, sd_idx, sd_limit)\ 157 | { \ 158 | u64 fpm_addr, fpm_limit; \ 159 | fpm_addr = (hmc_info)->hmc_obj[(type)].base + \ 160 | (hmc_info)->hmc_obj[(type)].size * (index); \ 161 | fpm_limit = fpm_addr + (hmc_info)->hmc_obj[(type)].size * (cnt);\ 162 | *(sd_idx) = (u32)(fpm_addr / I40E_HMC_DIRECT_BP_SIZE); \ 163 | *(sd_limit) = (u32)((fpm_limit - 1) / I40E_HMC_DIRECT_BP_SIZE); \ 164 | /* add one more to the limit to correct our range */ \ 165 | *(sd_limit) += 1; \ 166 | } 167 | 168 | /** 169 | * I40E_FIND_PD_INDEX_LIMIT - finds page descriptor index limit 170 | * @hmc_info: pointer to the HMC configuration information struct 171 | * @type: HMC resource type we're examining 172 | * @idx: starting index for the object 173 | * @cnt: number of objects we're trying to create 174 | * @pd_index: pointer to return page descriptor index 175 | * @pd_limit: pointer to return page descriptor index limit 176 | * 177 | * Calculates the page descriptor index and index limit for the resource 178 | * defined by i40e_hmc_rsrc_type. 179 | **/ 180 | #define I40E_FIND_PD_INDEX_LIMIT(hmc_info, type, idx, cnt, pd_index, pd_limit)\ 181 | { \ 182 | u64 fpm_adr, fpm_limit; \ 183 | fpm_adr = (hmc_info)->hmc_obj[(type)].base + \ 184 | (hmc_info)->hmc_obj[(type)].size * (idx); \ 185 | fpm_limit = fpm_adr + (hmc_info)->hmc_obj[(type)].size * (cnt); \ 186 | *(pd_index) = (u32)(fpm_adr / I40E_HMC_PAGED_BP_SIZE); \ 187 | *(pd_limit) = (u32)((fpm_limit - 1) / I40E_HMC_PAGED_BP_SIZE); \ 188 | /* add one more to the limit to correct our range */ \ 189 | *(pd_limit) += 1; \ 190 | } 191 | i40e_status i40e_add_sd_table_entry(struct i40e_hw *hw, 192 | struct i40e_hmc_info *hmc_info, 193 | u32 sd_index, 194 | enum i40e_sd_entry_type type, 195 | u64 direct_mode_sz); 196 | 197 | i40e_status i40e_add_pd_table_entry(struct i40e_hw *hw, 198 | struct i40e_hmc_info *hmc_info, 199 | u32 pd_index, 200 | struct i40e_dma_mem *rsrc_pg); 201 | i40e_status i40e_remove_pd_bp(struct i40e_hw *hw, 202 | struct i40e_hmc_info *hmc_info, 203 | u32 idx); 204 | i40e_status i40e_prep_remove_sd_bp(struct i40e_hmc_info *hmc_info, 205 | u32 idx); 206 | i40e_status i40e_remove_sd_bp_new(struct i40e_hw *hw, 207 | struct i40e_hmc_info *hmc_info, 208 | u32 idx, bool is_pf); 209 | i40e_status i40e_prep_remove_pd_page(struct i40e_hmc_info *hmc_info, 210 | u32 idx); 211 | i40e_status i40e_remove_pd_page_new(struct i40e_hw *hw, 212 | struct i40e_hmc_info *hmc_info, 213 | u32 idx, bool is_pf); 214 | 215 | #endif /* _I40E_HMC_H_ */ 216 | -------------------------------------------------------------------------------- /src/i40e_lan_hmc.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_LAN_HMC_H_ 5 | #define _I40E_LAN_HMC_H_ 6 | 7 | /* forward-declare the HW struct for the compiler */ 8 | struct i40e_hw; 9 | 10 | /* HMC element context information */ 11 | 12 | /* Rx queue context data 13 | * 14 | * The sizes of the variables may be larger than needed due to crossing byte 15 | * boundaries. If we do not have the width of the variable set to the correct 16 | * size then we could end up shifting bits off the top of the variable when the 17 | * variable is at the top of a byte and crosses over into the next byte. 18 | */ 19 | struct i40e_hmc_obj_rxq { 20 | u16 head; 21 | u16 cpuid; /* bigger than needed, see above for reason */ 22 | u64 base; 23 | u16 qlen; 24 | #define I40E_RXQ_CTX_DBUFF_SHIFT 7 25 | u16 dbuff; /* bigger than needed, see above for reason */ 26 | #define I40E_RXQ_CTX_HBUFF_SHIFT 6 27 | u16 hbuff; /* bigger than needed, see above for reason */ 28 | u8 dtype; 29 | u8 dsize; 30 | u8 crcstrip; 31 | u8 fc_ena; 32 | u8 l2tsel; 33 | u8 hsplit_0; 34 | u8 hsplit_1; 35 | u8 showiv; 36 | u32 rxmax; /* bigger than needed, see above for reason */ 37 | u8 tphrdesc_ena; 38 | u8 tphwdesc_ena; 39 | u8 tphdata_ena; 40 | u8 tphhead_ena; 41 | u16 lrxqthresh; /* bigger than needed, see above for reason */ 42 | u8 prefena; /* NOTE: normally must be set to 1 at init */ 43 | }; 44 | 45 | /* Tx queue context data 46 | * 47 | * The sizes of the variables may be larger than needed due to crossing byte 48 | * boundaries. If we do not have the width of the variable set to the correct 49 | * size then we could end up shifting bits off the top of the variable when the 50 | * variable is at the top of a byte and crosses over into the next byte. 51 | */ 52 | struct i40e_hmc_obj_txq { 53 | u16 head; 54 | u8 new_context; 55 | u64 base; 56 | u8 fc_ena; 57 | u8 timesync_ena; 58 | u8 fd_ena; 59 | u8 alt_vlan_ena; 60 | u16 thead_wb; 61 | u8 cpuid; 62 | u8 head_wb_ena; 63 | u16 qlen; 64 | u8 tphrdesc_ena; 65 | u8 tphrpacket_ena; 66 | u8 tphwdesc_ena; 67 | u64 head_wb_addr; 68 | u32 crc; 69 | u16 rdylist; 70 | u8 rdylist_act; 71 | }; 72 | 73 | /* for hsplit_0 field of Rx HMC context */ 74 | enum i40e_hmc_obj_rx_hsplit_0 { 75 | I40E_HMC_OBJ_RX_HSPLIT_0_NO_SPLIT = 0, 76 | I40E_HMC_OBJ_RX_HSPLIT_0_SPLIT_L2 = 1, 77 | I40E_HMC_OBJ_RX_HSPLIT_0_SPLIT_IP = 2, 78 | I40E_HMC_OBJ_RX_HSPLIT_0_SPLIT_TCP_UDP = 4, 79 | I40E_HMC_OBJ_RX_HSPLIT_0_SPLIT_SCTP = 8, 80 | }; 81 | 82 | /* fcoe_cntx and fcoe_filt are for debugging purpose only */ 83 | struct i40e_hmc_obj_fcoe_cntx { 84 | u32 rsv[32]; 85 | }; 86 | 87 | struct i40e_hmc_obj_fcoe_filt { 88 | u32 rsv[8]; 89 | }; 90 | 91 | /* Context sizes for LAN objects */ 92 | enum i40e_hmc_lan_object_size { 93 | I40E_HMC_LAN_OBJ_SZ_8 = 0x3, 94 | I40E_HMC_LAN_OBJ_SZ_16 = 0x4, 95 | I40E_HMC_LAN_OBJ_SZ_32 = 0x5, 96 | I40E_HMC_LAN_OBJ_SZ_64 = 0x6, 97 | I40E_HMC_LAN_OBJ_SZ_128 = 0x7, 98 | I40E_HMC_LAN_OBJ_SZ_256 = 0x8, 99 | I40E_HMC_LAN_OBJ_SZ_512 = 0x9, 100 | }; 101 | 102 | #define I40E_HMC_L2OBJ_BASE_ALIGNMENT 512 103 | #define I40E_HMC_OBJ_SIZE_TXQ 128 104 | #define I40E_HMC_OBJ_SIZE_RXQ 32 105 | #define I40E_HMC_OBJ_SIZE_FCOE_CNTX 64 106 | #define I40E_HMC_OBJ_SIZE_FCOE_FILT 64 107 | 108 | enum i40e_hmc_lan_rsrc_type { 109 | I40E_HMC_LAN_FULL = 0, 110 | I40E_HMC_LAN_TX = 1, 111 | I40E_HMC_LAN_RX = 2, 112 | I40E_HMC_FCOE_CTX = 3, 113 | I40E_HMC_FCOE_FILT = 4, 114 | I40E_HMC_LAN_MAX = 5 115 | }; 116 | 117 | enum i40e_hmc_model { 118 | I40E_HMC_MODEL_DIRECT_PREFERRED = 0, 119 | I40E_HMC_MODEL_DIRECT_ONLY = 1, 120 | I40E_HMC_MODEL_PAGED_ONLY = 2, 121 | I40E_HMC_MODEL_UNKNOWN, 122 | }; 123 | 124 | struct i40e_hmc_lan_create_obj_info { 125 | struct i40e_hmc_info *hmc_info; 126 | u32 rsrc_type; 127 | u32 start_idx; 128 | u32 count; 129 | enum i40e_sd_entry_type entry_type; 130 | u64 direct_mode_sz; 131 | }; 132 | 133 | struct i40e_hmc_lan_delete_obj_info { 134 | struct i40e_hmc_info *hmc_info; 135 | u32 rsrc_type; 136 | u32 start_idx; 137 | u32 count; 138 | }; 139 | 140 | i40e_status i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num, 141 | u32 rxq_num, u32 fcoe_cntx_num, 142 | u32 fcoe_filt_num); 143 | i40e_status i40e_configure_lan_hmc(struct i40e_hw *hw, 144 | enum i40e_hmc_model model); 145 | i40e_status i40e_shutdown_lan_hmc(struct i40e_hw *hw); 146 | 147 | i40e_status i40e_clear_lan_tx_queue_context(struct i40e_hw *hw, 148 | u16 queue); 149 | i40e_status i40e_set_lan_tx_queue_context(struct i40e_hw *hw, 150 | u16 queue, 151 | struct i40e_hmc_obj_txq *s); 152 | i40e_status i40e_clear_lan_rx_queue_context(struct i40e_hw *hw, 153 | u16 queue); 154 | i40e_status i40e_set_lan_rx_queue_context(struct i40e_hw *hw, 155 | u16 queue, 156 | struct i40e_hmc_obj_rxq *s); 157 | 158 | #endif /* _I40E_LAN_HMC_H_ */ 159 | -------------------------------------------------------------------------------- /src/i40e_osdep.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_OSDEP_H_ 5 | #define _I40E_OSDEP_H_ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #ifndef readq 18 | static inline __u64 readq(const volatile void __iomem *addr) 19 | { 20 | const volatile u32 __iomem *p = addr; 21 | u32 low, high; 22 | 23 | low = readl(p); 24 | high = readl(p + 1); 25 | 26 | return low + ((u64)high << 32); 27 | } 28 | #endif 29 | 30 | #ifndef writeq 31 | static inline void writeq(__u64 val, volatile void __iomem *addr) 32 | { 33 | writel(val, addr); 34 | writel(val >> 32, addr + 4); 35 | } 36 | #endif 37 | #include "kcompat.h" 38 | 39 | /* File to be the magic between shared code and 40 | * actual OS primitives 41 | */ 42 | 43 | #define hw_dbg(h, s, ...) do { \ 44 | pr_debug("i40e %02x:%02x.%x " s, \ 45 | (h)->bus.bus_id, (h)->bus.device, \ 46 | (h)->bus.func, ##__VA_ARGS__); \ 47 | } while (0) 48 | 49 | #define wr32(a, reg, value) writel((value), ((a)->hw_addr + (reg))) 50 | #define rd32(a, reg) readl((a)->hw_addr + (reg)) 51 | 52 | #define wr64(a, reg, value) writeq((value), ((a)->hw_addr + (reg))) 53 | #define rd64(a, reg) readq((a)->hw_addr + (reg)) 54 | #define i40e_flush(a) readl((a)->hw_addr + I40E_GLGEN_STAT) 55 | /* memory allocation tracking */ 56 | struct i40e_dma_mem { 57 | void *va; 58 | dma_addr_t pa; 59 | u32 size; 60 | }; 61 | 62 | struct i40e_virt_mem { 63 | void *va; 64 | u32 size; 65 | }; 66 | 67 | #define i40e_debug(h, m, s, ...) \ 68 | do { \ 69 | if (((m) & (h)->debug_mask)) \ 70 | pr_info("i40e %02x:%02x.%x " s, \ 71 | (h)->bus.bus_id, (h)->bus.device, \ 72 | (h)->bus.func, ##__VA_ARGS__); \ 73 | } while (0) 74 | 75 | /* these things are all directly replaced with sed during the kernel build */ 76 | #define INLINE inline 77 | 78 | #define CPU_TO_LE16(o) cpu_to_le16(o) 79 | #define CPU_TO_LE32(s) cpu_to_le32(s) 80 | #define CPU_TO_LE64(h) cpu_to_le64(h) 81 | #define LE16_TO_CPU(a) le16_to_cpu(a) 82 | #define LE32_TO_CPU(c) le32_to_cpu(c) 83 | #define LE64_TO_CPU(k) le64_to_cpu(k) 84 | 85 | /* SW spinlock */ 86 | struct i40e_spinlock { 87 | struct mutex spinlock; 88 | }; 89 | 90 | static inline void i40e_no_action(struct i40e_spinlock *sp) 91 | { 92 | /* nothing */ 93 | } 94 | 95 | /* the locks are initialized in _probe and destroyed in _remove 96 | * so make sure NOT to implement init/destroy here, as to 97 | * avoid the i40e_init_adminq code trying to reinitialize 98 | * the persistent lock memory 99 | */ 100 | #define i40e_init_spinlock(_sp) i40e_no_action(_sp) 101 | #define i40e_acquire_spinlock(_sp) i40e_acquire_spinlock_d(_sp) 102 | #define i40e_release_spinlock(_sp) i40e_release_spinlock_d(_sp) 103 | #define i40e_destroy_spinlock(_sp) i40e_no_action(_sp) 104 | 105 | #define i40e_memset(a, b, c, d) memset((a), (b), (c)) 106 | #define i40e_memcpy(a, b, c, d) memcpy((a), (b), (c)) 107 | 108 | typedef enum i40e_status_code i40e_status; 109 | #endif /* _I40E_OSDEP_H_ */ 110 | -------------------------------------------------------------------------------- /src/i40e_status.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_STATUS_H_ 5 | #define _I40E_STATUS_H_ 6 | 7 | /* Error Codes */ 8 | enum i40e_status_code { 9 | I40E_SUCCESS = 0, 10 | I40E_ERR_NVM = -1, 11 | I40E_ERR_NVM_CHECKSUM = -2, 12 | I40E_ERR_PHY = -3, 13 | I40E_ERR_CONFIG = -4, 14 | I40E_ERR_PARAM = -5, 15 | I40E_ERR_MAC_TYPE = -6, 16 | I40E_ERR_UNKNOWN_PHY = -7, 17 | I40E_ERR_LINK_SETUP = -8, 18 | I40E_ERR_ADAPTER_STOPPED = -9, 19 | I40E_ERR_INVALID_MAC_ADDR = -10, 20 | I40E_ERR_DEVICE_NOT_SUPPORTED = -11, 21 | I40E_ERR_PRIMARY_REQUESTS_PENDING = -12, 22 | I40E_ERR_INVALID_LINK_SETTINGS = -13, 23 | I40E_ERR_AUTONEG_NOT_COMPLETE = -14, 24 | I40E_ERR_RESET_FAILED = -15, 25 | I40E_ERR_SWFW_SYNC = -16, 26 | I40E_ERR_NO_AVAILABLE_VSI = -17, 27 | I40E_ERR_NO_MEMORY = -18, 28 | I40E_ERR_BAD_PTR = -19, 29 | I40E_ERR_RING_FULL = -20, 30 | I40E_ERR_INVALID_PD_ID = -21, 31 | I40E_ERR_INVALID_QP_ID = -22, 32 | I40E_ERR_INVALID_CQ_ID = -23, 33 | I40E_ERR_INVALID_CEQ_ID = -24, 34 | I40E_ERR_INVALID_AEQ_ID = -25, 35 | I40E_ERR_INVALID_SIZE = -26, 36 | I40E_ERR_INVALID_ARP_INDEX = -27, 37 | I40E_ERR_INVALID_FPM_FUNC_ID = -28, 38 | I40E_ERR_QP_INVALID_MSG_SIZE = -29, 39 | I40E_ERR_QP_TOOMANY_WRS_POSTED = -30, 40 | I40E_ERR_INVALID_FRAG_COUNT = -31, 41 | I40E_ERR_QUEUE_EMPTY = -32, 42 | I40E_ERR_INVALID_ALIGNMENT = -33, 43 | I40E_ERR_FLUSHED_QUEUE = -34, 44 | I40E_ERR_INVALID_PUSH_PAGE_INDEX = -35, 45 | I40E_ERR_INVALID_IMM_DATA_SIZE = -36, 46 | I40E_ERR_TIMEOUT = -37, 47 | I40E_ERR_OPCODE_MISMATCH = -38, 48 | I40E_ERR_CQP_COMPL_ERROR = -39, 49 | I40E_ERR_INVALID_VF_ID = -40, 50 | I40E_ERR_INVALID_HMCFN_ID = -41, 51 | I40E_ERR_BACKING_PAGE_ERROR = -42, 52 | I40E_ERR_NO_PBLCHUNKS_AVAILABLE = -43, 53 | I40E_ERR_INVALID_PBLE_INDEX = -44, 54 | I40E_ERR_INVALID_SD_INDEX = -45, 55 | I40E_ERR_INVALID_PAGE_DESC_INDEX = -46, 56 | I40E_ERR_INVALID_SD_TYPE = -47, 57 | I40E_ERR_MEMCPY_FAILED = -48, 58 | I40E_ERR_INVALID_HMC_OBJ_INDEX = -49, 59 | I40E_ERR_INVALID_HMC_OBJ_COUNT = -50, 60 | I40E_ERR_INVALID_SRQ_ARM_LIMIT = -51, 61 | I40E_ERR_SRQ_ENABLED = -52, 62 | I40E_ERR_ADMIN_QUEUE_ERROR = -53, 63 | I40E_ERR_ADMIN_QUEUE_TIMEOUT = -54, 64 | I40E_ERR_BUF_TOO_SHORT = -55, 65 | I40E_ERR_ADMIN_QUEUE_FULL = -56, 66 | I40E_ERR_ADMIN_QUEUE_NO_WORK = -57, 67 | I40E_ERR_BAD_IWARP_CQE = -58, 68 | I40E_ERR_NVM_BLANK_MODE = -59, 69 | I40E_ERR_NOT_IMPLEMENTED = -60, 70 | I40E_ERR_PE_DOORBELL_NOT_ENABLED = -61, 71 | I40E_ERR_DIAG_TEST_FAILED = -62, 72 | I40E_ERR_NOT_READY = -63, 73 | I40E_NOT_SUPPORTED = -64, 74 | I40E_ERR_FIRMWARE_API_VERSION = -65, 75 | I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR = -66, 76 | }; 77 | 78 | #endif /* _I40E_STATUS_H_ */ 79 | -------------------------------------------------------------------------------- /src/i40e_trace.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef CONFIG_TRACEPOINTS 5 | #if !defined(_I40E_TRACE_H_) 6 | #define _I40E_TRACE_H_ 7 | /* If the Linux kernel tracepoints are not available then the i40e_trace* 8 | * macros become nops. 9 | */ 10 | 11 | #define i40e_trace(trace_name, args...) 12 | #define i40e_trace_enabled(trace_name) (0) 13 | #endif /* !defined(_I40E_TRACE_H_) */ 14 | #else /* CONFIG_TRACEPOINTS */ 15 | /* 16 | * Modeled on trace-events-sample.h 17 | */ 18 | 19 | /* 20 | * This file is named i40e_trace.h. 21 | * 22 | * Since this include file's name is different from the trace 23 | * subsystem name, we'll have to define TRACE_INCLUDE_FILE at the end 24 | * of this file. 25 | */ 26 | #undef TRACE_SYSTEM 27 | #define TRACE_SYSTEM i40e 28 | 29 | /* 30 | * See trace-events-sample.h for a detailed description of why this 31 | * guard clause is different from most normal include files. 32 | */ 33 | #if !defined(_I40E_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) 34 | #define _I40E_TRACE_H_ 35 | 36 | #include 37 | 38 | /* 39 | * i40e_trace() macro enables shared code to refer to trace points 40 | * like: 41 | * 42 | * trace_i40e{,vf}_example(args...) 43 | * 44 | * ... as: 45 | * 46 | * i40e_trace(example, args...) 47 | * 48 | * ... to resolve to the PF or VF version of the tracepoint without 49 | * ifdefs, and to allow tracepoints to be disabled entirely at build 50 | * time. 51 | * 52 | * Trace point should always be referred to in the driver via this 53 | * macro. 54 | * 55 | * Similarly, i40e_trace_enabled(trace_name) wraps references to 56 | * trace_i40e{,vf}__enabled() functions. 57 | */ 58 | #define _I40E_TRACE_NAME(trace_name) (trace_ ## i40e ## _ ## trace_name) 59 | #define I40E_TRACE_NAME(trace_name) _I40E_TRACE_NAME(trace_name) 60 | 61 | #define i40e_trace(trace_name, args...) I40E_TRACE_NAME(trace_name)(args) 62 | 63 | #define i40e_trace_enabled(trace_name) I40E_TRACE_NAME(trace_name##_enabled)() 64 | 65 | /* 66 | * Events common to PF and VF. Corresponding versions will be defined 67 | * for both, named trace_i40e_* and trace_i40evf_*. The i40e_trace() 68 | * macro above will select the right trace point name for the driver 69 | * being built from shared code. 70 | */ 71 | 72 | /* Events related to a vsi & ring */ 73 | DECLARE_EVENT_CLASS( 74 | i40e_tx_template, 75 | TP_PROTO(struct i40e_ring *ring, 76 | struct i40e_tx_desc *desc, 77 | struct i40e_tx_buffer *buf), 78 | TP_ARGS(ring, desc, buf), 79 | /* 80 | * The convention here is to make the first fields in the 81 | * TP_STRUCT match the TP_PROTO exactly. This enables the use 82 | * of the args struct generated by the tplist tool (from the 83 | * bcc-tools package) to be used for those fields. To access 84 | * fields other than the tracepoint args will require the 85 | * tplist output to be adjusted. 86 | */ 87 | TP_STRUCT__entry( 88 | __field(void*, ring) 89 | __field(void*, desc) 90 | __field(void*, buf) 91 | __string(devname, ring->netdev->name)) 92 | , 93 | TP_fast_assign( 94 | __entry->ring = ring; 95 | __entry->desc = desc; 96 | __entry->buf = buf; 97 | _kc__assign_str(devname, ring->netdev->name);) 98 | , 99 | TP_printk( 100 | "netdev: %s ring: %p desc: %p buf %p", 101 | __get_str(devname), __entry->ring, 102 | __entry->desc, __entry->buf)); 103 | 104 | DEFINE_EVENT( 105 | i40e_tx_template, i40e_clean_tx_irq, 106 | TP_PROTO(struct i40e_ring *ring, 107 | struct i40e_tx_desc *desc, 108 | struct i40e_tx_buffer *buf), 109 | TP_ARGS(ring, desc, buf)); 110 | 111 | DEFINE_EVENT( 112 | i40e_tx_template, i40e_clean_tx_irq_unmap, 113 | TP_PROTO(struct i40e_ring *ring, 114 | struct i40e_tx_desc *desc, 115 | struct i40e_tx_buffer *buf), 116 | TP_ARGS(ring, desc, buf)); 117 | 118 | DECLARE_EVENT_CLASS( 119 | i40e_rx_template, 120 | TP_PROTO(struct i40e_ring *ring, 121 | union i40e_rx_desc *desc, 122 | struct sk_buff *skb), 123 | TP_ARGS(ring, desc, skb), 124 | TP_STRUCT__entry( 125 | __field(void*, ring) 126 | __field(void*, desc) 127 | __field(void*, skb) 128 | __string(devname, ring->netdev->name)) 129 | , 130 | TP_fast_assign( 131 | __entry->ring = ring; 132 | __entry->desc = desc; 133 | __entry->skb = skb; 134 | _kc__assign_str(devname, ring->netdev->name);) 135 | , 136 | TP_printk( 137 | "netdev: %s ring: %p desc: %p skb %p", 138 | __get_str(devname), __entry->ring, 139 | __entry->desc, __entry->skb)); 140 | 141 | DEFINE_EVENT( 142 | i40e_rx_template, i40e_clean_rx_irq, 143 | TP_PROTO(struct i40e_ring *ring, 144 | union i40e_rx_desc *desc, 145 | struct sk_buff *skb), 146 | TP_ARGS(ring, desc, skb)); 147 | 148 | DEFINE_EVENT( 149 | i40e_rx_template, i40e_clean_rx_irq_rx, 150 | TP_PROTO(struct i40e_ring *ring, 151 | union i40e_rx_desc *desc, 152 | struct sk_buff *skb), 153 | TP_ARGS(ring, desc, skb)); 154 | 155 | DECLARE_EVENT_CLASS( 156 | i40e_xmit_template, 157 | TP_PROTO(struct sk_buff *skb, 158 | struct i40e_ring *ring), 159 | TP_ARGS(skb, ring), 160 | TP_STRUCT__entry( 161 | __field(void*, skb) 162 | __field(void*, ring) 163 | __string(devname, ring->netdev->name)) 164 | , 165 | TP_fast_assign( 166 | __entry->skb = skb; 167 | __entry->ring = ring; 168 | _kc__assign_str(devname, ring->netdev->name);) 169 | , 170 | TP_printk( 171 | "netdev: %s skb: %p ring: %p", 172 | __get_str(devname), __entry->skb, 173 | __entry->ring)); 174 | 175 | DEFINE_EVENT( 176 | i40e_xmit_template, i40e_xmit_frame_ring, 177 | TP_PROTO(struct sk_buff *skb, 178 | struct i40e_ring *ring), 179 | TP_ARGS(skb, ring)); 180 | 181 | DEFINE_EVENT( 182 | i40e_xmit_template, i40e_xmit_frame_ring_drop, 183 | TP_PROTO(struct sk_buff *skb, 184 | struct i40e_ring *ring), 185 | TP_ARGS(skb, ring)); 186 | 187 | /* 188 | * Events unique to the PF. 189 | */ 190 | DECLARE_EVENT_CLASS( 191 | i40e_state_template, 192 | TP_PROTO(struct i40e_pf *pf, u64 val), 193 | TP_ARGS(pf, val), 194 | TP_STRUCT__entry( 195 | __field(u64, val) 196 | __field(u64, state) 197 | __field(u64, bus)) 198 | , 199 | TP_fast_assign( 200 | __entry->val = val; 201 | __entry->state = *(u64 *)pf->state; 202 | __entry->bus = (((u64)pf->hw.bus.bus_id) << 32) | 203 | (((u64)pf->hw.bus.device) << 16) | pf->hw.bus.func;) 204 | , 205 | TP_printk( 206 | "state: bus %02x:%02x.%1x state=%016llx val=%llx", 207 | (unsigned int)(__entry->bus >> 32), 208 | 0xffff & (unsigned int)(__entry->bus >> 16), 209 | 0xffff & (unsigned int)__entry->bus, 210 | __entry->state, __entry->val)); 211 | 212 | DEFINE_EVENT( 213 | i40e_state_template, i40e_state_reset, 214 | TP_PROTO(struct i40e_pf *pf, u64 val), 215 | TP_ARGS(pf, val)); 216 | 217 | DEFINE_EVENT( 218 | i40e_state_template, i40e_state_reset_pci_prepare, 219 | TP_PROTO(struct i40e_pf *pf, u64 val), 220 | TP_ARGS(pf, val)); 221 | 222 | DEFINE_EVENT( 223 | i40e_state_template, i40e_state_reset_pci_done, 224 | TP_PROTO(struct i40e_pf *pf, u64 val), 225 | TP_ARGS(pf, val)); 226 | 227 | DEFINE_EVENT( 228 | i40e_state_template, i40e_state_reset_corer, 229 | TP_PROTO(struct i40e_pf *pf, u64 val), 230 | TP_ARGS(pf, val)); 231 | 232 | DEFINE_EVENT( 233 | i40e_state_template, i40e_state_reset_globr, 234 | TP_PROTO(struct i40e_pf *pf, u64 val), 235 | TP_ARGS(pf, val)); 236 | 237 | DEFINE_EVENT( 238 | i40e_state_template, i40e_state_reset_empr, 239 | TP_PROTO(struct i40e_pf *pf, u64 val), 240 | TP_ARGS(pf, val)); 241 | 242 | DEFINE_EVENT( 243 | i40e_state_template, i40e_state_hmc_error, 244 | TP_PROTO(struct i40e_pf *pf, u64 val), 245 | TP_ARGS(pf, val)); 246 | 247 | DEFINE_EVENT( 248 | i40e_state_template, i40e_state_rebuild, 249 | TP_PROTO(struct i40e_pf *pf, u64 val), 250 | TP_ARGS(pf, val)); 251 | 252 | DEFINE_EVENT( 253 | i40e_state_template, i40e_state_arq, 254 | TP_PROTO(struct i40e_pf *pf, u64 val), 255 | TP_ARGS(pf, val)); 256 | 257 | DEFINE_EVENT( 258 | i40e_state_template, i40e_state_asq, 259 | TP_PROTO(struct i40e_pf *pf, u64 val), 260 | TP_ARGS(pf, val)); 261 | 262 | DEFINE_EVENT( 263 | i40e_state_template, i40e_state_udp_sync, 264 | TP_PROTO(struct i40e_pf *pf, u64 val), 265 | TP_ARGS(pf, val)); 266 | 267 | DEFINE_EVENT( 268 | i40e_state_template, i40e_state_watchdog, 269 | TP_PROTO(struct i40e_pf *pf, u64 val), 270 | TP_ARGS(pf, val)); 271 | 272 | DEFINE_EVENT( 273 | i40e_state_template, i40e_state_link, 274 | TP_PROTO(struct i40e_pf *pf, u64 val), 275 | TP_ARGS(pf, val)); 276 | 277 | DEFINE_EVENT( 278 | i40e_state_template, i40e_state_recovery, 279 | TP_PROTO(struct i40e_pf *pf, u64 val), 280 | TP_ARGS(pf, val)); 281 | 282 | DECLARE_EVENT_CLASS( 283 | i40e_ioctl_template, 284 | TP_PROTO(struct i40e_pf *pf, u64 val), 285 | TP_ARGS(pf, val), 286 | TP_STRUCT__entry( 287 | __field(u64, val) 288 | __field(u64, state) 289 | __field(u64, bus) 290 | __field(pid_t, pid) 291 | __array(char, comm, TASK_COMM_LEN)) 292 | , 293 | TP_fast_assign( 294 | __entry->val = val; 295 | __entry->state = *(u64 *)pf->state; 296 | __entry->bus = (((u64)pf->hw.bus.bus_id) << 32) | 297 | (((u64)pf->hw.bus.device) << 16) | pf->hw.bus.func; 298 | __entry->pid = current->pid; 299 | memcpy(__entry->comm, current->comm, sizeof(__entry->comm) - 1); 300 | __entry->comm[TASK_COMM_LEN - 1] = 0;) 301 | , 302 | TP_printk( 303 | "state: bus %02x:%02x.%1x state=%016llx val=%llx %5d:%s", 304 | (unsigned int)(__entry->bus >> 32), 305 | 0xffff & (unsigned int)(__entry->bus >> 16), 306 | 0xffff & (unsigned int)__entry->bus, 307 | __entry->state, __entry->val, 308 | __entry->pid, __entry->comm)); 309 | 310 | DEFINE_EVENT( 311 | i40e_ioctl_template, i40e_ioctl_get_drvinfo, 312 | TP_PROTO(struct i40e_pf *pf, u64 val), 313 | TP_ARGS(pf, val)); 314 | 315 | DEFINE_EVENT( 316 | i40e_ioctl_template, i40e_ioctl_get_eeprom_len, 317 | TP_PROTO(struct i40e_pf *pf, u64 val), 318 | TP_ARGS(pf, val)); 319 | 320 | DEFINE_EVENT( 321 | i40e_ioctl_template, i40e_ioctl_get_eeprom, 322 | TP_PROTO(struct i40e_pf *pf, u64 val), 323 | TP_ARGS(pf, val)); 324 | 325 | DEFINE_EVENT( 326 | i40e_ioctl_template, i40e_ioctl_set_eeprom, 327 | TP_PROTO(struct i40e_pf *pf, u64 val), 328 | TP_ARGS(pf, val)); 329 | 330 | DEFINE_EVENT( 331 | i40e_ioctl_template, i40e_ioctl_get_module_info, 332 | TP_PROTO(struct i40e_pf *pf, u64 val), 333 | TP_ARGS(pf, val)); 334 | 335 | DEFINE_EVENT( 336 | i40e_ioctl_template, i40e_ioctl_get_module_eeprom, 337 | TP_PROTO(struct i40e_pf *pf, u64 val), 338 | TP_ARGS(pf, val)); 339 | 340 | DEFINE_EVENT( 341 | i40e_ioctl_template, i40e_ioctl_get_link_ksettings, 342 | TP_PROTO(struct i40e_pf *pf, u64 val), 343 | TP_ARGS(pf, val)); 344 | 345 | DECLARE_EVENT_CLASS( 346 | i40e_nvmupd_template, 347 | TP_PROTO(struct i40e_hw *hw, 348 | struct i40e_nvm_access *cmd, int ret_val, int err), 349 | TP_ARGS(hw, cmd, ret_val, err), 350 | TP_STRUCT__entry( 351 | __field(int, ret_val) 352 | __field(int, err) 353 | __field(int, status) 354 | __field(u64, bus) 355 | __field(u32, command) 356 | __field(u32, config) 357 | __field(u32, offset) 358 | __field(u32, data_size)) 359 | , 360 | TP_fast_assign( 361 | __entry->ret_val = ret_val; 362 | __entry->err = err; 363 | __entry->status = hw->aq.asq_last_status; 364 | __entry->bus = (((u64)hw->bus.bus_id) << 32) | 365 | (((u64)hw->bus.device) << 16) | hw->bus.func; 366 | __entry->command = cmd->command; 367 | __entry->config = cmd->config; 368 | __entry->offset = cmd->offset; 369 | __entry->data_size = cmd->data_size;) 370 | , 371 | TP_printk( 372 | "nvmupd: bus %02x:%02x.%1x err=%d status=0x%x errno=%d module=%d offset=0x%x size=%d", 373 | (unsigned int)(__entry->bus >> 32), 374 | 0xffff & (unsigned int)(__entry->bus >> 16), 375 | 0xffff & (unsigned int)__entry->bus, 376 | __entry->ret_val, __entry->status, __entry->err, 377 | (__entry->config & I40E_NVM_MOD_PNT_MASK), 378 | __entry->offset, __entry->data_size)); 379 | 380 | DEFINE_EVENT( 381 | i40e_nvmupd_template, i40e_nvmupd_write, 382 | TP_PROTO(struct i40e_hw *hw, 383 | struct i40e_nvm_access *cmd, int ret_val, int err), 384 | TP_ARGS(hw, cmd, ret_val, err)); 385 | 386 | DEFINE_EVENT( 387 | i40e_nvmupd_template, i40e_nvmupd_read, 388 | TP_PROTO(struct i40e_hw *hw, 389 | struct i40e_nvm_access *cmd, int ret_val, int err), 390 | TP_ARGS(hw, cmd, ret_val, err)); 391 | 392 | #endif /* _I40E_TRACE_H_ */ 393 | /* This must be outside ifdef _I40E_TRACE_H */ 394 | 395 | /* This trace include file is not located in the .../include/trace 396 | * with the kernel tracepoint definitions, because we're a loadable 397 | * module. 398 | */ 399 | #undef TRACE_INCLUDE_PATH 400 | #define TRACE_INCLUDE_PATH . 401 | #undef TRACE_INCLUDE_FILE 402 | #define TRACE_INCLUDE_FILE i40e_trace 403 | #include 404 | #endif /* CONFIG_TRACEPOINTS */ 405 | -------------------------------------------------------------------------------- /src/i40e_txrx_common.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_TXRX_COMMON_H_ 5 | #define _I40E_TXRX_COMMON_H_ 6 | 7 | #ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL 8 | void i40e_fd_handle_status(struct i40e_ring *rx_ring, 9 | union i40e_rx_desc *rx_desc, u8 prog_id); 10 | #endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ 11 | int i40e_xmit_xdp_tx_ring(struct xdp_buff *xdp, struct i40e_ring *xdp_ring); 12 | #if (defined HAVE_AF_XDP_ZC_SUPPORT && defined HAVE_MEM_TYPE_XSK_BUFF_POOL) 13 | void i40e_clean_programming_status(struct i40e_ring *rx_ring, u64 qword0_raw, 14 | u64 qword1); 15 | #else 16 | struct i40e_rx_buffer *i40e_clean_programming_status 17 | (struct i40e_ring *rx_ring, 18 | union i40e_rx_desc *rx_desc, 19 | u64 qw); 20 | #endif 21 | void i40e_process_skb_fields(struct i40e_ring *rx_ring, 22 | union i40e_rx_desc *rx_desc, 23 | struct sk_buff *skb); 24 | void i40e_receive_skb(struct i40e_ring *rx_ring, 25 | struct sk_buff *skb, u16 vlan_tag, u16 vlan_tpid); 26 | 27 | void i40e_xdp_ring_update_tail(struct i40e_ring *xdp_ring); 28 | void i40e_update_rx_stats(struct i40e_ring *rx_ring, 29 | unsigned int total_rx_bytes, 30 | unsigned int total_rx_packets); 31 | void i40e_finalize_xdp_rx(struct i40e_ring *rx_ring, unsigned int xdp_res); 32 | void i40e_release_rx_desc(struct i40e_ring *rx_ring, u32 val); 33 | void i40e_xsk_clean_tx_ring(struct i40e_ring *tx_ring); 34 | void i40e_xsk_clean_rx_ring(struct i40e_ring *rx_ring); 35 | bool i40e_xsk_any_rx_ring_enabled(struct i40e_vsi *vsi); 36 | 37 | #ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL 38 | /** 39 | * i40e_rx_is_programming_status - check for programming status descriptor 40 | * @qw: qword representing status_error_len in CPU ordering 41 | * 42 | * The value of in the descriptor length field indicate if this 43 | * is a programming status descriptor for flow director or FCoE 44 | * by the value of I40E_RX_PROG_STATUS_DESC_LENGTH, otherwise 45 | * it is a packet descriptor. 46 | **/ 47 | static inline bool i40e_rx_is_programming_status(u64 qw) 48 | { 49 | /* The Rx filter programming status and SPH bit occupy the same 50 | * spot in the descriptor. Since we don't support packet split we 51 | * can just reuse the bit as an indication that this is a 52 | * programming status descriptor. 53 | */ 54 | return qw & I40E_RXD_QW1_LENGTH_SPH_MASK; 55 | } 56 | #endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ 57 | 58 | #define I40E_XDP_PASS 0 59 | #define I40E_XDP_CONSUMED BIT(0) 60 | #define I40E_XDP_TX BIT(1) 61 | #define I40E_XDP_REDIR BIT(2) 62 | 63 | static inline __le64 build_ctob(u32 td_cmd, u32 td_offset, unsigned int size, 64 | u32 td_tag) 65 | { 66 | return cpu_to_le64(I40E_TX_DESC_DTYPE_DATA | 67 | ((u64)td_cmd << I40E_TXD_QW1_CMD_SHIFT) | 68 | ((u64)td_offset << I40E_TXD_QW1_OFFSET_SHIFT) | 69 | ((u64)size << I40E_TXD_QW1_TX_BUF_SZ_SHIFT) | 70 | ((u64)td_tag << I40E_TXD_QW1_L2TAG1_SHIFT)); 71 | } 72 | 73 | #ifdef HAVE_AF_XDP_ZC_SUPPORT 74 | /** 75 | * i40e_update_tx_stats - Update the egress statistics for the Tx ring 76 | * @tx_ring: Tx ring to update 77 | * @total_packets: total packets sent 78 | * @total_bytes: total bytes sent 79 | **/ 80 | static inline void i40e_update_tx_stats(struct i40e_ring *tx_ring, 81 | unsigned int total_packets, 82 | unsigned int total_bytes) 83 | { 84 | u64_stats_update_begin(&tx_ring->syncp); 85 | tx_ring->stats.bytes += total_bytes; 86 | tx_ring->stats.packets += total_packets; 87 | u64_stats_update_end(&tx_ring->syncp); 88 | tx_ring->q_vector->tx.total_bytes += total_bytes; 89 | tx_ring->q_vector->tx.total_packets += total_packets; 90 | } 91 | #endif /* HAVE_AF_XDP_ZC_SUPPORT */ 92 | 93 | #define WB_STRIDE 4 94 | 95 | /** 96 | * i40e_arm_wb - (Possibly) arms Tx write-back 97 | * @tx_ring: Tx ring to update 98 | * @vsi: the VSI 99 | * @budget: the NAPI budget left 100 | **/ 101 | static inline void i40e_arm_wb(struct i40e_ring *tx_ring, 102 | struct i40e_vsi *vsi, 103 | int budget) 104 | { 105 | if (tx_ring->flags & I40E_TXR_FLAGS_WB_ON_ITR) { 106 | /* check to see if there are < 4 descriptors 107 | * waiting to be written back, then kick the hardware to force 108 | * them to be written back in case we stay in NAPI. 109 | * In this mode on X722 we do not enable Interrupt. 110 | */ 111 | unsigned int j = i40e_get_tx_pending(tx_ring, false); 112 | 113 | if (budget && 114 | ((j / WB_STRIDE) == 0) && j > 0 && 115 | !test_bit(__I40E_VSI_DOWN, vsi->state) && 116 | (I40E_DESC_UNUSED(tx_ring) != tx_ring->count)) 117 | tx_ring->arm_wb = true; 118 | } 119 | } 120 | 121 | #ifdef HAVE_MEM_TYPE_XSK_BUFF_POOL 122 | /** 123 | * i40e_rx_is_programming_status - check for programming status descriptor 124 | * @qword1: qword1 representing status_error_len in CPU ordering 125 | * 126 | * The value of in the descriptor length field indicate if this 127 | * is a programming status descriptor for flow director or FCoE 128 | * by the value of I40E_RX_PROG_STATUS_DESC_LENGTH, otherwise 129 | * it is a packet descriptor. 130 | **/ 131 | static inline bool i40e_rx_is_programming_status(u64 qword1) 132 | { 133 | /* The Rx filter programming status and SPH bit occupy the same 134 | * spot in the descriptor. Since we don't support packet split we 135 | * can just reuse the bit as an indication that this is a 136 | * programming status descriptor. 137 | */ 138 | return qword1 & I40E_RXD_QW1_LENGTH_SPH_MASK; 139 | } 140 | #endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ 141 | 142 | void i40e_xsk_clean_rx_ring(struct i40e_ring *rx_ring); 143 | void i40e_xsk_clean_tx_ring(struct i40e_ring *tx_ring); 144 | bool i40e_xsk_any_rx_ring_enabled(struct i40e_vsi *vsi); 145 | 146 | #endif /* _I40E_TXRX_COMMON_H_ */ 147 | -------------------------------------------------------------------------------- /src/i40e_virtchnl_pf.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_VIRTCHNL_PF_H_ 5 | #define _I40E_VIRTCHNL_PF_H_ 6 | 7 | #include "i40e.h" 8 | 9 | #define I40E_MAX_VLANID 4095 10 | 11 | #define I40E_VIRTCHNL_SUPPORTED_QTYPES 2 12 | 13 | #define I40E_DEFAULT_NUM_MDD_EVENTS_ALLOWED 3 14 | 15 | #define I40E_VLAN_PRIORITY_SHIFT 13 16 | #define I40E_VLAN_MASK 0xFFF 17 | #define I40E_PRIORITY_MASK 0xE000 18 | 19 | #define I40E_MAX_VF_PROMISC_FLAGS 3 20 | 21 | #define I40E_VF_STATE_WAIT_COUNT 20 22 | #define I40E_VFR_WAIT_COUNT 100 23 | #define I40E_VF_RESET_TIME_MIN 30000000 // time in nsec 24 | 25 | /* Various queue ctrls */ 26 | enum i40e_queue_ctrl { 27 | I40E_QUEUE_CTRL_UNKNOWN = 0, 28 | I40E_QUEUE_CTRL_ENABLE, 29 | I40E_QUEUE_CTRL_ENABLECHECK, 30 | I40E_QUEUE_CTRL_DISABLE, 31 | I40E_QUEUE_CTRL_DISABLECHECK, 32 | I40E_QUEUE_CTRL_FASTDISABLE, 33 | I40E_QUEUE_CTRL_FASTDISABLECHECK, 34 | }; 35 | 36 | /* VF states */ 37 | enum i40e_vf_states { 38 | I40E_VF_STATE_INIT = 0, 39 | I40E_VF_STATE_ACTIVE, 40 | I40E_VF_STATE_DISABLED, 41 | I40E_VF_STATE_MC_PROMISC, 42 | I40E_VF_STATE_UC_PROMISC, 43 | I40E_VF_STATE_PRE_ENABLE, 44 | I40E_VF_STATE_RESETTING, 45 | I40E_VF_STATE_RESOURCES_LOADED, 46 | }; 47 | 48 | /* VF capabilities */ 49 | enum i40e_vf_capabilities { 50 | I40E_VIRTCHNL_VF_CAP_PRIVILEGE = 0, 51 | I40E_VIRTCHNL_VF_CAP_L2, 52 | }; 53 | 54 | /* In ADq, max 4 VSI's can be allocated per VF including primary VF VSI. 55 | * These variables are used to store indices, id's and number of queues 56 | * for each VSI including that of primary VF VSI. Each Traffic class is 57 | * termed as channel and each channel can in-turn have 4 queues which 58 | * means max 16 queues overall per VF. 59 | */ 60 | struct i40evf_channel { 61 | u16 vsi_idx; /* index in PF struct for all channel VSIs */ 62 | u16 vsi_id; /* VSI ID used by firmware */ 63 | u16 num_qps; /* number of queue pairs requested by user */ 64 | u64 max_tx_rate; /* bandwidth rate allocation for VSIs */ 65 | }; 66 | 67 | /* used for VLAN list 'vm_vlan_list' by VM for trusted and untrusted VF */ 68 | struct i40e_vm_vlan { 69 | struct list_head list; 70 | s16 vlan; 71 | u16 vsi_id; 72 | }; 73 | 74 | /* used for MAC list 'vm_mac_list' to recognize MACs added by VM */ 75 | struct i40e_vm_mac { 76 | struct list_head list; 77 | u8 macaddr[ETH_ALEN]; 78 | }; 79 | 80 | /* used for following share for given traffic class by VF*/ 81 | struct i40e_vf_tc_info { 82 | bool applied; 83 | u8 applied_tc_share[I40E_MAX_TRAFFIC_CLASS]; 84 | u8 requested_tc_share[I40E_MAX_TRAFFIC_CLASS]; 85 | u16 max_tc_tx_rate[I40E_MAX_TRAFFIC_CLASS]; 86 | }; 87 | 88 | struct i40e_time_mac { 89 | unsigned long time_modified; 90 | u8 addr[ETH_ALEN]; 91 | }; 92 | 93 | struct i40e_mdd_vf_events { 94 | u64 count; /* total count of Rx|Tx events */ 95 | /* count number of the last printed event */ 96 | u64 last_printed; 97 | }; 98 | 99 | /* VF information structure */ 100 | struct i40e_vf { 101 | struct i40e_pf *pf; 102 | 103 | /* VF id in the PF space */ 104 | s16 vf_id; 105 | /* all VF vsis connect to the same parent */ 106 | enum i40e_switch_element_types parent_type; 107 | struct virtchnl_version_info vf_ver; 108 | u32 driver_caps; /* reported by VF driver */ 109 | 110 | /* VF Port Extender (PE) stag if used */ 111 | u16 stag; 112 | 113 | struct virtchnl_ether_addr default_lan_addr; 114 | struct i40e_time_mac legacy_last_added_umac; /* keeps last added MAC address */ 115 | s16 port_vlan_id; 116 | bool pf_set_mac; /* The VMM admin set the VF MAC address */ 117 | bool trusted; 118 | bool source_pruning; 119 | u64 reset_timestamp; 120 | 121 | /* VSI indices - actual VSI pointers are maintained in the PF structure 122 | * When assigned, these will be non-zero, because VSI 0 is always 123 | * the main LAN VSI for the PF. 124 | */ 125 | u16 lan_vsi_idx; /* index into PF struct */ 126 | u16 lan_vsi_id; /* ID as used by firmware */ 127 | 128 | u8 num_queue_pairs; /* num of qps assigned to VF vsis */ 129 | u8 num_req_queues; /* num of requested qps */ 130 | /* num of mdd tx and rx events detected */ 131 | struct i40e_mdd_vf_events mdd_rx_events; 132 | struct i40e_mdd_vf_events mdd_tx_events; 133 | 134 | unsigned long vf_caps; /* vf's adv. capabilities */ 135 | unsigned long vf_states; /* vf's runtime states */ 136 | unsigned int tx_rate; /* Tx bandwidth limit in Mbps */ 137 | #ifdef HAVE_NDO_SET_VF_LINK_STATE 138 | bool link_forced; 139 | bool link_up; /* only valid if VF link is forced */ 140 | #endif 141 | bool mac_anti_spoof; 142 | bool vlan_anti_spoof; 143 | u16 num_vlan; 144 | DECLARE_BITMAP(mirror_vlans, VLAN_N_VID); 145 | u16 vlan_rule_id; 146 | #define I40E_NO_VF_MIRROR -1 147 | /* assuming vf ids' range is <0..max_supported> */ 148 | #define I40E_IS_MIRROR_VLAN_ID_VALID(id) ((id) >= 0) 149 | u16 ingress_rule_id; 150 | int ingress_vlan; 151 | u16 egress_rule_id; 152 | int egress_vlan; 153 | DECLARE_BITMAP(trunk_vlans, VLAN_N_VID); 154 | bool trunk_set_by_pf; 155 | bool allow_untagged; /* update filters, when changing value */ 156 | bool loopback; 157 | bool vlan_stripping; 158 | u8 promisc_mode; 159 | u8 bw_share; 160 | bool bw_share_applied; /* true if config is applied to the device */ 161 | bool tc_bw_share_req; 162 | u8 queue_type; 163 | bool allow_bcast; 164 | bool is_disabled_from_host; /* bool for PF ctrl of VF enable/disable */ 165 | /* VLAN list created by VM for trusted and untrusted VF */ 166 | struct list_head vm_vlan_list; 167 | /* MAC list created by VM */ 168 | struct list_head vm_mac_list; 169 | /* ADq related variables */ 170 | bool adq_enabled; /* flag to enable adq */ 171 | u8 num_tc; 172 | struct i40evf_channel ch[I40E_MAX_VF_VSI]; 173 | struct hlist_head cloud_filter_list; 174 | u16 num_cloud_filters; 175 | struct i40e_vf_tc_info tc_info; 176 | struct virtchnl_vlan_caps vlan_v2_caps; 177 | }; 178 | 179 | void i40e_free_vfs(struct i40e_pf *pf); 180 | #if defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE) 181 | int i40e_pci_sriov_configure(struct pci_dev *dev, int num_vfs); 182 | #endif 183 | int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs); 184 | int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode, 185 | u32 v_retval, u8 *msg, u16 msglen); 186 | int i40e_vc_process_vflr_event(struct i40e_pf *pf); 187 | void i40e_vc_reset_vf(struct i40e_vf *vf, bool notify_vf); 188 | bool i40e_reset_vf(struct i40e_vf *vf, bool flr); 189 | bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr); 190 | void i40e_vc_notify_vf_reset(struct i40e_vf *vf); 191 | 192 | /* VF configuration related iplink handlers */ 193 | int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac); 194 | #ifdef IFLA_VF_VLAN_INFO_MAX 195 | int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, 196 | u16 vlan_id, u8 qos, __be16 vlan_proto); 197 | #else 198 | int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, 199 | int vf_id, u16 vlan_id, u8 qos); 200 | #endif 201 | #ifdef HAVE_NDO_SET_VF_MIN_MAX_TX_RATE 202 | int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate, 203 | int max_tx_rate); 204 | #else 205 | int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate); 206 | #endif 207 | #ifdef HAVE_NDO_SET_VF_TRUST 208 | int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting); 209 | #endif 210 | int i40e_ndo_enable_vf(struct net_device *netdev, int vf_id, bool enable); 211 | #ifdef IFLA_VF_MAX 212 | int i40e_ndo_get_vf_config(struct net_device *netdev, 213 | int vf_id, struct ifla_vf_info *ivi); 214 | #ifdef HAVE_NDO_SET_VF_LINK_STATE 215 | int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link); 216 | #endif 217 | #ifdef HAVE_VF_SPOOFCHK_CONFIGURE 218 | int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable); 219 | #endif 220 | #endif 221 | 222 | void i40e_vc_notify_link_state(struct i40e_pf *pf); 223 | void i40e_vc_notify_reset(struct i40e_pf *pf); 224 | void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev); 225 | #ifdef HAVE_VF_STATS 226 | int i40e_get_vf_stats(struct net_device *netdev, int vf_id, 227 | struct ifla_vf_stats *vf_stats); 228 | #endif 229 | extern const struct vfd_ops i40e_vfd_ops; 230 | 231 | #endif /* _I40E_VIRTCHNL_PF_H_ */ 232 | -------------------------------------------------------------------------------- /src/i40e_xsk.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _I40E_XSK_H_ 5 | #define _I40E_XSK_H_ 6 | 7 | #ifdef HAVE_AF_XDP_ZC_SUPPORT 8 | 9 | /* This value should match the pragma in the loop_unrolled_for 10 | * macro. Why 4? It is strictly empirical. It seems to be a good 11 | * compromise between the advantage of having simultaneous outstanding 12 | * reads to the DMA array that can hide each others latency and the 13 | * disadvantage of having a larger code path. 14 | */ 15 | #define PKTS_PER_BATCH 4 16 | 17 | #if __GNUC__ >= 8 18 | #define loop_unrolled_for _Pragma("GCC unroll 4") for 19 | #else 20 | #define loop_unrolled_for for 21 | #endif 22 | 23 | struct i40e_vsi; 24 | #ifdef HAVE_NETDEV_BPF_XSK_POOL 25 | struct xsk_buff_pool; 26 | #else 27 | struct xdp_umem; 28 | #endif /*HAVE_NETDEV_BPF_XSK_POOL */ 29 | struct zero_copy_allocator; 30 | 31 | int i40e_queue_pair_disable(struct i40e_vsi *vsi, int queue_pair); 32 | int i40e_queue_pair_enable(struct i40e_vsi *vsi, int queue_pair); 33 | #ifndef NO_XDP_QUERY_XSK_UMEM 34 | int i40e_xsk_umem_query(struct i40e_vsi *vsi, struct xdp_umem **umem, 35 | u16 qid); 36 | #endif /* NO_XDP_QUERY_XSK_UMEM */ 37 | #ifdef HAVE_NETDEV_BPF_XSK_POOL 38 | int i40e_xsk_pool_setup(struct i40e_vsi *vsi, struct xsk_buff_pool *pool, 39 | u16 qid); 40 | #else 41 | int i40e_xsk_umem_setup(struct i40e_vsi *vsi, struct xdp_umem *umem, 42 | u16 qid); 43 | #endif /* HAVE_NETDEV_BFP_XSK_POOL */ 44 | #ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL 45 | void i40e_zca_free(struct zero_copy_allocator *alloc, unsigned long handle); 46 | #endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ 47 | 48 | bool i40e_alloc_rx_buffers_zc(struct i40e_ring *rx_ring, u16 cleaned_count); 49 | int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget); 50 | 51 | bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi, struct i40e_ring *tx_ring); 52 | #ifdef HAVE_NDO_XSK_WAKEUP 53 | int i40e_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags); 54 | #else 55 | int i40e_xsk_async_xmit(struct net_device *dev, u32 queue_id); 56 | #endif /* HAVE_NDO_XSK_WAKEUP */ 57 | 58 | #ifdef HAVE_MEM_TYPE_XSK_BUFF_POOL 59 | int i40e_alloc_rx_bi_zc(struct i40e_ring *rx_ring); 60 | void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring); 61 | #endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ 62 | 63 | #endif /* HAVE_AF_XDP_SUPPORT */ 64 | #endif /* _I40E_XSK_H_ */ 65 | 66 | -------------------------------------------------------------------------------- /src/kcompat_defs.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _KCOMPAT_DEFS_H_ 5 | #define _KCOMPAT_DEFS_H_ 6 | 7 | #ifndef LINUX_VERSION_CODE 8 | #include 9 | #else 10 | #ifndef KERNEL_VERSION 11 | #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) 12 | #endif 13 | #endif /* LINUX_VERSION_CODE */ 14 | 15 | #ifndef UTS_RELEASE 16 | #include 17 | #endif 18 | 19 | /* 20 | * Include the definitions file for HAVE/NEED flags for the standard upstream 21 | * kernels. 22 | * 23 | * Then, based on the distribution we detect, load the distribution specific 24 | * definitions file that customizes the definitions for the target 25 | * distribution. 26 | */ 27 | #include "kcompat_std_defs.h" 28 | 29 | #ifdef CONFIG_SUSE_KERNEL 30 | #include "kcompat_sles_defs.h" 31 | #elif UBUNTU_VERSION_CODE 32 | #include "kcompat_ubuntu_defs.h" 33 | #elif RHEL_RELEASE_CODE 34 | #include "kcompat_rhel_defs.h" 35 | #endif 36 | 37 | #include "kcompat_generated_defs.h" 38 | 39 | #endif /* _KCOMPAT_DEFS_H_ */ 40 | -------------------------------------------------------------------------------- /src/kcompat_gcc.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _KCOMPAT_GCC_H_ 5 | #define _KCOMPAT_GCC_H_ 6 | 7 | #ifndef GCC_VERSION 8 | #define GCC_VERSION (__GNUC__ * 10000 \ 9 | + __GNUC_MINOR__ * 100 \ 10 | + __GNUC_PATCHLEVEL__) 11 | #endif /* GCC_VERSION */ 12 | 13 | /* as GCC_VERSION yields 40201 for any modern clang (checked on clang 7 & 13) 14 | * we want other means to add workarounds for "old GCC" */ 15 | #ifdef __clang__ 16 | #define GCC_IS_BELOW(x) 0 17 | #else 18 | #define GCC_IS_BELOW(x) (GCC_VERSION < (x)) 19 | #endif 20 | 21 | #ifdef __has_attribute 22 | #if __has_attribute(__fallthrough__) 23 | # define fallthrough __attribute__((__fallthrough__)) 24 | #else 25 | # define fallthrough do {} while (0) /* fallthrough */ 26 | #endif /* __has_attribute(fallthrough) */ 27 | #else 28 | # define fallthrough do {} while (0) /* fallthrough */ 29 | #endif /* __has_attribute */ 30 | 31 | /* 32 | * upstream commit 4eb6bd55cfb2 ("compiler.h: drop fallback overflow checkers") 33 | * removed bunch of code for builitin overflow fallback implementations, that 34 | * we need for gcc prior to 5.1 35 | */ 36 | #if !GCC_IS_BELOW(50100) 37 | #ifndef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 38 | #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 39 | #endif 40 | #endif /* GCC_VERSION >= 50100 */ 41 | 42 | #include "kcompat_overflow.h" 43 | 44 | /* Backport macros for controlling GCC diagnostics */ 45 | #if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,18,0) ) 46 | /* Compilers before gcc-4.6 do not understand "#pragma GCC diagnostic push" */ 47 | #if GCC_VERSION >= 40600 48 | #define __diag_str1(s) #s 49 | #define __diag_str(s) __diag_str1(s) 50 | #define __diag(s) _Pragma(__diag_str(GCC diagnostic s)) 51 | #else 52 | #define __diag(s) 53 | #endif /* GCC_VERSION >= 4.6 */ 54 | #define __diag_push() __diag(push) 55 | #define __diag_pop() __diag(pop) 56 | #endif /* LINUX_VERSION < 4.18.0 */ 57 | 58 | #if GCC_IS_BELOW(50000) 59 | /* Workaround for gcc bug - not accepting "(type)" before "{ ... }" as part of 60 | * static struct initializers [when used with -std=gnu11 switch] 61 | * https://bugzilla.redhat.com/show_bug.cgi?id=1672652 62 | * 63 | * fix was backported to gcc 4.8.5-39 by RedHat, contained in RHEL 7.7 64 | * workaround here is to just drop that redundant (commented out below) part and 65 | * redefine kernel macros used by us. 66 | */ 67 | 68 | /* Since problematic code could be triggered by print-family (incl. wrappers) 69 | * invocation, we have to first include headers that contain macros that we are 70 | * redefining, and only later proceed with the rest of includes. 71 | */ 72 | #include 73 | #include 74 | #include 75 | #include 76 | 77 | #ifdef __SPIN_LOCK_INITIALIZER 78 | #undef __SPIN_LOCK_UNLOCKED 79 | #define __SPIN_LOCK_UNLOCKED(lockname) \ 80 | /* (spinlock_t) */ __SPIN_LOCK_INITIALIZER(lockname) 81 | #endif /* __SPIN_LOCK_INITIALIZER */ 82 | 83 | #ifdef __RAW_SPIN_LOCK_INITIALIZER 84 | #undef __RAW_SPIN_LOCK_UNLOCKED 85 | #define __RAW_SPIN_LOCK_UNLOCKED(lockname) \ 86 | /* (raw_spinlock_t) */ __RAW_SPIN_LOCK_INITIALIZER(lockname) 87 | #endif /* __RAW_SPIN_LOCK_INITIALIZER */ 88 | 89 | #ifndef CONFIG_DEBUG_SPINLOCK 90 | /* raw_spin_lock_init needs __RAW_SPIN_LOCK_UNLOCKED with typecast, so keep the 91 | * original impl, 92 | * but enhance it with typecast dropped from __RAW_SPIN_LOCK_UNLOCKED() */ 93 | #undef raw_spin_lock_init 94 | #define raw_spin_lock_init(lock) \ 95 | do { *(lock) = (raw_spinlock_t) __RAW_SPIN_LOCK_UNLOCKED(lock); \ 96 | } while (0) 97 | #endif /* !CONFIG_DEBUG_SPINLOCK */ 98 | 99 | #undef STATIC_KEY_INIT_TRUE 100 | #define STATIC_KEY_INIT_TRUE \ 101 | { .enabled = { 1 }, \ 102 | { .type = 1UL } } 103 | 104 | #undef STATIC_KEY_INIT_FALSE 105 | #define STATIC_KEY_INIT_FALSE \ 106 | { .enabled = { 0 } } 107 | 108 | #undef STATIC_KEY_TRUE_INIT 109 | #define STATIC_KEY_TRUE_INIT \ 110 | /* (struct static_key_true) */ { .key = STATIC_KEY_INIT_TRUE } 111 | 112 | #undef STATIC_KEY_FALSE_INIT 113 | #define STATIC_KEY_FALSE_INIT \ 114 | /* (struct static_key_false) */ { .key = STATIC_KEY_INIT_FALSE } 115 | 116 | #ifdef HAVE_JUMP_LABEL 117 | /* dd_key_init() is used (indirectly) with arg like "(STATIC_KEY_INIT_FALSE)" 118 | * from DEFINE_DYNAMIC_DEBUG_METADATA(), which, depending on config has many 119 | * different definitions (including helper macros). 120 | * To reduce compat code, just consume parens from the arg instead copy-pasting 121 | * all definitions and slightly changing them. */ 122 | #define _KC_SLURP_PARENS(...) __VA_ARGS__ 123 | #undef dd_key_init 124 | #define dd_key_init(key, init) key = _KC_SLURP_PARENS init 125 | #endif /* HAVE_JUMP_LABEL */ 126 | 127 | #undef UUID_INIT 128 | #define UUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ 129 | {{ ((a) >> 24) & 0xff, ((a) >> 16) & 0xff, \ 130 | ((a) >> 8) & 0xff, (a) & 0xff, \ 131 | ((b) >> 8) & 0xff, (b) & 0xff, \ 132 | ((c) >> 8) & 0xff, (c) & 0xff, \ 133 | (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) \ 134 | }} 135 | 136 | #endif /* old GCC < 5.0 */ 137 | 138 | #endif /* _KCOMPAT_GCC_H_ */ 139 | -------------------------------------------------------------------------------- /src/kcompat_rhel_defs.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _KCOMPAT_RHEL_DEFS_H_ 5 | #define _KCOMPAT_RHEL_DEFS_H_ 6 | 7 | /* This is the RedHat Enterprise Linux distribution specific definitions file. 8 | * It defines what features need backports for a given version of the RHEL 9 | * kernel. 10 | * 11 | * It checks the RHEL_RELEASE_CODE and RHEL_RELEASE_VERSION macros to decide 12 | * what support the target kernel has. 13 | * 14 | * It assumes that kcompat_std_defs.h has already been processed, and will 15 | * #define or #undef any flags that have changed based on backports done by 16 | * RHEL. 17 | */ 18 | 19 | #if !RHEL_RELEASE_CODE 20 | #error "RHEL_RELEASE_CODE is 0 or undefined" 21 | #endif 22 | 23 | #ifndef RHEL_RELEASE_VERSION 24 | #error "RHEL_RELEASE_VERSION is undefined" 25 | #endif 26 | 27 | /*****************************************************************************/ 28 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3)) 29 | #define NEED_NETDEV_TXQ_BQL_PREFETCH 30 | #else /* >= 7.3 */ 31 | #endif /* 7.3 */ 32 | 33 | /*****************************************************************************/ 34 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,4)) 35 | #define NEED_BUILD_BUG_ON 36 | #else /* >= 7.4 */ 37 | #define HAVE_RHEL7_EXTENDED_OFFLOAD_STATS 38 | #endif /* 7.4 */ 39 | 40 | /*****************************************************************************/ 41 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,5)) 42 | #else /* >= 7.5 */ 43 | #define HAVE_FLOW_DISSECTOR_KEY_IP 44 | #endif /* 7.5 */ 45 | 46 | /*****************************************************************************/ 47 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,6)) 48 | #undef HAVE_XDP_BUFF_RXQ 49 | #undef HAVE_XDP_RXQ_INFO_REG_3_PARAMS 50 | #else /* >= 7.6 */ 51 | #undef NEED_JIFFIES_64_TIME_IS_MACROS 52 | #undef NEED_TC_CLS_CAN_OFFLOAD_AND_CHAIN0 53 | #undef NEED_TC_SETUP_QDISC_MQPRIO 54 | #endif /* 7.6 */ 55 | 56 | /*****************************************************************************/ 57 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,7)) 58 | #else /* >= 7.7 */ 59 | #define HAVE_DEVLINK_PORT_ATTRS_SET_PORT_FLAVOUR 60 | #define HAVE_ETHTOOL_NEW_100G_BITS 61 | #undef NEED_IN_TASK 62 | #define HAVE_FLOW_DISSECTOR_KEY_ENC_IP 63 | #endif /* 7.7 */ 64 | 65 | /*****************************************************************************/ 66 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,0)) 67 | #else /* >= 8.0 */ 68 | #undef HAVE_ETHTOOL_NEW_100G_BITS 69 | #define HAVE_NDO_OFFLOAD_STATS 70 | #undef HAVE_RHEL7_EXTENDED_OFFLOAD_STATS 71 | #endif /* 8.0 */ 72 | 73 | /*****************************************************************************/ 74 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,1)) 75 | #define NEED_IDA_ALLOC_MIN_MAX_RANGE_FREE 76 | #else /* >= 8.1 */ 77 | #define HAVE_ETHTOOL_NEW_100G_BITS 78 | #undef NEED_IDA_ALLOC_MIN_MAX_RANGE_FREE 79 | #undef NEED_INDIRECT_CALL_WRAPPER_MACROS 80 | #define HAVE_INDIRECT_CALL_WRAPPER_HEADER 81 | #define HAVE_LINKMODE 82 | #endif /* 8.1 */ 83 | 84 | /*****************************************************************************/ 85 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,2)) 86 | #else /* >= 8.2 */ 87 | #undef NEED_FLOW_INDR_BLOCK_CB_REGISTER 88 | #define HAVE_FLOW_INDR_BLOCK_LOCK 89 | #define HAVE_DEVLINK_PORT_ATTRS_SET_SWITCH_ID 90 | #define HAVE_NETDEV_SB_DEV 91 | #endif /* 8.2 */ 92 | 93 | /*****************************************************************************/ 94 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,3)) 95 | #else /* >= 8.3 */ 96 | #undef NEED_CPU_LATENCY_QOS_RENAME 97 | #define HAVE_RT_IRQ_SCHED_FIX 98 | #endif /* 8.3 */ 99 | 100 | /*****************************************************************************/ 101 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,4)) 102 | #else /* >= 8.4 */ 103 | #undef NEED_DEVLINK_PORT_ATTRS_SET_STRUCT 104 | #undef HAVE_XDP_QUERY_PROG 105 | #define HAVE_AF_XDP_ZC_SUPPORT 106 | #define HAVE_MEM_TYPE_XSK_BUFF_POOL 107 | #define HAVE_NDO_XSK_WAKEUP 108 | #define XSK_UMEM_RETURNS_XDP_DESC 109 | #undef NEED_XSK_UMEM_GET_RX_FRAME_SIZE 110 | #define HAVE_ETHTOOL_COALESCE_PARAMS_SUPPORT 111 | #endif /* 8.4 */ 112 | 113 | /*****************************************************************************/ 114 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,5)) 115 | #else /* >= 8.5 */ 116 | #undef HAVE_NAPI_BUSY_LOOP 117 | #undef HAVE_XDP_RXQ_INFO_REG_3_PARAMS 118 | #define NO_XDP_QUERY_XSK_UMEM 119 | #undef NEED_XSK_BUFF_POOL_RENAME 120 | #define HAVE_NETDEV_BPF_XSK_POOL 121 | #define HAVE_AF_XDP_NETDEV_UMEM 122 | #define HAVE_DEVLINK_OPS_CREATE_DEL 123 | #endif /* 8.5 */ 124 | 125 | /*****************************************************************************/ 126 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,7)) 127 | #else /* >= 8.7 */ 128 | #undef NEED_DEVLINK_ALLOC_SETS_DEV 129 | #define HAVE_DEVLINK_SET_STATE_3_PARAM 130 | #endif /* 8.7 */ 131 | 132 | /*****************************************************************************/ 133 | #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9,0)) 134 | #else /* >= 9.0 */ 135 | #define HAVE_XDP_BUFF_RXQ 136 | #endif /* 9.0 */ 137 | 138 | /*****************************************************************************/ 139 | #endif /* _KCOMPAT_RHEL_DEFS_H_ */ 140 | -------------------------------------------------------------------------------- /src/kcompat_sigil.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _KCOMPAT_SIGIL_H_ 5 | #define _KCOMPAT_SIGIL_H_ 6 | 7 | #define _STUB_0(code_if_true, code_if_false) code_if_false 8 | #define _STUB_1(code_if_true, code_if_false) code_if_true 9 | #define _PASTE(x, y) x ## y 10 | #define PASTE(x, y) _PASTE(x, y) 11 | #define _STUB_CODE(flag) PASTE(_STUB_, IS_ENABLED(flag)) 12 | 13 | #define DECLARE_OR_STUB(flag, stub_ret, ...) \ 14 | _STUB_CODE(flag)(,static inline) __VA_ARGS__ \ 15 | _STUB_CODE(flag)(;, { return stub_ret; }) 16 | 17 | /* 18 | * DEPAREN ... VANISH taken from SO https://stackoverflow.com/a/62984543 19 | * It is used to allow wraping KC() params in (), so they could contain a comma. 20 | */ 21 | #define DEPAREN(X) ESC(ISH X) 22 | #define ISH(...) ISH __VA_ARGS__ 23 | #define ESC(...) ESC_(__VA_ARGS__) 24 | #define ESC_(...) VAN ## __VA_ARGS__ 25 | #define VANISH 26 | 27 | #define KC_COMMA , 28 | 29 | #ifndef __CHECKER__ 30 | 31 | /* isn't it cool to write KC(FLAG, some code, optional alternative code) ? :) */ 32 | #define KC(flag, code_if_true, ...) \ 33 | _STUB_CODE(flag)(DEPAREN(code_if_true), DEPAREN(__VA_ARGS__)) 34 | 35 | #define KC__(X) X KC_COMMA 36 | #define __KC(X) KC_COMMA X 37 | 38 | //~ KC_(HAVE_NDO_FDB_ADD_VID, u16 vid) 39 | //~ -> 40 | //~ KC(HAVE_NDO_FDB_ADD_VID, (u16 vid, )) 41 | #define KC_(flag, param_if_true) \ 42 | KC(flag, (KC__(param_if_true))) 43 | 44 | //~ _KC(HAVE_FOO, u16 val) 45 | //~ -> 46 | //~ KC(HAVE_FOO, (, u16 val)) 47 | #define _KC(flag, param_if_true) \ 48 | KC(flag, (__KC(param_if_true))) 49 | 50 | #else /* __CHECKER__ */ 51 | /* KC replaced by KC_LOOKUP, for sparse */ 52 | #define KC_LOOKUP(flag, code_if_true, ...) \ 53 | _STUB_CODE(flag)(DEPAREN(code_if_true), DEPAREN(__VA_ARGS__)) 54 | #define KC_LOOKUP__(X) X KC_COMMA 55 | #define __KC_LOOKUP(X) KC_COMMA X 56 | #define KC_LOOKUP_(flag, param_if_true) \ 57 | KC_LOOKUP(flag, (KC_LOOKUP__(param_if_true))) 58 | #define _KC_LOOKUP(flag, param_if_true) \ 59 | KC_LOOKUP(flag, (__KC_LOOKUP(param_if_true))) 60 | #endif /* __CHECKER__ */ 61 | 62 | #endif /* _KCOMPAT_SIGIL_H_ */ 63 | -------------------------------------------------------------------------------- /src/kcompat_sles_defs.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _KCOMPAT_SLES_DEFS_H_ 5 | #define _KCOMPAT_SLES_DEFS_H_ 6 | 7 | /* This is the SUSE Linux Enterprise distribution specific definitions file. 8 | * It defines what features need backports for a given version of the SUSE 9 | * Linux Enterprise kernel. 10 | * 11 | * It checks a combination of the LINUX_VERSION code and the 12 | * SLE_LOCALVERSION_CODE to determine what support the kernel has. 13 | * 14 | * It assumes that kcompat_std_defs.h has already been processed, and will 15 | * #define or #undef any flags that have changed based on backports done by 16 | * SUSE. 17 | */ 18 | 19 | #ifndef LINUX_VERSION_CODE 20 | #error "LINUX_VERSION_CODE is undefined" 21 | #endif 22 | 23 | #ifndef KERNEL_VERSION 24 | #error "KERNEL_VERSION is undefined" 25 | #endif 26 | 27 | #if !SLE_KERNEL_REVISION 28 | #error "SLE_KERNEL_REVISION is 0 or undefined" 29 | #endif 30 | 31 | #if SLE_KERNEL_REVISION > 65535 32 | #error "SLE_KERNEL_REVISION is unexpectedly large" 33 | #endif 34 | 35 | /* SLE kernel versions are a combination of the LINUX_VERSION_CODE along with 36 | * an extra digit that indicates the SUSE specific revision of that kernel. 37 | * This value is found in the CONFIG_LOCALVERSION of the SUSE kernel, which is 38 | * extracted by common.mk and placed into SLE_KERNEL_REVISION_CODE. 39 | * 40 | * We combine the value of SLE_KERNEL_REVISION along with the LINUX_VERSION code 41 | * to generate the useful value that determines what specific kernel we're 42 | * dealing with. 43 | * 44 | * Just in case the SLE_KERNEL_REVISION ever goes above 255, we reserve 16 bits 45 | * instead of 8 for this value. 46 | */ 47 | #define SLE_KERNEL_CODE ((LINUX_VERSION_CODE << 16) + SLE_KERNEL_REVISION) 48 | #define SLE_KERNEL_VERSION(a,b,c,d) ((KERNEL_VERSION(a,b,c) << 16) + (d)) 49 | 50 | /* Unlike RHEL, SUSE kernels are not always tied to a single service pack. For 51 | * example, 4.12.14 was used as the base for SLE 15 SP1, SLE 12 SP4, and SLE 12 52 | * SP5. 53 | * 54 | * You can find the patches that SUSE applied to the kernel tree at 55 | * https://github.com/SUSE/kernel-source. 56 | * 57 | * You can find the correct kernel version for a check by using steps similar 58 | * to the following 59 | * 60 | * 1) download the kernel-source repo 61 | * 2) checkout the relevant branch, i.e SLE15-SP3 62 | * 3) find the relevant backport you're interested in the patches.suse 63 | * directory 64 | * 4) git log to locate the commit that introduced the backport 65 | * 5) git describe --contains to find the relevant tag that includes that 66 | * commit, i.e. rpm-5.3.18-37 67 | * 6) those digits represent the SLE kernel that introduced that backport. 68 | * 69 | * Try to keep the checks in SLE_KERNEL_CODE order and condense where 70 | * possible. 71 | */ 72 | 73 | /*****************************************************************************/ 74 | #if (SLE_KERNEL_CODE > SLE_KERNEL_VERSION(4,12,14,23) && \ 75 | SLE_KERNEL_CODE < SLE_KERNEL_VERSION(4,12,14,94)) 76 | /* 77 | * 4.12.14 is used as the base for SLE 12 SP4, SLE 12 SP5, SLE 15, and SLE 15 78 | * SP1. Unfortunately the revision codes do not line up cleanly. SLE 15 79 | * launched with 4.12.14-23. It appears that SLE 12 SP4 and SLE 15 SP1 both 80 | * diverged from this point, with SLE 12 SP4 kernels starting around 81 | * 4.12.14-94. A few backports for SLE 15 SP1 landed in some alpha and beta 82 | * kernels tagged between 4.12.14-25 up to 4.12.14-32. These changes did not 83 | * make it into SLE 12 SP4. This was cleaned up with SLE 12 SP5 by an apparent 84 | * merge in 4.12.14-111. The official launch of SLE 15 SP1 ended up with 85 | * version 4.12.14-195. 86 | * 87 | * Because of this inconsistency and because all of these kernels appear to be 88 | * alpha or beta kernel releases for SLE 15 SP1, we do not rely on version 89 | * checks between this range. Issue a warning to indicate that we do not 90 | * support these. 91 | */ 92 | #warning "SLE kernel versions between 4.12.14-23 and 4.12.14-94 are not supported" 93 | #endif 94 | 95 | /*****************************************************************************/ 96 | #if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(4,12,14,10)) 97 | #else /* >= 4.12.14-10 */ 98 | #undef NEED_INDIRECT_CALL_WRAPPER_MACROS 99 | #define HAVE_INDIRECT_CALL_WRAPPER_HEADER 100 | #endif /* 4.12.14-10 */ 101 | 102 | /*****************************************************************************/ 103 | #if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(4,12,14,111)) 104 | #define NEED_IDA_ALLOC_MIN_MAX_RANGE_FREE 105 | #else /* >= 4.12.14-111 */ 106 | #define HAVE_DEVLINK_PORT_ATTRS_SET_PORT_FLAVOUR 107 | #undef NEED_MACVLAN_ACCEL_PRIV 108 | #undef NEED_MACVLAN_RELEASE_L2FW_OFFLOAD 109 | #undef NEED_MACVLAN_SUPPORTS_DEST_FILTER 110 | #undef NEED_IDA_ALLOC_MIN_MAX_RANGE_FREE 111 | #endif /* 4.12.14-111 */ 112 | 113 | /*****************************************************************************/ 114 | /* SLES 12-SP5 base kernel version */ 115 | #if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(4,12,14,115)) 116 | #else /* >= 4.12.14-115 */ 117 | #define HAVE_NDO_SELECT_QUEUE_SB_DEV 118 | #undef NEED_TC_SETUP_QDISC_MQPRIO 119 | #undef NEED_TC_CLS_CAN_OFFLOAD_AND_CHAIN0 120 | #define HAVE_LINKMODE 121 | #endif /* 4.12.14-115 */ 122 | 123 | /*****************************************************************************/ 124 | #if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(5,3,8,2)) 125 | #else /* >= 5.3.8-2 */ 126 | #undef NEED_FLOW_INDR_BLOCK_CB_REGISTER 127 | #define HAVE_FLOW_INDR_BLOCK_LOCK 128 | #endif /* 5.3.8-2 */ 129 | 130 | #if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(5,3,18,26)) 131 | #else /* >= 5.3.18-26 */ 132 | #undef NEED_CPU_LATENCY_QOS_RENAME 133 | #endif 134 | 135 | /*****************************************************************************/ 136 | #if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(5,3,18,34)) 137 | #else /* >= 5.3.18-34 */ 138 | #undef NEED_DEVLINK_PORT_ATTRS_SET_STRUCT 139 | #endif /* 5.3.18-34 */ 140 | 141 | /*****************************************************************************/ 142 | #if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(5,3,18,41)) 143 | #define NEED_XSK_BUFF_POOL_RENAME 144 | #else /* >= 5.3.18-41 */ 145 | #define HAVE_XDP_BUFF_FRAME_SZ 146 | #define HAVE_NETDEV_BPF_XSK_POOL 147 | #undef NEED_XSK_UMEM_GET_RX_FRAME_SIZE 148 | #undef NEED_XSK_BUFF_POOL_RENAME 149 | #define HAVE_MEM_TYPE_XSK_BUFF_POOL 150 | #endif /* 5.3.18-41 */ 151 | 152 | /*****************************************************************************/ 153 | #if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(5,14,21,9)) 154 | #else /* >= 5.14.21-150400.9 */ 155 | #undef NEED_DEVLINK_ALLOC_SETS_DEV 156 | #define HAVE_DEVLINK_OPS_CREATE_DEL 157 | #define HAVE_DEVLINK_SET_STATE_3_PARAM 158 | #endif /* 5.14.21-150400.9 */ 159 | 160 | #endif /* _KCOMPAT_SLES_DEFS_H_ */ 161 | -------------------------------------------------------------------------------- /src/kcompat_std_defs.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _KCOMPAT_STD_DEFS_H_ 5 | #define _KCOMPAT_STD_DEFS_H_ 6 | 7 | /* This file contains the definitions for what kernel features need backports 8 | * for a given kernel. It targets only the standard stable kernel releases. 9 | * It must check only LINUX_VERSION_CODE and assume the kernel is a standard 10 | * release, and not a custom distribution. 11 | * 12 | * It must define HAVE_ and NEED_ for features. It must not 13 | * implement any backports, instead leaving the implementation to the 14 | * kcompat_impl.h header. 15 | * 16 | * If a feature can be easily implemented as a replacement macro or fully 17 | * backported, use a NEED_ to indicate that the feature needs 18 | * a backport. (If NEED_ is undefined, then no backport for that feature 19 | * is needed). 20 | * 21 | * If a feature cannot be easily implemented in kcompat directly, but 22 | * requires drivers to make specific changes such as stripping out an entire 23 | * feature or modifying a function pointer prototype, use a HAVE_. 24 | */ 25 | 26 | #ifndef LINUX_VERSION_CODE 27 | #error "LINUX_VERSION_CODE is undefined" 28 | #endif 29 | 30 | #ifndef KERNEL_VERSION 31 | #error "KERNEL_VERSION is undefined" 32 | #endif 33 | 34 | /*****************************************************************************/ 35 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0)) 36 | #else /* >= 4,8,0 */ 37 | #define HAVE_PCI_ALLOC_IRQ 38 | #endif /* 4,8,0 */ 39 | 40 | /*****************************************************************************/ 41 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) 42 | #define NEED_JIFFIES_64_TIME_IS_MACROS 43 | #else /* >= 4,9,0 */ 44 | #define HAVE_KTHREAD_DELAYED_API 45 | #define HAVE_NDO_OFFLOAD_STATS 46 | #endif /* 4,9,0 */ 47 | 48 | /*****************************************************************************/ 49 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,62)) 50 | #define NEED_IN_TASK 51 | #else /* >= 4,9,62 */ 52 | #endif /* 4,9,62 */ 53 | 54 | /*****************************************************************************/ 55 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0)) 56 | #else /* >= 4,12,0 */ 57 | #define HAVE_NAPI_BUSY_LOOP 58 | #endif /* 4,12,0 */ 59 | 60 | /*****************************************************************************/ 61 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,13,0)) 62 | #else /* >= 4,13,0 */ 63 | #define HAVE_FLOW_DISSECTOR_KEY_IP 64 | #endif /* 4,13,0 */ 65 | 66 | /*****************************************************************************/ 67 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) 68 | #define NEED_TC_SETUP_QDISC_MQPRIO 69 | #define NEED_NETDEV_XDP_STRUCT 70 | #else /* >= 4,15,0 */ 71 | #define HAVE_NDO_BPF 72 | #endif /* 4,15,0 */ 73 | 74 | /*****************************************************************************/ 75 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,16,0)) 76 | #define NEED_TC_CLS_CAN_OFFLOAD_AND_CHAIN0 77 | #else /* >= 4,16,0 */ 78 | #define HAVE_XDP_BUFF_RXQ 79 | #define HAVE_XDP_RXQ_INFO_REG_3_PARAMS 80 | #endif /* 4,16,0 */ 81 | 82 | /*****************************************************************************/ 83 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,17,0)) 84 | #define NEED_CONVERT_ART_NS_TO_TSC 85 | #else /* >= 4,17,0 */ 86 | #endif /* 4,17,0 */ 87 | 88 | /*****************************************************************************/ 89 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,18,0)) 90 | #define NEED_MACVLAN_ACCEL_PRIV 91 | #define NEED_MACVLAN_RELEASE_L2FW_OFFLOAD 92 | #define NEED_MACVLAN_SUPPORTS_DEST_FILTER 93 | #else /* >= 4,18,0 */ 94 | #define HAVE_DEVLINK_PORT_ATTRS_SET_PORT_FLAVOUR 95 | #endif /* 4,18,0 */ 96 | 97 | /*****************************************************************************/ 98 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,19,0)) 99 | #define NEED_IDA_ALLOC_MIN_MAX_RANGE_FREE 100 | #else /* >= 4,19,0 */ 101 | #define HAVE_TC_ETF_QOPT_OFFLOAD 102 | #define HAVE_FLOW_DISSECTOR_KEY_ENC_IP 103 | #endif /* 4,19,0 */ 104 | 105 | /*****************************************************************************/ 106 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0)) 107 | #else /* >= 4.20.0 */ 108 | #define HAVE_LINKMODE 109 | #endif /* 4.20.0 */ 110 | 111 | /*****************************************************************************/ 112 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)) 113 | #define NEED_INDIRECT_CALL_WRAPPER_MACROS 114 | #else /* >= 5.0.0 */ 115 | #define HAVE_INDIRECT_CALL_WRAPPER_HEADER 116 | #endif /* 5.0.0 */ 117 | 118 | /*****************************************************************************/ 119 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,1,0)) 120 | #else /* >= 5.1.0 */ 121 | #define HAVE_ETHTOOL_200G_BITS 122 | #define HAVE_ETHTOOL_NEW_100G_BITS 123 | #endif /* 5.1.0 */ 124 | 125 | /*****************************************************************************/ 126 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)) 127 | #else /* >= 5.2.0 */ 128 | #define HAVE_DEVLINK_PORT_ATTRS_SET_SWITCH_ID 129 | #endif /* 5.2.0 */ 130 | 131 | /*****************************************************************************/ 132 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0)) 133 | #define NEED_FLOW_INDR_BLOCK_CB_REGISTER 134 | #else /* >= 5.4.0 */ 135 | #define HAVE_FLOW_INDR_BLOCK_LOCK 136 | #define HAVE_XSK_UNALIGNED_CHUNK_PLACEMENT 137 | #endif /* 5.4.0 */ 138 | 139 | /*****************************************************************************/ 140 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0)) 141 | #define NEED_CPU_LATENCY_QOS_RENAME 142 | #else /* >= 5.7.0 */ 143 | #endif /* 5.7.0 */ 144 | 145 | /*****************************************************************************/ 146 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0)) 147 | #define NEED_XSK_UMEM_GET_RX_FRAME_SIZE 148 | #else /* >= 5.8.0 */ 149 | #undef HAVE_XSK_UNALIGNED_CHUNK_PLACEMENT 150 | #define HAVE_RT_IRQ_SCHED_FIX 151 | #endif /* 5.8.0 */ 152 | 153 | /*****************************************************************************/ 154 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,9,0)) 155 | #define NEED_DEVLINK_PORT_ATTRS_SET_STRUCT 156 | #define HAVE_XDP_QUERY_PROG 157 | #define NEED_INDIRECT_CALL_3_AND_4 158 | #else /* >= 5.9.0 */ 159 | #define HAVE_TASKLET_SETUP 160 | #endif /* 5.9.0 */ 161 | 162 | /*****************************************************************************/ 163 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)) 164 | #define NEED_XSK_BUFF_POOL_RENAME 165 | #else /* >= 5.10.0 */ 166 | #define HAVE_UDP_TUNNEL_NIC_SHARED 167 | #define HAVE_NETDEV_BPF_XSK_POOL 168 | #endif /* 5.10.0 */ 169 | 170 | /*****************************************************************************/ 171 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,11,0)) 172 | #else /* >= 5.11.0 */ 173 | #define HAVE_XSK_BATCHED_DESCRIPTOR_INTERFACES 174 | #undef HAVE_XDP_RXQ_INFO_REG_3_PARAMS 175 | #define HAVE_XSK_TX_PEEK_RELEASE_DESC_BATCH_3_PARAMS 176 | #endif /* 5.11.0 */ 177 | 178 | /*****************************************************************************/ 179 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,12,0)) 180 | #define NEED_EXPORT_INDIRECT_CALLABLE 181 | #else /* >= 5.12.0 */ 182 | #define HAVE_DEVLINK_OPS_CREATE_DEL 183 | #endif /* 5.12.0 */ 184 | 185 | /*****************************************************************************/ 186 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,13,0)) 187 | #else /* >= 5.13.0 */ 188 | #define HAVE_XPS_MAP_TYPE 189 | #endif /* 5.13.0 */ 190 | 191 | /*****************************************************************************/ 192 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,14,0)) 193 | #else /* >= 5.14.0 */ 194 | #define HAVE_TTY_WRITE_ROOM_UINT 195 | #endif /* 5.14.0 */ 196 | 197 | /*****************************************************************************/ 198 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0)) 199 | #define NEED_DEVLINK_ALLOC_SETS_DEV 200 | #else /* >= 5.15.0 */ 201 | #define HAVE_DEVICE_IN_MDEV_PARENT_OPS 202 | #define NEED_PCI_IOV_VF_ID 203 | #define HAVE_DEVLINK_SET_STATE_3_PARAM 204 | #endif /* 5.15.0 */ 205 | 206 | /*****************************************************************************/ 207 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0)) 208 | #else /* >= 5.16.0 */ 209 | #define HAVE_XSK_BATCHED_RX_ALLOC 210 | #endif /* 5.16.0 */ 211 | 212 | /*****************************************************************************/ 213 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)) 214 | #else /* >=5.18.0*/ 215 | #undef NEED_PCI_IOV_VF_ID 216 | #undef HAVE_XSK_TX_PEEK_RELEASE_DESC_BATCH_3_PARAMS 217 | #endif /* 5.18.0 */ 218 | 219 | /*****************************************************************************/ 220 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(6,1,0)) 221 | #else /* >=6.1.0 */ 222 | #define HAVE_FLOW_DISSECTOR_KEY_L2TPV3 223 | #define HAVE_TTY_TERMIOS_CONST_STRUCT 224 | #endif /* 6.1.0 */ 225 | 226 | #endif /* _KCOMPAT_STD_DEFS_H_ */ 227 | -------------------------------------------------------------------------------- /src/kcompat_ubuntu_defs.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _KCOMPAT_UBUNTU_DEFS_H_ 5 | #define _KCOMPAT_UBUNTU_DEFS_H_ 6 | 7 | /* This file contains the definitions for the Ubuntu specific distribution of 8 | * the Linux kernel. 9 | * 10 | * It checks the UBUNTU_VERSION_CODE to decide which features are available in 11 | * the target kernel. It assumes that kcompat_std_defs.h has already been 12 | * processed, and will #define or #undef the relevant flags based on what 13 | * features were backported by Ubuntu. 14 | */ 15 | 16 | #if !UTS_UBUNTU_RELEASE_ABI 17 | #error "UTS_UBUNTU_RELEASE_ABI is 0 or undefined" 18 | #endif 19 | 20 | #if !UBUNTU_VERSION_CODE 21 | #error "UBUNTU_VERSION_CODE is 0 or undefined" 22 | #endif 23 | 24 | #ifndef UBUNTU_VERSION 25 | #error "UBUNTU_VERSION is undefined" 26 | #endif 27 | 28 | /*****************************************************************************/ 29 | #if (UBUNTU_VERSION_CODE >= UBUNTU_VERSION(4,15,0,159) && \ 30 | UBUNTU_VERSION_CODE < UBUNTU_VERSION(4,15,0,999)) 31 | #endif 32 | 33 | /*****************************************************************************/ 34 | #endif /* _KCOMPAT_UBUNTU_DEFS_H_ */ 35 | -------------------------------------------------------------------------------- /src/kcompat_vfd.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _KCOMPAT_VFD_H_ 5 | #define _KCOMPAT_VFD_H_ 6 | 7 | #define VFD_PROMISC_OFF 0x00 8 | #define VFD_PROMISC_UNICAST 0x01 9 | #define VFD_PROMISC_MULTICAST 0x02 10 | 11 | #define VFD_LINKSTATE_OFF 0x00 12 | #define VFD_LINKSTATE_ON 0x01 13 | #define VFD_LINKSTATE_AUTO 0x02 14 | 15 | #define VFD_EGRESS_MIRROR_OFF -1 16 | #define VFD_INGRESS_MIRROR_OFF -1 17 | 18 | #define VFD_QUEUE_TYPE_RSS 0x00 19 | #define VFD_QUEUE_TYPE_QOS 0x01 20 | 21 | #define VFD_NUM_TC 0x8 22 | 23 | /** 24 | * struct vfd_objects - VF-d kobjects information struct 25 | * @num_vfs: number of VFs allocated 26 | * @sriov_kobj: pointer to the top sriov kobject 27 | * @vf_kobj: array of pointer to each VF's kobjects 28 | */ 29 | struct vfd_objects { 30 | int num_vfs; 31 | struct kobject *sriov_kobj; 32 | struct vfd_vf_obj *vfs; 33 | struct vfd_qos_objects *qos; 34 | }; 35 | 36 | /** 37 | * struct vfd_vf_obj - VF-d VF kobjects information struct 38 | * @vf_kobj: pointer to VF qos kobject 39 | * @vf_qos_kobj: pointer to VF kobject 40 | * @vf_tc_kobj: pointer to VF TC kobjects 41 | */ 42 | struct vfd_vf_obj { 43 | struct kobject *vf_qos_kobj; 44 | struct kobject *vf_kobj; 45 | struct kobject *vf_tc_kobjs[VFD_NUM_TC]; 46 | }; 47 | 48 | /** 49 | * struct vfd_qos_objects - VF-d qos kobjects information struct 50 | * @qos_kobj: pointer to PF qos kobject 51 | * @pf_qos_kobj: pointer to PF TC kobjects 52 | */ 53 | struct vfd_qos_objects { 54 | struct kobject *qos_kobj; 55 | struct kobject *pf_qos_kobjs[VFD_NUM_TC]; 56 | }; 57 | 58 | struct vfd_macaddr { 59 | u8 mac[ETH_ALEN]; 60 | struct list_head list; 61 | }; 62 | 63 | #define VFD_LINK_SPEED_2_5GB_SHIFT 0x0 64 | #define VFD_LINK_SPEED_100MB_SHIFT 0x1 65 | #define VFD_LINK_SPEED_1GB_SHIFT 0x2 66 | #define VFD_LINK_SPEED_10GB_SHIFT 0x3 67 | #define VFD_LINK_SPEED_40GB_SHIFT 0x4 68 | #define VFD_LINK_SPEED_20GB_SHIFT 0x5 69 | #define VFD_LINK_SPEED_25GB_SHIFT 0x6 70 | #define VFD_LINK_SPEED_5GB_SHIFT 0x7 71 | 72 | enum vfd_link_speed { 73 | VFD_LINK_SPEED_UNKNOWN = 0, 74 | VFD_LINK_SPEED_100MB = BIT(VFD_LINK_SPEED_100MB_SHIFT), 75 | VFD_LINK_SPEED_1GB = BIT(VFD_LINK_SPEED_1GB_SHIFT), 76 | VFD_LINK_SPEED_2_5GB = BIT(VFD_LINK_SPEED_2_5GB_SHIFT), 77 | VFD_LINK_SPEED_5GB = BIT(VFD_LINK_SPEED_5GB_SHIFT), 78 | VFD_LINK_SPEED_10GB = BIT(VFD_LINK_SPEED_10GB_SHIFT), 79 | VFD_LINK_SPEED_40GB = BIT(VFD_LINK_SPEED_40GB_SHIFT), 80 | VFD_LINK_SPEED_20GB = BIT(VFD_LINK_SPEED_20GB_SHIFT), 81 | VFD_LINK_SPEED_25GB = BIT(VFD_LINK_SPEED_25GB_SHIFT), 82 | }; 83 | 84 | struct vfd_ops { 85 | int (*get_trunk)(struct pci_dev *pdev, int vf_id, unsigned long *buff); 86 | int (*set_trunk)(struct pci_dev *pdev, int vf_id, 87 | const unsigned long *buff); 88 | int (*get_vlan_mirror)(struct pci_dev *pdev, int vf_id, 89 | unsigned long *buff); 90 | int (*set_vlan_mirror)(struct pci_dev *pdev, int vf_id, 91 | const unsigned long *buff); 92 | int (*get_egress_mirror)(struct pci_dev *pdev, int vf_id, int *data); 93 | int (*set_egress_mirror)(struct pci_dev *pdev, int vf_id, 94 | const int data); 95 | int (*get_ingress_mirror)(struct pci_dev *pdev, int vf_id, int *data); 96 | int (*set_ingress_mirror)(struct pci_dev *pdev, int vf_id, 97 | const int data); 98 | int (*get_mac_anti_spoof)(struct pci_dev *pdev, int vf_id, bool *data); 99 | int (*set_mac_anti_spoof)(struct pci_dev *pdev, int vf_id, 100 | const bool data); 101 | int (*get_vlan_anti_spoof)(struct pci_dev *pdev, int vf_id, bool *data); 102 | int (*set_vlan_anti_spoof)(struct pci_dev *pdev, int vf_id, 103 | const bool data); 104 | int (*get_allow_untagged)(struct pci_dev *pdev, int vf_id, bool *data); 105 | int (*set_allow_untagged)(struct pci_dev *pdev, int vf_id, 106 | const bool data); 107 | int (*get_loopback)(struct pci_dev *pdev, int vf_id, bool *data); 108 | int (*set_loopback)(struct pci_dev *pdev, int vf_id, const bool data); 109 | int (*get_mac)(struct pci_dev *pdev, int vf_id, u8 *macaddr); 110 | int (*set_mac)(struct pci_dev *pdev, int vf_id, const u8 *macaddr); 111 | int (*get_mac_list)(struct pci_dev *pdev, int vf_id, 112 | struct list_head *mac_list); 113 | int (*add_macs_to_list)(struct pci_dev *pdev, int vf_id, 114 | struct list_head *mac_list); 115 | int (*rem_macs_from_list)(struct pci_dev *pdev, int vf_id, 116 | struct list_head *mac_list); 117 | int (*get_promisc)(struct pci_dev *pdev, int vf_id, u8 *data); 118 | int (*set_promisc)(struct pci_dev *pdev, int vf_id, const u8 data); 119 | int (*get_vlan_strip)(struct pci_dev *pdev, int vf_id, bool *data); 120 | int (*set_vlan_strip)(struct pci_dev *pdev, int vf_id, const bool data); 121 | int (*get_link_state)(struct pci_dev *pdev, int vf_id, bool *enabled, 122 | enum vfd_link_speed *link_speed); 123 | int (*set_link_state)(struct pci_dev *pdev, int vf_id, const u8 data); 124 | int (*get_max_tx_rate)(struct pci_dev *pdev, int vf_id, 125 | unsigned int *max_tx_rate); 126 | int (*set_max_tx_rate)(struct pci_dev *pdev, int vf_id, 127 | unsigned int *max_tx_rate); 128 | int (*get_min_tx_rate)(struct kobject *, 129 | struct kobj_attribute *, char *); 130 | int (*set_min_tx_rate)(struct kobject *, struct kobj_attribute *, 131 | const char *, size_t); 132 | int (*get_spoofcheck)(struct kobject *, 133 | struct kobj_attribute *, char *); 134 | int (*set_spoofcheck)(struct kobject *, struct kobj_attribute *, 135 | const char *, size_t); 136 | int (*get_trust)(struct kobject *, 137 | struct kobj_attribute *, char *); 138 | int (*set_trust)(struct kobject *, struct kobj_attribute *, 139 | const char *, size_t); 140 | int (*get_vf_enable)(struct pci_dev *pdev, int vf_id, bool *data); 141 | int (*set_vf_enable)(struct pci_dev *pdev, int vf_id, const bool data); 142 | int (*get_rx_bytes) (struct pci_dev *pdev, int vf_id, u64 *data); 143 | int (*get_rx_dropped)(struct pci_dev *pdev, int vf_id, u64 *data); 144 | int (*get_rx_packets)(struct pci_dev *pdev, int vf_id, u64 *data); 145 | int (*get_tx_bytes) (struct pci_dev *pdev, int vf_id, u64 *data); 146 | int (*get_tx_dropped)(struct pci_dev *pdev, int vf_id, u64 *data); 147 | int (*get_tx_packets)(struct pci_dev *pdev, int vf_id, u64 *data); 148 | int (*get_tx_spoofed)(struct pci_dev *pdev, int vf_id, u64 *data); 149 | int (*get_tx_errors)(struct pci_dev *pdev, int vf_id, u64 *data); 150 | int (*reset_stats)(struct pci_dev *pdev, int vf_id); 151 | int (*set_vf_bw_share)(struct pci_dev *pdev, int vf_id, u8 bw_share); 152 | int (*get_vf_bw_share)(struct pci_dev *pdev, int vf_id, u8 *bw_share); 153 | int (*set_pf_qos_apply)(struct pci_dev *pdev); 154 | int (*get_pf_ingress_mirror)(struct pci_dev *pdev, int *data); 155 | int (*set_pf_ingress_mirror)(struct pci_dev *pdev, const int data); 156 | int (*get_pf_egress_mirror)(struct pci_dev *pdev, int *data); 157 | int (*set_pf_egress_mirror)(struct pci_dev *pdev, const int data); 158 | int (*get_pf_tpid)(struct pci_dev *pdev, u16 *data); 159 | int (*set_pf_tpid)(struct pci_dev *pdev, const u16 data); 160 | int (*get_num_queues)(struct pci_dev *pdev, int vf_id, int *num_queues); 161 | int (*set_num_queues)(struct pci_dev *pdev, int vf_id, const int num_queues); 162 | int (*get_trust_state)(struct pci_dev *pdev, int vf_id, bool *data); 163 | int (*set_trust_state)(struct pci_dev *pdev, int vf_id, bool data); 164 | int (*get_queue_type)(struct pci_dev *pdev, int vf_id, u8 *data); 165 | int (*set_queue_type)(struct pci_dev *pdev, int vf_id, const u8 data); 166 | int (*get_allow_bcast)(struct pci_dev *pdev, int vf_id, bool *data); 167 | int (*set_allow_bcast)(struct pci_dev *pdev, int vf_id, const bool data); 168 | int (*get_pf_qos_tc_max_bw)(struct pci_dev *pdev, int tc, u16 *req_bw); 169 | int (*set_pf_qos_tc_max_bw)(struct pci_dev *pdev, int tc, u16 req_bw); 170 | int (*get_pf_qos_tc_lsp)(struct pci_dev *pdev, int tc, bool *on); 171 | int (*set_pf_qos_tc_lsp)(struct pci_dev *pdev, int tc, bool on); 172 | int (*get_pf_qos_tc_priority)(struct pci_dev *pdev, int tc, 173 | char *tc_bitmap); 174 | int (*set_pf_qos_tc_priority)(struct pci_dev *pdev, int tc, 175 | char tc_bitmap); 176 | int (*get_vf_qos_tc_share)(struct pci_dev *pdev, int vf_id, int tc, 177 | u8 *share); 178 | int (*set_vf_qos_tc_share)(struct pci_dev *pdev, int vf_id, int tc, 179 | u8 share); 180 | int (*get_vf_max_tc_tx_rate)(struct pci_dev *pdev, int vf_id, int tc, 181 | int *rate); 182 | int (*set_vf_max_tc_tx_rate)(struct pci_dev *pdev, int vf_id, int tc, 183 | int rate); 184 | }; 185 | 186 | extern const struct vfd_ops *vfd_ops; 187 | 188 | #endif /* _KCOMPAT_VFD_H_ */ 189 | -------------------------------------------------------------------------------- /src/linux/auxiliary_bus.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* Copyright (C) 2013-2025 Intel Corporation */ 3 | 4 | #ifndef _AUXILIARY_BUS_H_ 5 | #define _AUXILIARY_BUS_H_ 6 | 7 | /* The CRC of the exported symbols which depend on 'struct device' can change 8 | * if the definition of 'struct dev_pm_qos' is not included in this file, i.e. 9 | * if we don't include this file. 10 | */ 11 | #include 12 | #include 13 | #include 14 | #include "auxiliary_compat.h" 15 | 16 | #ifndef HAVE_AUXILIARY_DEVICE_ID 17 | /* For some kernel, auxiliary is not mature enough so that part code is 18 | * included, but no driver uses it. HAVE_AUXILIARY_DEVICE_ID will be 19 | * generated only when CONFIG_AUXILIARY_BUS is not defined. If 20 | * HAVE_AUXILIARY_DEVICE_ID is defined, it means struct 21 | * auxiliary_device_id and AUXILIARY_NAME_SIZE, AXUILIARY_MODULE_PREFIX 22 | * in is used. Otherwise need definition here. 23 | */ 24 | #define AUXILIARY_NAME_SIZE 32 25 | #define AUXILIARY_MODULE_PREFIX "intel_auxiliary:" 26 | struct auxiliary_device_id { 27 | char name[AUXILIARY_NAME_SIZE]; 28 | kernel_ulong_t driver_data; 29 | }; 30 | #endif 31 | 32 | #define AUX_PREFIX(func) intel_ ## func 33 | 34 | #define auxiliary_device_init AUX_PREFIX(auxiliary_device_init) 35 | #define __auxiliary_device_add AUX_PREFIX(__auxiliary_device_add) 36 | #define auxiliary_find_device AUX_PREFIX(auxiliary_find_device) 37 | #define __auxiliary_driver_register AUX_PREFIX(__auxiliary_driver_register) 38 | #define auxiliary_driver_unregister AUX_PREFIX(auxiliary_driver_unregister) 39 | 40 | struct auxiliary_device { 41 | struct device dev; 42 | const char *name; 43 | u32 id; 44 | }; 45 | 46 | struct auxiliary_driver { 47 | int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id); 48 | void (*remove)(struct auxiliary_device *auxdev); 49 | void (*shutdown)(struct auxiliary_device *auxdev); 50 | int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state); 51 | int (*resume)(struct auxiliary_device *auxdev); 52 | const char *name; 53 | struct device_driver driver; 54 | const struct auxiliary_device_id *id_table; 55 | }; 56 | 57 | static inline struct auxiliary_device *to_auxiliary_dev(struct device *dev) 58 | { 59 | return container_of(dev, struct auxiliary_device, dev); 60 | } 61 | 62 | static inline struct auxiliary_driver *to_auxiliary_drv(struct device_driver *drv) 63 | { 64 | return container_of(drv, struct auxiliary_driver, driver); 65 | } 66 | 67 | int auxiliary_device_init(struct auxiliary_device *auxdev); 68 | int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname); 69 | #define auxiliary_device_add(auxdev) __auxiliary_device_add(auxdev, KBUILD_MODNAME) 70 | 71 | static inline void auxiliary_device_uninit(struct auxiliary_device *auxdev) 72 | { 73 | put_device(&auxdev->dev); 74 | } 75 | 76 | static inline void auxiliary_device_delete(struct auxiliary_device *auxdev) 77 | { 78 | device_del(&auxdev->dev); 79 | } 80 | 81 | int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner, 82 | const char *modname); 83 | #define auxiliary_driver_register(auxdrv) \ 84 | __auxiliary_driver_register(auxdrv, THIS_MODULE, KBUILD_MODNAME) 85 | 86 | void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv); 87 | 88 | /** 89 | * module_auxiliary_driver() - Helper macro for registering an auxiliary driver 90 | * @__auxiliary_driver: auxiliary driver struct 91 | * 92 | * Helper macro for auxiliary drivers which do not do anything special in 93 | * module init/exit. This eliminates a lot of boilerplate. Each module may only 94 | * use this macro once, and calling it replaces module_init() and module_exit() 95 | */ 96 | #define module_auxiliary_driver(__auxiliary_driver) \ 97 | module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister) 98 | 99 | struct auxiliary_device *auxiliary_find_device(struct device *start, 100 | const void *data, 101 | int (*match)(struct device *dev, const void *data)); 102 | 103 | #endif /* _AUXILIARY_BUS_H_ */ 104 | --------------------------------------------------------------------------------