mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-15 02:05:33 +00:00
Merge branch 'main' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
This commit is contained in:
commit
25dcaaf9b3
2
.mailmap
2
.mailmap
@ -535,6 +535,8 @@ Oleksij Rempel <linux@rempel-privat.de> <external.Oleksij.Rempel@de.bosch.com>
|
||||
Oleksij Rempel <linux@rempel-privat.de> <fixed-term.Oleksij.Rempel@de.bosch.com>
|
||||
Oleksij Rempel <o.rempel@pengutronix.de>
|
||||
Oleksij Rempel <o.rempel@pengutronix.de> <ore@pengutronix.de>
|
||||
Oliver Hartkopp <socketcan@hartkopp.net> <oliver.hartkopp@volkswagen.de>
|
||||
Oliver Hartkopp <socketcan@hartkopp.net> <oliver@hartkopp.net>
|
||||
Oliver Upton <oliver.upton@linux.dev> <oupton@google.com>
|
||||
Ondřej Jirman <megi@xff.cz> <megous@megous.com>
|
||||
Oza Pawandeep <quic_poza@quicinc.com> <poza@codeaurora.org>
|
||||
|
@ -104,7 +104,7 @@ quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4)
|
||||
YNL_INDEX:=$(srctree)/Documentation/networking/netlink_spec/index.rst
|
||||
YNL_RST_DIR:=$(srctree)/Documentation/networking/netlink_spec
|
||||
YNL_YAML_DIR:=$(srctree)/Documentation/netlink/specs
|
||||
YNL_TOOL:=$(srctree)/tools/net/ynl/ynl-gen-rst.py
|
||||
YNL_TOOL:=$(srctree)/tools/net/ynl/pyynl/ynl_gen_rst.py
|
||||
|
||||
YNL_RST_FILES_TMP := $(patsubst %.yaml,%.rst,$(wildcard $(YNL_YAML_DIR)/*.yaml))
|
||||
YNL_RST_FILES := $(patsubst $(YNL_YAML_DIR)%,$(YNL_RST_DIR)%, $(YNL_RST_FILES_TMP))
|
||||
|
@ -227,11 +227,119 @@ Intended use
|
||||
|
||||
Drivers that opt to use this API first need to identify which of the above 3
|
||||
quirk combinations (for a total of 8) match what the hardware documentation
|
||||
describes. Then they should wrap the packing() function, creating a new
|
||||
xxx_packing() that calls it using the proper QUIRK_* one-hot bits set.
|
||||
describes.
|
||||
|
||||
There are 3 supported usage patterns, detailed below.
|
||||
|
||||
packing()
|
||||
^^^^^^^^^
|
||||
|
||||
This API function is deprecated.
|
||||
|
||||
The packing() function returns an int-encoded error code, which protects the
|
||||
programmer against incorrect API use. The errors are not expected to occur
|
||||
during runtime, therefore it is reasonable for xxx_packing() to return void
|
||||
and simply swallow those errors. Optionally it can dump stack or print the
|
||||
error description.
|
||||
during runtime, therefore it is reasonable to wrap packing() into a custom
|
||||
function which returns void and swallows those errors. Optionally it can
|
||||
dump stack or print the error description.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void my_packing(void *buf, u64 *val, int startbit, int endbit,
|
||||
size_t len, enum packing_op op)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Adjust quirks accordingly */
|
||||
err = packing(buf, val, startbit, endbit, len, op, QUIRK_LSW32_IS_FIRST);
|
||||
if (likely(!err))
|
||||
return;
|
||||
|
||||
if (err == -EINVAL) {
|
||||
pr_err("Start bit (%d) expected to be larger than end (%d)\n",
|
||||
startbit, endbit);
|
||||
} else if (err == -ERANGE) {
|
||||
if ((startbit - endbit + 1) > 64)
|
||||
pr_err("Field %d-%d too large for 64 bits!\n",
|
||||
startbit, endbit);
|
||||
else
|
||||
pr_err("Cannot store %llx inside bits %d-%d (would truncate)\n",
|
||||
*val, startbit, endbit);
|
||||
}
|
||||
dump_stack();
|
||||
}
|
||||
|
||||
pack() and unpack()
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
These are const-correct variants of packing(), and eliminate the last "enum
|
||||
packing_op op" argument.
|
||||
|
||||
Calling pack(...) is equivalent, and preferred, to calling packing(..., PACK).
|
||||
|
||||
Calling unpack(...) is equivalent, and preferred, to calling packing(..., UNPACK).
|
||||
|
||||
pack_fields() and unpack_fields()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The library exposes optimized functions for the scenario where there are many
|
||||
fields represented in a buffer, and it encourages consumer drivers to avoid
|
||||
repetitive calls to pack() and unpack() for each field, but instead use
|
||||
pack_fields() and unpack_fields(), which reduces the code footprint.
|
||||
|
||||
These APIs use field definitions in arrays of ``struct packed_field_u8`` or
|
||||
``struct packed_field_u16``, allowing consumer drivers to minimize the size
|
||||
of these arrays according to their custom requirements.
|
||||
|
||||
The pack_fields() and unpack_fields() API functions are actually macros which
|
||||
automatically select the appropriate function at compile time, based on the
|
||||
type of the fields array passed in.
|
||||
|
||||
An additional benefit over pack() and unpack() is that sanity checks on the
|
||||
field definitions are handled at compile time with ``BUILD_BUG_ON`` rather
|
||||
than only when the offending code is executed. These functions return void and
|
||||
wrapping them to handle unexpected errors is not necessary.
|
||||
|
||||
It is recommended, but not required, that you wrap your packed buffer into a
|
||||
structured type with a fixed size. This generally makes it easier for the
|
||||
compiler to enforce that the correct size buffer is used.
|
||||
|
||||
Here is an example of how to use the fields APIs:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* Ordering inside the unpacked structure is flexible and can be different
|
||||
* from the packed buffer. Here, it is optimized to reduce padding.
|
||||
*/
|
||||
struct data {
|
||||
u64 field3;
|
||||
u32 field4;
|
||||
u16 field1;
|
||||
u8 field2;
|
||||
};
|
||||
|
||||
#define SIZE 13
|
||||
|
||||
typdef struct __packed { u8 buf[SIZE]; } packed_buf_t;
|
||||
|
||||
static const struct packed_field_u8 fields[] = {
|
||||
PACKED_FIELD(100, 90, struct data, field1),
|
||||
PACKED_FIELD(90, 87, struct data, field2),
|
||||
PACKED_FIELD(86, 30, struct data, field3),
|
||||
PACKED_FIELD(29, 0, struct data, field4),
|
||||
};
|
||||
|
||||
void unpack_your_data(const packed_buf_t *buf, struct data *unpacked)
|
||||
{
|
||||
BUILD_BUG_ON(sizeof(*buf) != SIZE;
|
||||
|
||||
unpack_fields(buf, sizeof(*buf), unpacked, fields,
|
||||
QUIRK_LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
void pack_your_data(const struct data *unpacked, packed_buf_t *buf)
|
||||
{
|
||||
BUILD_BUG_ON(sizeof(*buf) != SIZE;
|
||||
|
||||
pack_fields(buf, sizeof(*buf), unpacked, fields,
|
||||
QUIRK_LITTLE_ENDIAN);
|
||||
}
|
||||
|
@ -166,11 +166,11 @@ unevaluatedProperties: false
|
||||
examples:
|
||||
- |
|
||||
ethmac: ethernet@c9410000 {
|
||||
compatible = "amlogic,meson-gxbb-dwmac", "snps,dwmac";
|
||||
reg = <0xc9410000 0x10000>, <0xc8834540 0x8>;
|
||||
interrupts = <8>;
|
||||
interrupt-names = "macirq";
|
||||
clocks = <&clk_eth>, <&clk_fclk_div2>, <&clk_mpll2>, <&clk_fclk_div2>;
|
||||
clock-names = "stmmaceth", "clkin0", "clkin1", "timing-adjustment";
|
||||
phy-mode = "rgmii";
|
||||
compatible = "amlogic,meson-gxbb-dwmac", "snps,dwmac";
|
||||
reg = <0xc9410000 0x10000>, <0xc8834540 0x8>;
|
||||
interrupts = <8>;
|
||||
interrupt-names = "macirq";
|
||||
clocks = <&clk_eth>, <&clk_fclk_div2>, <&clk_mpll2>, <&clk_fclk_div2>;
|
||||
clock-names = "stmmaceth", "clkin0", "clkin1", "timing-adjustment";
|
||||
phy-mode = "rgmii";
|
||||
};
|
||||
|
@ -63,8 +63,8 @@ examples:
|
||||
#size-cells = <0>;
|
||||
|
||||
ethernet@1 {
|
||||
compatible = "usbb95,772b";
|
||||
reg = <1>;
|
||||
compatible = "usbb95,772b";
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -85,16 +85,16 @@ examples:
|
||||
#size-cells = <1>;
|
||||
|
||||
mdio0: mdio@e14 {
|
||||
compatible = "brcm,genet-mdio-v4";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0xe14 0x8>;
|
||||
compatible = "brcm,genet-mdio-v4";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0xe14 0x8>;
|
||||
|
||||
phy1: ethernet-phy@1 {
|
||||
phy1: ethernet-phy@1 {
|
||||
max-speed = <1000>;
|
||||
reg = <1>;
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -110,10 +110,10 @@ examples:
|
||||
interrupts = <0x0 0x16 0x0>, <0x0 0x17 0x0>;
|
||||
|
||||
mdio1: mdio@e14 {
|
||||
compatible = "brcm,genet-mdio-v4";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0xe14 0x8>;
|
||||
compatible = "brcm,genet-mdio-v4";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0xe14 0x8>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -129,15 +129,15 @@ examples:
|
||||
interrupts = <0x0 0x18 0x0>, <0x0 0x19 0x0>;
|
||||
|
||||
mdio2: mdio@e14 {
|
||||
compatible = "brcm,genet-mdio-v4";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0xe14 0x8>;
|
||||
compatible = "brcm,genet-mdio-v4";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0xe14 0x8>;
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
phy0: ethernet-phy@0 {
|
||||
max-speed = <1000>;
|
||||
reg = <0>;
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -38,43 +38,43 @@ unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mdio_mux_iproc: mdio-mux@66020000 {
|
||||
mdio-mux@66020000 {
|
||||
compatible = "brcm,mdio-mux-iproc";
|
||||
reg = <0x66020000 0x250>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mdio@0 {
|
||||
reg = <0x0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pci_phy0: pci-phy@0 {
|
||||
compatible = "brcm,ns2-pcie-phy";
|
||||
reg = <0x0>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
pci-phy@0 {
|
||||
compatible = "brcm,ns2-pcie-phy";
|
||||
reg = <0x0>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
mdio@7 {
|
||||
reg = <0x7>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x7>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pci_phy1: pci-phy@0 {
|
||||
compatible = "brcm,ns2-pcie-phy";
|
||||
reg = <0x0>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
pci-phy@0 {
|
||||
compatible = "brcm,ns2-pcie-phy";
|
||||
reg = <0x0>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
mdio@10 {
|
||||
reg = <0x10>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x10>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
gphy0: eth-phy@10 {
|
||||
reg = <0x10>;
|
||||
};
|
||||
eth-phy@10 {
|
||||
reg = <0x10>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -0,0 +1,58 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/can/atmel,at91sam9263-can.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip AT91 CAN Controller
|
||||
|
||||
maintainers:
|
||||
- Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
|
||||
allOf:
|
||||
- $ref: can-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- atmel,at91sam9263-can
|
||||
- atmel,at91sam9x5-can
|
||||
- items:
|
||||
- enum:
|
||||
- microchip,sam9x60-can
|
||||
- const: atmel,at91sam9x5-can
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: can_clk
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/clock/at91.h>
|
||||
can@f000c000 {
|
||||
compatible = "atmel,at91sam9263-can";
|
||||
reg = <0xf000c000 0x300>;
|
||||
interrupts = <30 IRQ_TYPE_LEVEL_HIGH 3>;
|
||||
clocks = <&pmc PMC_TYPE_PERIPHERAL 12>;
|
||||
clock-names = "can_clk";
|
||||
};
|
@ -1,15 +0,0 @@
|
||||
* AT91 CAN *
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "atmel,at91sam9263-can", "atmel,at91sam9x5-can" or
|
||||
"microchip,sam9x60-can"
|
||||
- reg: Should contain CAN controller registers location and length
|
||||
- interrupts: Should contain IRQ line for the CAN controller
|
||||
|
||||
Example:
|
||||
|
||||
can0: can@f000c000 {
|
||||
compatible = "atmel,at91sam9x5-can";
|
||||
reg = <0xf000c000 0x300>;
|
||||
interrupts = <40 4 5>
|
||||
};
|
@ -99,11 +99,11 @@ examples:
|
||||
#include <dt-bindings/reset/altr,rst-mgr.h>
|
||||
|
||||
can@ffc00000 {
|
||||
compatible = "bosch,d_can";
|
||||
reg = <0xffc00000 0x1000>;
|
||||
interrupts = <0 131 4>, <0 132 4>, <0 133 4>, <0 134 4>;
|
||||
clocks = <&can0_clk>;
|
||||
resets = <&rst CAN0_RESET>;
|
||||
compatible = "bosch,d_can";
|
||||
reg = <0xffc00000 0x1000>;
|
||||
interrupts = <0 131 4>, <0 132 4>, <0 133 4>, <0 134 4>;
|
||||
clocks = <&can0_clk>;
|
||||
resets = <&rst CAN0_RESET>;
|
||||
};
|
||||
- |
|
||||
can@0 {
|
||||
|
@ -56,15 +56,15 @@ examples:
|
||||
#size-cells = <0>;
|
||||
|
||||
can@1 {
|
||||
compatible = "microchip,mcp2515";
|
||||
reg = <1>;
|
||||
clocks = <&clk24m>;
|
||||
interrupt-parent = <&gpio4>;
|
||||
interrupts = <13 IRQ_TYPE_LEVEL_LOW>;
|
||||
vdd-supply = <®5v0>;
|
||||
xceiver-supply = <®5v0>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
compatible = "microchip,mcp2515";
|
||||
reg = <1>;
|
||||
clocks = <&clk24m>;
|
||||
interrupt-parent = <&gpio4>;
|
||||
interrupts = <13 IRQ_TYPE_LEVEL_LOW>;
|
||||
vdd-supply = <®5v0>;
|
||||
xceiver-supply = <®5v0>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -15,7 +15,11 @@ allOf:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: microchip,mpfs-can
|
||||
oneOf:
|
||||
- items:
|
||||
- const: microchip,pic64gx-can
|
||||
- const: microchip,mpfs-can
|
||||
- const: microchip,mpfs-can
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -63,7 +63,7 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
st,gcan:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
The phandle to the gcan node which allows to access the 512-bytes
|
||||
SRAM memory shared by the two bxCAN cells (CAN1 primary and CAN2
|
||||
|
@ -1,48 +0,0 @@
|
||||
Texas Instruments TCAN4x5x CAN Controller
|
||||
================================================
|
||||
|
||||
This file provides device node information for the TCAN4x5x interface contains.
|
||||
|
||||
Required properties:
|
||||
- compatible:
|
||||
"ti,tcan4552", "ti,tcan4x5x"
|
||||
"ti,tcan4553", "ti,tcan4x5x" or
|
||||
"ti,tcan4x5x"
|
||||
- reg: 0
|
||||
- #address-cells: 1
|
||||
- #size-cells: 0
|
||||
- spi-max-frequency: Maximum frequency of the SPI bus the chip can
|
||||
operate at should be less than or equal to 18 MHz.
|
||||
- interrupt-parent: the phandle to the interrupt controller which provides
|
||||
the interrupt.
|
||||
- interrupts: interrupt specification for data-ready.
|
||||
|
||||
See Documentation/devicetree/bindings/net/can/bosch,m_can.yaml for additional
|
||||
required property details.
|
||||
|
||||
Optional properties:
|
||||
- reset-gpios: Hardwired output GPIO. If not defined then software
|
||||
reset.
|
||||
- device-state-gpios: Input GPIO that indicates if the device is in
|
||||
a sleep state or if the device is active. Not
|
||||
available with tcan4552/4553.
|
||||
- device-wake-gpios: Wake up GPIO to wake up the TCAN device. Not
|
||||
available with tcan4552/4553.
|
||||
- wakeup-source: Leave the chip running when suspended, and configure
|
||||
the RX interrupt to wake up the device.
|
||||
|
||||
Example:
|
||||
tcan4x5x: tcan4x5x@0 {
|
||||
compatible = "ti,tcan4x5x";
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
spi-max-frequency = <10000000>;
|
||||
bosch,mram-cfg = <0x0 0 0 16 0 0 1 1>;
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
|
||||
device-state-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
|
||||
device-wake-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
|
||||
wakeup-source;
|
||||
};
|
199
Documentation/devicetree/bindings/net/can/ti,tcan4x5x.yaml
Normal file
199
Documentation/devicetree/bindings/net/can/ti,tcan4x5x.yaml
Normal file
@ -0,0 +1,199 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/can/ti,tcan4x5x.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments TCAN4x5x CAN Controller
|
||||
|
||||
maintainers:
|
||||
- Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- ti,tcan4552
|
||||
- ti,tcan4553
|
||||
- const: ti,tcan4x5x
|
||||
- const: ti,tcan4x5x
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description: The GPIO parent interrupt.
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: cclk
|
||||
|
||||
reset-gpios:
|
||||
description: Hardwired output GPIO. If not defined then software reset.
|
||||
maxItems: 1
|
||||
|
||||
device-state-gpios:
|
||||
description:
|
||||
Input GPIO that indicates if the device is in a sleep state or if the
|
||||
device is active. Not available with tcan4552/4553.
|
||||
maxItems: 1
|
||||
|
||||
device-wake-gpios:
|
||||
description:
|
||||
Wake up GPIO to wake up the TCAN device.
|
||||
Not available with tcan4552/4553.
|
||||
maxItems: 1
|
||||
|
||||
bosch,mram-cfg:
|
||||
description: |
|
||||
Message RAM configuration data.
|
||||
Multiple M_CAN instances can share the same Message RAM
|
||||
and each element(e.g Rx FIFO or Tx Buffer and etc) number
|
||||
in Message RAM is also configurable, so this property is
|
||||
telling driver how the shared or private Message RAM are
|
||||
used by this M_CAN controller.
|
||||
|
||||
The format should be as follows:
|
||||
<offset sidf_elems xidf_elems rxf0_elems rxf1_elems rxb_elems txe_elems txb_elems>
|
||||
The 'offset' is an address offset of the Message RAM where
|
||||
the following elements start from. This is usually set to
|
||||
0x0 if you're using a private Message RAM. The remain cells
|
||||
are used to specify how many elements are used for each FIFO/Buffer.
|
||||
|
||||
M_CAN includes the following elements according to user manual:
|
||||
11-bit Filter 0-128 elements / 0-128 words
|
||||
29-bit Filter 0-64 elements / 0-128 words
|
||||
Rx FIFO 0 0-64 elements / 0-1152 words
|
||||
Rx FIFO 1 0-64 elements / 0-1152 words
|
||||
Rx Buffers 0-64 elements / 0-1152 words
|
||||
Tx Event FIFO 0-32 elements / 0-64 words
|
||||
Tx Buffers 0-32 elements / 0-576 words
|
||||
|
||||
Please refer to 2.4.1 Message RAM Configuration in Bosch
|
||||
M_CAN user manual for details.
|
||||
$ref: /schemas/types.yaml#/definitions/int32-array
|
||||
items:
|
||||
- description: The 'offset' is an address offset of the Message RAM where
|
||||
the following elements start from. This is usually set to 0x0 if
|
||||
you're using a private Message RAM.
|
||||
default: 0
|
||||
- description: 11-bit Filter 0-128 elements / 0-128 words
|
||||
minimum: 0
|
||||
maximum: 128
|
||||
- description: 29-bit Filter 0-64 elements / 0-128 words
|
||||
minimum: 0
|
||||
maximum: 64
|
||||
- description: Rx FIFO 0 0-64 elements / 0-1152 words
|
||||
minimum: 0
|
||||
maximum: 64
|
||||
- description: Rx FIFO 1 0-64 elements / 0-1152 words
|
||||
minimum: 0
|
||||
maximum: 64
|
||||
- description: Rx Buffers 0-64 elements / 0-1152 words
|
||||
minimum: 0
|
||||
maximum: 64
|
||||
- description: Tx Event FIFO 0-32 elements / 0-64 words
|
||||
minimum: 0
|
||||
maximum: 32
|
||||
- description: Tx Buffers 0-32 elements / 0-576 words
|
||||
minimum: 0
|
||||
maximum: 32
|
||||
minItems: 1
|
||||
|
||||
spi-max-frequency:
|
||||
description:
|
||||
Must be half or less of "clocks" frequency.
|
||||
maximum: 18000000
|
||||
|
||||
ti,nwkrq-voltage-vio:
|
||||
type: boolean
|
||||
description:
|
||||
nWKRQ Pin GPO buffer voltage configuration.
|
||||
Set nWKRQ to use VIO voltage rail.
|
||||
When not set nWKRQ will use internal voltage rail.
|
||||
|
||||
wakeup-source:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
Enable CAN remote wakeup.
|
||||
|
||||
allOf:
|
||||
- $ref: can-controller.yaml#
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- ti,tcan4552
|
||||
- ti,tcan4553
|
||||
then:
|
||||
properties:
|
||||
device-state-gpios: false
|
||||
device-wake-gpios: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- bosch,mram-cfg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
can@0 {
|
||||
compatible = "ti,tcan4x5x";
|
||||
reg = <0>;
|
||||
clocks = <&can0_osc>;
|
||||
clock-names = "cclk";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&can0_pins>;
|
||||
spi-max-frequency = <10000000>;
|
||||
bosch,mram-cfg = <0x0 0 0 16 0 0 1 1>;
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
|
||||
device-state-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
|
||||
device-wake-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
|
||||
ti,nwkrq-voltage-vio;
|
||||
wakeup-source;
|
||||
};
|
||||
};
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
can@0 {
|
||||
compatible = "ti,tcan4552", "ti,tcan4x5x";
|
||||
reg = <0>;
|
||||
clocks = <&can0_osc>;
|
||||
clock-names = "cclk";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&can0_pins>;
|
||||
spi-max-frequency = <10000000>;
|
||||
bosch,mram-cfg = <0x0 0 0 16 0 0 1 1>;
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
|
||||
reset-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
|
||||
wakeup-source;
|
||||
};
|
||||
};
|
@ -129,6 +129,24 @@ properties:
|
||||
minimum: 0
|
||||
maximum: 383
|
||||
|
||||
rx-internal-delay-ps:
|
||||
description:
|
||||
RGMII Receive Clock Delay defined in pico seconds, used to select
|
||||
the DLL phase shift between 1000 ps (45 degree shift at 1Gbps) and
|
||||
3300 ps (147 degree shift at 1Gbps). A value of 0 ps will disable
|
||||
any delay. The Default is no delay.
|
||||
enum: [0, 1000, 1700, 2000, 2500, 3000, 3300]
|
||||
default: 0
|
||||
|
||||
tx-internal-delay-ps:
|
||||
description:
|
||||
RGMII Transmit Clock Delay defined in pico seconds, used to select
|
||||
the DLL phase shift between 1000 ps (45 degree shift at 1Gbps) and
|
||||
3300 ps (147 degree shift at 1Gbps). A value of 0 ps will disable
|
||||
any delay. The Default is no delay.
|
||||
enum: [0, 1000, 1700, 2000, 2500, 3000, 3300]
|
||||
default: 0
|
||||
|
||||
required:
|
||||
- reg
|
||||
- phys
|
||||
|
105
Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
Normal file
105
Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
Normal file
@ -0,0 +1,105 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright 2021-2024 NXP
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/nxp,s32-dwmac.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP S32G2xx/S32G3xx/S32R45 GMAC ethernet controller
|
||||
|
||||
maintainers:
|
||||
- Jan Petrous (OSS) <jan.petrous@oss.nxp.com>
|
||||
|
||||
description:
|
||||
This device is a Synopsys DWC IP, integrated on NXP S32G/R SoCs.
|
||||
The SoC series S32G2xx and S32G3xx feature one DWMAC instance,
|
||||
the SoC S32R45 has two instances. The devices can use RGMII/RMII/MII
|
||||
interface over Pinctrl device or the output can be routed
|
||||
to the embedded SerDes for SGMII connectivity.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: nxp,s32g2-dwmac
|
||||
- items:
|
||||
- enum:
|
||||
- nxp,s32g3-dwmac
|
||||
- nxp,s32r45-dwmac
|
||||
- const: nxp,s32g2-dwmac
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Main GMAC registers
|
||||
- description: GMAC PHY mode control register
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
const: macirq
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Main GMAC clock
|
||||
- description: Transmit clock
|
||||
- description: Receive clock
|
||||
- description: PTP reference clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: stmmaceth
|
||||
- const: tx
|
||||
- const: rx
|
||||
- const: ptp_ref
|
||||
|
||||
required:
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
allOf:
|
||||
- $ref: snps,dwmac.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
bus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
ethernet@4033c000 {
|
||||
compatible = "nxp,s32g2-dwmac";
|
||||
reg = <0x0 0x4033c000 0x0 0x2000>, /* gmac IP */
|
||||
<0x0 0x4007c004 0x0 0x4>; /* GMAC_0_CTRL_STS */
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "macirq";
|
||||
snps,mtl-rx-config = <&mtl_rx_setup>;
|
||||
snps,mtl-tx-config = <&mtl_tx_setup>;
|
||||
clocks = <&clks 24>, <&clks 17>, <&clks 16>, <&clks 15>;
|
||||
clock-names = "stmmaceth", "tx", "rx", "ptp_ref";
|
||||
phy-mode = "rgmii-id";
|
||||
phy-handle = <&phy0>;
|
||||
|
||||
mtl_rx_setup: rx-queues-config {
|
||||
snps,rx-queues-to-use = <5>;
|
||||
};
|
||||
|
||||
mtl_tx_setup: tx-queues-config {
|
||||
snps,tx-queues-to-use = <5>;
|
||||
};
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "snps,dwmac-mdio";
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@ -239,7 +239,7 @@ examples:
|
||||
|
||||
qcom,gsi-loader = "self";
|
||||
memory-region = <&ipa_fw_mem>;
|
||||
firmware-name = "qcom/sc7180-trogdor/modem/modem.mdt";
|
||||
firmware-name = "qcom/sc7180-trogdor/modem/modem.mbn";
|
||||
|
||||
iommus = <&apps_smmu 0x440 0x0>,
|
||||
<&apps_smmu 0x442 0x0>;
|
||||
|
@ -67,6 +67,7 @@ properties:
|
||||
- ingenic,x2000-mac
|
||||
- loongson,ls2k-dwmac
|
||||
- loongson,ls7a-dwmac
|
||||
- nxp,s32g2-dwmac
|
||||
- qcom,qcs404-ethqos
|
||||
- qcom,sa8775p-ethqos
|
||||
- qcom,sc8280xp-ethqos
|
||||
|
@ -154,56 +154,56 @@ examples:
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||
//Example 1
|
||||
ethernet0: ethernet@5800a000 {
|
||||
compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
|
||||
reg = <0x5800a000 0x2000>;
|
||||
reg-names = "stmmaceth";
|
||||
interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "macirq";
|
||||
clock-names = "stmmaceth",
|
||||
"mac-clk-tx",
|
||||
"mac-clk-rx",
|
||||
"ethstp",
|
||||
"eth-ck";
|
||||
clocks = <&rcc ETHMAC>,
|
||||
<&rcc ETHTX>,
|
||||
<&rcc ETHRX>,
|
||||
<&rcc ETHSTP>,
|
||||
<&rcc ETHCK_K>;
|
||||
st,syscon = <&syscfg 0x4>;
|
||||
snps,pbl = <2>;
|
||||
snps,axi-config = <&stmmac_axi_config_0>;
|
||||
snps,tso;
|
||||
phy-mode = "rgmii";
|
||||
};
|
||||
ethernet0: ethernet@5800a000 {
|
||||
compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
|
||||
reg = <0x5800a000 0x2000>;
|
||||
reg-names = "stmmaceth";
|
||||
interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "macirq";
|
||||
clock-names = "stmmaceth",
|
||||
"mac-clk-tx",
|
||||
"mac-clk-rx",
|
||||
"ethstp",
|
||||
"eth-ck";
|
||||
clocks = <&rcc ETHMAC>,
|
||||
<&rcc ETHTX>,
|
||||
<&rcc ETHRX>,
|
||||
<&rcc ETHSTP>,
|
||||
<&rcc ETHCK_K>;
|
||||
st,syscon = <&syscfg 0x4>;
|
||||
snps,pbl = <2>;
|
||||
snps,axi-config = <&stmmac_axi_config_0>;
|
||||
snps,tso;
|
||||
phy-mode = "rgmii";
|
||||
};
|
||||
|
||||
- |
|
||||
//Example 2 (MCU example)
|
||||
ethernet1: ethernet@40028000 {
|
||||
compatible = "st,stm32-dwmac", "snps,dwmac-3.50a";
|
||||
reg = <0x40028000 0x8000>;
|
||||
reg-names = "stmmaceth";
|
||||
interrupts = <0 61 0>, <0 62 0>;
|
||||
interrupt-names = "macirq", "eth_wake_irq";
|
||||
clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx";
|
||||
clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>;
|
||||
st,syscon = <&syscfg 0x4>;
|
||||
snps,pbl = <8>;
|
||||
snps,mixed-burst;
|
||||
phy-mode = "mii";
|
||||
};
|
||||
ethernet1: ethernet@40028000 {
|
||||
compatible = "st,stm32-dwmac", "snps,dwmac-3.50a";
|
||||
reg = <0x40028000 0x8000>;
|
||||
reg-names = "stmmaceth";
|
||||
interrupts = <0 61 0>, <0 62 0>;
|
||||
interrupt-names = "macirq", "eth_wake_irq";
|
||||
clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx";
|
||||
clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>;
|
||||
st,syscon = <&syscfg 0x4>;
|
||||
snps,pbl = <8>;
|
||||
snps,mixed-burst;
|
||||
phy-mode = "mii";
|
||||
};
|
||||
|
||||
- |
|
||||
//Example 3
|
||||
ethernet2: ethernet@40027000 {
|
||||
compatible = "st,stm32-dwmac", "snps,dwmac-4.10a";
|
||||
reg = <0x40028000 0x8000>;
|
||||
reg-names = "stmmaceth";
|
||||
interrupts = <61>;
|
||||
interrupt-names = "macirq";
|
||||
clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx";
|
||||
clocks = <&rcc 62>, <&rcc 61>, <&rcc 60>;
|
||||
st,syscon = <&syscfg 0x4>;
|
||||
snps,pbl = <8>;
|
||||
phy-mode = "mii";
|
||||
};
|
||||
ethernet2: ethernet@40027000 {
|
||||
compatible = "st,stm32-dwmac", "snps,dwmac-4.10a";
|
||||
reg = <0x40028000 0x8000>;
|
||||
reg-names = "stmmaceth";
|
||||
interrupts = <61>;
|
||||
interrupt-names = "macirq";
|
||||
clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx";
|
||||
clocks = <&rcc 62>, <&rcc 61>, <&rcc 60>;
|
||||
st,syscon = <&syscfg 0x4>;
|
||||
snps,pbl = <8>;
|
||||
phy-mode = "mii";
|
||||
};
|
||||
|
@ -72,9 +72,9 @@ unevaluatedProperties: false
|
||||
examples:
|
||||
- |
|
||||
davinci_mdio: mdio@4a101000 {
|
||||
compatible = "ti,davinci_mdio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x4a101000 0x1000>;
|
||||
bus_freq = <1000000>;
|
||||
compatible = "ti,davinci_mdio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x4a101000 0x1000>;
|
||||
bus_freq = <1000000>;
|
||||
};
|
||||
|
@ -96,6 +96,32 @@ properties:
|
||||
- master
|
||||
- slave
|
||||
|
||||
ti,gpio2-clk-out:
|
||||
description: |
|
||||
DP83822 PHY only.
|
||||
The GPIO2 pin on the DP83822 can be configured as clock output. When
|
||||
omitted, the PHY's default will be left as is.
|
||||
|
||||
- 'mac-if': In MII mode the clock frequency is 25-MHz, in RMII Mode the
|
||||
clock frequency is 50-MHz and in RGMII Mode the clock frequency is
|
||||
25-MHz.
|
||||
- 'xi': XI clock(pass-through clock from XI pin).
|
||||
- 'int-ref': Internal reference clock 25-MHz.
|
||||
- 'rmii-master-mode-ref': RMII master mode reference clock 50-MHz. RMII
|
||||
master mode reference clock is identical to MAC IF clock in RMII master
|
||||
mode.
|
||||
- 'free-running': Free running clock 125-MHz.
|
||||
- 'recovered': Recovered clock is a 125-MHz recovered clock from a
|
||||
connected link partner.
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum:
|
||||
- mac-if
|
||||
- xi
|
||||
- int-ref
|
||||
- rmii-master-mode-ref
|
||||
- free-running
|
||||
- recovered
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
@ -110,6 +136,7 @@ examples:
|
||||
reg = <0>;
|
||||
rx-internal-delay-ps = <1>;
|
||||
tx-internal-delay-ps = <1>;
|
||||
ti,gpio2-clk-out = "xi";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -302,16 +302,16 @@ examples:
|
||||
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
cpts@3d000 {
|
||||
compatible = "ti,am65-cpts";
|
||||
reg = <0x0 0x3d000 0x0 0x400>;
|
||||
clocks = <&k3_clks 18 2>;
|
||||
clock-names = "cpts";
|
||||
interrupts-extended = <&gic500 GIC_SPI 858 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "cpts";
|
||||
ti,cpts-ext-ts-inputs = <4>;
|
||||
ti,cpts-periodic-outputs = <2>;
|
||||
cpts@3d000 {
|
||||
compatible = "ti,am65-cpts";
|
||||
reg = <0x0 0x3d000 0x0 0x400>;
|
||||
clocks = <&k3_clks 18 2>;
|
||||
clock-names = "cpts";
|
||||
interrupts-extended = <&gic500 GIC_SPI 858 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "cpts";
|
||||
ti,cpts-ext-ts-inputs = <4>;
|
||||
ti,cpts-periodic-outputs = <2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -131,23 +131,23 @@ examples:
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
cpts@310d0000 {
|
||||
compatible = "ti,am65-cpts";
|
||||
reg = <0x310d0000 0x400>;
|
||||
reg-names = "cpts";
|
||||
clocks = <&main_cpts_mux>;
|
||||
clock-names = "cpts";
|
||||
interrupts-extended = <&k3_irq 163 0 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "cpts";
|
||||
ti,cpts-periodic-outputs = <6>;
|
||||
ti,cpts-ext-ts-inputs = <8>;
|
||||
compatible = "ti,am65-cpts";
|
||||
reg = <0x310d0000 0x400>;
|
||||
reg-names = "cpts";
|
||||
clocks = <&main_cpts_mux>;
|
||||
clock-names = "cpts";
|
||||
interrupts-extended = <&k3_irq 163 0 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "cpts";
|
||||
ti,cpts-periodic-outputs = <6>;
|
||||
ti,cpts-ext-ts-inputs = <8>;
|
||||
|
||||
main_cpts_mux: refclk-mux {
|
||||
#clock-cells = <0>;
|
||||
clocks = <&k3_clks 118 5>, <&k3_clks 118 11>,
|
||||
<&k3_clks 157 91>, <&k3_clks 157 77>,
|
||||
<&k3_clks 157 102>, <&k3_clks 157 80>,
|
||||
<&k3_clks 120 3>, <&k3_clks 121 3>;
|
||||
assigned-clocks = <&main_cpts_mux>;
|
||||
assigned-clock-parents = <&k3_clks 118 11>;
|
||||
};
|
||||
main_cpts_mux: refclk-mux {
|
||||
#clock-cells = <0>;
|
||||
clocks = <&k3_clks 118 5>, <&k3_clks 118 11>,
|
||||
<&k3_clks 157 91>, <&k3_clks 157 77>,
|
||||
<&k3_clks 157 102>, <&k3_clks 157 80>,
|
||||
<&k3_clks 120 3>, <&k3_clks 121 3>;
|
||||
assigned-clocks = <&main_cpts_mux>;
|
||||
assigned-clock-parents = <&k3_clks 118 11>;
|
||||
};
|
||||
};
|
||||
|
@ -79,15 +79,14 @@ examples:
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
mmc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
wifi@1 {
|
||||
compatible = "marvell,sd8897";
|
||||
reg = <1>;
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
|
||||
marvell,wakeup-pin = <3>;
|
||||
wifi@1 {
|
||||
compatible = "marvell,sd8897";
|
||||
reg = <1>;
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
|
||||
marvell,wakeup-pin = <3>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -106,6 +106,9 @@ properties:
|
||||
name-prefix:
|
||||
description: For enum the prefix of the values, optional.
|
||||
type: string
|
||||
enum-cnt-name:
|
||||
description: Name of the render-max counter enum entry.
|
||||
type: string
|
||||
# End genetlink-c
|
||||
|
||||
attribute-sets:
|
||||
|
@ -117,6 +117,9 @@ properties:
|
||||
name-prefix:
|
||||
description: For enum the prefix of the values, optional.
|
||||
type: string
|
||||
enum-cnt-name:
|
||||
description: Name of the render-max counter enum entry.
|
||||
type: string
|
||||
# End genetlink-c
|
||||
# Start genetlink-legacy
|
||||
members:
|
||||
|
@ -221,7 +221,7 @@ properties:
|
||||
type: &attr-type
|
||||
description: The netlink attribute type
|
||||
enum: [ unused, pad, flag, binary, bitfield32,
|
||||
u8, u16, u32, u64, s8, s16, s32, s64,
|
||||
uint, sint, u8, u16, u32, u64, s8, s16, s32, s64,
|
||||
string, nest, indexed-array, nest-type-value,
|
||||
sub-message ]
|
||||
doc:
|
||||
|
@ -5,6 +5,7 @@ name: ethtool
|
||||
protocol: genetlink-legacy
|
||||
|
||||
doc: Partial family for Ethtool Netlink.
|
||||
uapi-header: linux/ethtool_netlink_generated.h
|
||||
|
||||
definitions:
|
||||
-
|
||||
@ -12,43 +13,99 @@ definitions:
|
||||
enum-name:
|
||||
type: enum
|
||||
entries: [ vxlan, geneve, vxlan-gpe ]
|
||||
enum-cnt-name: __ethtool-udp-tunnel-type-cnt
|
||||
render-max: true
|
||||
-
|
||||
name: stringset
|
||||
type: enum
|
||||
entries: []
|
||||
header: linux/ethtool.h # skip rendering, no actual definition
|
||||
-
|
||||
name: header-flags
|
||||
type: flags
|
||||
entries: [ compact-bitsets, omit-reply, stats ]
|
||||
name-prefix: ethtool-flag-
|
||||
doc: common ethtool header flags
|
||||
entries:
|
||||
-
|
||||
name: compact-bitsets
|
||||
doc: use compact bitsets in reply
|
||||
-
|
||||
name: omit-reply
|
||||
doc: provide optional reply for SET or ACT requests
|
||||
-
|
||||
name: stats
|
||||
doc: request statistics, if supported by the driver
|
||||
-
|
||||
name: module-fw-flash-status
|
||||
type: enum
|
||||
entries: [ started, in_progress, completed, error ]
|
||||
doc: plug-in module firmware flashing status
|
||||
header: linux/ethtool.h
|
||||
entries:
|
||||
-
|
||||
name: started
|
||||
doc: The firmware flashing process has started.
|
||||
-
|
||||
name: in_progress
|
||||
doc: The firmware flashing process is in progress.
|
||||
-
|
||||
name: completed
|
||||
doc: The firmware flashing process was completed successfully.
|
||||
-
|
||||
name: error
|
||||
doc: The firmware flashing process was stopped due to an error.
|
||||
-
|
||||
name: c33-pse-ext-state
|
||||
enum-name:
|
||||
doc: "groups of PSE extended states functions. IEEE 802.3-2022 33.2.4.4 Variables"
|
||||
type: enum
|
||||
name-prefix: ethtool-c33-pse-ext-state-
|
||||
header: linux/ethtool.h
|
||||
entries:
|
||||
- none
|
||||
- error-condition
|
||||
- mr-mps-valid
|
||||
- mr-pse-enable
|
||||
- option-detect-ted
|
||||
- option-vport-lim
|
||||
- ovld-detected
|
||||
- power-not-available
|
||||
- short-detected
|
||||
-
|
||||
name: none
|
||||
doc: none
|
||||
-
|
||||
name: error-condition
|
||||
doc: Group of error_condition states
|
||||
-
|
||||
name: mr-mps-valid
|
||||
doc: Group of mr_mps_valid states
|
||||
-
|
||||
name: mr-pse-enable
|
||||
doc: Group of mr_pse_enable states
|
||||
-
|
||||
name: option-detect-ted
|
||||
doc: Group of option_detect_ted states
|
||||
-
|
||||
name: option-vport-lim
|
||||
doc: Group of option_vport_lim states
|
||||
-
|
||||
name: ovld-detected
|
||||
doc: Group of ovld_detected states
|
||||
-
|
||||
name: power-not-available
|
||||
doc: Group of power_not_available states
|
||||
-
|
||||
name: short-detected
|
||||
doc: Group of short_detected states
|
||||
-
|
||||
name: phy-upstream-type
|
||||
enum-name:
|
||||
type: enum
|
||||
entries: [ mac, phy ]
|
||||
-
|
||||
name: tcp-data-split
|
||||
type: enum
|
||||
entries: [ unknown, disabled, enabled ]
|
||||
|
||||
attribute-sets:
|
||||
-
|
||||
name: header
|
||||
attr-cnt-name: __ethtool-a-header-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: dev-index
|
||||
type: u32
|
||||
@ -65,7 +122,12 @@ attribute-sets:
|
||||
|
||||
-
|
||||
name: bitset-bit
|
||||
attr-cnt-name: __ethtool-a-bitset-bit-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: index
|
||||
type: u32
|
||||
@ -77,7 +139,12 @@ attribute-sets:
|
||||
type: flag
|
||||
-
|
||||
name: bitset-bits
|
||||
attr-cnt-name: __ethtool-a-bitset-bits-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: bit
|
||||
type: nest
|
||||
@ -85,7 +152,12 @@ attribute-sets:
|
||||
nested-attributes: bitset-bit
|
||||
-
|
||||
name: bitset
|
||||
attr-cnt-name: __ethtool-a-bitset-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: nomask
|
||||
type: flag
|
||||
@ -104,7 +176,12 @@ attribute-sets:
|
||||
type: binary
|
||||
-
|
||||
name: string
|
||||
attr-cnt-name: __ethtool-a-string-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: index
|
||||
type: u32
|
||||
@ -113,7 +190,16 @@ attribute-sets:
|
||||
type: string
|
||||
-
|
||||
name: strings
|
||||
attr-cnt-name: __ethtool-a-strings-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: string
|
||||
type: nest
|
||||
@ -121,7 +207,12 @@ attribute-sets:
|
||||
nested-attributes: string
|
||||
-
|
||||
name: stringset
|
||||
attr-cnt-name: __ethtool-a-stringset-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: id
|
||||
type: u32
|
||||
@ -135,7 +226,12 @@ attribute-sets:
|
||||
nested-attributes: strings
|
||||
-
|
||||
name: stringsets
|
||||
attr-cnt-name: __ethtool-a-stringsets-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: stringset
|
||||
type: nest
|
||||
@ -143,7 +239,12 @@ attribute-sets:
|
||||
nested-attributes: stringset
|
||||
-
|
||||
name: strset
|
||||
attr-cnt-name: __ethtool-a-strset-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -158,7 +259,12 @@ attribute-sets:
|
||||
|
||||
-
|
||||
name: privflags
|
||||
attr-cnt-name: __ethtool-a-privflags-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -170,7 +276,12 @@ attribute-sets:
|
||||
|
||||
-
|
||||
name: rings
|
||||
attr-cnt-name: __ethtool-a-rings-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -205,6 +316,7 @@ attribute-sets:
|
||||
-
|
||||
name: tcp-data-split
|
||||
type: u8
|
||||
enum: tcp-data-split
|
||||
-
|
||||
name: cqe-size
|
||||
type: u32
|
||||
@ -223,31 +335,48 @@ attribute-sets:
|
||||
|
||||
-
|
||||
name: mm-stat
|
||||
attr-cnt-name: __ethtool-a-mm-stat-cnt
|
||||
doc: MAC Merge (802.3)
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
-
|
||||
name: reassembly-errors
|
||||
doc: aMACMergeFrameAssErrorCount
|
||||
type: u64
|
||||
-
|
||||
name: smd-errors
|
||||
doc: aMACMergeFrameSmdErrorCount
|
||||
type: u64
|
||||
-
|
||||
name: reassembly-ok
|
||||
doc: aMACMergeFrameAssOkCount
|
||||
type: u64
|
||||
-
|
||||
name: rx-frag-count
|
||||
doc: aMACMergeFragCountRx
|
||||
type: u64
|
||||
-
|
||||
name: tx-frag-count
|
||||
doc: aMACMergeFragCountTx
|
||||
type: u64
|
||||
-
|
||||
name: hold-count
|
||||
doc: aMACMergeHoldCount
|
||||
type: u64
|
||||
-
|
||||
name: mm
|
||||
attr-cnt-name: __ethtool-a-mm-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -285,7 +414,12 @@ attribute-sets:
|
||||
nested-attributes: mm-stat
|
||||
-
|
||||
name: linkinfo
|
||||
attr-cnt-name: __ethtool-a-linkinfo-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -307,7 +441,12 @@ attribute-sets:
|
||||
type: u8
|
||||
-
|
||||
name: linkmodes
|
||||
attr-cnt-name: __ethtool-a-linkmodes-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -343,7 +482,12 @@ attribute-sets:
|
||||
type: u8
|
||||
-
|
||||
name: linkstate
|
||||
attr-cnt-name: __ethtool-a-linkstate-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -368,7 +512,12 @@ attribute-sets:
|
||||
type: u32
|
||||
-
|
||||
name: debug
|
||||
attr-cnt-name: __ethtool-a-debug-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -379,7 +528,12 @@ attribute-sets:
|
||||
nested-attributes: bitset
|
||||
-
|
||||
name: wol
|
||||
attr-cnt-name: __ethtool-a-wol-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -393,7 +547,12 @@ attribute-sets:
|
||||
type: binary
|
||||
-
|
||||
name: features
|
||||
attr-cnt-name: __ethtool-a-features-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -416,7 +575,12 @@ attribute-sets:
|
||||
nested-attributes: bitset
|
||||
-
|
||||
name: channels
|
||||
attr-cnt-name: __ethtool-a-channels-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -448,7 +612,12 @@ attribute-sets:
|
||||
|
||||
-
|
||||
name: irq-moderation
|
||||
attr-cnt-name: __ethtool-a-irq-moderation-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: usec
|
||||
type: u32
|
||||
@ -460,7 +629,12 @@ attribute-sets:
|
||||
type: u32
|
||||
-
|
||||
name: profile
|
||||
attr-cnt-name: __ethtool-a-profile-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: irq-moderation
|
||||
type: nest
|
||||
@ -468,7 +642,12 @@ attribute-sets:
|
||||
nested-attributes: irq-moderation
|
||||
-
|
||||
name: coalesce
|
||||
attr-cnt-name: __ethtool-a-coalesce-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -565,7 +744,12 @@ attribute-sets:
|
||||
|
||||
-
|
||||
name: pause-stat
|
||||
attr-cnt-name: __ethtool-a-pause-stat-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
@ -577,7 +761,12 @@ attribute-sets:
|
||||
type: u64
|
||||
-
|
||||
name: pause
|
||||
attr-cnt-name: __ethtool-a-pause-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -600,7 +789,12 @@ attribute-sets:
|
||||
type: u32
|
||||
-
|
||||
name: eee
|
||||
attr-cnt-name: __ethtool-a-eee-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -627,7 +821,12 @@ attribute-sets:
|
||||
type: u32
|
||||
-
|
||||
name: ts-stat
|
||||
attr-cnt-name: __ethtool-a-ts-stat-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: tx-pkts
|
||||
type: uint
|
||||
@ -638,8 +837,27 @@ attribute-sets:
|
||||
name: tx-err
|
||||
type: uint
|
||||
-
|
||||
name: tsinfo
|
||||
name: ts-hwtstamp-provider
|
||||
attr-cnt-name: __ethtool-a-ts-hwtstamp-provider-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: index
|
||||
type: u32
|
||||
-
|
||||
name: qualifier
|
||||
type: u32
|
||||
-
|
||||
name: tsinfo
|
||||
attr-cnt-name: __ethtool-a-tsinfo-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -663,21 +881,38 @@ attribute-sets:
|
||||
name: stats
|
||||
type: nest
|
||||
nested-attributes: ts-stat
|
||||
-
|
||||
name: hwtstamp-provider
|
||||
type: nest
|
||||
nested-attributes: ts-hwtstamp-provider
|
||||
-
|
||||
name: cable-result
|
||||
attr-cnt-name: __ethtool-a-cable-result-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: pair
|
||||
doc: ETHTOOL_A_CABLE_PAIR
|
||||
type: u8
|
||||
-
|
||||
name: code
|
||||
doc: ETHTOOL_A_CABLE_RESULT_CODE
|
||||
type: u8
|
||||
-
|
||||
name: src
|
||||
doc: ETHTOOL_A_CABLE_INF_SRC
|
||||
type: u32
|
||||
-
|
||||
name: cable-fault-length
|
||||
attr-cnt-name: __ethtool-a-cable-fault-length-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: pair
|
||||
type: u8
|
||||
@ -689,7 +924,12 @@ attribute-sets:
|
||||
type: u32
|
||||
-
|
||||
name: cable-nest
|
||||
attr-cnt-name: __ethtool-a-cable-nest-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: result
|
||||
type: nest
|
||||
@ -700,20 +940,31 @@ attribute-sets:
|
||||
nested-attributes: cable-fault-length
|
||||
-
|
||||
name: cable-test
|
||||
attr-cnt-name: __ethtool-a-cable-test-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
nested-attributes: header
|
||||
-
|
||||
name: cable-test-ntf
|
||||
attr-cnt-name: __ethtool-a-cable-test-ntf-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
nested-attributes: header
|
||||
-
|
||||
name: status
|
||||
doc: _STARTED/_COMPLETE
|
||||
type: u8
|
||||
-
|
||||
name: nest
|
||||
@ -721,7 +972,12 @@ attribute-sets:
|
||||
nested-attributes: cable-nest
|
||||
-
|
||||
name: cable-test-tdr-cfg
|
||||
attr-cnt-name: __ethtool-a-cable-test-tdr-cfg-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: first
|
||||
type: u32
|
||||
@ -736,7 +992,12 @@ attribute-sets:
|
||||
type: u8
|
||||
-
|
||||
name: cable-test-tdr-ntf
|
||||
attr-cnt-name: __ethtool-a-cable-test-tdr-ntf-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -750,7 +1011,12 @@ attribute-sets:
|
||||
nested-attributes: cable-nest
|
||||
-
|
||||
name: cable-test-tdr
|
||||
attr-cnt-name: __ethtool-a-cable-test-tdr-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -761,7 +1027,12 @@ attribute-sets:
|
||||
nested-attributes: cable-test-tdr-cfg
|
||||
-
|
||||
name: tunnel-udp-entry
|
||||
attr-cnt-name: __ethtool-a-tunnel-udp-entry-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: port
|
||||
type: u16
|
||||
@ -772,7 +1043,12 @@ attribute-sets:
|
||||
enum: udp-tunnel-type
|
||||
-
|
||||
name: tunnel-udp-table
|
||||
attr-cnt-name: __ethtool-a-tunnel-udp-table-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: size
|
||||
type: u32
|
||||
@ -787,14 +1063,24 @@ attribute-sets:
|
||||
nested-attributes: tunnel-udp-entry
|
||||
-
|
||||
name: tunnel-udp
|
||||
attr-cnt-name: __ethtool-a-tunnel-udp-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: table
|
||||
type: nest
|
||||
nested-attributes: tunnel-udp-table
|
||||
-
|
||||
name: tunnel-info
|
||||
attr-cnt-name: __ethtool-a-tunnel-info-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -805,7 +1091,12 @@ attribute-sets:
|
||||
nested-attributes: tunnel-udp
|
||||
-
|
||||
name: fec-stat
|
||||
attr-cnt-name: __ethtool-a-fec-stat-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
@ -823,7 +1114,12 @@ attribute-sets:
|
||||
sub-type: u64
|
||||
-
|
||||
name: fec
|
||||
attr-cnt-name: __ethtool-a-fec-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -844,7 +1140,12 @@ attribute-sets:
|
||||
nested-attributes: fec-stat
|
||||
-
|
||||
name: module-eeprom
|
||||
attr-cnt-name: __ethtool-a-module-eeprom-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -869,7 +1170,12 @@ attribute-sets:
|
||||
type: binary
|
||||
-
|
||||
name: stats-grp
|
||||
attr-cnt-name: __ethtool-a-stats-grp-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
@ -912,7 +1218,12 @@ attribute-sets:
|
||||
name: hist-val
|
||||
-
|
||||
name: stats
|
||||
attr-cnt-name: __ethtool-a-stats-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
@ -933,7 +1244,12 @@ attribute-sets:
|
||||
type: u32
|
||||
-
|
||||
name: phc-vclocks
|
||||
attr-cnt-name: __ethtool-a-phc-vclocks-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -947,7 +1263,12 @@ attribute-sets:
|
||||
sub-type: s32
|
||||
-
|
||||
name: module
|
||||
attr-cnt-name: __ethtool-a-module-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -960,7 +1281,13 @@ attribute-sets:
|
||||
type: u8
|
||||
-
|
||||
name: c33-pse-pw-limit
|
||||
attr-cnt-name: __ethtool-a-c33-pse-pw-limit-cnt
|
||||
attr-max-name: __ethtool-a-c33-pse-pw-limit-max
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: min
|
||||
type: u32
|
||||
@ -969,7 +1296,12 @@ attribute-sets:
|
||||
type: u32
|
||||
-
|
||||
name: pse
|
||||
attr-cnt-name: __ethtool-a-pse-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -1027,7 +1359,12 @@ attribute-sets:
|
||||
nested-attributes: c33-pse-pw-limit
|
||||
-
|
||||
name: rss
|
||||
attr-cnt-name: __ethtool-a-rss-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -1053,7 +1390,12 @@ attribute-sets:
|
||||
type: u32
|
||||
-
|
||||
name: plca
|
||||
attr-cnt-name: __ethtool-a-plca-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -1084,7 +1426,12 @@ attribute-sets:
|
||||
type: u32
|
||||
-
|
||||
name: module-fw-flash
|
||||
attr-cnt-name: __ethtool-a-module-fw-flash-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -1110,7 +1457,12 @@ attribute-sets:
|
||||
type: uint
|
||||
-
|
||||
name: phy
|
||||
attr-cnt-name: __ethtool-a-phy-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
@ -1137,6 +1489,33 @@ attribute-sets:
|
||||
-
|
||||
name: downstream-sfp-name
|
||||
type: string
|
||||
-
|
||||
name: tsconfig
|
||||
attr-cnt-name: __ethtool-a-tsconfig-cnt
|
||||
attributes:
|
||||
-
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
nested-attributes: header
|
||||
-
|
||||
name: hwtstamp-provider
|
||||
type: nest
|
||||
nested-attributes: ts-hwtstamp-provider
|
||||
-
|
||||
name: tx-types
|
||||
type: nest
|
||||
nested-attributes: bitset
|
||||
-
|
||||
name: rx-filters
|
||||
type: nest
|
||||
nested-attributes: bitset
|
||||
-
|
||||
name: hwtstamp-flags
|
||||
type: u32
|
||||
|
||||
operations:
|
||||
enum-model: directional
|
||||
@ -1578,6 +1957,7 @@ operations:
|
||||
request:
|
||||
attributes:
|
||||
- header
|
||||
- hwtstamp-provider
|
||||
reply:
|
||||
attributes:
|
||||
- header
|
||||
@ -1586,6 +1966,7 @@ operations:
|
||||
- rx-filters
|
||||
- phc-index
|
||||
- stats
|
||||
- hwtstamp-provider
|
||||
dump: *tsinfo-get-op
|
||||
-
|
||||
name: cable-test-act
|
||||
@ -1960,3 +2341,32 @@ operations:
|
||||
name: phy-ntf
|
||||
doc: Notification for change in PHY devices.
|
||||
notify: phy-get
|
||||
-
|
||||
name: tsconfig-get
|
||||
doc: Get hwtstamp config.
|
||||
|
||||
attribute-set: tsconfig
|
||||
|
||||
do: &tsconfig-get-op
|
||||
request:
|
||||
attributes:
|
||||
- header
|
||||
reply:
|
||||
attributes: &tsconfig
|
||||
- header
|
||||
- hwtstamp-provider
|
||||
- tx-types
|
||||
- rx-filters
|
||||
- hwtstamp-flags
|
||||
dump: *tsconfig-get-op
|
||||
-
|
||||
name: tsconfig-set
|
||||
doc: Set hwtstamp config.
|
||||
|
||||
attribute-set: tsconfig
|
||||
|
||||
do:
|
||||
request:
|
||||
attributes: *tsconfig
|
||||
reply:
|
||||
attributes: *tsconfig
|
||||
|
@ -1825,6 +1825,48 @@ attribute-sets:
|
||||
-
|
||||
name: erspan-hwid
|
||||
type: u16
|
||||
-
|
||||
name: linkinfo-vti-attrs
|
||||
name-prefix: ifla-vti-
|
||||
attributes:
|
||||
-
|
||||
name: link
|
||||
type: u32
|
||||
-
|
||||
name: ikey
|
||||
type: u32
|
||||
-
|
||||
name: okey
|
||||
type: u32
|
||||
-
|
||||
name: local
|
||||
type: binary
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: remote
|
||||
type: binary
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: fwmark
|
||||
type: u32
|
||||
-
|
||||
name: linkinfo-vti6-attrs
|
||||
subset-of: linkinfo-vti-attrs
|
||||
attributes:
|
||||
-
|
||||
name: link
|
||||
-
|
||||
name: ikey
|
||||
-
|
||||
name: okey
|
||||
-
|
||||
name: local
|
||||
display-hint: ipv6
|
||||
-
|
||||
name: remote
|
||||
display-hint: ipv6
|
||||
-
|
||||
name: fwmark
|
||||
-
|
||||
name: linkinfo-geneve-attrs
|
||||
name-prefix: ifla-geneve-
|
||||
@ -1941,6 +1983,42 @@ attribute-sets:
|
||||
-
|
||||
name: fwmark
|
||||
type: u32
|
||||
-
|
||||
name: linkinfo-ip6tnl-attrs
|
||||
subset-of: linkinfo-iptun-attrs
|
||||
attributes:
|
||||
-
|
||||
name: link
|
||||
-
|
||||
name: local
|
||||
display-hint: ipv6
|
||||
-
|
||||
name: remote
|
||||
display-hint: ipv6
|
||||
-
|
||||
name: ttl
|
||||
-
|
||||
name: encap-limit
|
||||
-
|
||||
name: flowinfo
|
||||
-
|
||||
name: flags
|
||||
# ip6tnl unlike ipip and sit has 32b flags
|
||||
type: u32
|
||||
-
|
||||
name: proto
|
||||
-
|
||||
name: encap-type
|
||||
-
|
||||
name: encap-flags
|
||||
-
|
||||
name: encap-sport
|
||||
-
|
||||
name: encap-dport
|
||||
-
|
||||
name: collect-metadata
|
||||
-
|
||||
name: fwmark
|
||||
-
|
||||
name: linkinfo-tun-attrs
|
||||
name-prefix: ifla-tun-
|
||||
@ -2086,6 +2164,9 @@ attribute-sets:
|
||||
-
|
||||
name: mctp-net
|
||||
type: u32
|
||||
-
|
||||
name: phys-binding
|
||||
type: u8
|
||||
-
|
||||
name: stats-attrs
|
||||
name-prefix: ifla-stats-
|
||||
@ -2166,6 +2247,12 @@ attribute-sets:
|
||||
name: peer-scrub
|
||||
type: u32
|
||||
enum: netkit-scrub
|
||||
-
|
||||
name: headroom
|
||||
type: u16
|
||||
-
|
||||
name: tailroom
|
||||
type: u16
|
||||
|
||||
sub-messages:
|
||||
-
|
||||
@ -2192,6 +2279,9 @@ sub-messages:
|
||||
-
|
||||
value: ipip
|
||||
attribute-set: linkinfo-iptun-attrs
|
||||
-
|
||||
value: ip6tnl
|
||||
attribute-set: linkinfo-ip6tnl-attrs
|
||||
-
|
||||
value: sit
|
||||
attribute-set: linkinfo-iptun-attrs
|
||||
@ -2204,6 +2294,12 @@ sub-messages:
|
||||
-
|
||||
value: vrf
|
||||
attribute-set: linkinfo-vrf-attrs
|
||||
-
|
||||
value: vti
|
||||
attribute-set: linkinfo-vti-attrs
|
||||
-
|
||||
value: vti6
|
||||
attribute-set: linkinfo-vti6-attrs
|
||||
-
|
||||
value: netkit
|
||||
attribute-set: linkinfo-netkit-attrs
|
||||
|
@ -177,6 +177,11 @@ attribute-sets:
|
||||
-
|
||||
name: rta-nh-id
|
||||
type: u32
|
||||
-
|
||||
name: rta-flowlabel
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
display-hint: hex
|
||||
-
|
||||
name: rta-metrics
|
||||
attributes:
|
||||
@ -260,6 +265,7 @@ operations:
|
||||
- rta-dport
|
||||
- rta-mark
|
||||
- rta-uid
|
||||
- rta-flowlabel
|
||||
reply:
|
||||
value: 24
|
||||
attributes: &all-route-attrs
|
||||
@ -299,6 +305,7 @@ operations:
|
||||
- rta-sport
|
||||
- rta-dport
|
||||
- rta-nh-id
|
||||
- rta-flowlabel
|
||||
dump:
|
||||
request:
|
||||
value: 26
|
||||
|
@ -172,6 +172,16 @@ attribute-sets:
|
||||
-
|
||||
name: dscp
|
||||
type: u8
|
||||
-
|
||||
name: flowlabel
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
display-hint: hex
|
||||
-
|
||||
name: flowlabel-mask
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
display-hint: hex
|
||||
|
||||
operations:
|
||||
enum-model: directional
|
||||
@ -203,6 +213,8 @@ operations:
|
||||
- sport-range
|
||||
- dport-range
|
||||
- dscp
|
||||
- flowlabel
|
||||
- flowlabel-mask
|
||||
-
|
||||
name: newrule-ntf
|
||||
doc: Notify a rule creation
|
||||
|
@ -1963,7 +1963,7 @@ obtain its hardware address from the first slave, which might not
|
||||
match the hardware address of the VLAN interfaces (which was
|
||||
ultimately copied from an earlier slave).
|
||||
|
||||
There are two methods to insure that the VLAN device operates
|
||||
There are two methods to ensure that the VLAN device operates
|
||||
with the correct hardware address if all slaves are removed from a
|
||||
bond interface:
|
||||
|
||||
@ -2078,7 +2078,7 @@ as an unsolicited ARP reply (because ARP matches replies on an
|
||||
interface basis), and is discarded. The MII monitor is not affected
|
||||
by the state of the routing table.
|
||||
|
||||
The solution here is simply to insure that slaves do not have
|
||||
The solution here is simply to ensure that slaves do not have
|
||||
routes of their own, and if for some reason they must, those routes do
|
||||
not supersede routes of their master. This should generally be the
|
||||
case, but unusual configurations or errant manual or automatic static
|
||||
@ -2295,7 +2295,7 @@ active-backup:
|
||||
the switches have an ISL and play together well. If the
|
||||
network configuration is such that one switch is specifically
|
||||
a backup switch (e.g., has lower capacity, higher cost, etc),
|
||||
then the primary option can be used to insure that the
|
||||
then the primary option can be used to ensure that the
|
||||
preferred link is always used when it is available.
|
||||
|
||||
broadcast:
|
||||
@ -2322,7 +2322,7 @@ monitor can provide a higher level of reliability in detecting end to
|
||||
end connectivity failures (which may be caused by the failure of any
|
||||
individual component to pass traffic for any reason). Additionally,
|
||||
the ARP monitor should be configured with multiple targets (at least
|
||||
one for each switch in the network). This will insure that,
|
||||
one for each switch in the network). This will ensure that,
|
||||
regardless of which switch is active, the ARP monitor has a suitable
|
||||
target to query.
|
||||
|
||||
|
@ -299,6 +299,18 @@ Use ethtool to view and set link-down-on-close, as follows::
|
||||
ethtool --show-priv-flags ethX
|
||||
ethtool --set-priv-flags ethX link-down-on-close [on|off]
|
||||
|
||||
Setting the mdd-auto-reset-vf Private Flag
|
||||
------------------------------------------
|
||||
|
||||
When the mdd-auto-reset-vf private flag is set to "on", the problematic VF will
|
||||
be automatically reset if a malformed descriptor is detected. If the flag is
|
||||
set to "off", the problematic VF will be disabled.
|
||||
|
||||
Use ethtool to view and set mdd-auto-reset-vf, as follows::
|
||||
|
||||
ethtool --show-priv-flags ethX
|
||||
ethtool --set-priv-flags ethX mdd-auto-reset-vf [on|off]
|
||||
|
||||
Viewing Link Messages
|
||||
---------------------
|
||||
Link messages will not be displayed to the console if the distribution is
|
||||
|
@ -237,6 +237,8 @@ Userspace to kernel:
|
||||
``ETHTOOL_MSG_MM_SET`` set MAC merge layer parameters
|
||||
``ETHTOOL_MSG_MODULE_FW_FLASH_ACT`` flash transceiver module firmware
|
||||
``ETHTOOL_MSG_PHY_GET`` get Ethernet PHY information
|
||||
``ETHTOOL_MSG_TSCONFIG_GET`` get hw timestamping configuration
|
||||
``ETHTOOL_MSG_TSCONFIG_SET`` set hw timestamping configuration
|
||||
===================================== =================================
|
||||
|
||||
Kernel to userspace:
|
||||
@ -286,6 +288,8 @@ Kernel to userspace:
|
||||
``ETHTOOL_MSG_MODULE_FW_FLASH_NTF`` transceiver module flash updates
|
||||
``ETHTOOL_MSG_PHY_GET_REPLY`` Ethernet PHY information
|
||||
``ETHTOOL_MSG_PHY_NTF`` Ethernet PHY information change
|
||||
``ETHTOOL_MSG_TSCONFIG_GET_REPLY`` hw timestamping configuration
|
||||
``ETHTOOL_MSG_TSCONFIG_SET_REPLY`` new hw timestamping configuration
|
||||
======================================== =================================
|
||||
|
||||
``GET`` requests are sent by userspace applications to retrieve device
|
||||
@ -1245,9 +1249,10 @@ Gets timestamping information like ``ETHTOOL_GET_TS_INFO`` ioctl request.
|
||||
|
||||
Request contents:
|
||||
|
||||
===================================== ====== ==========================
|
||||
``ETHTOOL_A_TSINFO_HEADER`` nested request header
|
||||
===================================== ====== ==========================
|
||||
======================================== ====== ============================
|
||||
``ETHTOOL_A_TSINFO_HEADER`` nested request header
|
||||
``ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER`` nested PTP hw clock provider
|
||||
======================================== ====== ============================
|
||||
|
||||
Kernel response contents:
|
||||
|
||||
@ -2243,6 +2248,75 @@ Kernel response contents:
|
||||
When ``ETHTOOL_A_PHY_UPSTREAM_TYPE`` is PHY_UPSTREAM_PHY, the PHY's parent is
|
||||
another PHY.
|
||||
|
||||
TSCONFIG_GET
|
||||
============
|
||||
|
||||
Retrieves the information about the current hardware timestamping source and
|
||||
configuration.
|
||||
|
||||
It is similar to the deprecated ``SIOCGHWTSTAMP`` ioctl request.
|
||||
|
||||
Request contents:
|
||||
|
||||
==================================== ====== ==========================
|
||||
``ETHTOOL_A_TSCONFIG_HEADER`` nested request header
|
||||
==================================== ====== ==========================
|
||||
|
||||
Kernel response contents:
|
||||
|
||||
======================================== ====== ============================
|
||||
``ETHTOOL_A_TSCONFIG_HEADER`` nested request header
|
||||
``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` nested PTP hw clock provider
|
||||
``ETHTOOL_A_TSCONFIG_TX_TYPES`` bitset hwtstamp Tx type
|
||||
``ETHTOOL_A_TSCONFIG_RX_FILTERS`` bitset hwtstamp Rx filter
|
||||
``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` u32 hwtstamp flags
|
||||
======================================== ====== ============================
|
||||
|
||||
When set the ``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` attribute identifies the
|
||||
source of the hw timestamping provider. It is composed by
|
||||
``ETHTOOL_A_TS_HWTSTAMP_PROVIDER_INDEX`` attribute which describe the index of
|
||||
the PTP device and ``ETHTOOL_A_TS_HWTSTAMP_PROVIDER_QUALIFIER`` which describe
|
||||
the qualifier of the timestamp.
|
||||
|
||||
When set the ``ETHTOOL_A_TSCONFIG_TX_TYPES``, ``ETHTOOL_A_TSCONFIG_RX_FILTERS``
|
||||
and the ``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` attributes identify the Tx
|
||||
type, the Rx filter and the flags configured for the current hw timestamping
|
||||
provider. The attributes are propagated to the driver through the following
|
||||
structure:
|
||||
|
||||
.. kernel-doc:: include/linux/net_tstamp.h
|
||||
:identifiers: kernel_hwtstamp_config
|
||||
|
||||
TSCONFIG_SET
|
||||
============
|
||||
|
||||
Set the information about the current hardware timestamping source and
|
||||
configuration.
|
||||
|
||||
It is similar to the deprecated ``SIOCSHWTSTAMP`` ioctl request.
|
||||
|
||||
Request contents:
|
||||
|
||||
======================================== ====== ============================
|
||||
``ETHTOOL_A_TSCONFIG_HEADER`` nested request header
|
||||
``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` nested PTP hw clock provider
|
||||
``ETHTOOL_A_TSCONFIG_TX_TYPES`` bitset hwtstamp Tx type
|
||||
``ETHTOOL_A_TSCONFIG_RX_FILTERS`` bitset hwtstamp Rx filter
|
||||
``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` u32 hwtstamp flags
|
||||
======================================== ====== ============================
|
||||
|
||||
Kernel response contents:
|
||||
|
||||
======================================== ====== ============================
|
||||
``ETHTOOL_A_TSCONFIG_HEADER`` nested request header
|
||||
``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` nested PTP hw clock provider
|
||||
``ETHTOOL_A_TSCONFIG_TX_TYPES`` bitset hwtstamp Tx type
|
||||
``ETHTOOL_A_TSCONFIG_RX_FILTERS`` bitset hwtstamp Rx filter
|
||||
``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` u32 hwtstamp flags
|
||||
======================================== ====== ============================
|
||||
|
||||
For a description of each attribute, see ``TSCONFIG_GET``.
|
||||
|
||||
Request translation
|
||||
===================
|
||||
|
||||
@ -2351,4 +2425,6 @@ are netlink only.
|
||||
n/a ``ETHTOOL_MSG_MM_SET``
|
||||
n/a ``ETHTOOL_MSG_MODULE_FW_FLASH_ACT``
|
||||
n/a ``ETHTOOL_MSG_PHY_GET``
|
||||
``SIOCGHWTSTAMP`` ``ETHTOOL_MSG_TSCONFIG_GET``
|
||||
``SIOCSHWTSTAMP`` ``ETHTOOL_MSG_TSCONFIG_SET``
|
||||
=================================== =====================================
|
||||
|
@ -72,7 +72,8 @@ exports a management (e.g. MLME) and data API.
|
||||
possibly with some kinds of acceleration like automatic CRC computation and
|
||||
comparison, automagic ACK handling, address matching, etc.
|
||||
|
||||
Those types of devices require different approach to be hooked into Linux kernel.
|
||||
Each type of device requires a different approach to be hooked into the Linux
|
||||
kernel.
|
||||
|
||||
HardMAC
|
||||
-------
|
||||
@ -81,10 +82,10 @@ See the header include/net/ieee802154_netdev.h. You have to implement Linux
|
||||
net_device, with .type = ARPHRD_IEEE802154. Data is exchanged with socket family
|
||||
code via plain sk_buffs. On skb reception skb->cb must contain additional
|
||||
info as described in the struct ieee802154_mac_cb. During packet transmission
|
||||
the skb->cb is used to provide additional data to device's header_ops->create
|
||||
function. Be aware that this data can be overridden later (when socket code
|
||||
submits skb to qdisc), so if you need something from that cb later, you should
|
||||
store info in the skb->data on your own.
|
||||
the skb->cb is used to provide additional data to the device's
|
||||
header_ops->create function. Be aware that this data can be overridden later
|
||||
(when socket code submits skb to qdisc), so if you need something from that cb
|
||||
later, you should store info in the skb->data on your own.
|
||||
|
||||
To hook the MLME interface you have to populate the ml_priv field of your
|
||||
net_device with a pointer to struct ieee802154_mlme_ops instance. The fields
|
||||
@ -94,8 +95,9 @@ All other fields are required.
|
||||
SoftMAC
|
||||
-------
|
||||
|
||||
The MAC is the middle layer in the IEEE 802.15.4 Linux stack. This moment it
|
||||
provides interface for drivers registration and management of slave interfaces.
|
||||
The MAC is the middle layer in the IEEE 802.15.4 Linux stack. At the moment, it
|
||||
provides an interface for driver registration and management of slave
|
||||
interfaces.
|
||||
|
||||
NOTE: Currently the only monitor device type is supported - it's IEEE 802.15.4
|
||||
stack interface for network sniffers (e.g. WireShark).
|
||||
|
@ -86,6 +86,7 @@ Contents:
|
||||
netdevices
|
||||
netfilter-sysctl
|
||||
netif-msg
|
||||
netmem
|
||||
nexthop-group-resilient
|
||||
nf_conntrack-sysctl
|
||||
nf_flowtable
|
||||
|
@ -1000,6 +1000,20 @@ tcp_tw_reuse - INTEGER
|
||||
|
||||
Default: 2
|
||||
|
||||
tcp_tw_reuse_delay - UNSIGNED INTEGER
|
||||
The delay in milliseconds before a TIME-WAIT socket can be reused by a
|
||||
new connection, if TIME-WAIT socket reuse is enabled. The actual reuse
|
||||
threshold is within [N, N+1] range, where N is the requested delay in
|
||||
milliseconds, to ensure the delay interval is never shorter than the
|
||||
configured value.
|
||||
|
||||
This setting contains an assumption about the other TCP timestamp clock
|
||||
tick interval. It should not be set to a value lower than the peer's
|
||||
clock tick for PAWS (Protection Against Wrapped Sequence numbers)
|
||||
mechanism work correctly for the reused connection.
|
||||
|
||||
Default: 1000 (milliseconds)
|
||||
|
||||
tcp_window_scaling - BOOLEAN
|
||||
Enable window scaling as defined in RFC1323.
|
||||
|
||||
|
@ -89,7 +89,7 @@ Observability
|
||||
=============
|
||||
The relation between PF, irq, napi, and queue can be observed via netlink spec::
|
||||
|
||||
$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump queue-get --json='{"ifindex": 13}'
|
||||
$ ./tools/net/ynl/pyynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump queue-get --json='{"ifindex": 13}'
|
||||
[{'id': 0, 'ifindex': 13, 'napi-id': 539, 'type': 'rx'},
|
||||
{'id': 1, 'ifindex': 13, 'napi-id': 540, 'type': 'rx'},
|
||||
{'id': 2, 'ifindex': 13, 'napi-id': 541, 'type': 'rx'},
|
||||
@ -101,7 +101,7 @@ The relation between PF, irq, napi, and queue can be observed via netlink spec::
|
||||
{'id': 3, 'ifindex': 13, 'napi-id': 542, 'type': 'tx'},
|
||||
{'id': 4, 'ifindex': 13, 'napi-id': 543, 'type': 'tx'}]
|
||||
|
||||
$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump napi-get --json='{"ifindex": 13}'
|
||||
$ ./tools/net/ynl/pyynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump napi-get --json='{"ifindex": 13}'
|
||||
[{'id': 543, 'ifindex': 13, 'irq': 42},
|
||||
{'id': 542, 'ifindex': 13, 'irq': 41},
|
||||
{'id': 541, 'ifindex': 13, 'irq': 40},
|
||||
|
@ -199,13 +199,13 @@ parameters mentioned above use hyphens instead of underscores:
|
||||
|
||||
Per-NAPI configuration can be done programmatically in a user application
|
||||
or by using a script included in the kernel source tree:
|
||||
``tools/net/ynl/cli.py``.
|
||||
``tools/net/ynl/pyynl/cli.py``.
|
||||
|
||||
For example, using the script:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ kernel-source/tools/net/ynl/cli.py \
|
||||
$ kernel-source/tools/net/ynl/pyynl/cli.py \
|
||||
--spec Documentation/netlink/specs/netdev.yaml \
|
||||
--do napi-set \
|
||||
--json='{"id": 345,
|
||||
|
@ -79,6 +79,7 @@ u8 sysctl_tcp_retries1
|
||||
u8 sysctl_tcp_retries2
|
||||
u8 sysctl_tcp_orphan_retries
|
||||
u8 sysctl_tcp_tw_reuse timewait_sock_ops
|
||||
unsigned_int sysctl_tcp_tw_reuse_delay timewait_sock_ops
|
||||
int sysctl_tcp_fin_timeout TCP_LAST_ACK/tcp_rcv_state_process
|
||||
unsigned_int sysctl_tcp_notsent_lowat read_mostly tcp_notsent_lowat/tcp_stream_memory_free
|
||||
u8 sysctl_tcp_sack tcp_syn_options
|
||||
|
@ -124,7 +124,7 @@ To remove a target::
|
||||
|
||||
The interface exposes these parameters of a netconsole target to userspace:
|
||||
|
||||
============== ================================= ============
|
||||
=============== ================================= ============
|
||||
enabled Is this target currently enabled? (read-write)
|
||||
extended Extended mode enabled (read-write)
|
||||
release Prepend kernel release to message (read-write)
|
||||
@ -135,7 +135,8 @@ The interface exposes these parameters of a netconsole target to userspace:
|
||||
remote_ip Remote agent's IP address (read-write)
|
||||
local_mac Local interface's MAC address (read-only)
|
||||
remote_mac Remote agent's MAC address (read-write)
|
||||
============== ================================= ============
|
||||
transmit_errors Number of packet send errors (read-only)
|
||||
=============== ================================= ============
|
||||
|
||||
The "enabled" attribute is also used to control whether the parameters of
|
||||
a target can be updated or not -- you can modify the parameters of only
|
||||
|
@ -297,3 +297,13 @@ napi->poll:
|
||||
Context:
|
||||
softirq
|
||||
will be called with interrupts disabled by netconsole.
|
||||
|
||||
NETDEV_INTERNAL symbol namespace
|
||||
================================
|
||||
|
||||
Symbols exported as NETDEV_INTERNAL can only be used in networking
|
||||
core and drivers which exclusively flow via the main networking list and trees.
|
||||
Note that the inverse is not true, most symbols outside of NETDEV_INTERNAL
|
||||
are not expected to be used by random code outside netdev either.
|
||||
Symbols may lack the designation because they predate the namespaces,
|
||||
or simply due to an oversight.
|
||||
|
@ -1,4 +1,4 @@
|
||||
SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
This file is populated during the build of the documentation (htmldocs) by the
|
||||
tools/net/ynl/ynl-gen-rst.py script.
|
||||
tools/net/ynl/pyynl/ynl_gen_rst.py script.
|
||||
|
79
Documentation/networking/netmem.rst
Normal file
79
Documentation/networking/netmem.rst
Normal file
@ -0,0 +1,79 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
==================================
|
||||
Netmem Support for Network Drivers
|
||||
==================================
|
||||
|
||||
This document outlines the requirements for network drivers to support netmem,
|
||||
an abstract memory type that enables features like device memory TCP. By
|
||||
supporting netmem, drivers can work with various underlying memory types
|
||||
with little to no modification.
|
||||
|
||||
Benefits of Netmem :
|
||||
|
||||
* Flexibility: Netmem can be backed by different memory types (e.g., struct
|
||||
page, DMA-buf), allowing drivers to support various use cases such as device
|
||||
memory TCP.
|
||||
* Future-proof: Drivers with netmem support are ready for upcoming
|
||||
features that rely on it.
|
||||
* Simplified Development: Drivers interact with a consistent API,
|
||||
regardless of the underlying memory implementation.
|
||||
|
||||
Driver Requirements
|
||||
===================
|
||||
|
||||
1. The driver must support page_pool.
|
||||
|
||||
2. The driver must support the tcp-data-split ethtool option.
|
||||
|
||||
3. The driver must use the page_pool netmem APIs for payload memory. The netmem
|
||||
APIs currently 1-to-1 correspond with page APIs. Conversion to netmem should
|
||||
be achievable by switching the page APIs to netmem APIs and tracking memory
|
||||
via netmem_refs in the driver rather than struct page * :
|
||||
|
||||
- page_pool_alloc -> page_pool_alloc_netmem
|
||||
- page_pool_get_dma_addr -> page_pool_get_dma_addr_netmem
|
||||
- page_pool_put_page -> page_pool_put_netmem
|
||||
|
||||
Not all page APIs have netmem equivalents at the moment. If your driver
|
||||
relies on a missing netmem API, feel free to add and propose to netdev@, or
|
||||
reach out to the maintainers and/or almasrymina@google.com for help adding
|
||||
the netmem API.
|
||||
|
||||
4. The driver must use the following PP_FLAGS:
|
||||
|
||||
- PP_FLAG_DMA_MAP: netmem is not dma-mappable by the driver. The driver
|
||||
must delegate the dma mapping to the page_pool, which knows when
|
||||
dma-mapping is (or is not) appropriate.
|
||||
- PP_FLAG_DMA_SYNC_DEV: netmem dma addr is not necessarily dma-syncable
|
||||
by the driver. The driver must delegate the dma syncing to the page_pool,
|
||||
which knows when dma-syncing is (or is not) appropriate.
|
||||
- PP_FLAG_ALLOW_UNREADABLE_NETMEM. The driver must specify this flag iff
|
||||
tcp-data-split is enabled.
|
||||
|
||||
5. The driver must not assume the netmem is readable and/or backed by pages.
|
||||
The netmem returned by the page_pool may be unreadable, in which case
|
||||
netmem_address() will return NULL. The driver must correctly handle
|
||||
unreadable netmem, i.e. don't attempt to handle its contents when
|
||||
netmem_address() is NULL.
|
||||
|
||||
Ideally, drivers should not have to check the underlying netmem type via
|
||||
helpers like netmem_is_net_iov() or convert the netmem to any of its
|
||||
underlying types via netmem_to_page() or netmem_to_net_iov(). In most cases,
|
||||
netmem or page_pool helpers that abstract this complexity are provided
|
||||
(and more can be added).
|
||||
|
||||
6. The driver must use page_pool_dma_sync_netmem_for_cpu() in lieu of
|
||||
dma_sync_single_range_for_cpu(). For some memory providers, dma_syncing for
|
||||
CPU will be done by the page_pool, for others (particularly dmabuf memory
|
||||
provider), dma syncing for CPU is the responsibility of the userspace using
|
||||
dmabuf APIs. The driver must delegate the entire dma-syncing operation to
|
||||
the page_pool which will do it correctly.
|
||||
|
||||
7. Avoid implementing driver-specific recycling on top of the page_pool. Drivers
|
||||
cannot hold onto a struct page to do their own recycling as the netmem may
|
||||
not be backed by a struct page. However, you may hold onto a page_pool
|
||||
reference with page_pool_fragment_netmem() or page_pool_ref_netmem() for
|
||||
that purpose, but be mindful that some netmem types might have longer
|
||||
circulation times, such as when userspace holds a reference in zerocopy
|
||||
scenarios.
|
@ -525,8 +525,8 @@ implicitly defined. ts[0] holds a software timestamp if set, ts[1]
|
||||
is again deprecated and ts[2] holds a hardware timestamp if set.
|
||||
|
||||
|
||||
3. Hardware Timestamping configuration: SIOCSHWTSTAMP and SIOCGHWTSTAMP
|
||||
=======================================================================
|
||||
3. Hardware Timestamping configuration: ETHTOOL_MSG_TSCONFIG_SET/GET
|
||||
====================================================================
|
||||
|
||||
Hardware time stamping must also be initialized for each device driver
|
||||
that is expected to do hardware time stamping. The parameter is defined in
|
||||
@ -539,12 +539,14 @@ include/uapi/linux/net_tstamp.h as::
|
||||
};
|
||||
|
||||
Desired behavior is passed into the kernel and to a specific device by
|
||||
calling ioctl(SIOCSHWTSTAMP) with a pointer to a struct ifreq whose
|
||||
ifr_data points to a struct hwtstamp_config. The tx_type and
|
||||
rx_filter are hints to the driver what it is expected to do. If
|
||||
the requested fine-grained filtering for incoming packets is not
|
||||
supported, the driver may time stamp more than just the requested types
|
||||
of packets.
|
||||
calling the tsconfig netlink socket ``ETHTOOL_MSG_TSCONFIG_SET``.
|
||||
The ``ETHTOOL_A_TSCONFIG_TX_TYPES``, ``ETHTOOL_A_TSCONFIG_RX_FILTERS`` and
|
||||
``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` netlink attributes are then used to set
|
||||
the struct hwtstamp_config accordingly.
|
||||
|
||||
The ``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` netlink nested attribute is used
|
||||
to select the source of the hardware time stamping. It is composed of an index
|
||||
for the device source and a qualifier for the type of time stamping.
|
||||
|
||||
Drivers are free to use a more permissive configuration than the requested
|
||||
configuration. It is expected that drivers should only implement directly the
|
||||
@ -563,9 +565,16 @@ Only a processes with admin rights may change the configuration. User
|
||||
space is responsible to ensure that multiple processes don't interfere
|
||||
with each other and that the settings are reset.
|
||||
|
||||
Any process can read the actual configuration by passing this
|
||||
structure to ioctl(SIOCGHWTSTAMP) in the same way. However, this has
|
||||
not been implemented in all drivers.
|
||||
Any process can read the actual configuration by requesting tsconfig netlink
|
||||
socket ``ETHTOOL_MSG_TSCONFIG_GET``.
|
||||
|
||||
The legacy configuration is the use of the ioctl(SIOCSHWTSTAMP) with a pointer
|
||||
to a struct ifreq whose ifr_data points to a struct hwtstamp_config.
|
||||
The tx_type and rx_filter are hints to the driver what it is expected to do.
|
||||
If the requested fine-grained filtering for incoming packets is not
|
||||
supported, the driver may time stamp more than just the requested types
|
||||
of packets. ioctl(SIOCGHWTSTAMP) is used in the same way as the
|
||||
ioctl(SIOCSHWTSTAMP). However, this has not been implemented in all drivers.
|
||||
|
||||
::
|
||||
|
||||
@ -610,9 +619,10 @@ not been implemented in all drivers.
|
||||
--------------------------------------------------------
|
||||
|
||||
A driver which supports hardware time stamping must support the
|
||||
SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with
|
||||
the actual values as described in the section on SIOCSHWTSTAMP. It
|
||||
should also support SIOCGHWTSTAMP.
|
||||
ndo_hwtstamp_set NDO or the legacy SIOCSHWTSTAMP ioctl and update the
|
||||
supplied struct hwtstamp_config with the actual values as described in
|
||||
the section on SIOCSHWTSTAMP. It should also support ndo_hwtstamp_get or
|
||||
the legacy SIOCGHWTSTAMP.
|
||||
|
||||
Time stamps for received packets must be stored in the skb. To get a pointer
|
||||
to the shared time stamp structure of the skb call skb_hwtstamps(). Then
|
||||
|
@ -200,6 +200,32 @@ received without a cmsg buffer set.
|
||||
|
||||
recv will never return data from mixed types of TLS records.
|
||||
|
||||
TLS 1.3 Key Updates
|
||||
-------------------
|
||||
|
||||
In TLS 1.3, KeyUpdate handshake messages signal that the sender is
|
||||
updating its TX key. Any message sent after a KeyUpdate will be
|
||||
encrypted using the new key. The userspace library can pass the new
|
||||
key to the kernel using the TLS_TX and TLS_RX socket options, as for
|
||||
the initial keys. TLS version and cipher cannot be changed.
|
||||
|
||||
To prevent attempting to decrypt incoming records using the wrong key,
|
||||
decryption will be paused when a KeyUpdate message is received by the
|
||||
kernel, until the new key has been provided using the TLS_RX socket
|
||||
option. Any read occurring after the KeyUpdate has been read and
|
||||
before the new key is provided will fail with EKEYEXPIRED. poll() will
|
||||
not report any read events from the socket until the new key is
|
||||
provided. There is no pausing on the transmit side.
|
||||
|
||||
Userspace should make sure that the crypto_info provided has been set
|
||||
properly. In particular, the kernel will not check for key/nonce
|
||||
reuse.
|
||||
|
||||
The number of successful and failed key updates is tracked in the
|
||||
``TlsTxRekeyOk``, ``TlsRxRekeyOk``, ``TlsTxRekeyError``,
|
||||
``TlsRxRekeyError`` statistics. The ``TlsRxRekeyReceived`` statistic
|
||||
counts KeyUpdate handshake messages that have been received.
|
||||
|
||||
Integrating in to userspace TLS library
|
||||
---------------------------------------
|
||||
|
||||
@ -286,3 +312,13 @@ TLS implementation exposes the following per-namespace statistics
|
||||
- ``TlsRxNoPadViolation`` -
|
||||
number of data RX records which had to be re-decrypted due to
|
||||
``TLS_RX_EXPECT_NO_PAD`` mis-prediction.
|
||||
|
||||
- ``TlsTxRekeyOk``, ``TlsRxRekeyOk`` -
|
||||
number of successful rekeys on existing sessions for TX and RX
|
||||
|
||||
- ``TlsTxRekeyError``, ``TlsRxRekeyError`` -
|
||||
number of failed rekeys on existing sessions for TX and RX
|
||||
|
||||
- ``TlsRxRekeyReceived`` -
|
||||
number of received KeyUpdate handshake messages, requiring userspace
|
||||
to provide a new RX key
|
||||
|
@ -169,7 +169,8 @@ the stack in xfrm_input().
|
||||
|
||||
hand the packet to napi_gro_receive() as usual
|
||||
|
||||
In ESN mode, xdo_dev_state_advance_esn() is called from xfrm_replay_advance_esn().
|
||||
In ESN mode, xdo_dev_state_advance_esn() is called from
|
||||
xfrm_replay_advance_esn() for RX, and xfrm_replay_overflow_offload_esn for TX.
|
||||
Driver will check packet seq number and update HW ESN state machine if needed.
|
||||
|
||||
Packet offload mode:
|
||||
|
@ -56,7 +56,9 @@ If ``name-prefix`` is specified it replaces the ``$family-$enum``
|
||||
portion of the entry name.
|
||||
|
||||
Boolean ``render-max`` controls creation of the max values
|
||||
(which are enabled by default for attribute enums).
|
||||
(which are enabled by default for attribute enums). These max
|
||||
values are named ``__$pfx-MAX`` and ``$pfx-MAX``. The name
|
||||
of the first value can be overridden via ``enum-cnt-name`` property.
|
||||
|
||||
Attributes
|
||||
==========
|
||||
|
@ -15,7 +15,7 @@ developing Netlink related code. The tool is implemented in Python
|
||||
and can use a YAML specification to issue Netlink requests
|
||||
to the kernel. Only Generic Netlink is supported.
|
||||
|
||||
The tool is located at ``tools/net/ynl/cli.py``. It accepts
|
||||
The tool is located at ``tools/net/ynl/pyynl/cli.py``. It accepts
|
||||
a handul of arguments, the most important ones are:
|
||||
|
||||
- ``--spec`` - point to the spec file
|
||||
@ -27,7 +27,7 @@ YAML specs can be found under ``Documentation/netlink/specs/``.
|
||||
|
||||
Example use::
|
||||
|
||||
$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/ethtool.yaml \
|
||||
$ ./tools/net/ynl/pyynl/cli.py --spec Documentation/netlink/specs/ethtool.yaml \
|
||||
--do rings-get \
|
||||
--json '{"header":{"dev-index": 18}}'
|
||||
{'header': {'dev-index': 18, 'dev-name': 'eni1np1'},
|
||||
@ -75,7 +75,7 @@ the two marker lines like above to a file, add that file to git,
|
||||
and run the regeneration tool. Grep the tree for ``YNL-GEN``
|
||||
to see other examples.
|
||||
|
||||
The code generation itself is performed by ``tools/net/ynl/ynl-gen-c.py``
|
||||
The code generation itself is performed by ``tools/net/ynl/pyynl/ynl_gen_c.py``
|
||||
but it takes a few arguments so calling it directly for each file
|
||||
quickly becomes tedious.
|
||||
|
||||
@ -84,7 +84,7 @@ YNL lib
|
||||
|
||||
``tools/net/ynl/lib/`` contains an implementation of a C library
|
||||
(based on libmnl) which integrates with code generated by
|
||||
``tools/net/ynl/ynl-gen-c.py`` to create easy to use netlink wrappers.
|
||||
``tools/net/ynl/pyynl/ynl_gen_c.py`` to create easy to use netlink wrappers.
|
||||
|
||||
YNL basics
|
||||
----------
|
||||
|
17
MAINTAINERS
17
MAINTAINERS
@ -2843,6 +2843,13 @@ S: Maintained
|
||||
F: arch/arm64/boot/dts/freescale/s32g*.dts*
|
||||
F: drivers/pinctrl/nxp/
|
||||
|
||||
ARM/NXP S32G/S32R DWMAC ETHERNET DRIVER
|
||||
M: Jan Petrous <jan.petrous@oss.nxp.com>
|
||||
L: NXP S32 Linux Team <s32@nxp.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
|
||||
F: drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
|
||||
|
||||
ARM/Orion SoC/Technologic Systems TS-78xx platform support
|
||||
M: Alexander Clouter <alex@digriz.org.uk>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
@ -4610,6 +4617,7 @@ F: drivers/net/ethernet/broadcom/bnx2x/
|
||||
|
||||
BROADCOM BNXT_EN 50 GIGABIT ETHERNET DRIVER
|
||||
M: Michael Chan <michael.chan@broadcom.com>
|
||||
M: Pavan Chebbi <pavan.chebbi@broadcom.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/firmware/broadcom/tee_bnxt_fw.c
|
||||
@ -5116,6 +5124,7 @@ F: include/uapi/linux/can/gw.h
|
||||
F: include/uapi/linux/can/isotp.h
|
||||
F: include/uapi/linux/can/raw.h
|
||||
F: net/can/
|
||||
F: net/sched/em_canid.c
|
||||
|
||||
CAN-J1939 NETWORK LAYER
|
||||
M: Robin van der Gracht <robin@protonic.nl>
|
||||
@ -10301,7 +10310,6 @@ F: drivers/input/touchscreen/himax_hx83112b.c
|
||||
|
||||
HIPPI
|
||||
M: Jes Sorensen <jes@trained-monkey.org>
|
||||
L: linux-hippi@sunsite.dk
|
||||
S: Maintained
|
||||
F: drivers/net/hippi/
|
||||
F: include/linux/hippidevice.h
|
||||
@ -13978,6 +13986,7 @@ M: Sunil Goutham <sgoutham@marvell.com>
|
||||
M: Geetha sowjanya <gakula@marvell.com>
|
||||
M: Subbaraya Sundeep <sbhatta@marvell.com>
|
||||
M: hariprasad <hkelam@marvell.com>
|
||||
M: Bharat Bhushan <bbhushan2@marvell.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/ethernet/marvell/octeontx2/nic/
|
||||
@ -16215,7 +16224,8 @@ M: Breno Leitao <leitao@debian.org>
|
||||
S: Maintained
|
||||
F: Documentation/networking/netconsole.rst
|
||||
F: drivers/net/netconsole.c
|
||||
F: tools/testing/selftests/drivers/net/netcons_basic.sh
|
||||
F: tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
|
||||
F: tools/testing/selftests/drivers/net/netcons\*
|
||||
|
||||
NETDEVSIM
|
||||
M: Jakub Kicinski <kuba@kernel.org>
|
||||
@ -16331,7 +16341,7 @@ F: include/linux/inetdevice.h
|
||||
F: include/linux/netdev*
|
||||
F: include/linux/platform_data/wiznet.h
|
||||
F: include/uapi/linux/cn_proc.h
|
||||
F: include/uapi/linux/ethtool_netlink.h
|
||||
F: include/uapi/linux/ethtool_netlink*
|
||||
F: include/uapi/linux/if_*
|
||||
F: include/uapi/linux/net_shaper.h
|
||||
F: include/uapi/linux/netdev*
|
||||
@ -17689,6 +17699,7 @@ F: Documentation/core-api/packing.rst
|
||||
F: include/linux/packing.h
|
||||
F: lib/packing.c
|
||||
F: lib/packing_test.c
|
||||
F: scripts/gen_packed_field_checks.c
|
||||
|
||||
PADATA PARALLEL EXECUTION MECHANISM
|
||||
M: Steffen Klassert <steffen.klassert@secunet.com>
|
||||
|
4
Makefile
4
Makefile
@ -1367,6 +1367,10 @@ PHONY += scripts_unifdef
|
||||
scripts_unifdef: scripts_basic
|
||||
$(Q)$(MAKE) $(build)=scripts scripts/unifdef
|
||||
|
||||
PHONY += scripts_gen_packed_field_checks
|
||||
scripts_gen_packed_field_checks: scripts_basic
|
||||
$(Q)$(MAKE) $(build)=scripts scripts/gen_packed_field_checks
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Install
|
||||
|
||||
|
@ -148,6 +148,8 @@
|
||||
|
||||
#define SCM_TS_OPT_ID 81
|
||||
|
||||
#define SO_RCVPRIORITY 82
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
@ -159,6 +159,8 @@
|
||||
|
||||
#define SCM_TS_OPT_ID 81
|
||||
|
||||
#define SO_RCVPRIORITY 82
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
@ -140,6 +140,8 @@
|
||||
|
||||
#define SCM_TS_OPT_ID 0x404C
|
||||
|
||||
#define SO_RCVPRIORITY 0x404D
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
@ -141,6 +141,8 @@
|
||||
|
||||
#define SCM_TS_OPT_ID 0x005a
|
||||
|
||||
#define SO_RCVPRIORITY 0x005b
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
|
||||
|
@ -943,7 +943,7 @@ int mlx5_ib_fs_add_op_fc(struct mlx5_ib_dev *dev, u32 port_num,
|
||||
}
|
||||
|
||||
dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
|
||||
dst.counter_id = mlx5_fc_id(opfc->fc);
|
||||
dst.counter = opfc->fc;
|
||||
|
||||
flow_act.action =
|
||||
MLX5_FLOW_CONTEXT_ACTION_COUNT | MLX5_FLOW_CONTEXT_ACTION_ALLOW;
|
||||
@ -1113,8 +1113,8 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
|
||||
handler->ibcounters = flow_act.counters;
|
||||
dest_arr[dest_num].type =
|
||||
MLX5_FLOW_DESTINATION_TYPE_COUNTER;
|
||||
dest_arr[dest_num].counter_id =
|
||||
mlx5_fc_id(mcounters->hw_cntrs_hndl);
|
||||
dest_arr[dest_num].counter =
|
||||
mcounters->hw_cntrs_hndl;
|
||||
dest_num++;
|
||||
}
|
||||
|
||||
@ -1603,7 +1603,7 @@ static bool raw_fs_is_multicast(struct mlx5_ib_flow_matcher *fs_matcher,
|
||||
static struct mlx5_ib_flow_handler *raw_fs_rule_add(
|
||||
struct mlx5_ib_dev *dev, struct mlx5_ib_flow_matcher *fs_matcher,
|
||||
struct mlx5_flow_context *flow_context, struct mlx5_flow_act *flow_act,
|
||||
u32 counter_id, void *cmd_in, int inlen, int dest_id, int dest_type)
|
||||
struct mlx5_fc *counter, void *cmd_in, int inlen, int dest_id, int dest_type)
|
||||
{
|
||||
struct mlx5_flow_destination *dst;
|
||||
struct mlx5_ib_flow_prio *ft_prio;
|
||||
@ -1652,8 +1652,12 @@ static struct mlx5_ib_flow_handler *raw_fs_rule_add(
|
||||
}
|
||||
|
||||
if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
|
||||
if (WARN_ON(!counter)) {
|
||||
err = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
|
||||
dst[dst_num].counter_id = counter_id;
|
||||
dst[dst_num].counter = counter;
|
||||
dst_num++;
|
||||
}
|
||||
|
||||
@ -1878,7 +1882,8 @@ static int get_dests(struct uverbs_attr_bundle *attrs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_flow_counter(void *obj, u32 offset, u32 *counter_id)
|
||||
static bool
|
||||
is_flow_counter(void *obj, u32 offset, u32 *counter_id, u32 *fc_bulk_size)
|
||||
{
|
||||
struct devx_obj *devx_obj = obj;
|
||||
u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);
|
||||
@ -1888,6 +1893,7 @@ static bool is_flow_counter(void *obj, u32 offset, u32 *counter_id)
|
||||
if (offset && offset >= devx_obj->flow_counter_bulk_size)
|
||||
return false;
|
||||
|
||||
*fc_bulk_size = devx_obj->flow_counter_bulk_size;
|
||||
*counter_id = MLX5_GET(dealloc_flow_counter_in,
|
||||
devx_obj->dinbox,
|
||||
flow_counter_id);
|
||||
@ -1904,13 +1910,13 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
|
||||
{
|
||||
struct mlx5_flow_context flow_context = {.flow_tag =
|
||||
MLX5_FS_DEFAULT_FLOW_TAG};
|
||||
u32 *offset_attr, offset = 0, counter_id = 0;
|
||||
int dest_id, dest_type = -1, inlen, len, ret, i;
|
||||
struct mlx5_ib_flow_handler *flow_handler;
|
||||
struct mlx5_ib_flow_matcher *fs_matcher;
|
||||
struct ib_uobject **arr_flow_actions;
|
||||
struct ib_uflow_resources *uflow_res;
|
||||
struct mlx5_flow_act flow_act = {};
|
||||
struct mlx5_fc *counter = NULL;
|
||||
struct ib_qp *qp = NULL;
|
||||
void *devx_obj, *cmd_in;
|
||||
struct ib_uobject *uobj;
|
||||
@ -1937,6 +1943,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
|
||||
len = uverbs_attr_get_uobjs_arr(attrs,
|
||||
MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX, &arr_flow_actions);
|
||||
if (len) {
|
||||
u32 *offset_attr, fc_bulk_size, offset = 0, counter_id = 0;
|
||||
devx_obj = arr_flow_actions[0]->object;
|
||||
|
||||
if (uverbs_attr_is_valid(attrs,
|
||||
@ -1956,8 +1963,11 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
|
||||
offset = *offset_attr;
|
||||
}
|
||||
|
||||
if (!is_flow_counter(devx_obj, offset, &counter_id))
|
||||
if (!is_flow_counter(devx_obj, offset, &counter_id, &fc_bulk_size))
|
||||
return -EINVAL;
|
||||
counter = mlx5_fc_local_create(counter_id, offset, fc_bulk_size);
|
||||
if (IS_ERR(counter))
|
||||
return PTR_ERR(counter);
|
||||
|
||||
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
|
||||
}
|
||||
@ -1968,8 +1978,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
|
||||
MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE);
|
||||
|
||||
uflow_res = flow_resources_alloc(MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS);
|
||||
if (!uflow_res)
|
||||
return -ENOMEM;
|
||||
if (!uflow_res) {
|
||||
ret = -ENOMEM;
|
||||
goto destroy_counter;
|
||||
}
|
||||
|
||||
len = uverbs_attr_get_uobjs_arr(attrs,
|
||||
MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS, &arr_flow_actions);
|
||||
@ -1996,7 +2008,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
|
||||
|
||||
flow_handler =
|
||||
raw_fs_rule_add(dev, fs_matcher, &flow_context, &flow_act,
|
||||
counter_id, cmd_in, inlen, dest_id, dest_type);
|
||||
counter, cmd_in, inlen, dest_id, dest_type);
|
||||
if (IS_ERR(flow_handler)) {
|
||||
ret = PTR_ERR(flow_handler);
|
||||
goto err_out;
|
||||
@ -2007,6 +2019,9 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
|
||||
return 0;
|
||||
err_out:
|
||||
ib_uverbs_flow_resources_free(uflow_res);
|
||||
destroy_counter:
|
||||
if (counter)
|
||||
mlx5_fc_local_destroy(counter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -294,20 +294,6 @@ get_Bprotocol4mask(u_int m)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct Bprotocol *
|
||||
get_Bprotocol4id(u_int id)
|
||||
{
|
||||
u_int m;
|
||||
|
||||
if (id < ISDN_P_B_START || id > 63) {
|
||||
printk(KERN_WARNING "%s id not in range %d\n",
|
||||
__func__, id);
|
||||
return NULL;
|
||||
}
|
||||
m = 1 << (id & ISDN_P_B_MASK);
|
||||
return get_Bprotocol4mask(m);
|
||||
}
|
||||
|
||||
int
|
||||
mISDN_register_Bprotocol(struct Bprotocol *bp)
|
||||
{
|
||||
|
@ -55,7 +55,6 @@ extern void __add_layer2(struct mISDNchannel *, struct mISDNstack *);
|
||||
|
||||
extern u_int get_all_Bprotocols(void);
|
||||
struct Bprotocol *get_Bprotocol4mask(u_int);
|
||||
struct Bprotocol *get_Bprotocol4id(u_int);
|
||||
|
||||
extern int mISDN_inittimer(u_int *);
|
||||
extern void mISDN_timer_cleanup(void);
|
||||
|
@ -84,7 +84,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
|
||||
|
||||
if (skb_copy_bits(skb, BAREUDP_BASE_HLEN, &ipversion,
|
||||
sizeof(ipversion))) {
|
||||
dev_core_stats_rx_dropped_inc(bareudp->dev);
|
||||
dev_dstats_rx_dropped(bareudp->dev);
|
||||
goto drop;
|
||||
}
|
||||
ipversion >>= 4;
|
||||
@ -94,7 +94,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
|
||||
} else if (ipversion == 6 && bareudp->multi_proto_mode) {
|
||||
proto = htons(ETH_P_IPV6);
|
||||
} else {
|
||||
dev_core_stats_rx_dropped_inc(bareudp->dev);
|
||||
dev_dstats_rx_dropped(bareudp->dev);
|
||||
goto drop;
|
||||
}
|
||||
} else if (bareudp->ethertype == htons(ETH_P_MPLS_UC)) {
|
||||
@ -108,7 +108,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
|
||||
ipv4_is_multicast(tunnel_hdr->daddr)) {
|
||||
proto = htons(ETH_P_MPLS_MC);
|
||||
} else {
|
||||
dev_core_stats_rx_dropped_inc(bareudp->dev);
|
||||
dev_dstats_rx_dropped(bareudp->dev);
|
||||
goto drop;
|
||||
}
|
||||
} else {
|
||||
@ -124,7 +124,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
|
||||
(addr_type & IPV6_ADDR_MULTICAST)) {
|
||||
proto = htons(ETH_P_MPLS_MC);
|
||||
} else {
|
||||
dev_core_stats_rx_dropped_inc(bareudp->dev);
|
||||
dev_dstats_rx_dropped(bareudp->dev);
|
||||
goto drop;
|
||||
}
|
||||
}
|
||||
@ -136,7 +136,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
|
||||
proto,
|
||||
!net_eq(bareudp->net,
|
||||
dev_net(bareudp->dev)))) {
|
||||
dev_core_stats_rx_dropped_inc(bareudp->dev);
|
||||
dev_dstats_rx_dropped(bareudp->dev);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
|
||||
|
||||
tun_dst = udp_tun_rx_dst(skb, family, key, 0, 0);
|
||||
if (!tun_dst) {
|
||||
dev_core_stats_rx_dropped_inc(bareudp->dev);
|
||||
dev_dstats_rx_dropped(bareudp->dev);
|
||||
goto drop;
|
||||
}
|
||||
skb_dst_set(skb, &tun_dst->dst);
|
||||
@ -194,7 +194,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
|
||||
len = skb->len;
|
||||
err = gro_cells_receive(&bareudp->gro_cells, skb);
|
||||
if (likely(err == NET_RX_SUCCESS))
|
||||
dev_sw_netstats_rx_add(bareudp->dev, len);
|
||||
dev_dstats_rx_add(bareudp->dev, len);
|
||||
|
||||
return 0;
|
||||
drop:
|
||||
@ -589,7 +589,7 @@ static void bareudp_setup(struct net_device *dev)
|
||||
dev->priv_flags |= IFF_NO_QUEUE;
|
||||
dev->lltx = true;
|
||||
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
|
||||
dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
|
||||
dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS;
|
||||
}
|
||||
|
||||
static int bareudp_validate(struct nlattr *tb[], struct nlattr *data[],
|
||||
|
@ -85,8 +85,6 @@ const char *can_get_state_str(const enum can_state state)
|
||||
default:
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
return "<unknown>";
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(can_get_state_str);
|
||||
|
||||
|
@ -999,7 +999,8 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
|
||||
can->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY |
|
||||
CAN_CTRLMODE_FD |
|
||||
CAN_CTRLMODE_FD_NON_ISO |
|
||||
CAN_CTRLMODE_CC_LEN8_DLC;
|
||||
CAN_CTRLMODE_CC_LEN8_DLC |
|
||||
CAN_CTRLMODE_BERR_REPORTING;
|
||||
|
||||
status = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_STAT_REG);
|
||||
if (!(status & KVASER_PCIEFD_KCAN_STAT_FD)) {
|
||||
@ -1234,11 +1235,15 @@ static int kvaser_pciefd_handle_data_packet(struct kvaser_pciefd *pcie,
|
||||
}
|
||||
|
||||
static void kvaser_pciefd_change_state(struct kvaser_pciefd_can *can,
|
||||
const struct can_berr_counter *bec,
|
||||
struct can_frame *cf,
|
||||
enum can_state new_state,
|
||||
enum can_state tx_state,
|
||||
enum can_state rx_state)
|
||||
{
|
||||
enum can_state old_state;
|
||||
|
||||
old_state = can->can.state;
|
||||
can_change_state(can->can.dev, cf, tx_state, rx_state);
|
||||
|
||||
if (new_state == CAN_STATE_BUS_OFF) {
|
||||
@ -1254,6 +1259,18 @@ static void kvaser_pciefd_change_state(struct kvaser_pciefd_can *can,
|
||||
can_bus_off(ndev);
|
||||
}
|
||||
}
|
||||
if (old_state == CAN_STATE_BUS_OFF &&
|
||||
new_state == CAN_STATE_ERROR_ACTIVE &&
|
||||
can->can.restart_ms) {
|
||||
can->can.can_stats.restarts++;
|
||||
if (cf)
|
||||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
}
|
||||
if (cf && new_state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = bec->txerr;
|
||||
cf->data[7] = bec->rxerr;
|
||||
}
|
||||
}
|
||||
|
||||
static void kvaser_pciefd_packet_to_state(struct kvaser_pciefd_rx_packet *p,
|
||||
@ -1288,7 +1305,7 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
|
||||
struct can_berr_counter bec;
|
||||
enum can_state old_state, new_state, tx_state, rx_state;
|
||||
struct net_device *ndev = can->can.dev;
|
||||
struct sk_buff *skb;
|
||||
struct sk_buff *skb = NULL;
|
||||
struct can_frame *cf = NULL;
|
||||
|
||||
old_state = can->can.state;
|
||||
@ -1297,16 +1314,10 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
|
||||
bec.rxerr = FIELD_GET(KVASER_PCIEFD_SPACK_RXERR_MASK, p->header[0]);
|
||||
|
||||
kvaser_pciefd_packet_to_state(p, &bec, &new_state, &tx_state, &rx_state);
|
||||
skb = alloc_can_err_skb(ndev, &cf);
|
||||
if (can->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
|
||||
skb = alloc_can_err_skb(ndev, &cf);
|
||||
if (new_state != old_state) {
|
||||
kvaser_pciefd_change_state(can, cf, new_state, tx_state, rx_state);
|
||||
if (old_state == CAN_STATE_BUS_OFF &&
|
||||
new_state == CAN_STATE_ERROR_ACTIVE &&
|
||||
can->can.restart_ms) {
|
||||
can->can.can_stats.restarts++;
|
||||
if (skb)
|
||||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
}
|
||||
kvaser_pciefd_change_state(can, &bec, cf, new_state, tx_state, rx_state);
|
||||
}
|
||||
|
||||
can->err_rep_cnt++;
|
||||
@ -1319,18 +1330,19 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
|
||||
can->bec.txerr = bec.txerr;
|
||||
can->bec.rxerr = bec.rxerr;
|
||||
|
||||
if (!skb) {
|
||||
ndev->stats.rx_dropped++;
|
||||
return -ENOMEM;
|
||||
if (can->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
|
||||
if (!skb) {
|
||||
netdev_warn(ndev, "No memory left for err_skb\n");
|
||||
ndev->stats.rx_dropped++;
|
||||
return -ENOMEM;
|
||||
}
|
||||
kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
|
||||
cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
|
||||
cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
|
||||
netif_rx(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1359,6 +1371,7 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
|
||||
{
|
||||
struct can_berr_counter bec;
|
||||
enum can_state old_state, new_state, tx_state, rx_state;
|
||||
int ret = 0;
|
||||
|
||||
old_state = can->can.state;
|
||||
|
||||
@ -1372,25 +1385,15 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
|
||||
struct can_frame *cf;
|
||||
|
||||
skb = alloc_can_err_skb(ndev, &cf);
|
||||
if (!skb) {
|
||||
kvaser_pciefd_change_state(can, &bec, cf, new_state, tx_state, rx_state);
|
||||
if (skb) {
|
||||
kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
|
||||
netif_rx(skb);
|
||||
} else {
|
||||
ndev->stats.rx_dropped++;
|
||||
return -ENOMEM;
|
||||
netdev_warn(ndev, "No memory left for err_skb\n");
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
|
||||
kvaser_pciefd_change_state(can, cf, new_state, tx_state, rx_state);
|
||||
if (old_state == CAN_STATE_BUS_OFF &&
|
||||
new_state == CAN_STATE_ERROR_ACTIVE &&
|
||||
can->can.restart_ms) {
|
||||
can->can.can_stats.restarts++;
|
||||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
}
|
||||
|
||||
kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
|
||||
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
|
||||
netif_rx(skb);
|
||||
}
|
||||
can->bec.txerr = bec.txerr;
|
||||
can->bec.rxerr = bec.rxerr;
|
||||
@ -1398,7 +1401,7 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
|
||||
if (bec.txerr || bec.rxerr)
|
||||
mod_timer(&can->bec_poll_timer, KVASER_PCIEFD_BEC_POLL_FREQ);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int kvaser_pciefd_handle_status_packet(struct kvaser_pciefd *pcie,
|
||||
|
@ -1785,6 +1785,13 @@ static void m_can_stop(struct net_device *dev)
|
||||
|
||||
/* set the state as STOPPED */
|
||||
cdev->can.state = CAN_STATE_STOPPED;
|
||||
|
||||
if (cdev->ops->deinit) {
|
||||
ret = cdev->ops->deinit(cdev);
|
||||
if (ret)
|
||||
netdev_err(dev, "failed to deinitialize: %pe\n",
|
||||
ERR_PTR(ret));
|
||||
}
|
||||
}
|
||||
|
||||
static int m_can_close(struct net_device *dev)
|
||||
@ -2466,6 +2473,7 @@ int m_can_class_suspend(struct device *dev)
|
||||
{
|
||||
struct m_can_classdev *cdev = dev_get_drvdata(dev);
|
||||
struct net_device *ndev = cdev->net;
|
||||
int ret = 0;
|
||||
|
||||
if (netif_running(ndev)) {
|
||||
netif_stop_queue(ndev);
|
||||
@ -2478,6 +2486,9 @@ int m_can_class_suspend(struct device *dev)
|
||||
if (cdev->pm_wake_source) {
|
||||
hrtimer_cancel(&cdev->hrtimer);
|
||||
m_can_write(cdev, M_CAN_IE, IR_RF0N);
|
||||
|
||||
if (cdev->ops->deinit)
|
||||
ret = cdev->ops->deinit(cdev);
|
||||
} else {
|
||||
m_can_stop(ndev);
|
||||
}
|
||||
@ -2489,7 +2500,7 @@ int m_can_class_suspend(struct device *dev)
|
||||
|
||||
cdev->can.state = CAN_STATE_SLEEPING;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(m_can_class_suspend);
|
||||
|
||||
@ -2497,14 +2508,13 @@ int m_can_class_resume(struct device *dev)
|
||||
{
|
||||
struct m_can_classdev *cdev = dev_get_drvdata(dev);
|
||||
struct net_device *ndev = cdev->net;
|
||||
int ret = 0;
|
||||
|
||||
pinctrl_pm_select_default_state(dev);
|
||||
|
||||
cdev->can.state = CAN_STATE_ERROR_ACTIVE;
|
||||
|
||||
if (netif_running(ndev)) {
|
||||
int ret;
|
||||
|
||||
ret = m_can_clk_start(cdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -2517,6 +2527,10 @@ int m_can_class_resume(struct device *dev)
|
||||
* again.
|
||||
*/
|
||||
cdev->active_interrupts |= IR_RF0N | IR_TEFN;
|
||||
|
||||
if (cdev->ops->init)
|
||||
ret = cdev->ops->init(cdev);
|
||||
|
||||
m_can_write(cdev, M_CAN_IE, cdev->active_interrupts);
|
||||
} else {
|
||||
ret = m_can_start(ndev);
|
||||
@ -2530,7 +2544,7 @@ int m_can_class_resume(struct device *dev)
|
||||
netif_start_queue(ndev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(m_can_class_resume);
|
||||
|
||||
|
@ -68,6 +68,7 @@ struct m_can_ops {
|
||||
int (*write_fifo)(struct m_can_classdev *cdev, int addr_offset,
|
||||
const void *val, size_t val_count);
|
||||
int (*init)(struct m_can_classdev *cdev);
|
||||
int (*deinit)(struct m_can_classdev *cdev);
|
||||
};
|
||||
|
||||
struct m_can_tx_op {
|
||||
|
@ -92,6 +92,8 @@
|
||||
#define TCAN4X5X_MODE_STANDBY BIT(6)
|
||||
#define TCAN4X5X_MODE_NORMAL BIT(7)
|
||||
|
||||
#define TCAN4X5X_NWKRQ_VOLTAGE_VIO BIT(19)
|
||||
|
||||
#define TCAN4X5X_DISABLE_WAKE_MSK (BIT(31) | BIT(30))
|
||||
#define TCAN4X5X_DISABLE_INH_MSK BIT(9)
|
||||
|
||||
@ -267,9 +269,24 @@ static int tcan4x5x_init(struct m_can_classdev *cdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (tcan4x5x->nwkrq_voltage_vio) {
|
||||
ret = regmap_set_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG,
|
||||
TCAN4X5X_NWKRQ_VOLTAGE_VIO);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tcan4x5x_deinit(struct m_can_classdev *cdev)
|
||||
{
|
||||
struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev);
|
||||
|
||||
return regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG,
|
||||
TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_STANDBY);
|
||||
};
|
||||
|
||||
static int tcan4x5x_disable_wake(struct m_can_classdev *cdev)
|
||||
{
|
||||
struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev);
|
||||
@ -318,6 +335,14 @@ static const struct tcan4x5x_version_info
|
||||
return &tcan4x5x_versions[TCAN4X5X];
|
||||
}
|
||||
|
||||
static void tcan4x5x_get_dt_data(struct m_can_classdev *cdev)
|
||||
{
|
||||
struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev);
|
||||
|
||||
tcan4x5x->nwkrq_voltage_vio =
|
||||
of_property_read_bool(cdev->dev->of_node, "ti,nwkrq-voltage-vio");
|
||||
}
|
||||
|
||||
static int tcan4x5x_get_gpios(struct m_can_classdev *cdev,
|
||||
const struct tcan4x5x_version_info *version_info)
|
||||
{
|
||||
@ -359,6 +384,7 @@ static int tcan4x5x_get_gpios(struct m_can_classdev *cdev,
|
||||
|
||||
static const struct m_can_ops tcan4x5x_ops = {
|
||||
.init = tcan4x5x_init,
|
||||
.deinit = tcan4x5x_deinit,
|
||||
.read_reg = tcan4x5x_read_reg,
|
||||
.write_reg = tcan4x5x_write_reg,
|
||||
.write_fifo = tcan4x5x_write_fifo,
|
||||
@ -392,7 +418,7 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
|
||||
priv->power = NULL;
|
||||
}
|
||||
|
||||
m_can_class_get_clocks(mcan_class);
|
||||
mcan_class->cclk = devm_clk_get(mcan_class->dev, "cclk");
|
||||
if (IS_ERR(mcan_class->cclk)) {
|
||||
dev_err(&spi->dev, "no CAN clock source defined\n");
|
||||
freq = TCAN4X5X_EXT_CLK_DEF;
|
||||
@ -453,6 +479,8 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
|
||||
goto out_power;
|
||||
}
|
||||
|
||||
tcan4x5x_get_dt_data(mcan_class);
|
||||
|
||||
tcan4x5x_check_wake(priv);
|
||||
|
||||
ret = tcan4x5x_write_tcan_reg(mcan_class, TCAN4X5X_INT_EN, 0);
|
||||
|
@ -42,6 +42,8 @@ struct tcan4x5x_priv {
|
||||
|
||||
struct tcan4x5x_map_buf map_buf_rx;
|
||||
struct tcan4x5x_map_buf map_buf_tx;
|
||||
|
||||
bool nwkrq_voltage_vio;
|
||||
};
|
||||
|
||||
static inline void
|
||||
|
@ -230,18 +230,9 @@ static int sp_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res_mem)
|
||||
return -ENODEV;
|
||||
|
||||
if (!devm_request_mem_region(&pdev->dev, res_mem->start,
|
||||
resource_size(res_mem), DRV_NAME))
|
||||
return -EBUSY;
|
||||
|
||||
addr = devm_ioremap(&pdev->dev, res_mem->start,
|
||||
resource_size(res_mem));
|
||||
if (!addr)
|
||||
return -ENOMEM;
|
||||
addr = devm_platform_get_and_ioremap_resource(pdev, 0, &res_mem);
|
||||
if (IS_ERR(addr))
|
||||
return PTR_ERR(addr);
|
||||
|
||||
if (of) {
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
|
@ -570,7 +570,7 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
|
||||
else
|
||||
state = CAN_STATE_ERROR_ACTIVE;
|
||||
}
|
||||
if (skb && state != CAN_STATE_BUS_OFF) {
|
||||
if (likely(skb) && state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
|
@ -818,7 +818,8 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
|
||||
init_completion(&priv->stop_comp);
|
||||
init_completion(&priv->flush_comp);
|
||||
init_completion(&priv->get_busparams_comp);
|
||||
priv->can.ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC;
|
||||
priv->can.ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC |
|
||||
CAN_CTRLMODE_BERR_REPORTING;
|
||||
|
||||
priv->dev = dev;
|
||||
priv->netdev = netdev;
|
||||
|
@ -926,6 +926,42 @@ kvaser_usb_hydra_bus_status_to_can_state(const struct kvaser_usb_net_priv *priv,
|
||||
}
|
||||
}
|
||||
|
||||
static void kvaser_usb_hydra_change_state(struct kvaser_usb_net_priv *priv,
|
||||
const struct can_berr_counter *bec,
|
||||
struct can_frame *cf,
|
||||
enum can_state new_state)
|
||||
{
|
||||
struct net_device *netdev = priv->netdev;
|
||||
enum can_state old_state = priv->can.state;
|
||||
enum can_state tx_state, rx_state;
|
||||
|
||||
tx_state = (bec->txerr >= bec->rxerr) ?
|
||||
new_state : CAN_STATE_ERROR_ACTIVE;
|
||||
rx_state = (bec->txerr <= bec->rxerr) ?
|
||||
new_state : CAN_STATE_ERROR_ACTIVE;
|
||||
can_change_state(netdev, cf, tx_state, rx_state);
|
||||
|
||||
if (new_state == CAN_STATE_BUS_OFF && old_state < CAN_STATE_BUS_OFF) {
|
||||
if (priv->can.restart_ms == 0)
|
||||
kvaser_usb_hydra_send_simple_cmd_async(priv, CMD_STOP_CHIP_REQ);
|
||||
|
||||
can_bus_off(netdev);
|
||||
}
|
||||
|
||||
if (priv->can.restart_ms &&
|
||||
old_state >= CAN_STATE_BUS_OFF &&
|
||||
new_state < CAN_STATE_BUS_OFF) {
|
||||
priv->can.can_stats.restarts++;
|
||||
if (cf)
|
||||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
}
|
||||
if (cf && new_state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = bec->txerr;
|
||||
cf->data[7] = bec->rxerr;
|
||||
}
|
||||
}
|
||||
|
||||
static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
|
||||
u8 bus_status,
|
||||
const struct can_berr_counter *bec)
|
||||
@ -951,41 +987,11 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
|
||||
return;
|
||||
|
||||
skb = alloc_can_err_skb(netdev, &cf);
|
||||
if (skb) {
|
||||
enum can_state tx_state, rx_state;
|
||||
|
||||
tx_state = (bec->txerr >= bec->rxerr) ?
|
||||
new_state : CAN_STATE_ERROR_ACTIVE;
|
||||
rx_state = (bec->txerr <= bec->rxerr) ?
|
||||
new_state : CAN_STATE_ERROR_ACTIVE;
|
||||
can_change_state(netdev, cf, tx_state, rx_state);
|
||||
}
|
||||
|
||||
if (new_state == CAN_STATE_BUS_OFF && old_state < CAN_STATE_BUS_OFF) {
|
||||
if (!priv->can.restart_ms)
|
||||
kvaser_usb_hydra_send_simple_cmd_async
|
||||
(priv, CMD_STOP_CHIP_REQ);
|
||||
|
||||
can_bus_off(netdev);
|
||||
}
|
||||
|
||||
if (!skb) {
|
||||
kvaser_usb_hydra_change_state(priv, bec, cf, new_state);
|
||||
if (skb)
|
||||
netif_rx(skb);
|
||||
else
|
||||
netdev_warn(netdev, "No memory left for err_skb\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->can.restart_ms &&
|
||||
old_state >= CAN_STATE_BUS_OFF &&
|
||||
new_state < CAN_STATE_BUS_OFF)
|
||||
priv->can.can_stats.restarts++;
|
||||
|
||||
if (new_state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = bec->txerr;
|
||||
cf->data[7] = bec->rxerr;
|
||||
}
|
||||
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
static void kvaser_usb_hydra_state_event(const struct kvaser_usb *dev,
|
||||
@ -1078,9 +1084,8 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
|
||||
{
|
||||
struct net_device *netdev = priv->netdev;
|
||||
struct net_device_stats *stats = &netdev->stats;
|
||||
struct can_frame *cf;
|
||||
struct sk_buff *skb;
|
||||
struct skb_shared_hwtstamps *shhwtstamps;
|
||||
struct can_frame *cf = NULL;
|
||||
struct sk_buff *skb = NULL;
|
||||
struct can_berr_counter bec;
|
||||
enum can_state new_state, old_state;
|
||||
u8 bus_status;
|
||||
@ -1096,52 +1101,26 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
|
||||
kvaser_usb_hydra_bus_status_to_can_state(priv, bus_status, &bec,
|
||||
&new_state);
|
||||
|
||||
skb = alloc_can_err_skb(netdev, &cf);
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
|
||||
skb = alloc_can_err_skb(netdev, &cf);
|
||||
if (new_state != old_state)
|
||||
kvaser_usb_hydra_change_state(priv, &bec, cf, new_state);
|
||||
|
||||
if (new_state != old_state) {
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
|
||||
if (skb) {
|
||||
enum can_state tx_state, rx_state;
|
||||
struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
|
||||
|
||||
tx_state = (bec.txerr >= bec.rxerr) ?
|
||||
new_state : CAN_STATE_ERROR_ACTIVE;
|
||||
rx_state = (bec.txerr <= bec.rxerr) ?
|
||||
new_state : CAN_STATE_ERROR_ACTIVE;
|
||||
|
||||
can_change_state(netdev, cf, tx_state, rx_state);
|
||||
|
||||
if (priv->can.restart_ms &&
|
||||
old_state >= CAN_STATE_BUS_OFF &&
|
||||
new_state < CAN_STATE_BUS_OFF)
|
||||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
}
|
||||
|
||||
if (new_state == CAN_STATE_BUS_OFF) {
|
||||
if (!priv->can.restart_ms)
|
||||
kvaser_usb_hydra_send_simple_cmd_async
|
||||
(priv, CMD_STOP_CHIP_REQ);
|
||||
|
||||
can_bus_off(netdev);
|
||||
shhwtstamps->hwtstamp = hwtstamp;
|
||||
cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
netif_rx(skb);
|
||||
} else {
|
||||
stats->rx_dropped++;
|
||||
netdev_warn(netdev, "No memory left for err_skb\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!skb) {
|
||||
stats->rx_dropped++;
|
||||
netdev_warn(netdev, "No memory left for err_skb\n");
|
||||
return;
|
||||
}
|
||||
|
||||
shhwtstamps = skb_hwtstamps(skb);
|
||||
shhwtstamps->hwtstamp = hwtstamp;
|
||||
|
||||
cf->can_id |= CAN_ERR_BUSERROR;
|
||||
if (new_state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
}
|
||||
|
||||
netif_rx(skb);
|
||||
|
||||
priv->bec.txerr = bec.txerr;
|
||||
priv->bec.rxerr = bec.rxerr;
|
||||
}
|
||||
|
@ -1120,10 +1120,8 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
|
||||
static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
|
||||
const struct kvaser_usb_err_summary *es)
|
||||
{
|
||||
struct can_frame *cf;
|
||||
struct can_frame tmp_cf = { .can_id = CAN_ERR_FLAG,
|
||||
.len = CAN_ERR_DLC };
|
||||
struct sk_buff *skb;
|
||||
struct can_frame *cf = NULL;
|
||||
struct sk_buff *skb = NULL;
|
||||
struct net_device_stats *stats;
|
||||
struct kvaser_usb_net_priv *priv;
|
||||
struct kvaser_usb_net_leaf_priv *leaf;
|
||||
@ -1143,18 +1141,10 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
|
||||
if (!netif_running(priv->netdev))
|
||||
return;
|
||||
|
||||
/* Update all of the CAN interface's state and error counters before
|
||||
* trying any memory allocation that can actually fail with -ENOMEM.
|
||||
*
|
||||
* We send a temporary stack-allocated error CAN frame to
|
||||
* can_change_state() for the very same reason.
|
||||
*
|
||||
* TODO: Split can_change_state() responsibility between updating the
|
||||
* CAN interface's state and counters, and the setting up of CAN error
|
||||
* frame ID and data to userspace. Remove stack allocation afterwards.
|
||||
*/
|
||||
old_state = priv->can.state;
|
||||
kvaser_usb_leaf_rx_error_update_can_state(priv, es, &tmp_cf);
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
|
||||
skb = alloc_can_err_skb(priv->netdev, &cf);
|
||||
kvaser_usb_leaf_rx_error_update_can_state(priv, es, cf);
|
||||
new_state = priv->can.state;
|
||||
|
||||
/* If there are errors, request status updates periodically as we do
|
||||
@ -1168,13 +1158,6 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
|
||||
schedule_delayed_work(&leaf->chip_state_req_work,
|
||||
msecs_to_jiffies(500));
|
||||
|
||||
skb = alloc_can_err_skb(priv->netdev, &cf);
|
||||
if (!skb) {
|
||||
stats->rx_dropped++;
|
||||
return;
|
||||
}
|
||||
memcpy(cf, &tmp_cf, sizeof(*cf));
|
||||
|
||||
if (new_state != old_state) {
|
||||
if (es->status &
|
||||
(M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) {
|
||||
@ -1187,11 +1170,20 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
|
||||
if (priv->can.restart_ms &&
|
||||
old_state == CAN_STATE_BUS_OFF &&
|
||||
new_state < CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
if (cf)
|
||||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
netif_carrier_on(priv->netdev);
|
||||
}
|
||||
}
|
||||
|
||||
if (!skb) {
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
|
||||
stats->rx_dropped++;
|
||||
netdev_warn(priv->netdev, "No memory left for err_skb\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (dev->driver_info->family) {
|
||||
case KVASER_LEAF:
|
||||
if (es->leaf.error_factor) {
|
||||
|
@ -2224,25 +2224,19 @@ int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy)
|
||||
}
|
||||
EXPORT_SYMBOL(b53_eee_init);
|
||||
|
||||
int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e)
|
||||
bool b53_support_eee(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct b53_device *dev = ds->priv;
|
||||
|
||||
if (is5325(dev) || is5365(dev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return 0;
|
||||
return !is5325(dev) && !is5365(dev);
|
||||
}
|
||||
EXPORT_SYMBOL(b53_get_mac_eee);
|
||||
EXPORT_SYMBOL(b53_support_eee);
|
||||
|
||||
int b53_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e)
|
||||
{
|
||||
struct b53_device *dev = ds->priv;
|
||||
struct ethtool_keee *p = &dev->ports[port].eee;
|
||||
|
||||
if (is5325(dev) || is5365(dev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
p->eee_enabled = e->eee_enabled;
|
||||
b53_eee_enable_set(ds, port, e->eee_enabled);
|
||||
|
||||
@ -2298,7 +2292,7 @@ static const struct dsa_switch_ops b53_switch_ops = {
|
||||
.phylink_get_caps = b53_phylink_get_caps,
|
||||
.port_enable = b53_enable_port,
|
||||
.port_disable = b53_disable_port,
|
||||
.get_mac_eee = b53_get_mac_eee,
|
||||
.support_eee = b53_support_eee,
|
||||
.set_mac_eee = b53_set_mac_eee,
|
||||
.port_bridge_join = b53_br_join,
|
||||
.port_bridge_leave = b53_br_leave,
|
||||
|
@ -384,7 +384,7 @@ int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
|
||||
void b53_disable_port(struct dsa_switch *ds, int port);
|
||||
void b53_brcm_hdr_setup(struct dsa_switch *ds, int port);
|
||||
int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy);
|
||||
int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e);
|
||||
bool b53_support_eee(struct dsa_switch *ds, int port);
|
||||
int b53_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e);
|
||||
|
||||
#endif
|
||||
|
@ -1232,7 +1232,7 @@ static const struct dsa_switch_ops bcm_sf2_ops = {
|
||||
.set_wol = bcm_sf2_sw_set_wol,
|
||||
.port_enable = bcm_sf2_port_setup,
|
||||
.port_disable = bcm_sf2_port_disable,
|
||||
.get_mac_eee = b53_get_mac_eee,
|
||||
.support_eee = b53_support_eee,
|
||||
.set_mac_eee = b53_set_mac_eee,
|
||||
.port_bridge_join = b53_br_join,
|
||||
.port_bridge_leave = b53_br_leave,
|
||||
|
@ -127,10 +127,14 @@ static const struct of_device_id ksz9477_dt_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ksz9477_dt_ids);
|
||||
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(ksz_i2c_pm_ops,
|
||||
ksz_switch_suspend, ksz_switch_resume);
|
||||
|
||||
static struct i2c_driver ksz9477_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "ksz9477-switch",
|
||||
.of_match_table = ksz9477_dt_ids,
|
||||
.pm = &ksz_i2c_pm_ops,
|
||||
},
|
||||
.probe = ksz9477_i2c_probe,
|
||||
.remove = ksz9477_i2c_remove,
|
||||
|
@ -1339,6 +1339,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
|
||||
.supports_rgmii = {false, false, true},
|
||||
.internal_phy = {true, true, false},
|
||||
.gbit_capable = {false, false, true},
|
||||
.ptp_capable = true,
|
||||
.wr_table = &ksz8563_register_set,
|
||||
.rd_table = &ksz8563_register_set,
|
||||
},
|
||||
@ -1550,6 +1551,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
|
||||
.internal_phy = {true, true, true, true,
|
||||
true, false, false},
|
||||
.gbit_capable = {true, true, true, true, true, true, true},
|
||||
.ptp_capable = true,
|
||||
.wr_table = &ksz9477_register_set,
|
||||
.rd_table = &ksz9477_register_set,
|
||||
},
|
||||
@ -1677,6 +1679,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
|
||||
.supports_rgmii = {false, false, true},
|
||||
.internal_phy = {true, true, false},
|
||||
.gbit_capable = {true, true, true},
|
||||
.ptp_capable = true,
|
||||
},
|
||||
|
||||
[KSZ8567] = {
|
||||
@ -1712,6 +1715,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
|
||||
true, false, false},
|
||||
.gbit_capable = {false, false, false, false, false,
|
||||
true, true},
|
||||
.ptp_capable = true,
|
||||
},
|
||||
|
||||
[KSZ9567] = {
|
||||
@ -1744,6 +1748,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
|
||||
.internal_phy = {true, true, true, true,
|
||||
true, false, false},
|
||||
.gbit_capable = {true, true, true, true, true, true, true},
|
||||
.ptp_capable = true,
|
||||
},
|
||||
|
||||
[LAN9370] = {
|
||||
@ -1773,6 +1778,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
|
||||
.supports_rmii = {false, false, false, false, true},
|
||||
.supports_rgmii = {false, false, false, false, true},
|
||||
.internal_phy = {true, true, true, true, false},
|
||||
.ptp_capable = true,
|
||||
},
|
||||
|
||||
[LAN9371] = {
|
||||
@ -1802,6 +1808,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
|
||||
.supports_rmii = {false, false, false, false, true, true},
|
||||
.supports_rgmii = {false, false, false, false, true, true},
|
||||
.internal_phy = {true, true, true, true, false, false},
|
||||
.ptp_capable = true,
|
||||
},
|
||||
|
||||
[LAN9372] = {
|
||||
@ -1835,6 +1842,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
|
||||
true, true, false, false},
|
||||
.internal_phy = {true, true, true, true,
|
||||
false, false, true, true},
|
||||
.ptp_capable = true,
|
||||
},
|
||||
|
||||
[LAN9373] = {
|
||||
@ -1868,6 +1876,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
|
||||
true, true, false, false},
|
||||
.internal_phy = {true, true, true, false,
|
||||
false, false, true, true},
|
||||
.ptp_capable = true,
|
||||
},
|
||||
|
||||
[LAN9374] = {
|
||||
@ -1901,6 +1910,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
|
||||
true, true, false, false},
|
||||
.internal_phy = {true, true, true, true,
|
||||
false, false, true, true},
|
||||
.ptp_capable = true,
|
||||
},
|
||||
|
||||
[LAN9646] = {
|
||||
@ -2544,7 +2554,11 @@ static int ksz_mdio_register(struct ksz_device *dev)
|
||||
bus->read = ksz_sw_mdio_read;
|
||||
bus->write = ksz_sw_mdio_write;
|
||||
bus->name = "ksz user smi";
|
||||
snprintf(bus->id, MII_BUS_ID_SIZE, "SMI-%d", ds->index);
|
||||
if (ds->dst->index != 0) {
|
||||
snprintf(bus->id, MII_BUS_ID_SIZE, "SMI-%d-%d", ds->dst->index, ds->index);
|
||||
} else {
|
||||
snprintf(bus->id, MII_BUS_ID_SIZE, "SMI-%d", ds->index);
|
||||
}
|
||||
}
|
||||
|
||||
ret = ksz_parse_dt_phy_config(dev, bus, mdio_np);
|
||||
@ -2805,16 +2819,21 @@ static int ksz_setup(struct dsa_switch *ds)
|
||||
if (ret)
|
||||
goto out_girq;
|
||||
|
||||
ret = ksz_ptp_irq_setup(ds, dp->index);
|
||||
if (ret)
|
||||
goto out_pirq;
|
||||
if (dev->info->ptp_capable) {
|
||||
ret = ksz_ptp_irq_setup(ds, dp->index);
|
||||
if (ret)
|
||||
goto out_pirq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = ksz_ptp_clock_register(ds);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "Failed to register PTP clock: %d\n", ret);
|
||||
goto out_ptpirq;
|
||||
if (dev->info->ptp_capable) {
|
||||
ret = ksz_ptp_clock_register(ds);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "Failed to register PTP clock: %d\n",
|
||||
ret);
|
||||
goto out_ptpirq;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ksz_mdio_register(dev);
|
||||
@ -2834,9 +2853,10 @@ static int ksz_setup(struct dsa_switch *ds)
|
||||
return 0;
|
||||
|
||||
out_ptp_clock_unregister:
|
||||
ksz_ptp_clock_unregister(ds);
|
||||
if (dev->info->ptp_capable)
|
||||
ksz_ptp_clock_unregister(ds);
|
||||
out_ptpirq:
|
||||
if (dev->irq > 0)
|
||||
if (dev->irq > 0 && dev->info->ptp_capable)
|
||||
dsa_switch_for_each_user_port(dp, dev->ds)
|
||||
ksz_ptp_irq_free(ds, dp->index);
|
||||
out_pirq:
|
||||
@ -2855,11 +2875,13 @@ static void ksz_teardown(struct dsa_switch *ds)
|
||||
struct ksz_device *dev = ds->priv;
|
||||
struct dsa_port *dp;
|
||||
|
||||
ksz_ptp_clock_unregister(ds);
|
||||
if (dev->info->ptp_capable)
|
||||
ksz_ptp_clock_unregister(ds);
|
||||
|
||||
if (dev->irq > 0) {
|
||||
dsa_switch_for_each_user_port(dp, dev->ds) {
|
||||
ksz_ptp_irq_free(ds, dp->index);
|
||||
if (dev->info->ptp_capable)
|
||||
ksz_ptp_irq_free(ds, dp->index);
|
||||
|
||||
ksz_irq_free(&dev->ports[dp->index].pirq);
|
||||
}
|
||||
@ -3444,12 +3466,12 @@ static int ksz_max_mtu(struct dsa_switch *ds, int port)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int ksz_validate_eee(struct dsa_switch *ds, int port)
|
||||
static bool ksz_support_eee(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct ksz_device *dev = ds->priv;
|
||||
|
||||
if (!dev->info->internal_phy[port])
|
||||
return -EOPNOTSUPP;
|
||||
return false;
|
||||
|
||||
switch (dev->chip_id) {
|
||||
case KSZ8563_CHIP_ID:
|
||||
@ -3461,41 +3483,16 @@ static int ksz_validate_eee(struct dsa_switch *ds, int port)
|
||||
case KSZ9896_CHIP_ID:
|
||||
case KSZ9897_CHIP_ID:
|
||||
case LAN9646_CHIP_ID:
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int ksz_get_mac_eee(struct dsa_switch *ds, int port,
|
||||
struct ethtool_keee *e)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ksz_validate_eee(ds, port);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* There is no documented control of Tx LPI configuration. */
|
||||
e->tx_lpi_enabled = true;
|
||||
|
||||
/* There is no documented control of Tx LPI timer. According to tests
|
||||
* Tx LPI timer seems to be set by default to minimal value.
|
||||
*/
|
||||
e->tx_lpi_timer = 0;
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int ksz_set_mac_eee(struct dsa_switch *ds, int port,
|
||||
struct ethtool_keee *e)
|
||||
{
|
||||
struct ksz_device *dev = ds->priv;
|
||||
int ret;
|
||||
|
||||
ret = ksz_validate_eee(ds, port);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!e->tx_lpi_enabled) {
|
||||
dev_err(dev->dev, "Disabling EEE Tx LPI is not supported\n");
|
||||
@ -4593,6 +4590,23 @@ static int ksz_hsr_leave(struct dsa_switch *ds, int port,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ksz_suspend(struct dsa_switch *ds)
|
||||
{
|
||||
struct ksz_device *dev = ds->priv;
|
||||
|
||||
cancel_delayed_work_sync(&dev->mib_read);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ksz_resume(struct dsa_switch *ds)
|
||||
{
|
||||
struct ksz_device *dev = ds->priv;
|
||||
|
||||
if (dev->mib_read_interval)
|
||||
schedule_delayed_work(&dev->mib_read, dev->mib_read_interval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dsa_switch_ops ksz_switch_ops = {
|
||||
.get_tag_protocol = ksz_get_tag_protocol,
|
||||
.connect_tag_protocol = ksz_connect_tag_protocol,
|
||||
@ -4633,6 +4647,8 @@ static const struct dsa_switch_ops ksz_switch_ops = {
|
||||
.port_max_mtu = ksz_max_mtu,
|
||||
.get_wol = ksz_get_wol,
|
||||
.set_wol = ksz_set_wol,
|
||||
.suspend = ksz_suspend,
|
||||
.resume = ksz_resume,
|
||||
.get_ts_info = ksz_get_ts_info,
|
||||
.port_hwtstamp_get = ksz_hwtstamp_get,
|
||||
.port_hwtstamp_set = ksz_hwtstamp_set,
|
||||
@ -4641,7 +4657,7 @@ static const struct dsa_switch_ops ksz_switch_ops = {
|
||||
.cls_flower_add = ksz_cls_flower_add,
|
||||
.cls_flower_del = ksz_cls_flower_del,
|
||||
.port_setup_tc = ksz_setup_tc,
|
||||
.get_mac_eee = ksz_get_mac_eee,
|
||||
.support_eee = ksz_support_eee,
|
||||
.set_mac_eee = ksz_set_mac_eee,
|
||||
.port_get_default_prio = ksz_port_get_default_prio,
|
||||
.port_set_default_prio = ksz_port_set_default_prio,
|
||||
@ -5132,6 +5148,24 @@ void ksz_switch_remove(struct ksz_device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL(ksz_switch_remove);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
int ksz_switch_suspend(struct device *dev)
|
||||
{
|
||||
struct ksz_device *priv = dev_get_drvdata(dev);
|
||||
|
||||
return dsa_switch_suspend(priv->ds);
|
||||
}
|
||||
EXPORT_SYMBOL(ksz_switch_suspend);
|
||||
|
||||
int ksz_switch_resume(struct device *dev)
|
||||
{
|
||||
struct ksz_device *priv = dev_get_drvdata(dev);
|
||||
|
||||
return dsa_switch_resume(priv->ds);
|
||||
}
|
||||
EXPORT_SYMBOL(ksz_switch_resume);
|
||||
#endif
|
||||
|
||||
MODULE_AUTHOR("Woojung Huh <Woojung.Huh@microchip.com>");
|
||||
MODULE_DESCRIPTION("Microchip KSZ Series Switch DSA Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -92,6 +92,7 @@ struct ksz_chip_data {
|
||||
bool supports_rgmii[KSZ_MAX_NUM_PORTS];
|
||||
bool internal_phy[KSZ_MAX_NUM_PORTS];
|
||||
bool gbit_capable[KSZ_MAX_NUM_PORTS];
|
||||
bool ptp_capable;
|
||||
const struct regmap_access_table *wr_table;
|
||||
const struct regmap_access_table *rd_table;
|
||||
};
|
||||
@ -444,6 +445,8 @@ struct ksz_dev_ops {
|
||||
struct ksz_device *ksz_switch_alloc(struct device *base, void *priv);
|
||||
int ksz_switch_register(struct ksz_device *dev);
|
||||
void ksz_switch_remove(struct ksz_device *dev);
|
||||
int ksz_switch_suspend(struct device *dev);
|
||||
int ksz_switch_resume(struct device *dev);
|
||||
|
||||
void ksz_init_mib_timer(struct ksz_device *dev);
|
||||
bool ksz_is_port_mac_global_usable(struct dsa_switch *ds, int port);
|
||||
|
@ -239,10 +239,14 @@ static const struct spi_device_id ksz_spi_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, ksz_spi_ids);
|
||||
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(ksz_spi_pm_ops,
|
||||
ksz_switch_suspend, ksz_switch_resume);
|
||||
|
||||
static struct spi_driver ksz_spi_driver = {
|
||||
.driver = {
|
||||
.name = "ksz-switch",
|
||||
.of_match_table = ksz_dt_ids,
|
||||
.pm = &ksz_spi_pm_ops,
|
||||
},
|
||||
.id_table = ksz_spi_ids,
|
||||
.probe = ksz_spi_probe,
|
||||
|
@ -3085,18 +3085,6 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mt753x_get_mac_eee(struct dsa_switch *ds, int port,
|
||||
struct ethtool_keee *e)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
u32 eeecr = mt7530_read(priv, MT753X_PMEEECR_P(port));
|
||||
|
||||
e->tx_lpi_enabled = !(eeecr & LPI_MODE_EN);
|
||||
e->tx_lpi_timer = LPI_THRESH_GET(eeecr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt753x_set_mac_eee(struct dsa_switch *ds, int port,
|
||||
struct ethtool_keee *e)
|
||||
{
|
||||
@ -3238,7 +3226,7 @@ const struct dsa_switch_ops mt7530_switch_ops = {
|
||||
.port_mirror_add = mt753x_port_mirror_add,
|
||||
.port_mirror_del = mt753x_port_mirror_del,
|
||||
.phylink_get_caps = mt753x_phylink_get_caps,
|
||||
.get_mac_eee = mt753x_get_mac_eee,
|
||||
.support_eee = dsa_supports_eee,
|
||||
.set_mac_eee = mt753x_set_mac_eee,
|
||||
.conduit_state_change = mt753x_conduit_state_change,
|
||||
.port_setup_tc = mt753x_setup_tc,
|
||||
|
@ -1289,9 +1289,6 @@ static size_t mv88e6095_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
|
||||
const struct mv88e6xxx_hw_stat *stat,
|
||||
uint64_t *data)
|
||||
{
|
||||
if (!(stat->type & (STATS_TYPE_BANK0 | STATS_TYPE_PORT)))
|
||||
return 0;
|
||||
|
||||
*data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 0,
|
||||
MV88E6XXX_G1_STATS_OP_HIST_RX);
|
||||
return 1;
|
||||
@ -1301,9 +1298,6 @@ static size_t mv88e6250_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
|
||||
const struct mv88e6xxx_hw_stat *stat,
|
||||
uint64_t *data)
|
||||
{
|
||||
if (!(stat->type & STATS_TYPE_BANK0))
|
||||
return 0;
|
||||
|
||||
*data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 0,
|
||||
MV88E6XXX_G1_STATS_OP_HIST_RX);
|
||||
return 1;
|
||||
@ -1313,9 +1307,6 @@ static size_t mv88e6320_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
|
||||
const struct mv88e6xxx_hw_stat *stat,
|
||||
uint64_t *data)
|
||||
{
|
||||
if (!(stat->type & (STATS_TYPE_BANK0 | STATS_TYPE_BANK1)))
|
||||
return 0;
|
||||
|
||||
*data = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
|
||||
MV88E6XXX_G1_STATS_OP_BANK_1_BIT_9,
|
||||
MV88E6XXX_G1_STATS_OP_HIST_RX);
|
||||
@ -1326,9 +1317,6 @@ static size_t mv88e6390_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
|
||||
const struct mv88e6xxx_hw_stat *stat,
|
||||
uint64_t *data)
|
||||
{
|
||||
if (!(stat->type & (STATS_TYPE_BANK0 | STATS_TYPE_BANK1)))
|
||||
return 0;
|
||||
|
||||
*data = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
|
||||
MV88E6XXX_G1_STATS_OP_BANK_1_BIT_10,
|
||||
0);
|
||||
@ -1341,6 +1329,9 @@ static size_t mv88e6xxx_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!(stat->type & chip->info->stats_type))
|
||||
return 0;
|
||||
|
||||
if (chip->info->ops->stats_get_stat) {
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
ret = chip->info->ops->stats_get_stat(chip, port, stat, data);
|
||||
@ -1522,13 +1513,6 @@ static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
}
|
||||
|
||||
static int mv88e6xxx_get_mac_eee(struct dsa_switch *ds, int port,
|
||||
struct ethtool_keee *e)
|
||||
{
|
||||
/* Nothing to do on the port's MAC */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mv88e6xxx_set_mac_eee(struct dsa_switch *ds, int port,
|
||||
struct ethtool_keee *e)
|
||||
{
|
||||
@ -5645,6 +5629,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 5,
|
||||
.stats_type = STATS_TYPE_BANK0,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.dual_chip = true,
|
||||
.ops = &mv88e6250_ops,
|
||||
@ -5665,6 +5650,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 5,
|
||||
.stats_type = STATS_TYPE_BANK0,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.dual_chip = true,
|
||||
.ops = &mv88e6250_ops,
|
||||
@ -5687,6 +5673,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 8,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -5708,6 +5695,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.global2_addr = 0x1c,
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 8,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.multi_chip = true,
|
||||
.ops = &mv88e6095_ops,
|
||||
@ -5730,6 +5718,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 8,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -5754,6 +5743,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -5776,6 +5766,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.global2_addr = 0x1c,
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.multi_chip = true,
|
||||
.ops = &mv88e6131_ops,
|
||||
@ -5800,6 +5791,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.atu_move_port_mask = 0x1f,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
|
||||
@ -5823,6 +5815,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -5848,6 +5841,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -5872,6 +5866,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -5897,6 +5892,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -5921,6 +5917,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -5946,6 +5943,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -5968,6 +5966,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.global2_addr = 0x1c,
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 8,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.multi_chip = true,
|
||||
.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
|
||||
@ -5992,6 +5991,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 3750,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 14,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
.atu_move_port_mask = 0x1f,
|
||||
@ -6016,6 +6016,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 3750,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 14,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.atu_move_port_mask = 0x1f,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6039,6 +6040,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 3750,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 14,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.atu_move_port_mask = 0x1f,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6063,6 +6065,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 3750,
|
||||
.g1_irqs = 10,
|
||||
.g2_irqs = 14,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.atu_move_port_mask = 0x1f,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6087,6 +6090,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 3750,
|
||||
.g1_irqs = 10,
|
||||
.g2_irqs = 14,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.atu_move_port_mask = 0x1f,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6114,6 +6118,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.dual_chip = true,
|
||||
.ptp_support = true,
|
||||
@ -6138,6 +6143,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6161,6 +6167,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.dual_chip = true,
|
||||
.ptp_support = true,
|
||||
@ -6184,6 +6191,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 3750,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 14,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.atu_move_port_mask = 0x1f,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6208,6 +6216,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 8,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6233,6 +6242,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 8,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.multi_chip = true,
|
||||
.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
|
||||
@ -6259,6 +6269,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.atu_move_port_mask = 0x1f,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
|
||||
@ -6283,6 +6294,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6307,6 +6319,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6332,6 +6345,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6359,6 +6373,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 3750,
|
||||
.g1_irqs = 10,
|
||||
.g2_irqs = 14,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.atu_move_port_mask = 0x1f,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6383,6 +6398,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 3750,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 14,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.atu_move_port_mask = 0x1f,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6408,6 +6424,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 3750,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 14,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.atu_move_port_mask = 0x1f,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -6433,6 +6450,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
.age_time_coeff = 3750,
|
||||
.g1_irqs = 10,
|
||||
.g2_irqs = 14,
|
||||
.stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
|
||||
.atu_move_port_mask = 0x1f,
|
||||
.pvt = true,
|
||||
.multi_chip = true,
|
||||
@ -7074,7 +7092,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
||||
.get_sset_count = mv88e6xxx_get_sset_count,
|
||||
.port_max_mtu = mv88e6xxx_get_max_mtu,
|
||||
.port_change_mtu = mv88e6xxx_change_mtu,
|
||||
.get_mac_eee = mv88e6xxx_get_mac_eee,
|
||||
.support_eee = dsa_supports_eee,
|
||||
.set_mac_eee = mv88e6xxx_set_mac_eee,
|
||||
.get_eeprom_len = mv88e6xxx_get_eeprom_len,
|
||||
.get_eeprom = mv88e6xxx_get_eeprom,
|
||||
|
@ -144,6 +144,7 @@ struct mv88e6xxx_info {
|
||||
unsigned int age_time_coeff;
|
||||
unsigned int g1_irqs;
|
||||
unsigned int g2_irqs;
|
||||
int stats_type;
|
||||
bool pvt;
|
||||
|
||||
/* Mark certain ports as invalid. This is required for example for the
|
||||
|
@ -342,7 +342,7 @@ static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
|
||||
dev_queue_xmit(skb);
|
||||
|
||||
ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
|
||||
msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
|
||||
QCA8K_ETHERNET_TIMEOUT);
|
||||
|
||||
*val = mgmt_eth_data->data[0];
|
||||
if (len > QCA_HDR_MGMT_DATA1_LEN)
|
||||
@ -394,7 +394,7 @@ static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
|
||||
dev_queue_xmit(skb);
|
||||
|
||||
ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
|
||||
msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));
|
||||
QCA8K_ETHERNET_TIMEOUT);
|
||||
|
||||
ack = mgmt_eth_data->ack;
|
||||
|
||||
@ -1019,7 +1019,7 @@ qca8k_setup_mdio_bus(struct qca8k_priv *priv)
|
||||
|
||||
of_get_phy_mode(port, &mode);
|
||||
|
||||
if (of_property_read_bool(port, "phy-handle") &&
|
||||
if (of_property_present(port, "phy-handle") &&
|
||||
mode != PHY_INTERFACE_MODE_INTERNAL)
|
||||
external_mdio_mask |= BIT(reg);
|
||||
else
|
||||
@ -2016,7 +2016,7 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
|
||||
.get_ethtool_stats = qca8k_get_ethtool_stats,
|
||||
.get_sset_count = qca8k_get_sset_count,
|
||||
.set_ageing_time = qca8k_set_ageing_time,
|
||||
.get_mac_eee = qca8k_get_mac_eee,
|
||||
.support_eee = dsa_supports_eee,
|
||||
.set_mac_eee = qca8k_set_mac_eee,
|
||||
.port_enable = qca8k_port_enable,
|
||||
.port_disable = qca8k_port_disable,
|
||||
|
@ -557,13 +557,6 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qca8k_get_mac_eee(struct dsa_switch *ds, int port,
|
||||
struct ethtool_keee *e)
|
||||
{
|
||||
/* Nothing to do on the port's MAC */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qca8k_port_configure_learning(struct dsa_switch *ds, int port,
|
||||
bool learning)
|
||||
{
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#define QCA8K_ETHERNET_MDIO_PRIORITY 7
|
||||
#define QCA8K_ETHERNET_PHY_PRIORITY 6
|
||||
#define QCA8K_ETHERNET_TIMEOUT 5
|
||||
#define QCA8K_ETHERNET_TIMEOUT msecs_to_jiffies(5)
|
||||
|
||||
#define QCA8K_NUM_PORTS 7
|
||||
#define QCA8K_NUM_CPU_PORTS 2
|
||||
@ -520,7 +520,6 @@ int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset);
|
||||
|
||||
/* Common eee function */
|
||||
int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *eee);
|
||||
int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e);
|
||||
|
||||
/* Common bridge function */
|
||||
void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
|
||||
|
@ -26,12 +26,8 @@ void sja1105_pack(void *buf, const u64 *val, int start, int end, size_t len)
|
||||
pr_err("Start bit (%d) expected to be larger than end (%d)\n",
|
||||
start, end);
|
||||
} else if (rc == -ERANGE) {
|
||||
if ((start - end + 1) > 64)
|
||||
pr_err("Field %d-%d too large for 64 bits!\n",
|
||||
start, end);
|
||||
else
|
||||
pr_err("Cannot store %llx inside bits %d-%d (would truncate)\n",
|
||||
*val, start, end);
|
||||
pr_err("Field %d-%d too large for 64 bits!\n",
|
||||
start, end);
|
||||
}
|
||||
dump_stack();
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ config ETHOC
|
||||
Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
|
||||
|
||||
config OA_TC6
|
||||
tristate "OPEN Alliance TC6 10BASE-T1x MAC-PHY support"
|
||||
tristate "OPEN Alliance TC6 10BASE-T1x MAC-PHY support" if COMPILE_TEST
|
||||
depends on SPI
|
||||
select PHYLIB
|
||||
help
|
||||
|
@ -74,7 +74,7 @@ static void ena_tx_timeout(struct net_device *dev, unsigned int txqueue)
|
||||
if (threshold < time_since_last_napi && napi_scheduled) {
|
||||
netdev_err(dev,
|
||||
"napi handler hasn't been called for a long time but is scheduled\n");
|
||||
reset_reason = ENA_REGS_RESET_SUSPECTED_POLL_STARVATION;
|
||||
reset_reason = ENA_REGS_RESET_SUSPECTED_POLL_STARVATION;
|
||||
}
|
||||
schedule_reset:
|
||||
/* Change the state of the device to trigger reset
|
||||
|
@ -421,18 +421,12 @@ static void xgene_enet_configure_clock(struct xgene_enet_pdata *pdata)
|
||||
|
||||
if (dev->of_node) {
|
||||
struct clk *parent = clk_get_parent(pdata->clk);
|
||||
long rate = rgmii_clock(pdata->phy_speed);
|
||||
|
||||
switch (pdata->phy_speed) {
|
||||
case SPEED_10:
|
||||
clk_set_rate(parent, 2500000);
|
||||
break;
|
||||
case SPEED_100:
|
||||
clk_set_rate(parent, 25000000);
|
||||
break;
|
||||
default:
|
||||
clk_set_rate(parent, 125000000);
|
||||
break;
|
||||
}
|
||||
if (rate < 0)
|
||||
rate = 125000000;
|
||||
|
||||
clk_set_rate(parent, rate);
|
||||
}
|
||||
#ifdef CONFIG_ACPI
|
||||
else {
|
||||
|
@ -8322,16 +8322,20 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
|
||||
if (rc)
|
||||
goto func_qcfg_exit;
|
||||
|
||||
flags = le16_to_cpu(resp->flags);
|
||||
#ifdef CONFIG_BNXT_SRIOV
|
||||
if (BNXT_VF(bp)) {
|
||||
struct bnxt_vf_info *vf = &bp->vf;
|
||||
|
||||
vf->vlan = le16_to_cpu(resp->vlan) & VLAN_VID_MASK;
|
||||
if (flags & FUNC_QCFG_RESP_FLAGS_TRUSTED_VF)
|
||||
vf->flags |= BNXT_VF_TRUST;
|
||||
else
|
||||
vf->flags &= ~BNXT_VF_TRUST;
|
||||
} else {
|
||||
bp->pf.registered_vfs = le16_to_cpu(resp->registered_vfs);
|
||||
}
|
||||
#endif
|
||||
flags = le16_to_cpu(resp->flags);
|
||||
if (flags & (FUNC_QCFG_RESP_FLAGS_FW_DCBX_AGENT_ENABLED |
|
||||
FUNC_QCFG_RESP_FLAGS_FW_LLDP_AGENT_ENABLED)) {
|
||||
bp->fw_cap |= BNXT_FW_CAP_LLDP_AGENT;
|
||||
@ -9160,10 +9164,18 @@ static int bnxt_alloc_ctx_mem(struct bnxt *bp)
|
||||
ena = 0;
|
||||
if ((bp->flags & BNXT_FLAG_ROCE_CAP) && !is_kdump_kernel()) {
|
||||
pg_lvl = 2;
|
||||
extra_qps = min_t(u32, 65536, max_qps - l2_qps - qp1_qps);
|
||||
/* allocate extra qps if fw supports RoCE fast qp destroy feature */
|
||||
extra_qps += fast_qpmd_qps;
|
||||
extra_srqs = min_t(u32, 8192, max_srqs - srqs);
|
||||
if (BNXT_SW_RES_LMT(bp)) {
|
||||
extra_qps = max_qps - l2_qps - qp1_qps;
|
||||
extra_srqs = max_srqs - srqs;
|
||||
} else {
|
||||
extra_qps = min_t(u32, 65536,
|
||||
max_qps - l2_qps - qp1_qps);
|
||||
/* allocate extra qps if fw supports RoCE fast qp
|
||||
* destroy feature
|
||||
*/
|
||||
extra_qps += fast_qpmd_qps;
|
||||
extra_srqs = min_t(u32, 8192, max_srqs - srqs);
|
||||
}
|
||||
if (fast_qpmd_qps)
|
||||
ena |= FUNC_BACKING_STORE_CFG_REQ_ENABLES_QP_FAST_QPMD;
|
||||
}
|
||||
@ -9199,14 +9211,20 @@ static int bnxt_alloc_ctx_mem(struct bnxt *bp)
|
||||
goto skip_rdma;
|
||||
|
||||
ctxm = &ctx->ctx_arr[BNXT_CTX_MRAV];
|
||||
/* 128K extra is needed to accommodate static AH context
|
||||
* allocation by f/w.
|
||||
*/
|
||||
num_mr = min_t(u32, ctxm->max_entries / 2, 1024 * 256);
|
||||
num_ah = min_t(u32, num_mr, 1024 * 128);
|
||||
ctxm->split_entry_cnt = BNXT_CTX_MRAV_AV_SPLIT_ENTRY + 1;
|
||||
if (!ctxm->mrav_av_entries || ctxm->mrav_av_entries > num_ah)
|
||||
ctxm->mrav_av_entries = num_ah;
|
||||
if (BNXT_SW_RES_LMT(bp) &&
|
||||
ctxm->split_entry_cnt == BNXT_CTX_MRAV_AV_SPLIT_ENTRY + 1) {
|
||||
num_ah = ctxm->mrav_av_entries;
|
||||
num_mr = ctxm->max_entries - num_ah;
|
||||
} else {
|
||||
/* 128K extra is needed to accommodate static AH context
|
||||
* allocation by f/w.
|
||||
*/
|
||||
num_mr = min_t(u32, ctxm->max_entries / 2, 1024 * 256);
|
||||
num_ah = min_t(u32, num_mr, 1024 * 128);
|
||||
ctxm->split_entry_cnt = BNXT_CTX_MRAV_AV_SPLIT_ENTRY + 1;
|
||||
if (!ctxm->mrav_av_entries || ctxm->mrav_av_entries > num_ah)
|
||||
ctxm->mrav_av_entries = num_ah;
|
||||
}
|
||||
|
||||
rc = bnxt_setup_ctxm_pg_tbls(bp, ctxm, num_mr + num_ah, 2);
|
||||
if (rc)
|
||||
@ -9513,6 +9531,9 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
|
||||
bp->flags |= BNXT_FLAG_UDP_GSO_CAP;
|
||||
if (flags_ext2 & FUNC_QCAPS_RESP_FLAGS_EXT2_TX_PKT_TS_CMPL_SUPPORTED)
|
||||
bp->fw_cap |= BNXT_FW_CAP_TX_TS_CMP;
|
||||
if (flags_ext2 &
|
||||
FUNC_QCAPS_RESP_FLAGS_EXT2_SW_MAX_RESOURCE_LIMITS_SUPPORTED)
|
||||
bp->fw_cap |= BNXT_FW_CAP_SW_MAX_RESOURCE_LIMITS;
|
||||
if (BNXT_PF(bp) &&
|
||||
(flags_ext2 & FUNC_QCAPS_RESP_FLAGS_EXT2_ROCE_VF_RESOURCE_MGMT_SUPPORTED))
|
||||
bp->fw_cap |= BNXT_FW_CAP_ROCE_VF_RESC_MGMT_SUPPORTED;
|
||||
@ -11571,6 +11592,26 @@ hwrm_phy_qcaps_exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void bnxt_hwrm_mac_qcaps(struct bnxt *bp)
|
||||
{
|
||||
struct hwrm_port_mac_qcaps_output *resp;
|
||||
struct hwrm_port_mac_qcaps_input *req;
|
||||
int rc;
|
||||
|
||||
if (bp->hwrm_spec_code < 0x10a03)
|
||||
return;
|
||||
|
||||
rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_QCAPS);
|
||||
if (rc)
|
||||
return;
|
||||
|
||||
resp = hwrm_req_hold(bp, req);
|
||||
rc = hwrm_req_send_silent(bp, req);
|
||||
if (!rc)
|
||||
bp->mac_flags = resp->flags;
|
||||
hwrm_req_drop(bp, req);
|
||||
}
|
||||
|
||||
static bool bnxt_support_dropped(u16 advertising, u16 supported)
|
||||
{
|
||||
u16 diff = advertising ^ supported;
|
||||
@ -15701,6 +15742,10 @@ static int bnxt_probe_phy(struct bnxt *bp, bool fw_dflt)
|
||||
bp->dev->priv_flags |= IFF_SUPP_NOFCS;
|
||||
else
|
||||
bp->dev->priv_flags &= ~IFF_SUPP_NOFCS;
|
||||
|
||||
bp->mac_flags = 0;
|
||||
bnxt_hwrm_mac_qcaps(bp);
|
||||
|
||||
if (!fw_dflt)
|
||||
return 0;
|
||||
|
||||
|
@ -2270,6 +2270,11 @@ struct bnxt {
|
||||
|
||||
#define BNXT_PF(bp) (!((bp)->flags & BNXT_FLAG_VF))
|
||||
#define BNXT_VF(bp) ((bp)->flags & BNXT_FLAG_VF)
|
||||
#ifdef CONFIG_BNXT_SRIOV
|
||||
#define BNXT_VF_IS_TRUSTED(bp) ((bp)->vf.flags & BNXT_VF_TRUST)
|
||||
#else
|
||||
#define BNXT_VF_IS_TRUSTED(bp) 0
|
||||
#endif
|
||||
#define BNXT_NPAR(bp) ((bp)->port_partition_type)
|
||||
#define BNXT_MH(bp) ((bp)->flags & BNXT_FLAG_MULTI_HOST)
|
||||
#define BNXT_SINGLE_PF(bp) (BNXT_PF(bp) && !BNXT_NPAR(bp) && !BNXT_MH(bp))
|
||||
@ -2482,6 +2487,7 @@ struct bnxt {
|
||||
#define BNXT_FW_CAP_CFA_NTUPLE_RX_EXT_IP_PROTO BIT_ULL(38)
|
||||
#define BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V3 BIT_ULL(39)
|
||||
#define BNXT_FW_CAP_VNIC_RE_FLUSH BIT_ULL(40)
|
||||
#define BNXT_FW_CAP_SW_MAX_RESOURCE_LIMITS BIT_ULL(41)
|
||||
|
||||
u32 fw_dbg_cap;
|
||||
|
||||
@ -2501,6 +2507,8 @@ struct bnxt {
|
||||
((bp)->fw_cap & BNXT_FW_CAP_ENABLE_RDMA_SRIOV)
|
||||
#define BNXT_ROCE_VF_RESC_CAP(bp) \
|
||||
((bp)->fw_cap & BNXT_FW_CAP_ROCE_VF_RESC_MGMT_SUPPORTED)
|
||||
#define BNXT_SW_RES_LMT(bp) \
|
||||
((bp)->fw_cap & BNXT_FW_CAP_SW_MAX_RESOURCE_LIMITS)
|
||||
|
||||
u32 hwrm_spec_code;
|
||||
u16 hwrm_cmd_seq;
|
||||
@ -2660,6 +2668,11 @@ struct bnxt {
|
||||
#define BNXT_PHY_FL_BANK_SEL (PORT_PHY_QCAPS_RESP_FLAGS2_BANK_ADDR_SUPPORTED << 8)
|
||||
#define BNXT_PHY_FL_SPEEDS2 (PORT_PHY_QCAPS_RESP_FLAGS2_SPEEDS2_SUPPORTED << 8)
|
||||
|
||||
/* copied from flags in hwrm_port_mac_qcaps_output */
|
||||
u8 mac_flags;
|
||||
#define BNXT_MAC_FL_NO_MAC_LPBK \
|
||||
PORT_MAC_QCAPS_RESP_FLAGS_LOCAL_LPBK_NOT_SUPPORTED
|
||||
|
||||
u8 num_tests;
|
||||
struct bnxt_test_info *test_info;
|
||||
|
||||
|
@ -2050,7 +2050,8 @@ static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs,
|
||||
int rc;
|
||||
|
||||
regs->version = 0;
|
||||
bnxt_dbg_hwrm_rd_reg(bp, 0, BNXT_PXP_REG_LEN / 4, _p);
|
||||
if (!(bp->fw_dbg_cap & DBG_QCAPS_RESP_FLAGS_REG_ACCESS_RESTRICTED))
|
||||
bnxt_dbg_hwrm_rd_reg(bp, 0, BNXT_PXP_REG_LEN / 4, _p);
|
||||
|
||||
if (!(bp->fw_cap & BNXT_FW_CAP_PCIE_STATS_SUPPORTED))
|
||||
return;
|
||||
@ -4375,6 +4376,9 @@ static int bnxt_get_module_info(struct net_device *dev,
|
||||
struct bnxt *bp = netdev_priv(dev);
|
||||
int rc;
|
||||
|
||||
if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp))
|
||||
return -EPERM;
|
||||
|
||||
/* No point in going further if phy status indicates
|
||||
* module is not inserted or if it is powered down or
|
||||
* if it is of type 10GBase-T
|
||||
@ -4426,6 +4430,9 @@ static int bnxt_get_module_eeprom(struct net_device *dev,
|
||||
u16 start = eeprom->offset, length = eeprom->len;
|
||||
int rc = 0;
|
||||
|
||||
if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp))
|
||||
return -EPERM;
|
||||
|
||||
memset(data, 0, eeprom->len);
|
||||
|
||||
/* Read A0 portion of the EEPROM */
|
||||
@ -4480,6 +4487,12 @@ static int bnxt_get_module_eeprom_by_page(struct net_device *dev,
|
||||
struct bnxt *bp = netdev_priv(dev);
|
||||
int rc;
|
||||
|
||||
if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Module read not permitted on untrusted VF");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
rc = bnxt_get_module_status(bp, extack);
|
||||
if (rc)
|
||||
return rc;
|
||||
@ -4887,35 +4900,44 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
|
||||
bnxt_close_nic(bp, true, false);
|
||||
bnxt_run_fw_tests(bp, test_mask, &test_results);
|
||||
|
||||
buf[BNXT_MACLPBK_TEST_IDX] = 1;
|
||||
bnxt_hwrm_mac_loopback(bp, true);
|
||||
msleep(250);
|
||||
rc = bnxt_half_open_nic(bp);
|
||||
if (rc) {
|
||||
bnxt_hwrm_mac_loopback(bp, false);
|
||||
etest->flags |= ETH_TEST_FL_FAILED;
|
||||
return;
|
||||
}
|
||||
buf[BNXT_MACLPBK_TEST_IDX] = 1;
|
||||
if (bp->mac_flags & BNXT_MAC_FL_NO_MAC_LPBK)
|
||||
goto skip_mac_loopback;
|
||||
|
||||
bnxt_hwrm_mac_loopback(bp, true);
|
||||
msleep(250);
|
||||
if (bnxt_run_loopback(bp))
|
||||
etest->flags |= ETH_TEST_FL_FAILED;
|
||||
else
|
||||
buf[BNXT_MACLPBK_TEST_IDX] = 0;
|
||||
|
||||
bnxt_hwrm_mac_loopback(bp, false);
|
||||
skip_mac_loopback:
|
||||
buf[BNXT_PHYLPBK_TEST_IDX] = 1;
|
||||
if (bp->phy_flags & BNXT_PHY_FL_NO_PHY_LPBK)
|
||||
goto skip_phy_loopback;
|
||||
|
||||
bnxt_hwrm_phy_loopback(bp, true, false);
|
||||
msleep(1000);
|
||||
if (bnxt_run_loopback(bp)) {
|
||||
buf[BNXT_PHYLPBK_TEST_IDX] = 1;
|
||||
if (bnxt_run_loopback(bp))
|
||||
etest->flags |= ETH_TEST_FL_FAILED;
|
||||
}
|
||||
else
|
||||
buf[BNXT_PHYLPBK_TEST_IDX] = 0;
|
||||
skip_phy_loopback:
|
||||
buf[BNXT_EXTLPBK_TEST_IDX] = 1;
|
||||
if (do_ext_lpbk) {
|
||||
etest->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
|
||||
bnxt_hwrm_phy_loopback(bp, true, true);
|
||||
msleep(1000);
|
||||
if (bnxt_run_loopback(bp)) {
|
||||
buf[BNXT_EXTLPBK_TEST_IDX] = 1;
|
||||
if (bnxt_run_loopback(bp))
|
||||
etest->flags |= ETH_TEST_FL_FAILED;
|
||||
}
|
||||
else
|
||||
buf[BNXT_EXTLPBK_TEST_IDX] = 0;
|
||||
}
|
||||
bnxt_hwrm_phy_loopback(bp, false, false);
|
||||
bnxt_half_close_nic(bp);
|
||||
|
@ -417,6 +417,8 @@ static void bnxt_set_edev_info(struct bnxt_en_dev *edev, struct bnxt *bp)
|
||||
edev->flags |= BNXT_EN_FLAG_VF;
|
||||
if (BNXT_ROCE_VF_RESC_CAP(bp))
|
||||
edev->flags |= BNXT_EN_FLAG_ROCE_VF_RES_MGMT;
|
||||
if (BNXT_SW_RES_LMT(bp))
|
||||
edev->flags |= BNXT_EN_FLAG_SW_RES_LMT;
|
||||
|
||||
edev->chip_num = bp->chip_num;
|
||||
edev->hw_ring_stats_size = bp->hw_ring_stats_size;
|
||||
|
@ -65,6 +65,8 @@ struct bnxt_en_dev {
|
||||
#define BNXT_EN_FLAG_VF 0x10
|
||||
#define BNXT_EN_VF(edev) ((edev)->flags & BNXT_EN_FLAG_VF)
|
||||
#define BNXT_EN_FLAG_ROCE_VF_RES_MGMT 0x20
|
||||
#define BNXT_EN_FLAG_SW_RES_LMT 0x40
|
||||
#define BNXT_EN_SW_RES_LMT(edev) ((edev)->flags & BNXT_EN_FLAG_SW_RES_LMT)
|
||||
|
||||
struct bnxt_ulp *ulp_tbl;
|
||||
int l2_db_size; /* Doorbell BAR size in
|
||||
|
@ -530,19 +530,9 @@ static void macb_set_tx_clk(struct macb *bp, int speed)
|
||||
if (bp->phy_interface == PHY_INTERFACE_MODE_MII)
|
||||
return;
|
||||
|
||||
switch (speed) {
|
||||
case SPEED_10:
|
||||
rate = 2500000;
|
||||
break;
|
||||
case SPEED_100:
|
||||
rate = 25000000;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
rate = 125000000;
|
||||
break;
|
||||
default:
|
||||
rate = rgmii_clock(speed);
|
||||
if (rate < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
rate_rounded = clk_round_rate(bp->tx_clk, rate);
|
||||
if (rate_rounded < 0)
|
||||
|
@ -6562,6 +6562,9 @@ static void cxgb4_advance_esn_state(struct xfrm_state *x)
|
||||
{
|
||||
struct adapter *adap = netdev2adap(x->xso.dev);
|
||||
|
||||
if (x->xso.dir != XFRM_DEV_OFFLOAD_IN)
|
||||
return;
|
||||
|
||||
if (!mutex_trylock(&uld_mutex)) {
|
||||
dev_dbg(adap->pdev_dev,
|
||||
"crypto uld critical resource is under use\n");
|
||||
|
@ -109,7 +109,7 @@ static struct enic_intr_mod_table mod_table[ENIC_MAX_COALESCE_TIMERS + 1] = {
|
||||
static struct enic_intr_mod_range mod_range[ENIC_MAX_LINK_SPEEDS] = {
|
||||
{0, 0}, /* 0 - 4 Gbps */
|
||||
{0, 3}, /* 4 - 10 Gbps */
|
||||
{3, 6}, /* 10 - 40 Gbps */
|
||||
{3, 6}, /* 10+ Gbps */
|
||||
};
|
||||
|
||||
static void enic_init_affinity_hint(struct enic *enic)
|
||||
@ -428,6 +428,36 @@ static void enic_mtu_check(struct enic *enic)
|
||||
}
|
||||
}
|
||||
|
||||
static void enic_set_rx_coal_setting(struct enic *enic)
|
||||
{
|
||||
unsigned int speed;
|
||||
int index = -1;
|
||||
struct enic_rx_coal *rx_coal = &enic->rx_coalesce_setting;
|
||||
|
||||
/* 1. Read the link speed from fw
|
||||
* 2. Pick the default range for the speed
|
||||
* 3. Update it in enic->rx_coalesce_setting
|
||||
*/
|
||||
speed = vnic_dev_port_speed(enic->vdev);
|
||||
if (speed > ENIC_LINK_SPEED_10G)
|
||||
index = ENIC_LINK_40G_INDEX;
|
||||
else if (speed > ENIC_LINK_SPEED_4G)
|
||||
index = ENIC_LINK_10G_INDEX;
|
||||
else
|
||||
index = ENIC_LINK_4G_INDEX;
|
||||
|
||||
rx_coal->small_pkt_range_start = mod_range[index].small_pkt_range_start;
|
||||
rx_coal->large_pkt_range_start = mod_range[index].large_pkt_range_start;
|
||||
rx_coal->range_end = ENIC_RX_COALESCE_RANGE_END;
|
||||
|
||||
/* Start with the value provided by UCSM */
|
||||
for (index = 0; index < enic->rq_count; index++)
|
||||
enic->cq[index].cur_rx_coal_timeval =
|
||||
enic->config.intr_timer_usec;
|
||||
|
||||
rx_coal->use_adaptive_rx_coalesce = 1;
|
||||
}
|
||||
|
||||
static void enic_link_check(struct enic *enic)
|
||||
{
|
||||
int link_status = vnic_dev_link_status(enic->vdev);
|
||||
@ -436,6 +466,7 @@ static void enic_link_check(struct enic *enic)
|
||||
if (link_status && !carrier_ok) {
|
||||
netdev_info(enic->netdev, "Link UP\n");
|
||||
netif_carrier_on(enic->netdev);
|
||||
enic_set_rx_coal_setting(enic);
|
||||
} else if (!link_status && carrier_ok) {
|
||||
netdev_info(enic->netdev, "Link DOWN\n");
|
||||
netif_carrier_off(enic->netdev);
|
||||
@ -1901,36 +1932,6 @@ static void enic_synchronize_irqs(struct enic *enic)
|
||||
}
|
||||
}
|
||||
|
||||
static void enic_set_rx_coal_setting(struct enic *enic)
|
||||
{
|
||||
unsigned int speed;
|
||||
int index = -1;
|
||||
struct enic_rx_coal *rx_coal = &enic->rx_coalesce_setting;
|
||||
|
||||
/* 1. Read the link speed from fw
|
||||
* 2. Pick the default range for the speed
|
||||
* 3. Update it in enic->rx_coalesce_setting
|
||||
*/
|
||||
speed = vnic_dev_port_speed(enic->vdev);
|
||||
if (ENIC_LINK_SPEED_10G < speed)
|
||||
index = ENIC_LINK_40G_INDEX;
|
||||
else if (ENIC_LINK_SPEED_4G < speed)
|
||||
index = ENIC_LINK_10G_INDEX;
|
||||
else
|
||||
index = ENIC_LINK_4G_INDEX;
|
||||
|
||||
rx_coal->small_pkt_range_start = mod_range[index].small_pkt_range_start;
|
||||
rx_coal->large_pkt_range_start = mod_range[index].large_pkt_range_start;
|
||||
rx_coal->range_end = ENIC_RX_COALESCE_RANGE_END;
|
||||
|
||||
/* Start with the value provided by UCSM */
|
||||
for (index = 0; index < enic->rq_count; index++)
|
||||
enic->cq[index].cur_rx_coal_timeval =
|
||||
enic->config.intr_timer_usec;
|
||||
|
||||
rx_coal->use_adaptive_rx_coalesce = 1;
|
||||
}
|
||||
|
||||
static int enic_dev_notify_set(struct enic *enic)
|
||||
{
|
||||
int err;
|
||||
@ -3063,7 +3064,6 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
timer_setup(&enic->notify_timer, enic_notify_timer, 0);
|
||||
|
||||
enic_rfs_flw_tbl_init(enic);
|
||||
enic_set_rx_coal_setting(enic);
|
||||
INIT_WORK(&enic->reset, enic_reset);
|
||||
INIT_WORK(&enic->tx_hang_reset, enic_tx_hang_reset);
|
||||
INIT_WORK(&enic->change_mtu_work, enic_change_mtu_work);
|
||||
|
@ -81,8 +81,7 @@ config UCC_GETH
|
||||
tristate "Freescale QE Gigabit Ethernet"
|
||||
depends on QUICC_ENGINE && PPC32
|
||||
select FSL_PQ_MDIO
|
||||
select PHYLIB
|
||||
select FIXED_PHY
|
||||
select PHYLINK
|
||||
help
|
||||
This driver supports the Gigabit Ethernet mode of the QUICC Engine,
|
||||
which is available on some Freescale SOCs.
|
||||
|
@ -2281,7 +2281,7 @@ static int dpaa_a050385_wa_xdpf(struct dpaa_priv *priv,
|
||||
new_xdpf->len = xdpf->len;
|
||||
new_xdpf->headroom = priv->tx_headroom;
|
||||
new_xdpf->frame_sz = DPAA_BP_RAW_SIZE;
|
||||
new_xdpf->mem.type = MEM_TYPE_PAGE_ORDER0;
|
||||
new_xdpf->mem_type = MEM_TYPE_PAGE_ORDER0;
|
||||
|
||||
/* Release the initial buffer */
|
||||
xdp_return_frame_rx_napi(xdpf);
|
||||
|
@ -780,13 +780,14 @@ struct ethsw_dump_ctx {
|
||||
static int dpaa2_switch_fdb_dump_nl(struct fdb_dump_entry *entry,
|
||||
struct ethsw_dump_ctx *dump)
|
||||
{
|
||||
struct ndo_fdb_dump_context *ctx = (void *)dump->cb->ctx;
|
||||
int is_dynamic = entry->type & DPSW_FDB_ENTRY_DINAMIC;
|
||||
u32 portid = NETLINK_CB(dump->cb->skb).portid;
|
||||
u32 seq = dump->cb->nlh->nlmsg_seq;
|
||||
struct nlmsghdr *nlh;
|
||||
struct ndmsg *ndm;
|
||||
|
||||
if (dump->idx < dump->cb->args[2])
|
||||
if (dump->idx < ctx->fdb_idx)
|
||||
goto skip;
|
||||
|
||||
nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
|
||||
|
@ -146,6 +146,27 @@ static int enetc_ptp_parse(struct sk_buff *skb, u8 *udp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool enetc_tx_csum_offload_check(struct sk_buff *skb)
|
||||
{
|
||||
switch (skb->csum_offset) {
|
||||
case offsetof(struct tcphdr, check):
|
||||
case offsetof(struct udphdr, check):
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool enetc_skb_is_ipv6(struct sk_buff *skb)
|
||||
{
|
||||
return vlan_get_protocol(skb) == htons(ETH_P_IPV6);
|
||||
}
|
||||
|
||||
static bool enetc_skb_is_tcp(struct sk_buff *skb)
|
||||
{
|
||||
return skb->csum_offset == offsetof(struct tcphdr, check);
|
||||
}
|
||||
|
||||
static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
|
||||
{
|
||||
bool do_vlan, do_onestep_tstamp = false, do_twostep_tstamp = false;
|
||||
@ -163,6 +184,29 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
|
||||
dma_addr_t dma;
|
||||
u8 flags = 0;
|
||||
|
||||
enetc_clear_tx_bd(&temp_bd);
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
/* Can not support TSD and checksum offload at the same time */
|
||||
if (priv->active_offloads & ENETC_F_TXCSUM &&
|
||||
enetc_tx_csum_offload_check(skb) && !tx_ring->tsd_enable) {
|
||||
temp_bd.l3_aux0 = FIELD_PREP(ENETC_TX_BD_L3_START,
|
||||
skb_network_offset(skb));
|
||||
temp_bd.l3_aux1 = FIELD_PREP(ENETC_TX_BD_L3_HDR_LEN,
|
||||
skb_network_header_len(skb) / 4);
|
||||
temp_bd.l3_aux1 |= FIELD_PREP(ENETC_TX_BD_L3T,
|
||||
enetc_skb_is_ipv6(skb));
|
||||
if (enetc_skb_is_tcp(skb))
|
||||
temp_bd.l4_aux = FIELD_PREP(ENETC_TX_BD_L4T,
|
||||
ENETC_TXBD_L4T_TCP);
|
||||
else
|
||||
temp_bd.l4_aux = FIELD_PREP(ENETC_TX_BD_L4T,
|
||||
ENETC_TXBD_L4T_UDP);
|
||||
flags |= ENETC_TXBD_FLAGS_CSUM_LSO | ENETC_TXBD_FLAGS_L4CS;
|
||||
} else if (skb_checksum_help(skb)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
i = tx_ring->next_to_use;
|
||||
txbd = ENETC_TXBD(*tx_ring, i);
|
||||
prefetchw(txbd);
|
||||
@ -173,7 +217,6 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
|
||||
|
||||
temp_bd.addr = cpu_to_le64(dma);
|
||||
temp_bd.buf_len = cpu_to_le16(len);
|
||||
temp_bd.lstatus = 0;
|
||||
|
||||
tx_swbd = &tx_ring->tx_swbd[i];
|
||||
tx_swbd->dma = dma;
|
||||
@ -489,8 +532,233 @@ static void enetc_tso_complete_csum(struct enetc_bdr *tx_ring, struct tso_t *tso
|
||||
}
|
||||
}
|
||||
|
||||
static int enetc_lso_count_descs(const struct sk_buff *skb)
|
||||
{
|
||||
/* 4 BDs: 1 BD for LSO header + 1 BD for extended BD + 1 BD
|
||||
* for linear area data but not include LSO header, namely
|
||||
* skb_headlen(skb) - lso_hdr_len (it may be 0, but that's
|
||||
* okay, we only need to consider the worst case). And 1 BD
|
||||
* for gap.
|
||||
*/
|
||||
return skb_shinfo(skb)->nr_frags + 4;
|
||||
}
|
||||
|
||||
static int enetc_lso_get_hdr_len(const struct sk_buff *skb)
|
||||
{
|
||||
int hdr_len, tlen;
|
||||
|
||||
tlen = skb_is_gso_tcp(skb) ? tcp_hdrlen(skb) : sizeof(struct udphdr);
|
||||
hdr_len = skb_transport_offset(skb) + tlen;
|
||||
|
||||
return hdr_len;
|
||||
}
|
||||
|
||||
static void enetc_lso_start(struct sk_buff *skb, struct enetc_lso_t *lso)
|
||||
{
|
||||
lso->lso_seg_size = skb_shinfo(skb)->gso_size;
|
||||
lso->ipv6 = enetc_skb_is_ipv6(skb);
|
||||
lso->tcp = skb_is_gso_tcp(skb);
|
||||
lso->l3_hdr_len = skb_network_header_len(skb);
|
||||
lso->l3_start = skb_network_offset(skb);
|
||||
lso->hdr_len = enetc_lso_get_hdr_len(skb);
|
||||
lso->total_len = skb->len - lso->hdr_len;
|
||||
}
|
||||
|
||||
static void enetc_lso_map_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb,
|
||||
int *i, struct enetc_lso_t *lso)
|
||||
{
|
||||
union enetc_tx_bd txbd_tmp, *txbd;
|
||||
struct enetc_tx_swbd *tx_swbd;
|
||||
u16 frm_len, frm_len_ext;
|
||||
u8 flags, e_flags = 0;
|
||||
dma_addr_t addr;
|
||||
char *hdr;
|
||||
|
||||
/* Get the first BD of the LSO BDs chain */
|
||||
txbd = ENETC_TXBD(*tx_ring, *i);
|
||||
tx_swbd = &tx_ring->tx_swbd[*i];
|
||||
prefetchw(txbd);
|
||||
|
||||
/* Prepare LSO header: MAC + IP + TCP/UDP */
|
||||
hdr = tx_ring->tso_headers + *i * TSO_HEADER_SIZE;
|
||||
memcpy(hdr, skb->data, lso->hdr_len);
|
||||
addr = tx_ring->tso_headers_dma + *i * TSO_HEADER_SIZE;
|
||||
|
||||
/* {frm_len_ext, frm_len} indicates the total length of
|
||||
* large transmit data unit. frm_len contains the 16 least
|
||||
* significant bits and frm_len_ext contains the 4 most
|
||||
* significant bits.
|
||||
*/
|
||||
frm_len = lso->total_len & 0xffff;
|
||||
frm_len_ext = (lso->total_len >> 16) & 0xf;
|
||||
|
||||
/* Set the flags of the first BD */
|
||||
flags = ENETC_TXBD_FLAGS_EX | ENETC_TXBD_FLAGS_CSUM_LSO |
|
||||
ENETC_TXBD_FLAGS_LSO | ENETC_TXBD_FLAGS_L4CS;
|
||||
|
||||
enetc_clear_tx_bd(&txbd_tmp);
|
||||
txbd_tmp.addr = cpu_to_le64(addr);
|
||||
txbd_tmp.hdr_len = cpu_to_le16(lso->hdr_len);
|
||||
|
||||
/* first BD needs frm_len and offload flags set */
|
||||
txbd_tmp.frm_len = cpu_to_le16(frm_len);
|
||||
txbd_tmp.flags = flags;
|
||||
|
||||
txbd_tmp.l3_aux0 = FIELD_PREP(ENETC_TX_BD_L3_START, lso->l3_start);
|
||||
/* l3_hdr_size in 32-bits (4 bytes) */
|
||||
txbd_tmp.l3_aux1 = FIELD_PREP(ENETC_TX_BD_L3_HDR_LEN,
|
||||
lso->l3_hdr_len / 4);
|
||||
if (lso->ipv6)
|
||||
txbd_tmp.l3_aux1 |= ENETC_TX_BD_L3T;
|
||||
else
|
||||
txbd_tmp.l3_aux0 |= ENETC_TX_BD_IPCS;
|
||||
|
||||
txbd_tmp.l4_aux = FIELD_PREP(ENETC_TX_BD_L4T, lso->tcp ?
|
||||
ENETC_TXBD_L4T_TCP : ENETC_TXBD_L4T_UDP);
|
||||
|
||||
/* For the LSO header we do not set the dma address since
|
||||
* we do not want it unmapped when we do cleanup. We still
|
||||
* set len so that we count the bytes sent.
|
||||
*/
|
||||
tx_swbd->len = lso->hdr_len;
|
||||
tx_swbd->do_twostep_tstamp = false;
|
||||
tx_swbd->check_wb = false;
|
||||
|
||||
/* Actually write the header in the BD */
|
||||
*txbd = txbd_tmp;
|
||||
|
||||
/* Get the next BD, and the next BD is extended BD */
|
||||
enetc_bdr_idx_inc(tx_ring, i);
|
||||
txbd = ENETC_TXBD(*tx_ring, *i);
|
||||
tx_swbd = &tx_ring->tx_swbd[*i];
|
||||
prefetchw(txbd);
|
||||
|
||||
enetc_clear_tx_bd(&txbd_tmp);
|
||||
if (skb_vlan_tag_present(skb)) {
|
||||
/* Setup the VLAN fields */
|
||||
txbd_tmp.ext.vid = cpu_to_le16(skb_vlan_tag_get(skb));
|
||||
txbd_tmp.ext.tpid = ENETC_TPID_8021Q;
|
||||
e_flags = ENETC_TXBD_E_FLAGS_VLAN_INS;
|
||||
}
|
||||
|
||||
/* Write the BD */
|
||||
txbd_tmp.ext.e_flags = e_flags;
|
||||
txbd_tmp.ext.lso_sg_size = cpu_to_le16(lso->lso_seg_size);
|
||||
txbd_tmp.ext.frm_len_ext = cpu_to_le16(frm_len_ext);
|
||||
*txbd = txbd_tmp;
|
||||
}
|
||||
|
||||
static int enetc_lso_map_data(struct enetc_bdr *tx_ring, struct sk_buff *skb,
|
||||
int *i, struct enetc_lso_t *lso, int *count)
|
||||
{
|
||||
union enetc_tx_bd txbd_tmp, *txbd = NULL;
|
||||
struct enetc_tx_swbd *tx_swbd;
|
||||
skb_frag_t *frag;
|
||||
dma_addr_t dma;
|
||||
u8 flags = 0;
|
||||
int len, f;
|
||||
|
||||
len = skb_headlen(skb) - lso->hdr_len;
|
||||
if (len > 0) {
|
||||
dma = dma_map_single(tx_ring->dev, skb->data + lso->hdr_len,
|
||||
len, DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(tx_ring->dev, dma))
|
||||
return -ENOMEM;
|
||||
|
||||
enetc_bdr_idx_inc(tx_ring, i);
|
||||
txbd = ENETC_TXBD(*tx_ring, *i);
|
||||
tx_swbd = &tx_ring->tx_swbd[*i];
|
||||
prefetchw(txbd);
|
||||
*count += 1;
|
||||
|
||||
enetc_clear_tx_bd(&txbd_tmp);
|
||||
txbd_tmp.addr = cpu_to_le64(dma);
|
||||
txbd_tmp.buf_len = cpu_to_le16(len);
|
||||
|
||||
tx_swbd->dma = dma;
|
||||
tx_swbd->len = len;
|
||||
tx_swbd->is_dma_page = 0;
|
||||
tx_swbd->dir = DMA_TO_DEVICE;
|
||||
}
|
||||
|
||||
frag = &skb_shinfo(skb)->frags[0];
|
||||
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++, frag++) {
|
||||
if (txbd)
|
||||
*txbd = txbd_tmp;
|
||||
|
||||
len = skb_frag_size(frag);
|
||||
dma = skb_frag_dma_map(tx_ring->dev, frag);
|
||||
if (dma_mapping_error(tx_ring->dev, dma))
|
||||
return -ENOMEM;
|
||||
|
||||
/* Get the next BD */
|
||||
enetc_bdr_idx_inc(tx_ring, i);
|
||||
txbd = ENETC_TXBD(*tx_ring, *i);
|
||||
tx_swbd = &tx_ring->tx_swbd[*i];
|
||||
prefetchw(txbd);
|
||||
*count += 1;
|
||||
|
||||
enetc_clear_tx_bd(&txbd_tmp);
|
||||
txbd_tmp.addr = cpu_to_le64(dma);
|
||||
txbd_tmp.buf_len = cpu_to_le16(len);
|
||||
|
||||
tx_swbd->dma = dma;
|
||||
tx_swbd->len = len;
|
||||
tx_swbd->is_dma_page = 1;
|
||||
tx_swbd->dir = DMA_TO_DEVICE;
|
||||
}
|
||||
|
||||
/* Last BD needs 'F' bit set */
|
||||
flags |= ENETC_TXBD_FLAGS_F;
|
||||
txbd_tmp.flags = flags;
|
||||
*txbd = txbd_tmp;
|
||||
|
||||
tx_swbd->is_eof = 1;
|
||||
tx_swbd->skb = skb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int enetc_lso_hw_offload(struct enetc_bdr *tx_ring, struct sk_buff *skb)
|
||||
{
|
||||
struct enetc_tx_swbd *tx_swbd;
|
||||
struct enetc_lso_t lso = {0};
|
||||
int err, i, count = 0;
|
||||
|
||||
/* Initialize the LSO handler */
|
||||
enetc_lso_start(skb, &lso);
|
||||
i = tx_ring->next_to_use;
|
||||
|
||||
enetc_lso_map_hdr(tx_ring, skb, &i, &lso);
|
||||
/* First BD and an extend BD */
|
||||
count += 2;
|
||||
|
||||
err = enetc_lso_map_data(tx_ring, skb, &i, &lso, &count);
|
||||
if (err)
|
||||
goto dma_err;
|
||||
|
||||
/* Go to the next BD */
|
||||
enetc_bdr_idx_inc(tx_ring, &i);
|
||||
tx_ring->next_to_use = i;
|
||||
enetc_update_tx_ring_tail(tx_ring);
|
||||
|
||||
return count;
|
||||
|
||||
dma_err:
|
||||
do {
|
||||
tx_swbd = &tx_ring->tx_swbd[i];
|
||||
enetc_free_tx_frame(tx_ring, tx_swbd);
|
||||
if (i == 0)
|
||||
i = tx_ring->bd_count;
|
||||
i--;
|
||||
} while (--count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
|
||||
{
|
||||
struct enetc_ndev_priv *priv = netdev_priv(tx_ring->ndev);
|
||||
int hdr_len, total_len, data_len;
|
||||
struct enetc_tx_swbd *tx_swbd;
|
||||
union enetc_tx_bd *txbd;
|
||||
@ -556,7 +824,7 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb
|
||||
bd_data_num++;
|
||||
tso_build_data(skb, &tso, size);
|
||||
|
||||
if (unlikely(bd_data_num >= ENETC_MAX_SKB_FRAGS && data_len))
|
||||
if (unlikely(bd_data_num >= priv->max_frags && data_len))
|
||||
goto err_chained_bd;
|
||||
}
|
||||
|
||||
@ -594,7 +862,7 @@ static netdev_tx_t enetc_start_xmit(struct sk_buff *skb,
|
||||
{
|
||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||
struct enetc_bdr *tx_ring;
|
||||
int count, err;
|
||||
int count;
|
||||
|
||||
/* Queue one-step Sync packet if already locked */
|
||||
if (skb->cb[0] & ENETC_F_TX_ONESTEP_SYNC_TSTAMP) {
|
||||
@ -608,16 +876,28 @@ static netdev_tx_t enetc_start_xmit(struct sk_buff *skb,
|
||||
tx_ring = priv->tx_ring[skb->queue_mapping];
|
||||
|
||||
if (skb_is_gso(skb)) {
|
||||
if (enetc_bd_unused(tx_ring) < tso_count_descs(skb)) {
|
||||
netif_stop_subqueue(ndev, tx_ring->index);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
/* LSO data unit lengths of up to 256KB are supported */
|
||||
if (priv->active_offloads & ENETC_F_LSO &&
|
||||
(skb->len - enetc_lso_get_hdr_len(skb)) <=
|
||||
ENETC_LSO_MAX_DATA_LEN) {
|
||||
if (enetc_bd_unused(tx_ring) < enetc_lso_count_descs(skb)) {
|
||||
netif_stop_subqueue(ndev, tx_ring->index);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
enetc_lock_mdio();
|
||||
count = enetc_map_tx_tso_buffs(tx_ring, skb);
|
||||
enetc_unlock_mdio();
|
||||
count = enetc_lso_hw_offload(tx_ring, skb);
|
||||
} else {
|
||||
if (enetc_bd_unused(tx_ring) < tso_count_descs(skb)) {
|
||||
netif_stop_subqueue(ndev, tx_ring->index);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
enetc_lock_mdio();
|
||||
count = enetc_map_tx_tso_buffs(tx_ring, skb);
|
||||
enetc_unlock_mdio();
|
||||
}
|
||||
} else {
|
||||
if (unlikely(skb_shinfo(skb)->nr_frags > ENETC_MAX_SKB_FRAGS))
|
||||
if (unlikely(skb_shinfo(skb)->nr_frags > priv->max_frags))
|
||||
if (unlikely(skb_linearize(skb)))
|
||||
goto drop_packet_err;
|
||||
|
||||
@ -627,11 +907,6 @@ static netdev_tx_t enetc_start_xmit(struct sk_buff *skb,
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
err = skb_checksum_help(skb);
|
||||
if (err)
|
||||
goto drop_packet_err;
|
||||
}
|
||||
enetc_lock_mdio();
|
||||
count = enetc_map_tx_buffs(tx_ring, skb);
|
||||
enetc_unlock_mdio();
|
||||
@ -640,7 +915,7 @@ static netdev_tx_t enetc_start_xmit(struct sk_buff *skb,
|
||||
if (unlikely(!count))
|
||||
goto drop_packet_err;
|
||||
|
||||
if (enetc_bd_unused(tx_ring) < ENETC_TXBDS_MAX_NEEDED)
|
||||
if (enetc_bd_unused(tx_ring) < ENETC_TXBDS_MAX_NEEDED(priv->max_frags))
|
||||
netif_stop_subqueue(ndev, tx_ring->index);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
@ -908,7 +1183,8 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
|
||||
if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) &&
|
||||
__netif_subqueue_stopped(ndev, tx_ring->index) &&
|
||||
!test_bit(ENETC_TX_DOWN, &priv->flags) &&
|
||||
(enetc_bd_unused(tx_ring) >= ENETC_TXBDS_MAX_NEEDED))) {
|
||||
(enetc_bd_unused(tx_ring) >=
|
||||
ENETC_TXBDS_MAX_NEEDED(priv->max_frags)))) {
|
||||
netif_wake_subqueue(ndev, tx_ring->index);
|
||||
}
|
||||
|
||||
@ -1759,6 +2035,9 @@ void enetc_get_si_caps(struct enetc_si *si)
|
||||
rss = enetc_rd(hw, ENETC_SIRSSCAPR);
|
||||
si->num_rss = ENETC_SIRSSCAPR_GET_NUM_RSS(rss);
|
||||
}
|
||||
|
||||
if (val & ENETC_SIPCAPR0_LSO)
|
||||
si->hw_features |= ENETC_SI_F_LSO;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(enetc_get_si_caps);
|
||||
|
||||
@ -2055,6 +2334,14 @@ static int enetc_setup_default_rss_table(struct enetc_si *si, int num_groups)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void enetc_set_lso_flags_mask(struct enetc_hw *hw)
|
||||
{
|
||||
enetc_wr(hw, ENETC4_SILSOSFMR0,
|
||||
SILSOSFMR0_VAL_SET(ENETC4_TCP_NL_SEG_FLAGS_DMASK,
|
||||
ENETC4_TCP_NL_SEG_FLAGS_DMASK));
|
||||
enetc_wr(hw, ENETC4_SILSOSFMR1, 0);
|
||||
}
|
||||
|
||||
int enetc_configure_si(struct enetc_ndev_priv *priv)
|
||||
{
|
||||
struct enetc_si *si = priv->si;
|
||||
@ -2068,6 +2355,9 @@ int enetc_configure_si(struct enetc_ndev_priv *priv)
|
||||
/* enable SI */
|
||||
enetc_wr(hw, ENETC_SIMR, ENETC_SIMR_EN);
|
||||
|
||||
if (si->hw_features & ENETC_SI_F_LSO)
|
||||
enetc_set_lso_flags_mask(hw);
|
||||
|
||||
/* TODO: RSS support for i.MX95 will be supported later, and the
|
||||
* is_enetc_rev1() condition will be removed
|
||||
*/
|
||||
@ -3269,17 +3559,21 @@ EXPORT_SYMBOL_GPL(enetc_pci_remove);
|
||||
static const struct enetc_drvdata enetc_pf_data = {
|
||||
.sysclk_freq = ENETC_CLK_400M,
|
||||
.pmac_offset = ENETC_PMAC_OFFSET,
|
||||
.max_frags = ENETC_MAX_SKB_FRAGS,
|
||||
.eth_ops = &enetc_pf_ethtool_ops,
|
||||
};
|
||||
|
||||
static const struct enetc_drvdata enetc4_pf_data = {
|
||||
.sysclk_freq = ENETC_CLK_333M,
|
||||
.tx_csum = true,
|
||||
.max_frags = ENETC4_MAX_SKB_FRAGS,
|
||||
.pmac_offset = ENETC4_PMAC_OFFSET,
|
||||
.eth_ops = &enetc4_pf_ethtool_ops,
|
||||
};
|
||||
|
||||
static const struct enetc_drvdata enetc_vf_data = {
|
||||
.sysclk_freq = ENETC_CLK_400M,
|
||||
.max_frags = ENETC_MAX_SKB_FRAGS,
|
||||
.eth_ops = &enetc_vf_ethtool_ops,
|
||||
};
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user