mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
Including fixes from bpf, wifi, and netfilter.
Current release - regressions: - bpf: fix nullness propagation for reg to reg comparisons, avoid null-deref - inet: control sockets should not use current thread task_frag - bpf: always use maximal size for copy_array() - eth: bnxt_en: don't link netdev to a devlink port for VFs Current release - new code bugs: - rxrpc: fix a couple of potential use-after-frees - netfilter: conntrack: fix IPv6 exthdr error check - wifi: iwlwifi: fw: skip PPAG for JF, avoid FW crashes - eth: dsa: qca8k: various fixes for the in-band register access - eth: nfp: fix schedule in atomic context when sync mc address - eth: renesas: rswitch: fix getting mac address from device tree - mobile: ipa: use proper endpoint mask for suspend Previous releases - regressions: - tcp: add TIME_WAIT sockets in bhash2, fix regression caught by Jiri / python tests - net: tc: don't intepret cls results when asked to drop, fix oob-access - vrf: determine the dst using the original ifindex for multicast - eth: bnxt_en: - fix XDP RX path if BPF adjusted packet length - fix HDS (header placement) and jumbo thresholds for RX packets - eth: ice: xsk: do not use xdp_return_frame() on tx_buf->raw_buf, avoid memory corruptions Previous releases - always broken: - ulp: prevent ULP without clone op from entering the LISTEN status - veth: fix race with AF_XDP exposing old or uninitialized descriptors - bpf: - pull before calling skb_postpull_rcsum() (fix checksum support and avoid a WARN()) - fix panic due to wrong pageattr of im->image (when livepatch and kretfunc coexist) - keep a reference to the mm, in case the task is dead - mptcp: fix deadlock in fastopen error path - netfilter: - nf_tables: perform type checking for existing sets - nf_tables: honor set timeout and garbage collection updates - ipset: fix hash:net,port,net hang with /0 subnet - ipset: avoid hung task warning when adding/deleting entries - selftests: net: - fix cmsg_so_mark.sh test hang on non-x86 systems - fix the arp_ndisc_evict_nocarrier test for IPv6 - usb: rndis_host: secure rndis_query check against int overflow - eth: r8169: fix dmar pte write access during suspend/resume with WOL - eth: lan966x: fix configuration of the PCS - eth: sparx5: fix reading of the MAC address - eth: qed: allow sleep in qed_mcp_trace_dump() - eth: hns3: - fix interrupts re-initialization after VF FLR - fix handling of promisc when MAC addr table gets full - refine the handling for VF heartbeat - eth: mlx5: - properly handle ingress QinQ-tagged packets on VST - fix io_eq_size and event_eq_size params validation on big endian - fix RoCE setting at HCA level if not supported at all - don't turn CQE compression on by default for IPoIB - eth: ena: - fix toeplitz initial hash key value - account for the number of XDP-processed bytes in interface stats - fix rx_copybreak value update Misc: - ethtool: harden phy stat handling against buggy drivers - docs: netdev: convert maintainer's doc from FAQ to a normal document Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmO3MLcACgkQMUZtbf5S IrsEQBAAijPrpxsGMfX+VMqZ8RPKA3Qg8XF3ji2fSp4c0kiKv6lYI7PzPTR3u/fj CAlhQMHv7z53uM6Zd7FdUVl23paaEycu8YnlwSubg9z+wSeh/RQ6iq94mSk1PV+K LLVR/yop2N35Yp/oc5KZMb9fMLkxRG9Ci73QUVVYgvIrSd4Zdm13FjfVjL2C1MZH Yp003wigMs9IkIHOpHjNqwn/5s//0yXsb1PgKxCsaMdMQsG0yC+7eyDmxshCqsji xQm15mkGMjvWEYJaa4Tj4L3JW6lWbQzCu9nqPUX16KpmrnScr8S8Is+aifFZIBeW GZeDYgvjSxNWodeOrJnD3X+fnbrR9+qfx7T9y7XighfytAz5DNm1LwVOvZKDgPFA s+LlxOhzkDNEqbIsusK/LW+04EFc5gJyTI2iR6s4SSqmH3c3coJZQJeyRFWDZy/x 1oqzcCcq8SwGUTJ9g6HAmDQoVkhDWDT/ZcRKhpWG0nJub972lB2iwM7LrAu+HoHI r8hyCkHpOi5S3WZKI9gPiGD+yOlpVAuG2wHg2IpjhKQvtd9DFUChGDhFeoB2rqJf 9uI3RJBBYTDkeNu3kpfy5uMh2XhvbIZntK5kwpJ4VettZWFMaOAzn7KNqk8iT4gJ ASMrUrX59X0TAN0MgpJJm7uGtKbKZOu4lHNm74TUxH7V7bYn7dk= =TlcN -----END PGP SIGNATURE----- Merge tag 'net-6.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from bpf, wifi, and netfilter. Current release - regressions: - bpf: fix nullness propagation for reg to reg comparisons, avoid null-deref - inet: control sockets should not use current thread task_frag - bpf: always use maximal size for copy_array() - eth: bnxt_en: don't link netdev to a devlink port for VFs Current release - new code bugs: - rxrpc: fix a couple of potential use-after-frees - netfilter: conntrack: fix IPv6 exthdr error check - wifi: iwlwifi: fw: skip PPAG for JF, avoid FW crashes - eth: dsa: qca8k: various fixes for the in-band register access - eth: nfp: fix schedule in atomic context when sync mc address - eth: renesas: rswitch: fix getting mac address from device tree - mobile: ipa: use proper endpoint mask for suspend Previous releases - regressions: - tcp: add TIME_WAIT sockets in bhash2, fix regression caught by Jiri / python tests - net: tc: don't intepret cls results when asked to drop, fix oob-access - vrf: determine the dst using the original ifindex for multicast - eth: bnxt_en: - fix XDP RX path if BPF adjusted packet length - fix HDS (header placement) and jumbo thresholds for RX packets - eth: ice: xsk: do not use xdp_return_frame() on tx_buf->raw_buf, avoid memory corruptions Previous releases - always broken: - ulp: prevent ULP without clone op from entering the LISTEN status - veth: fix race with AF_XDP exposing old or uninitialized descriptors - bpf: - pull before calling skb_postpull_rcsum() (fix checksum support and avoid a WARN()) - fix panic due to wrong pageattr of im->image (when livepatch and kretfunc coexist) - keep a reference to the mm, in case the task is dead - mptcp: fix deadlock in fastopen error path - netfilter: - nf_tables: perform type checking for existing sets - nf_tables: honor set timeout and garbage collection updates - ipset: fix hash:net,port,net hang with /0 subnet - ipset: avoid hung task warning when adding/deleting entries - selftests: net: - fix cmsg_so_mark.sh test hang on non-x86 systems - fix the arp_ndisc_evict_nocarrier test for IPv6 - usb: rndis_host: secure rndis_query check against int overflow - eth: r8169: fix dmar pte write access during suspend/resume with WOL - eth: lan966x: fix configuration of the PCS - eth: sparx5: fix reading of the MAC address - eth: qed: allow sleep in qed_mcp_trace_dump() - eth: hns3: - fix interrupts re-initialization after VF FLR - fix handling of promisc when MAC addr table gets full - refine the handling for VF heartbeat - eth: mlx5: - properly handle ingress QinQ-tagged packets on VST - fix io_eq_size and event_eq_size params validation on big endian - fix RoCE setting at HCA level if not supported at all - don't turn CQE compression on by default for IPoIB - eth: ena: - fix toeplitz initial hash key value - account for the number of XDP-processed bytes in interface stats - fix rx_copybreak value update Misc: - ethtool: harden phy stat handling against buggy drivers - docs: netdev: convert maintainer's doc from FAQ to a normal document" * tag 'net-6.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (112 commits) caif: fix memory leak in cfctrl_linkup_request() inet: control sockets should not use current thread task_frag net/ulp: prevent ULP without clone op from entering the LISTEN status qed: allow sleep in qed_mcp_trace_dump() MAINTAINERS: Update maintainers for ptp_vmw driver usb: rndis_host: Secure rndis_query check against int overflow net: dpaa: Fix dtsec check for PCS availability octeontx2-pf: Fix lmtst ID used in aura free drivers/net/bonding/bond_3ad: return when there's no aggregator netfilter: ipset: Rework long task execution when adding/deleting entries netfilter: ipset: fix hash:net,port,net hang with /0 subnet net: sparx5: Fix reading of the MAC address vxlan: Fix memory leaks in error path net: sched: htb: fix htb_classify() kernel-doc net: sched: cbq: dont intepret cls results when asked to drop net: sched: atm: dont intepret cls results when asked to drop dt-bindings: net: marvell,orion-mdio: Fix examples dt-bindings: net: sun8i-emac: Add phy-supply property net: ipa: use proper endpoint mask for suspend selftests: net: return non-zero for failures reported in arp_ndisc_evict_nocarrier ...
This commit is contained in:
commit
50011c32f4
@ -40,6 +40,9 @@ properties:
|
||||
clock-names:
|
||||
const: stmmaceth
|
||||
|
||||
phy-supply:
|
||||
description: PHY regulator
|
||||
|
||||
syscon:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
|
@ -16,9 +16,6 @@ description: |
|
||||
8k has a second unit which provides an interface with the xMDIO bus. This
|
||||
driver handles these interfaces.
|
||||
|
||||
allOf:
|
||||
- $ref: "mdio.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
@ -39,13 +36,38 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
allOf:
|
||||
- $ref: mdio.yaml#
|
||||
|
||||
- if:
|
||||
required:
|
||||
- interrupts
|
||||
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- items:
|
||||
- $ref: /schemas/types.yaml#/definitions/cell
|
||||
- const: 0x84
|
||||
|
||||
else:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- items:
|
||||
- $ref: /schemas/types.yaml#/definitions/cell
|
||||
- enum:
|
||||
- 0x4
|
||||
- 0x10
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mdio@d0072004 {
|
||||
compatible = "marvell,orion-mdio";
|
||||
reg = <0xd0072004 0x4>;
|
||||
reg = <0xd0072004 0x84>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
interrupts = <30>;
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
.. _netdev-FAQ:
|
||||
|
||||
==========
|
||||
netdev FAQ
|
||||
==========
|
||||
=============================
|
||||
Networking subsystem (netdev)
|
||||
=============================
|
||||
|
||||
tl;dr
|
||||
-----
|
||||
@ -15,14 +15,15 @@ tl;dr
|
||||
- don't repost your patches within one 24h period
|
||||
- reverse xmas tree
|
||||
|
||||
What is netdev?
|
||||
---------------
|
||||
It is a mailing list for all network-related Linux stuff. This
|
||||
netdev
|
||||
------
|
||||
|
||||
netdev is a mailing list for all network-related Linux stuff. This
|
||||
includes anything found under net/ (i.e. core code like IPv6) and
|
||||
drivers/net (i.e. hardware specific drivers) in the Linux source tree.
|
||||
|
||||
Note that some subsystems (e.g. wireless drivers) which have a high
|
||||
volume of traffic have their own specific mailing lists.
|
||||
volume of traffic have their own specific mailing lists and trees.
|
||||
|
||||
The netdev list is managed (like many other Linux mailing lists) through
|
||||
VGER (http://vger.kernel.org/) with archives available at
|
||||
@ -32,32 +33,10 @@ Aside from subsystems like those mentioned above, all network-related
|
||||
Linux development (i.e. RFC, review, comments, etc.) takes place on
|
||||
netdev.
|
||||
|
||||
How do the changes posted to netdev make their way into Linux?
|
||||
--------------------------------------------------------------
|
||||
There are always two trees (git repositories) in play. Both are
|
||||
driven by David Miller, the main network maintainer. There is the
|
||||
``net`` tree, and the ``net-next`` tree. As you can probably guess from
|
||||
the names, the ``net`` tree is for fixes to existing code already in the
|
||||
mainline tree from Linus, and ``net-next`` is where the new code goes
|
||||
for the future release. You can find the trees here:
|
||||
Development cycle
|
||||
-----------------
|
||||
|
||||
- https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
|
||||
- https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
|
||||
|
||||
How do I indicate which tree (net vs. net-next) my patch should be in?
|
||||
----------------------------------------------------------------------
|
||||
To help maintainers and CI bots you should explicitly mark which tree
|
||||
your patch is targeting. Assuming that you use git, use the prefix
|
||||
flag::
|
||||
|
||||
git format-patch --subject-prefix='PATCH net-next' start..finish
|
||||
|
||||
Use ``net`` instead of ``net-next`` (always lower case) in the above for
|
||||
bug-fix ``net`` content.
|
||||
|
||||
How often do changes from these trees make it to the mainline Linus tree?
|
||||
-------------------------------------------------------------------------
|
||||
To understand this, you need to know a bit of background information on
|
||||
Here is a bit of background information on
|
||||
the cadence of Linux development. Each new release starts off with a
|
||||
two week "merge window" where the main maintainers feed their new stuff
|
||||
to Linus for merging into the mainline tree. After the two weeks, the
|
||||
@ -69,9 +48,33 @@ rc2 is released. This repeats on a roughly weekly basis until rc7
|
||||
state of churn), and a week after the last vX.Y-rcN was done, the
|
||||
official vX.Y is released.
|
||||
|
||||
Relating that to netdev: At the beginning of the 2-week merge window,
|
||||
the ``net-next`` tree will be closed - no new changes/features. The
|
||||
accumulated new content of the past ~10 weeks will be passed onto
|
||||
To find out where we are now in the cycle - load the mainline (Linus)
|
||||
page here:
|
||||
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
|
||||
and note the top of the "tags" section. If it is rc1, it is early in
|
||||
the dev cycle. If it was tagged rc7 a week ago, then a release is
|
||||
probably imminent. If the most recent tag is a final release tag
|
||||
(without an ``-rcN`` suffix) - we are most likely in a merge window
|
||||
and ``net-next`` is closed.
|
||||
|
||||
git trees and patch flow
|
||||
------------------------
|
||||
|
||||
There are two networking trees (git repositories) in play. Both are
|
||||
driven by David Miller, the main network maintainer. There is the
|
||||
``net`` tree, and the ``net-next`` tree. As you can probably guess from
|
||||
the names, the ``net`` tree is for fixes to existing code already in the
|
||||
mainline tree from Linus, and ``net-next`` is where the new code goes
|
||||
for the future release. You can find the trees here:
|
||||
|
||||
- https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
|
||||
- https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
|
||||
|
||||
Relating that to kernel development: At the beginning of the 2-week
|
||||
merge window, the ``net-next`` tree will be closed - no new changes/features.
|
||||
The accumulated new content of the past ~10 weeks will be passed onto
|
||||
mainline/Linus via a pull request for vX.Y -- at the same time, the
|
||||
``net`` tree will start accumulating fixes for this pulled content
|
||||
relating to vX.Y
|
||||
@ -103,22 +106,14 @@ focus for ``net`` is on stabilization and bug fixes.
|
||||
|
||||
Finally, the vX.Y gets released, and the whole cycle starts over.
|
||||
|
||||
So where are we now in this cycle?
|
||||
----------------------------------
|
||||
netdev patch review
|
||||
-------------------
|
||||
|
||||
Load the mainline (Linus) page here:
|
||||
Patch status
|
||||
~~~~~~~~~~~~
|
||||
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
|
||||
and note the top of the "tags" section. If it is rc1, it is early in
|
||||
the dev cycle. If it was tagged rc7 a week ago, then a release is
|
||||
probably imminent. If the most recent tag is a final release tag
|
||||
(without an ``-rcN`` suffix) - we are most likely in a merge window
|
||||
and ``net-next`` is closed.
|
||||
|
||||
How can I tell the status of a patch I've sent?
|
||||
-----------------------------------------------
|
||||
Start by looking at the main patchworks queue for netdev:
|
||||
Status of a patch can be checked by looking at the main patchwork
|
||||
queue for netdev:
|
||||
|
||||
https://patchwork.kernel.org/project/netdevbpf/list/
|
||||
|
||||
@ -127,8 +122,20 @@ patch. Patches are indexed by the ``Message-ID`` header of the emails
|
||||
which carried them so if you have trouble finding your patch append
|
||||
the value of ``Message-ID`` to the URL above.
|
||||
|
||||
How long before my patch is accepted?
|
||||
-------------------------------------
|
||||
Updating patch status
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It may be tempting to help the maintainers and update the state of your
|
||||
own patches when you post a new version or spot a bug. Please **do not**
|
||||
do that.
|
||||
Interfering with the patch status on patchwork will only cause confusion. Leave
|
||||
it to the maintainer to figure out what is the most recent and current
|
||||
version that should be applied. If there is any doubt, the maintainer
|
||||
will reply and ask what should be done.
|
||||
|
||||
Review timelines
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Generally speaking, the patches get triaged quickly (in less than
|
||||
48h). But be patient, if your patch is active in patchwork (i.e. it's
|
||||
listed on the project's patch list) the chances it was missed are close to zero.
|
||||
@ -136,116 +143,47 @@ Asking the maintainer for status updates on your
|
||||
patch is a good way to ensure your patch is ignored or pushed to the
|
||||
bottom of the priority list.
|
||||
|
||||
Should I directly update patchwork state of my own patches?
|
||||
-----------------------------------------------------------
|
||||
It may be tempting to help the maintainers and update the state of your
|
||||
own patches when you post a new version or spot a bug. Please do not do that.
|
||||
Interfering with the patch status on patchwork will only cause confusion. Leave
|
||||
it to the maintainer to figure out what is the most recent and current
|
||||
version that should be applied. If there is any doubt, the maintainer
|
||||
will reply and ask what should be done.
|
||||
Partial resends
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
How do I divide my work into patches?
|
||||
-------------------------------------
|
||||
|
||||
Put yourself in the shoes of the reviewer. Each patch is read separately
|
||||
and therefore should constitute a comprehensible step towards your stated
|
||||
goal.
|
||||
|
||||
Avoid sending series longer than 15 patches. Larger series takes longer
|
||||
to review as reviewers will defer looking at it until they find a large
|
||||
chunk of time. A small series can be reviewed in a short time, so Maintainers
|
||||
just do it. As a result, a sequence of smaller series gets merged quicker and
|
||||
with better review coverage. Re-posting large series also increases the mailing
|
||||
list traffic.
|
||||
|
||||
I made changes to only a few patches in a patch series should I resend only those changed?
|
||||
------------------------------------------------------------------------------------------
|
||||
No, please resend the entire patch series and make sure you do number your
|
||||
Please always resend the entire patch series and make sure you do number your
|
||||
patches such that it is clear this is the latest and greatest set of patches
|
||||
that can be applied.
|
||||
that can be applied. Do not try to resend just the patches which changed.
|
||||
|
||||
I have received review feedback, when should I post a revised version of the patches?
|
||||
-------------------------------------------------------------------------------------
|
||||
Allow at least 24 hours to pass between postings. This will ensure reviewers
|
||||
from all geographical locations have a chance to chime in. Do not wait
|
||||
too long (weeks) between postings either as it will make it harder for reviewers
|
||||
to recall all the context.
|
||||
Handling misapplied patches
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Make sure you address all the feedback in your new posting. Do not post a new
|
||||
version of the code if the discussion about the previous version is still
|
||||
ongoing, unless directly instructed by a reviewer.
|
||||
|
||||
I submitted multiple versions of a patch series and it looks like a version other than the last one has been accepted, what should I do?
|
||||
----------------------------------------------------------------------------------------------------------------------------------------
|
||||
Occasionally a patch series gets applied before receiving critical feedback,
|
||||
or the wrong version of a series gets applied.
|
||||
There is no revert possible, once it is pushed out, it stays like that.
|
||||
Please send incremental versions on top of what has been merged in order to fix
|
||||
the patches the way they would look like if your latest patch series was to be
|
||||
merged.
|
||||
|
||||
Are there special rules regarding stable submissions on netdev?
|
||||
---------------------------------------------------------------
|
||||
Stable tree
|
||||
~~~~~~~~~~~
|
||||
|
||||
While it used to be the case that netdev submissions were not supposed
|
||||
to carry explicit ``CC: stable@vger.kernel.org`` tags that is no longer
|
||||
the case today. Please follow the standard stable rules in
|
||||
:ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`,
|
||||
and make sure you include appropriate Fixes tags!
|
||||
|
||||
Is the comment style convention different for the networking content?
|
||||
---------------------------------------------------------------------
|
||||
Yes, in a largely trivial way. Instead of this::
|
||||
Security fixes
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
/*
|
||||
* foobar blah blah blah
|
||||
* another line of text
|
||||
*/
|
||||
|
||||
it is requested that you make it look like this::
|
||||
|
||||
/* foobar blah blah blah
|
||||
* another line of text
|
||||
*/
|
||||
|
||||
What is "reverse xmas tree"?
|
||||
----------------------------
|
||||
|
||||
Netdev has a convention for ordering local variables in functions.
|
||||
Order the variable declaration lines longest to shortest, e.g.::
|
||||
|
||||
struct scatterlist *sg;
|
||||
struct sk_buff *skb;
|
||||
int err, i;
|
||||
|
||||
If there are dependencies between the variables preventing the ordering
|
||||
move the initialization out of line.
|
||||
|
||||
I am working in existing code which uses non-standard formatting. Which formatting should I use?
|
||||
------------------------------------------------------------------------------------------------
|
||||
Make your code follow the most recent guidelines, so that eventually all code
|
||||
in the domain of netdev is in the preferred format.
|
||||
|
||||
I found a bug that might have possible security implications or similar. Should I mail the main netdev maintainer off-list?
|
||||
---------------------------------------------------------------------------------------------------------------------------
|
||||
No. The current netdev maintainer has consistently requested that
|
||||
Do not email netdev maintainers directly if you think you discovered
|
||||
a bug that might have possible security implications.
|
||||
The current netdev maintainer has consistently requested that
|
||||
people use the mailing lists and not reach out directly. If you aren't
|
||||
OK with that, then perhaps consider mailing security@kernel.org or
|
||||
reading about http://oss-security.openwall.org/wiki/mailing-lists/distros
|
||||
as possible alternative mechanisms.
|
||||
|
||||
What level of testing is expected before I submit my change?
|
||||
------------------------------------------------------------
|
||||
At the very minimum your changes must survive an ``allyesconfig`` and an
|
||||
``allmodconfig`` build with ``W=1`` set without new warnings or failures.
|
||||
|
||||
Ideally you will have done run-time testing specific to your change,
|
||||
and the patch series contains a set of kernel selftest for
|
||||
``tools/testing/selftests/net`` or using the KUnit framework.
|
||||
Co-posting changes to user space components
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You are expected to test your changes on top of the relevant networking
|
||||
tree (``net`` or ``net-next``) and not e.g. a stable tree or ``linux-next``.
|
||||
|
||||
How do I post corresponding changes to user space components?
|
||||
-------------------------------------------------------------
|
||||
User space code exercising kernel features should be posted
|
||||
alongside kernel patches. This gives reviewers a chance to see
|
||||
how any new interface is used and how well it works.
|
||||
@ -270,42 +208,10 @@ to the mailing list, e.g.::
|
||||
Posting as one thread is discouraged because it confuses patchwork
|
||||
(as of patchwork 2.2.2).
|
||||
|
||||
Can I reproduce the checks from patchwork on my local machine?
|
||||
--------------------------------------------------------------
|
||||
Preparing changes
|
||||
-----------------
|
||||
|
||||
Checks in patchwork are mostly simple wrappers around existing kernel
|
||||
scripts, the sources are available at:
|
||||
|
||||
https://github.com/kuba-moo/nipa/tree/master/tests
|
||||
|
||||
Running all the builds and checks locally is a pain, can I post my patches and have the patchwork bot validate them?
|
||||
--------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
No, you must ensure that your patches are ready by testing them locally
|
||||
before posting to the mailing list. The patchwork build bot instance
|
||||
gets overloaded very easily and netdev@vger really doesn't need more
|
||||
traffic if we can help it.
|
||||
|
||||
netdevsim is great, can I extend it for my out-of-tree tests?
|
||||
-------------------------------------------------------------
|
||||
|
||||
No, ``netdevsim`` is a test vehicle solely for upstream tests.
|
||||
(Please add your tests under ``tools/testing/selftests/``.)
|
||||
|
||||
We also give no guarantees that ``netdevsim`` won't change in the future
|
||||
in a way which would break what would normally be considered uAPI.
|
||||
|
||||
Is netdevsim considered a "user" of an API?
|
||||
-------------------------------------------
|
||||
|
||||
Linux kernel has a long standing rule that no API should be added unless
|
||||
it has a real, in-tree user. Mock-ups and tests based on ``netdevsim`` are
|
||||
strongly encouraged when adding new APIs, but ``netdevsim`` in itself
|
||||
is **not** considered a use case/user.
|
||||
|
||||
Any other tips to help ensure my net/net-next patch gets OK'd?
|
||||
--------------------------------------------------------------
|
||||
Attention to detail. Re-read your own work as if you were the
|
||||
Attention to detail is important. Re-read your own work as if you were the
|
||||
reviewer. You can start with using ``checkpatch.pl``, perhaps even with
|
||||
the ``--strict`` flag. But do not be mindlessly robotic in doing so.
|
||||
If your change is a bug fix, make sure your commit log indicates the
|
||||
@ -320,10 +226,133 @@ Finally, go back and read
|
||||
:ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
|
||||
to be sure you are not repeating some common mistake documented there.
|
||||
|
||||
My company uses peer feedback in employee performance reviews. Can I ask netdev maintainers for feedback?
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
Indicating target tree
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Yes, especially if you spend significant amount of time reviewing code
|
||||
To help maintainers and CI bots you should explicitly mark which tree
|
||||
your patch is targeting. Assuming that you use git, use the prefix
|
||||
flag::
|
||||
|
||||
git format-patch --subject-prefix='PATCH net-next' start..finish
|
||||
|
||||
Use ``net`` instead of ``net-next`` (always lower case) in the above for
|
||||
bug-fix ``net`` content.
|
||||
|
||||
Dividing work into patches
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Put yourself in the shoes of the reviewer. Each patch is read separately
|
||||
and therefore should constitute a comprehensible step towards your stated
|
||||
goal.
|
||||
|
||||
Avoid sending series longer than 15 patches. Larger series takes longer
|
||||
to review as reviewers will defer looking at it until they find a large
|
||||
chunk of time. A small series can be reviewed in a short time, so Maintainers
|
||||
just do it. As a result, a sequence of smaller series gets merged quicker and
|
||||
with better review coverage. Re-posting large series also increases the mailing
|
||||
list traffic.
|
||||
|
||||
Multi-line comments
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Comment style convention is slightly different for networking and most of
|
||||
the tree. Instead of this::
|
||||
|
||||
/*
|
||||
* foobar blah blah blah
|
||||
* another line of text
|
||||
*/
|
||||
|
||||
it is requested that you make it look like this::
|
||||
|
||||
/* foobar blah blah blah
|
||||
* another line of text
|
||||
*/
|
||||
|
||||
Local variable ordering ("reverse xmas tree", "RCS")
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Netdev has a convention for ordering local variables in functions.
|
||||
Order the variable declaration lines longest to shortest, e.g.::
|
||||
|
||||
struct scatterlist *sg;
|
||||
struct sk_buff *skb;
|
||||
int err, i;
|
||||
|
||||
If there are dependencies between the variables preventing the ordering
|
||||
move the initialization out of line.
|
||||
|
||||
Format precedence
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
When working in existing code which uses nonstandard formatting make
|
||||
your code follow the most recent guidelines, so that eventually all code
|
||||
in the domain of netdev is in the preferred format.
|
||||
|
||||
Resending after review
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Allow at least 24 hours to pass between postings. This will ensure reviewers
|
||||
from all geographical locations have a chance to chime in. Do not wait
|
||||
too long (weeks) between postings either as it will make it harder for reviewers
|
||||
to recall all the context.
|
||||
|
||||
Make sure you address all the feedback in your new posting. Do not post a new
|
||||
version of the code if the discussion about the previous version is still
|
||||
ongoing, unless directly instructed by a reviewer.
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
Expected level of testing
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
At the very minimum your changes must survive an ``allyesconfig`` and an
|
||||
``allmodconfig`` build with ``W=1`` set without new warnings or failures.
|
||||
|
||||
Ideally you will have done run-time testing specific to your change,
|
||||
and the patch series contains a set of kernel selftest for
|
||||
``tools/testing/selftests/net`` or using the KUnit framework.
|
||||
|
||||
You are expected to test your changes on top of the relevant networking
|
||||
tree (``net`` or ``net-next``) and not e.g. a stable tree or ``linux-next``.
|
||||
|
||||
patchwork checks
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Checks in patchwork are mostly simple wrappers around existing kernel
|
||||
scripts, the sources are available at:
|
||||
|
||||
https://github.com/kuba-moo/nipa/tree/master/tests
|
||||
|
||||
**Do not** post your patches just to run them through the checks.
|
||||
You must ensure that your patches are ready by testing them locally
|
||||
before posting to the mailing list. The patchwork build bot instance
|
||||
gets overloaded very easily and netdev@vger really doesn't need more
|
||||
traffic if we can help it.
|
||||
|
||||
netdevsim
|
||||
~~~~~~~~~
|
||||
|
||||
``netdevsim`` is a test driver which can be used to exercise driver
|
||||
configuration APIs without requiring capable hardware.
|
||||
Mock-ups and tests based on ``netdevsim`` are strongly encouraged when
|
||||
adding new APIs, but ``netdevsim`` in itself is **not** considered
|
||||
a use case/user. You must also implement the new APIs in a real driver.
|
||||
|
||||
We give no guarantees that ``netdevsim`` won't change in the future
|
||||
in a way which would break what would normally be considered uAPI.
|
||||
|
||||
``netdevsim`` is reserved for use by upstream tests only, so any
|
||||
new ``netdevsim`` features must be accompanied by selftests under
|
||||
``tools/testing/selftests/``.
|
||||
|
||||
Testimonials / feedback
|
||||
-----------------------
|
||||
|
||||
Some companies use peer feedback in employee performance reviews.
|
||||
Please feel free to request feedback from netdev maintainers,
|
||||
especially if you spend significant amount of time reviewing code
|
||||
and go out of your way to improve shared infrastructure.
|
||||
|
||||
The feedback must be requested by you, the contributor, and will always
|
||||
|
@ -22246,7 +22246,9 @@ F: drivers/scsi/vmw_pvscsi.c
|
||||
F: drivers/scsi/vmw_pvscsi.h
|
||||
|
||||
VMWARE VIRTUAL PTP CLOCK DRIVER
|
||||
M: Vivek Thampi <vithampi@vmware.com>
|
||||
M: Srivatsa S. Bhat (VMware) <srivatsa@csail.mit.edu>
|
||||
M: Deep Shah <sdeep@vmware.com>
|
||||
R: Alexey Makhalov <amakhalov@vmware.com>
|
||||
R: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
|
@ -659,3 +659,19 @@
|
||||
interrupts = <16 2 1 9>;
|
||||
};
|
||||
};
|
||||
|
||||
&fman0_rx_0x08 {
|
||||
/delete-property/ fsl,fman-10g-port;
|
||||
};
|
||||
|
||||
&fman0_tx_0x28 {
|
||||
/delete-property/ fsl,fman-10g-port;
|
||||
};
|
||||
|
||||
&fman0_rx_0x09 {
|
||||
/delete-property/ fsl,fman-10g-port;
|
||||
};
|
||||
|
||||
&fman0_tx_0x29 {
|
||||
/delete-property/ fsl,fman-10g-port;
|
||||
};
|
||||
|
@ -1549,6 +1549,7 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr)
|
||||
slave_err(bond->dev, port->slave->dev,
|
||||
"Port %d did not find a suitable aggregator\n",
|
||||
port->actor_port_number);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* if all aggregator's ports are READY_N == TRUE, set ready=TRUE
|
||||
|
@ -2654,10 +2654,12 @@ static void bond_miimon_link_change(struct bonding *bond,
|
||||
|
||||
static void bond_miimon_commit(struct bonding *bond)
|
||||
{
|
||||
struct slave *slave, *primary;
|
||||
struct slave *slave, *primary, *active;
|
||||
bool do_failover = false;
|
||||
struct list_head *iter;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
bond_for_each_slave(bond, slave, iter) {
|
||||
switch (slave->link_new_state) {
|
||||
case BOND_LINK_NOCHANGE:
|
||||
@ -2700,8 +2702,8 @@ static void bond_miimon_commit(struct bonding *bond)
|
||||
|
||||
bond_miimon_link_change(bond, slave, BOND_LINK_UP);
|
||||
|
||||
if (!rcu_access_pointer(bond->curr_active_slave) || slave == primary ||
|
||||
slave->prio > rcu_dereference(bond->curr_active_slave)->prio)
|
||||
active = rtnl_dereference(bond->curr_active_slave);
|
||||
if (!active || slave == primary || slave->prio > active->prio)
|
||||
do_failover = true;
|
||||
|
||||
continue;
|
||||
|
@ -2,7 +2,6 @@
|
||||
config NET_DSA_MV88E6XXX
|
||||
tristate "Marvell 88E6xxx Ethernet switch fabric support"
|
||||
depends on NET_DSA
|
||||
depends on PTP_1588_CLOCK_OPTIONAL
|
||||
select IRQ_DOMAIN
|
||||
select NET_DSA_TAG_EDSA
|
||||
select NET_DSA_TAG_DSA
|
||||
@ -13,7 +12,8 @@ config NET_DSA_MV88E6XXX
|
||||
config NET_DSA_MV88E6XXX_PTP
|
||||
bool "PTP support for Marvell 88E6xxx"
|
||||
default n
|
||||
depends on NET_DSA_MV88E6XXX && PTP_1588_CLOCK
|
||||
depends on (NET_DSA_MV88E6XXX = y && PTP_1588_CLOCK = y) || \
|
||||
(NET_DSA_MV88E6XXX = m && PTP_1588_CLOCK)
|
||||
help
|
||||
Say Y to enable PTP hardware timestamping on Marvell 88E6xxx switch
|
||||
chips that support it.
|
||||
|
@ -37,77 +37,104 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
|
||||
}
|
||||
|
||||
static int
|
||||
qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo)
|
||||
qca8k_mii_write_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
|
||||
{
|
||||
u16 *cached_lo = &priv->mdio_cache.lo;
|
||||
struct mii_bus *bus = priv->bus;
|
||||
int ret;
|
||||
u16 lo;
|
||||
|
||||
if (lo == *cached_lo)
|
||||
return 0;
|
||||
|
||||
lo = val & 0xffff;
|
||||
ret = bus->write(bus, phy_id, regnum, lo);
|
||||
if (ret < 0)
|
||||
dev_err_ratelimited(&bus->dev,
|
||||
"failed to write qca8k 32bit lo register\n");
|
||||
|
||||
*cached_lo = lo;
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi)
|
||||
qca8k_mii_write_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
|
||||
{
|
||||
u16 *cached_hi = &priv->mdio_cache.hi;
|
||||
struct mii_bus *bus = priv->bus;
|
||||
int ret;
|
||||
u16 hi;
|
||||
|
||||
if (hi == *cached_hi)
|
||||
return 0;
|
||||
|
||||
hi = (u16)(val >> 16);
|
||||
ret = bus->write(bus, phy_id, regnum, hi);
|
||||
if (ret < 0)
|
||||
dev_err_ratelimited(&bus->dev,
|
||||
"failed to write qca8k 32bit hi register\n");
|
||||
|
||||
*cached_hi = hi;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
qca8k_mii_read_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bus->read(bus, phy_id, regnum);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
*val = ret & 0xffff;
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_err_ratelimited(&bus->dev,
|
||||
"failed to read qca8k 32bit lo register\n");
|
||||
*val = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
qca8k_mii_read_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bus->read(bus, phy_id, regnum);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
*val = ret << 16;
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_err_ratelimited(&bus->dev,
|
||||
"failed to read qca8k 32bit hi register\n");
|
||||
*val = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
|
||||
{
|
||||
u32 hi, lo;
|
||||
int ret;
|
||||
|
||||
ret = bus->read(bus, phy_id, regnum);
|
||||
if (ret >= 0) {
|
||||
*val = ret;
|
||||
ret = bus->read(bus, phy_id, regnum + 1);
|
||||
*val |= ret << 16;
|
||||
}
|
||||
*val = 0;
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err_ratelimited(&bus->dev,
|
||||
"failed to read qca8k 32bit register\n");
|
||||
*val = 0;
|
||||
return ret;
|
||||
}
|
||||
ret = qca8k_mii_read_lo(bus, phy_id, regnum, &lo);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
ret = qca8k_mii_read_hi(bus, phy_id, regnum + 1, &hi);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
*val = lo | hi;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val)
|
||||
qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
|
||||
{
|
||||
u16 lo, hi;
|
||||
int ret;
|
||||
if (qca8k_mii_write_lo(bus, phy_id, regnum, val) < 0)
|
||||
return;
|
||||
|
||||
lo = val & 0xffff;
|
||||
hi = (u16)(val >> 16);
|
||||
|
||||
ret = qca8k_set_lo(priv, phy_id, regnum, lo);
|
||||
if (ret >= 0)
|
||||
ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi);
|
||||
qca8k_mii_write_hi(bus, phy_id, regnum + 1, val);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -146,7 +173,16 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
|
||||
|
||||
command = get_unaligned_le32(&mgmt_ethhdr->command);
|
||||
cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command);
|
||||
|
||||
len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command);
|
||||
/* Special case for len of 15 as this is the max value for len and needs to
|
||||
* be increased before converting it from word to dword.
|
||||
*/
|
||||
if (len == 15)
|
||||
len++;
|
||||
|
||||
/* We can ignore odd value, we always round up them in the alloc function. */
|
||||
len *= sizeof(u16);
|
||||
|
||||
/* Make sure the seq match the requested packet */
|
||||
if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq)
|
||||
@ -193,17 +229,33 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
/* Max value for len reg is 15 (0xf) but the switch actually return 16 byte
|
||||
* Actually for some reason the steps are:
|
||||
* 0: nothing
|
||||
* 1-4: first 4 byte
|
||||
* 5-6: first 12 byte
|
||||
* 7-15: all 16 byte
|
||||
/* Hdr mgmt length value is in step of word size.
|
||||
* As an example to process 4 byte of data the correct length to set is 2.
|
||||
* To process 8 byte 4, 12 byte 6, 16 byte 8...
|
||||
*
|
||||
* Odd values will always return the next size on the ack packet.
|
||||
* (length of 3 (6 byte) will always return 8 bytes of data)
|
||||
*
|
||||
* This means that a value of 15 (0xf) actually means reading/writing 32 bytes
|
||||
* of data.
|
||||
*
|
||||
* To correctly calculate the length we devide the requested len by word and
|
||||
* round up.
|
||||
* On the ack function we can skip the odd check as we already handle the
|
||||
* case here.
|
||||
*/
|
||||
if (len == 16)
|
||||
real_len = 15;
|
||||
else
|
||||
real_len = len;
|
||||
real_len = DIV_ROUND_UP(len, sizeof(u16));
|
||||
|
||||
/* We check if the result len is odd and we round up another time to
|
||||
* the next size. (length of 3 will be increased to 4 as switch will always
|
||||
* return 8 bytes)
|
||||
*/
|
||||
if (real_len % sizeof(u16) != 0)
|
||||
real_len++;
|
||||
|
||||
/* Max reg value is 0xf(15) but switch will always return the next size (32 byte) */
|
||||
if (real_len == 16)
|
||||
real_len--;
|
||||
|
||||
skb_reset_mac_header(skb);
|
||||
skb_set_network_header(skb, skb->len);
|
||||
@ -417,7 +469,7 @@ qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
qca8k_mii_write32(priv, 0x10 | r2, r1, val);
|
||||
qca8k_mii_write32(bus, 0x10 | r2, r1, val);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&bus->mdio_lock);
|
||||
@ -450,7 +502,7 @@ qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_
|
||||
|
||||
val &= ~mask;
|
||||
val |= write_val;
|
||||
qca8k_mii_write32(priv, 0x10 | r2, r1, val);
|
||||
qca8k_mii_write32(bus, 0x10 | r2, r1, val);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&bus->mdio_lock);
|
||||
@ -688,9 +740,9 @@ qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)
|
||||
|
||||
qca8k_split_addr(reg, &r1, &r2, &page);
|
||||
|
||||
ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0,
|
||||
ret = read_poll_timeout(qca8k_mii_read_hi, ret1, !(val & mask), 0,
|
||||
QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
|
||||
bus, 0x10 | r2, r1, &val);
|
||||
bus, 0x10 | r2, r1 + 1, &val);
|
||||
|
||||
/* Check if qca8k_read has failed for a different reason
|
||||
* before returnting -ETIMEDOUT
|
||||
@ -725,14 +777,14 @@ qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data)
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
qca8k_mii_write32(priv, 0x10 | r2, r1, val);
|
||||
qca8k_mii_write32(bus, 0x10 | r2, r1, val);
|
||||
|
||||
ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
|
||||
QCA8K_MDIO_MASTER_BUSY);
|
||||
|
||||
exit:
|
||||
/* even if the busy_wait timeouts try to clear the MASTER_EN */
|
||||
qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
|
||||
qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0);
|
||||
|
||||
mutex_unlock(&bus->mdio_lock);
|
||||
|
||||
@ -762,18 +814,18 @@ qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
qca8k_mii_write32(priv, 0x10 | r2, r1, val);
|
||||
qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, val);
|
||||
|
||||
ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
|
||||
QCA8K_MDIO_MASTER_BUSY);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
|
||||
ret = qca8k_mii_read_lo(bus, 0x10 | r2, r1, &val);
|
||||
|
||||
exit:
|
||||
/* even if the busy_wait timeouts try to clear the MASTER_EN */
|
||||
qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
|
||||
qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0);
|
||||
|
||||
mutex_unlock(&bus->mdio_lock);
|
||||
|
||||
@ -1943,8 +1995,6 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
|
||||
}
|
||||
|
||||
priv->mdio_cache.page = 0xffff;
|
||||
priv->mdio_cache.lo = 0xffff;
|
||||
priv->mdio_cache.hi = 0xffff;
|
||||
|
||||
/* Check the detected switch id */
|
||||
ret = qca8k_read_switch_id(priv);
|
||||
|
@ -375,11 +375,6 @@ struct qca8k_mdio_cache {
|
||||
* mdio writes
|
||||
*/
|
||||
u16 page;
|
||||
/* lo and hi can also be cached and from Documentation we can skip one
|
||||
* extra mdio write if lo or hi is didn't change.
|
||||
*/
|
||||
u16 lo;
|
||||
u16 hi;
|
||||
};
|
||||
|
||||
struct qca8k_pcs {
|
||||
|
@ -2400,29 +2400,18 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
switch (func) {
|
||||
case ENA_ADMIN_TOEPLITZ:
|
||||
if (key) {
|
||||
if (key_len != sizeof(hash_key->key)) {
|
||||
netdev_err(ena_dev->net_device,
|
||||
"key len (%u) doesn't equal the supported size (%zu)\n",
|
||||
key_len, sizeof(hash_key->key));
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(hash_key->key, key, key_len);
|
||||
rss->hash_init_val = init_val;
|
||||
hash_key->key_parts = key_len / sizeof(hash_key->key[0]);
|
||||
if ((func == ENA_ADMIN_TOEPLITZ) && key) {
|
||||
if (key_len != sizeof(hash_key->key)) {
|
||||
netdev_err(ena_dev->net_device,
|
||||
"key len (%u) doesn't equal the supported size (%zu)\n",
|
||||
key_len, sizeof(hash_key->key));
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case ENA_ADMIN_CRC32:
|
||||
rss->hash_init_val = init_val;
|
||||
break;
|
||||
default:
|
||||
netdev_err(ena_dev->net_device, "Invalid hash function (%d)\n",
|
||||
func);
|
||||
return -EINVAL;
|
||||
memcpy(hash_key->key, key, key_len);
|
||||
hash_key->key_parts = key_len / sizeof(hash_key->key[0]);
|
||||
}
|
||||
|
||||
rss->hash_init_val = init_val;
|
||||
old_func = rss->hash_func;
|
||||
rss->hash_func = func;
|
||||
rc = ena_com_set_hash_function(ena_dev);
|
||||
|
@ -887,11 +887,7 @@ static int ena_set_tunable(struct net_device *netdev,
|
||||
switch (tuna->id) {
|
||||
case ETHTOOL_RX_COPYBREAK:
|
||||
len = *(u32 *)data;
|
||||
if (len > adapter->netdev->mtu) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
adapter->rx_copybreak = len;
|
||||
ret = ena_set_rx_copybreak(adapter, len);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
|
@ -374,9 +374,9 @@ static int ena_xdp_xmit(struct net_device *dev, int n,
|
||||
|
||||
static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
|
||||
{
|
||||
u32 verdict = ENA_XDP_PASS;
|
||||
struct bpf_prog *xdp_prog;
|
||||
struct ena_ring *xdp_ring;
|
||||
u32 verdict = XDP_PASS;
|
||||
struct xdp_frame *xdpf;
|
||||
u64 *xdp_stat;
|
||||
|
||||
@ -393,7 +393,7 @@ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
|
||||
if (unlikely(!xdpf)) {
|
||||
trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
|
||||
xdp_stat = &rx_ring->rx_stats.xdp_aborted;
|
||||
verdict = XDP_ABORTED;
|
||||
verdict = ENA_XDP_DROP;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -409,29 +409,35 @@ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
|
||||
|
||||
spin_unlock(&xdp_ring->xdp_tx_lock);
|
||||
xdp_stat = &rx_ring->rx_stats.xdp_tx;
|
||||
verdict = ENA_XDP_TX;
|
||||
break;
|
||||
case XDP_REDIRECT:
|
||||
if (likely(!xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog))) {
|
||||
xdp_stat = &rx_ring->rx_stats.xdp_redirect;
|
||||
verdict = ENA_XDP_REDIRECT;
|
||||
break;
|
||||
}
|
||||
trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
|
||||
xdp_stat = &rx_ring->rx_stats.xdp_aborted;
|
||||
verdict = XDP_ABORTED;
|
||||
verdict = ENA_XDP_DROP;
|
||||
break;
|
||||
case XDP_ABORTED:
|
||||
trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
|
||||
xdp_stat = &rx_ring->rx_stats.xdp_aborted;
|
||||
verdict = ENA_XDP_DROP;
|
||||
break;
|
||||
case XDP_DROP:
|
||||
xdp_stat = &rx_ring->rx_stats.xdp_drop;
|
||||
verdict = ENA_XDP_DROP;
|
||||
break;
|
||||
case XDP_PASS:
|
||||
xdp_stat = &rx_ring->rx_stats.xdp_pass;
|
||||
verdict = ENA_XDP_PASS;
|
||||
break;
|
||||
default:
|
||||
bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, verdict);
|
||||
xdp_stat = &rx_ring->rx_stats.xdp_invalid;
|
||||
verdict = ENA_XDP_DROP;
|
||||
}
|
||||
|
||||
ena_increase_stat(xdp_stat, 1, &rx_ring->syncp);
|
||||
@ -512,16 +518,18 @@ static void ena_xdp_exchange_program_rx_in_range(struct ena_adapter *adapter,
|
||||
struct bpf_prog *prog,
|
||||
int first, int count)
|
||||
{
|
||||
struct bpf_prog *old_bpf_prog;
|
||||
struct ena_ring *rx_ring;
|
||||
int i = 0;
|
||||
|
||||
for (i = first; i < count; i++) {
|
||||
rx_ring = &adapter->rx_ring[i];
|
||||
xchg(&rx_ring->xdp_bpf_prog, prog);
|
||||
if (prog) {
|
||||
old_bpf_prog = xchg(&rx_ring->xdp_bpf_prog, prog);
|
||||
|
||||
if (!old_bpf_prog && prog) {
|
||||
ena_xdp_register_rxq_info(rx_ring);
|
||||
rx_ring->rx_headroom = XDP_PACKET_HEADROOM;
|
||||
} else {
|
||||
} else if (old_bpf_prog && !prog) {
|
||||
ena_xdp_unregister_rxq_info(rx_ring);
|
||||
rx_ring->rx_headroom = NET_SKB_PAD;
|
||||
}
|
||||
@ -672,6 +680,7 @@ static void ena_init_io_rings_common(struct ena_adapter *adapter,
|
||||
ring->ena_dev = adapter->ena_dev;
|
||||
ring->per_napi_packets = 0;
|
||||
ring->cpu = 0;
|
||||
ring->numa_node = 0;
|
||||
ring->no_interrupt_event_cnt = 0;
|
||||
u64_stats_init(&ring->syncp);
|
||||
}
|
||||
@ -775,6 +784,7 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid)
|
||||
tx_ring->next_to_use = 0;
|
||||
tx_ring->next_to_clean = 0;
|
||||
tx_ring->cpu = ena_irq->cpu;
|
||||
tx_ring->numa_node = node;
|
||||
return 0;
|
||||
|
||||
err_push_buf_intermediate_buf:
|
||||
@ -907,6 +917,7 @@ static int ena_setup_rx_resources(struct ena_adapter *adapter,
|
||||
rx_ring->next_to_clean = 0;
|
||||
rx_ring->next_to_use = 0;
|
||||
rx_ring->cpu = ena_irq->cpu;
|
||||
rx_ring->numa_node = node;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1619,12 +1630,12 @@ static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp)
|
||||
* we expect, then we simply drop it
|
||||
*/
|
||||
if (unlikely(rx_ring->ena_bufs[0].len > ENA_XDP_MAX_MTU))
|
||||
return XDP_DROP;
|
||||
return ENA_XDP_DROP;
|
||||
|
||||
ret = ena_xdp_execute(rx_ring, xdp);
|
||||
|
||||
/* The xdp program might expand the headers */
|
||||
if (ret == XDP_PASS) {
|
||||
if (ret == ENA_XDP_PASS) {
|
||||
rx_info->page_offset = xdp->data - xdp->data_hard_start;
|
||||
rx_ring->ena_bufs[0].len = xdp->data_end - xdp->data;
|
||||
}
|
||||
@ -1663,7 +1674,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
|
||||
xdp_init_buff(&xdp, ENA_PAGE_SIZE, &rx_ring->xdp_rxq);
|
||||
|
||||
do {
|
||||
xdp_verdict = XDP_PASS;
|
||||
xdp_verdict = ENA_XDP_PASS;
|
||||
skb = NULL;
|
||||
ena_rx_ctx.ena_bufs = rx_ring->ena_bufs;
|
||||
ena_rx_ctx.max_bufs = rx_ring->sgl_size;
|
||||
@ -1691,7 +1702,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
|
||||
xdp_verdict = ena_xdp_handle_buff(rx_ring, &xdp);
|
||||
|
||||
/* allocate skb and fill it */
|
||||
if (xdp_verdict == XDP_PASS)
|
||||
if (xdp_verdict == ENA_XDP_PASS)
|
||||
skb = ena_rx_skb(rx_ring,
|
||||
rx_ring->ena_bufs,
|
||||
ena_rx_ctx.descs,
|
||||
@ -1709,14 +1720,15 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
|
||||
/* Packets was passed for transmission, unmap it
|
||||
* from RX side.
|
||||
*/
|
||||
if (xdp_verdict == XDP_TX || xdp_verdict == XDP_REDIRECT) {
|
||||
if (xdp_verdict & ENA_XDP_FORWARDED) {
|
||||
ena_unmap_rx_buff(rx_ring,
|
||||
&rx_ring->rx_buffer_info[req_id]);
|
||||
rx_ring->rx_buffer_info[req_id].page = NULL;
|
||||
}
|
||||
}
|
||||
if (xdp_verdict != XDP_PASS) {
|
||||
if (xdp_verdict != ENA_XDP_PASS) {
|
||||
xdp_flags |= xdp_verdict;
|
||||
total_len += ena_rx_ctx.ena_bufs[0].len;
|
||||
res_budget--;
|
||||
continue;
|
||||
}
|
||||
@ -1760,7 +1772,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
|
||||
ena_refill_rx_bufs(rx_ring, refill_required);
|
||||
}
|
||||
|
||||
if (xdp_flags & XDP_REDIRECT)
|
||||
if (xdp_flags & ENA_XDP_REDIRECT)
|
||||
xdp_do_flush_map();
|
||||
|
||||
return work_done;
|
||||
@ -1814,8 +1826,9 @@ static void ena_adjust_adaptive_rx_intr_moderation(struct ena_napi *ena_napi)
|
||||
static void ena_unmask_interrupt(struct ena_ring *tx_ring,
|
||||
struct ena_ring *rx_ring)
|
||||
{
|
||||
u32 rx_interval = tx_ring->smoothed_interval;
|
||||
struct ena_eth_io_intr_reg intr_reg;
|
||||
u32 rx_interval = 0;
|
||||
|
||||
/* Rx ring can be NULL when for XDP tx queues which don't have an
|
||||
* accompanying rx_ring pair.
|
||||
*/
|
||||
@ -1853,20 +1866,27 @@ static void ena_update_ring_numa_node(struct ena_ring *tx_ring,
|
||||
if (likely(tx_ring->cpu == cpu))
|
||||
goto out;
|
||||
|
||||
tx_ring->cpu = cpu;
|
||||
if (rx_ring)
|
||||
rx_ring->cpu = cpu;
|
||||
|
||||
numa_node = cpu_to_node(cpu);
|
||||
|
||||
if (likely(tx_ring->numa_node == numa_node))
|
||||
goto out;
|
||||
|
||||
put_cpu();
|
||||
|
||||
if (numa_node != NUMA_NO_NODE) {
|
||||
ena_com_update_numa_node(tx_ring->ena_com_io_cq, numa_node);
|
||||
if (rx_ring)
|
||||
tx_ring->numa_node = numa_node;
|
||||
if (rx_ring) {
|
||||
rx_ring->numa_node = numa_node;
|
||||
ena_com_update_numa_node(rx_ring->ena_com_io_cq,
|
||||
numa_node);
|
||||
}
|
||||
}
|
||||
|
||||
tx_ring->cpu = cpu;
|
||||
if (rx_ring)
|
||||
rx_ring->cpu = cpu;
|
||||
|
||||
return;
|
||||
out:
|
||||
put_cpu();
|
||||
@ -1987,11 +2007,10 @@ static int ena_io_poll(struct napi_struct *napi, int budget)
|
||||
if (ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev))
|
||||
ena_adjust_adaptive_rx_intr_moderation(ena_napi);
|
||||
|
||||
ena_update_ring_numa_node(tx_ring, rx_ring);
|
||||
ena_unmask_interrupt(tx_ring, rx_ring);
|
||||
}
|
||||
|
||||
ena_update_ring_numa_node(tx_ring, rx_ring);
|
||||
|
||||
ret = rx_work_done;
|
||||
} else {
|
||||
ret = budget;
|
||||
@ -2376,7 +2395,7 @@ static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid)
|
||||
ctx.mem_queue_type = ena_dev->tx_mem_queue_type;
|
||||
ctx.msix_vector = msix_vector;
|
||||
ctx.queue_size = tx_ring->ring_size;
|
||||
ctx.numa_node = cpu_to_node(tx_ring->cpu);
|
||||
ctx.numa_node = tx_ring->numa_node;
|
||||
|
||||
rc = ena_com_create_io_queue(ena_dev, &ctx);
|
||||
if (rc) {
|
||||
@ -2444,7 +2463,7 @@ static int ena_create_io_rx_queue(struct ena_adapter *adapter, int qid)
|
||||
ctx.mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
|
||||
ctx.msix_vector = msix_vector;
|
||||
ctx.queue_size = rx_ring->ring_size;
|
||||
ctx.numa_node = cpu_to_node(rx_ring->cpu);
|
||||
ctx.numa_node = rx_ring->numa_node;
|
||||
|
||||
rc = ena_com_create_io_queue(ena_dev, &ctx);
|
||||
if (rc) {
|
||||
@ -2805,6 +2824,24 @@ int ena_update_queue_sizes(struct ena_adapter *adapter,
|
||||
return dev_was_up ? ena_up(adapter) : 0;
|
||||
}
|
||||
|
||||
int ena_set_rx_copybreak(struct ena_adapter *adapter, u32 rx_copybreak)
|
||||
{
|
||||
struct ena_ring *rx_ring;
|
||||
int i;
|
||||
|
||||
if (rx_copybreak > min_t(u16, adapter->netdev->mtu, ENA_PAGE_SIZE))
|
||||
return -EINVAL;
|
||||
|
||||
adapter->rx_copybreak = rx_copybreak;
|
||||
|
||||
for (i = 0; i < adapter->num_io_queues; i++) {
|
||||
rx_ring = &adapter->rx_ring[i];
|
||||
rx_ring->rx_copybreak = rx_copybreak;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count)
|
||||
{
|
||||
struct ena_com_dev *ena_dev = adapter->ena_dev;
|
||||
|
@ -262,9 +262,11 @@ struct ena_ring {
|
||||
bool disable_meta_caching;
|
||||
u16 no_interrupt_event_cnt;
|
||||
|
||||
/* cpu for TPH */
|
||||
/* cpu and NUMA for TPH */
|
||||
int cpu;
|
||||
/* number of tx/rx_buffer_info's entries */
|
||||
int numa_node;
|
||||
|
||||
/* number of tx/rx_buffer_info's entries */
|
||||
int ring_size;
|
||||
|
||||
enum ena_admin_placement_policy_type tx_mem_queue_type;
|
||||
@ -392,6 +394,8 @@ int ena_update_queue_sizes(struct ena_adapter *adapter,
|
||||
|
||||
int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count);
|
||||
|
||||
int ena_set_rx_copybreak(struct ena_adapter *adapter, u32 rx_copybreak);
|
||||
|
||||
int ena_get_sset_count(struct net_device *netdev, int sset);
|
||||
|
||||
static inline void ena_reset_device(struct ena_adapter *adapter,
|
||||
@ -409,6 +413,15 @@ enum ena_xdp_errors_t {
|
||||
ENA_XDP_NO_ENOUGH_QUEUES,
|
||||
};
|
||||
|
||||
enum ENA_XDP_ACTIONS {
|
||||
ENA_XDP_PASS = 0,
|
||||
ENA_XDP_TX = BIT(0),
|
||||
ENA_XDP_REDIRECT = BIT(1),
|
||||
ENA_XDP_DROP = BIT(2)
|
||||
};
|
||||
|
||||
#define ENA_XDP_FORWARDED (ENA_XDP_TX | ENA_XDP_REDIRECT)
|
||||
|
||||
static inline bool ena_xdp_present(struct ena_adapter *adapter)
|
||||
{
|
||||
return !!adapter->xdp_bpf_prog;
|
||||
|
@ -1064,6 +1064,9 @@ static void xgbe_free_irqs(struct xgbe_prv_data *pdata)
|
||||
|
||||
devm_free_irq(pdata->dev, pdata->dev_irq, pdata);
|
||||
|
||||
tasklet_kill(&pdata->tasklet_dev);
|
||||
tasklet_kill(&pdata->tasklet_ecc);
|
||||
|
||||
if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq))
|
||||
devm_free_irq(pdata->dev, pdata->ecc_irq, pdata);
|
||||
|
||||
|
@ -447,8 +447,10 @@ static void xgbe_i2c_stop(struct xgbe_prv_data *pdata)
|
||||
xgbe_i2c_disable(pdata);
|
||||
xgbe_i2c_clear_all_interrupts(pdata);
|
||||
|
||||
if (pdata->dev_irq != pdata->i2c_irq)
|
||||
if (pdata->dev_irq != pdata->i2c_irq) {
|
||||
devm_free_irq(pdata->dev, pdata->i2c_irq, pdata);
|
||||
tasklet_kill(&pdata->tasklet_i2c);
|
||||
}
|
||||
}
|
||||
|
||||
static int xgbe_i2c_start(struct xgbe_prv_data *pdata)
|
||||
|
@ -1390,8 +1390,10 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
|
||||
/* Disable auto-negotiation */
|
||||
xgbe_an_disable_all(pdata);
|
||||
|
||||
if (pdata->dev_irq != pdata->an_irq)
|
||||
if (pdata->dev_irq != pdata->an_irq) {
|
||||
devm_free_irq(pdata->dev, pdata->an_irq, pdata);
|
||||
tasklet_kill(&pdata->tasklet_an);
|
||||
}
|
||||
|
||||
pdata->phy_if.phy_impl.stop(pdata);
|
||||
|
||||
|
@ -2784,17 +2784,11 @@ static int bcm_enet_shared_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm_enet_shared_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this "shared" driver is needed because both macs share a single
|
||||
* address space
|
||||
*/
|
||||
struct platform_driver bcm63xx_enet_shared_driver = {
|
||||
.probe = bcm_enet_shared_probe,
|
||||
.remove = bcm_enet_shared_remove,
|
||||
.driver = {
|
||||
.name = "bcm63xx_enet_shared",
|
||||
.owner = THIS_MODULE,
|
||||
|
@ -991,8 +991,7 @@ static struct sk_buff *bnxt_rx_multi_page_skb(struct bnxt *bp,
|
||||
dma_addr -= bp->rx_dma_offset;
|
||||
dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir,
|
||||
DMA_ATTR_WEAK_ORDERING);
|
||||
skb = build_skb(page_address(page), BNXT_PAGE_MODE_BUF_SIZE +
|
||||
bp->rx_dma_offset);
|
||||
skb = build_skb(page_address(page), PAGE_SIZE);
|
||||
if (!skb) {
|
||||
__free_page(page);
|
||||
return NULL;
|
||||
@ -1925,7 +1924,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
|
||||
dma_addr = rx_buf->mapping;
|
||||
|
||||
if (bnxt_xdp_attached(bp, rxr)) {
|
||||
bnxt_xdp_buff_init(bp, rxr, cons, &data_ptr, &len, &xdp);
|
||||
bnxt_xdp_buff_init(bp, rxr, cons, data_ptr, len, &xdp);
|
||||
if (agg_bufs) {
|
||||
u32 frag_len = bnxt_rx_agg_pages_xdp(bp, cpr, &xdp,
|
||||
cp_cons, agg_bufs,
|
||||
@ -1940,7 +1939,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
|
||||
}
|
||||
|
||||
if (xdp_active) {
|
||||
if (bnxt_rx_xdp(bp, rxr, cons, xdp, data, &len, event)) {
|
||||
if (bnxt_rx_xdp(bp, rxr, cons, xdp, data, &data_ptr, &len, event)) {
|
||||
rc = 1;
|
||||
goto next_rx;
|
||||
}
|
||||
@ -3969,8 +3968,10 @@ void bnxt_set_ring_params(struct bnxt *bp)
|
||||
bp->rx_agg_ring_mask = (bp->rx_agg_nr_pages * RX_DESC_CNT) - 1;
|
||||
|
||||
if (BNXT_RX_PAGE_MODE(bp)) {
|
||||
rx_space = BNXT_PAGE_MODE_BUF_SIZE;
|
||||
rx_size = BNXT_MAX_PAGE_MODE_MTU;
|
||||
rx_space = PAGE_SIZE;
|
||||
rx_size = PAGE_SIZE -
|
||||
ALIGN(max(NET_SKB_PAD, XDP_PACKET_HEADROOM), 8) -
|
||||
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
||||
} else {
|
||||
rx_size = SKB_DATA_ALIGN(BNXT_RX_COPY_THRESH + NET_IP_ALIGN);
|
||||
rx_space = rx_size + NET_SKB_PAD +
|
||||
@ -5398,15 +5399,16 @@ static int bnxt_hwrm_vnic_set_hds(struct bnxt *bp, u16 vnic_id)
|
||||
req->flags = cpu_to_le32(VNIC_PLCMODES_CFG_REQ_FLAGS_JUMBO_PLACEMENT);
|
||||
req->enables = cpu_to_le32(VNIC_PLCMODES_CFG_REQ_ENABLES_JUMBO_THRESH_VALID);
|
||||
|
||||
if (BNXT_RX_PAGE_MODE(bp) && !BNXT_RX_JUMBO_MODE(bp)) {
|
||||
if (BNXT_RX_PAGE_MODE(bp)) {
|
||||
req->jumbo_thresh = cpu_to_le16(bp->rx_buf_use_size);
|
||||
} else {
|
||||
req->flags |= cpu_to_le32(VNIC_PLCMODES_CFG_REQ_FLAGS_HDS_IPV4 |
|
||||
VNIC_PLCMODES_CFG_REQ_FLAGS_HDS_IPV6);
|
||||
req->enables |=
|
||||
cpu_to_le32(VNIC_PLCMODES_CFG_REQ_ENABLES_HDS_THRESHOLD_VALID);
|
||||
req->jumbo_thresh = cpu_to_le16(bp->rx_copy_thresh);
|
||||
req->hds_threshold = cpu_to_le16(bp->rx_copy_thresh);
|
||||
}
|
||||
/* thresholds not implemented in firmware yet */
|
||||
req->jumbo_thresh = cpu_to_le16(bp->rx_copy_thresh);
|
||||
req->hds_threshold = cpu_to_le16(bp->rx_copy_thresh);
|
||||
req->vnic_id = cpu_to_le32(vnic->fw_vnic_id);
|
||||
return hwrm_req_send(bp, req);
|
||||
}
|
||||
@ -13591,7 +13593,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
return -ENOMEM;
|
||||
|
||||
bp = netdev_priv(dev);
|
||||
SET_NETDEV_DEVLINK_PORT(dev, &bp->dl_port);
|
||||
bp->board_idx = ent->driver_data;
|
||||
bp->msg_enable = BNXT_DEF_MSG_ENABLE;
|
||||
bnxt_set_max_func_irqs(bp, max_irqs);
|
||||
@ -13599,6 +13600,10 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
if (bnxt_vf_pciid(bp->board_idx))
|
||||
bp->flags |= BNXT_FLAG_VF;
|
||||
|
||||
/* No devlink port registration in case of a VF */
|
||||
if (BNXT_PF(bp))
|
||||
SET_NETDEV_DEVLINK_PORT(dev, &bp->dl_port);
|
||||
|
||||
if (pdev->msix_cap)
|
||||
bp->flags |= BNXT_FLAG_MSIX_CAP;
|
||||
|
||||
|
@ -591,12 +591,20 @@ struct nqe_cn {
|
||||
#define BNXT_RX_PAGE_SIZE (1 << BNXT_RX_PAGE_SHIFT)
|
||||
|
||||
#define BNXT_MAX_MTU 9500
|
||||
#define BNXT_PAGE_MODE_BUF_SIZE \
|
||||
|
||||
/* First RX buffer page in XDP multi-buf mode
|
||||
*
|
||||
* +-------------------------------------------------------------------------+
|
||||
* | XDP_PACKET_HEADROOM | bp->rx_buf_use_size | skb_shared_info|
|
||||
* | (bp->rx_dma_offset) | | |
|
||||
* +-------------------------------------------------------------------------+
|
||||
*/
|
||||
#define BNXT_MAX_PAGE_MODE_MTU_SBUF \
|
||||
((unsigned int)PAGE_SIZE - VLAN_ETH_HLEN - NET_IP_ALIGN - \
|
||||
XDP_PACKET_HEADROOM)
|
||||
#define BNXT_MAX_PAGE_MODE_MTU \
|
||||
BNXT_PAGE_MODE_BUF_SIZE - \
|
||||
SKB_DATA_ALIGN((unsigned int)sizeof(struct skb_shared_info))
|
||||
(BNXT_MAX_PAGE_MODE_MTU_SBUF - \
|
||||
SKB_DATA_ALIGN((unsigned int)sizeof(struct skb_shared_info)))
|
||||
|
||||
#define BNXT_MIN_PKT_SIZE 52
|
||||
|
||||
@ -2134,7 +2142,6 @@ struct bnxt {
|
||||
#define BNXT_DUMP_CRASH 1
|
||||
|
||||
struct bpf_prog *xdp_prog;
|
||||
u8 xdp_has_frags;
|
||||
|
||||
struct bnxt_ptp_cfg *ptp_cfg;
|
||||
u8 ptp_all_rx_tstamp;
|
||||
|
@ -177,7 +177,7 @@ bool bnxt_xdp_attached(struct bnxt *bp, struct bnxt_rx_ring_info *rxr)
|
||||
}
|
||||
|
||||
void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
||||
u16 cons, u8 **data_ptr, unsigned int *len,
|
||||
u16 cons, u8 *data_ptr, unsigned int len,
|
||||
struct xdp_buff *xdp)
|
||||
{
|
||||
struct bnxt_sw_rx_bd *rx_buf;
|
||||
@ -191,13 +191,10 @@ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
||||
offset = bp->rx_offset;
|
||||
|
||||
mapping = rx_buf->mapping - bp->rx_dma_offset;
|
||||
dma_sync_single_for_cpu(&pdev->dev, mapping + offset, *len, bp->rx_dir);
|
||||
|
||||
if (bp->xdp_has_frags)
|
||||
buflen = BNXT_PAGE_MODE_BUF_SIZE + offset;
|
||||
dma_sync_single_for_cpu(&pdev->dev, mapping + offset, len, bp->rx_dir);
|
||||
|
||||
xdp_init_buff(xdp, buflen, &rxr->xdp_rxq);
|
||||
xdp_prepare_buff(xdp, *data_ptr - offset, offset, *len, false);
|
||||
xdp_prepare_buff(xdp, data_ptr - offset, offset, len, false);
|
||||
}
|
||||
|
||||
void bnxt_xdp_buff_frags_free(struct bnxt_rx_ring_info *rxr,
|
||||
@ -222,7 +219,8 @@ void bnxt_xdp_buff_frags_free(struct bnxt_rx_ring_info *rxr,
|
||||
* false - packet should be passed to the stack.
|
||||
*/
|
||||
bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
|
||||
struct xdp_buff xdp, struct page *page, unsigned int *len, u8 *event)
|
||||
struct xdp_buff xdp, struct page *page, u8 **data_ptr,
|
||||
unsigned int *len, u8 *event)
|
||||
{
|
||||
struct bpf_prog *xdp_prog = READ_ONCE(rxr->xdp_prog);
|
||||
struct bnxt_tx_ring_info *txr;
|
||||
@ -255,8 +253,10 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
|
||||
*event &= ~BNXT_RX_EVENT;
|
||||
|
||||
*len = xdp.data_end - xdp.data;
|
||||
if (orig_data != xdp.data)
|
||||
if (orig_data != xdp.data) {
|
||||
offset = xdp.data - xdp.data_hard_start;
|
||||
*data_ptr = xdp.data_hard_start + offset;
|
||||
}
|
||||
|
||||
switch (act) {
|
||||
case XDP_PASS:
|
||||
@ -401,10 +401,8 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
|
||||
netdev_warn(dev, "ethtool rx/tx channels must be combined to support XDP.\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
if (prog) {
|
||||
if (prog)
|
||||
tx_xdp = bp->rx_nr_rings;
|
||||
bp->xdp_has_frags = prog->aux->xdp_has_frags;
|
||||
}
|
||||
|
||||
tc = netdev_get_num_tc(dev);
|
||||
if (!tc)
|
||||
|
@ -18,8 +18,8 @@ struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
|
||||
struct xdp_buff *xdp);
|
||||
void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts);
|
||||
bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
|
||||
struct xdp_buff xdp, struct page *page, unsigned int *len,
|
||||
u8 *event);
|
||||
struct xdp_buff xdp, struct page *page, u8 **data_ptr,
|
||||
unsigned int *len, u8 *event);
|
||||
int bnxt_xdp(struct net_device *dev, struct netdev_bpf *xdp);
|
||||
int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
|
||||
struct xdp_frame **frames, u32 flags);
|
||||
@ -27,7 +27,7 @@ int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
|
||||
bool bnxt_xdp_attached(struct bnxt *bp, struct bnxt_rx_ring_info *rxr);
|
||||
|
||||
void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
||||
u16 cons, u8 **data_ptr, unsigned int *len,
|
||||
u16 cons, u8 *data_ptr, unsigned int len,
|
||||
struct xdp_buff *xdp);
|
||||
void bnxt_xdp_buff_frags_free(struct bnxt_rx_ring_info *rxr,
|
||||
struct xdp_buff *xdp);
|
||||
|
@ -127,11 +127,6 @@ static int enetc_ierb_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int enetc_ierb_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id enetc_ierb_match[] = {
|
||||
{ .compatible = "fsl,ls1028a-enetc-ierb", },
|
||||
{},
|
||||
@ -144,7 +139,6 @@ static struct platform_driver enetc_ierb_driver = {
|
||||
.of_match_table = enetc_ierb_match,
|
||||
},
|
||||
.probe = enetc_ierb_probe,
|
||||
.remove = enetc_ierb_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(enetc_ierb_driver);
|
||||
|
@ -1430,7 +1430,7 @@ int dtsec_initialization(struct mac_device *mac_dev,
|
||||
dtsec->dtsec_drv_param->tx_pad_crc = true;
|
||||
|
||||
phy_node = of_parse_phandle(mac_node, "tbi-handle", 0);
|
||||
if (!phy_node || of_device_is_available(phy_node)) {
|
||||
if (!phy_node || !of_device_is_available(phy_node)) {
|
||||
of_node_put(phy_node);
|
||||
err = -EINVAL;
|
||||
dev_err_probe(mac_dev->dev, err,
|
||||
|
@ -3855,18 +3855,16 @@ static int hns3_gro_complete(struct sk_buff *skb, u32 l234info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool hns3_checksum_complete(struct hns3_enet_ring *ring,
|
||||
static void hns3_checksum_complete(struct hns3_enet_ring *ring,
|
||||
struct sk_buff *skb, u32 ptype, u16 csum)
|
||||
{
|
||||
if (ptype == HNS3_INVALID_PTYPE ||
|
||||
hns3_rx_ptype_tbl[ptype].ip_summed != CHECKSUM_COMPLETE)
|
||||
return false;
|
||||
return;
|
||||
|
||||
hns3_ring_stats_update(ring, csum_complete);
|
||||
skb->ip_summed = CHECKSUM_COMPLETE;
|
||||
skb->csum = csum_unfold((__force __sum16)csum);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void hns3_rx_handle_csum(struct sk_buff *skb, u32 l234info,
|
||||
@ -3926,8 +3924,7 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
|
||||
ptype = hnae3_get_field(ol_info, HNS3_RXD_PTYPE_M,
|
||||
HNS3_RXD_PTYPE_S);
|
||||
|
||||
if (hns3_checksum_complete(ring, skb, ptype, csum))
|
||||
return;
|
||||
hns3_checksum_complete(ring, skb, ptype, csum);
|
||||
|
||||
/* check if hardware has done checksum */
|
||||
if (!(bd_base_info & BIT(HNS3_RXD_L3L4P_B)))
|
||||
@ -3936,6 +3933,7 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
|
||||
if (unlikely(l234info & (BIT(HNS3_RXD_L3E_B) | BIT(HNS3_RXD_L4E_B) |
|
||||
BIT(HNS3_RXD_OL3E_B) |
|
||||
BIT(HNS3_RXD_OL4E_B)))) {
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
hns3_ring_stats_update(ring, l3l4_csum_err);
|
||||
|
||||
return;
|
||||
|
@ -3910,9 +3910,17 @@ static int hclge_set_all_vf_rst(struct hclge_dev *hdev, bool reset)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!reset || !test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
|
||||
if (!reset ||
|
||||
!test_bit(HCLGE_VPORT_STATE_INITED, &vport->state))
|
||||
continue;
|
||||
|
||||
if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state) &&
|
||||
hdev->reset_type == HNAE3_FUNC_RESET) {
|
||||
set_bit(HCLGE_VPORT_NEED_NOTIFY_RESET,
|
||||
&vport->need_notify);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Inform VF to process the reset.
|
||||
* hclge_inform_reset_assert_to_vf may fail if VF
|
||||
* driver is not loaded.
|
||||
@ -4609,18 +4617,25 @@ static void hclge_reset_service_task(struct hclge_dev *hdev)
|
||||
|
||||
static void hclge_update_vport_alive(struct hclge_dev *hdev)
|
||||
{
|
||||
#define HCLGE_ALIVE_SECONDS_NORMAL 8
|
||||
|
||||
unsigned long alive_time = HCLGE_ALIVE_SECONDS_NORMAL * HZ;
|
||||
int i;
|
||||
|
||||
/* start from vport 1 for PF is always alive */
|
||||
for (i = 1; i < hdev->num_alloc_vport; i++) {
|
||||
struct hclge_vport *vport = &hdev->vport[i];
|
||||
|
||||
if (time_after(jiffies, vport->last_active_jiffies + 8 * HZ))
|
||||
if (!test_bit(HCLGE_VPORT_STATE_INITED, &vport->state) ||
|
||||
!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
|
||||
continue;
|
||||
if (time_after(jiffies, vport->last_active_jiffies +
|
||||
alive_time)) {
|
||||
clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
|
||||
|
||||
/* If vf is not alive, set to default value */
|
||||
if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
|
||||
vport->mps = HCLGE_MAC_DEFAULT_FRAME;
|
||||
dev_warn(&hdev->pdev->dev,
|
||||
"VF %u heartbeat timeout\n",
|
||||
i - HCLGE_VF_VPORT_START_NUM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8064,9 +8079,11 @@ int hclge_vport_start(struct hclge_vport *vport)
|
||||
{
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
|
||||
set_bit(HCLGE_VPORT_STATE_INITED, &vport->state);
|
||||
set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
|
||||
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
|
||||
vport->last_active_jiffies = jiffies;
|
||||
vport->need_notify = 0;
|
||||
|
||||
if (test_bit(vport->vport_id, hdev->vport_config_block)) {
|
||||
if (vport->vport_id) {
|
||||
@ -8084,7 +8101,9 @@ int hclge_vport_start(struct hclge_vport *vport)
|
||||
|
||||
void hclge_vport_stop(struct hclge_vport *vport)
|
||||
{
|
||||
clear_bit(HCLGE_VPORT_STATE_INITED, &vport->state);
|
||||
clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
|
||||
vport->need_notify = 0;
|
||||
}
|
||||
|
||||
static int hclge_client_start(struct hnae3_handle *handle)
|
||||
@ -9208,7 +9227,8 @@ static int hclge_set_vf_mac(struct hnae3_handle *handle, int vf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_info(&hdev->pdev->dev, "MAC of VF %d has been set to %s\n",
|
||||
dev_info(&hdev->pdev->dev,
|
||||
"MAC of VF %d has been set to %s, will be active after VF reset\n",
|
||||
vf, format_mac_addr);
|
||||
return 0;
|
||||
}
|
||||
@ -10465,12 +10485,16 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
|
||||
* for DEVICE_VERSION_V3, vf doesn't need to know about the port based
|
||||
* VLAN state.
|
||||
*/
|
||||
if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3 &&
|
||||
test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
|
||||
(void)hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
|
||||
vport->vport_id,
|
||||
state, &vlan_info);
|
||||
|
||||
if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3) {
|
||||
if (test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
|
||||
(void)hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
|
||||
vport->vport_id,
|
||||
state,
|
||||
&vlan_info);
|
||||
else
|
||||
set_bit(HCLGE_VPORT_NEED_NOTIFY_VF_VLAN,
|
||||
&vport->need_notify);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -11941,7 +11965,7 @@ static void hclge_reset_vport_state(struct hclge_dev *hdev)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < hdev->num_alloc_vport; i++) {
|
||||
hclge_vport_stop(vport);
|
||||
clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
|
||||
vport++;
|
||||
}
|
||||
}
|
||||
@ -12754,60 +12778,71 @@ static int hclge_gro_en(struct hnae3_handle *handle, bool enable)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
|
||||
static int hclge_sync_vport_promisc_mode(struct hclge_vport *vport)
|
||||
{
|
||||
struct hclge_vport *vport = &hdev->vport[0];
|
||||
struct hnae3_handle *handle = &vport->nic;
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
bool uc_en = false;
|
||||
bool mc_en = false;
|
||||
u8 tmp_flags;
|
||||
bool bc_en;
|
||||
int ret;
|
||||
u16 i;
|
||||
|
||||
if (vport->last_promisc_flags != vport->overflow_promisc_flags) {
|
||||
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
|
||||
vport->last_promisc_flags = vport->overflow_promisc_flags;
|
||||
}
|
||||
|
||||
if (test_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state)) {
|
||||
if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
|
||||
&vport->state))
|
||||
return 0;
|
||||
|
||||
/* for PF */
|
||||
if (!vport->vport_id) {
|
||||
tmp_flags = handle->netdev_flags | vport->last_promisc_flags;
|
||||
ret = hclge_set_promisc_mode(handle, tmp_flags & HNAE3_UPE,
|
||||
tmp_flags & HNAE3_MPE);
|
||||
if (!ret) {
|
||||
clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
|
||||
&vport->state);
|
||||
if (!ret)
|
||||
set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
|
||||
&vport->state);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < hdev->num_alloc_vport; i++) {
|
||||
bool uc_en = false;
|
||||
bool mc_en = false;
|
||||
bool bc_en;
|
||||
|
||||
vport = &hdev->vport[i];
|
||||
|
||||
if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
|
||||
&vport->state))
|
||||
continue;
|
||||
|
||||
if (vport->vf_info.trusted) {
|
||||
uc_en = vport->vf_info.request_uc_en > 0 ||
|
||||
vport->overflow_promisc_flags &
|
||||
HNAE3_OVERFLOW_UPE;
|
||||
mc_en = vport->vf_info.request_mc_en > 0 ||
|
||||
vport->overflow_promisc_flags &
|
||||
HNAE3_OVERFLOW_MPE;
|
||||
}
|
||||
bc_en = vport->vf_info.request_bc_en > 0;
|
||||
|
||||
ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en,
|
||||
mc_en, bc_en);
|
||||
if (ret) {
|
||||
else
|
||||
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
|
||||
&vport->state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* for VF */
|
||||
if (vport->vf_info.trusted) {
|
||||
uc_en = vport->vf_info.request_uc_en > 0 ||
|
||||
vport->overflow_promisc_flags & HNAE3_OVERFLOW_UPE;
|
||||
mc_en = vport->vf_info.request_mc_en > 0 ||
|
||||
vport->overflow_promisc_flags & HNAE3_OVERFLOW_MPE;
|
||||
}
|
||||
bc_en = vport->vf_info.request_bc_en > 0;
|
||||
|
||||
ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en,
|
||||
mc_en, bc_en);
|
||||
if (ret) {
|
||||
set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
|
||||
return ret;
|
||||
}
|
||||
hclge_set_vport_vlan_fltr_change(vport);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
|
||||
{
|
||||
struct hclge_vport *vport;
|
||||
int ret;
|
||||
u16 i;
|
||||
|
||||
for (i = 0; i < hdev->num_alloc_vport; i++) {
|
||||
vport = &hdev->vport[i];
|
||||
|
||||
ret = hclge_sync_vport_promisc_mode(vport);
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
hclge_set_vport_vlan_fltr_change(vport);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12944,6 +12979,11 @@ static void hclge_clear_vport_vf_info(struct hclge_vport *vport, int vfid)
|
||||
struct hclge_vlan_info vlan_info;
|
||||
int ret;
|
||||
|
||||
clear_bit(HCLGE_VPORT_STATE_INITED, &vport->state);
|
||||
clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
|
||||
vport->need_notify = 0;
|
||||
vport->mps = 0;
|
||||
|
||||
/* after disable sriov, clean VF rate configured by PF */
|
||||
ret = hclge_tm_qs_shaper_cfg(vport, 0);
|
||||
if (ret)
|
||||
|
@ -995,9 +995,15 @@ enum HCLGE_VPORT_STATE {
|
||||
HCLGE_VPORT_STATE_MAC_TBL_CHANGE,
|
||||
HCLGE_VPORT_STATE_PROMISC_CHANGE,
|
||||
HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
|
||||
HCLGE_VPORT_STATE_INITED,
|
||||
HCLGE_VPORT_STATE_MAX
|
||||
};
|
||||
|
||||
enum HCLGE_VPORT_NEED_NOTIFY {
|
||||
HCLGE_VPORT_NEED_NOTIFY_RESET,
|
||||
HCLGE_VPORT_NEED_NOTIFY_VF_VLAN,
|
||||
};
|
||||
|
||||
struct hclge_vlan_info {
|
||||
u16 vlan_proto; /* so far support 802.1Q only */
|
||||
u16 qos;
|
||||
@ -1044,6 +1050,7 @@ struct hclge_vport {
|
||||
struct hnae3_handle roce;
|
||||
|
||||
unsigned long state;
|
||||
unsigned long need_notify;
|
||||
unsigned long last_active_jiffies;
|
||||
u32 mps; /* Max packet size */
|
||||
struct hclge_vf_info vf_info;
|
||||
|
@ -124,17 +124,26 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len,
|
||||
return status;
|
||||
}
|
||||
|
||||
static int hclge_inform_vf_reset(struct hclge_vport *vport, u16 reset_type)
|
||||
{
|
||||
__le16 msg_data;
|
||||
u8 dest_vfid;
|
||||
|
||||
dest_vfid = (u8)vport->vport_id;
|
||||
msg_data = cpu_to_le16(reset_type);
|
||||
|
||||
/* send this requested info to VF */
|
||||
return hclge_send_mbx_msg(vport, (u8 *)&msg_data, sizeof(msg_data),
|
||||
HCLGE_MBX_ASSERTING_RESET, dest_vfid);
|
||||
}
|
||||
|
||||
int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
|
||||
{
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
__le16 msg_data;
|
||||
u16 reset_type;
|
||||
u8 dest_vfid;
|
||||
|
||||
BUILD_BUG_ON(HNAE3_MAX_RESET > U16_MAX);
|
||||
|
||||
dest_vfid = (u8)vport->vport_id;
|
||||
|
||||
if (hdev->reset_type == HNAE3_FUNC_RESET)
|
||||
reset_type = HNAE3_VF_PF_FUNC_RESET;
|
||||
else if (hdev->reset_type == HNAE3_FLR_RESET)
|
||||
@ -142,11 +151,7 @@ int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
|
||||
else
|
||||
reset_type = HNAE3_VF_FUNC_RESET;
|
||||
|
||||
msg_data = cpu_to_le16(reset_type);
|
||||
|
||||
/* send this requested info to VF */
|
||||
return hclge_send_mbx_msg(vport, (u8 *)&msg_data, sizeof(msg_data),
|
||||
HCLGE_MBX_ASSERTING_RESET, dest_vfid);
|
||||
return hclge_inform_vf_reset(vport, reset_type);
|
||||
}
|
||||
|
||||
static void hclge_free_vector_ring_chain(struct hnae3_ring_chain_node *head)
|
||||
@ -652,9 +657,56 @@ static int hclge_reset_vf(struct hclge_vport *vport)
|
||||
return hclge_func_reset_cmd(hdev, vport->vport_id);
|
||||
}
|
||||
|
||||
static void hclge_notify_vf_config(struct hclge_vport *vport)
|
||||
{
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
|
||||
struct hclge_port_base_vlan_config *vlan_cfg;
|
||||
int ret;
|
||||
|
||||
hclge_push_vf_link_status(vport);
|
||||
if (test_bit(HCLGE_VPORT_NEED_NOTIFY_RESET, &vport->need_notify)) {
|
||||
ret = hclge_inform_vf_reset(vport, HNAE3_VF_PF_FUNC_RESET);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"failed to inform VF %u reset!",
|
||||
vport->vport_id - HCLGE_VF_VPORT_START_NUM);
|
||||
return;
|
||||
}
|
||||
vport->need_notify = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3 &&
|
||||
test_bit(HCLGE_VPORT_NEED_NOTIFY_VF_VLAN, &vport->need_notify)) {
|
||||
vlan_cfg = &vport->port_base_vlan_cfg;
|
||||
ret = hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
|
||||
vport->vport_id,
|
||||
vlan_cfg->state,
|
||||
&vlan_cfg->vlan_info);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"failed to inform VF %u port base vlan!",
|
||||
vport->vport_id - HCLGE_VF_VPORT_START_NUM);
|
||||
return;
|
||||
}
|
||||
clear_bit(HCLGE_VPORT_NEED_NOTIFY_VF_VLAN, &vport->need_notify);
|
||||
}
|
||||
}
|
||||
|
||||
static void hclge_vf_keep_alive(struct hclge_vport *vport)
|
||||
{
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
|
||||
vport->last_active_jiffies = jiffies;
|
||||
|
||||
if (test_bit(HCLGE_VPORT_STATE_INITED, &vport->state) &&
|
||||
!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) {
|
||||
set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
|
||||
dev_info(&hdev->pdev->dev, "VF %u is alive!",
|
||||
vport->vport_id - HCLGE_VF_VPORT_START_NUM);
|
||||
hclge_notify_vf_config(vport);
|
||||
}
|
||||
}
|
||||
|
||||
static int hclge_set_vf_mtu(struct hclge_vport *vport,
|
||||
@ -954,6 +1006,7 @@ static int hclge_mbx_vf_uninit_handler(struct hclge_mbx_ops_param *param)
|
||||
hclge_rm_vport_all_mac_table(param->vport, true,
|
||||
HCLGE_MAC_ADDR_MC);
|
||||
hclge_rm_vport_all_vlan_table(param->vport, true);
|
||||
param->vport->mps = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2767,7 +2767,8 @@ static int hclgevf_pci_reset(struct hclgevf_dev *hdev)
|
||||
struct pci_dev *pdev = hdev->pdev;
|
||||
int ret = 0;
|
||||
|
||||
if (hdev->reset_type == HNAE3_VF_FULL_RESET &&
|
||||
if ((hdev->reset_type == HNAE3_VF_FULL_RESET ||
|
||||
hdev->reset_type == HNAE3_FLR_RESET) &&
|
||||
test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) {
|
||||
hclgevf_misc_irq_uninit(hdev);
|
||||
hclgevf_uninit_msi(hdev);
|
||||
|
@ -783,7 +783,7 @@ construct_skb:
|
||||
static void
|
||||
ice_clean_xdp_tx_buf(struct ice_tx_ring *xdp_ring, struct ice_tx_buf *tx_buf)
|
||||
{
|
||||
xdp_return_frame((struct xdp_frame *)tx_buf->raw_buf);
|
||||
page_frag_free(tx_buf->raw_buf);
|
||||
xdp_ring->xdp_tx_active--;
|
||||
dma_unmap_single(xdp_ring->dev, dma_unmap_addr(tx_buf, dma),
|
||||
dma_unmap_len(tx_buf, len), DMA_TO_DEVICE);
|
||||
|
@ -589,7 +589,7 @@ int rvu_mbox_handler_mcs_free_resources(struct rvu *rvu,
|
||||
u16 pcifunc = req->hdr.pcifunc;
|
||||
struct mcs_rsrc_map *map;
|
||||
struct mcs *mcs;
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
if (req->mcs_id >= rvu->mcs_blk_cnt)
|
||||
return MCS_AF_ERR_INVALID_MCSID;
|
||||
|
@ -1012,6 +1012,7 @@ static void otx2_pool_refill_task(struct work_struct *work)
|
||||
rbpool = cq->rbpool;
|
||||
free_ptrs = cq->pool_ptrs;
|
||||
|
||||
get_cpu();
|
||||
while (cq->pool_ptrs) {
|
||||
if (otx2_alloc_rbuf(pfvf, rbpool, &bufptr)) {
|
||||
/* Schedule a WQ if we fails to free atleast half of the
|
||||
@ -1031,6 +1032,7 @@ static void otx2_pool_refill_task(struct work_struct *work)
|
||||
pfvf->hw_ops->aura_freeptr(pfvf, qidx, bufptr + OTX2_HEAD_ROOM);
|
||||
cq->pool_ptrs--;
|
||||
}
|
||||
put_cpu();
|
||||
cq->refill_task_sched = false;
|
||||
}
|
||||
|
||||
@ -1368,6 +1370,7 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf)
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
get_cpu();
|
||||
/* Allocate pointers and free them to aura/pool */
|
||||
for (qidx = 0; qidx < hw->tot_tx_queues; qidx++) {
|
||||
pool_id = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, qidx);
|
||||
@ -1376,18 +1379,24 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf)
|
||||
sq = &qset->sq[qidx];
|
||||
sq->sqb_count = 0;
|
||||
sq->sqb_ptrs = kcalloc(num_sqbs, sizeof(*sq->sqb_ptrs), GFP_KERNEL);
|
||||
if (!sq->sqb_ptrs)
|
||||
return -ENOMEM;
|
||||
if (!sq->sqb_ptrs) {
|
||||
err = -ENOMEM;
|
||||
goto err_mem;
|
||||
}
|
||||
|
||||
for (ptr = 0; ptr < num_sqbs; ptr++) {
|
||||
if (otx2_alloc_rbuf(pfvf, pool, &bufptr))
|
||||
return -ENOMEM;
|
||||
err = otx2_alloc_rbuf(pfvf, pool, &bufptr);
|
||||
if (err)
|
||||
goto err_mem;
|
||||
pfvf->hw_ops->aura_freeptr(pfvf, pool_id, bufptr);
|
||||
sq->sqb_ptrs[sq->sqb_count++] = (u64)bufptr;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_mem:
|
||||
put_cpu();
|
||||
return err ? -ENOMEM : 0;
|
||||
|
||||
fail:
|
||||
otx2_mbox_reset(&pfvf->mbox.mbox, 0);
|
||||
otx2_aura_pool_free(pfvf);
|
||||
@ -1426,18 +1435,21 @@ int otx2_rq_aura_pool_init(struct otx2_nic *pfvf)
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
get_cpu();
|
||||
/* Allocate pointers and free them to aura/pool */
|
||||
for (pool_id = 0; pool_id < hw->rqpool_cnt; pool_id++) {
|
||||
pool = &pfvf->qset.pool[pool_id];
|
||||
for (ptr = 0; ptr < num_ptrs; ptr++) {
|
||||
if (otx2_alloc_rbuf(pfvf, pool, &bufptr))
|
||||
return -ENOMEM;
|
||||
err = otx2_alloc_rbuf(pfvf, pool, &bufptr);
|
||||
if (err)
|
||||
goto err_mem;
|
||||
pfvf->hw_ops->aura_freeptr(pfvf, pool_id,
|
||||
bufptr + OTX2_HEAD_ROOM);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_mem:
|
||||
put_cpu();
|
||||
return err ? -ENOMEM : 0;
|
||||
fail:
|
||||
otx2_mbox_reset(&pfvf->mbox.mbox, 0);
|
||||
otx2_aura_pool_free(pfvf);
|
||||
|
@ -468,7 +468,7 @@ static int mlx5_devlink_enable_roce_validate(struct devlink *devlink, u32 id,
|
||||
bool new_state = val.vbool;
|
||||
|
||||
if (new_state && !MLX5_CAP_GEN(dev, roce) &&
|
||||
!MLX5_CAP_GEN(dev, roce_rw_supported)) {
|
||||
!(MLX5_CAP_GEN(dev, roce_rw_supported) && MLX5_CAP_GEN_MAX(dev, roce))) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Device doesn't support RoCE");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@ -563,7 +563,7 @@ static int mlx5_devlink_eq_depth_validate(struct devlink *devlink, u32 id,
|
||||
union devlink_param_value val,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
return (val.vu16 >= 64 && val.vu16 <= 4096) ? 0 : -EINVAL;
|
||||
return (val.vu32 >= 64 && val.vu32 <= 4096) ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static const struct devlink_param mlx5_devlink_params[] = {
|
||||
|
@ -459,7 +459,11 @@ static int mlx5e_rx_reporter_diagnose(struct devlink_health_reporter *reporter,
|
||||
goto unlock;
|
||||
|
||||
for (i = 0; i < priv->channels.num; i++) {
|
||||
struct mlx5e_rq *rq = &priv->channels.c[i]->rq;
|
||||
struct mlx5e_channel *c = priv->channels.c[i];
|
||||
struct mlx5e_rq *rq;
|
||||
|
||||
rq = test_bit(MLX5E_CHANNEL_STATE_XSK, c->state) ?
|
||||
&c->xskrq : &c->rq;
|
||||
|
||||
err = mlx5e_rx_reporter_build_diagnose_output(rq, fmsg);
|
||||
if (err)
|
||||
|
@ -2103,14 +2103,9 @@ out_err:
|
||||
static void
|
||||
mlx5_ct_tc_create_dbgfs(struct mlx5_tc_ct_priv *ct_priv)
|
||||
{
|
||||
bool is_fdb = ct_priv->ns_type == MLX5_FLOW_NAMESPACE_FDB;
|
||||
struct mlx5_tc_ct_debugfs *ct_dbgfs = &ct_priv->debugfs;
|
||||
char dirname[16] = {};
|
||||
|
||||
if (sscanf(dirname, "ct_%s", is_fdb ? "fdb" : "nic") < 0)
|
||||
return;
|
||||
|
||||
ct_dbgfs->root = debugfs_create_dir(dirname, mlx5_debugfs_get_dev_root(ct_priv->dev));
|
||||
ct_dbgfs->root = debugfs_create_dir("ct", mlx5_debugfs_get_dev_root(ct_priv->dev));
|
||||
debugfs_create_atomic_t("offloaded", 0400, ct_dbgfs->root,
|
||||
&ct_dbgfs->stats.offloaded);
|
||||
debugfs_create_atomic_t("rx_dropped", 0400, ct_dbgfs->root,
|
||||
|
@ -222,7 +222,7 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
|
||||
int err;
|
||||
|
||||
list_for_each_entry(flow, flow_list, tmp_list) {
|
||||
if (!mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, SLOW))
|
||||
if (!mlx5e_is_offloaded_flow(flow))
|
||||
continue;
|
||||
|
||||
attr = mlx5e_tc_get_encap_attr(flow);
|
||||
@ -231,6 +231,13 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
|
||||
esw_attr->dests[flow->tmp_entry_index].flags &= ~MLX5_ESW_DEST_ENCAP_VALID;
|
||||
esw_attr->dests[flow->tmp_entry_index].pkt_reformat = NULL;
|
||||
|
||||
/* Clear pkt_reformat before checking slow path flag. Because
|
||||
* in next iteration, the same flow is already set slow path
|
||||
* flag, but still need to clear the pkt_reformat.
|
||||
*/
|
||||
if (flow_flag_test(flow, SLOW))
|
||||
continue;
|
||||
|
||||
/* update from encap rule to slow path rule */
|
||||
spec = &flow->attr->parse_attr->spec;
|
||||
rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec);
|
||||
|
@ -273,6 +273,11 @@ static int mlx5e_tc_tun_parse_geneve_options(struct mlx5e_priv *priv,
|
||||
geneve_tlv_option_0_data, be32_to_cpu(opt_data_key));
|
||||
MLX5_SET(fte_match_set_misc3, misc_3_c,
|
||||
geneve_tlv_option_0_data, be32_to_cpu(opt_data_mask));
|
||||
if (MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev,
|
||||
ft_field_support.geneve_tlv_option_0_exist)) {
|
||||
MLX5_SET_TO_ONES(fte_match_set_misc, misc_c, geneve_tlv_option_0_exist);
|
||||
MLX5_SET_TO_ONES(fte_match_set_misc, misc_v, geneve_tlv_option_0_exist);
|
||||
}
|
||||
|
||||
spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_3;
|
||||
|
||||
|
@ -1305,7 +1305,7 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c,
|
||||
sq->channel = c;
|
||||
sq->uar_map = mdev->mlx5e_res.hw_objs.bfreg.map;
|
||||
sq->min_inline_mode = params->tx_min_inline_mode;
|
||||
sq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu);
|
||||
sq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu) - ETH_FCS_LEN;
|
||||
sq->xsk_pool = xsk_pool;
|
||||
|
||||
sq->stats = sq->xsk_pool ?
|
||||
|
@ -67,6 +67,7 @@ static void esw_acl_egress_lgcy_groups_destroy(struct mlx5_vport *vport)
|
||||
int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
|
||||
struct mlx5_vport *vport)
|
||||
{
|
||||
bool vst_mode_steering = esw_vst_mode_is_steering(esw);
|
||||
struct mlx5_flow_destination drop_ctr_dst = {};
|
||||
struct mlx5_flow_destination *dst = NULL;
|
||||
struct mlx5_fc *drop_counter = NULL;
|
||||
@ -77,6 +78,7 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
|
||||
*/
|
||||
int table_size = 2;
|
||||
int dest_num = 0;
|
||||
int actions_flag;
|
||||
int err = 0;
|
||||
|
||||
if (vport->egress.legacy.drop_counter) {
|
||||
@ -119,8 +121,11 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
|
||||
vport->vport, vport->info.vlan, vport->info.qos);
|
||||
|
||||
/* Allowed vlan rule */
|
||||
actions_flag = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
|
||||
if (vst_mode_steering)
|
||||
actions_flag |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
|
||||
err = esw_egress_acl_vlan_create(esw, vport, NULL, vport->info.vlan,
|
||||
MLX5_FLOW_CONTEXT_ACTION_ALLOW);
|
||||
actions_flag);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
|
@ -139,11 +139,14 @@ static void esw_acl_ingress_lgcy_groups_destroy(struct mlx5_vport *vport)
|
||||
int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
|
||||
struct mlx5_vport *vport)
|
||||
{
|
||||
bool vst_mode_steering = esw_vst_mode_is_steering(esw);
|
||||
struct mlx5_flow_destination drop_ctr_dst = {};
|
||||
struct mlx5_flow_destination *dst = NULL;
|
||||
struct mlx5_flow_act flow_act = {};
|
||||
struct mlx5_flow_spec *spec = NULL;
|
||||
struct mlx5_fc *counter = NULL;
|
||||
bool vst_check_cvlan = false;
|
||||
bool vst_push_cvlan = false;
|
||||
/* The ingress acl table contains 4 groups
|
||||
* (2 active rules at the same time -
|
||||
* 1 allow rule from one of the first 3 groups.
|
||||
@ -203,7 +206,26 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (vport->info.vlan || vport->info.qos)
|
||||
if ((vport->info.vlan || vport->info.qos)) {
|
||||
if (vst_mode_steering)
|
||||
vst_push_cvlan = true;
|
||||
else if (!MLX5_CAP_ESW(esw->dev, vport_cvlan_insert_always))
|
||||
vst_check_cvlan = true;
|
||||
}
|
||||
|
||||
if (vst_check_cvlan || vport->info.spoofchk)
|
||||
spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
|
||||
|
||||
/* Create ingress allow rule */
|
||||
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
|
||||
if (vst_push_cvlan) {
|
||||
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
|
||||
flow_act.vlan[0].prio = vport->info.qos;
|
||||
flow_act.vlan[0].vid = vport->info.vlan;
|
||||
flow_act.vlan[0].ethtype = ETH_P_8021Q;
|
||||
}
|
||||
|
||||
if (vst_check_cvlan)
|
||||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
|
||||
outer_headers.cvlan_tag);
|
||||
|
||||
@ -218,9 +240,6 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
|
||||
ether_addr_copy(smac_v, vport->info.mac);
|
||||
}
|
||||
|
||||
/* Create ingress allow rule */
|
||||
spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
|
||||
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
|
||||
vport->ingress.allow_rule = mlx5_add_flow_rules(vport->ingress.acl, spec,
|
||||
&flow_act, NULL, 0);
|
||||
if (IS_ERR(vport->ingress.allow_rule)) {
|
||||
@ -232,6 +251,9 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!vst_check_cvlan && !vport->info.spoofchk)
|
||||
goto out;
|
||||
|
||||
memset(&flow_act, 0, sizeof(flow_act));
|
||||
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
|
||||
/* Attach drop flow counter */
|
||||
@ -257,7 +279,8 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
|
||||
return 0;
|
||||
|
||||
out:
|
||||
esw_acl_ingress_lgcy_cleanup(esw, vport);
|
||||
if (err)
|
||||
esw_acl_ingress_lgcy_cleanup(esw, vport);
|
||||
kvfree(spec);
|
||||
return err;
|
||||
}
|
||||
|
@ -161,10 +161,17 @@ static int modify_esw_vport_cvlan(struct mlx5_core_dev *dev, u16 vport,
|
||||
esw_vport_context.vport_cvlan_strip, 1);
|
||||
|
||||
if (set_flags & SET_VLAN_INSERT) {
|
||||
/* insert only if no vlan in packet */
|
||||
MLX5_SET(modify_esw_vport_context_in, in,
|
||||
esw_vport_context.vport_cvlan_insert, 1);
|
||||
|
||||
if (MLX5_CAP_ESW(dev, vport_cvlan_insert_always)) {
|
||||
/* insert either if vlan exist in packet or not */
|
||||
MLX5_SET(modify_esw_vport_context_in, in,
|
||||
esw_vport_context.vport_cvlan_insert,
|
||||
MLX5_VPORT_CVLAN_INSERT_ALWAYS);
|
||||
} else {
|
||||
/* insert only if no vlan in packet */
|
||||
MLX5_SET(modify_esw_vport_context_in, in,
|
||||
esw_vport_context.vport_cvlan_insert,
|
||||
MLX5_VPORT_CVLAN_INSERT_WHEN_NO_CVLAN);
|
||||
}
|
||||
MLX5_SET(modify_esw_vport_context_in, in,
|
||||
esw_vport_context.cvlan_pcp, qos);
|
||||
MLX5_SET(modify_esw_vport_context_in, in,
|
||||
@ -809,6 +816,7 @@ out_free:
|
||||
|
||||
static int esw_vport_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
|
||||
{
|
||||
bool vst_mode_steering = esw_vst_mode_is_steering(esw);
|
||||
u16 vport_num = vport->vport;
|
||||
int flags;
|
||||
int err;
|
||||
@ -839,8 +847,9 @@ static int esw_vport_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
|
||||
|
||||
flags = (vport->info.vlan || vport->info.qos) ?
|
||||
SET_VLAN_STRIP | SET_VLAN_INSERT : 0;
|
||||
modify_esw_vport_cvlan(esw->dev, vport_num, vport->info.vlan,
|
||||
vport->info.qos, flags);
|
||||
if (esw->mode == MLX5_ESWITCH_OFFLOADS || !vst_mode_steering)
|
||||
modify_esw_vport_cvlan(esw->dev, vport_num, vport->info.vlan,
|
||||
vport->info.qos, flags);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -1848,6 +1857,7 @@ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
|
||||
u16 vport, u16 vlan, u8 qos, u8 set_flags)
|
||||
{
|
||||
struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport);
|
||||
bool vst_mode_steering = esw_vst_mode_is_steering(esw);
|
||||
int err = 0;
|
||||
|
||||
if (IS_ERR(evport))
|
||||
@ -1855,9 +1865,11 @@ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
|
||||
if (vlan > 4095 || qos > 7)
|
||||
return -EINVAL;
|
||||
|
||||
err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set_flags);
|
||||
if (err)
|
||||
return err;
|
||||
if (esw->mode == MLX5_ESWITCH_OFFLOADS || !vst_mode_steering) {
|
||||
err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set_flags);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
evport->info.vlan = vlan;
|
||||
evport->info.qos = qos;
|
||||
|
@ -527,6 +527,12 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
|
||||
int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
|
||||
u16 vport, u16 vlan, u8 qos, u8 set_flags);
|
||||
|
||||
static inline bool esw_vst_mode_is_steering(struct mlx5_eswitch *esw)
|
||||
{
|
||||
return (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, pop_vlan) &&
|
||||
MLX5_CAP_ESW_INGRESS_ACL(esw->dev, push_vlan));
|
||||
}
|
||||
|
||||
static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev *dev,
|
||||
u8 vlan_depth)
|
||||
{
|
||||
|
@ -674,6 +674,12 @@ static void mlx5_fw_fatal_reporter_err_work(struct work_struct *work)
|
||||
dev = container_of(priv, struct mlx5_core_dev, priv);
|
||||
devlink = priv_to_devlink(dev);
|
||||
|
||||
mutex_lock(&dev->intf_state_mutex);
|
||||
if (test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags)) {
|
||||
mlx5_core_err(dev, "health works are not permitted at this stage\n");
|
||||
return;
|
||||
}
|
||||
mutex_unlock(&dev->intf_state_mutex);
|
||||
enter_error_state(dev, false);
|
||||
if (IS_ERR_OR_NULL(health->fw_fatal_reporter)) {
|
||||
devl_lock(devlink);
|
||||
|
@ -71,6 +71,10 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
|
||||
params->packet_merge.type = MLX5E_PACKET_MERGE_NONE;
|
||||
params->hard_mtu = MLX5_IB_GRH_BYTES + MLX5_IPOIB_HARD_LEN;
|
||||
params->tunneled_offload_en = false;
|
||||
|
||||
/* CQE compression is not supported for IPoIB */
|
||||
params->rx_cqe_compress_def = false;
|
||||
MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS, params->rx_cqe_compress_def);
|
||||
}
|
||||
|
||||
/* Called directly after IPoIB netdevice was created to initialize SW structs */
|
||||
|
@ -228,6 +228,7 @@ static void mlx5_ldev_free(struct kref *ref)
|
||||
if (ldev->nb.notifier_call)
|
||||
unregister_netdevice_notifier_net(&init_net, &ldev->nb);
|
||||
mlx5_lag_mp_cleanup(ldev);
|
||||
cancel_delayed_work_sync(&ldev->bond_work);
|
||||
destroy_workqueue(ldev->wq);
|
||||
mlx5_lag_mpesw_cleanup(ldev);
|
||||
mutex_destroy(&ldev->lock);
|
||||
|
@ -613,7 +613,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
|
||||
MLX5_SET(cmd_hca_cap, set_hca_cap, num_total_dynamic_vf_msix,
|
||||
MLX5_CAP_GEN_MAX(dev, num_total_dynamic_vf_msix));
|
||||
|
||||
if (MLX5_CAP_GEN(dev, roce_rw_supported))
|
||||
if (MLX5_CAP_GEN(dev, roce_rw_supported) && MLX5_CAP_GEN_MAX(dev, roce))
|
||||
MLX5_SET(cmd_hca_cap, set_hca_cap, roce,
|
||||
mlx5_is_roce_on(dev));
|
||||
|
||||
@ -1050,6 +1050,8 @@ err_rl_cleanup:
|
||||
err_tables_cleanup:
|
||||
mlx5_geneve_destroy(dev->geneve);
|
||||
mlx5_vxlan_destroy(dev->vxlan);
|
||||
mlx5_cleanup_clock(dev);
|
||||
mlx5_cleanup_reserved_gids(dev);
|
||||
mlx5_cq_debugfs_cleanup(dev);
|
||||
mlx5_fw_reset_cleanup(dev);
|
||||
err_events_cleanup:
|
||||
|
@ -381,7 +381,7 @@ int lan966x_port_pcs_set(struct lan966x_port *port,
|
||||
}
|
||||
|
||||
/* Take PCS out of reset */
|
||||
lan_rmw(DEV_CLOCK_CFG_LINK_SPEED_SET(2) |
|
||||
lan_rmw(DEV_CLOCK_CFG_LINK_SPEED_SET(LAN966X_SPEED_1000) |
|
||||
DEV_CLOCK_CFG_PCS_RX_RST_SET(0) |
|
||||
DEV_CLOCK_CFG_PCS_TX_RST_SET(0),
|
||||
DEV_CLOCK_CFG_LINK_SPEED |
|
||||
|
@ -834,7 +834,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
|
||||
if (err)
|
||||
goto cleanup_config;
|
||||
|
||||
if (!of_get_mac_address(np, sparx5->base_mac)) {
|
||||
if (of_get_mac_address(np, sparx5->base_mac)) {
|
||||
dev_info(sparx5->dev, "MAC addr was not set, use random MAC\n");
|
||||
eth_random_addr(sparx5->base_mac);
|
||||
sparx5->base_mac[5] = 0;
|
||||
|
@ -617,6 +617,9 @@ struct nfp_net_dp {
|
||||
* @vnic_no_name: For non-port PF vNIC make ndo_get_phys_port_name return
|
||||
* -EOPNOTSUPP to keep backwards compatibility (set by app)
|
||||
* @port: Pointer to nfp_port structure if vNIC is a port
|
||||
* @mc_lock: Protect mc_addrs list
|
||||
* @mc_addrs: List of mc addrs to add/del to HW
|
||||
* @mc_work: Work to update mc addrs
|
||||
* @app_priv: APP private data for this vNIC
|
||||
*/
|
||||
struct nfp_net {
|
||||
@ -718,6 +721,10 @@ struct nfp_net {
|
||||
|
||||
struct nfp_port *port;
|
||||
|
||||
spinlock_t mc_lock;
|
||||
struct list_head mc_addrs;
|
||||
struct work_struct mc_work;
|
||||
|
||||
void *app_priv;
|
||||
};
|
||||
|
||||
|
@ -1334,9 +1334,14 @@ err_unlock:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nfp_net_mc_cfg(struct net_device *netdev, const unsigned char *addr, const u32 cmd)
|
||||
struct nfp_mc_addr_entry {
|
||||
u8 addr[ETH_ALEN];
|
||||
u32 cmd;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static int nfp_net_mc_cfg(struct nfp_net *nn, const unsigned char *addr, const u32 cmd)
|
||||
{
|
||||
struct nfp_net *nn = netdev_priv(netdev);
|
||||
int ret;
|
||||
|
||||
ret = nfp_net_mbox_lock(nn, NFP_NET_CFG_MULTICAST_SZ);
|
||||
@ -1351,6 +1356,25 @@ static int nfp_net_mc_cfg(struct net_device *netdev, const unsigned char *addr,
|
||||
return nfp_net_mbox_reconfig_and_unlock(nn, cmd);
|
||||
}
|
||||
|
||||
static int nfp_net_mc_prep(struct nfp_net *nn, const unsigned char *addr, const u32 cmd)
|
||||
{
|
||||
struct nfp_mc_addr_entry *entry;
|
||||
|
||||
entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
|
||||
ether_addr_copy(entry->addr, addr);
|
||||
entry->cmd = cmd;
|
||||
spin_lock_bh(&nn->mc_lock);
|
||||
list_add_tail(&entry->list, &nn->mc_addrs);
|
||||
spin_unlock_bh(&nn->mc_lock);
|
||||
|
||||
schedule_work(&nn->mc_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfp_net_mc_sync(struct net_device *netdev, const unsigned char *addr)
|
||||
{
|
||||
struct nfp_net *nn = netdev_priv(netdev);
|
||||
@ -1361,12 +1385,35 @@ static int nfp_net_mc_sync(struct net_device *netdev, const unsigned char *addr)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return nfp_net_mc_cfg(netdev, addr, NFP_NET_CFG_MBOX_CMD_MULTICAST_ADD);
|
||||
return nfp_net_mc_prep(nn, addr, NFP_NET_CFG_MBOX_CMD_MULTICAST_ADD);
|
||||
}
|
||||
|
||||
static int nfp_net_mc_unsync(struct net_device *netdev, const unsigned char *addr)
|
||||
{
|
||||
return nfp_net_mc_cfg(netdev, addr, NFP_NET_CFG_MBOX_CMD_MULTICAST_DEL);
|
||||
struct nfp_net *nn = netdev_priv(netdev);
|
||||
|
||||
return nfp_net_mc_prep(nn, addr, NFP_NET_CFG_MBOX_CMD_MULTICAST_DEL);
|
||||
}
|
||||
|
||||
static void nfp_net_mc_addr_config(struct work_struct *work)
|
||||
{
|
||||
struct nfp_net *nn = container_of(work, struct nfp_net, mc_work);
|
||||
struct nfp_mc_addr_entry *entry, *tmp;
|
||||
struct list_head tmp_list;
|
||||
|
||||
INIT_LIST_HEAD(&tmp_list);
|
||||
|
||||
spin_lock_bh(&nn->mc_lock);
|
||||
list_splice_init(&nn->mc_addrs, &tmp_list);
|
||||
spin_unlock_bh(&nn->mc_lock);
|
||||
|
||||
list_for_each_entry_safe(entry, tmp, &tmp_list, list) {
|
||||
if (nfp_net_mc_cfg(nn, entry->addr, entry->cmd))
|
||||
nn_err(nn, "Config mc address to HW failed.\n");
|
||||
|
||||
list_del(&entry->list);
|
||||
kfree(entry);
|
||||
}
|
||||
}
|
||||
|
||||
static void nfp_net_set_rx_mode(struct net_device *netdev)
|
||||
@ -2633,6 +2680,11 @@ int nfp_net_init(struct nfp_net *nn)
|
||||
|
||||
if (!nn->dp.netdev)
|
||||
return 0;
|
||||
|
||||
spin_lock_init(&nn->mc_lock);
|
||||
INIT_LIST_HEAD(&nn->mc_addrs);
|
||||
INIT_WORK(&nn->mc_work, nfp_net_mc_addr_config);
|
||||
|
||||
return register_netdev(nn->dp.netdev);
|
||||
|
||||
err_clean_mbox:
|
||||
@ -2652,5 +2704,6 @@ void nfp_net_clean(struct nfp_net *nn)
|
||||
unregister_netdev(nn->dp.netdev);
|
||||
nfp_net_ipsec_clean(nn);
|
||||
nfp_ccm_mbox_clean(nn);
|
||||
flush_work(&nn->mc_work);
|
||||
nfp_net_reconfig_wait_posted(nn);
|
||||
}
|
||||
|
@ -1832,7 +1832,8 @@ static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
|
||||
struct qed_ptt *p_ptt,
|
||||
u32 image_type,
|
||||
u32 *nvram_offset_bytes,
|
||||
u32 *nvram_size_bytes)
|
||||
u32 *nvram_size_bytes,
|
||||
bool b_can_sleep)
|
||||
{
|
||||
u32 ret_mcp_resp, ret_mcp_param, ret_txn_size;
|
||||
struct mcp_file_att file_att;
|
||||
@ -1846,7 +1847,8 @@ static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
|
||||
&ret_mcp_resp,
|
||||
&ret_mcp_param,
|
||||
&ret_txn_size,
|
||||
(u32 *)&file_att, false);
|
||||
(u32 *)&file_att,
|
||||
b_can_sleep);
|
||||
|
||||
/* Check response */
|
||||
if (nvm_result || (ret_mcp_resp & FW_MSG_CODE_MASK) !=
|
||||
@ -1873,7 +1875,9 @@ static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
|
||||
static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
|
||||
struct qed_ptt *p_ptt,
|
||||
u32 nvram_offset_bytes,
|
||||
u32 nvram_size_bytes, u32 *ret_buf)
|
||||
u32 nvram_size_bytes,
|
||||
u32 *ret_buf,
|
||||
bool b_can_sleep)
|
||||
{
|
||||
u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy;
|
||||
s32 bytes_left = nvram_size_bytes;
|
||||
@ -1899,7 +1903,7 @@ static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
|
||||
&ret_mcp_resp,
|
||||
&ret_mcp_param, &ret_read_size,
|
||||
(u32 *)((u8 *)ret_buf + read_offset),
|
||||
false))
|
||||
b_can_sleep))
|
||||
return DBG_STATUS_NVRAM_READ_FAILED;
|
||||
|
||||
/* Check response */
|
||||
@ -3380,7 +3384,8 @@ static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn,
|
||||
p_ptt,
|
||||
NVM_TYPE_HW_DUMP_OUT,
|
||||
&hw_dump_offset_bytes,
|
||||
&hw_dump_size_bytes);
|
||||
&hw_dump_size_bytes,
|
||||
false);
|
||||
if (status != DBG_STATUS_OK)
|
||||
return 0;
|
||||
|
||||
@ -3397,7 +3402,9 @@ static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn,
|
||||
status = qed_nvram_read(p_hwfn,
|
||||
p_ptt,
|
||||
hw_dump_offset_bytes,
|
||||
hw_dump_size_bytes, dump_buf + offset);
|
||||
hw_dump_size_bytes,
|
||||
dump_buf + offset,
|
||||
false);
|
||||
if (status != DBG_STATUS_OK) {
|
||||
DP_NOTICE(p_hwfn,
|
||||
"Failed to read MCP HW Dump image from NVRAM\n");
|
||||
@ -4123,7 +4130,9 @@ static enum dbg_status qed_mcp_trace_get_meta_info(struct qed_hwfn *p_hwfn,
|
||||
return qed_find_nvram_image(p_hwfn,
|
||||
p_ptt,
|
||||
nvram_image_type,
|
||||
trace_meta_offset, trace_meta_size);
|
||||
trace_meta_offset,
|
||||
trace_meta_size,
|
||||
true);
|
||||
}
|
||||
|
||||
/* Reads the MCP Trace meta data from NVRAM into the specified buffer */
|
||||
@ -4139,7 +4148,10 @@ static enum dbg_status qed_mcp_trace_read_meta(struct qed_hwfn *p_hwfn,
|
||||
/* Read meta data from NVRAM */
|
||||
status = qed_nvram_read(p_hwfn,
|
||||
p_ptt,
|
||||
nvram_offset_in_bytes, size_in_bytes, buf);
|
||||
nvram_offset_in_bytes,
|
||||
size_in_bytes,
|
||||
buf,
|
||||
true);
|
||||
if (status != DBG_STATUS_OK)
|
||||
return status;
|
||||
|
||||
|
@ -2505,7 +2505,13 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter)
|
||||
goto disable_mbx_intr;
|
||||
|
||||
qlcnic_83xx_clear_function_resources(adapter);
|
||||
qlcnic_dcb_enable(adapter->dcb);
|
||||
|
||||
err = qlcnic_dcb_enable(adapter->dcb);
|
||||
if (err) {
|
||||
qlcnic_dcb_free(adapter->dcb);
|
||||
goto disable_mbx_intr;
|
||||
}
|
||||
|
||||
qlcnic_83xx_initialize_nic(adapter, 1);
|
||||
qlcnic_dcb_get_info(adapter->dcb);
|
||||
|
||||
|
@ -41,11 +41,6 @@ struct qlcnic_dcb {
|
||||
unsigned long state;
|
||||
};
|
||||
|
||||
static inline void qlcnic_clear_dcb_ops(struct qlcnic_dcb *dcb)
|
||||
{
|
||||
kfree(dcb);
|
||||
}
|
||||
|
||||
static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
|
||||
{
|
||||
if (dcb && dcb->ops->get_hw_capability)
|
||||
@ -112,9 +107,8 @@ static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_dcb *dcb)
|
||||
dcb->ops->init_dcbnl_ops(dcb);
|
||||
}
|
||||
|
||||
static inline void qlcnic_dcb_enable(struct qlcnic_dcb *dcb)
|
||||
static inline int qlcnic_dcb_enable(struct qlcnic_dcb *dcb)
|
||||
{
|
||||
if (dcb && qlcnic_dcb_attach(dcb))
|
||||
qlcnic_clear_dcb_ops(dcb);
|
||||
return dcb ? qlcnic_dcb_attach(dcb) : 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -2599,7 +2599,13 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
"Device does not support MSI interrupts\n");
|
||||
|
||||
if (qlcnic_82xx_check(adapter)) {
|
||||
qlcnic_dcb_enable(adapter->dcb);
|
||||
err = qlcnic_dcb_enable(adapter->dcb);
|
||||
if (err) {
|
||||
qlcnic_dcb_free(adapter->dcb);
|
||||
dev_err(&pdev->dev, "Failed to enable DCB\n");
|
||||
goto err_out_free_hw;
|
||||
}
|
||||
|
||||
qlcnic_dcb_get_info(adapter->dcb);
|
||||
err = qlcnic_setup_intr(adapter);
|
||||
|
||||
|
@ -2210,28 +2210,6 @@ static int rtl_set_mac_address(struct net_device *dev, void *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtl_wol_enable_rx(struct rtl8169_private *tp)
|
||||
{
|
||||
if (tp->mac_version >= RTL_GIGA_MAC_VER_25)
|
||||
RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) |
|
||||
AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
|
||||
}
|
||||
|
||||
static void rtl_prepare_power_down(struct rtl8169_private *tp)
|
||||
{
|
||||
if (tp->dash_type != RTL_DASH_NONE)
|
||||
return;
|
||||
|
||||
if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
|
||||
tp->mac_version == RTL_GIGA_MAC_VER_33)
|
||||
rtl_ephy_write(tp, 0x19, 0xff64);
|
||||
|
||||
if (device_may_wakeup(tp_to_dev(tp))) {
|
||||
phy_speed_down(tp->phydev, false);
|
||||
rtl_wol_enable_rx(tp);
|
||||
}
|
||||
}
|
||||
|
||||
static void rtl_init_rxcfg(struct rtl8169_private *tp)
|
||||
{
|
||||
switch (tp->mac_version) {
|
||||
@ -2455,6 +2433,31 @@ static void rtl_enable_rxdvgate(struct rtl8169_private *tp)
|
||||
rtl_wait_txrx_fifo_empty(tp);
|
||||
}
|
||||
|
||||
static void rtl_wol_enable_rx(struct rtl8169_private *tp)
|
||||
{
|
||||
if (tp->mac_version >= RTL_GIGA_MAC_VER_25)
|
||||
RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) |
|
||||
AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
|
||||
|
||||
if (tp->mac_version >= RTL_GIGA_MAC_VER_40)
|
||||
rtl_disable_rxdvgate(tp);
|
||||
}
|
||||
|
||||
static void rtl_prepare_power_down(struct rtl8169_private *tp)
|
||||
{
|
||||
if (tp->dash_type != RTL_DASH_NONE)
|
||||
return;
|
||||
|
||||
if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
|
||||
tp->mac_version == RTL_GIGA_MAC_VER_33)
|
||||
rtl_ephy_write(tp, 0x19, 0xff64);
|
||||
|
||||
if (device_may_wakeup(tp_to_dev(tp))) {
|
||||
phy_speed_down(tp->phydev, false);
|
||||
rtl_wol_enable_rx(tp);
|
||||
}
|
||||
}
|
||||
|
||||
static void rtl_set_tx_config_registers(struct rtl8169_private *tp)
|
||||
{
|
||||
u32 val = TX_DMA_BURST << TxDMAShift |
|
||||
@ -3872,7 +3875,7 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp)
|
||||
netdev_reset_queue(tp->dev);
|
||||
}
|
||||
|
||||
static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down)
|
||||
static void rtl8169_cleanup(struct rtl8169_private *tp)
|
||||
{
|
||||
napi_disable(&tp->napi);
|
||||
|
||||
@ -3884,9 +3887,6 @@ static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down)
|
||||
|
||||
rtl_rx_close(tp);
|
||||
|
||||
if (going_down && tp->dev->wol_enabled)
|
||||
goto no_reset;
|
||||
|
||||
switch (tp->mac_version) {
|
||||
case RTL_GIGA_MAC_VER_28:
|
||||
case RTL_GIGA_MAC_VER_31:
|
||||
@ -3907,7 +3907,7 @@ static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down)
|
||||
}
|
||||
|
||||
rtl_hw_reset(tp);
|
||||
no_reset:
|
||||
|
||||
rtl8169_tx_clear(tp);
|
||||
rtl8169_init_ring_indexes(tp);
|
||||
}
|
||||
@ -3918,7 +3918,7 @@ static void rtl_reset_work(struct rtl8169_private *tp)
|
||||
|
||||
netif_stop_queue(tp->dev);
|
||||
|
||||
rtl8169_cleanup(tp, false);
|
||||
rtl8169_cleanup(tp);
|
||||
|
||||
for (i = 0; i < NUM_RX_DESC; i++)
|
||||
rtl8169_mark_to_asic(tp->RxDescArray + i);
|
||||
@ -4605,7 +4605,7 @@ static void rtl8169_down(struct rtl8169_private *tp)
|
||||
pci_clear_master(tp->pci_dev);
|
||||
rtl_pci_commit(tp);
|
||||
|
||||
rtl8169_cleanup(tp, true);
|
||||
rtl8169_cleanup(tp);
|
||||
rtl_disable_exit_l1(tp);
|
||||
rtl_prepare_power_down(tp);
|
||||
}
|
||||
|
@ -1578,6 +1578,7 @@ static int rswitch_device_alloc(struct rswitch_private *priv, int index)
|
||||
{
|
||||
struct platform_device *pdev = priv->pdev;
|
||||
struct rswitch_device *rdev;
|
||||
struct device_node *port;
|
||||
struct net_device *ndev;
|
||||
int err;
|
||||
|
||||
@ -1606,7 +1607,9 @@ static int rswitch_device_alloc(struct rswitch_private *priv, int index)
|
||||
|
||||
netif_napi_add(ndev, &rdev->napi, rswitch_poll);
|
||||
|
||||
err = of_get_ethdev_address(pdev->dev.of_node, ndev);
|
||||
port = rswitch_get_port_node(rdev);
|
||||
err = of_get_ethdev_address(port, ndev);
|
||||
of_node_put(port);
|
||||
if (err) {
|
||||
if (is_valid_ether_addr(rdev->etha->mac_addr))
|
||||
eth_hw_addr_set(ndev, rdev->etha->mac_addr);
|
||||
@ -1786,6 +1789,11 @@ static int renesas_eth_sw_probe(struct platform_device *pdev)
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
ret = rswitch_init(priv);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
device_set_wakeup_capable(&pdev->dev, 1);
|
||||
|
||||
|
@ -132,10 +132,10 @@ static void ipa_interrupt_suspend_control(struct ipa_interrupt *interrupt,
|
||||
u32 endpoint_id, bool enable)
|
||||
{
|
||||
struct ipa *ipa = interrupt->ipa;
|
||||
u32 mask = BIT(endpoint_id % 32);
|
||||
u32 unit = endpoint_id / 32;
|
||||
const struct ipa_reg *reg;
|
||||
u32 offset;
|
||||
u32 mask;
|
||||
u32 val;
|
||||
|
||||
WARN_ON(!test_bit(endpoint_id, ipa->available));
|
||||
@ -148,7 +148,6 @@ static void ipa_interrupt_suspend_control(struct ipa_interrupt *interrupt,
|
||||
offset = ipa_reg_n_offset(reg, unit);
|
||||
val = ioread32(ipa->reg_virt + offset);
|
||||
|
||||
mask = BIT(endpoint_id);
|
||||
if (enable)
|
||||
val |= mask;
|
||||
else
|
||||
|
@ -105,6 +105,7 @@ static int xgmiitorgmii_probe(struct mdio_device *mdiodev)
|
||||
|
||||
if (!priv->phy_dev->drv) {
|
||||
dev_info(dev, "Attached phy not ready\n");
|
||||
put_device(&priv->phy_dev->mdio.dev);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,8 @@ static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
|
||||
|
||||
off = le32_to_cpu(u.get_c->offset);
|
||||
len = le32_to_cpu(u.get_c->len);
|
||||
if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE))
|
||||
if (unlikely((off > CONTROL_BUFFER_SIZE - 8) ||
|
||||
(len > CONTROL_BUFFER_SIZE - 8 - off)))
|
||||
goto response_error;
|
||||
|
||||
if (*reply_len != -1 && len != *reply_len)
|
||||
|
@ -974,6 +974,9 @@ static int veth_poll(struct napi_struct *napi, int budget)
|
||||
xdp_set_return_frame_no_direct();
|
||||
done = veth_xdp_rcv(rq, budget, &bq, &stats);
|
||||
|
||||
if (stats.xdp_redirect > 0)
|
||||
xdp_do_flush();
|
||||
|
||||
if (done < budget && napi_complete_done(napi, done)) {
|
||||
/* Write rx_notify_masked before reading ptr_ring */
|
||||
smp_store_mb(rq->rx_notify_masked, false);
|
||||
@ -987,8 +990,6 @@ static int veth_poll(struct napi_struct *napi, int budget)
|
||||
|
||||
if (stats.xdp_tx > 0)
|
||||
veth_xdp_flush(rq, &bq);
|
||||
if (stats.xdp_redirect > 0)
|
||||
xdp_do_flush();
|
||||
xdp_clear_return_frame_no_direct();
|
||||
|
||||
return done;
|
||||
|
@ -1288,6 +1288,10 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
|
||||
(le32_to_cpu(gdesc->dword[3]) &
|
||||
VMXNET3_RCD_CSUM_OK) == VMXNET3_RCD_CSUM_OK) {
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
if ((le32_to_cpu(gdesc->dword[0]) &
|
||||
(1UL << VMXNET3_RCD_HDR_INNER_SHIFT))) {
|
||||
skb->csum_level = 1;
|
||||
}
|
||||
WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
|
||||
!(le32_to_cpu(gdesc->dword[0]) &
|
||||
(1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
|
||||
@ -1297,6 +1301,10 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
|
||||
} else if (gdesc->rcd.v6 && (le32_to_cpu(gdesc->dword[3]) &
|
||||
(1 << VMXNET3_RCD_TUC_SHIFT))) {
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
if ((le32_to_cpu(gdesc->dword[0]) &
|
||||
(1UL << VMXNET3_RCD_HDR_INNER_SHIFT))) {
|
||||
skb->csum_level = 1;
|
||||
}
|
||||
WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
|
||||
!(le32_to_cpu(gdesc->dword[0]) &
|
||||
(1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
|
||||
|
@ -1385,8 +1385,8 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
|
||||
|
||||
/* loopback, multicast & non-ND link-local traffic; do not push through
|
||||
* packet taps again. Reset pkt_type for upper layers to process skb.
|
||||
* For strict packets with a source LLA, determine the dst using the
|
||||
* original ifindex.
|
||||
* For non-loopback strict packets, determine the dst using the original
|
||||
* ifindex.
|
||||
*/
|
||||
if (skb->pkt_type == PACKET_LOOPBACK || (need_strict && !is_ndisc)) {
|
||||
skb->dev = vrf_dev;
|
||||
@ -1395,7 +1395,7 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
|
||||
|
||||
if (skb->pkt_type == PACKET_LOOPBACK)
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
else if (ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)
|
||||
else
|
||||
vrf_ip6_input_dst(skb, vrf_dev, orig_iif);
|
||||
|
||||
goto out;
|
||||
|
@ -2917,16 +2917,23 @@ static int vxlan_init(struct net_device *dev)
|
||||
vxlan_vnigroup_init(vxlan);
|
||||
|
||||
dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
|
||||
if (!dev->tstats)
|
||||
return -ENOMEM;
|
||||
|
||||
err = gro_cells_init(&vxlan->gro_cells, dev);
|
||||
if (err) {
|
||||
free_percpu(dev->tstats);
|
||||
return err;
|
||||
if (!dev->tstats) {
|
||||
err = -ENOMEM;
|
||||
goto err_vnigroup_uninit;
|
||||
}
|
||||
|
||||
err = gro_cells_init(&vxlan->gro_cells, dev);
|
||||
if (err)
|
||||
goto err_free_percpu;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_percpu:
|
||||
free_percpu(dev->tstats);
|
||||
err_vnigroup_uninit:
|
||||
if (vxlan->cfg.flags & VXLAN_F_VNIFILTER)
|
||||
vxlan_vnigroup_uninit(vxlan);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void vxlan_fdb_delete_default(struct vxlan_dev *vxlan, __be32 vni)
|
||||
|
@ -327,9 +327,9 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
|
||||
#define __STAT_SAFE(hif_dev, expr) ((hif_dev)->htc_handle->drv_priv ? (expr) : 0)
|
||||
#define CAB_STAT_INC(priv) ((priv)->debug.tx_stats.cab_queued++)
|
||||
#define TX_QSTAT_INC(priv, q) ((priv)->debug.tx_stats.queue_stats[q]++)
|
||||
#define __STAT_SAFE(hif_dev, expr) do { ((hif_dev)->htc_handle->drv_priv ? (expr) : 0); } while (0)
|
||||
#define CAB_STAT_INC(priv) do { ((priv)->debug.tx_stats.cab_queued++); } while (0)
|
||||
#define TX_QSTAT_INC(priv, q) do { ((priv)->debug.tx_stats.queue_stats[q]++); } while (0)
|
||||
|
||||
#define TX_STAT_INC(hif_dev, c) \
|
||||
__STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c++)
|
||||
@ -378,10 +378,10 @@ void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
|
||||
struct ethtool_stats *stats, u64 *data);
|
||||
#else
|
||||
|
||||
#define TX_STAT_INC(hif_dev, c)
|
||||
#define TX_STAT_ADD(hif_dev, c, a)
|
||||
#define RX_STAT_INC(hif_dev, c)
|
||||
#define RX_STAT_ADD(hif_dev, c, a)
|
||||
#define TX_STAT_INC(hif_dev, c) do { } while (0)
|
||||
#define TX_STAT_ADD(hif_dev, c, a) do { } while (0)
|
||||
#define RX_STAT_INC(hif_dev, c) do { } while (0)
|
||||
#define RX_STAT_ADD(hif_dev, c, a) do { } while (0)
|
||||
|
||||
#define CAB_STAT_INC(priv)
|
||||
#define TX_QSTAT_INC(priv, c)
|
||||
|
@ -1106,6 +1106,11 @@ int iwl_read_ppag_table(struct iwl_fw_runtime *fwrt, union iwl_ppag_table_cmd *c
|
||||
int i, j, num_sub_bands;
|
||||
s8 *gain;
|
||||
|
||||
/* many firmware images for JF lie about this */
|
||||
if (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id) ==
|
||||
CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) {
|
||||
IWL_DEBUG_RADIO(fwrt,
|
||||
"PPAG capability not supported by FW, command not sent.\n");
|
||||
|
@ -2,6 +2,7 @@
|
||||
config MT7996E
|
||||
tristate "MediaTek MT7996 (PCIe) support"
|
||||
select MT76_CONNAC_LIB
|
||||
select RELAY
|
||||
depends on MAC80211
|
||||
depends on PCI
|
||||
help
|
||||
|
@ -3,6 +3,3 @@ obj-$(CONFIG_WLCORE) += wlcore/
|
||||
obj-$(CONFIG_WL12XX) += wl12xx/
|
||||
obj-$(CONFIG_WL1251) += wl1251/
|
||||
obj-$(CONFIG_WL18XX) += wl18xx/
|
||||
|
||||
# small builtin driver bit
|
||||
obj-$(CONFIG_WILINK_PLATFORM_DATA) += wilink_platform_data.o
|
||||
|
@ -410,13 +410,13 @@ static ssize_t qeth_dev_isolation_show(struct device *dev,
|
||||
|
||||
switch (card->options.isolation) {
|
||||
case ISOLATION_MODE_NONE:
|
||||
return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_NONE);
|
||||
return sysfs_emit(buf, "%s\n", ATTR_QETH_ISOLATION_NONE);
|
||||
case ISOLATION_MODE_FWD:
|
||||
return snprintf(buf, 9, "%s\n", ATTR_QETH_ISOLATION_FWD);
|
||||
return sysfs_emit(buf, "%s\n", ATTR_QETH_ISOLATION_FWD);
|
||||
case ISOLATION_MODE_DROP:
|
||||
return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_DROP);
|
||||
return sysfs_emit(buf, "%s\n", ATTR_QETH_ISOLATION_DROP);
|
||||
default:
|
||||
return snprintf(buf, 5, "%s\n", "N/A");
|
||||
return sysfs_emit(buf, "%s\n", "N/A");
|
||||
}
|
||||
}
|
||||
|
||||
@ -500,9 +500,9 @@ static ssize_t qeth_hw_trap_show(struct device *dev,
|
||||
struct qeth_card *card = dev_get_drvdata(dev);
|
||||
|
||||
if (card->info.hwtrap)
|
||||
return snprintf(buf, 5, "arm\n");
|
||||
return sysfs_emit(buf, "arm\n");
|
||||
else
|
||||
return snprintf(buf, 8, "disarm\n");
|
||||
return sysfs_emit(buf, "disarm\n");
|
||||
}
|
||||
|
||||
static ssize_t qeth_hw_trap_store(struct device *dev,
|
||||
|
@ -45,8 +45,8 @@ struct sk_buff;
|
||||
QCA_HDR_MGMT_COMMAND_LEN + \
|
||||
QCA_HDR_MGMT_DATA1_LEN)
|
||||
|
||||
#define QCA_HDR_MGMT_DATA2_LEN 12 /* Other 12 byte for the mdio data */
|
||||
#define QCA_HDR_MGMT_PADDING_LEN 34 /* Padding to reach the min Ethernet packet */
|
||||
#define QCA_HDR_MGMT_DATA2_LEN 28 /* Other 28 byte for the mdio data */
|
||||
#define QCA_HDR_MGMT_PADDING_LEN 18 /* Padding to reach the min Ethernet packet */
|
||||
|
||||
#define QCA_HDR_MGMT_PKT_LEN (QCA_HDR_MGMT_HEADER_LEN + \
|
||||
QCA_HDR_LEN + \
|
||||
|
@ -1090,6 +1090,11 @@ enum {
|
||||
MLX5_VPORT_ADMIN_STATE_AUTO = 0x2,
|
||||
};
|
||||
|
||||
enum {
|
||||
MLX5_VPORT_CVLAN_INSERT_WHEN_NO_CVLAN = 0x1,
|
||||
MLX5_VPORT_CVLAN_INSERT_ALWAYS = 0x3,
|
||||
};
|
||||
|
||||
enum {
|
||||
MLX5_L3_PROT_TYPE_IPV4 = 0,
|
||||
MLX5_L3_PROT_TYPE_IPV6 = 1,
|
||||
|
@ -913,7 +913,8 @@ struct mlx5_ifc_e_switch_cap_bits {
|
||||
u8 vport_svlan_insert[0x1];
|
||||
u8 vport_cvlan_insert_if_not_exist[0x1];
|
||||
u8 vport_cvlan_insert_overwrite[0x1];
|
||||
u8 reserved_at_5[0x2];
|
||||
u8 reserved_at_5[0x1];
|
||||
u8 vport_cvlan_insert_always[0x1];
|
||||
u8 esw_shared_ingress_acl[0x1];
|
||||
u8 esw_uplink_ingress_acl[0x1];
|
||||
u8 root_ft_on_other_esw[0x1];
|
||||
|
@ -197,7 +197,7 @@ struct ip_set_region {
|
||||
};
|
||||
|
||||
/* Max range where every element is added/deleted in one step */
|
||||
#define IPSET_MAX_RANGE (1<<20)
|
||||
#define IPSET_MAX_RANGE (1<<14)
|
||||
|
||||
/* The max revision number supported by any set type + 1 */
|
||||
#define IPSET_REVISION_MAX 9
|
||||
|
@ -826,10 +826,7 @@ struct phy_driver {
|
||||
* whether to advertise lower-speed modes for that interface. It is
|
||||
* assumed that if a rate matching mode is supported on an interface,
|
||||
* then that interface's rate can be adapted to all slower link speeds
|
||||
* supported by the phy. If iface is %PHY_INTERFACE_MODE_NA, and the phy
|
||||
* supports any kind of rate matching for any interface, then it must
|
||||
* return that rate matching mode (preferring %RATE_MATCH_PAUSE to
|
||||
* %RATE_MATCH_CRS). If the interface is not supported, this should
|
||||
* supported by the phy. If the interface is not supported, this should
|
||||
* return %RATE_MATCH_NONE.
|
||||
*/
|
||||
int (*get_rate_matching)(struct phy_device *phydev,
|
||||
|
@ -108,6 +108,10 @@ struct inet_bind2_bucket {
|
||||
struct hlist_node node;
|
||||
/* List of sockets hashed to this bucket */
|
||||
struct hlist_head owners;
|
||||
/* bhash has twsk in owners, but bhash2 has twsk in
|
||||
* deathrow not to add a member in struct sock_common.
|
||||
*/
|
||||
struct hlist_head deathrow;
|
||||
};
|
||||
|
||||
static inline struct net *ib_net(const struct inet_bind_bucket *ib)
|
||||
|
@ -73,9 +73,14 @@ struct inet_timewait_sock {
|
||||
u32 tw_priority;
|
||||
struct timer_list tw_timer;
|
||||
struct inet_bind_bucket *tw_tb;
|
||||
struct inet_bind2_bucket *tw_tb2;
|
||||
struct hlist_node tw_bind2_node;
|
||||
};
|
||||
#define tw_tclass tw_tos
|
||||
|
||||
#define twsk_for_each_bound_bhash2(__tw, list) \
|
||||
hlist_for_each_entry(__tw, list, tw_bind2_node)
|
||||
|
||||
static inline struct inet_timewait_sock *inet_twsk(const struct sock *sk)
|
||||
{
|
||||
return (struct inet_timewait_sock *)sk;
|
||||
|
@ -312,17 +312,29 @@ struct nft_set_iter {
|
||||
/**
|
||||
* struct nft_set_desc - description of set elements
|
||||
*
|
||||
* @ktype: key type
|
||||
* @klen: key length
|
||||
* @dtype: data type
|
||||
* @dlen: data length
|
||||
* @objtype: object type
|
||||
* @flags: flags
|
||||
* @size: number of set elements
|
||||
* @policy: set policy
|
||||
* @gc_int: garbage collector interval
|
||||
* @field_len: length of each field in concatenation, bytes
|
||||
* @field_count: number of concatenated fields in element
|
||||
* @expr: set must support for expressions
|
||||
*/
|
||||
struct nft_set_desc {
|
||||
u32 ktype;
|
||||
unsigned int klen;
|
||||
u32 dtype;
|
||||
unsigned int dlen;
|
||||
u32 objtype;
|
||||
unsigned int size;
|
||||
u32 policy;
|
||||
u32 gc_int;
|
||||
u64 timeout;
|
||||
u8 field_len[NFT_REG32_COUNT];
|
||||
u8 field_count;
|
||||
bool expr;
|
||||
@ -585,7 +597,9 @@ void *nft_set_catchall_gc(const struct nft_set *set);
|
||||
|
||||
static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
|
||||
{
|
||||
return set->gc_int ? msecs_to_jiffies(set->gc_int) : HZ;
|
||||
u32 gc_int = READ_ONCE(set->gc_int);
|
||||
|
||||
return gc_int ? msecs_to_jiffies(gc_int) : HZ;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1558,6 +1572,9 @@ struct nft_trans_rule {
|
||||
struct nft_trans_set {
|
||||
struct nft_set *set;
|
||||
u32 set_id;
|
||||
u32 gc_int;
|
||||
u64 timeout;
|
||||
bool update;
|
||||
bool bound;
|
||||
};
|
||||
|
||||
@ -1567,6 +1584,12 @@ struct nft_trans_set {
|
||||
(((struct nft_trans_set *)trans->data)->set_id)
|
||||
#define nft_trans_set_bound(trans) \
|
||||
(((struct nft_trans_set *)trans->data)->bound)
|
||||
#define nft_trans_set_update(trans) \
|
||||
(((struct nft_trans_set *)trans->data)->update)
|
||||
#define nft_trans_set_timeout(trans) \
|
||||
(((struct nft_trans_set *)trans->data)->timeout)
|
||||
#define nft_trans_set_gc_int(trans) \
|
||||
(((struct nft_trans_set *)trans->data)->gc_int)
|
||||
|
||||
struct nft_trans_chain {
|
||||
bool update;
|
||||
|
@ -216,6 +216,8 @@ skip:
|
||||
return tp->classify(skb, tp, res);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_CLS */
|
||||
|
||||
static inline void tc_wrapper_init(void)
|
||||
{
|
||||
#ifdef CONFIG_X86
|
||||
@ -224,8 +226,6 @@ static inline void tc_wrapper_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_CLS */
|
||||
|
||||
#else
|
||||
|
||||
#define TC_INDIRECT_SCOPE static
|
||||
|
@ -1062,10 +1062,10 @@ TRACE_EVENT(rxrpc_receive,
|
||||
);
|
||||
|
||||
TRACE_EVENT(rxrpc_recvmsg,
|
||||
TP_PROTO(struct rxrpc_call *call, enum rxrpc_recvmsg_trace why,
|
||||
TP_PROTO(unsigned int call_debug_id, enum rxrpc_recvmsg_trace why,
|
||||
int ret),
|
||||
|
||||
TP_ARGS(call, why, ret),
|
||||
TP_ARGS(call_debug_id, why, ret),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, call )
|
||||
@ -1074,7 +1074,7 @@ TRACE_EVENT(rxrpc_recvmsg,
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->call = call ? call->debug_id : 0;
|
||||
__entry->call = call_debug_id;
|
||||
__entry->why = why;
|
||||
__entry->ret = ret;
|
||||
),
|
||||
|
@ -38,7 +38,7 @@
|
||||
*/
|
||||
#define BR2684_ENCAPS_VC (0) /* VC-mux */
|
||||
#define BR2684_ENCAPS_LLC (1)
|
||||
#define BR2684_ENCAPS_AUTODETECT (2) /* Unsuported */
|
||||
#define BR2684_ENCAPS_AUTODETECT (2) /* Unsupported */
|
||||
|
||||
/*
|
||||
* Is this VC bridged or routed?
|
||||
|
@ -351,8 +351,10 @@ BTF_ID(func, bpf_lsm_bpf_prog_alloc_security)
|
||||
BTF_ID(func, bpf_lsm_bpf_prog_free_security)
|
||||
BTF_ID(func, bpf_lsm_file_alloc_security)
|
||||
BTF_ID(func, bpf_lsm_file_free_security)
|
||||
#ifdef CONFIG_SECURITY_NETWORK
|
||||
BTF_ID(func, bpf_lsm_sk_alloc_security)
|
||||
BTF_ID(func, bpf_lsm_sk_free_security)
|
||||
#endif /* CONFIG_SECURITY_NETWORK */
|
||||
BTF_ID(func, bpf_lsm_task_free)
|
||||
BTF_SET_END(untrusted_lsm_hooks)
|
||||
|
||||
|
@ -438,6 +438,7 @@ struct bpf_iter_seq_task_vma_info {
|
||||
*/
|
||||
struct bpf_iter_seq_task_common common;
|
||||
struct task_struct *task;
|
||||
struct mm_struct *mm;
|
||||
struct vm_area_struct *vma;
|
||||
u32 tid;
|
||||
unsigned long prev_vm_start;
|
||||
@ -456,16 +457,19 @@ task_vma_seq_get_next(struct bpf_iter_seq_task_vma_info *info)
|
||||
enum bpf_task_vma_iter_find_op op;
|
||||
struct vm_area_struct *curr_vma;
|
||||
struct task_struct *curr_task;
|
||||
struct mm_struct *curr_mm;
|
||||
u32 saved_tid = info->tid;
|
||||
|
||||
/* If this function returns a non-NULL vma, it holds a reference to
|
||||
* the task_struct, and holds read lock on vma->mm->mmap_lock.
|
||||
* the task_struct, holds a refcount on mm->mm_users, and holds
|
||||
* read lock on vma->mm->mmap_lock.
|
||||
* If this function returns NULL, it does not hold any reference or
|
||||
* lock.
|
||||
*/
|
||||
if (info->task) {
|
||||
curr_task = info->task;
|
||||
curr_vma = info->vma;
|
||||
curr_mm = info->mm;
|
||||
/* In case of lock contention, drop mmap_lock to unblock
|
||||
* the writer.
|
||||
*
|
||||
@ -504,13 +508,15 @@ task_vma_seq_get_next(struct bpf_iter_seq_task_vma_info *info)
|
||||
* 4.2) VMA2 and VMA2' covers different ranges, process
|
||||
* VMA2'.
|
||||
*/
|
||||
if (mmap_lock_is_contended(curr_task->mm)) {
|
||||
if (mmap_lock_is_contended(curr_mm)) {
|
||||
info->prev_vm_start = curr_vma->vm_start;
|
||||
info->prev_vm_end = curr_vma->vm_end;
|
||||
op = task_vma_iter_find_vma;
|
||||
mmap_read_unlock(curr_task->mm);
|
||||
if (mmap_read_lock_killable(curr_task->mm))
|
||||
mmap_read_unlock(curr_mm);
|
||||
if (mmap_read_lock_killable(curr_mm)) {
|
||||
mmput(curr_mm);
|
||||
goto finish;
|
||||
}
|
||||
} else {
|
||||
op = task_vma_iter_next_vma;
|
||||
}
|
||||
@ -535,42 +541,47 @@ again:
|
||||
op = task_vma_iter_find_vma;
|
||||
}
|
||||
|
||||
if (!curr_task->mm)
|
||||
curr_mm = get_task_mm(curr_task);
|
||||
if (!curr_mm)
|
||||
goto next_task;
|
||||
|
||||
if (mmap_read_lock_killable(curr_task->mm))
|
||||
if (mmap_read_lock_killable(curr_mm)) {
|
||||
mmput(curr_mm);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case task_vma_iter_first_vma:
|
||||
curr_vma = find_vma(curr_task->mm, 0);
|
||||
curr_vma = find_vma(curr_mm, 0);
|
||||
break;
|
||||
case task_vma_iter_next_vma:
|
||||
curr_vma = find_vma(curr_task->mm, curr_vma->vm_end);
|
||||
curr_vma = find_vma(curr_mm, curr_vma->vm_end);
|
||||
break;
|
||||
case task_vma_iter_find_vma:
|
||||
/* We dropped mmap_lock so it is necessary to use find_vma
|
||||
* to find the next vma. This is similar to the mechanism
|
||||
* in show_smaps_rollup().
|
||||
*/
|
||||
curr_vma = find_vma(curr_task->mm, info->prev_vm_end - 1);
|
||||
curr_vma = find_vma(curr_mm, info->prev_vm_end - 1);
|
||||
/* case 1) and 4.2) above just use curr_vma */
|
||||
|
||||
/* check for case 2) or case 4.1) above */
|
||||
if (curr_vma &&
|
||||
curr_vma->vm_start == info->prev_vm_start &&
|
||||
curr_vma->vm_end == info->prev_vm_end)
|
||||
curr_vma = find_vma(curr_task->mm, curr_vma->vm_end);
|
||||
curr_vma = find_vma(curr_mm, curr_vma->vm_end);
|
||||
break;
|
||||
}
|
||||
if (!curr_vma) {
|
||||
/* case 3) above, or case 2) 4.1) with vma->next == NULL */
|
||||
mmap_read_unlock(curr_task->mm);
|
||||
mmap_read_unlock(curr_mm);
|
||||
mmput(curr_mm);
|
||||
goto next_task;
|
||||
}
|
||||
info->task = curr_task;
|
||||
info->vma = curr_vma;
|
||||
info->mm = curr_mm;
|
||||
return curr_vma;
|
||||
|
||||
next_task:
|
||||
@ -579,6 +590,7 @@ next_task:
|
||||
|
||||
put_task_struct(curr_task);
|
||||
info->task = NULL;
|
||||
info->mm = NULL;
|
||||
info->tid++;
|
||||
goto again;
|
||||
|
||||
@ -587,6 +599,7 @@ finish:
|
||||
put_task_struct(curr_task);
|
||||
info->task = NULL;
|
||||
info->vma = NULL;
|
||||
info->mm = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -658,7 +671,9 @@ static void task_vma_seq_stop(struct seq_file *seq, void *v)
|
||||
*/
|
||||
info->prev_vm_start = ~0UL;
|
||||
info->prev_vm_end = info->vma->vm_end;
|
||||
mmap_read_unlock(info->task->mm);
|
||||
mmap_read_unlock(info->mm);
|
||||
mmput(info->mm);
|
||||
info->mm = NULL;
|
||||
put_task_struct(info->task);
|
||||
info->task = NULL;
|
||||
}
|
||||
|
@ -488,6 +488,10 @@ again:
|
||||
/* reset fops->func and fops->trampoline for re-register */
|
||||
tr->fops->func = NULL;
|
||||
tr->fops->trampoline = 0;
|
||||
|
||||
/* reset im->image memory attr for arch_prepare_bpf_trampoline */
|
||||
set_memory_nx((long)im->image, 1);
|
||||
set_memory_rw((long)im->image, 1);
|
||||
goto again;
|
||||
}
|
||||
#endif
|
||||
|
@ -1054,6 +1054,8 @@ static void print_insn_state(struct bpf_verifier_env *env,
|
||||
*/
|
||||
static void *copy_array(void *dst, const void *src, size_t n, size_t size, gfp_t flags)
|
||||
{
|
||||
size_t alloc_bytes;
|
||||
void *orig = dst;
|
||||
size_t bytes;
|
||||
|
||||
if (ZERO_OR_NULL_PTR(src))
|
||||
@ -1062,11 +1064,11 @@ static void *copy_array(void *dst, const void *src, size_t n, size_t size, gfp_t
|
||||
if (unlikely(check_mul_overflow(n, size, &bytes)))
|
||||
return NULL;
|
||||
|
||||
if (ksize(dst) < ksize(src)) {
|
||||
kfree(dst);
|
||||
dst = kmalloc_track_caller(kmalloc_size_roundup(bytes), flags);
|
||||
if (!dst)
|
||||
return NULL;
|
||||
alloc_bytes = max(ksize(orig), kmalloc_size_roundup(bytes));
|
||||
dst = krealloc(orig, alloc_bytes, flags);
|
||||
if (!dst) {
|
||||
kfree(orig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(dst, src, bytes);
|
||||
@ -11822,10 +11824,17 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
|
||||
* register B - not null
|
||||
* for JNE A, B, ... - A is not null in the false branch;
|
||||
* for JEQ A, B, ... - A is not null in the true branch.
|
||||
*
|
||||
* Since PTR_TO_BTF_ID points to a kernel struct that does
|
||||
* not need to be null checked by the BPF program, i.e.,
|
||||
* could be null even without PTR_MAYBE_NULL marking, so
|
||||
* only propagate nullness when neither reg is that type.
|
||||
*/
|
||||
if (!is_jmp32 && BPF_SRC(insn->code) == BPF_X &&
|
||||
__is_pointer_value(false, src_reg) && __is_pointer_value(false, dst_reg) &&
|
||||
type_may_be_null(src_reg->type) != type_may_be_null(dst_reg->type)) {
|
||||
type_may_be_null(src_reg->type) != type_may_be_null(dst_reg->type) &&
|
||||
base_type(src_reg->type) != PTR_TO_BTF_ID &&
|
||||
base_type(dst_reg->type) != PTR_TO_BTF_ID) {
|
||||
eq_branch_regs = NULL;
|
||||
switch (opcode) {
|
||||
case BPF_JEQ:
|
||||
|
@ -269,11 +269,15 @@ int cfctrl_linkup_request(struct cflayer *layer,
|
||||
default:
|
||||
pr_warn("Request setup of bad link type = %d\n",
|
||||
param->linktype);
|
||||
cfpkt_destroy(pkt);
|
||||
return -EINVAL;
|
||||
}
|
||||
req = kzalloc(sizeof(*req), GFP_KERNEL);
|
||||
if (!req)
|
||||
if (!req) {
|
||||
cfpkt_destroy(pkt);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
req->client_layer = user_layer;
|
||||
req->cmd = CFCTRL_CMD_LINK_SETUP;
|
||||
req->param = *param;
|
||||
|
@ -3180,15 +3180,18 @@ static int bpf_skb_generic_push(struct sk_buff *skb, u32 off, u32 len)
|
||||
|
||||
static int bpf_skb_generic_pop(struct sk_buff *skb, u32 off, u32 len)
|
||||
{
|
||||
void *old_data;
|
||||
|
||||
/* skb_ensure_writable() is not needed here, as we're
|
||||
* already working on an uncloned skb.
|
||||
*/
|
||||
if (unlikely(!pskb_may_pull(skb, off + len)))
|
||||
return -ENOMEM;
|
||||
|
||||
skb_postpull_rcsum(skb, skb->data + off, len);
|
||||
memmove(skb->data + len, skb->data, off);
|
||||
old_data = skb->data;
|
||||
__skb_pull(skb, len);
|
||||
skb_postpull_rcsum(skb, old_data + off, len);
|
||||
memmove(skb->data, old_data, off);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2078,58 +2078,91 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
|
||||
static int ethtool_vzalloc_stats_array(int n_stats, u64 **data)
|
||||
{
|
||||
const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
|
||||
const struct ethtool_ops *ops = dev->ethtool_ops;
|
||||
struct phy_device *phydev = dev->phydev;
|
||||
struct ethtool_stats stats;
|
||||
u64 *data;
|
||||
int ret, n_stats;
|
||||
|
||||
if (!phydev && (!ops->get_ethtool_phy_stats || !ops->get_sset_count))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (phydev && !ops->get_ethtool_phy_stats &&
|
||||
phy_ops && phy_ops->get_sset_count)
|
||||
n_stats = phy_ops->get_sset_count(phydev);
|
||||
else
|
||||
n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
|
||||
if (n_stats < 0)
|
||||
return n_stats;
|
||||
if (n_stats > S32_MAX / sizeof(u64))
|
||||
return -ENOMEM;
|
||||
WARN_ON_ONCE(!n_stats);
|
||||
if (WARN_ON_ONCE(!n_stats))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
*data = vzalloc(array_size(n_stats, sizeof(u64)));
|
||||
if (!*data)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,
|
||||
struct ethtool_stats *stats,
|
||||
u64 **data)
|
||||
{
|
||||
const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
|
||||
int n_stats, ret;
|
||||
|
||||
if (!phy_ops || !phy_ops->get_sset_count || !phy_ops->get_stats)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
n_stats = phy_ops->get_sset_count(phydev);
|
||||
|
||||
ret = ethtool_vzalloc_stats_array(n_stats, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
stats->n_stats = n_stats;
|
||||
return phy_ops->get_stats(phydev, stats, *data);
|
||||
}
|
||||
|
||||
static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
|
||||
struct ethtool_stats *stats,
|
||||
u64 **data)
|
||||
{
|
||||
const struct ethtool_ops *ops = dev->ethtool_ops;
|
||||
int n_stats, ret;
|
||||
|
||||
if (!ops || !ops->get_sset_count || ops->get_ethtool_phy_stats)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
|
||||
|
||||
ret = ethtool_vzalloc_stats_array(n_stats, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
stats->n_stats = n_stats;
|
||||
ops->get_ethtool_phy_stats(dev, stats, *data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
|
||||
{
|
||||
struct phy_device *phydev = dev->phydev;
|
||||
struct ethtool_stats stats;
|
||||
u64 *data = NULL;
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
if (copy_from_user(&stats, useraddr, sizeof(stats)))
|
||||
return -EFAULT;
|
||||
|
||||
stats.n_stats = n_stats;
|
||||
if (phydev)
|
||||
ret = ethtool_get_phy_stats_phydev(phydev, &stats, &data);
|
||||
|
||||
if (n_stats) {
|
||||
data = vzalloc(array_size(n_stats, sizeof(u64)));
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
if (ret == -EOPNOTSUPP)
|
||||
ret = ethtool_get_phy_stats_ethtool(dev, &stats, &data);
|
||||
|
||||
if (phydev && !ops->get_ethtool_phy_stats &&
|
||||
phy_ops && phy_ops->get_stats) {
|
||||
ret = phy_ops->get_stats(phydev, &stats, data);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
} else {
|
||||
ops->get_ethtool_phy_stats(dev, &stats, data);
|
||||
}
|
||||
} else {
|
||||
data = NULL;
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (copy_to_user(useraddr, &stats, sizeof(stats))) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = -EFAULT;
|
||||
if (copy_to_user(useraddr, &stats, sizeof(stats)))
|
||||
goto out;
|
||||
useraddr += sizeof(stats);
|
||||
if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
|
||||
goto out;
|
||||
ret = 0;
|
||||
if (copy_to_user(useraddr, data, array_size(stats.n_stats, sizeof(u64))))
|
||||
ret = -EFAULT;
|
||||
|
||||
out:
|
||||
vfree(data);
|
||||
|
@ -1665,6 +1665,7 @@ int inet_ctl_sock_create(struct sock **sk, unsigned short family,
|
||||
if (rc == 0) {
|
||||
*sk = sock->sk;
|
||||
(*sk)->sk_allocation = GFP_ATOMIC;
|
||||
(*sk)->sk_use_task_frag = false;
|
||||
/*
|
||||
* Unhash it so that IP input processing does not even see it,
|
||||
* we do not wish this socket to see incoming packets.
|
||||
|
@ -173,22 +173,40 @@ static bool inet_bind_conflict(const struct sock *sk, struct sock *sk2,
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool __inet_bhash2_conflict(const struct sock *sk, struct sock *sk2,
|
||||
kuid_t sk_uid, bool relax,
|
||||
bool reuseport_cb_ok, bool reuseport_ok)
|
||||
{
|
||||
if (sk->sk_family == AF_INET && ipv6_only_sock(sk2))
|
||||
return false;
|
||||
|
||||
return inet_bind_conflict(sk, sk2, sk_uid, relax,
|
||||
reuseport_cb_ok, reuseport_ok);
|
||||
}
|
||||
|
||||
static bool inet_bhash2_conflict(const struct sock *sk,
|
||||
const struct inet_bind2_bucket *tb2,
|
||||
kuid_t sk_uid,
|
||||
bool relax, bool reuseport_cb_ok,
|
||||
bool reuseport_ok)
|
||||
{
|
||||
struct inet_timewait_sock *tw2;
|
||||
struct sock *sk2;
|
||||
|
||||
sk_for_each_bound_bhash2(sk2, &tb2->owners) {
|
||||
if (sk->sk_family == AF_INET && ipv6_only_sock(sk2))
|
||||
continue;
|
||||
|
||||
if (inet_bind_conflict(sk, sk2, sk_uid, relax,
|
||||
reuseport_cb_ok, reuseport_ok))
|
||||
if (__inet_bhash2_conflict(sk, sk2, sk_uid, relax,
|
||||
reuseport_cb_ok, reuseport_ok))
|
||||
return true;
|
||||
}
|
||||
|
||||
twsk_for_each_bound_bhash2(tw2, &tb2->deathrow) {
|
||||
sk2 = (struct sock *)tw2;
|
||||
|
||||
if (__inet_bhash2_conflict(sk, sk2, sk_uid, relax,
|
||||
reuseport_cb_ok, reuseport_ok))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1182,12 +1200,26 @@ void inet_csk_prepare_forced_close(struct sock *sk)
|
||||
}
|
||||
EXPORT_SYMBOL(inet_csk_prepare_forced_close);
|
||||
|
||||
static int inet_ulp_can_listen(const struct sock *sk)
|
||||
{
|
||||
const struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
|
||||
if (icsk->icsk_ulp_ops && !icsk->icsk_ulp_ops->clone)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int inet_csk_listen_start(struct sock *sk)
|
||||
{
|
||||
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
int err;
|
||||
|
||||
err = inet_ulp_can_listen(sk);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
|
||||
reqsk_queue_alloc(&icsk->icsk_accept_queue);
|
||||
|
||||
sk->sk_ack_backlog = 0;
|
||||
|
@ -116,6 +116,7 @@ static void inet_bind2_bucket_init(struct inet_bind2_bucket *tb,
|
||||
#endif
|
||||
tb->rcv_saddr = sk->sk_rcv_saddr;
|
||||
INIT_HLIST_HEAD(&tb->owners);
|
||||
INIT_HLIST_HEAD(&tb->deathrow);
|
||||
hlist_add_head(&tb->node, &head->chain);
|
||||
}
|
||||
|
||||
@ -137,7 +138,7 @@ struct inet_bind2_bucket *inet_bind2_bucket_create(struct kmem_cache *cachep,
|
||||
/* Caller must hold hashbucket lock for this tb with local BH disabled */
|
||||
void inet_bind2_bucket_destroy(struct kmem_cache *cachep, struct inet_bind2_bucket *tb)
|
||||
{
|
||||
if (hlist_empty(&tb->owners)) {
|
||||
if (hlist_empty(&tb->owners) && hlist_empty(&tb->deathrow)) {
|
||||
__hlist_del(&tb->node);
|
||||
kmem_cache_free(cachep, tb);
|
||||
}
|
||||
@ -1103,15 +1104,16 @@ ok:
|
||||
/* Head lock still held and bh's disabled */
|
||||
inet_bind_hash(sk, tb, tb2, port);
|
||||
|
||||
spin_unlock(&head2->lock);
|
||||
|
||||
if (sk_unhashed(sk)) {
|
||||
inet_sk(sk)->inet_sport = htons(port);
|
||||
inet_ehash_nolisten(sk, (struct sock *)tw, NULL);
|
||||
}
|
||||
if (tw)
|
||||
inet_twsk_bind_unhash(tw, hinfo);
|
||||
|
||||
spin_unlock(&head2->lock);
|
||||
spin_unlock(&head->lock);
|
||||
|
||||
if (tw)
|
||||
inet_twsk_deschedule_put(tw);
|
||||
local_bh_enable();
|
||||
|
@ -29,6 +29,7 @@
|
||||
void inet_twsk_bind_unhash(struct inet_timewait_sock *tw,
|
||||
struct inet_hashinfo *hashinfo)
|
||||
{
|
||||
struct inet_bind2_bucket *tb2 = tw->tw_tb2;
|
||||
struct inet_bind_bucket *tb = tw->tw_tb;
|
||||
|
||||
if (!tb)
|
||||
@ -37,6 +38,11 @@ void inet_twsk_bind_unhash(struct inet_timewait_sock *tw,
|
||||
__hlist_del(&tw->tw_bind_node);
|
||||
tw->tw_tb = NULL;
|
||||
inet_bind_bucket_destroy(hashinfo->bind_bucket_cachep, tb);
|
||||
|
||||
__hlist_del(&tw->tw_bind2_node);
|
||||
tw->tw_tb2 = NULL;
|
||||
inet_bind2_bucket_destroy(hashinfo->bind2_bucket_cachep, tb2);
|
||||
|
||||
__sock_put((struct sock *)tw);
|
||||
}
|
||||
|
||||
@ -45,7 +51,7 @@ static void inet_twsk_kill(struct inet_timewait_sock *tw)
|
||||
{
|
||||
struct inet_hashinfo *hashinfo = tw->tw_dr->hashinfo;
|
||||
spinlock_t *lock = inet_ehash_lockp(hashinfo, tw->tw_hash);
|
||||
struct inet_bind_hashbucket *bhead;
|
||||
struct inet_bind_hashbucket *bhead, *bhead2;
|
||||
|
||||
spin_lock(lock);
|
||||
sk_nulls_del_node_init_rcu((struct sock *)tw);
|
||||
@ -54,9 +60,13 @@ static void inet_twsk_kill(struct inet_timewait_sock *tw)
|
||||
/* Disassociate with bind bucket. */
|
||||
bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), tw->tw_num,
|
||||
hashinfo->bhash_size)];
|
||||
bhead2 = inet_bhashfn_portaddr(hashinfo, (struct sock *)tw,
|
||||
twsk_net(tw), tw->tw_num);
|
||||
|
||||
spin_lock(&bhead->lock);
|
||||
spin_lock(&bhead2->lock);
|
||||
inet_twsk_bind_unhash(tw, hashinfo);
|
||||
spin_unlock(&bhead2->lock);
|
||||
spin_unlock(&bhead->lock);
|
||||
|
||||
refcount_dec(&tw->tw_dr->tw_refcount);
|
||||
@ -93,6 +103,12 @@ static void inet_twsk_add_bind_node(struct inet_timewait_sock *tw,
|
||||
hlist_add_head(&tw->tw_bind_node, list);
|
||||
}
|
||||
|
||||
static void inet_twsk_add_bind2_node(struct inet_timewait_sock *tw,
|
||||
struct hlist_head *list)
|
||||
{
|
||||
hlist_add_head(&tw->tw_bind2_node, list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter the time wait state. This is called with locally disabled BH.
|
||||
* Essentially we whip up a timewait bucket, copy the relevant info into it
|
||||
@ -105,17 +121,28 @@ void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
|
||||
const struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
struct inet_ehash_bucket *ehead = inet_ehash_bucket(hashinfo, sk->sk_hash);
|
||||
spinlock_t *lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
|
||||
struct inet_bind_hashbucket *bhead;
|
||||
struct inet_bind_hashbucket *bhead, *bhead2;
|
||||
|
||||
/* Step 1: Put TW into bind hash. Original socket stays there too.
|
||||
Note, that any socket with inet->num != 0 MUST be bound in
|
||||
binding cache, even if it is closed.
|
||||
*/
|
||||
bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), inet->inet_num,
|
||||
hashinfo->bhash_size)];
|
||||
bhead2 = inet_bhashfn_portaddr(hashinfo, sk, twsk_net(tw), inet->inet_num);
|
||||
|
||||
spin_lock(&bhead->lock);
|
||||
spin_lock(&bhead2->lock);
|
||||
|
||||
tw->tw_tb = icsk->icsk_bind_hash;
|
||||
WARN_ON(!icsk->icsk_bind_hash);
|
||||
inet_twsk_add_bind_node(tw, &tw->tw_tb->owners);
|
||||
|
||||
tw->tw_tb2 = icsk->icsk_bind2_hash;
|
||||
WARN_ON(!icsk->icsk_bind2_hash);
|
||||
inet_twsk_add_bind2_node(tw, &tw->tw_tb2->deathrow);
|
||||
|
||||
spin_unlock(&bhead2->lock);
|
||||
spin_unlock(&bhead->lock);
|
||||
|
||||
spin_lock(lock);
|
||||
|
@ -139,6 +139,10 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
|
||||
if (sk->sk_socket)
|
||||
clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
|
||||
|
||||
err = -EINVAL;
|
||||
if (!ulp_ops->clone && sk->sk_state == TCP_LISTEN)
|
||||
goto out_err;
|
||||
|
||||
err = ulp_ops->init(sk);
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
@ -1662,6 +1662,8 @@ static void mptcp_set_nospace(struct sock *sk)
|
||||
set_bit(MPTCP_NOSPACE, &mptcp_sk(sk)->flags);
|
||||
}
|
||||
|
||||
static int mptcp_disconnect(struct sock *sk, int flags);
|
||||
|
||||
static int mptcp_sendmsg_fastopen(struct sock *sk, struct sock *ssk, struct msghdr *msg,
|
||||
size_t len, int *copied_syn)
|
||||
{
|
||||
@ -1672,9 +1674,9 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct sock *ssk, struct msgh
|
||||
lock_sock(ssk);
|
||||
msg->msg_flags |= MSG_DONTWAIT;
|
||||
msk->connect_flags = O_NONBLOCK;
|
||||
msk->is_sendmsg = 1;
|
||||
msk->fastopening = 1;
|
||||
ret = tcp_sendmsg_fastopen(ssk, msg, copied_syn, len, NULL);
|
||||
msk->is_sendmsg = 0;
|
||||
msk->fastopening = 0;
|
||||
msg->msg_flags = saved_flags;
|
||||
release_sock(ssk);
|
||||
|
||||
@ -1688,6 +1690,8 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct sock *ssk, struct msgh
|
||||
*/
|
||||
if (ret && ret != -EINPROGRESS && ret != -ERESTARTSYS && ret != -EINTR)
|
||||
*copied_syn = 0;
|
||||
} else if (ret && ret != -EINPROGRESS) {
|
||||
mptcp_disconnect(sk, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -2353,7 +2357,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
|
||||
/* otherwise tcp will dispose of the ssk and subflow ctx */
|
||||
if (ssk->sk_state == TCP_LISTEN) {
|
||||
tcp_set_state(ssk, TCP_CLOSE);
|
||||
mptcp_subflow_queue_clean(ssk);
|
||||
mptcp_subflow_queue_clean(sk, ssk);
|
||||
inet_csk_listen_stop(ssk);
|
||||
mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CLOSED);
|
||||
}
|
||||
@ -2989,6 +2993,14 @@ static int mptcp_disconnect(struct sock *sk, int flags)
|
||||
{
|
||||
struct mptcp_sock *msk = mptcp_sk(sk);
|
||||
|
||||
/* We are on the fastopen error path. We can't call straight into the
|
||||
* subflows cleanup code due to lock nesting (we are already under
|
||||
* msk->firstsocket lock). Do nothing and leave the cleanup to the
|
||||
* caller.
|
||||
*/
|
||||
if (msk->fastopening)
|
||||
return 0;
|
||||
|
||||
inet_sk_state_store(sk, TCP_CLOSE);
|
||||
|
||||
mptcp_stop_timer(sk);
|
||||
@ -3532,7 +3544,7 @@ static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
/* if reaching here via the fastopen/sendmsg path, the caller already
|
||||
* acquired the subflow socket lock, too.
|
||||
*/
|
||||
if (msk->is_sendmsg)
|
||||
if (msk->fastopening)
|
||||
err = __inet_stream_connect(ssock, uaddr, addr_len, msk->connect_flags, 1);
|
||||
else
|
||||
err = inet_stream_connect(ssock, uaddr, addr_len, msk->connect_flags);
|
||||
|
@ -295,7 +295,7 @@ struct mptcp_sock {
|
||||
u8 recvmsg_inq:1,
|
||||
cork:1,
|
||||
nodelay:1,
|
||||
is_sendmsg:1;
|
||||
fastopening:1;
|
||||
int connect_flags;
|
||||
struct work_struct work;
|
||||
struct sk_buff *ooo_last_skb;
|
||||
@ -628,7 +628,7 @@ void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
|
||||
struct mptcp_subflow_context *subflow);
|
||||
void __mptcp_subflow_send_ack(struct sock *ssk);
|
||||
void mptcp_subflow_reset(struct sock *ssk);
|
||||
void mptcp_subflow_queue_clean(struct sock *ssk);
|
||||
void mptcp_subflow_queue_clean(struct sock *sk, struct sock *ssk);
|
||||
void mptcp_sock_graft(struct sock *sk, struct socket *parent);
|
||||
struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);
|
||||
bool __mptcp_close(struct sock *sk, long timeout);
|
||||
|
@ -1791,7 +1791,7 @@ static void subflow_state_change(struct sock *sk)
|
||||
}
|
||||
}
|
||||
|
||||
void mptcp_subflow_queue_clean(struct sock *listener_ssk)
|
||||
void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_ssk)
|
||||
{
|
||||
struct request_sock_queue *queue = &inet_csk(listener_ssk)->icsk_accept_queue;
|
||||
struct mptcp_sock *msk, *next, *head = NULL;
|
||||
@ -1840,8 +1840,23 @@ void mptcp_subflow_queue_clean(struct sock *listener_ssk)
|
||||
|
||||
do_cancel_work = __mptcp_close(sk, 0);
|
||||
release_sock(sk);
|
||||
if (do_cancel_work)
|
||||
if (do_cancel_work) {
|
||||
/* lockdep will report a false positive ABBA deadlock
|
||||
* between cancel_work_sync and the listener socket.
|
||||
* The involved locks belong to different sockets WRT
|
||||
* the existing AB chain.
|
||||
* Using a per socket key is problematic as key
|
||||
* deregistration requires process context and must be
|
||||
* performed at socket disposal time, in atomic
|
||||
* context.
|
||||
* Just tell lockdep to consider the listener socket
|
||||
* released here.
|
||||
*/
|
||||
mutex_release(&listener_sk->sk_lock.dep_map, _RET_IP_);
|
||||
mptcp_cancel_work(sk);
|
||||
mutex_acquire(&listener_sk->sk_lock.dep_map,
|
||||
SINGLE_DEPTH_NESTING, 0, _RET_IP_);
|
||||
}
|
||||
sock_put(sk);
|
||||
}
|
||||
|
||||
|
@ -1698,9 +1698,10 @@ call_ad(struct net *net, struct sock *ctnl, struct sk_buff *skb,
|
||||
ret = set->variant->uadt(set, tb, adt, &lineno, flags, retried);
|
||||
ip_set_unlock(set);
|
||||
retried = true;
|
||||
} while (ret == -EAGAIN &&
|
||||
set->variant->resize &&
|
||||
(ret = set->variant->resize(set, retried)) == 0);
|
||||
} while (ret == -ERANGE ||
|
||||
(ret == -EAGAIN &&
|
||||
set->variant->resize &&
|
||||
(ret = set->variant->resize(set, retried)) == 0));
|
||||
|
||||
if (!ret || (ret == -IPSET_ERR_EXIST && eexist))
|
||||
return 0;
|
||||
|
@ -100,11 +100,11 @@ static int
|
||||
hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
|
||||
{
|
||||
const struct hash_ip4 *h = set->data;
|
||||
struct hash_ip4 *h = set->data;
|
||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||
struct hash_ip4_elem e = { 0 };
|
||||
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
|
||||
u32 ip = 0, ip_to = 0, hosts;
|
||||
u32 ip = 0, ip_to = 0, hosts, i = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (tb[IPSET_ATTR_LINENO])
|
||||
@ -149,14 +149,14 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
|
||||
hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1);
|
||||
|
||||
/* 64bit division is not allowed on 32bit */
|
||||
if (((u64)ip_to - ip + 1) >> (32 - h->netmask) > IPSET_MAX_RANGE)
|
||||
return -ERANGE;
|
||||
|
||||
if (retried)
|
||||
ip = ntohl(h->next.ip);
|
||||
for (; ip <= ip_to;) {
|
||||
for (; ip <= ip_to; i++) {
|
||||
e.ip = htonl(ip);
|
||||
if (i > IPSET_MAX_RANGE) {
|
||||
hash_ip4_data_next(&h->next, &e);
|
||||
return -ERANGE;
|
||||
}
|
||||
ret = adtfn(set, &e, &ext, &ext, flags);
|
||||
if (ret && !ip_set_eexist(ret, flags))
|
||||
return ret;
|
||||
|
@ -97,11 +97,11 @@ static int
|
||||
hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
|
||||
{
|
||||
const struct hash_ipmark4 *h = set->data;
|
||||
struct hash_ipmark4 *h = set->data;
|
||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||
struct hash_ipmark4_elem e = { };
|
||||
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
|
||||
u32 ip, ip_to = 0;
|
||||
u32 ip, ip_to = 0, i = 0;
|
||||
int ret;
|
||||
|
||||
if (tb[IPSET_ATTR_LINENO])
|
||||
@ -148,13 +148,14 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
ip_set_mask_from_to(ip, ip_to, cidr);
|
||||
}
|
||||
|
||||
if (((u64)ip_to - ip + 1) > IPSET_MAX_RANGE)
|
||||
return -ERANGE;
|
||||
|
||||
if (retried)
|
||||
ip = ntohl(h->next.ip);
|
||||
for (; ip <= ip_to; ip++) {
|
||||
for (; ip <= ip_to; ip++, i++) {
|
||||
e.ip = htonl(ip);
|
||||
if (i > IPSET_MAX_RANGE) {
|
||||
hash_ipmark4_data_next(&h->next, &e);
|
||||
return -ERANGE;
|
||||
}
|
||||
ret = adtfn(set, &e, &ext, &ext, flags);
|
||||
|
||||
if (ret && !ip_set_eexist(ret, flags))
|
||||
|
@ -112,11 +112,11 @@ static int
|
||||
hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
|
||||
{
|
||||
const struct hash_ipport4 *h = set->data;
|
||||
struct hash_ipport4 *h = set->data;
|
||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||
struct hash_ipport4_elem e = { .ip = 0 };
|
||||
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
|
||||
u32 ip, ip_to = 0, p = 0, port, port_to;
|
||||
u32 ip, ip_to = 0, p = 0, port, port_to, i = 0;
|
||||
bool with_ports = false;
|
||||
int ret;
|
||||
|
||||
@ -184,17 +184,18 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
swap(port, port_to);
|
||||
}
|
||||
|
||||
if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
|
||||
return -ERANGE;
|
||||
|
||||
if (retried)
|
||||
ip = ntohl(h->next.ip);
|
||||
for (; ip <= ip_to; ip++) {
|
||||
p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
|
||||
: port;
|
||||
for (; p <= port_to; p++) {
|
||||
for (; p <= port_to; p++, i++) {
|
||||
e.ip = htonl(ip);
|
||||
e.port = htons(p);
|
||||
if (i > IPSET_MAX_RANGE) {
|
||||
hash_ipport4_data_next(&h->next, &e);
|
||||
return -ERANGE;
|
||||
}
|
||||
ret = adtfn(set, &e, &ext, &ext, flags);
|
||||
|
||||
if (ret && !ip_set_eexist(ret, flags))
|
||||
|
@ -108,11 +108,11 @@ static int
|
||||
hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
|
||||
{
|
||||
const struct hash_ipportip4 *h = set->data;
|
||||
struct hash_ipportip4 *h = set->data;
|
||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||
struct hash_ipportip4_elem e = { .ip = 0 };
|
||||
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
|
||||
u32 ip, ip_to = 0, p = 0, port, port_to;
|
||||
u32 ip, ip_to = 0, p = 0, port, port_to, i = 0;
|
||||
bool with_ports = false;
|
||||
int ret;
|
||||
|
||||
@ -180,17 +180,18 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
swap(port, port_to);
|
||||
}
|
||||
|
||||
if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
|
||||
return -ERANGE;
|
||||
|
||||
if (retried)
|
||||
ip = ntohl(h->next.ip);
|
||||
for (; ip <= ip_to; ip++) {
|
||||
p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
|
||||
: port;
|
||||
for (; p <= port_to; p++) {
|
||||
for (; p <= port_to; p++, i++) {
|
||||
e.ip = htonl(ip);
|
||||
e.port = htons(p);
|
||||
if (i > IPSET_MAX_RANGE) {
|
||||
hash_ipportip4_data_next(&h->next, &e);
|
||||
return -ERANGE;
|
||||
}
|
||||
ret = adtfn(set, &e, &ext, &ext, flags);
|
||||
|
||||
if (ret && !ip_set_eexist(ret, flags))
|
||||
|
@ -160,12 +160,12 @@ static int
|
||||
hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
|
||||
{
|
||||
const struct hash_ipportnet4 *h = set->data;
|
||||
struct hash_ipportnet4 *h = set->data;
|
||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||
struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 };
|
||||
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
|
||||
u32 ip = 0, ip_to = 0, p = 0, port, port_to;
|
||||
u32 ip2_from = 0, ip2_to = 0, ip2;
|
||||
u32 ip2_from = 0, ip2_to = 0, ip2, i = 0;
|
||||
bool with_ports = false;
|
||||
u8 cidr;
|
||||
int ret;
|
||||
@ -253,9 +253,6 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
swap(port, port_to);
|
||||
}
|
||||
|
||||
if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
|
||||
return -ERANGE;
|
||||
|
||||
ip2_to = ip2_from;
|
||||
if (tb[IPSET_ATTR_IP2_TO]) {
|
||||
ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to);
|
||||
@ -282,9 +279,15 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
|
||||
for (; p <= port_to; p++) {
|
||||
e.port = htons(p);
|
||||
do {
|
||||
i++;
|
||||
e.ip2 = htonl(ip2);
|
||||
ip2 = ip_set_range_to_cidr(ip2, ip2_to, &cidr);
|
||||
e.cidr = cidr - 1;
|
||||
if (i > IPSET_MAX_RANGE) {
|
||||
hash_ipportnet4_data_next(&h->next,
|
||||
&e);
|
||||
return -ERANGE;
|
||||
}
|
||||
ret = adtfn(set, &e, &ext, &ext, flags);
|
||||
|
||||
if (ret && !ip_set_eexist(ret, flags))
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user