From 2e30960097f6bc1a0dff89c0bcbc4138e3506d7c Mon Sep 17 00:00:00 2001 From: Jie Meng Date: Wed, 5 Oct 2022 10:00:39 -0700 Subject: bpf, x64: Remove unnecessary check on existence of SSE2 SSE2 and hence lfence are architectural in x86-64 and no need to check whether they're supported in CPU. SSE2's CPUID flag is still set to maintain backward compatibility with older code or code shared with x86, but bpf_jit_comp.c is compiled under x86-64 exclusively so the check is redundant. Signed-off-by: Jie Meng Signed-off-by: Daniel Borkmann Acked-by: KP Singh Link: https://lore.kernel.org/bpf/20221005170039.3936894-1-jmeng@fb.com --- arch/x86/net/bpf_jit_comp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 99620428ad78..0abd082786e7 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -1226,8 +1226,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image /* speculation barrier */ case BPF_ST | BPF_NOSPEC: - if (boot_cpu_has(X86_FEATURE_XMM2)) - EMIT_LFENCE(); + EMIT_LFENCE(); break; /* ST: *(u8*)(dst_reg + off) = imm */ -- cgit v1.2.3 From 2994bf7705b4dca2b0e4634d79d3474868562216 Mon Sep 17 00:00:00 2001 From: Marcin Wojtas Date: Fri, 14 Oct 2022 23:32:53 +0200 Subject: arm64: dts: marvell: Update network description to match schema Update the PP2 ethernet ports subnodes' names to match schema enforced by the marvell,pp2.yaml contents. Add new required properties ('reg') which contains information about the port ID, keeping 'port-id' ones for backward compatibility. Signed-off-by: Marcin Wojtas Signed-off-by: David S. Miller --- arch/arm64/boot/dts/marvell/armada-cp11x.dtsi | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi index d6c0990a267d..7d0043824f2a 100644 --- a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi @@ -58,6 +58,8 @@ ranges = <0x0 0x0 ADDRESSIFY(CP11X_BASE) 0x2000000>; CP11X_LABEL(ethernet): ethernet@0 { + #address-cells = <1>; + #size-cells = <0>; compatible = "marvell,armada-7k-pp22"; reg = <0x0 0x100000>, <0x129000 0xb000>, <0x220000 0x800>; clocks = <&CP11X_LABEL(clk) 1 3>, <&CP11X_LABEL(clk) 1 9>, @@ -69,7 +71,7 @@ status = "disabled"; dma-coherent; - CP11X_LABEL(eth0): eth0 { + CP11X_LABEL(eth0): ethernet-port@0 { interrupts = <39 IRQ_TYPE_LEVEL_HIGH>, <43 IRQ_TYPE_LEVEL_HIGH>, <47 IRQ_TYPE_LEVEL_HIGH>, @@ -83,12 +85,13 @@ interrupt-names = "hif0", "hif1", "hif2", "hif3", "hif4", "hif5", "hif6", "hif7", "hif8", "link"; - port-id = <0>; + reg = <0>; + port-id = <0>; /* For backward compatibility. */ gop-port-id = <0>; status = "disabled"; }; - CP11X_LABEL(eth1): eth1 { + CP11X_LABEL(eth1): ethernet-port@1 { interrupts = <40 IRQ_TYPE_LEVEL_HIGH>, <44 IRQ_TYPE_LEVEL_HIGH>, <48 IRQ_TYPE_LEVEL_HIGH>, @@ -102,12 +105,13 @@ interrupt-names = "hif0", "hif1", "hif2", "hif3", "hif4", "hif5", "hif6", "hif7", "hif8", "link"; - port-id = <1>; + reg = <1>; + port-id = <1>; /* For backward compatibility. */ gop-port-id = <2>; status = "disabled"; }; - CP11X_LABEL(eth2): eth2 { + CP11X_LABEL(eth2): ethernet-port@2 { interrupts = <41 IRQ_TYPE_LEVEL_HIGH>, <45 IRQ_TYPE_LEVEL_HIGH>, <49 IRQ_TYPE_LEVEL_HIGH>, @@ -121,7 +125,8 @@ interrupt-names = "hif0", "hif1", "hif2", "hif3", "hif4", "hif5", "hif6", "hif7", "hif8", "link"; - port-id = <2>; + reg = <2>; + port-id = <2>; /* For backward compatibility. */ gop-port-id = <3>; status = "disabled"; }; -- cgit v1.2.3 From 844e44988fa8f747f1a730b1e1586a9f3ca23c0e Mon Sep 17 00:00:00 2001 From: Marcin Wojtas Date: Fri, 14 Oct 2022 23:32:54 +0200 Subject: ARM: dts: armada-375: Update network description to match schema Update the PP2 ethernet ports subnodes' names to match schema enforced by the marvell,pp2.yaml contents. Add new required properties ('reg') which contains information about the port ID, keeping 'port-id' ones for backward compatibility. Signed-off-by: Marcin Wojtas Signed-off-by: David S. Miller --- arch/arm/boot/dts/armada-375.dtsi | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi index 929deaf312a5..9fbe0cfec48f 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -178,6 +178,8 @@ /* Network controller */ ethernet: ethernet@f0000 { + #address-cells = <1>; + #size-cells = <0>; compatible = "marvell,armada-375-pp2"; reg = <0xf0000 0xa000>, /* Packet Processor regs */ <0xc0000 0x3060>, /* LMS regs */ @@ -187,15 +189,17 @@ clock-names = "pp_clk", "gop_clk"; status = "disabled"; - eth0: eth0 { + eth0: ethernet-port@0 { interrupts = ; - port-id = <0>; + reg = <0>; + port-id = <0>; /* For backward compatibility. */ status = "disabled"; }; - eth1: eth1 { + eth1: ethernet-port@1 { interrupts = ; - port-id = <1>; + reg = <1>; + port-id = <1>; /* For backward compatibility. */ status = "disabled"; }; }; -- cgit v1.2.3 From 36926a7d70c2d462fca1ed85bfee000d17fd8662 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Mon, 17 Oct 2022 16:22:39 -0400 Subject: powerpc: dts: t208x: Mark MAC1 and MAC2 as 10G On the T208X SoCs, MAC1 and MAC2 support XGMII. Add some new MAC dtsi fragments, and mark the QMAN ports as 10G. Fixes: da414bb923d9 ("powerpc/mpc85xx: Add FSL QorIQ DPAA FMan support to the SoC device tree(s)") Signed-off-by: Sean Anderson Signed-off-by: David S. Miller --- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi | 44 ++++++++++++++++++++++ arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi | 44 ++++++++++++++++++++++ arch/powerpc/boot/dts/fsl/t2081si-post.dtsi | 4 +- 3 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi (limited to 'arch') diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi new file mode 100644 index 000000000000..437dab3fc017 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later +/* + * QorIQ FMan v3 10g port #2 device tree stub [ controller @ offset 0x400000 ] + * + * Copyright 2022 Sean Anderson + * Copyright 2012 - 2015 Freescale Semiconductor Inc. + */ + +fman@400000 { + fman0_rx_0x08: port@88000 { + cell-index = <0x8>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x88000 0x1000>; + fsl,fman-10g-port; + }; + + fman0_tx_0x28: port@a8000 { + cell-index = <0x28>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xa8000 0x1000>; + fsl,fman-10g-port; + }; + + ethernet@e0000 { + cell-index = <0>; + compatible = "fsl,fman-memac"; + reg = <0xe0000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; + ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy0>; + }; + + mdio@e1000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xe1000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ + + pcsphy0: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi new file mode 100644 index 000000000000..ad116b17850a --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later +/* + * QorIQ FMan v3 10g port #3 device tree stub [ controller @ offset 0x400000 ] + * + * Copyright 2022 Sean Anderson + * Copyright 2012 - 2015 Freescale Semiconductor Inc. + */ + +fman@400000 { + fman0_rx_0x09: port@89000 { + cell-index = <0x9>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x89000 0x1000>; + fsl,fman-10g-port; + }; + + fman0_tx_0x29: port@a9000 { + cell-index = <0x29>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xa9000 0x1000>; + fsl,fman-10g-port; + }; + + ethernet@e2000 { + cell-index = <1>; + compatible = "fsl,fman-memac"; + reg = <0xe2000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; + ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy1>; + }; + + mdio@e3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xe3000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ + + pcsphy1: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; diff --git a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi index ecbb447920bc..74e17e134387 100644 --- a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi @@ -609,8 +609,8 @@ /include/ "qoriq-bman1.dtsi" /include/ "qoriq-fman3-0.dtsi" -/include/ "qoriq-fman3-0-1g-0.dtsi" -/include/ "qoriq-fman3-0-1g-1.dtsi" +/include/ "qoriq-fman3-0-10g-2.dtsi" +/include/ "qoriq-fman3-0-10g-3.dtsi" /include/ "qoriq-fman3-0-1g-2.dtsi" /include/ "qoriq-fman3-0-1g-3.dtsi" /include/ "qoriq-fman3-0-1g-4.dtsi" -- cgit v1.2.3 From 4e31b808fad1f7c505f916e844000aa9dcbd2ccf Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Mon, 17 Oct 2022 16:22:40 -0400 Subject: powerpc: dts: qoriq: Add nodes for QSGMII PCSs Now that we actually read registers from QSGMII PCSs, it's important that we have the correct address (instead of hoping that we're the MAC with all the QSGMII PCSs on its bus). This adds nodes for the QSGMII PCSs. They have the same addresses on all SoCs (e.g. if QSGMIIA is present it's used for MACs 1 through 4). Since the first QSGMII PCSs share an address with the SGMII and XFI PCSs, we only add new nodes for PCSs 2-4. This avoids address conflicts on the bus. Signed-off-by: Sean Anderson Signed-off-by: David S. Miller --- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi | 3 ++- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi | 10 +++++++++- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi | 10 +++++++++- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi | 10 +++++++++- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi | 3 ++- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi | 3 ++- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi | 3 ++- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi | 10 +++++++++- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi | 10 +++++++++- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi | 10 +++++++++- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi | 3 ++- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi | 10 +++++++++- arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi | 10 +++++++++- arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi | 10 +++++++++- arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi | 3 ++- arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi | 10 +++++++++- arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi | 10 +++++++++- arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi | 10 +++++++++- arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi | 3 ++- arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi | 10 +++++++++- 20 files changed, 131 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi index baa0c503e741..7e70977f282a 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi @@ -55,7 +55,8 @@ fman@400000 { reg = <0xe0000 0x1000>; fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; ptp-timer = <&ptp_timer0>; - pcsphy-handle = <&pcsphy0>; + pcsphy-handle = <&pcsphy0>, <&pcsphy0>; + pcs-handle-names = "sgmii", "qsgmii"; }; mdio@e1000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi index 93095600e808..5f89f7c1761f 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi @@ -52,7 +52,15 @@ fman@400000 { compatible = "fsl,fman-memac"; reg = <0xf0000 0x1000>; fsl,fman-ports = <&fman0_rx_0x10 &fman0_tx_0x30>; - pcsphy-handle = <&pcsphy6>; + pcsphy-handle = <&pcsphy6>, <&qsgmiib_pcs2>, <&pcsphy6>; + pcs-handle-names = "sgmii", "qsgmii", "xfi"; + }; + + mdio@e9000 { + qsgmiib_pcs2: ethernet-pcs@2 { + compatible = "fsl,lynx-pcs"; + reg = <2>; + }; }; mdio@f1000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi index ff4bd38f0645..71eb75e82c2e 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi @@ -55,7 +55,15 @@ fman@400000 { reg = <0xe2000 0x1000>; fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; ptp-timer = <&ptp_timer0>; - pcsphy-handle = <&pcsphy1>; + pcsphy-handle = <&pcsphy1>, <&qsgmiia_pcs1>; + pcs-handle-names = "sgmii", "qsgmii"; + }; + + mdio@e1000 { + qsgmiia_pcs1: ethernet-pcs@1 { + compatible = "fsl,lynx-pcs"; + reg = <1>; + }; }; mdio@e3000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi index 1fa38ed6f59e..fb7032ddb7fc 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi @@ -52,7 +52,15 @@ fman@400000 { compatible = "fsl,fman-memac"; reg = <0xf2000 0x1000>; fsl,fman-ports = <&fman0_rx_0x11 &fman0_tx_0x31>; - pcsphy-handle = <&pcsphy7>; + pcsphy-handle = <&pcsphy7>, <&qsgmiib_pcs3>, <&pcsphy7>; + pcs-handle-names = "sgmii", "qsgmii", "xfi"; + }; + + mdio@e9000 { + qsgmiib_pcs3: ethernet-pcs@3 { + compatible = "fsl,lynx-pcs"; + reg = <3>; + }; }; mdio@f3000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi index 437dab3fc017..6b3609574b0f 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi @@ -27,7 +27,8 @@ fman@400000 { reg = <0xe0000 0x1000>; fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; ptp-timer = <&ptp_timer0>; - pcsphy-handle = <&pcsphy0>; + pcsphy-handle = <&pcsphy0>, <&pcsphy0>; + pcs-handle-names = "sgmii", "xfi"; }; mdio@e1000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi index ad116b17850a..28ed1a85a436 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi @@ -27,7 +27,8 @@ fman@400000 { reg = <0xe2000 0x1000>; fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; ptp-timer = <&ptp_timer0>; - pcsphy-handle = <&pcsphy1>; + pcsphy-handle = <&pcsphy1>, <&pcsphy1>; + pcs-handle-names = "sgmii", "xfi"; }; mdio@e3000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi index a8cc9780c0c4..1089d6861bfb 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi @@ -51,7 +51,8 @@ fman@400000 { reg = <0xe0000 0x1000>; fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; ptp-timer = <&ptp_timer0>; - pcsphy-handle = <&pcsphy0>; + pcsphy-handle = <&pcsphy0>, <&pcsphy0>; + pcs-handle-names = "sgmii", "qsgmii"; }; mdio@e1000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi index 8b8bd70c9382..a95bbb4fc827 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi @@ -51,7 +51,15 @@ fman@400000 { reg = <0xe2000 0x1000>; fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; ptp-timer = <&ptp_timer0>; - pcsphy-handle = <&pcsphy1>; + pcsphy-handle = <&pcsphy1>, <&qsgmiia_pcs1>; + pcs-handle-names = "sgmii", "qsgmii"; + }; + + mdio@e1000 { + qsgmiia_pcs1: ethernet-pcs@1 { + compatible = "fsl,lynx-pcs"; + reg = <1>; + }; }; mdio@e3000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi index 619c880b54d8..7d5af0147a25 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi @@ -51,7 +51,15 @@ fman@400000 { reg = <0xe4000 0x1000>; fsl,fman-ports = <&fman0_rx_0x0a &fman0_tx_0x2a>; ptp-timer = <&ptp_timer0>; - pcsphy-handle = <&pcsphy2>; + pcsphy-handle = <&pcsphy2>, <&qsgmiia_pcs2>; + pcs-handle-names = "sgmii", "qsgmii"; + }; + + mdio@e1000 { + qsgmiia_pcs2: ethernet-pcs@2 { + compatible = "fsl,lynx-pcs"; + reg = <2>; + }; }; mdio@e5000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi index d7ebb73a400d..61e5466ec854 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi @@ -51,7 +51,15 @@ fman@400000 { reg = <0xe6000 0x1000>; fsl,fman-ports = <&fman0_rx_0x0b &fman0_tx_0x2b>; ptp-timer = <&ptp_timer0>; - pcsphy-handle = <&pcsphy3>; + pcsphy-handle = <&pcsphy3>, <&qsgmiia_pcs3>; + pcs-handle-names = "sgmii", "qsgmii"; + }; + + mdio@e1000 { + qsgmiia_pcs3: ethernet-pcs@3 { + compatible = "fsl,lynx-pcs"; + reg = <3>; + }; }; mdio@e7000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi index b151d696a069..3ba0cdafc069 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi @@ -51,7 +51,8 @@ fman@400000 { reg = <0xe8000 0x1000>; fsl,fman-ports = <&fman0_rx_0x0c &fman0_tx_0x2c>; ptp-timer = <&ptp_timer0>; - pcsphy-handle = <&pcsphy4>; + pcsphy-handle = <&pcsphy4>, <&pcsphy4>; + pcs-handle-names = "sgmii", "qsgmii"; }; mdio@e9000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi index adc0ae0013a3..51748de0a289 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi @@ -51,7 +51,15 @@ fman@400000 { reg = <0xea000 0x1000>; fsl,fman-ports = <&fman0_rx_0x0d &fman0_tx_0x2d>; ptp-timer = <&ptp_timer0>; - pcsphy-handle = <&pcsphy5>; + pcsphy-handle = <&pcsphy5>, <&qsgmiib_pcs1>; + pcs-handle-names = "sgmii", "qsgmii"; + }; + + mdio@e9000 { + qsgmiib_pcs1: ethernet-pcs@1 { + compatible = "fsl,lynx-pcs"; + reg = <1>; + }; }; mdio@eb000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi index 435047e0e250..ee4f5170f632 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi @@ -52,7 +52,15 @@ fman@500000 { compatible = "fsl,fman-memac"; reg = <0xf0000 0x1000>; fsl,fman-ports = <&fman1_rx_0x10 &fman1_tx_0x30>; - pcsphy-handle = <&pcsphy14>; + pcsphy-handle = <&pcsphy14>, <&qsgmiid_pcs2>, <&pcsphy14>; + pcs-handle-names = "sgmii", "qsgmii", "xfi"; + }; + + mdio@e9000 { + qsgmiid_pcs2: ethernet-pcs@2 { + compatible = "fsl,lynx-pcs"; + reg = <2>; + }; }; mdio@f1000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi index c098657cca0a..83d2e0ce8f7b 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi @@ -52,7 +52,15 @@ fman@500000 { compatible = "fsl,fman-memac"; reg = <0xf2000 0x1000>; fsl,fman-ports = <&fman1_rx_0x11 &fman1_tx_0x31>; - pcsphy-handle = <&pcsphy15>; + pcsphy-handle = <&pcsphy15>, <&qsgmiid_pcs3>, <&pcsphy15>; + pcs-handle-names = "sgmii", "qsgmii", "xfi"; + }; + + mdio@e9000 { + qsgmiid_pcs3: ethernet-pcs@3 { + compatible = "fsl,lynx-pcs"; + reg = <3>; + }; }; mdio@f3000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi index 9d06824815f3..3132fc73f133 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi @@ -51,7 +51,8 @@ fman@500000 { reg = <0xe0000 0x1000>; fsl,fman-ports = <&fman1_rx_0x08 &fman1_tx_0x28>; ptp-timer = <&ptp_timer1>; - pcsphy-handle = <&pcsphy8>; + pcsphy-handle = <&pcsphy8>, <&pcsphy8>; + pcs-handle-names = "sgmii", "qsgmii"; }; mdio@e1000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi index 70e947730c4b..75e904d96602 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi @@ -51,7 +51,15 @@ fman@500000 { reg = <0xe2000 0x1000>; fsl,fman-ports = <&fman1_rx_0x09 &fman1_tx_0x29>; ptp-timer = <&ptp_timer1>; - pcsphy-handle = <&pcsphy9>; + pcsphy-handle = <&pcsphy9>, <&qsgmiic_pcs1>; + pcs-handle-names = "sgmii", "qsgmii"; + }; + + mdio@e1000 { + qsgmiic_pcs1: ethernet-pcs@1 { + compatible = "fsl,lynx-pcs"; + reg = <1>; + }; }; mdio@e3000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi index ad96e6529595..69f2cc7b8f19 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi @@ -51,7 +51,15 @@ fman@500000 { reg = <0xe4000 0x1000>; fsl,fman-ports = <&fman1_rx_0x0a &fman1_tx_0x2a>; ptp-timer = <&ptp_timer1>; - pcsphy-handle = <&pcsphy10>; + pcsphy-handle = <&pcsphy10>, <&qsgmiic_pcs2>; + pcs-handle-names = "sgmii", "qsgmii"; + }; + + mdio@e1000 { + qsgmiic_pcs2: ethernet-pcs@2 { + compatible = "fsl,lynx-pcs"; + reg = <2>; + }; }; mdio@e5000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi index 034bc4b71f7a..b3aaf01d7da0 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi @@ -51,7 +51,15 @@ fman@500000 { reg = <0xe6000 0x1000>; fsl,fman-ports = <&fman1_rx_0x0b &fman1_tx_0x2b>; ptp-timer = <&ptp_timer1>; - pcsphy-handle = <&pcsphy11>; + pcsphy-handle = <&pcsphy11>, <&qsgmiic_pcs3>; + pcs-handle-names = "sgmii", "qsgmii"; + }; + + mdio@e1000 { + qsgmiic_pcs3: ethernet-pcs@3 { + compatible = "fsl,lynx-pcs"; + reg = <3>; + }; }; mdio@e7000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi index 93ca23d82b39..18e020432807 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi @@ -51,7 +51,8 @@ fman@500000 { reg = <0xe8000 0x1000>; fsl,fman-ports = <&fman1_rx_0x0c &fman1_tx_0x2c>; ptp-timer = <&ptp_timer1>; - pcsphy-handle = <&pcsphy12>; + pcsphy-handle = <&pcsphy12>, <&pcsphy12>; + pcs-handle-names = "sgmii", "qsgmii"; }; mdio@e9000 { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi index 23b3117a2fd2..55f329d13f19 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi @@ -51,7 +51,15 @@ fman@500000 { reg = <0xea000 0x1000>; fsl,fman-ports = <&fman1_rx_0x0d &fman1_tx_0x2d>; ptp-timer = <&ptp_timer1>; - pcsphy-handle = <&pcsphy13>; + pcsphy-handle = <&pcsphy13>, <&qsgmiid_pcs1>; + pcs-handle-names = "sgmii", "qsgmii"; + }; + + mdio@e9000 { + qsgmiid_pcs1: ethernet-pcs@1 { + compatible = "fsl,lynx-pcs"; + reg = <1>; + }; }; mdio@eb000 { -- cgit v1.2.3 From 4e748b1bd7c06c9f744b873939aef8982d81dcaf Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Mon, 17 Oct 2022 16:22:41 -0400 Subject: arm64: dts: layerscape: Add nodes for QSGMII PCSs Now that we actually read registers from QSGMII PCSs, it's important that we have the correct address (instead of hoping that we're the MAC with all the QSGMII PCSs on its bus). This adds nodes for the QSGMII PCSs. The exact mapping of QSGMII to MACs depends on the SoC. Since the first QSGMII PCSs share an address with the SGMII and XFI PCSs, we only add new nodes for PCSs 2-4. This avoids address conflicts on the bus. Signed-off-by: Sean Anderson Signed-off-by: David S. Miller --- arch/arm64/boot/dts/freescale/fsl-ls1043-post.dtsi | 24 +++++++++++++++++++++ arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi | 25 ++++++++++++++++++++++ 2 files changed, 49 insertions(+) (limited to 'arch') diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043-post.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043-post.dtsi index d237162a8744..5c4d7eef8b61 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043-post.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043-post.dtsi @@ -24,9 +24,12 @@ /* these aliases provide the FMan ports mapping */ enet0: ethernet@e0000 { + pcs-handle-names = "qsgmii"; }; enet1: ethernet@e2000 { + pcsphy-handle = <&pcsphy1>, <&qsgmiib_pcs1>; + pcs-handle-names = "sgmii", "qsgmii"; }; enet2: ethernet@e4000 { @@ -36,11 +39,32 @@ }; enet4: ethernet@e8000 { + pcsphy-handle = <&pcsphy4>, <&qsgmiib_pcs2>; + pcs-handle-names = "sgmii", "qsgmii"; }; enet5: ethernet@ea000 { + pcsphy-handle = <&pcsphy5>, <&qsgmiib_pcs3>; + pcs-handle-names = "sgmii", "qsgmii"; }; enet6: ethernet@f0000 { }; + + mdio@e1000 { + qsgmiib_pcs1: ethernet-pcs@1 { + compatible = "fsl,lynx-pcs"; + reg = <0x1>; + }; + + qsgmiib_pcs2: ethernet-pcs@2 { + compatible = "fsl,lynx-pcs"; + reg = <0x2>; + }; + + qsgmiib_pcs3: ethernet-pcs@3 { + compatible = "fsl,lynx-pcs"; + reg = <0x3>; + }; + }; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi index d6caaea57d90..4e3345093943 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi @@ -23,6 +23,8 @@ &fman0 { /* these aliases provide the FMan ports mapping */ enet0: ethernet@e0000 { + pcsphy-handle = <&qsgmiib_pcs3>; + pcs-handle-names = "qsgmii"; }; enet1: ethernet@e2000 { @@ -35,14 +37,37 @@ }; enet4: ethernet@e8000 { + pcsphy-handle = <&pcsphy4>, <&qsgmiib_pcs1>; + pcs-handle-names = "sgmii", "qsgmii"; }; enet5: ethernet@ea000 { + pcsphy-handle = <&pcsphy5>, <&pcsphy5>; + pcs-handle-names = "sgmii", "qsgmii"; }; enet6: ethernet@f0000 { }; enet7: ethernet@f2000 { + pcsphy-handle = <&pcsphy7>, <&qsgmiib_pcs2>, <&pcsphy7>; + pcs-handle-names = "sgmii", "qsgmii", "xfi"; + }; + + mdio@eb000 { + qsgmiib_pcs1: ethernet-pcs@1 { + compatible = "fsl,lynx-pcs"; + reg = <0x1>; + }; + + qsgmiib_pcs2: ethernet-pcs@2 { + compatible = "fsl,lynx-pcs"; + reg = <0x2>; + }; + + qsgmiib_pcs3: ethernet-pcs@3 { + compatible = "fsl,lynx-pcs"; + reg = <0x3>; + }; }; }; -- cgit v1.2.3 From 81b35e7cad790eecf9f359662804bb26055ac7e8 Mon Sep 17 00:00:00 2001 From: Jie Meng Date: Fri, 7 Oct 2022 13:23:47 -0700 Subject: bpf,x64: avoid unnecessary instructions when shift dest is ecx x64 JIT produces redundant instructions when a shift operation's destination register is BPF_REG_4/ecx and this patch removes them. Specifically, when dest reg is BPF_REG_4 but the src isn't, we needn't push and pop ecx around shift only to get it overwritten by r11 immediately afterwards. In the rare case when both dest and src registers are BPF_REG_4, a single shift instruction is sufficient and we don't need the two MOV instructions around the shift. To summarize using shift left as an example, without patch: ------------------------------------------------- | dst == ecx | dst != ecx ================================================= src == ecx | mov r11, ecx | shl dst, cl | shl r11, ecx | | mov ecx, r11 | ------------------------------------------------- src != ecx | mov r11, ecx | push ecx | push ecx | mov ecx, src | mov ecx, src | shl dst, cl | shl r11, cl | pop ecx | pop ecx | | mov ecx, r11 | ------------------------------------------------- With patch: ------------------------------------------------- | dst == ecx | dst != ecx ================================================= src == ecx | shl ecx, cl | shl dst, cl ------------------------------------------------- src != ecx | mov r11, ecx | push ecx | mov ecx, src | mov ecx, src | shl r11, cl | shl dst, cl | mov ecx, r11 | pop ecx ------------------------------------------------- Signed-off-by: Jie Meng Link: https://lore.kernel.org/r/20221007202348.1118830-2-jmeng@fb.com Signed-off-by: Alexei Starovoitov --- arch/x86/net/bpf_jit_comp.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 0abd082786e7..d926ca637d8d 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -1138,16 +1138,15 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image case BPF_ALU64 | BPF_RSH | BPF_X: case BPF_ALU64 | BPF_ARSH | BPF_X: - /* Check for bad case when dst_reg == rcx */ - if (dst_reg == BPF_REG_4) { - /* mov r11, dst_reg */ - EMIT_mov(AUX_REG, dst_reg); - dst_reg = AUX_REG; - } - if (src_reg != BPF_REG_4) { /* common case */ - EMIT1(0x51); /* push rcx */ - + /* Check for bad case when dst_reg == rcx */ + if (dst_reg == BPF_REG_4) { + /* mov r11, dst_reg */ + EMIT_mov(AUX_REG, dst_reg); + dst_reg = AUX_REG; + } else { + EMIT1(0x51); /* push rcx */ + } /* mov rcx, src_reg */ EMIT_mov(BPF_REG_4, src_reg); } @@ -1159,12 +1158,14 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image b3 = simple_alu_opcodes[BPF_OP(insn->code)]; EMIT2(0xD3, add_1reg(b3, dst_reg)); - if (src_reg != BPF_REG_4) - EMIT1(0x59); /* pop rcx */ + if (src_reg != BPF_REG_4) { + if (insn->dst_reg == BPF_REG_4) + /* mov dst_reg, r11 */ + EMIT_mov(insn->dst_reg, AUX_REG); + else + EMIT1(0x59); /* pop rcx */ + } - if (insn->dst_reg == BPF_REG_4) - /* mov dst_reg, r11 */ - EMIT_mov(insn->dst_reg, AUX_REG); break; case BPF_ALU | BPF_END | BPF_FROM_BE: -- cgit v1.2.3 From 77d8f5d47bfbb5f0a8630102838ffb22cd70d6f5 Mon Sep 17 00:00:00 2001 From: Jie Meng Date: Fri, 7 Oct 2022 13:23:48 -0700 Subject: bpf,x64: use shrx/sarx/shlx when available BMI2 provides 3 shift instructions (shrx, sarx and shlx) that use VEX encoding but target general purpose registers [1]. They allow the shift count in any general purpose register and have the same performance as non BMI2 shift instructions [2]. Instead of shr/sar/shl that implicitly use %cl (lowest 8 bit of %rcx), emit their more flexible alternatives provided in BMI2 when advantageous; keep using the non BMI2 instructions when shift count is already in BPF_REG_4/%rcx as non BMI2 instructions are shorter. To summarize, when BMI2 is available: ------------------------------------------------- | arbitrary dst ================================================= src == ecx | shl dst, cl ------------------------------------------------- src != ecx | shlx dst, dst, src ------------------------------------------------- And no additional register shuffling is needed. A concrete example between non BMI2 and BMI2 codegen. To shift %rsi by %rdi: Without BMI2: ef3: push %rcx 51 ef4: mov %rdi,%rcx 48 89 f9 ef7: shl %cl,%rsi 48 d3 e6 efa: pop %rcx 59 With BMI2: f0b: shlx %rdi,%rsi,%rsi c4 e2 c1 f7 f6 [1] https://en.wikipedia.org/wiki/X86_Bit_manipulation_instruction_set [2] https://www.agner.org/optimize/instruction_tables.pdf Signed-off-by: Jie Meng Link: https://lore.kernel.org/r/20221007202348.1118830-3-jmeng@fb.com Signed-off-by: Alexei Starovoitov --- arch/x86/net/bpf_jit_comp.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'arch') diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index d926ca637d8d..d7dd8e0db8da 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -891,6 +891,65 @@ static void emit_nops(u8 **pprog, int len) *pprog = prog; } +/* emit the 3-byte VEX prefix + * + * r: same as rex.r, extra bit for ModRM reg field + * x: same as rex.x, extra bit for SIB index field + * b: same as rex.b, extra bit for ModRM r/m, or SIB base + * m: opcode map select, encoding escape bytes e.g. 0x0f38 + * w: same as rex.w (32 bit or 64 bit) or opcode specific + * src_reg2: additional source reg (encoded as BPF reg) + * l: vector length (128 bit or 256 bit) or reserved + * pp: opcode prefix (none, 0x66, 0xf2 or 0xf3) + */ +static void emit_3vex(u8 **pprog, bool r, bool x, bool b, u8 m, + bool w, u8 src_reg2, bool l, u8 pp) +{ + u8 *prog = *pprog; + const u8 b0 = 0xc4; /* first byte of 3-byte VEX prefix */ + u8 b1, b2; + u8 vvvv = reg2hex[src_reg2]; + + /* reg2hex gives only the lower 3 bit of vvvv */ + if (is_ereg(src_reg2)) + vvvv |= 1 << 3; + + /* + * 2nd byte of 3-byte VEX prefix + * ~ means bit inverted encoding + * + * 7 0 + * +---+---+---+---+---+---+---+---+ + * |~R |~X |~B | m | + * +---+---+---+---+---+---+---+---+ + */ + b1 = (!r << 7) | (!x << 6) | (!b << 5) | (m & 0x1f); + /* + * 3rd byte of 3-byte VEX prefix + * + * 7 0 + * +---+---+---+---+---+---+---+---+ + * | W | ~vvvv | L | pp | + * +---+---+---+---+---+---+---+---+ + */ + b2 = (w << 7) | ((~vvvv & 0xf) << 3) | (l << 2) | (pp & 3); + + EMIT3(b0, b1, b2); + *pprog = prog; +} + +/* emit BMI2 shift instruction */ +static void emit_shiftx(u8 **pprog, u32 dst_reg, u8 src_reg, bool is64, u8 op) +{ + u8 *prog = *pprog; + bool r = is_ereg(dst_reg); + u8 m = 2; /* escape code 0f38 */ + + emit_3vex(&prog, r, false, r, m, is64, src_reg, false, op); + EMIT2(0xf7, add_2reg(0xC0, dst_reg, dst_reg)); + *pprog = prog; +} + #define INSN_SZ_DIFF (((addrs[i] - addrs[i - 1]) - (prog - temp))) static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image, @@ -1137,6 +1196,28 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image case BPF_ALU64 | BPF_LSH | BPF_X: case BPF_ALU64 | BPF_RSH | BPF_X: case BPF_ALU64 | BPF_ARSH | BPF_X: + /* BMI2 shifts aren't better when shift count is already in rcx */ + if (boot_cpu_has(X86_FEATURE_BMI2) && src_reg != BPF_REG_4) { + /* shrx/sarx/shlx dst_reg, dst_reg, src_reg */ + bool w = (BPF_CLASS(insn->code) == BPF_ALU64); + u8 op; + + switch (BPF_OP(insn->code)) { + case BPF_LSH: + op = 1; /* prefix 0x66 */ + break; + case BPF_RSH: + op = 3; /* prefix 0xf2 */ + break; + case BPF_ARSH: + op = 2; /* prefix 0xf3 */ + break; + } + + emit_shiftx(&prog, dst_reg, src_reg, w, op); + + break; + } if (src_reg != BPF_REG_4) { /* common case */ /* Check for bad case when dst_reg == rcx */ -- cgit v1.2.3 From 271de525e1d7f564e88a9d212c50998b49a54476 Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Tue, 25 Oct 2022 11:45:16 -0700 Subject: bpf: Remove prog->active check for bpf_lsm and bpf_iter The commit 64696c40d03c ("bpf: Add __bpf_prog_{enter,exit}_struct_ops for struct_ops trampoline") removed prog->active check for struct_ops prog. The bpf_lsm and bpf_iter is also using trampoline. Like struct_ops, the bpf_lsm and bpf_iter have fixed hooks for the prog to attach. The kernel does not call the same hook in a recursive way. This patch also removes the prog->active check for bpf_lsm and bpf_iter. A later patch has a test to reproduce the recursion issue for a sleepable bpf_lsm program. This patch appends the '_recur' naming to the existing enter and exit functions that track the prog->active counter. New __bpf_prog_{enter,exit}[_sleepable] function are added to skip the prog->active tracking. The '_struct_ops' version is also removed. It also moves the decision on picking the enter and exit function to the new bpf_trampoline_{enter,exit}(). It returns the '_recur' ones for all tracing progs to use. For bpf_lsm, bpf_iter, struct_ops (no prog->active tracking after 64696c40d03c), and bpf_lsm_cgroup (no prog->active tracking after 69fd337a975c7), it will return the functions that don't track the prog->active. Signed-off-by: Martin KaFai Lau Link: https://lore.kernel.org/r/20221025184524.3526117-2-martin.lau@linux.dev Signed-off-by: Alexei Starovoitov --- arch/arm64/net/bpf_jit_comp.c | 9 ++--- arch/x86/net/bpf_jit_comp.c | 19 ++-------- include/linux/bpf.h | 24 ++++++------- include/linux/bpf_verifier.h | 15 +++++++- kernel/bpf/syscall.c | 5 +-- kernel/bpf/trampoline.c | 80 ++++++++++++++++++++++++++++++++++++------- 6 files changed, 98 insertions(+), 54 deletions(-) (limited to 'arch') diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index 30f76178608b..62f805f427b7 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -1649,13 +1649,8 @@ static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l, struct bpf_prog *p = l->link.prog; int cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie); - if (p->aux->sleepable) { - enter_prog = (u64)__bpf_prog_enter_sleepable; - exit_prog = (u64)__bpf_prog_exit_sleepable; - } else { - enter_prog = (u64)__bpf_prog_enter; - exit_prog = (u64)__bpf_prog_exit; - } + enter_prog = (u64)bpf_trampoline_enter(p); + exit_prog = (u64)bpf_trampoline_exit(p); if (l->cookie == 0) { /* if cookie is zero, one instruction is enough to store it */ diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index d7dd8e0db8da..36ffe67ad6e5 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -1894,10 +1894,6 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog, struct bpf_tramp_link *l, int stack_size, int run_ctx_off, bool save_ret) { - void (*exit)(struct bpf_prog *prog, u64 start, - struct bpf_tramp_run_ctx *run_ctx) = __bpf_prog_exit; - u64 (*enter)(struct bpf_prog *prog, - struct bpf_tramp_run_ctx *run_ctx) = __bpf_prog_enter; u8 *prog = *pprog; u8 *jmp_insn; int ctx_cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie); @@ -1916,23 +1912,12 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog, */ emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_1, -run_ctx_off + ctx_cookie_off); - if (p->aux->sleepable) { - enter = __bpf_prog_enter_sleepable; - exit = __bpf_prog_exit_sleepable; - } else if (p->type == BPF_PROG_TYPE_STRUCT_OPS) { - enter = __bpf_prog_enter_struct_ops; - exit = __bpf_prog_exit_struct_ops; - } else if (p->expected_attach_type == BPF_LSM_CGROUP) { - enter = __bpf_prog_enter_lsm_cgroup; - exit = __bpf_prog_exit_lsm_cgroup; - } - /* arg1: mov rdi, progs[i] */ emit_mov_imm64(&prog, BPF_REG_1, (long) p >> 32, (u32) (long) p); /* arg2: lea rsi, [rbp - ctx_cookie_off] */ EMIT4(0x48, 0x8D, 0x75, -run_ctx_off); - if (emit_call(&prog, enter, prog)) + if (emit_call(&prog, bpf_trampoline_enter(p), prog)) return -EINVAL; /* remember prog start time returned by __bpf_prog_enter */ emit_mov_reg(&prog, true, BPF_REG_6, BPF_REG_0); @@ -1977,7 +1962,7 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog, emit_mov_reg(&prog, true, BPF_REG_2, BPF_REG_6); /* arg3: lea rdx, [rbp - run_ctx_off] */ EMIT4(0x48, 0x8D, 0x55, -run_ctx_off); - if (emit_call(&prog, exit, prog)) + if (emit_call(&prog, bpf_trampoline_exit(p), prog)) return -EINVAL; *pprog = prog; diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 9e7d46d16032..1279e699dc98 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -854,22 +854,18 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *tr, void *image, void *i const struct btf_func_model *m, u32 flags, struct bpf_tramp_links *tlinks, void *orig_call); -/* these two functions are called from generated trampoline */ -u64 notrace __bpf_prog_enter(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx); -void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, struct bpf_tramp_run_ctx *run_ctx); -u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx); -void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start, - struct bpf_tramp_run_ctx *run_ctx); -u64 notrace __bpf_prog_enter_lsm_cgroup(struct bpf_prog *prog, - struct bpf_tramp_run_ctx *run_ctx); -void notrace __bpf_prog_exit_lsm_cgroup(struct bpf_prog *prog, u64 start, - struct bpf_tramp_run_ctx *run_ctx); -u64 notrace __bpf_prog_enter_struct_ops(struct bpf_prog *prog, - struct bpf_tramp_run_ctx *run_ctx); -void notrace __bpf_prog_exit_struct_ops(struct bpf_prog *prog, u64 start, - struct bpf_tramp_run_ctx *run_ctx); +u64 notrace __bpf_prog_enter_sleepable_recur(struct bpf_prog *prog, + struct bpf_tramp_run_ctx *run_ctx); +void notrace __bpf_prog_exit_sleepable_recur(struct bpf_prog *prog, u64 start, + struct bpf_tramp_run_ctx *run_ctx); void notrace __bpf_tramp_enter(struct bpf_tramp_image *tr); void notrace __bpf_tramp_exit(struct bpf_tramp_image *tr); +typedef u64 (*bpf_trampoline_enter_t)(struct bpf_prog *prog, + struct bpf_tramp_run_ctx *run_ctx); +typedef void (*bpf_trampoline_exit_t)(struct bpf_prog *prog, u64 start, + struct bpf_tramp_run_ctx *run_ctx); +bpf_trampoline_enter_t bpf_trampoline_enter(const struct bpf_prog *prog); +bpf_trampoline_exit_t bpf_trampoline_exit(const struct bpf_prog *prog); struct bpf_ksym { unsigned long start; diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 9e1e6965f407..1a32baa78ce2 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -642,10 +642,23 @@ static inline u32 type_flag(u32 type) } /* only use after check_attach_btf_id() */ -static inline enum bpf_prog_type resolve_prog_type(struct bpf_prog *prog) +static inline enum bpf_prog_type resolve_prog_type(const struct bpf_prog *prog) { return prog->type == BPF_PROG_TYPE_EXT ? prog->aux->dst_prog->type : prog->type; } +static inline bool bpf_prog_check_recur(const struct bpf_prog *prog) +{ + switch (resolve_prog_type(prog)) { + case BPF_PROG_TYPE_TRACING: + return prog->expected_attach_type != BPF_TRACE_ITER; + case BPF_PROG_TYPE_STRUCT_OPS: + case BPF_PROG_TYPE_LSM: + return false; + default: + return true; + } +} + #endif /* _LINUX_BPF_VERIFIER_H */ diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 7b373a5e861f..a0b4266196a8 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -5133,13 +5133,14 @@ int kern_sys_bpf(int cmd, union bpf_attr *attr, unsigned int size) run_ctx.bpf_cookie = 0; run_ctx.saved_run_ctx = NULL; - if (!__bpf_prog_enter_sleepable(prog, &run_ctx)) { + if (!__bpf_prog_enter_sleepable_recur(prog, &run_ctx)) { /* recursion detected */ bpf_prog_put(prog); return -EBUSY; } attr->test.retval = bpf_prog_run(prog, (void *) (long) attr->test.ctx_in); - __bpf_prog_exit_sleepable(prog, 0 /* bpf_prog_run does runtime stats */, &run_ctx); + __bpf_prog_exit_sleepable_recur(prog, 0 /* bpf_prog_run does runtime stats */, + &run_ctx); bpf_prog_put(prog); return 0; #endif diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index bf0906e1e2b9..d6395215b849 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -864,7 +864,7 @@ static __always_inline u64 notrace bpf_prog_start_time(void) * [2..MAX_U64] - execute bpf prog and record execution time. * This is start time. */ -u64 notrace __bpf_prog_enter(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx) +static u64 notrace __bpf_prog_enter_recur(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx) __acquires(RCU) { rcu_read_lock(); @@ -901,7 +901,8 @@ static void notrace update_prog_stats(struct bpf_prog *prog, } } -void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, struct bpf_tramp_run_ctx *run_ctx) +static void notrace __bpf_prog_exit_recur(struct bpf_prog *prog, u64 start, + struct bpf_tramp_run_ctx *run_ctx) __releases(RCU) { bpf_reset_run_ctx(run_ctx->saved_run_ctx); @@ -912,8 +913,8 @@ void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, struct bpf_tramp_ rcu_read_unlock(); } -u64 notrace __bpf_prog_enter_lsm_cgroup(struct bpf_prog *prog, - struct bpf_tramp_run_ctx *run_ctx) +static u64 notrace __bpf_prog_enter_lsm_cgroup(struct bpf_prog *prog, + struct bpf_tramp_run_ctx *run_ctx) __acquires(RCU) { /* Runtime stats are exported via actual BPF_LSM_CGROUP @@ -927,8 +928,8 @@ u64 notrace __bpf_prog_enter_lsm_cgroup(struct bpf_prog *prog, return NO_START_TIME; } -void notrace __bpf_prog_exit_lsm_cgroup(struct bpf_prog *prog, u64 start, - struct bpf_tramp_run_ctx *run_ctx) +static void notrace __bpf_prog_exit_lsm_cgroup(struct bpf_prog *prog, u64 start, + struct bpf_tramp_run_ctx *run_ctx) __releases(RCU) { bpf_reset_run_ctx(run_ctx->saved_run_ctx); @@ -937,7 +938,8 @@ void notrace __bpf_prog_exit_lsm_cgroup(struct bpf_prog *prog, u64 start, rcu_read_unlock(); } -u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx) +u64 notrace __bpf_prog_enter_sleepable_recur(struct bpf_prog *prog, + struct bpf_tramp_run_ctx *run_ctx) { rcu_read_lock_trace(); migrate_disable(); @@ -953,8 +955,8 @@ u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, struct bpf_tramp_r return bpf_prog_start_time(); } -void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start, - struct bpf_tramp_run_ctx *run_ctx) +void notrace __bpf_prog_exit_sleepable_recur(struct bpf_prog *prog, u64 start, + struct bpf_tramp_run_ctx *run_ctx) { bpf_reset_run_ctx(run_ctx->saved_run_ctx); @@ -964,8 +966,30 @@ void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start, rcu_read_unlock_trace(); } -u64 notrace __bpf_prog_enter_struct_ops(struct bpf_prog *prog, - struct bpf_tramp_run_ctx *run_ctx) +static u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, + struct bpf_tramp_run_ctx *run_ctx) +{ + rcu_read_lock_trace(); + migrate_disable(); + might_fault(); + + run_ctx->saved_run_ctx = bpf_set_run_ctx(&run_ctx->run_ctx); + + return bpf_prog_start_time(); +} + +static void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start, + struct bpf_tramp_run_ctx *run_ctx) +{ + bpf_reset_run_ctx(run_ctx->saved_run_ctx); + + update_prog_stats(prog, start); + migrate_enable(); + rcu_read_unlock_trace(); +} + +static u64 notrace __bpf_prog_enter(struct bpf_prog *prog, + struct bpf_tramp_run_ctx *run_ctx) __acquires(RCU) { rcu_read_lock(); @@ -976,8 +1000,8 @@ u64 notrace __bpf_prog_enter_struct_ops(struct bpf_prog *prog, return bpf_prog_start_time(); } -void notrace __bpf_prog_exit_struct_ops(struct bpf_prog *prog, u64 start, - struct bpf_tramp_run_ctx *run_ctx) +static void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, + struct bpf_tramp_run_ctx *run_ctx) __releases(RCU) { bpf_reset_run_ctx(run_ctx->saved_run_ctx); @@ -997,6 +1021,36 @@ void notrace __bpf_tramp_exit(struct bpf_tramp_image *tr) percpu_ref_put(&tr->pcref); } +bpf_trampoline_enter_t bpf_trampoline_enter(const struct bpf_prog *prog) +{ + bool sleepable = prog->aux->sleepable; + + if (bpf_prog_check_recur(prog)) + return sleepable ? __bpf_prog_enter_sleepable_recur : + __bpf_prog_enter_recur; + + if (resolve_prog_type(prog) == BPF_PROG_TYPE_LSM && + prog->expected_attach_type == BPF_LSM_CGROUP) + return __bpf_prog_enter_lsm_cgroup; + + return sleepable ? __bpf_prog_enter_sleepable : __bpf_prog_enter; +} + +bpf_trampoline_exit_t bpf_trampoline_exit(const struct bpf_prog *prog) +{ + bool sleepable = prog->aux->sleepable; + + if (bpf_prog_check_recur(prog)) + return sleepable ? __bpf_prog_exit_sleepable_recur : + __bpf_prog_exit_recur; + + if (resolve_prog_type(prog) == BPF_PROG_TYPE_LSM && + prog->expected_attach_type == BPF_LSM_CGROUP) + return __bpf_prog_exit_lsm_cgroup; + + return sleepable ? __bpf_prog_exit_sleepable : __bpf_prog_exit; +} + int __weak arch_prepare_bpf_trampoline(struct bpf_tramp_image *tr, void *image, void *image_end, const struct btf_func_model *m, u32 flags, -- cgit v1.2.3 From d5e2d038dbece821f1af57acbeded3aa9a1832c1 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 25 Oct 2022 11:42:54 -0700 Subject: eth: fealnx: delete the driver for Myson MTD-800 The git history for this driver seems to be completely automated / tree wide changes. I can't find any boards or systems which would use this chip. Google search shows pictures of towel warmers and no networking products. Signed-off-by: Jakub Kicinski Reviewed-by: Leon Romanovsky Link: https://lore.kernel.org/r/20221025184254.1717982-1-kuba@kernel.org Signed-off-by: Paolo Abeni --- arch/mips/configs/mtx1_defconfig | 1 - arch/powerpc/configs/ppc6xx_defconfig | 1 - drivers/net/ethernet/Kconfig | 10 - drivers/net/ethernet/Makefile | 1 - drivers/net/ethernet/fealnx.c | 1953 --------------------------------- 5 files changed, 1966 deletions(-) delete mode 100644 drivers/net/ethernet/fealnx.c (limited to 'arch') diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index edf9634aa8ee..89a1511d2ee4 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -284,7 +284,6 @@ CONFIG_IXGB=m CONFIG_SKGE=m CONFIG_SKY2=m CONFIG_MYRI10GE=m -CONFIG_FEALNX=m CONFIG_NATSEMI=m CONFIG_NS83820=m CONFIG_S2IO=m diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index d23deb94b36e..115d40be5481 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -461,7 +461,6 @@ CONFIG_MV643XX_ETH=m CONFIG_SKGE=m CONFIG_SKY2=m CONFIG_MYRI10GE=m -CONFIG_FEALNX=m CONFIG_NATSEMI=m CONFIG_NS83820=m CONFIG_PCMCIA_AXNET=m diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index 1917da784191..323ec56e8a74 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig @@ -132,16 +132,6 @@ source "drivers/net/ethernet/mscc/Kconfig" source "drivers/net/ethernet/microsoft/Kconfig" source "drivers/net/ethernet/moxa/Kconfig" source "drivers/net/ethernet/myricom/Kconfig" - -config FEALNX - tristate "Myson MTD-8xx PCI Ethernet support" - depends on PCI - select CRC32 - select MII - help - Say Y here to support the Myson MTD-800 family of PCI-based Ethernet - cards. - source "drivers/net/ethernet/ni/Kconfig" source "drivers/net/ethernet/natsemi/Kconfig" source "drivers/net/ethernet/neterion/Kconfig" diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index 0d872d4efcd1..2fedbaa545eb 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile @@ -64,7 +64,6 @@ obj-$(CONFIG_NET_VENDOR_MICROCHIP) += microchip/ obj-$(CONFIG_NET_VENDOR_MICROSEMI) += mscc/ obj-$(CONFIG_NET_VENDOR_MOXART) += moxa/ obj-$(CONFIG_NET_VENDOR_MYRI) += myricom/ -obj-$(CONFIG_FEALNX) += fealnx.o obj-$(CONFIG_NET_VENDOR_NATSEMI) += natsemi/ obj-$(CONFIG_NET_VENDOR_NETERION) += neterion/ obj-$(CONFIG_NET_VENDOR_NETRONOME) += netronome/ diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c deleted file mode 100644 index ed18450fd2cc..000000000000 --- a/drivers/net/ethernet/fealnx.c +++ /dev/null @@ -1,1953 +0,0 @@ -/* - Written 1998-2000 by Donald Becker. - - This software may be used and distributed according to the terms of - the GNU General Public License (GPL), incorporated herein by reference. - Drivers based on or derived from this code fall under the GPL and must - retain the authorship, copyright and license notice. This file is not - a complete program and may only be used when the entire operating - system is licensed under the GPL. - - The author may be reached as becker@scyld.com, or C/O - Scyld Computing Corporation - 410 Severn Ave., Suite 210 - Annapolis MD 21403 - - Support information and updates available at - http://www.scyld.com/network/pci-skeleton.html - - Linux kernel updates: - - Version 2.51, Nov 17, 2001 (jgarzik): - - Add ethtool support - - Replace some MII-related magic numbers with constants - -*/ - -#define DRV_NAME "fealnx" - -static int debug; /* 1-> print debug message */ -static int max_interrupt_work = 20; - -/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). */ -static int multicast_filter_limit = 32; - -/* Set the copy breakpoint for the copy-only-tiny-frames scheme. */ -/* Setting to > 1518 effectively disables this feature. */ -static int rx_copybreak; - -/* Used to pass the media type, etc. */ -/* Both 'options[]' and 'full_duplex[]' should exist for driver */ -/* interoperability. */ -/* The media type is usually passed in 'options[]'. */ -#define MAX_UNITS 8 /* More are supported, limit only on options */ -static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; - -/* Operational parameters that are set at compile time. */ -/* Keep the ring sizes a power of two for compile efficiency. */ -/* The compiler will convert '%'<2^N> into a bit mask. */ -/* Making the Tx ring too large decreases the effectiveness of channel */ -/* bonding and packet priority. */ -/* There are no ill effects from too-large receive rings. */ -// 88-12-9 modify, -// #define TX_RING_SIZE 16 -// #define RX_RING_SIZE 32 -#define TX_RING_SIZE 6 -#define RX_RING_SIZE 12 -#define TX_TOTAL_SIZE TX_RING_SIZE*sizeof(struct fealnx_desc) -#define RX_TOTAL_SIZE RX_RING_SIZE*sizeof(struct fealnx_desc) - -/* Operational parameters that usually are not changed. */ -/* Time in jiffies before concluding the transmitter is hung. */ -#define TX_TIMEOUT (2*HZ) - -#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */ - - -/* Include files, designed to support most kernel versions 2.0.0 and later. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include /* Processor type for cache alignment. */ -#include -#include -#include - -/* This driver was written to use PCI memory space, however some x86 systems - work only with I/O space accesses. */ -#ifndef __alpha__ -#define USE_IO_OPS -#endif - -/* Kernel compatibility defines, some common to David Hinds' PCMCIA package. */ -/* This is only in the support-all-kernels source code. */ - -#define RUN_AT(x) (jiffies + (x)) - -MODULE_AUTHOR("Myson or whoever"); -MODULE_DESCRIPTION("Myson MTD-8xx 100/10M Ethernet PCI Adapter Driver"); -MODULE_LICENSE("GPL"); -module_param(max_interrupt_work, int, 0); -module_param(debug, int, 0); -module_param(rx_copybreak, int, 0); -module_param(multicast_filter_limit, int, 0); -module_param_array(options, int, NULL, 0); -module_param_array(full_duplex, int, NULL, 0); -MODULE_PARM_DESC(max_interrupt_work, "fealnx maximum events handled per interrupt"); -MODULE_PARM_DESC(debug, "fealnx enable debugging (0-1)"); -MODULE_PARM_DESC(rx_copybreak, "fealnx copy breakpoint for copy-only-tiny-frames"); -MODULE_PARM_DESC(multicast_filter_limit, "fealnx maximum number of filtered multicast addresses"); -MODULE_PARM_DESC(options, "fealnx: Bits 0-3: media type, bit 17: full duplex"); -MODULE_PARM_DESC(full_duplex, "fealnx full duplex setting(s) (1)"); - -enum { - MIN_REGION_SIZE = 136, -}; - -/* A chip capabilities table, matching the entries in pci_tbl[] above. */ -enum chip_capability_flags { - HAS_MII_XCVR, - HAS_CHIP_XCVR, -}; - -/* 89/6/13 add, */ -/* for different PHY */ -enum phy_type_flags { - MysonPHY = 1, - AhdocPHY = 2, - SeeqPHY = 3, - MarvellPHY = 4, - Myson981 = 5, - LevelOnePHY = 6, - OtherPHY = 10, -}; - -struct chip_info { - char *chip_name; - int flags; -}; - -static const struct chip_info skel_netdrv_tbl[] = { - { "100/10M Ethernet PCI Adapter", HAS_MII_XCVR }, - { "100/10M Ethernet PCI Adapter", HAS_CHIP_XCVR }, - { "1000/100/10M Ethernet PCI Adapter", HAS_MII_XCVR }, -}; - -/* Offsets to the Command and Status Registers. */ -enum fealnx_offsets { - PAR0 = 0x0, /* physical address 0-3 */ - PAR1 = 0x04, /* physical address 4-5 */ - MAR0 = 0x08, /* multicast address 0-3 */ - MAR1 = 0x0C, /* multicast address 4-7 */ - FAR0 = 0x10, /* flow-control address 0-3 */ - FAR1 = 0x14, /* flow-control address 4-5 */ - TCRRCR = 0x18, /* receive & transmit configuration */ - BCR = 0x1C, /* bus command */ - TXPDR = 0x20, /* transmit polling demand */ - RXPDR = 0x24, /* receive polling demand */ - RXCWP = 0x28, /* receive current word pointer */ - TXLBA = 0x2C, /* transmit list base address */ - RXLBA = 0x30, /* receive list base address */ - ISR = 0x34, /* interrupt status */ - IMR = 0x38, /* interrupt mask */ - FTH = 0x3C, /* flow control high/low threshold */ - MANAGEMENT = 0x40, /* bootrom/eeprom and mii management */ - TALLY = 0x44, /* tally counters for crc and mpa */ - TSR = 0x48, /* tally counter for transmit status */ - BMCRSR = 0x4c, /* basic mode control and status */ - PHYIDENTIFIER = 0x50, /* phy identifier */ - ANARANLPAR = 0x54, /* auto-negotiation advertisement and link - partner ability */ - ANEROCR = 0x58, /* auto-negotiation expansion and pci conf. */ - BPREMRPSR = 0x5c, /* bypass & receive error mask and phy status */ -}; - -/* Bits in the interrupt status/enable registers. */ -/* The bits in the Intr Status/Enable registers, mostly interrupt sources. */ -enum intr_status_bits { - RFCON = 0x00020000, /* receive flow control xon packet */ - RFCOFF = 0x00010000, /* receive flow control xoff packet */ - LSCStatus = 0x00008000, /* link status change */ - ANCStatus = 0x00004000, /* autonegotiation completed */ - FBE = 0x00002000, /* fatal bus error */ - FBEMask = 0x00001800, /* mask bit12-11 */ - ParityErr = 0x00000000, /* parity error */ - TargetErr = 0x00001000, /* target abort */ - MasterErr = 0x00000800, /* master error */ - TUNF = 0x00000400, /* transmit underflow */ - ROVF = 0x00000200, /* receive overflow */ - ETI = 0x00000100, /* transmit early int */ - ERI = 0x00000080, /* receive early int */ - CNTOVF = 0x00000040, /* counter overflow */ - RBU = 0x00000020, /* receive buffer unavailable */ - TBU = 0x00000010, /* transmit buffer unavilable */ - TI = 0x00000008, /* transmit interrupt */ - RI = 0x00000004, /* receive interrupt */ - RxErr = 0x00000002, /* receive error */ -}; - -/* Bits in the NetworkConfig register, W for writing, R for reading */ -/* FIXME: some names are invented by me. Marked with (name?) */ -/* If you have docs and know bit names, please fix 'em */ -enum rx_mode_bits { - CR_W_ENH = 0x02000000, /* enhanced mode (name?) */ - CR_W_FD = 0x00100000, /* full duplex */ - CR_W_PS10 = 0x00080000, /* 10 mbit */ - CR_W_TXEN = 0x00040000, /* tx enable (name?) */ - CR_W_PS1000 = 0x00010000, /* 1000 mbit */ - /* CR_W_RXBURSTMASK= 0x00000e00, Im unsure about this */ - CR_W_RXMODEMASK = 0x000000e0, - CR_W_PROM = 0x00000080, /* promiscuous mode */ - CR_W_AB = 0x00000040, /* accept broadcast */ - CR_W_AM = 0x00000020, /* accept mutlicast */ - CR_W_ARP = 0x00000008, /* receive runt pkt */ - CR_W_ALP = 0x00000004, /* receive long pkt */ - CR_W_SEP = 0x00000002, /* receive error pkt */ - CR_W_RXEN = 0x00000001, /* rx enable (unicast?) (name?) */ - - CR_R_TXSTOP = 0x04000000, /* tx stopped (name?) */ - CR_R_FD = 0x00100000, /* full duplex detected */ - CR_R_PS10 = 0x00080000, /* 10 mbit detected */ - CR_R_RXSTOP = 0x00008000, /* rx stopped (name?) */ -}; - -/* The Tulip Rx and Tx buffer descriptors. */ -struct fealnx_desc { - s32 status; - s32 control; - u32 buffer; - u32 next_desc; - struct fealnx_desc *next_desc_logical; - struct sk_buff *skbuff; - u32 reserved1; - u32 reserved2; -}; - -/* Bits in network_desc.status */ -enum rx_desc_status_bits { - RXOWN = 0x80000000, /* own bit */ - FLNGMASK = 0x0fff0000, /* frame length */ - FLNGShift = 16, - MARSTATUS = 0x00004000, /* multicast address received */ - BARSTATUS = 0x00002000, /* broadcast address received */ - PHYSTATUS = 0x00001000, /* physical address received */ - RXFSD = 0x00000800, /* first descriptor */ - RXLSD = 0x00000400, /* last descriptor */ - ErrorSummary = 0x80, /* error summary */ - RUNTPKT = 0x40, /* runt packet received */ - LONGPKT = 0x20, /* long packet received */ - FAE = 0x10, /* frame align error */ - CRC = 0x08, /* crc error */ - RXER = 0x04, /* receive error */ -}; - -enum rx_desc_control_bits { - RXIC = 0x00800000, /* interrupt control */ - RBSShift = 0, -}; - -enum tx_desc_status_bits { - TXOWN = 0x80000000, /* own bit */ - JABTO = 0x00004000, /* jabber timeout */ - CSL = 0x00002000, /* carrier sense lost */ - LC = 0x00001000, /* late collision */ - EC = 0x00000800, /* excessive collision */ - UDF = 0x00000400, /* fifo underflow */ - DFR = 0x00000200, /* deferred */ - HF = 0x00000100, /* heartbeat fail */ - NCRMask = 0x000000ff, /* collision retry count */ - NCRShift = 0, -}; - -enum tx_desc_control_bits { - TXIC = 0x80000000, /* interrupt control */ - ETIControl = 0x40000000, /* early transmit interrupt */ - TXLD = 0x20000000, /* last descriptor */ - TXFD = 0x10000000, /* first descriptor */ - CRCEnable = 0x08000000, /* crc control */ - PADEnable = 0x04000000, /* padding control */ - RetryTxLC = 0x02000000, /* retry late collision */ - PKTSMask = 0x3ff800, /* packet size bit21-11 */ - PKTSShift = 11, - TBSMask = 0x000007ff, /* transmit buffer bit 10-0 */ - TBSShift = 0, -}; - -/* BootROM/EEPROM/MII Management Register */ -#define MASK_MIIR_MII_READ 0x00000000 -#define MASK_MIIR_MII_WRITE 0x00000008 -#define MASK_MIIR_MII_MDO 0x00000004 -#define MASK_MIIR_MII_MDI 0x00000002 -#define MASK_MIIR_MII_MDC 0x00000001 - -/* ST+OP+PHYAD+REGAD+TA */ -#define OP_READ 0x6000 /* ST:01+OP:10+PHYAD+REGAD+TA:Z0 */ -#define OP_WRITE 0x5002 /* ST:01+OP:01+PHYAD+REGAD+TA:10 */ - -/* ------------------------------------------------------------------------- */ -/* Constants for Myson PHY */ -/* ------------------------------------------------------------------------- */ -#define MysonPHYID 0xd0000302 -/* 89-7-27 add, (begin) */ -#define MysonPHYID0 0x0302 -#define StatusRegister 18 -#define SPEED100 0x0400 // bit10 -#define FULLMODE 0x0800 // bit11 -/* 89-7-27 add, (end) */ - -/* ------------------------------------------------------------------------- */ -/* Constants for Seeq 80225 PHY */ -/* ------------------------------------------------------------------------- */ -#define SeeqPHYID0 0x0016 - -#define MIIRegister18 18 -#define SPD_DET_100 0x80 -#define DPLX_DET_FULL 0x40 - -/* ------------------------------------------------------------------------- */ -/* Constants for Ahdoc 101 PHY */ -/* ------------------------------------------------------------------------- */ -#define AhdocPHYID0 0x0022 - -#define DiagnosticReg 18 -#define DPLX_FULL 0x0800 -#define Speed_100 0x0400 - -/* 89/6/13 add, */ -/* -------------------------------------------------------------------------- */ -/* Constants */ -/* -------------------------------------------------------------------------- */ -#define MarvellPHYID0 0x0141 -#define LevelOnePHYID0 0x0013 - -#define MII1000BaseTControlReg 9 -#define MII1000BaseTStatusReg 10 -#define SpecificReg 17 - -/* for 1000BaseT Control Register */ -#define PHYAbletoPerform1000FullDuplex 0x0200 -#define PHYAbletoPerform1000HalfDuplex 0x0100 -#define PHY1000AbilityMask 0x300 - -// for phy specific status register, marvell phy. -#define SpeedMask 0x0c000 -#define Speed_1000M 0x08000 -#define Speed_100M 0x4000 -#define Speed_10M 0 -#define Full_Duplex 0x2000 - -// 89/12/29 add, for phy specific status register, levelone phy, (begin) -#define LXT1000_100M 0x08000 -#define LXT1000_1000M 0x0c000 -#define LXT1000_Full 0x200 -// 89/12/29 add, for phy specific status register, levelone phy, (end) - -/* for 3-in-1 case, BMCRSR register */ -#define LinkIsUp2 0x00040000 - -/* for PHY */ -#define LinkIsUp 0x0004 - - -struct netdev_private { - /* Descriptor rings first for alignment. */ - struct fealnx_desc *rx_ring; - struct fealnx_desc *tx_ring; - - dma_addr_t rx_ring_dma; - dma_addr_t tx_ring_dma; - - spinlock_t lock; - - /* Media monitoring timer. */ - struct timer_list timer; - - /* Reset timer */ - struct timer_list reset_timer; - int reset_timer_armed; - unsigned long crvalue_sv; - unsigned long imrvalue_sv; - - /* Frequently used values: keep some adjacent for cache effect. */ - int flags; - struct pci_dev *pci_dev; - unsigned long crvalue; - unsigned long bcrvalue; - unsigned long imrvalue; - struct fealnx_desc *cur_rx; - struct fealnx_desc *lack_rxbuf; - int really_rx_count; - struct fealnx_desc *cur_tx; - struct fealnx_desc *cur_tx_copy; - int really_tx_count; - int free_tx_count; - unsigned int rx_buf_sz; /* Based on MTU+slack. */ - - /* These values are keep track of the transceiver/media in use. */ - unsigned int linkok; - unsigned int line_speed; - unsigned int duplexmode; - unsigned int default_port:4; /* Last dev->if_port value. */ - unsigned int PHYType; - - /* MII transceiver section. */ - int mii_cnt; /* MII device addresses. */ - unsigned char phys[2]; /* MII device addresses. */ - struct mii_if_info mii; - void __iomem *mem; -}; - - -static int mdio_read(struct net_device *dev, int phy_id, int location); -static void mdio_write(struct net_device *dev, int phy_id, int location, int value); -static int netdev_open(struct net_device *dev); -static void getlinktype(struct net_device *dev); -static void getlinkstatus(struct net_device *dev); -static void netdev_timer(struct timer_list *t); -static void reset_timer(struct timer_list *t); -static void fealnx_tx_timeout(struct net_device *dev, unsigned int txqueue); -static void init_ring(struct net_device *dev); -static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t intr_handler(int irq, void *dev_instance); -static int netdev_rx(struct net_device *dev); -static void set_rx_mode(struct net_device *dev); -static void __set_rx_mode(struct net_device *dev); -static struct net_device_stats *get_stats(struct net_device *dev); -static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static const struct ethtool_ops netdev_ethtool_ops; -static int netdev_close(struct net_device *dev); -static void reset_rx_descriptors(struct net_device *dev); -static void reset_tx_descriptors(struct net_device *dev); - -static void stop_nic_rx(void __iomem *ioaddr, long crvalue) -{ - int delay = 0x1000; - iowrite32(crvalue & ~(CR_W_RXEN), ioaddr + TCRRCR); - while (--delay) { - if ( (ioread32(ioaddr + TCRRCR) & CR_R_RXSTOP) == CR_R_RXSTOP) - break; - } -} - - -static void stop_nic_rxtx(void __iomem *ioaddr, long crvalue) -{ - int delay = 0x1000; - iowrite32(crvalue & ~(CR_W_RXEN+CR_W_TXEN), ioaddr + TCRRCR); - while (--delay) { - if ( (ioread32(ioaddr + TCRRCR) & (CR_R_RXSTOP+CR_R_TXSTOP)) - == (CR_R_RXSTOP+CR_R_TXSTOP) ) - break; - } -} - -static const struct net_device_ops netdev_ops = { - .ndo_open = netdev_open, - .ndo_stop = netdev_close, - .ndo_start_xmit = start_tx, - .ndo_get_stats = get_stats, - .ndo_set_rx_mode = set_rx_mode, - .ndo_eth_ioctl = mii_ioctl, - .ndo_tx_timeout = fealnx_tx_timeout, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -static int fealnx_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct netdev_private *np; - int i, option, err, irq; - static int card_idx = -1; - char boardname[12]; - void __iomem *ioaddr; - unsigned long len; - unsigned int chip_id = ent->driver_data; - struct net_device *dev; - void *ring_space; - dma_addr_t ring_dma; - u8 addr[ETH_ALEN]; -#ifdef USE_IO_OPS - int bar = 0; -#else - int bar = 1; -#endif - - card_idx++; - sprintf(boardname, "fealnx%d", card_idx); - - option = card_idx < MAX_UNITS ? options[card_idx] : 0; - - i = pci_enable_device(pdev); - if (i) return i; - pci_set_master(pdev); - - len = pci_resource_len(pdev, bar); - if (len < MIN_REGION_SIZE) { - dev_err(&pdev->dev, - "region size %ld too small, aborting\n", len); - return -ENODEV; - } - - i = pci_request_regions(pdev, boardname); - if (i) - return i; - - irq = pdev->irq; - - ioaddr = pci_iomap(pdev, bar, len); - if (!ioaddr) { - err = -ENOMEM; - goto err_out_res; - } - - dev = alloc_etherdev(sizeof(struct netdev_private)); - if (!dev) { - err = -ENOMEM; - goto err_out_unmap; - } - SET_NETDEV_DEV(dev, &pdev->dev); - - /* read ethernet id */ - for (i = 0; i < 6; ++i) - addr[i] = ioread8(ioaddr + PAR0 + i); - eth_hw_addr_set(dev, addr); - - /* Reset the chip to erase previous misconfiguration. */ - iowrite32(0x00000001, ioaddr + BCR); - - /* Make certain the descriptor lists are aligned. */ - np = netdev_priv(dev); - np->mem = ioaddr; - spin_lock_init(&np->lock); - np->pci_dev = pdev; - np->flags = skel_netdrv_tbl[chip_id].flags; - pci_set_drvdata(pdev, dev); - np->mii.dev = dev; - np->mii.mdio_read = mdio_read; - np->mii.mdio_write = mdio_write; - np->mii.phy_id_mask = 0x1f; - np->mii.reg_num_mask = 0x1f; - - ring_space = dma_alloc_coherent(&pdev->dev, RX_TOTAL_SIZE, &ring_dma, - GFP_KERNEL); - if (!ring_space) { - err = -ENOMEM; - goto err_out_free_dev; - } - np->rx_ring = ring_space; - np->rx_ring_dma = ring_dma; - - ring_space = dma_alloc_coherent(&pdev->dev, TX_TOTAL_SIZE, &ring_dma, - GFP_KERNEL); - if (!ring_space) { - err = -ENOMEM; - goto err_out_free_rx; - } - np->tx_ring = ring_space; - np->tx_ring_dma = ring_dma; - - /* find the connected MII xcvrs */ - if (np->flags == HAS_MII_XCVR) { - int phy, phy_idx = 0; - - for (phy = 1; phy < 32 && phy_idx < ARRAY_SIZE(np->phys); - phy++) { - int mii_status = mdio_read(dev, phy, 1); - - if (mii_status != 0xffff && mii_status != 0x0000) { - np->phys[phy_idx++] = phy; - dev_info(&pdev->dev, - "MII PHY found at address %d, status " - "0x%4.4x.\n", phy, mii_status); - /* get phy type */ - { - unsigned int data; - - data = mdio_read(dev, np->phys[0], 2); - if (data == SeeqPHYID0) - np->PHYType = SeeqPHY; - else if (data == AhdocPHYID0) - np->PHYType = AhdocPHY; - else if (data == MarvellPHYID0) - np->PHYType = MarvellPHY; - else if (data == MysonPHYID0) - np->PHYType = Myson981; - else if (data == LevelOnePHYID0) - np->PHYType = LevelOnePHY; - else - np->PHYType = OtherPHY; - } - } - } - - np->mii_cnt = phy_idx; - if (phy_idx == 0) - dev_warn(&pdev->dev, - "MII PHY not found -- this device may " - "not operate correctly.\n"); - } else { - np->phys[0] = 32; -/* 89/6/23 add, (begin) */ - /* get phy type */ - if (ioread32(ioaddr + PHYIDENTIFIER) == MysonPHYID) - np->PHYType = MysonPHY; - else - np->PHYType = OtherPHY; - } - np->mii.phy_id = np->phys[0]; - - if (dev->mem_start) - option = dev->mem_start; - - /* The lower four bits are the media type. */ - if (option > 0) { - if (option & 0x200) - np->mii.full_duplex = 1; - np->default_port = option & 15; - } - - if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0) - np->mii.full_duplex = full_duplex[card_idx]; - - if (np->mii.full_duplex) { - dev_info(&pdev->dev, "Media type forced to Full Duplex.\n"); -/* 89/6/13 add, (begin) */ -// if (np->PHYType==MarvellPHY) - if ((np->PHYType == MarvellPHY) || (np->PHYType == LevelOnePHY)) { - unsigned int data; - - data = mdio_read(dev, np->phys[0], 9); - data = (data & 0xfcff) | 0x0200; - mdio_write(dev, np->phys[0], 9, data); - } -/* 89/6/13 add, (end) */ - if (np->flags == HAS_MII_XCVR) - mdio_write(dev, np->phys[0], MII_ADVERTISE, ADVERTISE_FULL); - else - iowrite32(ADVERTISE_FULL, ioaddr + ANARANLPAR); - np->mii.force_media = 1; - } - - dev->netdev_ops = &netdev_ops; - dev->ethtool_ops = &netdev_ethtool_ops; - dev->watchdog_timeo = TX_TIMEOUT; - - err = register_netdev(dev); - if (err) - goto err_out_free_tx; - - printk(KERN_INFO "%s: %s at %p, %pM, IRQ %d.\n", - dev->name, skel_netdrv_tbl[chip_id].chip_name, ioaddr, - dev->dev_addr, irq); - - return 0; - -err_out_free_tx: - dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, np->tx_ring, - np->tx_ring_dma); -err_out_free_rx: - dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, np->rx_ring, - np->rx_ring_dma); -err_out_free_dev: - free_netdev(dev); -err_out_unmap: - pci_iounmap(pdev, ioaddr); -err_out_res: - pci_release_regions(pdev); - return err; -} - - -static void fealnx_remove_one(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - if (dev) { - struct netdev_private *np = netdev_priv(dev); - - dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, np->tx_ring, - np->tx_ring_dma); - dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, np->rx_ring, - np->rx_ring_dma); - unregister_netdev(dev); - pci_iounmap(pdev, np->mem); - free_netdev(dev); - pci_release_regions(pdev); - } else - printk(KERN_ERR "fealnx: remove for unknown device\n"); -} - - -static ulong m80x_send_cmd_to_phy(void __iomem *miiport, int opcode, int phyad, int regad) -{ - ulong miir; - int i; - unsigned int mask, data; - - /* enable MII output */ - miir = (ulong) ioread32(miiport); - miir &= 0xfffffff0; - - miir |= MASK_MIIR_MII_WRITE + MASK_MIIR_MII_MDO; - - /* send 32 1's preamble */ - for (i = 0; i < 32; i++) { - /* low MDC; MDO is already high (miir) */ - miir &= ~MASK_MIIR_MII_MDC; - iowrite32(miir, miiport); - - /* high MDC */ - miir |= MASK_MIIR_MII_MDC; - iowrite32(miir, miiport); - } - - /* calculate ST+OP+PHYAD+REGAD+TA */ - data = opcode | (phyad << 7) | (regad << 2); - - /* sent out */ - mask = 0x8000; - while (mask) { - /* low MDC, prepare MDO */ - miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO); - if (mask & data) - miir |= MASK_MIIR_MII_MDO; - - iowrite32(miir, miiport); - /* high MDC */ - miir |= MASK_MIIR_MII_MDC; - iowrite32(miir, miiport); - udelay(30); - - /* next */ - mask >>= 1; - if (mask == 0x2 && opcode == OP_READ) - miir &= ~MASK_MIIR_MII_WRITE; - } - return miir; -} - - -static int mdio_read(struct net_device *dev, int phyad, int regad) -{ - struct netdev_private *np = netdev_priv(dev); - void __iomem *miiport = np->mem + MANAGEMENT; - ulong miir; - unsigned int mask, data; - - miir = m80x_send_cmd_to_phy(miiport, OP_READ, phyad, regad); - - /* read data */ - mask = 0x8000; - data = 0; - while (mask) { - /* low MDC */ - miir &= ~MASK_MIIR_MII_MDC; - iowrite32(miir, miiport); - - /* read MDI */ - miir = ioread32(miiport); - if (miir & MASK_MIIR_MII_MDI) - data |= mask; - - /* high MDC, and wait */ - miir |= MASK_MIIR_MII_MDC; - iowrite32(miir, miiport); - udelay(30); - - /* next */ - mask >>= 1; - } - - /* low MDC */ - miir &= ~MASK_MIIR_MII_MDC; - iowrite32(miir, miiport); - - return data & 0xffff; -} - - -static void mdio_write(struct net_device *dev, int phyad, int regad, int data) -{ - struct netdev_private *np = netdev_priv(dev); - void __iomem *miiport = np->mem + MANAGEMENT; - ulong miir; - unsigned int mask; - - miir = m80x_send_cmd_to_phy(miiport, OP_WRITE, phyad, regad); - - /* write data */ - mask = 0x8000; - while (mask) { - /* low MDC, prepare MDO */ - miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO); - if (mask & data) - miir |= MASK_MIIR_MII_MDO; - iowrite32(miir, miiport); - - /* high MDC */ - miir |= MASK_MIIR_MII_MDC; - iowrite32(miir, miiport); - - /* next */ - mask >>= 1; - } - - /* low MDC */ - miir &= ~MASK_MIIR_MII_MDC; - iowrite32(miir, miiport); -} - - -static int netdev_open(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - void __iomem *ioaddr = np->mem; - const int irq = np->pci_dev->irq; - int rc, i; - - iowrite32(0x00000001, ioaddr + BCR); /* Reset */ - - rc = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev); - if (rc) - return -EAGAIN; - - for (i = 0; i < 3; i++) - iowrite16(((const unsigned short *)dev->dev_addr)[i], - ioaddr + PAR0 + i*2); - - init_ring(dev); - - iowrite32(np->rx_ring_dma, ioaddr + RXLBA); - iowrite32(np->tx_ring_dma, ioaddr + TXLBA); - - /* Initialize other registers. */ - /* Configure the PCI bus bursts and FIFO thresholds. - 486: Set 8 longword burst. - 586: no burst limit. - Burst length 5:3 - 0 0 0 1 - 0 0 1 4 - 0 1 0 8 - 0 1 1 16 - 1 0 0 32 - 1 0 1 64 - 1 1 0 128 - 1 1 1 256 - Wait the specified 50 PCI cycles after a reset by initializing - Tx and Rx queues and the address filter list. - FIXME (Ueimor): optimistic for alpha + posted writes ? */ - - np->bcrvalue = 0x10; /* little-endian, 8 burst length */ -#ifdef __BIG_ENDIAN - np->bcrvalue |= 0x04; /* big-endian */ -#endif - -#if defined(__i386__) && !defined(MODULE) && !defined(CONFIG_UML) - if (boot_cpu_data.x86 <= 4) - np->crvalue = 0xa00; - else -#endif - np->crvalue = 0xe00; /* rx 128 burst length */ - - -// 89/12/29 add, -// 90/1/16 modify, -// np->imrvalue=FBE|TUNF|CNTOVF|RBU|TI|RI; - np->imrvalue = TUNF | CNTOVF | RBU | TI | RI; - if (np->pci_dev->device == 0x891) { - np->bcrvalue |= 0x200; /* set PROG bit */ - np->crvalue |= CR_W_ENH; /* set enhanced bit */ - np->imrvalue |= ETI; - } - iowrite32(np->bcrvalue, ioaddr + BCR); - - if (dev->if_port == 0) - dev->if_port = np->default_port; - - iowrite32(0, ioaddr + RXPDR); -// 89/9/1 modify, -// np->crvalue = 0x00e40001; /* tx store and forward, tx/rx enable */ - np->crvalue |= 0x00e40001; /* tx store and forward, tx/rx enable */ - np->mii.full_duplex = np->mii.force_media; - getlinkstatus(dev); - if (np->linkok) - getlinktype(dev); - __set_rx_mode(dev); - - netif_start_queue(dev); - - /* Clear and Enable interrupts by setting the interrupt mask. */ - iowrite32(FBE | TUNF | CNTOVF | RBU | TI | RI, ioaddr + ISR); - iowrite32(np->imrvalue, ioaddr + IMR); - - if (debug) - printk(KERN_DEBUG "%s: Done netdev_open().\n", dev->name); - - /* Set the timer to check for link beat. */ - timer_setup(&np->timer, netdev_timer, 0); - np->timer.expires = RUN_AT(3 * HZ); - - /* timer handler */ - add_timer(&np->timer); - - timer_setup(&np->reset_timer, reset_timer, 0); - np->reset_timer_armed = 0; - return rc; -} - - -static void getlinkstatus(struct net_device *dev) -/* function: Routine will read MII Status Register to get link status. */ -/* input : dev... pointer to the adapter block. */ -/* output : none. */ -{ - struct netdev_private *np = netdev_priv(dev); - unsigned int i, DelayTime = 0x1000; - - np->linkok = 0; - - if (np->PHYType == MysonPHY) { - for (i = 0; i < DelayTime; ++i) { - if (ioread32(np->mem + BMCRSR) & LinkIsUp2) { - np->linkok = 1; - return; - } - udelay(100); - } - } else { - for (i = 0; i < DelayTime; ++i) { - if (mdio_read(dev, np->phys[0], MII_BMSR) & BMSR_LSTATUS) { - np->linkok = 1; - return; - } - udelay(100); - } - } -} - - -static void getlinktype(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - - if (np->PHYType == MysonPHY) { /* 3-in-1 case */ - if (ioread32(np->mem + TCRRCR) & CR_R_FD) - np->duplexmode = 2; /* full duplex */ - else - np->duplexmode = 1; /* half duplex */ - if (ioread32(np->mem + TCRRCR) & CR_R_PS10) - np->line_speed = 1; /* 10M */ - else - np->line_speed = 2; /* 100M */ - } else { - if (np->PHYType == SeeqPHY) { /* this PHY is SEEQ 80225 */ - unsigned int data; - - data = mdio_read(dev, np->phys[0], MIIRegister18); - if (data & SPD_DET_100) - np->line_speed = 2; /* 100M */ - else - np->line_speed = 1; /* 10M */ - if (data & DPLX_DET_FULL) - np->duplexmode = 2; /* full duplex mode */ - else - np->duplexmode = 1; /* half duplex mode */ - } else if (np->PHYType == AhdocPHY) { - unsigned int data; - - data = mdio_read(dev, np->phys[0], DiagnosticReg); - if (data & Speed_100) - np->line_speed = 2; /* 100M */ - else - np->line_speed = 1; /* 10M */ - if (data & DPLX_FULL) - np->duplexmode = 2; /* full duplex mode */ - else - np->duplexmode = 1; /* half duplex mode */ - } -/* 89/6/13 add, (begin) */ - else if (np->PHYType == MarvellPHY) { - unsigned int data; - - data = mdio_read(dev, np->phys[0], SpecificReg); - if (data & Full_Duplex) - np->duplexmode = 2; /* full duplex mode */ - else - np->duplexmode = 1; /* half duplex mode */ - data &= SpeedMask; - if (data == Speed_1000M) - np->line_speed = 3; /* 1000M */ - else if (data == Speed_100M) - np->line_speed = 2; /* 100M */ - else - np->line_speed = 1; /* 10M */ - } -/* 89/6/13 add, (end) */ -/* 89/7/27 add, (begin) */ - else if (np->PHYType == Myson981) { - unsigned int data; - - data = mdio_read(dev, np->phys[0], StatusRegister); - - if (data & SPEED100) - np->line_speed = 2; - else - np->line_speed = 1; - - if (data & FULLMODE) - np->duplexmode = 2; - else - np->duplexmode = 1; - } -/* 89/7/27 add, (end) */ -/* 89/12/29 add */ - else if (np->PHYType == LevelOnePHY) { - unsigned int data; - - data = mdio_read(dev, np->phys[0], SpecificReg); - if (data & LXT1000_Full) - np->duplexmode = 2; /* full duplex mode */ - else - np->duplexmode = 1; /* half duplex mode */ - data &= SpeedMask; - if (data == LXT1000_1000M) - np->line_speed = 3; /* 1000M */ - else if (data == LXT1000_100M) - np->line_speed = 2; /* 100M */ - else - np->line_speed = 1; /* 10M */ - } - np->crvalue &= (~CR_W_PS10) & (~CR_W_FD) & (~CR_W_PS1000); - if (np->line_speed == 1) - np->crvalue |= CR_W_PS10; - else if (np->line_speed == 3) - np->crvalue |= CR_W_PS1000; - if (np->duplexmode == 2) - np->crvalue |= CR_W_FD; - } -} - - -/* Take lock before calling this */ -static void allocate_rx_buffers(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - - /* allocate skb for rx buffers */ - while (np->really_rx_count != RX_RING_SIZE) { - struct sk_buff *skb; - - skb = netdev_alloc_skb(dev, np->rx_buf_sz); - if (skb == NULL) - break; /* Better luck next round. */ - - while (np->lack_rxbuf->skbuff) - np->lack_rxbuf = np->lack_rxbuf->next_desc_logical; - - np->lack_rxbuf->skbuff = skb; - np->lack_rxbuf->buffer = dma_map_single(&np->pci_dev->dev, - skb->data, - np->rx_buf_sz, - DMA_FROM_DEVICE); - np->lack_rxbuf->status = RXOWN; - ++np->really_rx_count; - } -} - - -static void netdev_timer(struct timer_list *t) -{ - struct netdev_private *np = from_timer(np, t, timer); - struct net_device *dev = np->mii.dev; - void __iomem *ioaddr = np->mem; - int old_crvalue = np->crvalue; - unsigned int old_linkok = np->linkok; - unsigned long flags; - - if (debug) - printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x " - "config %8.8x.\n", dev->name, ioread32(ioaddr + ISR), - ioread32(ioaddr + TCRRCR)); - - spin_lock_irqsave(&np->lock, flags); - - if (np->flags == HAS_MII_XCVR) { - getlinkstatus(dev); - if ((old_linkok == 0) && (np->linkok == 1)) { /* we need to detect the media type again */ - getlinktype(dev); - if (np->crvalue != old_crvalue) { - stop_nic_rxtx(ioaddr, np->crvalue); - iowrite32(np->crvalue, ioaddr + TCRRCR); - } - } - } - - allocate_rx_buffers(dev); - - spin_unlock_irqrestore(&np->lock, flags); - - np->timer.expires = RUN_AT(10 * HZ); - add_timer(&np->timer); -} - - -/* Take lock before calling */ -/* Reset chip and disable rx, tx and interrupts */ -static void reset_and_disable_rxtx(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - void __iomem *ioaddr = np->mem; - int delay=51; - - /* Reset the chip's Tx and Rx processes. */ - stop_nic_rxtx(ioaddr, 0); - - /* Disable interrupts by clearing the interrupt mask. */ - iowrite32(0, ioaddr + IMR); - - /* Reset the chip to erase previous misconfiguration. */ - iowrite32(0x00000001, ioaddr + BCR); - - /* Ueimor: wait for 50 PCI cycles (and flush posted writes btw). - We surely wait too long (address+data phase). Who cares? */ - while (--delay) { - ioread32(ioaddr + BCR); - rmb(); - } -} - - -/* Take lock before calling */ -/* Restore chip after reset */ -static void enable_rxtx(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - void __iomem *ioaddr = np->mem; - - reset_rx_descriptors(dev); - - iowrite32(np->tx_ring_dma + ((char*)np->cur_tx - (char*)np->tx_ring), - ioaddr + TXLBA); - iowrite32(np->rx_ring_dma + ((char*)np->cur_rx - (char*)np->rx_ring), - ioaddr + RXLBA); - - iowrite32(np->bcrvalue, ioaddr + BCR); - - iowrite32(0, ioaddr + RXPDR); - __set_rx_mode(dev); /* changes np->crvalue, writes it into TCRRCR */ - - /* Clear and Enable interrupts by setting the interrupt mask. */ - iowrite32(FBE | TUNF | CNTOVF | RBU | TI | RI, ioaddr + ISR); - iowrite32(np->imrvalue, ioaddr + IMR); - - iowrite32(0, ioaddr + TXPDR); -} - - -static void reset_timer(struct timer_list *t) -{ - struct netdev_private *np = from_timer(np, t, reset_timer); - struct net_device *dev = np->mii.dev; - unsigned long flags; - - printk(KERN_WARNING "%s: resetting tx and rx machinery\n", dev->name); - - spin_lock_irqsave(&np->lock, flags); - np->crvalue = np->crvalue_sv; - np->imrvalue = np->imrvalue_sv; - - reset_and_disable_rxtx(dev); - /* works for me without this: - reset_tx_descriptors(dev); */ - enable_rxtx(dev); - netif_start_queue(dev); /* FIXME: or netif_wake_queue(dev); ? */ - - np->reset_timer_armed = 0; - - spin_unlock_irqrestore(&np->lock, flags); -} - - -static void fealnx_tx_timeout(struct net_device *dev, unsigned int txqueue) -{ - struct netdev_private *np = netdev_priv(dev); - void __iomem *ioaddr = np->mem; - unsigned long flags; - int i; - - printk(KERN_WARNING - "%s: Transmit timed out, status %8.8x, resetting...\n", - dev->name, ioread32(ioaddr + ISR)); - - { - printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring); - for (i = 0; i < RX_RING_SIZE; i++) - printk(KERN_CONT " %8.8x", - (unsigned int) np->rx_ring[i].status); - printk(KERN_CONT "\n"); - printk(KERN_DEBUG " Tx ring %p: ", np->tx_ring); - for (i = 0; i < TX_RING_SIZE; i++) - printk(KERN_CONT " %4.4x", np->tx_ring[i].status); - printk(KERN_CONT "\n"); - } - - spin_lock_irqsave(&np->lock, flags); - - reset_and_disable_rxtx(dev); - reset_tx_descriptors(dev); - enable_rxtx(dev); - - spin_unlock_irqrestore(&np->lock, flags); - - netif_trans_update(dev); /* prevent tx timeout */ - dev->stats.tx_errors++; - netif_wake_queue(dev); /* or .._start_.. ?? */ -} - - -/* Initialize the Rx and Tx rings, along with various 'dev' bits. */ -static void init_ring(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - int i; - - /* initialize rx variables */ - np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32); - np->cur_rx = &np->rx_ring[0]; - np->lack_rxbuf = np->rx_ring; - np->really_rx_count = 0; - - /* initial rx descriptors. */ - for (i = 0; i < RX_RING_SIZE; i++) { - np->rx_ring[i].status = 0; - np->rx_ring[i].control = np->rx_buf_sz << RBSShift; - np->rx_ring[i].next_desc = np->rx_ring_dma + - (i + 1)*sizeof(struct fealnx_desc); - np->rx_ring[i].next_desc_logical = &np->rx_ring[i + 1]; - np->rx_ring[i].skbuff = NULL; - } - - /* for the last rx descriptor */ - np->rx_ring[i - 1].next_desc = np->rx_ring_dma; - np->rx_ring[i - 1].next_desc_logical = np->rx_ring; - - /* allocate skb for rx buffers */ - for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz); - - if (skb == NULL) { - np->lack_rxbuf = &np->rx_ring[i]; - break; - } - - ++np->really_rx_count; - np->rx_ring[i].skbuff = skb; - np->rx_ring[i].buffer = dma_map_single(&np->pci_dev->dev, - skb->data, - np->rx_buf_sz, - DMA_FROM_DEVICE); - np->rx_ring[i].status = RXOWN; - np->rx_ring[i].control |= RXIC; - } - - /* initialize tx variables */ - np->cur_tx = &np->tx_ring[0]; - np->cur_tx_copy = &np->tx_ring[0]; - np->really_tx_count = 0; - np->free_tx_count = TX_RING_SIZE; - - for (i = 0; i < TX_RING_SIZE; i++) { - np->tx_ring[i].status = 0; - /* do we need np->tx_ring[i].control = XXX; ?? */ - np->tx_ring[i].next_desc = np->tx_ring_dma + - (i + 1)*sizeof(struct fealnx_desc); - np->tx_ring[i].next_desc_logical = &np->tx_ring[i + 1]; - np->tx_ring[i].skbuff = NULL; - } - - /* for the last tx descriptor */ - np->tx_ring[i - 1].next_desc = np->tx_ring_dma; - np->tx_ring[i - 1].next_desc_logical = &np->tx_ring[0]; -} - - -static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&np->lock, flags); - - np->cur_tx_copy->skbuff = skb; - -#define one_buffer -#define BPT 1022 -#if defined(one_buffer) - np->cur_tx_copy->buffer = dma_map_single(&np->pci_dev->dev, skb->data, - skb->len, DMA_TO_DEVICE); - np->cur_tx_copy->control = TXIC | TXLD | TXFD | CRCEnable | PADEnable; - np->cur_tx_copy->control |= (skb->len << PKTSShift); /* pkt size */ - np->cur_tx_copy->control |= (skb->len << TBSShift); /* buffer size */ -// 89/12/29 add, - if (np->pci_dev->device == 0x891) - np->cur_tx_copy->control |= ETIControl | RetryTxLC; - np->cur_tx_copy->status = TXOWN; - np->cur_tx_copy = np->cur_tx_copy->next_desc_logical; - --np->free_tx_count; -#elif defined(two_buffer) - if (skb->len > BPT) { - struct fealnx_desc *next; - - /* for the first descriptor */ - np->cur_tx_copy->buffer = dma_map_single(&np->pci_dev->dev, - skb->data, BPT, - DMA_TO_DEVICE); - np->cur_tx_copy->control = TXIC | TXFD | CRCEnable | PADEnable; - np->cur_tx_copy->control |= (skb->len << PKTSShift); /* pkt size */ - np->cur_tx_copy->control |= (BPT << TBSShift); /* buffer size */ - - /* for the last descriptor */ - next = np->cur_tx_copy->next_desc_logical; - next->skbuff = skb; - next->control = TXIC | TXLD | CRCEnable | PADEnable; - next->control |= (skb->len << PKTSShift); /* pkt size */ - next->control |= ((skb->len - BPT) << TBSShift); /* buf size */ -// 89/12/29 add, - if (np->pci_dev->device == 0x891) - np->cur_tx_copy->control |= ETIControl | RetryTxLC; - next->buffer = dma_map_single(&ep->pci_dev->dev, - skb->data + BPT, skb->len - BPT, - DMA_TO_DEVICE); - - next->status = TXOWN; - np->cur_tx_copy->status = TXOWN; - - np->cur_tx_copy = next->next_desc_logical; - np->free_tx_count -= 2; - } else { - np->cur_tx_copy->buffer = dma_map_single(&np->pci_dev->dev, - skb->data, skb->len, - DMA_TO_DEVICE); - np->cur_tx_copy->control = TXIC | TXLD | TXFD | CRCEnable | PADEnable; - np->cur_tx_copy->control |= (skb->len << PKTSShift); /* pkt size */ - np->cur_tx_copy->control |= (skb->len << TBSShift); /* buffer size */ -// 89/12/29 add, - if (np->pci_dev->device == 0x891) - np->cur_tx_copy->control |= ETIControl | RetryTxLC; - np->cur_tx_copy->status = TXOWN; - np->cur_tx_copy = np->cur_tx_copy->next_desc_logical; - --np->free_tx_count; - } -#endif - - if (np->free_tx_count < 2) - netif_stop_queue(dev); - ++np->really_tx_count; - iowrite32(0, np->mem + TXPDR); - - spin_unlock_irqrestore(&np->lock, flags); - return NETDEV_TX_OK; -} - - -/* Take lock before calling */ -/* Chip probably hosed tx ring. Clean up. */ -static void reset_tx_descriptors(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - struct fealnx_desc *cur; - int i; - - /* initialize tx variables */ - np->cur_tx = &np->tx_ring[0]; - np->cur_tx_copy = &np->tx_ring[0]; - np->really_tx_count = 0; - np->free_tx_count = TX_RING_SIZE; - - for (i = 0; i < TX_RING_SIZE; i++) { - cur = &np->tx_ring[i]; - if (cur->skbuff) { - dma_unmap_single(&np->pci_dev->dev, cur->buffer, - cur->skbuff->len, DMA_TO_DEVICE); - dev_kfree_skb_any(cur->skbuff); - cur->skbuff = NULL; - } - cur->status = 0; - cur->control = 0; /* needed? */ - /* probably not needed. We do it for purely paranoid reasons */ - cur->next_desc = np->tx_ring_dma + - (i + 1)*sizeof(struct fealnx_desc); - cur->next_desc_logical = &np->tx_ring[i + 1]; - } - /* for the last tx descriptor */ - np->tx_ring[TX_RING_SIZE - 1].next_desc = np->tx_ring_dma; - np->tx_ring[TX_RING_SIZE - 1].next_desc_logical = &np->tx_ring[0]; -} - - -/* Take lock and stop rx before calling this */ -static void reset_rx_descriptors(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - struct fealnx_desc *cur = np->cur_rx; - int i; - - allocate_rx_buffers(dev); - - for (i = 0; i < RX_RING_SIZE; i++) { - if (cur->skbuff) - cur->status = RXOWN; - cur = cur->next_desc_logical; - } - - iowrite32(np->rx_ring_dma + ((char*)np->cur_rx - (char*)np->rx_ring), - np->mem + RXLBA); -} - - -/* The interrupt handler does all of the Rx thread work and cleans up - after the Tx thread. */ -static irqreturn_t intr_handler(int irq, void *dev_instance) -{ - struct net_device *dev = (struct net_device *) dev_instance; - struct netdev_private *np = netdev_priv(dev); - void __iomem *ioaddr = np->mem; - long boguscnt = max_interrupt_work; - unsigned int num_tx = 0; - int handled = 0; - - spin_lock(&np->lock); - - iowrite32(0, ioaddr + IMR); - - do { - u32 intr_status = ioread32(ioaddr + ISR); - - /* Acknowledge all of the current interrupt sources ASAP. */ - iowrite32(intr_status, ioaddr + ISR); - - if (debug) - printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n", dev->name, - intr_status); - - if (!(intr_status & np->imrvalue)) - break; - - handled = 1; - -// 90/1/16 delete, -// -// if (intr_status & FBE) -// { /* fatal error */ -// stop_nic_tx(ioaddr, 0); -// stop_nic_rx(ioaddr, 0); -// break; -// }; - - if (intr_status & TUNF) - iowrite32(0, ioaddr + TXPDR); - - if (intr_status & CNTOVF) { - /* missed pkts */ - dev->stats.rx_missed_errors += - ioread32(ioaddr + TALLY) & 0x7fff; - - /* crc error */ - dev->stats.rx_crc_errors += - (ioread32(ioaddr + TALLY) & 0x7fff0000) >> 16; - } - - if (intr_status & (RI | RBU)) { - if (intr_status & RI) - netdev_rx(dev); - else { - stop_nic_rx(ioaddr, np->crvalue); - reset_rx_descriptors(dev); - iowrite32(np->crvalue, ioaddr + TCRRCR); - } - } - - while (np->really_tx_count) { - long tx_status = np->cur_tx->status; - long tx_control = np->cur_tx->control; - - if (!(tx_control & TXLD)) { /* this pkt is combined by two tx descriptors */ - struct fealnx_desc *next; - - next = np->cur_tx->next_desc_logical; - tx_status = next->status; - tx_control = next->control; - } - - if (tx_status & TXOWN) - break; - - if (!(np->crvalue & CR_W_ENH)) { - if (tx_status & (CSL | LC | EC | UDF | HF)) { - dev->stats.tx_errors++; - if (tx_status & EC) - dev->stats.tx_aborted_errors++; - if (tx_status & CSL) - dev->stats.tx_carrier_errors++; - if (tx_status & LC) - dev->stats.tx_window_errors++; - if (tx_status & UDF) - dev->stats.tx_fifo_errors++; - if ((tx_status & HF) && np->mii.full_duplex == 0) - dev->stats.tx_heartbeat_errors++; - - } else { - dev->stats.tx_bytes += - ((tx_control & PKTSMask) >> PKTSShift); - - dev->stats.collisions += - ((tx_status & NCRMask) >> NCRShift); - dev->stats.tx_packets++; - } - } else { - dev->stats.tx_bytes += - ((tx_control & PKTSMask) >> PKTSShift); - dev->stats.tx_packets++; - } - - /* Free the original skb. */ - dma_unmap_single(&np->pci_dev->dev, - np->cur_tx->buffer, - np->cur_tx->skbuff->len, - DMA_TO_DEVICE); - dev_consume_skb_irq(np->cur_tx->skbuff); - np->cur_tx->skbuff = NULL; - --np->really_tx_count; - if (np->cur_tx->control & TXLD) { - np->cur_tx = np->cur_tx->next_desc_logical; - ++np->free_tx_count; - } else { - np->cur_tx = np->cur_tx->next_desc_logical; - np->cur_tx = np->cur_tx->next_desc_logical; - np->free_tx_count += 2; - } - num_tx++; - } /* end of for loop */ - - if (num_tx && np->free_tx_count >= 2) - netif_wake_queue(dev); - - /* read transmit status for enhanced mode only */ - if (np->crvalue & CR_W_ENH) { - long data; - - data = ioread32(ioaddr + TSR); - dev->stats.tx_errors += (data & 0xff000000) >> 24; - dev->stats.tx_aborted_errors += - (data & 0xff000000) >> 24; - dev->stats.tx_window_errors += - (data & 0x00ff0000) >> 16; - dev->stats.collisions += (data & 0x0000ffff); - } - - if (--boguscnt < 0) { - printk(KERN_WARNING "%s: Too much work at interrupt, " - "status=0x%4.4x.\n", dev->name, intr_status); - if (!np->reset_timer_armed) { - np->reset_timer_armed = 1; - np->reset_timer.expires = RUN_AT(HZ/2); - add_timer(&np->reset_timer); - stop_nic_rxtx(ioaddr, 0); - netif_stop_queue(dev); - /* or netif_tx_disable(dev); ?? */ - /* Prevent other paths from enabling tx,rx,intrs */ - np->crvalue_sv = np->crvalue; - np->imrvalue_sv = np->imrvalue; - np->crvalue &= ~(CR_W_TXEN | CR_W_RXEN); /* or simply = 0? */ - np->imrvalue = 0; - } - - break; - } - } while (1); - - /* read the tally counters */ - /* missed pkts */ - dev->stats.rx_missed_errors += ioread32(ioaddr + TALLY) & 0x7fff; - - /* crc error */ - dev->stats.rx_crc_errors += - (ioread32(ioaddr + TALLY) & 0x7fff0000) >> 16; - - if (debug) - printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n", - dev->name, ioread32(ioaddr + ISR)); - - iowrite32(np->imrvalue, ioaddr + IMR); - - spin_unlock(&np->lock); - - return IRQ_RETVAL(handled); -} - - -/* This routine is logically part of the interrupt handler, but separated - for clarity and better register allocation. */ -static int netdev_rx(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - void __iomem *ioaddr = np->mem; - - /* If EOP is set on the next entry, it's a new packet. Send it up. */ - while (!(np->cur_rx->status & RXOWN) && np->cur_rx->skbuff) { - s32 rx_status = np->cur_rx->status; - - if (np->really_rx_count == 0) - break; - - if (debug) - printk(KERN_DEBUG " netdev_rx() status was %8.8x.\n", rx_status); - - if ((!((rx_status & RXFSD) && (rx_status & RXLSD))) || - (rx_status & ErrorSummary)) { - if (rx_status & ErrorSummary) { /* there was a fatal error */ - if (debug) - printk(KERN_DEBUG - "%s: Receive error, Rx status %8.8x.\n", - dev->name, rx_status); - - dev->stats.rx_errors++; /* end of a packet. */ - if (rx_status & (LONGPKT | RUNTPKT)) - dev->stats.rx_length_errors++; - if (rx_status & RXER) - dev->stats.rx_frame_errors++; - if (rx_status & CRC) - dev->stats.rx_crc_errors++; - } else { - int need_to_reset = 0; - int desno = 0; - - if (rx_status & RXFSD) { /* this pkt is too long, over one rx buffer */ - struct fealnx_desc *cur; - - /* check this packet is received completely? */ - cur = np->cur_rx; - while (desno <= np->really_rx_count) { - ++desno; - if ((!(cur->status & RXOWN)) && - (cur->status & RXLSD)) - break; - /* goto next rx descriptor */ - cur = cur->next_desc_logical; - } - if (desno > np->really_rx_count) - need_to_reset = 1; - } else /* RXLSD did not find, something error */ - need_to_reset = 1; - - if (need_to_reset == 0) { - int i; - - dev->stats.rx_length_errors++; - - /* free all rx descriptors related this long pkt */ - for (i = 0; i < desno; ++i) { - if (!np->cur_rx->skbuff) { - printk(KERN_DEBUG - "%s: I'm scared\n", dev->name); - break; - } - np->cur_rx->status = RXOWN; - np->cur_rx = np->cur_rx->next_desc_logical; - } - continue; - } else { /* rx error, need to reset this chip */ - stop_nic_rx(ioaddr, np->crvalue); - reset_rx_descriptors(dev); - iowrite32(np->crvalue, ioaddr + TCRRCR); - } - break; /* exit the while loop */ - } - } else { /* this received pkt is ok */ - - struct sk_buff *skb; - /* Omit the four octet CRC from the length. */ - short pkt_len = ((rx_status & FLNGMASK) >> FLNGShift) - 4; - -#ifndef final_version - if (debug) - printk(KERN_DEBUG " netdev_rx() normal Rx pkt length %d" - " status %x.\n", pkt_len, rx_status); -#endif - - /* Check if the packet is long enough to accept without copying - to a minimally-sized skbuff. */ - if (pkt_len < rx_copybreak && - (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) { - skb_reserve(skb, 2); /* 16 byte align the IP header */ - dma_sync_single_for_cpu(&np->pci_dev->dev, - np->cur_rx->buffer, - np->rx_buf_sz, - DMA_FROM_DEVICE); - /* Call copy + cksum if available. */ - -#if ! defined(__alpha__) - skb_copy_to_linear_data(skb, - np->cur_rx->skbuff->data, pkt_len); - skb_put(skb, pkt_len); -#else - skb_put_data(skb, np->cur_rx->skbuff->data, - pkt_len); -#endif - dma_sync_single_for_device(&np->pci_dev->dev, - np->cur_rx->buffer, - np->rx_buf_sz, - DMA_FROM_DEVICE); - } else { - dma_unmap_single(&np->pci_dev->dev, - np->cur_rx->buffer, - np->rx_buf_sz, - DMA_FROM_DEVICE); - skb_put(skb = np->cur_rx->skbuff, pkt_len); - np->cur_rx->skbuff = NULL; - --np->really_rx_count; - } - skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); - dev->stats.rx_packets++; - dev->stats.rx_bytes += pkt_len; - } - - np->cur_rx = np->cur_rx->next_desc_logical; - } /* end of while loop */ - - /* allocate skb for rx buffers */ - allocate_rx_buffers(dev); - - return 0; -} - - -static struct net_device_stats *get_stats(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - void __iomem *ioaddr = np->mem; - - /* The chip only need report frame silently dropped. */ - if (netif_running(dev)) { - dev->stats.rx_missed_errors += - ioread32(ioaddr + TALLY) & 0x7fff; - dev->stats.rx_crc_errors += - (ioread32(ioaddr + TALLY) & 0x7fff0000) >> 16; - } - - return &dev->stats; -} - - -/* for dev->set_multicast_list */ -static void set_rx_mode(struct net_device *dev) -{ - spinlock_t *lp = &((struct netdev_private *)netdev_priv(dev))->lock; - unsigned long flags; - spin_lock_irqsave(lp, flags); - __set_rx_mode(dev); - spin_unlock_irqrestore(lp, flags); -} - - -/* Take lock before calling */ -static void __set_rx_mode(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - void __iomem *ioaddr = np->mem; - u32 mc_filter[2]; /* Multicast hash filter */ - u32 rx_mode; - - if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ - memset(mc_filter, 0xff, sizeof(mc_filter)); - rx_mode = CR_W_PROM | CR_W_AB | CR_W_AM; - } else if ((netdev_mc_count(dev) > multicast_filter_limit) || - (dev->flags & IFF_ALLMULTI)) { - /* Too many to match, or accept all multicasts. */ - memset(mc_filter, 0xff, sizeof(mc_filter)); - rx_mode = CR_W_AB | CR_W_AM; - } else { - struct netdev_hw_addr *ha; - - memset(mc_filter, 0, sizeof(mc_filter)); - netdev_for_each_mc_addr(ha, dev) { - unsigned int bit; - bit = (ether_crc(ETH_ALEN, ha->addr) >> 26) ^ 0x3F; - mc_filter[bit >> 5] |= (1 << bit); - } - rx_mode = CR_W_AB | CR_W_AM; - } - - stop_nic_rxtx(ioaddr, np->crvalue); - - iowrite32(mc_filter[0], ioaddr + MAR0); - iowrite32(mc_filter[1], ioaddr + MAR1); - np->crvalue &= ~CR_W_RXMODEMASK; - np->crvalue |= rx_mode; - iowrite32(np->crvalue, ioaddr + TCRRCR); -} - -static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - struct netdev_private *np = netdev_priv(dev); - - strscpy(info->driver, DRV_NAME, sizeof(info->driver)); - strscpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); -} - -static int netdev_get_link_ksettings(struct net_device *dev, - struct ethtool_link_ksettings *cmd) -{ - struct netdev_private *np = netdev_priv(dev); - - spin_lock_irq(&np->lock); - mii_ethtool_get_link_ksettings(&np->mii, cmd); - spin_unlock_irq(&np->lock); - - return 0; -} - -static int netdev_set_link_ksettings(struct net_device *dev, - const struct ethtool_link_ksettings *cmd) -{ - struct netdev_private *np = netdev_priv(dev); - int rc; - - spin_lock_irq(&np->lock); - rc = mii_ethtool_set_link_ksettings(&np->mii, cmd); - spin_unlock_irq(&np->lock); - - return rc; -} - -static int netdev_nway_reset(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - return mii_nway_restart(&np->mii); -} - -static u32 netdev_get_link(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - return mii_link_ok(&np->mii); -} - -static u32 netdev_get_msglevel(struct net_device *dev) -{ - return debug; -} - -static void netdev_set_msglevel(struct net_device *dev, u32 value) -{ - debug = value; -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, - .nway_reset = netdev_nway_reset, - .get_link = netdev_get_link, - .get_msglevel = netdev_get_msglevel, - .set_msglevel = netdev_set_msglevel, - .get_link_ksettings = netdev_get_link_ksettings, - .set_link_ksettings = netdev_set_link_ksettings, -}; - -static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct netdev_private *np = netdev_priv(dev); - int rc; - - if (!netif_running(dev)) - return -EINVAL; - - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL); - spin_unlock_irq(&np->lock); - - return rc; -} - - -static int netdev_close(struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - void __iomem *ioaddr = np->mem; - int i; - - netif_stop_queue(dev); - - /* Disable interrupts by clearing the interrupt mask. */ - iowrite32(0x0000, ioaddr + IMR); - - /* Stop the chip's Tx and Rx processes. */ - stop_nic_rxtx(ioaddr, 0); - - del_timer_sync(&np->timer); - del_timer_sync(&np->reset_timer); - - free_irq(np->pci_dev->irq, dev); - - /* Free all the skbuffs in the Rx queue. */ - for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = np->rx_ring[i].skbuff; - - np->rx_ring[i].status = 0; - if (skb) { - dma_unmap_single(&np->pci_dev->dev, - np->rx_ring[i].buffer, np->rx_buf_sz, - DMA_FROM_DEVICE); - dev_kfree_skb(skb); - np->rx_ring[i].skbuff = NULL; - } - } - - for (i = 0; i < TX_RING_SIZE; i++) { - struct sk_buff *skb = np->tx_ring[i].skbuff; - - if (skb) { - dma_unmap_single(&np->pci_dev->dev, - np->tx_ring[i].buffer, skb->len, - DMA_TO_DEVICE); - dev_kfree_skb(skb); - np->tx_ring[i].skbuff = NULL; - } - } - - return 0; -} - -static const struct pci_device_id fealnx_pci_tbl[] = { - {0x1516, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x1516, 0x0803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - {0x1516, 0x0891, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, - {} /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, fealnx_pci_tbl); - - -static struct pci_driver fealnx_driver = { - .name = "fealnx", - .id_table = fealnx_pci_tbl, - .probe = fealnx_init_one, - .remove = fealnx_remove_one, -}; - -module_pci_driver(fealnx_driver); -- cgit v1.2.3 From eed4f1ddad8c5ad7596b229caec8bd7b477b81ee Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 5 Nov 2022 23:36:16 +0100 Subject: arm64: dts: mediatek: mt7986: add support for RX Wireless Ethernet Dispatch Similar to TX Wireless Ethernet Dispatch, introduce RX Wireless Ethernet Dispatch to offload traffic received by the wlan interface to lan/wan one. Co-developed-by: Sujuan Chen Signed-off-by: Sujuan Chen Signed-off-by: Lorenzo Bianconi Signed-off-by: David S. Miller --- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 65 +++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'arch') diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi index 72e0d9722e07..07dee1c0d281 100644 --- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi @@ -76,6 +76,47 @@ no-map; reg = <0 0x4fc00000 0 0x00100000>; }; + + wo_emi0: wo-emi@4fd00000 { + reg = <0 0x4fd00000 0 0x40000>; + no-map; + }; + + wo_emi1: wo-emi@4fd40000 { + reg = <0 0x4fd40000 0 0x40000>; + no-map; + }; + + wo_ilm0: wo-ilm@151e0000 { + reg = <0 0x151e0000 0 0x8000>; + no-map; + }; + + wo_ilm1: wo-ilm@151f0000 { + reg = <0 0x151f0000 0 0x8000>; + no-map; + }; + + wo_data: wo-data@4fd80000 { + reg = <0 0x4fd80000 0 0x240000>; + no-map; + }; + + wo_dlm0: wo-dlm@151e8000 { + reg = <0 0x151e8000 0 0x2000>; + no-map; + }; + + wo_dlm1: wo-dlm@151f8000 { + reg = <0 0x151f8000 0 0x2000>; + no-map; + }; + + wo_boot: wo-boot@15194000 { + reg = <0 0x15194000 0 0x1000>; + no-map; + }; + }; timer { @@ -240,6 +281,11 @@ reg = <0 0x15010000 0 0x1000>; interrupt-parent = <&gic>; interrupts = ; + memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>, + <&wo_data>, <&wo_boot>; + memory-region-names = "wo-emi", "wo-ilm", "wo-dlm", + "wo-data", "wo-boot"; + mediatek,wo-ccif = <&wo_ccif0>; }; wed1: wed@15011000 { @@ -248,6 +294,25 @@ reg = <0 0x15011000 0 0x1000>; interrupt-parent = <&gic>; interrupts = ; + memory-region = <&wo_emi1>, <&wo_ilm1>, <&wo_dlm1>, + <&wo_data>, <&wo_boot>; + memory-region-names = "wo-emi", "wo-ilm", "wo-dlm", + "wo-data", "wo-boot"; + mediatek,wo-ccif = <&wo_ccif1>; + }; + + wo_ccif0: syscon@151a5000 { + compatible = "mediatek,mt7986-wo-ccif", "syscon"; + reg = <0 0x151a5000 0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + }; + + wo_ccif1: syscon@151ad000 { + compatible = "mediatek,mt7986-wo-ccif", "syscon"; + reg = <0 0x151ad000 0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; }; eth: ethernet@15100000 { -- cgit v1.2.3 From 354259fa73e2aac92ae5e19522adb69a92c15b49 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 9 Nov 2022 09:57:58 +0000 Subject: net: remove skb->vlan_present skb->vlan_present seems redundant. We can instead derive it from this boolean expression: vlan_present = skb->vlan_proto != 0 || skb->vlan_tci != 0 Add a new union, to access both fields in a single load/store when possible. union { u32 vlan_all; struct { __be16 vlan_proto; __u16 vlan_tci; }; }; This allows following patch to remove a conditional test in GRO stack. Note: We move remcsum_offload to keep TC_AT_INGRESS_MASK and SKB_MONO_DELIVERY_TIME_MASK unchanged. Signed-off-by: Eric Dumazet Acked-by: Yonghong Song Acked-by: Martin KaFai Lau Signed-off-by: Jakub Kicinski --- arch/sparc/net/bpf_jit_comp_32.c | 10 +++++----- .../net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 2 +- include/linux/if_vlan.h | 9 +++------ include/linux/skbuff.h | 18 ++++++++++-------- lib/test_bpf.c | 1 - net/core/filter.c | 22 ++++++++++------------ 6 files changed, 29 insertions(+), 33 deletions(-) (limited to 'arch') diff --git a/arch/sparc/net/bpf_jit_comp_32.c b/arch/sparc/net/bpf_jit_comp_32.c index b1dbf2fa8c0a..a74e5004c6c8 100644 --- a/arch/sparc/net/bpf_jit_comp_32.c +++ b/arch/sparc/net/bpf_jit_comp_32.c @@ -555,11 +555,11 @@ void bpf_jit_compile(struct bpf_prog *fp) emit_skb_load16(vlan_tci, r_A); break; case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT: - __emit_skb_load8(__pkt_vlan_present_offset, r_A); - if (PKT_VLAN_PRESENT_BIT) - emit_alu_K(SRL, PKT_VLAN_PRESENT_BIT); - if (PKT_VLAN_PRESENT_BIT < 7) - emit_andi(r_A, 1, r_A); + emit_skb_load32(vlan_all, r_A); + emit_cmpi(r_A, 0); + emit_branch_off(BE, 12); + emit_nop(); + emit_loadimm(1, r_A); break; case BPF_LD | BPF_W | BPF_LEN: emit_skb_load32(len, r_A); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c index 303930499a4c..c1ea60bc2630 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -1973,7 +1973,7 @@ static u16 otx2_select_queue(struct net_device *netdev, struct sk_buff *skb, #endif #ifdef CONFIG_DCB - if (!skb->vlan_present) + if (!skb_vlan_tag_present(skb)) goto pick_tx; vlan_prio = skb->vlan_tci >> 13; diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index e00c4ee81ff7..6864b89ef868 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -76,7 +76,7 @@ static inline bool is_vlan_dev(const struct net_device *dev) return dev->priv_flags & IFF_802_1Q_VLAN; } -#define skb_vlan_tag_present(__skb) ((__skb)->vlan_present) +#define skb_vlan_tag_present(__skb) (!!(__skb)->vlan_all) #define skb_vlan_tag_get(__skb) ((__skb)->vlan_tci) #define skb_vlan_tag_get_id(__skb) ((__skb)->vlan_tci & VLAN_VID_MASK) #define skb_vlan_tag_get_cfi(__skb) (!!((__skb)->vlan_tci & VLAN_CFI_MASK)) @@ -471,7 +471,7 @@ static inline struct sk_buff *vlan_insert_tag_set_proto(struct sk_buff *skb, */ static inline void __vlan_hwaccel_clear_tag(struct sk_buff *skb) { - skb->vlan_present = 0; + skb->vlan_all = 0; } /** @@ -483,9 +483,7 @@ static inline void __vlan_hwaccel_clear_tag(struct sk_buff *skb) */ static inline void __vlan_hwaccel_copy_tag(struct sk_buff *dst, const struct sk_buff *src) { - dst->vlan_present = src->vlan_present; - dst->vlan_proto = src->vlan_proto; - dst->vlan_tci = src->vlan_tci; + dst->vlan_all = src->vlan_all; } /* @@ -519,7 +517,6 @@ static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb, { skb->vlan_proto = vlan_proto; skb->vlan_tci = vlan_tci; - skb->vlan_present = 1; } /** diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 59c9fd55699d..4e464a27adaf 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -818,7 +818,7 @@ typedef unsigned char *sk_buff_data_t; * @mark: Generic packet mark * @reserved_tailroom: (aka @mark) number of bytes of free space available * at the tail of an sk_buff - * @vlan_present: VLAN tag is present + * @vlan_all: vlan fields (proto & tci) * @vlan_proto: vlan encapsulation protocol * @vlan_tci: vlan tag control information * @inner_protocol: Protocol (encapsulation) @@ -951,7 +951,7 @@ struct sk_buff { /* private: */ __u8 __pkt_vlan_present_offset[0]; /* public: */ - __u8 vlan_present:1; /* See PKT_VLAN_PRESENT_BIT */ + __u8 remcsum_offload:1; __u8 csum_complete_sw:1; __u8 csum_level:2; __u8 dst_pending_confirm:1; @@ -966,7 +966,6 @@ struct sk_buff { __u8 ipvs_property:1; __u8 inner_protocol_type:1; - __u8 remcsum_offload:1; #ifdef CONFIG_NET_SWITCHDEV __u8 offload_fwd_mark:1; __u8 offload_l3_fwd_mark:1; @@ -999,8 +998,13 @@ struct sk_buff { __u32 priority; int skb_iif; __u32 hash; - __be16 vlan_proto; - __u16 vlan_tci; + union { + u32 vlan_all; + struct { + __be16 vlan_proto; + __u16 vlan_tci; + }; + }; #if defined(CONFIG_NET_RX_BUSY_POLL) || defined(CONFIG_XPS) union { unsigned int napi_id; @@ -1059,15 +1063,13 @@ struct sk_buff { #endif #define PKT_TYPE_OFFSET offsetof(struct sk_buff, __pkt_type_offset) -/* if you move pkt_vlan_present, tc_at_ingress, or mono_delivery_time +/* if you move tc_at_ingress or mono_delivery_time * around, you also must adapt these constants. */ #ifdef __BIG_ENDIAN_BITFIELD -#define PKT_VLAN_PRESENT_BIT 7 #define TC_AT_INGRESS_MASK (1 << 0) #define SKB_MONO_DELIVERY_TIME_MASK (1 << 2) #else -#define PKT_VLAN_PRESENT_BIT 0 #define TC_AT_INGRESS_MASK (1 << 7) #define SKB_MONO_DELIVERY_TIME_MASK (1 << 5) #endif diff --git a/lib/test_bpf.c b/lib/test_bpf.c index 5820704165a6..ade9ac672adb 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c @@ -14346,7 +14346,6 @@ static struct sk_buff *populate_skb(char *buf, int size) skb->hash = SKB_HASH; skb->queue_mapping = SKB_QUEUE_MAP; skb->vlan_tci = SKB_VLAN_TCI; - skb->vlan_present = SKB_VLAN_PRESENT; skb->vlan_proto = htons(ETH_P_IP); dev_net_set(&dev, &init_net); skb->dev = &dev; diff --git a/net/core/filter.c b/net/core/filter.c index bb0136e7a8e4..358d5e70671a 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -325,11 +325,11 @@ static u32 convert_skb_access(int skb_field, int dst_reg, int src_reg, offsetof(struct sk_buff, vlan_tci)); break; case SKF_AD_VLAN_TAG_PRESENT: - *insn++ = BPF_LDX_MEM(BPF_B, dst_reg, src_reg, PKT_VLAN_PRESENT_OFFSET); - if (PKT_VLAN_PRESENT_BIT) - *insn++ = BPF_ALU32_IMM(BPF_RSH, dst_reg, PKT_VLAN_PRESENT_BIT); - if (PKT_VLAN_PRESENT_BIT < 7) - *insn++ = BPF_ALU32_IMM(BPF_AND, dst_reg, 1); + BUILD_BUG_ON(sizeof_field(struct sk_buff, vlan_all) != 4); + *insn++ = BPF_LDX_MEM(BPF_W, dst_reg, src_reg, + offsetof(struct sk_buff, vlan_all)); + *insn++ = BPF_JMP_IMM(BPF_JEQ, dst_reg, 0, 1); + *insn++ = BPF_ALU32_IMM(BPF_MOV, dst_reg, 1); break; } @@ -9290,13 +9290,11 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type, break; case offsetof(struct __sk_buff, vlan_present): - *target_size = 1; - *insn++ = BPF_LDX_MEM(BPF_B, si->dst_reg, si->src_reg, - PKT_VLAN_PRESENT_OFFSET); - if (PKT_VLAN_PRESENT_BIT) - *insn++ = BPF_ALU32_IMM(BPF_RSH, si->dst_reg, PKT_VLAN_PRESENT_BIT); - if (PKT_VLAN_PRESENT_BIT < 7) - *insn++ = BPF_ALU32_IMM(BPF_AND, si->dst_reg, 1); + *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->src_reg, + bpf_target_off(struct sk_buff, + vlan_all, 4, target_size)); + *insn++ = BPF_JMP_IMM(BPF_JEQ, si->dst_reg, 0, 1); + *insn++ = BPF_ALU32_IMM(BPF_MOV, si->dst_reg, 1); break; case offsetof(struct __sk_buff, vlan_tci): -- cgit v1.2.3 From e14e4c933e0047653f835e30d7d740ebb2a530cc Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 9 Nov 2022 14:42:48 -0800 Subject: ARM: OMAP2+: pdata-quirks: stop including wl12xx.h As of commit 2398c41d6432 ("omap: pdata-quirks: remove openpandora quirks for mmc3 and wl1251") the code no longer creates an instance of wl1251_platform_data, so there is no need for including this header. Signed-off-by: Dmitry Torokhov Acked-by: Tony Lindgren Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221109224250.2885119-1-dmitry.torokhov@gmail.com --- arch/arm/mach-omap2/pdata-quirks.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 5b99d602c87b..9409b9f5711c 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From b54b6003612a376e7be32cbc5c1af3754bbbbb3d Mon Sep 17 00:00:00 2001 From: Pu Lehui Date: Tue, 6 Dec 2022 17:14:10 +0800 Subject: riscv, bpf: Emit fixed-length instructions for BPF_PSEUDO_FUNC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For BPF_PSEUDO_FUNC instruction, verifier will refill imm with correct addresses of bpf_calls and then run last pass of JIT. Since the emit_imm of RV64 is variable-length, which will emit appropriate length instructions accorroding to the imm, it may broke ctx->offset, and lead to unpredictable problem, such as inaccurate jump. So let's fix it with fixed-length instructions. Fixes: 69c087ba6225 ("bpf: Add bpf_for_each_map_elem() helper") Suggested-by: Björn Töpel Signed-off-by: Pu Lehui Signed-off-by: Daniel Borkmann Reviewed-by: Björn Töpel Acked-by: Björn Töpel Link: https://lore.kernel.org/bpf/20221206091410.1584784-1-pulehui@huaweicloud.com --- arch/riscv/net/bpf_jit_comp64.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c index 00df3a8f92ac..f2417ac54edd 100644 --- a/arch/riscv/net/bpf_jit_comp64.c +++ b/arch/riscv/net/bpf_jit_comp64.c @@ -136,6 +136,25 @@ static bool in_auipc_jalr_range(s64 val) val < ((1L << 31) - (1L << 11)); } +/* Emit fixed-length instructions for address */ +static int emit_addr(u8 rd, u64 addr, bool extra_pass, struct rv_jit_context *ctx) +{ + u64 ip = (u64)(ctx->insns + ctx->ninsns); + s64 off = addr - ip; + s64 upper = (off + (1 << 11)) >> 12; + s64 lower = off & 0xfff; + + if (extra_pass && !in_auipc_jalr_range(off)) { + pr_err("bpf-jit: target offset 0x%llx is out of range\n", off); + return -ERANGE; + } + + emit(rv_auipc(rd, upper), ctx); + emit(rv_addi(rd, rd, lower), ctx); + return 0; +} + +/* Emit variable-length instructions for 32-bit and 64-bit imm */ static void emit_imm(u8 rd, s64 val, struct rv_jit_context *ctx) { /* Note that the immediate from the add is sign-extended, @@ -1050,7 +1069,15 @@ out_be: u64 imm64; imm64 = (u64)insn1.imm << 32 | (u32)imm; - emit_imm(rd, imm64, ctx); + if (bpf_pseudo_func(insn)) { + /* fixed-length insns for extra jit pass */ + ret = emit_addr(rd, imm64, extra_pass, ctx); + if (ret) + return ret; + } else { + emit_imm(rd, imm64, ctx); + } + return 1; } -- cgit v1.2.3 From 7a73b976eda916a2ed703e4b996c92c871715d9b Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Fri, 4 Nov 2022 22:12:59 +0100 Subject: arm64: dts: apple: t8103: Add Bluetooth controller Add bluetooth controller nodes and the required brcm,board-type properties to be able to select the correct firmware to all board device trees. Signed-off-by: Sven Peter Signed-off-by: Luiz Augusto von Dentz --- arch/arm64/boot/dts/apple/t8103-j274.dts | 4 ++++ arch/arm64/boot/dts/apple/t8103-j293.dts | 4 ++++ arch/arm64/boot/dts/apple/t8103-j313.dts | 4 ++++ arch/arm64/boot/dts/apple/t8103-j456.dts | 4 ++++ arch/arm64/boot/dts/apple/t8103-j457.dts | 4 ++++ arch/arm64/boot/dts/apple/t8103-jxxx.dtsi | 8 ++++++++ 6 files changed, 28 insertions(+) (limited to 'arch') diff --git a/arch/arm64/boot/dts/apple/t8103-j274.dts b/arch/arm64/boot/dts/apple/t8103-j274.dts index c1f3ba9c39f6..b52ddc409893 100644 --- a/arch/arm64/boot/dts/apple/t8103-j274.dts +++ b/arch/arm64/boot/dts/apple/t8103-j274.dts @@ -21,6 +21,10 @@ }; }; +&bluetooth0 { + brcm,board-type = "apple,atlantisb"; +}; + &wifi0 { brcm,board-type = "apple,atlantisb"; }; diff --git a/arch/arm64/boot/dts/apple/t8103-j293.dts b/arch/arm64/boot/dts/apple/t8103-j293.dts index ecb10d237a05..151074109a11 100644 --- a/arch/arm64/boot/dts/apple/t8103-j293.dts +++ b/arch/arm64/boot/dts/apple/t8103-j293.dts @@ -17,6 +17,10 @@ model = "Apple MacBook Pro (13-inch, M1, 2020)"; }; +&bluetooth0 { + brcm,board-type = "apple,honshu"; +}; + &wifi0 { brcm,board-type = "apple,honshu"; }; diff --git a/arch/arm64/boot/dts/apple/t8103-j313.dts b/arch/arm64/boot/dts/apple/t8103-j313.dts index df741737b8e6..bc1f865aa790 100644 --- a/arch/arm64/boot/dts/apple/t8103-j313.dts +++ b/arch/arm64/boot/dts/apple/t8103-j313.dts @@ -17,6 +17,10 @@ model = "Apple MacBook Air (M1, 2020)"; }; +&bluetooth0 { + brcm,board-type = "apple,shikoku"; +}; + &wifi0 { brcm,board-type = "apple,shikoku"; }; diff --git a/arch/arm64/boot/dts/apple/t8103-j456.dts b/arch/arm64/boot/dts/apple/t8103-j456.dts index 8c6bf9592510..7ea27456f33c 100644 --- a/arch/arm64/boot/dts/apple/t8103-j456.dts +++ b/arch/arm64/boot/dts/apple/t8103-j456.dts @@ -21,6 +21,10 @@ }; }; +&bluetooth0 { + brcm,board-type = "apple,capri"; +}; + &wifi0 { brcm,board-type = "apple,capri"; }; diff --git a/arch/arm64/boot/dts/apple/t8103-j457.dts b/arch/arm64/boot/dts/apple/t8103-j457.dts index fe7c0aaf7d62..8ee0ac871426 100644 --- a/arch/arm64/boot/dts/apple/t8103-j457.dts +++ b/arch/arm64/boot/dts/apple/t8103-j457.dts @@ -21,6 +21,10 @@ }; }; +&bluetooth0 { + brcm,board-type = "apple,santorini"; +}; + &wifi0 { brcm,board-type = "apple,santorini"; }; diff --git a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi index 3d15b8e2a6c1..cc2e04035763 100644 --- a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi @@ -11,6 +11,7 @@ / { aliases { + bluetooth0 = &bluetooth0; serial0 = &serial0; serial2 = &serial2; wifi0 = &wifi0; @@ -77,4 +78,11 @@ local-mac-address = [00 00 00 00 00 00]; apple,antenna-sku = "XX"; }; + + bluetooth0: bluetooth@0,1 { + compatible = "pci14e4,5f69"; + reg = <0x10100 0x0 0x0 0x0 0x0>; + /* To be filled by the loader */ + local-bd-address = [00 00 00 00 00 00]; + }; }; -- cgit v1.2.3