From 2e63a4fc4056bcddcdc700f4d978432c90e9314d Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 20 Aug 2020 15:57:38 +0200 Subject: [PATCH 01/27] Remove more promiscuous messages --- .../hack-5.4/999-stop-promiscuous-info.patch | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/root/target/linux/generic/hack-5.4/999-stop-promiscuous-info.patch b/root/target/linux/generic/hack-5.4/999-stop-promiscuous-info.patch index 2dc06ee6..850613b5 100644 --- a/root/target/linux/generic/hack-5.4/999-stop-promiscuous-info.patch +++ b/root/target/linux/generic/hack-5.4/999-stop-promiscuous-info.patch @@ -12,3 +12,36 @@ if (audit_enabled) { current_uid_gid(&uid, &gid); audit_log(current->audit_context, GFP_ATOMIC, +--- a/drivers/net/usb/r8152.c 2020-08-13 13:11:25.866435255 +0200 ++++ b/drivers/net/usb/r8152.c 2020-08-13 13:11:51.973994306 +0200 +@@ -2353,7 +2353,7 @@ + + if (netdev->flags & IFF_PROMISC) { + /* Unconditionally log net taps. */ +- netif_notice(tp, link, netdev, "Promiscuous mode enabled\n"); ++ //netif_notice(tp, link, netdev, "Promiscuous mode enabled\n"); + ocp_data |= RCR_AM | RCR_AAP; + mc_filter[1] = 0xffffffff; + mc_filter[0] = 0xffffffff; +--- a/drivers/net/usb/pegasus.c 2020-08-13 13:14:15.519570376 +0200 ++++ b/drivers/net/usb/pegasus.c 2020-08-13 13:14:26.795380006 +0200 +@@ -1031,7 +1031,7 @@ + + if (net->flags & IFF_PROMISC) { + pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS; +- netif_info(pegasus, link, net, "Promiscuous mode enabled\n"); ++ //netif_info(pegasus, link, net, "Promiscuous mode enabled\n"); + } else if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI)) { + pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST; + pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS; +--- a/drivers/net/ethernet/realtek/r8169_main.c 2020-08-13 13:15:44.478068638 +0200 ++++ b/drivers/net/ethernet/realtek/r8169_main.c 2020-08-13 13:15:59.181820450 +0200 +@@ -4313,7 +4313,7 @@ + + if (dev->flags & IFF_PROMISC) { + /* Unconditionally log net taps. */ +- netif_notice(tp, link, dev, "Promiscuous mode enabled\n"); ++ //netif_notice(tp, link, dev, "Promiscuous mode enabled\n"); + rx_mode |= AcceptAllPhys; + } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT || + dev->flags & IFF_ALLMULTI || From f890a36727d7ce259a589c62057cbb64aca4681a Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 20 Aug 2020 16:01:51 +0200 Subject: [PATCH 02/27] Add p2w_r619ac support --- root/package/firmware/ipq-wifi/Makefile | 119 +++ .../ipq-wifi/board-p2w_r619ac.qca4019 | Bin 0 -> 24300 bytes .../ipq40xx/base-files/etc/board.d/02_network | 173 +++++ .../etc/hotplug.d/firmware/11-ath10k-caldata | 242 ++++++ .../base-files/lib/upgrade/platform.sh | 123 +++ .../arm/boot/dts/qcom-ipq4019-r619ac-128m.dts | 18 + .../arch/arm/boot/dts/qcom-ipq4019-r619ac.dts | 12 + .../arm/boot/dts/qcom-ipq4019-r619ac.dtsi | 322 ++++++++ root/target/linux/ipq40xx/image/Makefile | 734 ++++++++++++++++++ .../901-arm-boot-add-dts-files.patch | 65 ++ 10 files changed, 1808 insertions(+) create mode 100644 root/package/firmware/ipq-wifi/Makefile create mode 100644 root/package/firmware/ipq-wifi/board-p2w_r619ac.qca4019 create mode 100755 root/target/linux/ipq40xx/base-files/etc/board.d/02_network create mode 100644 root/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata create mode 100644 root/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh create mode 100644 root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac-128m.dts create mode 100644 root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac.dts create mode 100644 root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac.dtsi create mode 100644 root/target/linux/ipq40xx/image/Makefile create mode 100644 root/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch diff --git a/root/package/firmware/ipq-wifi/Makefile b/root/package/firmware/ipq-wifi/Makefile new file mode 100644 index 00000000..4b0e29ec --- /dev/null +++ b/root/package/firmware/ipq-wifi/Makefile @@ -0,0 +1,119 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/version.mk + +PKG_NAME:=ipq-wifi +PKG_RELEASE:=1 +PKG_FLAGS:=nonshared + +include $(INCLUDE_DIR)/package.mk + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Compile +endef + +# Use ath10k-bdencoder from https://github.com/qca/qca-swiss-army-knife.git +# to generate the board-* files here. +# +# This is intended to be used on an interim basis until device-specific +# board data for new devices is available through the upstream compilation +# +# Please send a mail with your device-specific board files upstream. +# You can find instructions and examples on the linux-wireless wiki: +# + +ALLWIFIBOARDS:= \ + 8dev_habanero-dvk \ + aruba_ap-303 \ + avm_fritzrepeater-1200 \ + buffalo_wtr-m2133hp \ + cellc_rtl30vw \ + dlink_dap2610 \ + engenius_eap2200 \ + engenius_emd1 \ + engenius_emr3500 \ + ezviz_cs-w3-wd1200g-eup \ + glinet_gl-s1300 \ + linksys_ea8300 \ + p2w_r619c \ + mobipromo_cm520-79f \ + qxwlan_e2600ac + +ALLWIFIPACKAGES:=$(foreach BOARD,$(ALLWIFIBOARDS),ipq-wifi-$(BOARD)) + +define Package/ipq-wifi-default + SUBMENU:=ath10k Board-Specific Overrides + SECTION:=firmware + CATEGORY:=Firmware + DEPENDS:=@TARGET_ipq40xx + TITLE:=Custom Board +endef + +define ipq-wifi-install-one-to + $(INSTALL_DIR) $(2)/lib/firmware/ath10k/$(3)/ + $(INSTALL_DATA) $(1) $(2)/lib/firmware/ath10k/$(3)/board-2.bin +endef + +define ipq-wifi-install-one + $(if $(filter $(suffix $(1)),.QCA4019 .qca4019),\ + $(call ipq-wifi-install-one-to,$(1),$(2),QCA4019/hw1.0),\ + $(if $(filter $(suffix $(1)),.QCA9888 .qca9888),\ + $(call ipq-wifi-install-one-to,$(1),$(2),QCA9888/hw2.0),\ + $(if $(filter $(suffix $(1)),.QCA9984 .qca9984),\ + $(call ipq-wifi-install-one-to,$(1),$(2),QCA9984/hw1.0),\ + $(error Unrecognized board-file suffix '$(suffix $(1))' for '$(1)')\ + ))) + +endef +# Blank line required at end of above define due to foreach context + +define generate-ipq-wifi-package + define Package/ipq-wifi-$(1) + $(call Package/ipq-wifi-default) + TITLE:=board-2.bin Overrides for $(2) + CONFLICTS:=$(PREV_BOARD) + endef + + define Package/ipq-wifi-$(1)/description +The $(2) requires board-specific, reference ("cal") data +that is not yet present in the upstream wireless firmware distribution. + +This package supplies board-2.bin file(s) that, in the interim, +overwrite those supplied by the ath10k-firmware-* packages. + +This is package is only necessary for the $(2). + +Do not install it for any other device! + endef + + define Package/ipq-wifi-$(1)/install-overlay + $$$$(foreach IPQ_WIFI_BOARD_FILE,$$$$(wildcard board-$(1).*),\ + $$$$(call ipq-wifi-install-one,$$$$(IPQ_WIFI_BOARD_FILE),$$(1))) + endef + + PREV_BOARD+=ipq-wifi-$(1) +endef + +# Add board name to ALLWIFIBOARDS +# Place files in this directory as board-. +# Add $(eval $(call generate-ipq-wifi-package,,)) + +$(eval $(call generate-ipq-wifi-package,8dev_habanero-dvk,8devices Habanero DVK)) +$(eval $(call generate-ipq-wifi-package,aruba_ap-303,Aruba AP-303)) +$(eval $(call generate-ipq-wifi-package,avm_fritzrepeater-1200,AVM FRITZRepeater 1200)) +$(eval $(call generate-ipq-wifi-package,buffalo_wtr-m2133hp,Buffalo WTR-M2133HP)) +$(eval $(call generate-ipq-wifi-package,cellc_rtl30vw, Cell C RTL30VW)) +$(eval $(call generate-ipq-wifi-package,dlink_dap2610,D-Link DAP-2610)) +$(eval $(call generate-ipq-wifi-package,engenius_eap2200,EnGenius EAP2200)) +$(eval $(call generate-ipq-wifi-package,engenius_emd1,EnGenius EMD1)) +$(eval $(call generate-ipq-wifi-package,engenius_emr3500,EnGenius EMR3500)) +$(eval $(call generate-ipq-wifi-package,ezviz_cs-w3-wd1200g-eup,EZVIZ CS-W3-WD1200G EUP)) +$(eval $(call generate-ipq-wifi-package,glinet_gl-s1300,GL.iNet GL-S1300)) +$(eval $(call generate-ipq-wifi-package,linksys_ea8300,Linksys EA8300)) +$(eval $(call generate-ipq-wifi-package,mobipromo_cm520-79f,MobiPromo CM520-79F)) +$(eval $(call generate-ipq-wifi-package,qxwlan_e2600ac,Qxwlan E2600AC)) +$(eval $(call generate-ipq-wifi-package,p2w_r619ac,PW R619AC)) + +$(foreach PACKAGE,$(ALLWIFIPACKAGES),$(eval $(call BuildPackage,$(PACKAGE)))) diff --git a/root/package/firmware/ipq-wifi/board-p2w_r619ac.qca4019 b/root/package/firmware/ipq-wifi/board-p2w_r619ac.qca4019 new file mode 100644 index 0000000000000000000000000000000000000000..a1b1166f6f9dd713fd5d45bbf50767a03703e902 GIT binary patch literal 24300 zcmeHPT~HHQ7QVsoqvA*>0UY-!5feV8|2_H7=d%G%oUWu3h@orVC(ND#&VeZuK` z?(KW-Irr-(>F)a_pQWcor|nS2#b!s#bJOw_pt7d4H0sVsE7{M|B3Slt7niH&q z0yJJ^A7FrD0M@yCp(=n|UOX&4;LDZ>h4E-80OI50|MTVzkaFC>+kan3rF0F)me>2+ zf&t^{>|X6;B=9qo+57C*H%{&Hg0n#{N>GlJJzb{S%y`^^h~!x7%*Es9o}k5rd`-t7 zEe^}N#dh3>4#Z`{;gF&kBK5Io04$L@DxRL7eB!9j?Ebvj4Iimq-8O}2 zYpYh1sZM=0+SAfls?N^b{Aj4>Olytiv&_Ut!_cbL8vmO?s2M1t1?qsJQy)ybJr(6za7zghvi-RNnB zuGtd7qtTv=jn(RWNvy>oVrG8tsWn1*PnVgyX@{A3*siSvlx)vzd9^<2EB_)(8@tOV zb>wPoOHygrPHy(Yp~HrZGlCl5V#Dxm!{#%=wd{TOuV{{Em-Dy#$nN)7olYqe7Wu25 z-fH|h_l&4EaQ`>M^@i=|qU!?=KDkjy*K&!2L@5^_|qkNkDV6EYeoq#hyY+PTwGij zXuD>OtE;PE7sd+-;qyXxyaJ{Nymq4HS4N<{y{>M@4poK( ztY7cuMh2G%!}vU25UgM_IaU^$5Hkfx}my zXd6L_BE^bCB1)s8A_WoQsJ18;8iX8g5iDD%U^s@Q;b~YL9*0#QJ$9n`Y+FayTmwig z^1va3g|kGg=PZnib46U07w(1m;&NOrl0TPYS$LKxOC`f)m=YJ`Vv+c{7)!>JMaimI zJQkDSQ%M;6ZJSd$Nu^U+(dL}vGapFUIQuml^T+)~{;G65{dGE)jc1FpRq=TI>v${$ zPZ6c4$b(?LHHRXhU-B(FcdO4DN31pM17-S?#kOVZ|7D?VE8&`yp2K{OK8+HMk{tx- zQ^O80Gn!W=N;43kD>MQ$0yF|N0yF|N0;?E-P2x>h5bIO%r&um4Nt}eGvOFjO`6Ux5NQn&t&m2+dPrDV}!tl~pRPkp5zFy9q|`Sx38xTyA&>Bn9G0Lun_-`I=UrTLk6 z(Fo`o@dptM`cOO{gLfdMIy zGGzb*e}61&0w50XG03BWgc}~@^H3^YOTXN8z60(lUMfrLHS|1A`;C$L>A+%lALLaD0c=I-X-!uFIx3Ft3BE zSS{2_sCf-kC2yftLCx!*Dsc<70_r%3c0E=;y36J?SXqhAXU#aLVDG`U&Z{?w@rl3L zvsV@>)3f2c<6r@JfG9x40g87DOogjNDwP5xyi35OxKt!nB`n(g^>kE6EFZBChO;un z8CVW0QJjcvWvRQ-Ywj4-=Nwfoms=c1x%NqRx%T243`$M?)i1V&skS}Unlq0fns=-{^=DaVI zYmbHuw!CJ9ft8u0e%o;!;o1W(muuG9f$Y`cy#zo?$*lSYDAcZnmiD>!GEN`o_C5btgXZW$5~xh+6pzg?i$)LIRQ|Qcx@=ihetM{GH za}#TpJ!zZMB`3J#Tl8;i&9g`L2U6|BRE6jP_rn)fw-+P@r}MyTccD+ z#L%HbS3x;kHADyj>~@~0*5_*zC$F12hz5P3R!U6hd$dQC+XTMm2<6({WJ<tyHE-Vocu>{rX1jE(sSo^mYrw!DOeYi73`3EBz)7re>m4Csq2vL=3v4 zMcEReX`JZR*JyKeDIB=K#_u(J0wLU?rRycBV!*uUZ7g&mRB%wz%j3Key{G6?>AzA%UNG z9O=wx79Qr7cxHSzaNztF9skg#qQ7=Ds8gfEy?tHpUOrx)B^Sr|`(EfPXp1`*tlgON z^j5`1SyNc0-`;24n!Kcl@J#?b>OEGWOczB52HqPy+$lRLtYPhZJf!JJZQ@t>?tRi* zTP#lu3-I-PaJ}M?Qi=1t*!rHFQ*lSUcWu~q|5nMx}9sa{*$;qHf@4aJPNA_oKjpDQ2hKzN!nJTfw+kdRLrY-$= zRHaY;vp;5?i)!>c=(X#1=P_-rLdave4H&9E&)X55;Lp2h(6nql8hMDFePghyJEfUl z!`XZDLUoBEg&z>W>Hezpz_zR?u{Za8+paGXw7lIc*`1->%{^}YvI?TJHAoJL>; zAn>8Tyy0#wHt^_csa8rF)Kak^EG!iM!C&17=7)svLJC}+=9f3-^57||y~m=h)6b1T zQSH|*S_~WT(@iu23qxSOM32Spx3FwijMw|Q_9TNH{nCsxS{4R7B(poIW&S2W1mfB| zrRD4=@*w2Ulbm; +}; + +/delete-node/ &rootfs_part2; diff --git a/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac.dts b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac.dts new file mode 100644 index 00000000..31010dd1 --- /dev/null +++ b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac.dts @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qcom-ipq4019-r619ac.dtsi" + +/ { + model = "P&W R619AC"; + compatible = "p2w,r619ac"; + + chosen { + bootargs-append = " root=/dev/ubiblock0_1 rootfstype=squashfs"; + }; +}; diff --git a/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac.dtsi b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac.dtsi new file mode 100644 index 00000000..81018dd0 --- /dev/null +++ b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac.dtsi @@ -0,0 +1,322 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qcom-ipq4019.dtsi" +#include +#include +#include + +/ { + aliases { + led-boot = &led_sys; + led-failsafe = &led_sys; + led-running = &led_sys; + led-upgrade = &led_sys; + label-mac-device = &gmac0; + }; + + soc { + rng@22000 { + status = "okay"; + }; + + mdio@90000 { + status = "okay"; + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; + }; + + ess-psgmii@98000 { + status = "okay"; + }; + + tcsr@1949000 { + compatible = "qcom,tcsr"; + reg = <0x1949000 0x100>; + qcom,wifi_glb_cfg = ; + }; + + tcsr@194b000 { + compatible = "qcom,tcsr"; + reg = <0x194b000 0x100>; + qcom,usb-hsphy-mode-select = ; + }; + + ess_tcsr@1953000 { + compatible = "qcom,tcsr"; + reg = <0x1953000 0x1000>; + qcom,ess-interface-select = ; + }; + + tcsr@1957000 { + compatible = "qcom,tcsr"; + reg = <0x1957000 0x100>; + qcom,wifi_noc_memtype_m0_m2 = ; + }; + + usb2@60f8800 { + status = "okay"; + }; + + usb3@8af8800 { + status = "okay"; + }; + + crypto@8e3a000 { + status = "okay"; + }; + + watchdog@b017000 { + status = "okay"; + }; + + ess-switch@c000000 { + status = "okay"; + }; + + edma@c080000 { + status = "okay"; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-0 = <&led_pins>; + pinctrl-names = "default"; + + led_sys: sys { + label = "r619ac:blue:sys"; + gpios = <&tlmm 39 GPIO_ACTIVE_HIGH>; + }; + + wlan2g { + label = "r619ac:blue:wlan2g"; + gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "phy0tpt"; + }; + + wlan5g { + label = "r619ac:blue:wlan5g"; + gpios = <&tlmm 50 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "phy1tpt"; + }; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&tlmm 18 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; +}; + +&blsp_dma { + status = "okay"; +}; + +&blsp1_spi1 { + status = "okay"; + + flash@0 { + reg = <0>; + compatible = "jedec,spi-nor"; + spi-max-frequency = <24000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "SBL1"; + reg = <0x0 0x40000>; + read-only; + }; + + partition@40000 { + label = "MIBIB"; + reg = <0x40000 0x20000>; + read-only; + }; + + partition@60000 { + label = "QSEE"; + reg = <0x60000 0x60000>; + read-only; + }; + + partition@c0000 { + label = "CDT"; + reg = <0xc0000 0x10000>; + read-only; + }; + + partition@d0000 { + label = "DDRPARAMS"; + reg = <0xd0000 0x10000>; + read-only; + }; + + partition@e0000 { + label = "APPSBLENV"; + reg = <0xe0000 0x10000>; + read-only; + }; + + partition@f0000 { + label = "APPSBL"; + reg = <0xf0000 0x80000>; + read-only; + }; + + partition@1 { + label = "Bootloader"; + reg = <0x0 0x170000>; + read-only; + }; + + partition@170000 { + label = "ART"; + reg = <0x170000 0x10000>; + read-only; + }; + + partition@180000 { + label = "unused"; + reg = <0x180000 0xe80000>; + }; + }; + }; +}; + +&blsp1_uart1 { + pinctrl-0 = <&serial_0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&cryptobam { + status = "okay"; +}; + +&nand { + status = "okay"; + + nand@0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + rootfs_part1: partition@0 { + label = "rootfs"; + reg = <0x0 0x4000000>; + }; + + rootfs_part2: partition@4000000 { + label = "unused1"; + reg = <0x4000000 0x4000000>; + }; + }; + }; +}; + +&qpic_bam { + status = "okay"; +}; + +&sdhci { + pinctrl-0 = <&sd_0_pins>; + pinctrl-names = "default"; + vqmmc-supply = <&vqmmc>; + status = "okay"; +}; + +&tlmm { + mdio_pins: mdio_pinmux { + mux_1 { + pins = "gpio6"; + function = "mdio"; + bias-pull-up; + }; + + mux_2 { + pins = "gpio7"; + function = "mdc"; + bias-pull-up; + }; + }; + + sd_0_pins: sd_0_pinmux { + mux_1 { + pins = "gpio23", "gpio24", "gpio25", "gpio26", "gpio28"; + function = "sdio"; + drive-strength = <10>; + }; + + mux_2 { + pins = "gpio27"; + function = "sdio"; + drive-strength = <16>; + }; + }; + + serial_0_pins: serial0-pinmux { + mux { + pins = "gpio16", "gpio17"; + function = "blsp_uart0"; + bias-disable; + }; + }; + + led_pins: led_pinmux { + mux { + pins = "gpio32", "gpio39", "gpio50"; + function = "gpio"; + bias-pull-up; + output-low; + }; + + mux_1 { + pins = "gpio52"; + function = "gpio"; + bias-pull-up; + output-high; + }; + + mux_2 { + pins = "gpio61"; + function = "gpio"; + bias-pull-down; + output-high; + }; + }; +}; + +&usb3_ss_phy { + status = "okay"; +}; + +&usb3_hs_phy { + status = "okay"; +}; + +&usb2_hs_phy { + status = "okay"; +}; + +&vqmmc { + status = "okay"; +}; + +&wifi0 { + status = "okay"; + qcom,ath10k-calibration-variant = "R619AC"; +}; + +&wifi1 { + status = "okay"; + qcom,ath10k-calibration-variant = "R619AC"; +}; diff --git a/root/target/linux/ipq40xx/image/Makefile b/root/target/linux/ipq40xx/image/Makefile new file mode 100644 index 00000000..44b6da6d --- /dev/null +++ b/root/target/linux/ipq40xx/image/Makefile @@ -0,0 +1,734 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +DEVICE_VARS += NETGEAR_BOARD_ID NETGEAR_HW_ID +DEVICE_VARS += RAS_BOARD RAS_ROOTFS_SIZE RAS_VERSION +DEVICE_VARS += WRGG_DEVNAME WRGG_SIGNATURE + +define Device/Default + PROFILES := Default + KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts) + KERNEL_INITRAMFS_PREFIX := $$(IMG_PREFIX)-$(1)-initramfs + KERNEL_PREFIX := $$(IMAGE_PREFIX) + KERNEL_LOADADDR := 0x80208000 + DEVICE_DTS = $$(SOC)-$(lastword $(subst _, ,$(1))) + SUPPORTED_DEVICES := $(subst _,$(comma),$(1)) + IMAGES := sysupgrade.bin + IMAGE/sysupgrade.bin = sysupgrade-tar | append-metadata + IMAGE/sysupgrade.bin/squashfs := +endef + +define Device/FitImage + KERNEL_SUFFIX := -fit-uImage.itb + KERNEL = kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb + KERNEL_NAME := Image +endef + +define Device/FitImageLzma + KERNEL_SUFFIX := -fit-uImage.itb + KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb + KERNEL_NAME := Image +endef + +define Device/FitzImage + KERNEL_SUFFIX := -fit-zImage.itb + KERNEL = kernel-bin | fit none $$(DTS_DIR)/$$(DEVICE_DTS).dtb + KERNEL_NAME := zImage +endef + +define Device/UbiFit + KERNEL_IN_UBI := 1 + IMAGES := nand-factory.ubi nand-sysupgrade.bin + IMAGE/nand-factory.ubi := append-ubi + IMAGE/nand-sysupgrade.bin := sysupgrade-tar | append-metadata +endef + +define Device/DniImage + $(call Device/FitzImage) + NETGEAR_BOARD_ID := + NETGEAR_HW_ID := + IMAGES += factory.img + IMAGE/factory.img := append-kernel | pad-offset 64k 64 | append-uImage-fakehdr filesystem | append-rootfs | pad-rootfs | netgear-dni + IMAGE/sysupgrade.bin := append-kernel | pad-offset 64k 64 | append-uImage-fakehdr filesystem | \ + append-rootfs | pad-rootfs | append-metadata | check-size +endef + +define Build/append-rootfshdr + mkimage -A $(LINUX_KARCH) \ + -O linux -T filesystem \ + -C lzma -a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \ + -n root.squashfs -d $(IMAGE_ROOTFS) $@.new + dd if=$@.new bs=64 count=1 >> $(IMAGE_KERNEL) +endef + +define Build/mkmylofw_32m + $(eval device_id=$(word 1,$(1))) + $(eval revision=$(word 2,$(1))) + + let \ + size="$$(stat -c%s $@)" \ + pad="$(subst k,* 1024,$(BLOCKSIZE))" \ + pad="(pad - (size % pad)) % pad" \ + newsize='size + pad'; \ + $(STAGING_DIR_HOST)/bin/mkmylofw \ + -B WPE72 -i 0x11f6:$(device_id):0x11f6:$(device_id) -r $(revision) \ + -s 0x2000000 -p0x180000:$$newsize:al:0x80208000:"OpenWrt":$@ \ + $@.new + @mv $@.new $@ +endef + +define Build/qsdk-ipq-factory-nand-askey + $(TOPDIR)/scripts/mkits-qsdk-ipq-image.sh $@.its\ + askey_kernel $(IMAGE_KERNEL) \ + askey_fs $(IMAGE_ROOTFS) \ + ubifs $@ + PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new + @mv $@.new $@ +endef + +define Build/SenaoFW + -$(STAGING_DIR_HOST)/bin/mksenaofw \ + -n $(BOARD_NAME) -r $(VENDOR_ID) -p $(1) \ + -c $(DATECODE) -w $(2) -x $(CW_VER) -t 0 \ + -e $@ \ + -o $@.new + @cp $@.new $@ +endef + +define Build/wrgg-image + mkwrggimg -i $@ \ + -o $@.new \ + -d "$(WRGG_DEVNAME)" \ + -s "$(WRGG_SIGNATURE)" \ + -v "" -m "" -B "" + mv $@.new $@ +endef + +define Device/8dev_habanero-dvk + $(call Device/FitImageLzma) + DEVICE_VENDOR := 8devices + DEVICE_MODEL := Habanero DVK + IMAGE_SIZE := 30976k + SOC := qcom-ipq4019 + DEVICE_PACKAGES := ipq-wifi-8dev_habanero-dvk + IMAGE/sysupgrade.bin := append-kernel | pad-to 64k | append-rootfs | pad-rootfs | append-metadata | check-size +endef +TARGET_DEVICES += 8dev_habanero-dvk + +define Device/8dev_jalapeno-common + $(call Device/FitImage) + $(call Device/UbiFit) + BLOCKSIZE := 128k + PAGESIZE := 2048 + SOC := qcom-ipq4018 +endef + +define Device/8dev_jalapeno + $(call Device/8dev_jalapeno-common) + DEVICE_VENDOR := 8devices + DEVICE_MODEL := Jalapeno +endef +TARGET_DEVICES += 8dev_jalapeno + +define Device/alfa-network_ap120c-ac + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := ALFA Network + DEVICE_MODEL := AP120C-AC + SOC := qcom-ipq4018 + DEVICE_PACKAGES := kmod-usb-acm \ + kmod-tpm-i2c-atmel uboot-envtools + BLOCKSIZE := 128k + PAGESIZE := 2048 + IMAGE_SIZE := 65536k + IMAGES := nand-factory.bin nand-sysupgrade.bin + IMAGE/nand-factory.bin := append-ubi | qsdk-ipq-factory-nand +endef +TARGET_DEVICES += alfa-network_ap120c-ac + +define Device/aruba_glenmorangie + $(call Device/FitImageLzma) + DEVICE_VENDOR := Aruba + SOC := qcom-ipq4029 + DEVICE_PACKAGES := ipq-wifi-aruba_ap-303 +endef + +define Device/aruba_ap-303 + $(call Device/aruba_glenmorangie) + DEVICE_MODEL := AP-303 +endef +TARGET_DEVICES += aruba_ap-303 + +define Device/aruba_ap-303h + $(call Device/aruba_glenmorangie) + DEVICE_MODEL := AP-303H +endef +TARGET_DEVICES += aruba_ap-303h + +define Device/aruba_ap-365 + $(call Device/aruba_glenmorangie) + DEVICE_MODEL := AP-365 + DEVICE_PACKAGES += kmod-hwmon-ad7418 +endef +TARGET_DEVICES += aruba_ap-365 + +define Device/asus_map-ac2200 + $(call Device/FitImageLzma) + DEVICE_VENDOR := ASUS + DEVICE_MODEL := Lyra (MAP-AC2200) + SOC := qcom-ipq4019 + DEVICE_PACKAGES := ath10k-firmware-qca9888-ct kmod-ath3k +endef +TARGET_DEVICES += asus_map-ac2200 + +define Device/asus_rt-ac58u + $(call Device/FitImageLzma) + DEVICE_VENDOR := ASUS + DEVICE_MODEL := RT-AC58U + SOC := qcom-ipq4018 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DTB_SIZE := 65536 + IMAGE_SIZE := 20439364 + FILESYSTEMS := squashfs +# Someone - in their infinite wisdom - decided to put the firmware +# version in front of the image name \03\00\00\04 => Version 3.0.0.4 +# Since u-boot works with strings we either need another fixup step +# to add a version... or we are very careful not to add '\0' into that +# string and call it a day.... Yeah, we do the latter! + UIMAGE_NAME:=$(shell echo -e '\03\01\01\01RT-AC58U') + DEVICE_PACKAGES := -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers \ + kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += asus_rt-ac58u + +define Device/avm_fritzbox-4040 + $(call Device/FitImageLzma) + DEVICE_VENDOR := AVM + DEVICE_MODEL := FRITZ!Box 4040 + SOC := qcom-ipq4018 + BOARD_NAME := fritz4040 + IMAGE_SIZE := 29056k + UBOOT_PATH := $(STAGING_DIR_IMAGE)/uboot-fritz4040.bin + UBOOT_PARTITION_SIZE := 524288 + IMAGES += eva.bin + IMAGE/eva.bin := append-uboot | pad-to $$$$(UBOOT_PARTITION_SIZE) | append-kernel | append-rootfs | pad-rootfs + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata | check-size + DEVICE_PACKAGES := fritz-tffs fritz-caldata +endef +TARGET_DEVICES += avm_fritzbox-4040 + +define Device/avm_fritzbox-7530 + $(call Device/FitImageLzma) + DEVICE_VENDOR := AVM + DEVICE_MODEL := FRITZ!Box 7530 + SOC := qcom-ipq4019 + DEVICE_PACKAGES := fritz-caldata fritz-tffs-nand +endef +TARGET_DEVICES += avm_fritzbox-7530 + +define Device/avm_fritzrepeater-1200 + $(call Device/FitImageLzma) + DEVICE_VENDOR := AVM + DEVICE_MODEL := FRITZ!Repeater 1200 + SOC := qcom-ipq4019 + DEVICE_PACKAGES := fritz-caldata fritz-tffs-nand ipq-wifi-avm_fritzrepeater-1200 +endef +TARGET_DEVICES += avm_fritzrepeater-1200 + +define Device/avm_fritzrepeater-3000 + $(call Device/FitImageLzma) + DEVICE_VENDOR := AVM + DEVICE_MODEL := FRITZ!Repeater 3000 + SOC := qcom-ipq4019 + DEVICE_PACKAGES := ath10k-firmware-qca9984-ct fritz-caldata fritz-tffs-nand +endef +TARGET_DEVICES += avm_fritzrepeater-3000 + +define Device/buffalo_wtr-m2133hp + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := Buffalo + DEVICE_MODEL := WTR-M2133HP + SOC := qcom-ipq4019 + DEVICE_PACKAGES := uboot-envtools ath10k-firmware-qca9984-ct ipq-wifi-buffalo_wtr-m2133hp + BLOCKSIZE := 128k + PAGESIZE := 2048 +endef +TARGET_DEVICES += buffalo_wtr-m2133hp + +define Device/cellc_rtl30vw + KERNEL_SUFFIX := -fit-uImage.itb + KERNEL_INITRAMFS = kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb + KERNEL = kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb | uImage lzma | pad-to 2048 + KERNEL_NAME := Image + KERNEL_IN_UBI := + IMAGES := nand-factory.bin nand-sysupgrade.bin + IMAGE/nand-factory.bin := append-rootfshdr | append-ubi | qsdk-ipq-factory-nand-askey + IMAGE/nand-sysupgrade.bin := append-rootfshdr | sysupgrade-tar | append-metadata + DEVICE_VENDOR := Cell C + DEVICE_MODEL := RTL30VW + SOC := qcom-ipq4019 + DEVICE_DTS_CONFIG := config@5 + KERNEL_INSTALL := 1 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 57344k + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := kmod-usb-net-qmi-wwan kmod-usb-serial-option uqmi ipq-wifi-cellc_rtl30vw +endef +TARGET_DEVICES += cellc_rtl30vw + +define Device/cilab_meshpoint-one + $(call Device/8dev_jalapeno-common) + DEVICE_VENDOR := Crisis Innovation Lab + DEVICE_MODEL := MeshPoint.One + DEVICE_PACKAGES := kmod-i2c-gpio kmod-iio-bmp280-i2c kmod-hwmon-ina2xx kmod-rtc-pcf2127 +endef +TARGET_DEVICES += cilab_meshpoint-one + +define Device/compex_wpj419 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := Compex + DEVICE_MODEL := WPJ419 + SOC := qcom-ipq4019 + DEVICE_DTS_CONFIG := config@12 + KERNEL_INSTALL := 1 + BLOCKSIZE := 128k + PAGESIZE := 2048 + FILESYSTEMS := squashfs +endef +TARGET_DEVICES += compex_wpj419 + +define Device/compex_wpj428 + $(call Device/FitImage) + DEVICE_VENDOR := Compex + DEVICE_MODEL := WPJ428 + SOC := qcom-ipq4028 + DEVICE_DTS_CONFIG := config@4 + BLOCKSIZE := 64k + IMAGE_SIZE := 31232k + KERNEL_SIZE := 4096k + IMAGES += cpximg-6a04.bin + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + IMAGE/cpximg-6a04.bin := append-kernel | append-rootfs | pad-rootfs | mkmylofw_32m 0x8A2 3 + DEVICE_PACKAGES := kmod-gpio-beeper +endef +TARGET_DEVICES += compex_wpj428 + +define Device/dlink_dap-2610 + $(call Device/FitImageLzma) + DEVICE_VENDOR := D-Link + DEVICE_MODEL := DAP-2610 + SOC := qcom-ipq4018 + DEVICE_DTS_CONFIG := config@ap.dk01.1-c1 + BLOCKSIZE := 64k + WRGG_DEVNAME := /dev/mtdblock/8 + WRGG_SIGNATURE := wapac30_dkbs_dap2610 + IMAGE_SIZE := 14080k + IMAGES += factory.bin + # Bootloader expects a special 160 byte header which is added by + # wrgg-image. + # Factory image size must be larger than 6MB, and size in wrgg header must + # match actual factory image size to be flashable from D-Link http server. + # Bootloader verifies checksum of wrgg image before booting, thus jffs2 + # cannot be part of the wrgg image. This is solved in the factory image by + # having the rootfs at the end of the image (without pad-rootfs). And in + # the sysupgrade image only the kernel is included in the wrgg checksum, + # but this is not flashable from the D-link http server. + # append-rootfs must start on an erase block boundary. + IMAGE/factory.bin := append-kernel | pad-offset 6144k 160 | append-rootfs | wrgg-image | check-size + IMAGE/sysupgrade.bin := append-kernel | wrgg-image | pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs | check-size | append-metadata + DEVICE_PACKAGES := ipq-wifi-dlink_dap2610 +endef +TARGET_DEVICES += dlink_dap-2610 + +define Device/engenius_eap1300 + $(call Device/FitImage) + DEVICE_VENDOR := EnGenius + DEVICE_MODEL := EAP1300 + DEVICE_DTS_CONFIG := config@4 + BOARD_NAME := eap1300 + SOC := qcom-ipq4018 + KERNEL_SIZE := 5120k + IMAGE_SIZE := 25344k + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata +endef +TARGET_DEVICES += engenius_eap1300 + +define Device/engenius_eap2200 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := EnGenius + DEVICE_MODEL := EAP2200 + SOC := qcom-ipq4019 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := ath10k-firmware-qca9888-ct ipq-wifi-engenius_eap2200 -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers +endef +TARGET_DEVICES += engenius_eap2200 + +define Device/engenius_emd1 + $(call Device/FitImage) + DEVICE_VENDOR := EnGenius + DEVICE_MODEL := EMD1 + DEVICE_DTS_CONFIG := config@4 + SOC := qcom-ipq4018 + IMAGE_SIZE := 30720k + IMAGES += factory.bin + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + IMAGE/factory.bin := qsdk-ipq-factory-nor | check-size +endef +TARGET_DEVICES += engenius_emd1 + +define Device/engenius_emr3500 + $(call Device/FitImage) + DEVICE_VENDOR := EnGenius + DEVICE_MODEL := EMR3500 + DEVICE_DTS_CONFIG := config@4 + SOC := qcom-ipq4018 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 30720k + IMAGES += factory.bin + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + IMAGE/factory.bin := qsdk-ipq-factory-nor | check-size +endef +TARGET_DEVICES += engenius_emr3500 + +define Device/engenius_ens620ext + $(call Device/FitImage) + DEVICE_VENDOR := EnGenius + DEVICE_MODEL := ENS620EXT + SOC := qcom-ipq4018 + DEVICE_DTS_CONFIG := config@4 + BLOCKSIZE := 64k + PAGESIZE := 256 + BOARD_NAME := ENS620EXT + VENDOR_ID := 0x0101 + PRODUCT_ID := 0x79 + PRODUCT_ID_NEW := 0xA4 + DATECODE := 190507 + FW_VER := 3.1.2 + FW_VER_NEW := 3.5.6 + CW_VER := 1.8.99 + IMAGE_SIZE := 21312k + KERNEL_SIZE := 5120k + FILESYSTEMS := squashfs + IMAGES += factory_30.bin factory_35.bin + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | check-size | append-metadata + IMAGE/factory_30.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | check-size | SenaoFW $$$$(PRODUCT_ID) $$$$(FW_VER) + IMAGE/factory_35.bin := qsdk-ipq-factory-nor | check-size | SenaoFW $$$$(PRODUCT_ID_NEW) $$$$(FW_VER_NEW) +endef +TARGET_DEVICES += engenius_ens620ext + +define Device/ezviz_cs-w3-wd1200g-eup + $(call Device/FitImage) + DEVICE_VENDOR := EZVIZ + DEVICE_MODEL := CS-W3-WD1200G + DEVICE_VARIANT := EUP + DEVICE_DTS_CONFIG := config@4 + IMAGE_SIZE := 14848k + SOC := qcom-ipq4018 + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | \ + append-metadata + DEVICE_PACKAGES := -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers \ + ipq-wifi-ezviz_cs-w3-wd1200g-eup +endef +TARGET_DEVICES += ezviz_cs-w3-wd1200g-eup + +define Device/glinet_gl-b1300 + $(call Device/FitImage) + DEVICE_VENDOR := GL.iNet + DEVICE_MODEL := GL-B1300 + BOARD_NAME := gl-b1300 + SOC := qcom-ipq4029 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 26624k + IMAGE/sysupgrade.bin := append-kernel |append-rootfs | pad-rootfs | append-metadata +endef +TARGET_DEVICES += glinet_gl-b1300 + +define Device/glinet_gl-s1300 + $(call Device/FitImage) + DEVICE_VENDOR := GL.iNet + DEVICE_MODEL := GL-S1300 + SOC := qcom-ipq4029 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 26624k + IMAGES := sysupgrade.bin + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + DEVICE_PACKAGES := ipq-wifi-glinet_gl-s1300 kmod-fs-ext4 kmod-mmc kmod-spi-dev +endef +TARGET_DEVICES += glinet_gl-s1300 + +define Device/linksys_ea6350v3 + # The Linksys EA6350v3 has a uboot bootloader that does not + # support either booting lzma kernel images nor booting UBI + # partitions. This uboot, however, supports raw kernel images and + # gzipped images. + # + # As for the time of writing this, the device will boot the kernel + # from a fixed address with a fixed length of 3MiB. Also, the + # device has a hard-coded kernel command line that requieres the + # rootfs and alt_rootfs to be in mtd11 and mtd13 respectively. + # Oh... and the kernel partition overlaps with the rootfs + # partition (the same for alt_kernel and alt_rootfs). + # + # If you are planing re-partitioning the device, you may want to + # keep those details in mind: + # 1. The kernel adresses you should honor are 0x00000000 and + # 0x02800000 respectively. + # 2. The kernel size (plus the dtb) cannot exceed 3.00MiB in size. + # 3. You can use 'zImage', but not a raw 'Image' packed with lzma. + # 4. The kernel command line from uboot is harcoded to boot with + # rootfs either in mtd11 or mtd13. + $(call Device/FitzImage) + DEVICE_VENDOR := Linksys + DEVICE_MODEL := EA6350 + DEVICE_VARIANT := v3 + SOC := qcom-ipq4018 + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_SIZE := 3072k + IMAGE_SIZE := 37888k + UBINIZE_OPTS := -E 5 + IMAGES += factory.bin + IMAGE/factory.bin := append-kernel | append-uImage-fakehdr filesystem | pad-to $$$$(KERNEL_SIZE) | append-ubi | linksys-image type=EA6350v3 + DEVICE_PACKAGES := uboot-envtools +endef +TARGET_DEVICES += linksys_ea6350v3 + +define Device/linksys_ea8300 + $(call Device/FitzImage) + DEVICE_VENDOR := Linksys + DEVICE_MODEL := EA8300 + SOC := qcom-ipq4019 + KERNEL_SIZE := 3072k + IMAGE_SIZE := 87040k + BLOCKSIZE := 128k + PAGESIZE := 2048 + UBINIZE_OPTS := -E 5 # EOD marks to "hide" factory sig at EOF + IMAGES += factory.bin + IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | linksys-image type=EA8300 + DEVICE_PACKAGES := uboot-envtools ath10k-firmware-qca9888-ct ipq-wifi-linksys_ea8300 kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += linksys_ea8300 + +define Device/meraki_mr33 + $(call Device/FitImage) + DEVICE_VENDOR := Cisco Meraki + DEVICE_MODEL := MR33 + SOC := qcom-ipq4029 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := -swconfig ath10k-firmware-qca9887-ct +endef +TARGET_DEVICES += meraki_mr33 + +define Device/mobipromo_cm520-79f + $(call Device/FitzImage) + $(call Device/UbiFit) + DEVICE_VENDOR := MobiPromo + DEVICE_MODEL := CM520-79F + SOC := qcom-ipq4019 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := ipq-wifi-mobipromo_cm520-79f kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += mobipromo_cm520-79f + +define Device/netgear_ex61x0v2 + $(call Device/DniImage) + DEVICE_DTS_CONFIG := config@4 + NETGEAR_BOARD_ID := EX6150v2series + NETGEAR_HW_ID := 29765285+16+0+128+2x2 + IMAGE_SIZE := 14400k + SOC := qcom-ipq4018 +endef + +define Device/netgear_ex6100v2 + $(call Device/netgear_ex61x0v2) + DEVICE_VENDOR := Netgear + DEVICE_MODEL := EX6100 + DEVICE_VARIANT := v2 +endef +TARGET_DEVICES += netgear_ex6100v2 + +define Device/netgear_ex6150v2 + $(call Device/netgear_ex61x0v2) + DEVICE_VENDOR := Netgear + DEVICE_MODEL := EX6150 + DEVICE_VARIANT := v2 +endef +TARGET_DEVICES += netgear_ex6150v2 + +define Device/openmesh_a42 + $(call Device/FitImageLzma) + DEVICE_VENDOR := OpenMesh + DEVICE_MODEL := A42 + SOC := qcom-ipq4018 + DEVICE_DTS_CONFIG := config@om.a42 + BLOCKSIZE := 64k + KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE) + IMAGE_SIZE := 15616k + IMAGES += factory.bin + IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=A42 + IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata + DEVICE_PACKAGES := uboot-envtools +endef +TARGET_DEVICES += openmesh_a42 + +define Device/openmesh_a62 + $(call Device/FitImageLzma) + DEVICE_VENDOR := OpenMesh + DEVICE_MODEL := A62 + SOC := qcom-ipq4019 + DEVICE_DTS_CONFIG := config@om.a62 + BLOCKSIZE := 64k + KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE) + IMAGE_SIZE := 15552k + IMAGES += factory.bin + IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=A62 + IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata + DEVICE_PACKAGES := ath10k-firmware-qca9888-ct uboot-envtools +endef + +TARGET_DEVICES += openmesh_a62 + +define Device/qcom_ap-dk01.1-c1 + DEVICE_VENDOR := Qualcomm Atheros + DEVICE_MODEL := AP-DK01.1 + DEVICE_VARIANT := C1 + BOARD_NAME := ap-dk01.1-c1 + SOC := qcom-ipq4019 + DEVICE_DTS := qcom-ipq4019-ap.dk01.1-c1 + KERNEL_INSTALL := 1 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 26624k + $(call Device/FitImage) + IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | append-metadata +endef +TARGET_DEVICES += qcom_ap-dk01.1-c1 + +define Device/qcom_ap-dk04.1-c1 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := Qualcomm Atheros + DEVICE_MODEL := AP-DK04.1 + DEVICE_VARIANT := C1 + SOC := qcom-ipq4019 + DEVICE_DTS := qcom-ipq4019-ap.dk04.1-c1 + KERNEL_INSTALL := 1 + KERNEL_SIZE := 4048k + BLOCKSIZE := 128k + PAGESIZE := 2048 + BOARD_NAME := ap-dk04.1-c1 +endef +TARGET_DEVICES += qcom_ap-dk04.1-c1 + +define Device/p2w_r619ac + $(call Device/FitzImage) + $(call Device/UbiFit) + DEVICE_VENDOR := P&W + DEVICE_MODEL := R619AC + SOC := qcom-ipq4019 + DEVICE_DTS_CONFIG := config@10 + BLOCKSIZE := 128k + PAGESIZE := 2048 + IMAGES += nand-factory.bin + IMAGE/nand-factory.bin := append-ubi | qsdk-ipq-factory-nand + DEVICE_PACKAGES := ipq-wifi-p2w_r619ac +endef +TARGET_DEVICES += p2w_r619ac + +define Device/p2w_r619ac-128m + $(call Device/FitzImage) + $(call Device/UbiFit) + DEVICE_VENDOR := P&W + DEVICE_MODEL := R619AC + DEVICE_VARIANT := 128M + SOC := qcom-ipq4019 + DEVICE_DTS_CONFIG := config@10 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := ipq-wifi-p2w_r619ac +endef +TARGET_DEVICES += p2w_r619ac-128m + +define Device/qxwlan_e2600ac-c1 + $(call Device/FitImage) + DEVICE_VENDOR := Qxwlan + DEVICE_MODEL := E2600AC + DEVICE_VARIANT := C1 + BOARD_NAME := e2600ac-c1 + SOC := qcom-ipq4019 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 31232k + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + DEVICE_PACKAGES := ipq-wifi-qxwlan_e2600ac +endef +TARGET_DEVICES += qxwlan_e2600ac-c1 + +define Device/qxwlan_e2600ac-c2 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := Qxwlan + DEVICE_MODEL := E2600AC + DEVICE_VARIANT := C2 + SOC := qcom-ipq4019 + KERNEL_INSTALL := 1 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := ipq-wifi-qxwlan_e2600ac +endef +TARGET_DEVICES += qxwlan_e2600ac-c2 + +define Device/unielec_u4019-32m + $(call Device/FitImage) + DEVICE_VENDOR := Unielec + DEVICE_MODEL := U4019 + DEVICE_VARIANT := 32M + BOARD_NAME := u4019-32m + SOC := qcom-ipq4019 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 31232k + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata +endef +TARGET_DEVICES += unielec_u4019-32m + +define Device/zyxel_nbg6617 + $(call Device/FitImageLzma) + DEVICE_VENDOR := ZyXEL + DEVICE_MODEL := NBG6617 + SOC := qcom-ipq4018 + KERNEL_SIZE := 4096k + ROOTFS_SIZE := 24960k + RAS_BOARD := NBG6617 + RAS_ROOTFS_SIZE := 19840k + RAS_VERSION := "$(VERSION_DIST) $(REVISION)" + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + IMAGES += factory.bin +# The ZyXEL firmware allows flashing thru the web-gui only when the rootfs is +# at least as large as the one of the initial firmware image (not the current +# one on the device). This only applies to the Web-UI, the bootlaoder ignores +# this minimum-size. However, the larger image can be flashed both ways. + IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 64k | check-size $$$$(ROOTFS_SIZE) | zyxel-ras-image separate-kernel + IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | check-size $$$$(ROOTFS_SIZE) | sysupgrade-tar rootfs=$$$$@ | append-metadata + DEVICE_PACKAGES := uboot-envtools kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += zyxel_nbg6617 + +define Device/zyxel_wre6606 + $(call Device/FitImage) + DEVICE_VENDOR := ZyXEL + DEVICE_MODEL := WRE6606 + DEVICE_DTS_CONFIG := config@4 + SOC := qcom-ipq4018 + IMAGE_SIZE := 13184k + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata | check-size + DEVICE_PACKAGES := -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers +endef +TARGET_DEVICES += zyxel_wre6606 + +$(eval $(call BuildImage)) diff --git a/root/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch b/root/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch new file mode 100644 index 00000000..ade7a675 --- /dev/null +++ b/root/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch @@ -0,0 +1,65 @@ +From a10fab12a927e60b7141a602e740d70cb4d09e4a Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 9 Mar 2017 11:03:18 +0100 +Subject: [PATCH] arm: boot: add dts files + +Signed-off-by: John Crispin +--- + arch/arm/boot/dts/Makefile | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -837,11 +837,52 @@ dtb-$(CONFIG_ARCH_QCOM) += \ + qcom-apq8074-dragonboard.dtb \ + qcom-apq8084-ifc6540.dtb \ + qcom-apq8084-mtp.dtb \ ++ qcom-ipq4018-a42.dtb \ ++ qcom-ipq4018-ap120c-ac.dtb \ ++ qcom-ipq4018-dap-2610.dtb \ ++ qcom-ipq4018-cs-w3-wd1200g-eup.dtb \ ++ qcom-ipq4018-ea6350v3.dtb \ ++ qcom-ipq4018-eap1300.dtb \ ++ qcom-ipq4018-emd1.dtb \ ++ qcom-ipq4018-emr3500.dtb \ ++ qcom-ipq4018-ens620ext.dtb \ ++ qcom-ipq4018-ex6100v2.dtb \ ++ qcom-ipq4018-ex6150v2.dtb \ ++ qcom-ipq4018-fritzbox-4040.dtb \ ++ qcom-ipq4018-jalapeno.dtb \ ++ qcom-ipq4018-meshpoint-one.dtb \ ++ qcom-ipq4018-nbg6617.dtb \ ++ qcom-ipq4018-rt-ac58u.dtb \ ++ qcom-ipq4018-wre6606.dtb \ + qcom-ipq4019-ap.dk01.1-c1.dtb \ + qcom-ipq4019-ap.dk04.1-c1.dtb \ + qcom-ipq4019-ap.dk04.1-c3.dtb \ + qcom-ipq4019-ap.dk07.1-c1.dtb \ + qcom-ipq4019-ap.dk07.1-c2.dtb \ ++ qcom-ipq4019-a62.dtb \ ++ qcom-ipq4019-cm520-79f.dtb \ ++ qcom-ipq4019-ea8300.dtb \ ++ qcom-ipq4019-eap2200.dtb \ ++ qcom-ipq4019-fritzbox-7530.dtb \ ++ qcom-ipq4019-fritzrepeater-1200.dtb \ ++ qcom-ipq4019-fritzrepeater-3000.dtb \ ++ qcom-ipq4019-r619ac.dtb \ ++ qcom-ipq4019-r619ac-128m.dtb \ ++ qcom-ipq4019-map-ac2200.dtb \ ++ qcom-ipq4019-e2600ac-c1.dtb \ ++ qcom-ipq4019-e2600ac-c2.dtb \ ++ qcom-ipq4019-habanero-dvk.dtb \ ++ qcom-ipq4019-rtl30vw.dtb \ ++ qcom-ipq4019-u4019-32m.dtb \ ++ qcom-ipq4019-wpj419.dtb \ ++ qcom-ipq4019-wtr-m2133hp.dtb \ ++ qcom-ipq4028-wpj428.dtb \ ++ qcom-ipq4029-ap-303.dtb \ ++ qcom-ipq4029-ap-303h.dtb \ ++ qcom-ipq4029-ap-365.dtb \ ++ qcom-ipq4029-gl-b1300.dtb \ ++ qcom-ipq4029-gl-s1300.dtb \ ++ qcom-ipq4029-mr33.dtb \ + qcom-ipq8064-ap148.dtb \ + qcom-msm8660-surf.dtb \ + qcom-msm8960-cdp.dtb \ From 0b21a298c69a6156b3a967a1a19e8a590d145363 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 20 Aug 2020 16:02:07 +0200 Subject: [PATCH 03/27] Update MPTCP --- .../linux/generic/hack-5.4/690-mptcp_trunk.patch | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch index 7457f75d..61b5df80 100644 --- a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch +++ b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch @@ -3718,7 +3718,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c seq = tp->write_seq + tp->max_window + 2; if (!seq) -@@ -2616,17 +2736,11 @@ +@@ -2616,20 +2736,14 @@ icsk->icsk_backoff = 0; tp->snd_cwnd = 2; icsk->icsk_probes_out = 0; @@ -3732,6 +3732,9 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c + + tcp_reset_vars(sk); + + if (icsk->icsk_ca_ops->release) + icsk->icsk_ca_ops->release(sk); + memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); tcp_set_ca_state(sk, TCP_CA_Open); - tp->is_sack_reneg = 0; - tcp_clear_retrans(tp); @@ -3856,15 +3859,6 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (!(val & 1)) inet_csk_enter_pingpong_mode(sk); } -@@ -3069,7 +3240,7 @@ - #ifdef CONFIG_TCP_MD5SIG - case TCP_MD5SIG: - case TCP_MD5SIG_EXT: -- if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) -+ if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN) && !sock_flag(sk, SOCK_MPTCP)) - err = tp->af_specific->md5_parse(sk, optname, optval, optlen); - else - err = -EINVAL; @@ -3128,6 +3299,32 @@ tp->notsent_lowat = val; sk->sk_write_space(sk); From 56c3d2b6211a05cdc2f4bf61e5b6c8ff607c93e8 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 20 Aug 2020 16:02:20 +0200 Subject: [PATCH 04/27] Update OpenWrt --- build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index 12cc2927..ced3bf33 100755 --- a/build.sh +++ b/build.sh @@ -70,9 +70,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "18b7d87a8f76b4cf36e943d9211bd26d79f55ec6" - _get_repo feeds/packages https://github.com/openwrt/packages "1c67444c33d85cd74d3a68d1a251626342554f03" - _get_repo feeds/luci https://github.com/openwrt/luci "b2e00f23a7862f47b8bd975207ba8242b55e6cf0" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "da986035973a8c803e6f193ae502ff65e6d551c3" + _get_repo feeds/packages https://github.com/openwrt/packages "91bf524845d4733c77c11f359b1c915e788ece14" + _get_repo feeds/luci https://github.com/openwrt/luci "b2fa7903ebfdbe9f485a94710b77320fe7897dba" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" From 78841c82321d936e4aa85264fb3562d3344d12e0 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 8 Sep 2020 20:06:28 +0200 Subject: [PATCH 05/27] Close stale issues --- .github/workflows/stale.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..71c06708 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,19 @@ +name: Mark stale issues and pull requests + +on: + schedule: + - cron: "30 1 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3.0.10 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: "This issue is stale because it has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days" + stale-pr-message: 'It has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days' + days-before-stale: 120 + days-before-close: 5 + exempt-issue-labels: 'work-in-progress,enhancement' + exempt-pr-labels: 'work-in-progress,enhancement' From edcdf37fe679ef3e401e3189bc191e4faf736705 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 8 Sep 2020 20:16:26 +0200 Subject: [PATCH 06/27] Change stale actions cron --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 71c06708..8bd7b5c7 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -2,7 +2,7 @@ name: Mark stale issues and pull requests on: schedule: - - cron: "30 1 * * *" + - cron: "0 19 * * *" jobs: stale: From ccc51fcd408afb1ea1b335875ae5652a31fce71c Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 8 Sep 2020 21:11:19 +0200 Subject: [PATCH 07/27] Execute stale action on push --- .github/workflows/stale.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 8bd7b5c7..0df84802 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,6 +1,7 @@ name: Mark stale issues and pull requests on: + push: schedule: - cron: "0 19 * * *" From c634dbadfe8065fb58ccf378388b98a979716f73 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 10 Sep 2020 21:08:02 +0200 Subject: [PATCH 08/27] Update MPTCP patch --- .../generic/hack-5.4/690-mptcp_trunk.patch | 899 +++++++++--------- 1 file changed, 450 insertions(+), 449 deletions(-) diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch index 61b5df80..dfb008e1 100644 --- a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch +++ b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch @@ -1,7 +1,7 @@ -diff -aurN linux-5.4/Documentation/admin-guide/kernel-parameters.txt mptcp-mptcp_trunk/Documentation/admin-guide/kernel-parameters.txt ---- linux-5.4/Documentation/admin-guide/kernel-parameters.txt 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/Documentation/admin-guide/kernel-parameters.txt 2020-07-14 19:34:59.000000000 +0200 -@@ -2724,6 +2724,10 @@ +diff -aurN linux-5.4.64/Documentation/admin-guide/kernel-parameters.txt linux-5.4.64.mptcp/Documentation/admin-guide/kernel-parameters.txt +--- linux-5.4.64/Documentation/admin-guide/kernel-parameters.txt 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/Documentation/admin-guide/kernel-parameters.txt 2020-09-10 19:25:10.375223065 +0200 +@@ -2734,6 +2734,10 @@ allocations which rules out almost all kernel allocations. Use with caution! @@ -12,9 +12,9 @@ diff -aurN linux-5.4/Documentation/admin-guide/kernel-parameters.txt mptcp-mptcp MTD_Partition= [MTD] Format: ,,, -diff -aurN linux-5.4/Documentation/networking/ip-sysctl.txt mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt ---- linux-5.4/Documentation/networking/ip-sysctl.txt 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/Documentation/networking/ip-sysctl.txt 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/Documentation/networking/ip-sysctl.txt linux-5.4.64.mptcp/Documentation/networking/ip-sysctl.txt +--- linux-5.4.64/Documentation/networking/ip-sysctl.txt 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/Documentation/networking/ip-sysctl.txt 2020-09-10 19:25:10.375223065 +0200 @@ -818,6 +818,18 @@ Default: 0 (disabled) @@ -34,10 +34,10 @@ diff -aurN linux-5.4/Documentation/networking/ip-sysctl.txt mptcp-mptcp_trunk/Do UDP variables: udp_l3mdev_accept - BOOLEAN -diff -aurN linux-5.4/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c ---- linux-5.4/drivers/infiniband/hw/cxgb4/cm.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/drivers/infiniband/hw/cxgb4/cm.c 2020-07-14 19:34:59.000000000 +0200 -@@ -3946,7 +3946,7 @@ +diff -aurN linux-5.4.64/drivers/infiniband/hw/cxgb4/cm.c linux-5.4.64.mptcp/drivers/infiniband/hw/cxgb4/cm.c +--- linux-5.4.64/drivers/infiniband/hw/cxgb4/cm.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/drivers/infiniband/hw/cxgb4/cm.c 2020-09-10 19:25:10.439222000 +0200 +@@ -3949,7 +3949,7 @@ */ memset(&tmp_opt, 0, sizeof(tmp_opt)); tcp_clear_options(&tmp_opt); @@ -46,9 +46,9 @@ diff -aurN linux-5.4/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_trunk/drivers/ req = __skb_push(skb, sizeof(*req)); memset(req, 0, sizeof(*req)); -diff -aurN linux-5.4/include/linux/skbuff.h mptcp-mptcp_trunk/include/linux/skbuff.h ---- linux-5.4/include/linux/skbuff.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/linux/skbuff.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/linux/skbuff.h linux-5.4.64.mptcp/include/linux/skbuff.h +--- linux-5.4.64/include/linux/skbuff.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/linux/skbuff.h 2020-09-10 19:25:10.439222000 +0200 @@ -717,7 +717,7 @@ * want to keep them across layers you have to do a skb_clone() * first. This is owned by whoever has the skb queued ATM. @@ -58,9 +58,9 @@ diff -aurN linux-5.4/include/linux/skbuff.h mptcp-mptcp_trunk/include/linux/skbu union { struct { -diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h ---- linux-5.4/include/linux/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/linux/tcp.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/linux/tcp.h linux-5.4.64.mptcp/include/linux/tcp.h +--- linux-5.4.64/include/linux/tcp.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/linux/tcp.h 2020-09-10 19:25:10.499221003 +0200 @@ -54,7 +54,7 @@ /* TCP Fast Open */ #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ @@ -146,7 +146,7 @@ diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h struct tcp_sock { /* inet_connection_sock has to be the first member of tcp_sock */ struct inet_connection_sock inet_conn; -@@ -395,6 +450,44 @@ +@@ -397,6 +452,44 @@ */ struct request_sock __rcu *fastopen_rsk; u32 *saved_syn; @@ -191,7 +191,7 @@ diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h }; enum tsq_enum { -@@ -406,6 +499,8 @@ +@@ -408,6 +501,8 @@ TCP_MTU_REDUCED_DEFERRED, /* tcp_v{4|6}_err() could not call * tcp_v{4|6}_mtu_reduced() */ @@ -200,7 +200,7 @@ diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h }; enum tsq_flags { -@@ -415,6 +510,8 @@ +@@ -417,6 +512,8 @@ TCPF_WRITE_TIMER_DEFERRED = (1UL << TCP_WRITE_TIMER_DEFERRED), TCPF_DELACK_TIMER_DEFERRED = (1UL << TCP_DELACK_TIMER_DEFERRED), TCPF_MTU_REDUCED_DEFERRED = (1UL << TCP_MTU_REDUCED_DEFERRED), @@ -209,7 +209,7 @@ diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h }; static inline struct tcp_sock *tcp_sk(const struct sock *sk) -@@ -438,6 +535,7 @@ +@@ -440,6 +537,7 @@ #ifdef CONFIG_TCP_MD5SIG struct tcp_md5sig_key *tw_md5_key; #endif @@ -217,9 +217,9 @@ diff -aurN linux-5.4/include/linux/tcp.h mptcp-mptcp_trunk/include/linux/tcp.h }; static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) -diff -aurN linux-5.4/include/net/inet_common.h mptcp-mptcp_trunk/include/net/inet_common.h ---- linux-5.4/include/net/inet_common.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_common.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/net/inet_common.h linux-5.4.64.mptcp/include/net/inet_common.h +--- linux-5.4.64/include/net/inet_common.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/net/inet_common.h 2020-09-10 19:25:10.499221003 +0200 @@ -2,6 +2,7 @@ #ifndef _INET_COMMON_H #define _INET_COMMON_H @@ -237,9 +237,9 @@ diff -aurN linux-5.4/include/net/inet_common.h mptcp-mptcp_trunk/include/net/ine int inet_release(struct socket *sock); int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags); -diff -aurN linux-5.4/include/net/inet_connection_sock.h mptcp-mptcp_trunk/include/net/inet_connection_sock.h ---- linux-5.4/include/net/inet_connection_sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_connection_sock.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/net/inet_connection_sock.h linux-5.4.64.mptcp/include/net/inet_connection_sock.h +--- linux-5.4.64/include/net/inet_connection_sock.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/net/inet_connection_sock.h 2020-09-10 19:25:10.499221003 +0200 @@ -25,6 +25,7 @@ struct inet_bind_bucket; @@ -248,9 +248,9 @@ diff -aurN linux-5.4/include/net/inet_connection_sock.h mptcp-mptcp_trunk/includ /* * Pointers to address related TCP functions -diff -aurN linux-5.4/include/net/inet_sock.h mptcp-mptcp_trunk/include/net/inet_sock.h ---- linux-5.4/include/net/inet_sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/inet_sock.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/net/inet_sock.h linux-5.4.64.mptcp/include/net/inet_sock.h +--- linux-5.4.64/include/net/inet_sock.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/net/inet_sock.h 2020-09-10 19:25:10.499221003 +0200 @@ -79,7 +79,7 @@ #define ireq_state req.__req_common.skc_state #define ireq_family req.__req_common.skc_family @@ -269,9 +269,9 @@ diff -aurN linux-5.4/include/net/inet_sock.h mptcp-mptcp_trunk/include/net/inet_ smc_ok : 1; u32 ir_mark; union { -diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h ---- linux-5.4/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/net/mptcp.h linux-5.4.64.mptcp/include/net/mptcp.h +--- linux-5.4.64/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/include/net/mptcp.h 2020-09-10 19:25:10.499221003 +0200 @@ -0,0 +1,1571 @@ +/* + * MPTCP implementation @@ -1844,9 +1844,9 @@ diff -aurN linux-5.4/include/net/mptcp.h mptcp-mptcp_trunk/include/net/mptcp.h +#endif /* CONFIG_MPTCP */ + +#endif /* _MPTCP_H */ -diff -aurN linux-5.4/include/net/mptcp_v4.h mptcp-mptcp_trunk/include/net/mptcp_v4.h ---- linux-5.4/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp_v4.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/net/mptcp_v4.h linux-5.4.64.mptcp/include/net/mptcp_v4.h +--- linux-5.4.64/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/include/net/mptcp_v4.h 2020-09-10 19:25:10.499221003 +0200 @@ -0,0 +1,76 @@ +/* + * MPTCP implementation @@ -1924,9 +1924,9 @@ diff -aurN linux-5.4/include/net/mptcp_v4.h mptcp-mptcp_trunk/include/net/mptcp_ +#endif /* CONFIG_MPTCP */ + +#endif /* MPTCP_V4_H_ */ -diff -aurN linux-5.4/include/net/mptcp_v6.h mptcp-mptcp_trunk/include/net/mptcp_v6.h ---- linux-5.4/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/mptcp_v6.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/net/mptcp_v6.h linux-5.4.64.mptcp/include/net/mptcp_v6.h +--- linux-5.4.64/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/include/net/mptcp_v6.h 2020-09-10 19:25:10.499221003 +0200 @@ -0,0 +1,77 @@ +/* + * MPTCP implementation @@ -2005,9 +2005,9 @@ diff -aurN linux-5.4/include/net/mptcp_v6.h mptcp-mptcp_trunk/include/net/mptcp_ +#endif /* CONFIG_MPTCP */ + +#endif /* _MPTCP_V6_H */ -diff -aurN linux-5.4/include/net/net_namespace.h mptcp-mptcp_trunk/include/net/net_namespace.h ---- linux-5.4/include/net/net_namespace.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/net_namespace.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/net/net_namespace.h linux-5.4.64.mptcp/include/net/net_namespace.h +--- linux-5.4.64/include/net/net_namespace.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/net/net_namespace.h 2020-09-10 19:25:10.499221003 +0200 @@ -19,6 +19,7 @@ #include #include @@ -2026,9 +2026,9 @@ diff -aurN linux-5.4/include/net/net_namespace.h mptcp-mptcp_trunk/include/net/n #if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN) struct netns_ieee802154_lowpan ieee802154_lowpan; #endif -diff -aurN linux-5.4/include/net/netns/mptcp.h mptcp-mptcp_trunk/include/net/netns/mptcp.h ---- linux-5.4/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/netns/mptcp.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/net/netns/mptcp.h linux-5.4.64.mptcp/include/net/netns/mptcp.h +--- linux-5.4.64/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/include/net/netns/mptcp.h 2020-09-10 19:25:10.499221003 +0200 @@ -0,0 +1,52 @@ +/* + * MPTCP implementation - MPTCP namespace @@ -2082,9 +2082,9 @@ diff -aurN linux-5.4/include/net/netns/mptcp.h mptcp-mptcp_trunk/include/net/net +}; + +#endif /* __NETNS_MPTCP_H__ */ -diff -aurN linux-5.4/include/net/snmp.h mptcp-mptcp_trunk/include/net/snmp.h ---- linux-5.4/include/net/snmp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/snmp.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/net/snmp.h linux-5.4.64.mptcp/include/net/snmp.h +--- linux-5.4.64/include/net/snmp.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/net/snmp.h 2020-09-10 19:25:10.499221003 +0200 @@ -86,7 +86,6 @@ atomic_long_t mibs[ICMP6MSG_MIB_MAX]; }; @@ -2093,10 +2093,10 @@ diff -aurN linux-5.4/include/net/snmp.h mptcp-mptcp_trunk/include/net/snmp.h /* TCP */ #define TCP_MIB_MAX __TCP_MIB_MAX struct tcp_mib { -diff -aurN linux-5.4/include/net/sock.h mptcp-mptcp_trunk/include/net/sock.h ---- linux-5.4/include/net/sock.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/sock.h 2020-07-14 19:34:59.000000000 +0200 -@@ -814,6 +814,7 @@ +diff -aurN linux-5.4.64/include/net/sock.h linux-5.4.64.mptcp/include/net/sock.h +--- linux-5.4.64/include/net/sock.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/net/sock.h 2020-09-10 19:25:10.499221003 +0200 +@@ -819,6 +819,7 @@ SOCK_TXTIME, SOCK_XDP, /* XDP is attached */ SOCK_TSTAMP_NEW, /* Indicates 64 bit timestamps always */ @@ -2104,7 +2104,7 @@ diff -aurN linux-5.4/include/net/sock.h mptcp-mptcp_trunk/include/net/sock.h }; #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) -@@ -1122,6 +1123,7 @@ +@@ -1131,6 +1132,7 @@ void (*unhash)(struct sock *sk); void (*rehash)(struct sock *sk); int (*get_port)(struct sock *sk, unsigned short snum); @@ -2112,9 +2112,9 @@ diff -aurN linux-5.4/include/net/sock.h mptcp-mptcp_trunk/include/net/sock.h /* Keeping track of sockets in use */ #ifdef CONFIG_PROC_FS -diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h ---- linux-5.4/include/net/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/tcp.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/net/tcp.h linux-5.4.64.mptcp/include/net/tcp.h +--- linux-5.4.64/include/net/tcp.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/net/tcp.h 2020-09-10 19:25:10.499221003 +0200 @@ -182,6 +182,7 @@ #define TCPOPT_SACK 5 /* SACK Block */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ @@ -2288,7 +2288,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h struct dst_entry *dst, u32 tsoff); int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th, u32 cookie); -@@ -536,7 +658,8 @@ +@@ -547,7 +669,8 @@ u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th, u16 *mssp); @@ -2298,7 +2298,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h u64 cookie_init_timestamp(struct request_sock *req); bool cookie_timestamp_decode(const struct net *net, struct tcp_options_received *opt); -@@ -550,7 +673,8 @@ +@@ -561,7 +684,8 @@ u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph, const struct tcphdr *th, u16 *mssp); @@ -2308,7 +2308,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h #endif /* tcp_output.c */ -@@ -586,10 +710,16 @@ +@@ -597,10 +721,16 @@ void tcp_skb_collapse_tstamp(struct sk_buff *skb, const struct sk_buff *next_skb); @@ -2325,7 +2325,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb); void tcp_fin(struct sock *sk); -@@ -633,7 +763,7 @@ +@@ -644,7 +774,7 @@ } /* tcp.c */ @@ -2334,7 +2334,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h /* Read 'sendfile()'-style from a TCP socket */ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, -@@ -817,6 +947,12 @@ +@@ -828,6 +958,12 @@ u16 tcp_gso_size; }; }; @@ -2347,7 +2347,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h __u8 tcp_flags; /* TCP header flags. (tcp[13]) */ __u8 sacked; /* State flags for SACK. */ -@@ -835,6 +971,14 @@ +@@ -846,6 +982,14 @@ has_rxtstamp:1, /* SKB has a RX timestamp */ unused:5; __u32 ack_seq; /* Sequence number ACK'd */ @@ -2362,7 +2362,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h union { struct { /* There is space for up to 24 bytes */ -@@ -1076,6 +1220,8 @@ +@@ -1087,6 +1231,8 @@ int tcp_set_allowed_congestion_control(char *allowed); int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, bool reinit, bool cap_net_admin); @@ -2371,7 +2371,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h u32 tcp_slow_start(struct tcp_sock *tp, u32 acked); void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked); -@@ -1377,6 +1523,19 @@ +@@ -1388,6 +1534,19 @@ space - (space>>tcp_adv_win_scale); } @@ -2391,7 +2391,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h /* Note: caller must be prepared to deal with negative returns */ static inline int tcp_space(const struct sock *sk) { -@@ -1949,6 +2108,30 @@ +@@ -1975,6 +2134,30 @@ #endif }; @@ -2422,7 +2422,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h struct tcp_request_sock_ops { u16 mss_clamp; #ifdef CONFIG_TCP_MD5SIG -@@ -1959,12 +2142,13 @@ +@@ -1985,12 +2168,13 @@ const struct sock *sk, const struct sk_buff *skb); #endif @@ -2441,7 +2441,7 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h #endif struct dst_entry *(*route_req)(const struct sock *sk, struct flowi *fl, const struct request_sock *req); -@@ -1978,15 +2162,17 @@ +@@ -2004,15 +2188,17 @@ #ifdef CONFIG_SYN_COOKIES static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, @@ -2460,9 +2460,9 @@ diff -aurN linux-5.4/include/net/tcp.h mptcp-mptcp_trunk/include/net/tcp.h const struct sock *sk, struct sk_buff *skb, __u16 *mss) { -diff -aurN linux-5.4/include/net/tcp_states.h mptcp-mptcp_trunk/include/net/tcp_states.h ---- linux-5.4/include/net/tcp_states.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/tcp_states.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/net/tcp_states.h linux-5.4.64.mptcp/include/net/tcp_states.h +--- linux-5.4.64/include/net/tcp_states.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/net/tcp_states.h 2020-09-10 19:25:10.499221003 +0200 @@ -22,6 +22,7 @@ TCP_LISTEN, TCP_CLOSING, /* Now a valid state */ @@ -2479,9 +2479,9 @@ diff -aurN linux-5.4/include/net/tcp_states.h mptcp-mptcp_trunk/include/net/tcp_ }; #endif /* _LINUX_TCP_STATES_H */ -diff -aurN linux-5.4/include/net/transp_v6.h mptcp-mptcp_trunk/include/net/transp_v6.h ---- linux-5.4/include/net/transp_v6.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/net/transp_v6.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/net/transp_v6.h linux-5.4.64.mptcp/include/net/transp_v6.h +--- linux-5.4.64/include/net/transp_v6.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/net/transp_v6.h 2020-09-10 19:25:10.499221003 +0200 @@ -58,6 +58,8 @@ /* address family specific functions */ @@ -2491,9 +2491,9 @@ diff -aurN linux-5.4/include/net/transp_v6.h mptcp-mptcp_trunk/include/net/trans void inet6_destroy_sock(struct sock *sk); -diff -aurN linux-5.4/include/trace/events/tcp.h mptcp-mptcp_trunk/include/trace/events/tcp.h ---- linux-5.4/include/trace/events/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/trace/events/tcp.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/trace/events/tcp.h linux-5.4.64.mptcp/include/trace/events/tcp.h +--- linux-5.4.64/include/trace/events/tcp.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/trace/events/tcp.h 2020-09-10 19:25:10.499221003 +0200 @@ -10,6 +10,7 @@ #include #include @@ -2542,9 +2542,9 @@ diff -aurN linux-5.4/include/trace/events/tcp.h mptcp-mptcp_trunk/include/trace/ ); #endif /* _TRACE_TCP_H */ -diff -aurN linux-5.4/include/uapi/linux/bpf.h mptcp-mptcp_trunk/include/uapi/linux/bpf.h ---- linux-5.4/include/uapi/linux/bpf.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/bpf.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/uapi/linux/bpf.h linux-5.4.64.mptcp/include/uapi/linux/bpf.h +--- linux-5.4.64/include/uapi/linux/bpf.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/uapi/linux/bpf.h 2020-09-10 19:25:10.499221003 +0200 @@ -3438,6 +3438,7 @@ BPF_TCP_LISTEN, BPF_TCP_CLOSING, /* Now a valid state */ @@ -2553,9 +2553,9 @@ diff -aurN linux-5.4/include/uapi/linux/bpf.h mptcp-mptcp_trunk/include/uapi/lin BPF_TCP_MAX_STATES /* Leave at the end! */ }; -diff -aurN linux-5.4/include/uapi/linux/if.h mptcp-mptcp_trunk/include/uapi/linux/if.h ---- linux-5.4/include/uapi/linux/if.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/if.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/uapi/linux/if.h linux-5.4.64.mptcp/include/uapi/linux/if.h +--- linux-5.4.64/include/uapi/linux/if.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/uapi/linux/if.h 2020-09-10 19:25:10.499221003 +0200 @@ -132,6 +132,9 @@ #define IFF_ECHO IFF_ECHO #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ @@ -2566,9 +2566,9 @@ diff -aurN linux-5.4/include/uapi/linux/if.h mptcp-mptcp_trunk/include/uapi/linu #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) -diff -aurN linux-5.4/include/uapi/linux/in.h mptcp-mptcp_trunk/include/uapi/linux/in.h ---- linux-5.4/include/uapi/linux/in.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/in.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/uapi/linux/in.h linux-5.4.64.mptcp/include/uapi/linux/in.h +--- linux-5.4.64/include/uapi/linux/in.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/uapi/linux/in.h 2020-09-10 19:25:10.499221003 +0200 @@ -76,6 +76,8 @@ #define IPPROTO_MPLS IPPROTO_MPLS IPPROTO_RAW = 255, /* Raw IP packets */ @@ -2578,9 +2578,9 @@ diff -aurN linux-5.4/include/uapi/linux/in.h mptcp-mptcp_trunk/include/uapi/linu IPPROTO_MAX }; #endif -diff -aurN linux-5.4/include/uapi/linux/mptcp.h mptcp-mptcp_trunk/include/uapi/linux/mptcp.h ---- linux-5.4/include/uapi/linux/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/mptcp.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/uapi/linux/mptcp.h linux-5.4.64.mptcp/include/uapi/linux/mptcp.h +--- linux-5.4.64/include/uapi/linux/mptcp.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/include/uapi/linux/mptcp.h 2020-09-10 19:25:10.499221003 +0200 @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* @@ -2731,9 +2731,9 @@ diff -aurN linux-5.4/include/uapi/linux/mptcp.h mptcp-mptcp_trunk/include/uapi/l +}; + +#endif /* _LINUX_MPTCP_H */ -diff -aurN linux-5.4/include/uapi/linux/tcp.h mptcp-mptcp_trunk/include/uapi/linux/tcp.h ---- linux-5.4/include/uapi/linux/tcp.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/include/uapi/linux/tcp.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/include/uapi/linux/tcp.h linux-5.4.64.mptcp/include/uapi/linux/tcp.h +--- linux-5.4.64/include/uapi/linux/tcp.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/include/uapi/linux/tcp.h 2020-09-10 19:25:10.499221003 +0200 @@ -18,9 +18,15 @@ #ifndef _UAPI_LINUX_TCP_H #define _UAPI_LINUX_TCP_H @@ -2819,10 +2819,10 @@ diff -aurN linux-5.4/include/uapi/linux/tcp.h mptcp-mptcp_trunk/include/uapi/lin /* for TCP_MD5SIG socket option */ #define TCP_MD5SIG_MAXKEYLEN 80 -diff -aurN linux-5.4/net/core/dev.c mptcp-mptcp_trunk/net/core/dev.c ---- linux-5.4/net/core/dev.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/dev.c 2020-07-14 19:34:59.000000000 +0200 -@@ -7855,7 +7855,7 @@ +diff -aurN linux-5.4.64/net/core/dev.c linux-5.4.64.mptcp/net/core/dev.c +--- linux-5.4.64/net/core/dev.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/core/dev.c 2020-09-10 19:25:10.503220935 +0200 +@@ -7851,7 +7851,7 @@ dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP | IFF_DYNAMIC | IFF_MULTICAST | IFF_PORTSEL | @@ -2831,18 +2831,18 @@ diff -aurN linux-5.4/net/core/dev.c mptcp-mptcp_trunk/net/core/dev.c (dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC | IFF_ALLMULTI)); -diff -aurN linux-5.4/net/core/net-traces.c mptcp-mptcp_trunk/net/core/net-traces.c ---- linux-5.4/net/core/net-traces.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/net-traces.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/core/net-traces.c linux-5.4.64.mptcp/net/core/net-traces.c +--- linux-5.4.64/net/core/net-traces.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/core/net-traces.c 2020-09-10 19:25:10.503220935 +0200 @@ -60,3 +60,5 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(napi_poll); EXPORT_TRACEPOINT_SYMBOL_GPL(tcp_send_reset); + +EXPORT_TRACEPOINT_SYMBOL_GPL(mptcp_retransmit); -diff -aurN linux-5.4/net/core/skbuff.c mptcp-mptcp_trunk/net/core/skbuff.c ---- linux-5.4/net/core/skbuff.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/skbuff.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/core/skbuff.c linux-5.4.64.mptcp/net/core/skbuff.c +--- linux-5.4.64/net/core/skbuff.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/core/skbuff.c 2020-09-10 19:25:10.503220935 +0200 @@ -573,7 +573,7 @@ skb_drop_list(&skb_shinfo(skb)->frag_list); } @@ -2852,9 +2852,9 @@ diff -aurN linux-5.4/net/core/skbuff.c mptcp-mptcp_trunk/net/core/skbuff.c { struct sk_buff *list; -diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c ---- linux-5.4/net/core/sock.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/core/sock.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/core/sock.c linux-5.4.64.mptcp/net/core/sock.c +--- linux-5.4.64/net/core/sock.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/core/sock.c 2020-09-10 19:26:53.689504155 +0200 @@ -135,6 +135,11 @@ #include @@ -2906,15 +2906,18 @@ diff -aurN linux-5.4/net/core/sock.c mptcp-mptcp_trunk/net/core/sock.c } else sk = kmalloc(prot->obj_size, priority); -@@ -1832,4 +1858,5 @@ +@@ -1832,7 +1858,7 @@ + newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; atomic_set(&newsk->sk_zckey, 0); - sock_reset_flag(newsk, SOCK_DONE); +- sock_reset_flag(newsk, SOCK_DONE); + sock_reset_flag(newsk, SOCK_MPTCP); -diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c ---- linux-5.4/net/ipv4/af_inet.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/af_inet.c 2020-07-14 19:34:59.000000000 +0200 + /* sk->sk_memcg will be populated at accept() time */ + newsk->sk_memcg = NULL; +diff -aurN linux-5.4.64/net/ipv4/af_inet.c linux-5.4.64.mptcp/net/ipv4/af_inet.c +--- linux-5.4.64/net/ipv4/af_inet.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/af_inet.c 2020-09-10 19:25:10.503220935 +0200 @@ -100,6 +100,7 @@ #include #include @@ -2987,9 +2990,9 @@ diff -aurN linux-5.4/net/ipv4/af_inet.c mptcp-mptcp_trunk/net/ipv4/af_inet.c /* Setup TCP slab cache for open requests. */ tcp_init(); -diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c ---- linux-5.4/net/ipv4/inet_connection_sock.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/inet_connection_sock.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv4/inet_connection_sock.c linux-5.4.64.mptcp/net/ipv4/inet_connection_sock.c +--- linux-5.4.64/net/ipv4/inet_connection_sock.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/inet_connection_sock.c 2020-09-10 19:25:10.503220935 +0200 @@ -19,6 +19,7 @@ #include #include @@ -2998,7 +3001,7 @@ diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/ #include #include #include -@@ -693,7 +694,10 @@ +@@ -727,7 +728,10 @@ int max_retries, thresh; u8 defer_accept; @@ -3010,7 +3013,7 @@ diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/ goto drop; max_retries = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_synack_retries; -@@ -782,7 +786,9 @@ +@@ -816,7 +820,9 @@ const struct request_sock *req, const gfp_t priority) { @@ -3021,7 +3024,7 @@ diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/ if (newsk) { struct inet_connection_sock *newicsk = inet_csk(newsk); -@@ -981,7 +987,14 @@ +@@ -1015,7 +1021,14 @@ */ while ((req = reqsk_queue_remove(queue, sk)) != NULL) { struct sock *child = req->sk; @@ -3036,7 +3039,7 @@ diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/ local_bh_disable(); bh_lock_sock(child); WARN_ON(sock_owned_by_user(child)); -@@ -991,6 +1004,10 @@ +@@ -1025,6 +1038,10 @@ reqsk_put(req); bh_unlock_sock(child); local_bh_enable(); @@ -3047,9 +3050,9 @@ diff -aurN linux-5.4/net/ipv4/inet_connection_sock.c mptcp-mptcp_trunk/net/ipv4/ sock_put(child); cond_resched(); -diff -aurN linux-5.4/net/ipv4/ip_sockglue.c mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c ---- linux-5.4/net/ipv4/ip_sockglue.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/ip_sockglue.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv4/ip_sockglue.c linux-5.4.64.mptcp/net/ipv4/ip_sockglue.c +--- linux-5.4.64/net/ipv4/ip_sockglue.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/ip_sockglue.c 2020-09-10 19:25:10.503220935 +0200 @@ -44,6 +44,8 @@ #endif #include @@ -3089,10 +3092,10 @@ diff -aurN linux-5.4/net/ipv4/ip_sockglue.c mptcp-mptcp_trunk/net/ipv4/ip_sockgl } break; case IP_TTL: -diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig ---- linux-5.4/net/ipv4/Kconfig 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/Kconfig 2020-07-14 19:34:59.000000000 +0200 -@@ -654,6 +654,51 @@ +diff -aurN linux-5.4.64/net/ipv4/Kconfig linux-5.4.64.mptcp/net/ipv4/Kconfig +--- linux-5.4.64/net/ipv4/Kconfig 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/Kconfig 2020-09-10 19:25:10.503220935 +0200 +@@ -655,6 +655,51 @@ bufferbloat, policers, or AQM schemes that do not provide a delay signal. It requires the fq ("Fair Queue") pacing packet scheduler. @@ -3144,7 +3147,7 @@ diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig choice prompt "Default TCP congestion control" default DEFAULT_CUBIC -@@ -691,6 +736,21 @@ +@@ -692,6 +737,21 @@ config DEFAULT_BBR bool "BBR" if TCP_CONG_BBR=y @@ -3166,7 +3169,7 @@ diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig config DEFAULT_RENO bool "Reno" endchoice -@@ -711,6 +771,10 @@ +@@ -712,6 +772,10 @@ default "vegas" if DEFAULT_VEGAS default "westwood" if DEFAULT_WESTWOOD default "veno" if DEFAULT_VENO @@ -3177,9 +3180,9 @@ diff -aurN linux-5.4/net/ipv4/Kconfig mptcp-mptcp_trunk/net/ipv4/Kconfig default "reno" if DEFAULT_RENO default "dctcp" if DEFAULT_DCTCP default "cdg" if DEFAULT_CDG -diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies.c ---- linux-5.4/net/ipv4/syncookies.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/syncookies.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv4/syncookies.c linux-5.4.64.mptcp/net/ipv4/syncookies.c +--- linux-5.4.64/net/ipv4/syncookies.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/syncookies.c 2020-09-10 19:25:10.503220935 +0200 @@ -12,6 +12,8 @@ #include #include @@ -3305,9 +3308,9 @@ diff -aurN linux-5.4/net/ipv4/syncookies.c mptcp-mptcp_trunk/net/ipv4/syncookies /* ip_queue_xmit() depends on our flow being setup * Normal sockets get it right from inet_csk_route_child_sock() */ -diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c ---- linux-5.4/net/ipv4/tcp.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv4/tcp.c linux-5.4.64.mptcp/net/ipv4/tcp.c +--- linux-5.4.64/net/ipv4/tcp.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/tcp.c 2020-09-10 19:44:12.204220735 +0200 @@ -270,6 +270,7 @@ #include @@ -3352,7 +3355,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c sk_sockets_allocated_inc(sk); sk->sk_route_forced_caps = NETIF_F_GSO; } -@@ -777,6 +800,7 @@ +@@ -785,6 +808,7 @@ int ret; sock_rps_record_flow(sk); @@ -3360,7 +3363,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c /* * We can't seek on a socket input */ -@@ -787,6 +811,16 @@ +@@ -795,6 +819,16 @@ lock_sock(sk); @@ -3377,7 +3380,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK); while (tss.len) { ret = __tcp_splice_read(sk, &tss); -@@ -902,8 +936,7 @@ +@@ -910,8 +944,7 @@ return NULL; } @@ -3387,7 +3390,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c { struct tcp_sock *tp = tcp_sk(sk); u32 new_size_goal, size_goal; -@@ -931,8 +964,13 @@ +@@ -939,8 +972,13 @@ { int mss_now; @@ -3403,7 +3406,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c return mss_now; } -@@ -971,12 +1009,34 @@ +@@ -979,12 +1017,34 @@ * is fully established. */ if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && @@ -3439,7 +3442,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); mss_now = tcp_send_mss(sk, &size_goal, flags); -@@ -1099,7 +1159,8 @@ +@@ -1106,7 +1166,8 @@ int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset, size_t size, int flags) { @@ -3449,7 +3452,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c return sock_no_sendpage_locked(sk, page, offset, size, flags); tcp_rate_check_app_limited(sk); /* is sending application-limited? */ -@@ -1221,12 +1282,21 @@ +@@ -1228,12 +1289,21 @@ * is fully established. */ if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && @@ -3472,7 +3475,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (unlikely(tp->repair)) { if (tp->repair_queue == TCP_RECV_QUEUE) { copied = tcp_send_rcvq(sk, msg, size); -@@ -1520,7 +1590,7 @@ +@@ -1526,7 +1596,7 @@ * calculation of whether or not we must ACK for the sake of * a window update. */ @@ -3481,7 +3484,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c { struct tcp_sock *tp = tcp_sk(sk); bool time_to_ack = false; -@@ -1563,7 +1633,7 @@ +@@ -1569,7 +1639,7 @@ /* Optimize, __tcp_select_window() is not cheap. */ if (2*rcv_window_now <= tp->window_clamp) { @@ -3490,7 +3493,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c /* Send ACK now, if this read freed lots of space * in our buffer. Certainly, new_window is new window. -@@ -1679,7 +1749,7 @@ +@@ -1685,7 +1755,7 @@ /* Clean up data we have read: This will do ACK frames. */ if (copied > 0) { tcp_recv_skb(sk, seq, &offset); @@ -3499,7 +3502,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } return copied; } -@@ -1970,6 +2040,16 @@ +@@ -1976,6 +2046,16 @@ lock_sock(sk); @@ -3516,7 +3519,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c err = -ENOTCONN; if (sk->sk_state == TCP_LISTEN) goto out; -@@ -2088,7 +2168,7 @@ +@@ -2094,7 +2174,7 @@ } } @@ -3525,7 +3528,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (copied >= target) { /* Do not sleep, just process backlog. */ -@@ -2179,7 +2259,7 @@ +@@ -2186,7 +2266,7 @@ */ /* Clean up data we have read: This will do ACK frames. */ @@ -3534,7 +3537,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c release_sock(sk); -@@ -2238,8 +2318,11 @@ +@@ -2245,8 +2325,11 @@ switch (state) { case TCP_ESTABLISHED: @@ -3547,7 +3550,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c break; case TCP_CLOSE: -@@ -2252,8 +2335,11 @@ +@@ -2259,8 +2342,11 @@ inet_put_port(sk); /* fall through */ default: @@ -3560,7 +3563,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } /* Change state AFTER socket is unhashed to avoid closed -@@ -2287,7 +2373,7 @@ +@@ -2294,7 +2380,7 @@ [TCP_NEW_SYN_RECV] = TCP_CLOSE, /* should not happen ! */ }; @@ -3569,7 +3572,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c { int next = (int)new_state[sk->sk_state]; int ns = next & TCP_STATE_MASK; -@@ -2317,7 +2403,7 @@ +@@ -2324,7 +2410,7 @@ TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) { /* Clear out any half completed packets. FIN if needed. */ if (tcp_close_state(sk)) @@ -3578,7 +3581,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } } EXPORT_SYMBOL(tcp_shutdown); -@@ -2342,6 +2428,17 @@ +@@ -2349,6 +2435,17 @@ int data_was_unread = 0; int state; @@ -3596,7 +3599,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c lock_sock(sk); sk->sk_shutdown = SHUTDOWN_MASK; -@@ -2386,7 +2483,7 @@ +@@ -2393,7 +2490,7 @@ /* Unread data was tossed, zap the connection. */ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE); tcp_set_state(sk, TCP_CLOSE); @@ -3605,7 +3608,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { /* Check zero linger _after_ checking for unread data. */ sk->sk_prot->disconnect(sk, 0); -@@ -2460,7 +2557,7 @@ +@@ -2467,7 +2564,7 @@ struct tcp_sock *tp = tcp_sk(sk); if (tp->linger2 < 0) { tcp_set_state(sk, TCP_CLOSE); @@ -3614,7 +3617,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONLINGER); } else { -@@ -2470,7 +2567,8 @@ +@@ -2477,7 +2574,8 @@ inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); } else { @@ -3624,7 +3627,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c goto out; } } -@@ -2479,7 +2577,7 @@ +@@ -2486,7 +2584,7 @@ sk_mem_reclaim(sk); if (tcp_check_oom(sk, 0)) { tcp_set_state(sk, TCP_CLOSE); @@ -3633,7 +3636,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); } else if (!check_net(sock_net(sk))) { -@@ -2511,15 +2609,6 @@ +@@ -2518,15 +2616,6 @@ } EXPORT_SYMBOL(tcp_close); @@ -3649,7 +3652,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c static void tcp_rtx_queue_purge(struct sock *sk) { struct rb_node *p = rb_first(&sk->tcp_rtx_queue); -@@ -2540,6 +2629,10 @@ +@@ -2548,6 +2637,10 @@ { struct sk_buff *skb; @@ -3660,7 +3663,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c tcp_chrono_stop(sk, TCP_CHRONO_BUSY); while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) { tcp_skb_tsorted_anchor_cleanup(skb); -@@ -2558,6 +2651,29 @@ +@@ -2566,6 +2659,35 @@ inet_csk(sk)->icsk_backoff = 0; } @@ -3676,6 +3679,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c + tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; + tp->snd_cwnd = TCP_INIT_CWND; + tp->snd_cwnd_cnt = 0; ++ tp->delivered = 0; + tp->delivered_ce = 0; + tp->is_sack_reneg = 0; + tcp_clear_retrans(tp); @@ -3683,6 +3687,11 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c + tp->bytes_acked = 0; + tp->bytes_received = 0; + tp->bytes_retrans = 0; ++ tp->total_retrans = 0; ++ tp->segs_in = 0; ++ tp->segs_out = 0; ++ tp->data_segs_in = 0; ++ tp->data_segs_out = 0; + /* There's a bubble in the pipe until at least the first ACK. */ + tp->app_limited = ~0U; +} @@ -3690,7 +3699,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c int tcp_disconnect(struct sock *sk, int flags) { struct inet_sock *inet = inet_sk(sk); -@@ -2580,7 +2696,7 @@ +@@ -2588,7 +2710,7 @@ /* The last check adjusts for discrepancy of Linux wrt. RFC * states */ @@ -3699,7 +3708,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c sk->sk_err = ECONNRESET; } else if (old_state == TCP_SYN_SENT) sk->sk_err = ECONNRESET; -@@ -2602,11 +2718,15 @@ +@@ -2610,11 +2732,15 @@ if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) inet_reset_saddr(sk); @@ -3718,7 +3727,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c seq = tp->write_seq + tp->max_window + 2; if (!seq) -@@ -2616,20 +2736,14 @@ +@@ -2624,20 +2750,14 @@ icsk->icsk_backoff = 0; tp->snd_cwnd = 2; icsk->icsk_probes_out = 0; @@ -3742,22 +3751,22 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c inet_csk_delack_init(sk); /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0 * issue in __tcp_select_window() -@@ -2636,14 +2752,10 @@ +@@ -2649,14 +2769,6 @@ sk->sk_rx_dst = NULL; tcp_saved_syn_free(tp); tp->compressed_ack = 0; - tp->segs_in = 0; - tp->segs_out = 0; +- tp->segs_in = 0; +- tp->segs_out = 0; - tp->bytes_sent = 0; - tp->bytes_acked = 0; - tp->bytes_received = 0; - tp->bytes_retrans = 0; - tp->data_segs_in = 0; - tp->data_segs_out = 0; +- tp->data_segs_in = 0; +- tp->data_segs_out = 0; tp->duplicate_sack[0].start_seq = 0; tp->duplicate_sack[0].end_seq = 0; tp->dsack_dups = 0; -@@ -2648,8 +2760,6 @@ +@@ -2665,8 +2777,6 @@ tp->sacked_out = 0; tp->tlp_high_seq = 0; tp->last_oow_ack_time = 0; @@ -3766,7 +3775,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c tp->rack.mstamp = 0; tp->rack.advanced = 0; tp->rack.reo_wnd_steps = 1; -@@ -2683,7 +2793,7 @@ +@@ -2700,7 +2810,7 @@ static inline bool tcp_can_repair_sock(const struct sock *sk) { return ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN) && @@ -3775,7 +3784,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int len) -@@ -2852,6 +2962,61 @@ +@@ -2869,6 +2979,61 @@ return tcp_fastopen_reset_cipher(net, sk, key, backup_key); } @@ -3837,7 +3846,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c default: /* fallthru */ break; -@@ -3032,6 +3197,12 @@ +@@ -3051,6 +3216,12 @@ break; case TCP_DEFER_ACCEPT: @@ -3850,7 +3859,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c /* Translate value in seconds to number of retransmits */ icsk->icsk_accept_queue.rskq_defer_accept = secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, -@@ -3059,7 +3230,7 @@ +@@ -3078,7 +3249,7 @@ (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && inet_csk_ack_scheduled(sk)) { icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; @@ -3859,7 +3868,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (!(val & 1)) inet_csk_enter_pingpong_mode(sk); } -@@ -3128,6 +3299,32 @@ +@@ -3144,6 +3315,32 @@ tp->notsent_lowat = val; sk->sk_write_space(sk); break; @@ -3892,7 +3901,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c case TCP_INQ: if (val > 1 || val < 0) err = -EINVAL; -@@ -3192,7 +3389,7 @@ +@@ -3208,7 +3405,7 @@ } /* Return information about state of tcp endpoint in API format. */ @@ -3901,7 +3910,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c { const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */ const struct inet_connection_sock *icsk = inet_csk(sk); -@@ -3229,7 +3426,8 @@ +@@ -3245,7 +3442,8 @@ return; } @@ -3911,7 +3920,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c info->tcpi_ca_state = icsk->icsk_ca_state; info->tcpi_retransmits = icsk->icsk_retransmits; -@@ -3305,7 +3503,9 @@ +@@ -3321,7 +3519,9 @@ info->tcpi_reord_seen = tp->reord_seen; info->tcpi_rcv_ooopack = tp->rcv_ooopack; info->tcpi_snd_wnd = tp->snd_wnd; @@ -3922,7 +3931,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c } EXPORT_SYMBOL_GPL(tcp_get_info); -@@ -3452,7 +3652,7 @@ +@@ -3468,7 +3668,7 @@ if (get_user(len, optlen)) return -EFAULT; @@ -3931,7 +3940,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c len = min_t(unsigned int, len, sizeof(info)); if (put_user(len, optlen)) -@@ -3649,6 +3849,87 @@ +@@ -3657,6 +3857,87 @@ } return 0; } @@ -4019,7 +4028,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c #ifdef CONFIG_MMU case TCP_ZEROCOPY_RECEIVE: { struct tcp_zerocopy_receive zc; -@@ -3851,7 +4132,9 @@ +@@ -3862,7 +4143,9 @@ if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); @@ -4029,7 +4038,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c tcp_clear_xmit_timers(sk); if (req) reqsk_fastopen_remove(sk, req, false); -@@ -3867,6 +4150,8 @@ +@@ -3878,6 +4161,8 @@ int tcp_abort(struct sock *sk, int err) { @@ -4038,7 +4047,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (!sk_fullsock(sk)) { if (sk->sk_state == TCP_NEW_SYN_RECV) { struct request_sock *req = inet_reqsk(sk); -@@ -3880,7 +4165,7 @@ +@@ -3891,7 +4176,7 @@ } /* Don't race with userspace socket closes such as tcp_close. */ @@ -4047,7 +4056,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (sk->sk_state == TCP_LISTEN) { tcp_set_state(sk, TCP_CLOSE); -@@ -3889,7 +4174,7 @@ +@@ -3900,7 +4185,7 @@ /* Don't race with BH socket closes such as inet_csk_listen_stop. */ local_bh_disable(); @@ -4056,7 +4065,7 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c if (!sock_flag(sk, SOCK_DEAD)) { sk->sk_err = err; -@@ -3897,14 +4182,14 @@ +@@ -3908,14 +4193,14 @@ smp_wmb(); sk->sk_error_report(sk); if (tcp_need_reset(sk->sk_state)) @@ -4074,9 +4083,9 @@ diff -aurN linux-5.4/net/ipv4/tcp.c mptcp-mptcp_trunk/net/ipv4/tcp.c return 0; } EXPORT_SYMBOL_GPL(tcp_abort); -diff -aurN linux-5.4/net/ipv4/tcp_cong.c mptcp-mptcp_trunk/net/ipv4/tcp_cong.c ---- linux-5.4/net/ipv4/tcp_cong.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_cong.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv4/tcp_cong.c linux-5.4.64.mptcp/net/ipv4/tcp_cong.c +--- linux-5.4.64/net/ipv4/tcp_cong.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/tcp_cong.c 2020-09-10 19:25:10.503220935 +0200 @@ -328,13 +328,19 @@ return ret; } @@ -4099,9 +4108,9 @@ diff -aurN linux-5.4/net/ipv4/tcp_cong.c mptcp-mptcp_trunk/net/ipv4/tcp_cong.c { struct inet_connection_sock *icsk = inet_csk(sk); const struct tcp_congestion_ops *ca; -diff -aurN linux-5.4/net/ipv4/tcp_diag.c mptcp-mptcp_trunk/net/ipv4/tcp_diag.c ---- linux-5.4/net/ipv4/tcp_diag.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_diag.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv4/tcp_diag.c linux-5.4.64.mptcp/net/ipv4/tcp_diag.c +--- linux-5.4.64/net/ipv4/tcp_diag.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/tcp_diag.c 2020-09-10 19:25:10.503220935 +0200 @@ -31,7 +31,7 @@ r->idiag_wqueue = READ_ONCE(tp->write_seq) - tp->snd_una; } @@ -4111,9 +4120,9 @@ diff -aurN linux-5.4/net/ipv4/tcp_diag.c mptcp-mptcp_trunk/net/ipv4/tcp_diag.c } #ifdef CONFIG_TCP_MD5SIG -diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c ---- linux-5.4/net/ipv4/tcp_fastopen.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_fastopen.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv4/tcp_fastopen.c linux-5.4.64.mptcp/net/ipv4/tcp_fastopen.c +--- linux-5.4.64/net/ipv4/tcp_fastopen.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/tcp_fastopen.c 2020-09-10 19:25:10.503220935 +0200 @@ -9,6 +9,7 @@ #include #include @@ -4122,7 +4131,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fast void tcp_fastopen_init_key_once(struct net *net) { -@@ -113,8 +114,6 @@ +@@ -136,8 +137,6 @@ const siphash_key_t *key, struct tcp_fastopen_cookie *foc) { @@ -4131,7 +4140,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fast if (req->rsk_ops->family == AF_INET) { const struct iphdr *iph = ip_hdr(syn); -@@ -235,8 +234,9 @@ +@@ -258,8 +257,9 @@ { struct tcp_sock *tp; struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; @@ -4142,7 +4151,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fast child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, NULL, &own_req); -@@ -271,15 +271,26 @@ +@@ -294,15 +294,26 @@ refcount_set(&req->rsk_refcnt, 2); @@ -4172,9 +4181,9 @@ diff -aurN linux-5.4/net/ipv4/tcp_fastopen.c mptcp-mptcp_trunk/net/ipv4/tcp_fast /* tcp_conn_request() is sending the SYNACK, * and queues the child into listener accept queue. */ -diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c ---- linux-5.4/net/ipv4/tcp_input.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_input.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv4/tcp_input.c linux-5.4.64.mptcp/net/ipv4/tcp_input.c +--- linux-5.4.64/net/ipv4/tcp_input.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/tcp_input.c 2020-09-10 19:32:43.267687285 +0200 @@ -76,35 +76,15 @@ #include #include @@ -4214,7 +4223,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c #define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH) #define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) -@@ -348,8 +328,12 @@ +@@ -349,8 +329,12 @@ per_mss = roundup_pow_of_two(per_mss) + SKB_DATA_ALIGN(sizeof(struct sk_buff)); @@ -4229,7 +4238,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Fast Recovery (RFC 5681 3.2) : * Cubic needs 1.7 factor, rounded to 2 to include -@@ -358,9 +342,17 @@ +@@ -359,9 +343,17 @@ sndmem = ca_ops->sndbuf_expand ? ca_ops->sndbuf_expand(sk) : 2; sndmem *= nr_segs * per_mss; @@ -4248,7 +4257,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c } /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) -@@ -409,9 +401,14 @@ +@@ -410,9 +402,14 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); @@ -4264,7 +4273,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Check #1 */ if (room > 0 && !tcp_under_memory_pressure(sk)) { -@@ -421,13 +418,13 @@ +@@ -422,13 +419,13 @@ * will fit to rcvbuf in future. */ if (tcp_win_from_space(sk, skb->truesize) <= skb->len) @@ -4281,7 +4290,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c inet_csk(sk)->icsk_ack.quick |= 1; } } -@@ -610,7 +607,10 @@ +@@ -611,7 +608,10 @@ tcp_mstamp_refresh(tp); time = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcvq_space.time); @@ -4293,7 +4302,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c return; /* Number of bytes copied to user in last RTT */ -@@ -833,7 +833,7 @@ +@@ -834,7 +834,7 @@ /* Calculate rto without backoff. This is the second half of Van Jacobson's * routine referred to above. */ @@ -4302,7 +4311,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { const struct tcp_sock *tp = tcp_sk(sk); /* Old crap is replaced with new one. 8) -@@ -1404,6 +1404,13 @@ +@@ -1406,6 +1406,13 @@ int len; int in_sack; @@ -4316,7 +4325,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Normally R but no L won't result in plain S */ if (!dup_sack && (TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_RETRANS)) == TCPCB_SACKED_RETRANS) -@@ -2953,7 +2960,7 @@ +@@ -2960,7 +2967,7 @@ */ tcp_update_rtt_min(sk, ca_rtt_us, flag); tcp_rtt_estimator(sk, seq_rtt_us); @@ -4325,7 +4334,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* RFC6298: only reset backoff on valid RTT measurement. */ inet_csk(sk)->icsk_backoff = 0; -@@ -3021,7 +3028,7 @@ +@@ -3028,7 +3035,7 @@ } /* If we get here, the whole TSO packet has not been acked. */ @@ -4334,7 +4343,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { struct tcp_sock *tp = tcp_sk(sk); u32 packets_acked; -@@ -3041,8 +3048,7 @@ +@@ -3048,8 +3055,7 @@ return packets_acked; } @@ -4344,7 +4353,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { const struct skb_shared_info *shinfo; -@@ -3147,6 +3153,8 @@ +@@ -3154,6 +3160,8 @@ */ if (likely(!(scb->tcp_flags & TCPHDR_SYN))) { flag |= FLAG_DATA_ACKED; @@ -4353,7 +4362,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c } else { flag |= FLAG_SYN_ACKED; tp->retrans_stamp = 0; -@@ -3266,7 +3274,7 @@ +@@ -3274,7 +3282,7 @@ return flag; } @@ -4362,7 +4371,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { struct inet_connection_sock *icsk = inet_csk(sk); struct sk_buff *head = tcp_send_head(sk); -@@ -3338,9 +3346,8 @@ +@@ -3346,9 +3354,8 @@ /* Check that window update is acceptable. * The function assumes that snd_una<=ack<=snd_next. */ @@ -4374,7 +4383,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { return after(ack, tp->snd_una) || after(ack_seq, tp->snd_wl1) || -@@ -3577,7 +3584,7 @@ +@@ -3586,7 +3593,7 @@ } /* This routine deals with incoming acks, but not outgoing ones. */ @@ -4383,7 +4392,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); -@@ -3691,6 +3698,16 @@ +@@ -3709,6 +3716,16 @@ tcp_rack_update_reo_wnd(sk, &rs); @@ -4400,7 +4409,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (tp->tlp_high_seq) tcp_process_tlp_ack(sk, ack, flag); /* If needed, reset TLP/RTO timer; RACK may later override this. */ -@@ -3833,8 +3850,10 @@ +@@ -3851,8 +3868,10 @@ */ void tcp_parse_options(const struct net *net, const struct sk_buff *skb, @@ -4413,7 +4422,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { const unsigned char *ptr; const struct tcphdr *th = tcp_hdr(skb); -@@ -3920,6 +3939,10 @@ +@@ -3938,6 +3957,10 @@ */ break; #endif @@ -4424,7 +4433,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c case TCPOPT_FASTOPEN: tcp_parse_fastopen_option( opsize - TCPOLEN_FASTOPEN_BASE, -@@ -3987,7 +4010,9 @@ +@@ -4005,7 +4028,9 @@ return true; } @@ -4435,7 +4444,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) tp->rx_opt.rcv_tsecr -= tp->tsoffset; -@@ -4146,6 +4171,11 @@ +@@ -4164,6 +4189,11 @@ { struct tcp_sock *tp = tcp_sk(sk); @@ -4447,7 +4456,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c inet_csk_schedule_ack(sk); sk->sk_shutdown |= RCV_SHUTDOWN; -@@ -4156,6 +4186,10 @@ +@@ -4174,6 +4204,10 @@ case TCP_ESTABLISHED: /* Move to CLOSE_WAIT */ tcp_set_state(sk, TCP_CLOSE_WAIT); @@ -4458,7 +4467,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c inet_csk_enter_pingpong_mode(sk); break; -@@ -4178,9 +4212,16 @@ +@@ -4196,9 +4230,16 @@ tcp_set_state(sk, TCP_CLOSING); break; case TCP_FIN_WAIT2: @@ -4476,7 +4485,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c break; default: /* Only TCP_LISTEN and TCP_CLOSE are left, in these -@@ -4202,6 +4243,10 @@ +@@ -4220,6 +4261,10 @@ if (!sock_flag(sk, SOCK_DEAD)) { sk->sk_state_change(sk); @@ -4487,7 +4496,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Do not send POLL_HUP for half duplex close. */ if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) -@@ -4416,6 +4461,9 @@ +@@ -4434,6 +4479,9 @@ *fragstolen = false; @@ -4497,7 +4506,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Its possible this segment overlaps with prior segment in queue */ if (TCP_SKB_CB(from)->seq != TCP_SKB_CB(to)->end_seq) return false; -@@ -4470,7 +4518,7 @@ +@@ -4488,7 +4536,7 @@ /* This one checks to see if we can put data from the * out_of_order queue into the receive_queue. */ @@ -4506,7 +4515,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { struct tcp_sock *tp = tcp_sk(sk); __u32 dsack_high = tp->rcv_nxt; -@@ -4493,7 +4541,14 @@ +@@ -4511,7 +4559,14 @@ p = rb_next(p); rb_erase(&skb->rbnode, &tp->out_of_order_queue); @@ -4522,7 +4531,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_drop(sk, skb); continue; } -@@ -4523,6 +4578,9 @@ +@@ -4541,6 +4596,9 @@ static int tcp_try_rmem_schedule(struct sock *sk, struct sk_buff *skb, unsigned int size) { @@ -4532,7 +4541,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || !sk_rmem_schedule(sk, skb, size)) { -@@ -4537,7 +4595,7 @@ +@@ -4555,7 +4613,7 @@ return 0; } @@ -4541,7 +4550,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { struct tcp_sock *tp = tcp_sk(sk); struct rb_node **p, *parent; -@@ -4604,7 +4662,8 @@ +@@ -4627,7 +4685,8 @@ continue; } if (before(seq, TCP_SKB_CB(skb1)->end_seq)) { @@ -4551,7 +4560,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* All the bits are present. Drop. */ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPOFOMERGE); -@@ -4651,6 +4710,11 @@ +@@ -4674,6 +4733,11 @@ end_seq); break; } @@ -4563,7 +4572,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c rb_erase(&skb1->rbnode, &tp->out_of_order_queue); tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, TCP_SKB_CB(skb1)->end_seq); -@@ -4662,7 +4726,7 @@ +@@ -4685,7 +4749,7 @@ tp->ooo_last_skb = skb; add_sack: @@ -4572,7 +4581,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_sack_new_ofo_skb(sk, seq, end_seq); end: if (skb) { -@@ -4672,8 +4736,8 @@ +@@ -4699,8 +4763,8 @@ } } @@ -4583,17 +4592,16 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { int eaten; struct sk_buff *tail = skb_peek_tail(&sk->sk_receive_queue); -@@ -4746,8 +4810,7 @@ - const struct tcp_sock *tp = tcp_sk(sk); +@@ -4774,7 +4838,7 @@ int avail = tp->rcv_nxt - tp->copied_seq; -- if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && + if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && - !sock_flag(sk, SOCK_DONE)) -+ if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && !sock_flag(sk, SOCK_DONE) && !mptcp(tp)) ++ !sock_flag(sk, SOCK_DONE) && !mptcp(tp)) return; sk->sk_data_ready(sk); -@@ -4758,10 +4822,14 @@ +@@ -4786,10 +4850,14 @@ bool fragstolen; int eaten; @@ -4609,7 +4617,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c skb_dst_drop(skb); __skb_pull(skb, tcp_hdr(skb)->doff * 4); -@@ -4789,7 +4857,7 @@ +@@ -4816,7 +4884,7 @@ } eaten = tcp_queue_rcv(sk, skb, &fragstolen); @@ -4618,7 +4626,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_event_data_recv(sk, skb); if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) tcp_fin(sk); -@@ -4811,7 +4879,11 @@ +@@ -4838,7 +4906,11 @@ if (eaten > 0) kfree_skb_partial(skb, fragstolen); @@ -4631,7 +4639,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_data_ready(sk); return; } -@@ -5154,7 +5226,7 @@ +@@ -5181,7 +5253,7 @@ return -1; } @@ -4640,7 +4648,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { const struct tcp_sock *tp = tcp_sk(sk); -@@ -5189,7 +5261,7 @@ +@@ -5216,7 +5288,7 @@ { struct tcp_sock *tp = tcp_sk(sk); @@ -4649,7 +4657,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_sndbuf_expand(sk); tp->snd_cwnd_stamp = tcp_jiffies32; } -@@ -5203,10 +5275,11 @@ +@@ -5230,10 +5302,11 @@ sock_reset_flag(sk, SOCK_QUEUE_SHRUNK); /* pairs with tcp_poll() */ smp_mb(); @@ -4664,7 +4672,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED); } } -@@ -5225,6 +5298,8 @@ +@@ -5252,6 +5325,8 @@ { struct tcp_sock *tp = tcp_sk(sk); unsigned long rtt, delay; @@ -4673,7 +4681,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* More than one full frame received... */ if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss && -@@ -5233,8 +5308,8 @@ +@@ -5260,8 +5335,8 @@ * If application uses SO_RCVLOWAT, we want send ack now if * we have not received enough bytes to satisfy the condition. */ @@ -4684,7 +4692,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* We ACK each frame or... */ tcp_in_quickack_mode(sk) || /* Protocol state mandates a one-time immediate ACK */ -@@ -5369,6 +5444,10 @@ +@@ -5396,6 +5471,10 @@ { struct tcp_sock *tp = tcp_sk(sk); @@ -4695,7 +4703,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Check if we get a new urgent pointer - normally not. */ if (th->urg) tcp_check_urg(sk, th); -@@ -5511,9 +5590,15 @@ +@@ -5538,9 +5617,15 @@ goto discard; } @@ -4711,7 +4719,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_drop(sk, skb); return false; } -@@ -5570,6 +5655,10 @@ +@@ -5597,6 +5682,10 @@ tp->rx_opt.saw_tstamp = 0; @@ -4722,7 +4730,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* pred_flags is 0xS?10 << 16 + snd_wnd * if header_prediction is to be made * 'S' will always be tp->tcp_header_len >> 2 -@@ -5742,7 +5831,7 @@ +@@ -5769,7 +5858,7 @@ tcp_call_bpf(sk, bpf_op, 0, NULL); tcp_init_congestion_control(sk); @@ -4731,7 +4739,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c } void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) -@@ -5779,17 +5868,24 @@ +@@ -5806,17 +5895,24 @@ struct tcp_fastopen_cookie *cookie) { struct tcp_sock *tp = tcp_sk(sk); @@ -4758,7 +4766,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c mss = opt.mss_clamp; } -@@ -5813,7 +5909,11 @@ +@@ -5840,7 +5936,11 @@ tcp_fastopen_cache_set(sk, mss, cookie, syn_drop, try_exp); @@ -4771,7 +4779,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c skb_rbtree_walk_from(data) { if (__tcp_retransmit_skb(sk, data, 1)) break; -@@ -5868,9 +5968,13 @@ +@@ -5895,9 +5995,13 @@ struct tcp_sock *tp = tcp_sk(sk); struct tcp_fastopen_cookie foc = { .len = -1 }; int saved_clamp = tp->rx_opt.mss_clamp; @@ -4786,7 +4794,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) tp->rx_opt.rcv_tsecr -= tp->tsoffset; -@@ -5931,6 +6035,35 @@ +@@ -5958,6 +6062,35 @@ tcp_try_undo_spurious_syn(sk); tcp_ack(sk, skb, FLAG_SLOWPATH); @@ -4822,7 +4830,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Ok.. it's good. Set up sequence numbers and * move to established. */ -@@ -5957,6 +6090,11 @@ +@@ -5984,6 +6117,11 @@ tp->tcp_header_len = sizeof(struct tcphdr); } @@ -4834,7 +4842,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); tcp_initialize_rcv_mss(sk); -@@ -5980,9 +6118,12 @@ +@@ -6007,9 +6145,12 @@ } if (fastopen_fail) return -1; @@ -4849,7 +4857,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Save one ACK. Data will be ready after * several ticks, if write_pending is set. * -@@ -6021,6 +6162,7 @@ +@@ -6048,6 +6189,7 @@ tcp_paws_reject(&tp->rx_opt, 0)) goto discard_and_undo; @@ -4857,7 +4865,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (th->syn) { /* We see SYN without ACK. It is attempt of * simultaneous connect with crossed SYNs. -@@ -6037,6 +6179,11 @@ +@@ -6064,6 +6206,11 @@ tp->tcp_header_len = sizeof(struct tcphdr); } @@ -4869,7 +4877,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c WRITE_ONCE(tp->rcv_nxt, TCP_SKB_CB(skb)->seq + 1); WRITE_ONCE(tp->copied_seq, tp->rcv_nxt); tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; -@@ -6123,6 +6270,7 @@ +@@ -6154,6 +6301,7 @@ */ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) @@ -4877,7 +4885,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c { struct tcp_sock *tp = tcp_sk(sk); struct inet_connection_sock *icsk = inet_csk(sk); -@@ -6165,6 +6313,16 @@ +@@ -6196,6 +6344,16 @@ tp->rx_opt.saw_tstamp = 0; tcp_mstamp_refresh(tp); queued = tcp_rcv_synsent_state_process(sk, skb, th); @@ -4894,7 +4902,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (queued >= 0) return queued; -@@ -6237,6 +6395,8 @@ +@@ -6268,6 +6426,8 @@ if (tp->rx_opt.tstamp_ok) tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; @@ -4903,7 +4911,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (!inet_csk(sk)->icsk_ca_ops->cong_control) tcp_update_pacing_rate(sk); -@@ -6246,6 +6406,30 @@ +@@ -6277,6 +6437,30 @@ tcp_initialize_rcv_mss(sk); tcp_fast_path_on(tp); @@ -4934,7 +4942,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c break; case TCP_FIN_WAIT1: { -@@ -6286,7 +6470,8 @@ +@@ -6317,7 +6501,8 @@ tmo = tcp_fin_time(sk); if (tmo > TCP_TIMEWAIT_LEN) { inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); @@ -4944,7 +4952,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c /* Bad case. We could lose such FIN otherwise. * It is not a big problem, but it looks confusing * and not so rare event. We still can lose it now, -@@ -6295,7 +6480,7 @@ +@@ -6326,7 +6511,7 @@ */ inet_csk_reset_keepalive_timer(sk, tmo); } else { @@ -4953,7 +4961,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c goto discard; } break; -@@ -6303,7 +6488,7 @@ +@@ -6334,7 +6519,7 @@ case TCP_CLOSING: if (tp->snd_una == tp->write_seq) { @@ -4962,7 +4970,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c goto discard; } break; -@@ -6315,6 +6500,9 @@ +@@ -6346,6 +6531,9 @@ goto discard; } break; @@ -4972,7 +4980,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c } /* step 6: check the URG bit */ -@@ -6336,7 +6524,8 @@ +@@ -6367,7 +6555,8 @@ */ if (sk->sk_shutdown & RCV_SHUTDOWN) { if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && @@ -4982,7 +4990,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONDATA); tcp_reset(sk); return 1; -@@ -6438,6 +6627,8 @@ +@@ -6469,6 +6658,8 @@ ireq->wscale_ok = rx_opt->wscale_ok; ireq->acked = 0; ireq->ecn_ok = 0; @@ -4991,7 +4999,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c ireq->ir_rmt_port = tcp_hdr(skb)->source; ireq->ir_num = ntohs(tcp_hdr(skb)->dest); ireq->ir_mark = inet_request_mark(sk, skb); -@@ -6563,12 +6754,17 @@ +@@ -6594,12 +6785,17 @@ /* TW buckets are converted to open requests without * limitations, they conserve resources and peer is * evidently real one. @@ -5010,7 +5018,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c } if (sk_acceptq_is_full(sk)) { -@@ -6586,8 +6782,8 @@ +@@ -6617,8 +6813,8 @@ tcp_clear_options(&tmp_opt); tmp_opt.mss_clamp = af_ops->mss_clamp; tmp_opt.user_mss = tp->rx_opt.user_mss; @@ -5021,7 +5029,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (want_cookie && !tmp_opt.saw_tstamp) tcp_clear_options(&tmp_opt); -@@ -6602,7 +6798,8 @@ +@@ -6633,7 +6829,8 @@ /* Note: tcp_v6_init_req() might override ir_iif for link locals */ inet_rsk(req)->ir_iif = inet_request_bound_dev_if(sk, skb); @@ -5031,7 +5039,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c if (security_inet_conn_request(sk, skb, req)) goto drop_and_free; -@@ -6638,7 +6835,7 @@ +@@ -6669,7 +6866,7 @@ tcp_ecn_create_request(req, skb, sk, dst); if (want_cookie) { @@ -5040,7 +5048,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c req->cookie_ts = tmp_opt.tstamp_ok; if (!tmp_opt.tstamp_ok) inet_rsk(req)->ecn_ok = 0; -@@ -6653,17 +6850,25 @@ +@@ -6684,17 +6881,25 @@ fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc, dst); } if (fastopen_sk) { @@ -5067,9 +5075,9 @@ diff -aurN linux-5.4/net/ipv4/tcp_input.c mptcp-mptcp_trunk/net/ipv4/tcp_input.c sock_put(fastopen_sk); } else { tcp_rsk(req)->tfo_listener = false; -diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c ---- linux-5.4/net/ipv4/tcp_ipv4.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv4/tcp_ipv4.c linux-5.4.64.mptcp/net/ipv4/tcp_ipv4.c +--- linux-5.4.64/net/ipv4/tcp_ipv4.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/tcp_ipv4.c 2020-09-10 19:25:10.503220935 +0200 @@ -62,6 +62,8 @@ #include #include @@ -5328,7 +5336,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c { kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); } -@@ -1345,9 +1383,10 @@ +@@ -1354,9 +1392,10 @@ return false; } @@ -5342,7 +5350,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c { struct inet_request_sock *ireq = inet_rsk(req); struct net *net = sock_net(sk_listener); -@@ -1355,6 +1394,8 @@ +@@ -1364,6 +1403,8 @@ sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb)); @@ -5351,7 +5359,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c } static struct dst_entry *tcp_v4_route_req(const struct sock *sk, -@@ -1374,7 +1415,7 @@ +@@ -1383,7 +1424,7 @@ .syn_ack_timeout = tcp_syn_ack_timeout, }; @@ -5360,7 +5368,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c .mss_clamp = TCP_MSS_DEFAULT, #ifdef CONFIG_TCP_MD5SIG .req_md5_lookup = tcp_v4_md5_lookup, -@@ -1511,7 +1552,7 @@ +@@ -1520,7 +1561,7 @@ } EXPORT_SYMBOL(tcp_v4_syn_recv_sock); @@ -5369,7 +5377,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c { #ifdef CONFIG_SYN_COOKIES const struct tcphdr *th = tcp_hdr(skb); -@@ -1549,6 +1590,9 @@ +@@ -1558,6 +1599,9 @@ { struct sock *rsk; @@ -5379,7 +5387,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ struct dst_entry *dst = sk->sk_rx_dst; -@@ -1793,6 +1837,10 @@ +@@ -1802,6 +1846,10 @@ TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + skb->len - th->doff * 4); TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); @@ -5390,7 +5398,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); TCP_SKB_CB(skb)->tcp_tw_isn = 0; TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph); -@@ -1812,8 +1860,8 @@ +@@ -1821,8 +1869,8 @@ int sdif = inet_sdif(skb); const struct iphdr *iph; const struct tcphdr *th; @@ -5400,7 +5408,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c int ret; if (skb->pkt_type != PACKET_HOST) -@@ -1867,7 +1915,11 @@ +@@ -1876,7 +1924,11 @@ reqsk_put(req); goto csum_error; } @@ -5413,7 +5421,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c inet_csk_reqsk_queue_drop_and_put(sk, req); goto lookup; } -@@ -1876,6 +1928,7 @@ +@@ -1885,6 +1937,7 @@ */ sock_hold(sk); refcounted = true; @@ -5421,7 +5429,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c nsk = NULL; if (!tcp_filter(sk, skb)) { th = (const struct tcphdr *)skb->data; -@@ -1936,19 +1989,28 @@ +@@ -1945,19 +1998,28 @@ sk_incoming_cpu_update(sk); @@ -5454,7 +5462,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c if (skb_to_free) __kfree_skb(skb_to_free); -@@ -1964,6 +2026,19 @@ +@@ -1973,6 +2035,19 @@ tcp_v4_fill_cb(skb, iph, th); @@ -5474,7 +5482,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c if (tcp_checksum_complete(skb)) { csum_error: __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); -@@ -2012,6 +2087,18 @@ +@@ -2021,6 +2096,18 @@ refcounted = false; goto process; } @@ -5493,7 +5501,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c } /* to ACK */ /* fall through */ -@@ -2081,7 +2168,12 @@ +@@ -2090,7 +2177,12 @@ tcp_init_sock(sk); @@ -5507,7 +5515,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c #ifdef CONFIG_TCP_MD5SIG tcp_sk(sk)->af_specific = &tcp_sock_ipv4_specific; -@@ -2100,6 +2192,11 @@ +@@ -2109,6 +2201,11 @@ tcp_cleanup_congestion_control(sk); @@ -5519,7 +5527,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c tcp_cleanup_ulp(sk); /* Cleanup up the write buffer. */ -@@ -2603,6 +2700,11 @@ +@@ -2613,6 +2710,11 @@ .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_tcp_rmem), .max_header = MAX_TCP_HEADER, .obj_size = sizeof(struct tcp_sock), @@ -5531,7 +5539,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c .slab_flags = SLAB_TYPESAFE_BY_RCU, .twsk_prot = &tcp_timewait_sock_ops, .rsk_prot = &tcp_request_sock_ops, -@@ -2613,6 +2715,9 @@ +@@ -2623,6 +2725,9 @@ .compat_getsockopt = compat_tcp_getsockopt, #endif .diag_destroy = tcp_abort, @@ -5541,9 +5549,9 @@ diff -aurN linux-5.4/net/ipv4/tcp_ipv4.c mptcp-mptcp_trunk/net/ipv4/tcp_ipv4.c }; EXPORT_SYMBOL(tcp_prot); -diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c ---- linux-5.4/net/ipv4/tcp_minisocks.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_minisocks.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv4/tcp_minisocks.c linux-5.4.64.mptcp/net/ipv4/tcp_minisocks.c +--- linux-5.4.64/net/ipv4/tcp_minisocks.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/tcp_minisocks.c 2020-09-10 19:25:10.503220935 +0200 @@ -19,11 +19,13 @@ * Jorge Cwik, */ @@ -5787,9 +5795,9 @@ diff -aurN linux-5.4/net/ipv4/tcp_minisocks.c mptcp-mptcp_trunk/net/ipv4/tcp_min sock_put(child); return ret; } -diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output.c ---- linux-5.4/net/ipv4/tcp_output.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_output.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv4/tcp_output.c linux-5.4.64.mptcp/net/ipv4/tcp_output.c +--- linux-5.4.64/net/ipv4/tcp_output.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/tcp_output.c 2020-09-10 19:34:56.261474044 +0200 @@ -37,6 +37,12 @@ #define pr_fmt(fmt) "TCP: " fmt @@ -5816,7 +5824,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); -@@ -252,12 +255,16 @@ +@@ -255,12 +258,16 @@ * value can be stuffed directly into th->window for an outgoing * frame. */ @@ -5836,7 +5844,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* Never shrink the offered window */ if (new_win < cur_win) { -@@ -273,6 +280,7 @@ +@@ -276,6 +283,7 @@ LINUX_MIB_TCPWANTZEROWINDOWADV); new_win = ALIGN(cur_win, 1 << tp->rx_opt.rcv_wscale); } @@ -5844,7 +5852,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output tp->rcv_wnd = new_win; tp->rcv_wup = tp->rcv_nxt; -@@ -385,7 +393,7 @@ +@@ -388,7 +396,7 @@ /* Constructs common control bits of non-data skb. If SYN/FIN is present, * auto increment end seqno. */ @@ -5853,7 +5861,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { skb->ip_summed = CHECKSUM_PARTIAL; -@@ -400,7 +408,7 @@ +@@ -403,7 +411,7 @@ TCP_SKB_CB(skb)->end_seq = seq; } @@ -5862,7 +5870,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { return tp->snd_una != tp->snd_up; } -@@ -411,6 +419,7 @@ +@@ -414,6 +422,7 @@ #define OPTION_WSCALE (1 << 3) #define OPTION_FAST_OPEN_COOKIE (1 << 8) #define OPTION_SMC (1 << 9) @@ -5870,7 +5878,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output static void smc_options_write(__be32 *ptr, u16 *options) { -@@ -427,17 +436,6 @@ +@@ -430,17 +439,6 @@ #endif } @@ -5888,7 +5896,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* Write previously computed TCP options to the packet. * * Beware: Something in the Internet is very sensitive to the ordering of -@@ -452,7 +450,7 @@ +@@ -455,7 +453,7 @@ * (but it may well be that other scenarios fail similarly). */ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, @@ -5897,7 +5905,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { u16 options = opts->options; /* mungable copy */ -@@ -546,6 +544,9 @@ +@@ -549,6 +547,9 @@ } smc_options_write(ptr, &options); @@ -5907,7 +5915,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output } static void smc_set_option(const struct tcp_sock *tp, -@@ -632,6 +633,8 @@ +@@ -635,6 +636,8 @@ if (unlikely(!(OPTION_TS & opts->options))) remaining -= TCPOLEN_SACKPERM_ALIGNED; } @@ -5916,7 +5924,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output if (fastopen && fastopen->cookie.len >= 0) { u32 need = fastopen->cookie.len; -@@ -713,6 +716,9 @@ +@@ -718,6 +721,9 @@ smc_set_option_cond(tcp_sk(sk), ireq, opts, &remaining); @@ -5926,7 +5934,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output return MAX_TCP_OPTION_SPACE - remaining; } -@@ -747,17 +753,22 @@ +@@ -752,14 +758,19 @@ opts->tsecr = tp->rx_opt.ts_recent; size += TCPOLEN_TSTAMP_ALIGNED; } @@ -5935,29 +5943,22 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack; if (unlikely(eff_sacks)) { -- const unsigned int remaining = MAX_TCP_OPTION_SPACE - size; + const unsigned int remaining = MAX_TCP_OPTION_SPACE - size; - opts->num_sack_blocks = - min_t(unsigned int, eff_sacks, - (remaining - TCPOLEN_SACK_BASE_ALIGNED) / - TCPOLEN_SACK_PERBLOCK); -- if (likely(opts->num_sack_blocks)) -- size += TCPOLEN_SACK_BASE_ALIGNED + -- opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; -+ const unsigned remaining = MAX_TCP_OPTION_SPACE - size; + if (remaining < TCPOLEN_SACK_BASE_ALIGNED) + opts->num_sack_blocks = 0; + else + opts->num_sack_blocks = -+ min_t(unsigned int, eff_sacks, -+ (remaining - TCPOLEN_SACK_BASE_ALIGNED) / -+ TCPOLEN_SACK_PERBLOCK); -+ if (likely(opts->num_sack_blocks)) -+ size += TCPOLEN_SACK_BASE_ALIGNED + -+ opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; - } - - return size; -@@ -796,19 +808,31 @@ ++ min_t(unsigned int, eff_sacks, ++ (remaining - TCPOLEN_SACK_BASE_ALIGNED) / ++ TCPOLEN_SACK_PERBLOCK); + if (likely(opts->num_sack_blocks)) + size += TCPOLEN_SACK_BASE_ALIGNED + + opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; +@@ -802,19 +813,31 @@ tcp_xmit_retransmit_queue(sk); } @@ -5996,7 +5997,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output } /* * One tasklet per cpu tries to send more skbs. -@@ -845,7 +869,9 @@ +@@ -851,7 +874,9 @@ #define TCP_DEFERRED_ALL (TCPF_TSQ_DEFERRED | \ TCPF_WRITE_TIMER_DEFERRED | \ TCPF_DELACK_TIMER_DEFERRED | \ @@ -6007,7 +6008,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /** * tcp_release_cb - tcp release_sock() callback * @sk: socket -@@ -868,6 +894,9 @@ +@@ -874,6 +899,9 @@ if (flags & TCPF_TSQ_DEFERRED) { tcp_tsq_write(sk); __sock_put(sk); @@ -6017,7 +6018,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output } /* Here begins the tricky part : * We are called from release_sock() with : -@@ -892,6 +921,13 @@ +@@ -898,6 +926,13 @@ inet_csk(sk)->icsk_af_ops->mtu_reduced(sk); __sock_put(sk); } @@ -6031,7 +6032,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output } EXPORT_SYMBOL(tcp_release_cb); -@@ -975,8 +1011,8 @@ +@@ -981,8 +1016,8 @@ return HRTIMER_NORESTART; } @@ -6042,7 +6043,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { struct tcp_sock *tp = tcp_sk(sk); -@@ -1118,10 +1154,10 @@ +@@ -1128,10 +1163,10 @@ } } @@ -6055,7 +6056,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output tcp_ecn_send(sk, skb, th, tcp_header_size); } else { /* RFC1323: The window in SYN & SYN/ACK segments -@@ -1179,8 +1215,8 @@ +@@ -1189,8 +1224,8 @@ return err; } @@ -6066,7 +6067,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { return __tcp_transmit_skb(sk, skb, clone_it, gfp_mask, tcp_sk(sk)->rcv_nxt); -@@ -1191,7 +1227,7 @@ +@@ -1201,7 +1236,7 @@ * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames, * otherwise socket can stall. */ @@ -6075,7 +6076,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { struct tcp_sock *tp = tcp_sk(sk); -@@ -1204,7 +1240,7 @@ +@@ -1214,7 +1249,7 @@ } /* Initialize TSO segments for a packet. */ @@ -6084,7 +6085,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { if (skb->len <= mss_now) { /* Avoid the costly divide in the normal -@@ -1221,7 +1257,7 @@ +@@ -1231,7 +1266,7 @@ /* Pcount in the middle of the write queue got changed, we need to do various * tweaks to fix counters */ @@ -6093,7 +6094,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { struct tcp_sock *tp = tcp_sk(sk); -@@ -1390,7 +1426,7 @@ +@@ -1400,7 +1435,7 @@ /* This is similar to __pskb_pull_tail(). The difference is that pulled * data is not copied, but immediately discarded. */ @@ -6102,7 +6103,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { struct skb_shared_info *shinfo; int i, k, eat; -@@ -1612,6 +1648,7 @@ +@@ -1622,6 +1657,7 @@ return mss_now; } @@ -6110,7 +6111,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* RFC2861, slow part. Adjust cwnd, after it was not full during one rto. * As additional protections, we do not touch cwnd in retransmission phases, -@@ -1693,8 +1730,8 @@ +@@ -1703,8 +1739,8 @@ * But we can avoid doing the divide again given we already have * skb_pcount = skb->len / mss_now */ @@ -6121,7 +6122,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { if (skb->len < tcp_skb_pcount(skb) * mss_now) tp->snd_sml = TCP_SKB_CB(skb)->end_seq; -@@ -1754,11 +1791,11 @@ +@@ -1764,11 +1800,11 @@ } /* Returns the portion of skb which can be sent right away */ @@ -6138,7 +6139,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { const struct tcp_sock *tp = tcp_sk(sk); u32 partial, needed, window, max_len; -@@ -1788,13 +1825,14 @@ +@@ -1798,13 +1834,14 @@ /* Can at least one segment of SKB be sent right now, according to the * congestion window rules? If so, return how many segments are allowed. */ @@ -6156,7 +6157,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output tcp_skb_pcount(skb) == 1) return 1; -@@ -1809,12 +1847,13 @@ +@@ -1819,12 +1856,13 @@ halfcwnd = max(cwnd >> 1, 1U); return min(halfcwnd, cwnd - in_flight); } @@ -6171,7 +6172,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { int tso_segs = tcp_skb_pcount(skb); -@@ -1829,8 +1868,8 @@ +@@ -1839,8 +1877,8 @@ /* Return true if the Nagle test allows this packet to be * sent now. */ @@ -6182,7 +6183,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { /* Nagle rule does not apply to frames, which sit in the middle of the * write_queue (they have no chances to get new data). -@@ -1842,7 +1881,8 @@ +@@ -1852,7 +1890,8 @@ return true; /* Don't use the nagle rule for urgent data (or for the final FIN). */ @@ -6192,7 +6193,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output return true; if (!tcp_nagle_check(skb->len < cur_mss, tp, nonagle)) -@@ -1852,9 +1892,8 @@ +@@ -1862,9 +1901,8 @@ } /* Does at least the first segment of SKB fit into the send window? */ @@ -6204,7 +6205,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { u32 end_seq = TCP_SKB_CB(skb)->end_seq; -@@ -1863,6 +1902,7 @@ +@@ -1873,6 +1911,7 @@ return !after(end_seq, tcp_wnd_end(tp)); } @@ -6212,7 +6213,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* Trim TSO SKB to LEN bytes, put the remaining data into a new packet * which is put after SKB on the list. It is very much like -@@ -2021,7 +2061,8 @@ +@@ -2031,7 +2070,8 @@ /* If this packet won't get more data, do not wait. */ if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) || @@ -6222,7 +6223,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output goto send_now; return true; -@@ -2354,7 +2395,7 @@ +@@ -2364,7 +2404,7 @@ * Returns true, if no segments are in flight and we have queued segments, * but cannot send anything now because of SWS or another problem. */ @@ -6231,7 +6232,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output int push_one, gfp_t gfp) { struct tcp_sock *tp = tcp_sk(sk); -@@ -2368,7 +2409,12 @@ +@@ -2378,7 +2418,12 @@ sent_pkts = 0; tcp_mstamp_refresh(tp); @@ -6245,7 +6246,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* Do MTU probing. */ result = tcp_mtu_probe(sk); if (!result) { -@@ -2549,7 +2595,7 @@ +@@ -2572,7 +2617,7 @@ skb = tcp_send_head(sk); if (skb && tcp_snd_wnd_test(tp, skb, mss)) { pcount = tp->packets_out; @@ -6254,7 +6255,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output if (tp->packets_out > pcount) goto probe_sent; goto rearm_timer; -@@ -2613,8 +2659,8 @@ +@@ -2634,8 +2679,8 @@ if (unlikely(sk->sk_state == TCP_CLOSE)) return; @@ -6265,7 +6266,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output tcp_check_probe_timer(sk); } -@@ -2627,7 +2673,8 @@ +@@ -2648,7 +2693,8 @@ BUG_ON(!skb || skb->len < mss_now); @@ -6275,7 +6276,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output } /* This function returns the amount that we can raise the -@@ -2849,6 +2896,10 @@ +@@ -2870,6 +2916,10 @@ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN) return; @@ -6286,7 +6287,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output skb_rbtree_walk_from_safe(skb, tmp) { if (!tcp_can_collapse(sk, skb)) break; -@@ -3325,7 +3376,7 @@ +@@ -3351,7 +3401,7 @@ /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ th->window = htons(min(req->rsk_rcv_wnd, 65535U)); @@ -6295,7 +6296,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output th->doff = (tcp_header_size >> 2); __TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); -@@ -3407,13 +3458,13 @@ +@@ -3433,13 +3483,13 @@ if (rcv_wnd == 0) rcv_wnd = dst_metric(dst, RTAX_INITRWND); @@ -6316,7 +6317,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output tp->rx_opt.rcv_wscale = rcv_wscale; tp->rcv_ssthresh = tp->rcv_wnd; -@@ -3438,6 +3489,36 @@ +@@ -3464,6 +3514,36 @@ inet_csk(sk)->icsk_rto = tcp_timeout_init(sk); inet_csk(sk)->icsk_retransmits = 0; tcp_clear_retrans(tp); @@ -6353,7 +6354,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output } static void tcp_connect_queue_skb(struct sock *sk, struct sk_buff *skb) -@@ -3701,6 +3782,7 @@ +@@ -3727,6 +3807,7 @@ { __tcp_send_ack(sk, tcp_sk(sk)->rcv_nxt); } @@ -6361,7 +6362,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output /* This routine sends a packet with an out of date sequence * number. It assumes the other end will try to ack it. -@@ -3713,7 +3795,7 @@ +@@ -3739,7 +3820,7 @@ * one is with SEG.SEQ=SND.UNA to deliver urgent pointer, another is * out-of-date with SND.UNA-1 to probe window. */ @@ -6370,7 +6371,7 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; -@@ -3800,7 +3882,7 @@ +@@ -3826,7 +3907,7 @@ unsigned long timeout; int err; @@ -6379,9 +6380,9 @@ diff -aurN linux-5.4/net/ipv4/tcp_output.c mptcp-mptcp_trunk/net/ipv4/tcp_output if (tp->packets_out || tcp_write_queue_empty(sk)) { /* Cancel probe timer, if it is not required. */ -diff -aurN linux-5.4/net/ipv4/tcp_timer.c mptcp-mptcp_trunk/net/ipv4/tcp_timer.c ---- linux-5.4/net/ipv4/tcp_timer.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv4/tcp_timer.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv4/tcp_timer.c linux-5.4.64.mptcp/net/ipv4/tcp_timer.c +--- linux-5.4.64/net/ipv4/tcp_timer.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv4/tcp_timer.c 2020-09-10 19:25:10.507220869 +0200 @@ -21,6 +21,7 @@ #include @@ -6593,9 +6594,9 @@ diff -aurN linux-5.4/net/ipv4/tcp_timer.c mptcp-mptcp_trunk/net/ipv4/tcp_timer.c sock_put(sk); } -diff -aurN linux-5.4/net/ipv6/addrconf.c mptcp-mptcp_trunk/net/ipv6/addrconf.c ---- linux-5.4/net/ipv6/addrconf.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/addrconf.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv6/addrconf.c linux-5.4.64.mptcp/net/ipv6/addrconf.c +--- linux-5.4.64/net/ipv6/addrconf.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv6/addrconf.c 2020-09-10 19:25:10.507220869 +0200 @@ -967,6 +967,7 @@ kfree_rcu(ifp, rcu); @@ -6604,9 +6605,9 @@ diff -aurN linux-5.4/net/ipv6/addrconf.c mptcp-mptcp_trunk/net/ipv6/addrconf.c static void ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) -diff -aurN linux-5.4/net/ipv6/af_inet6.c mptcp-mptcp_trunk/net/ipv6/af_inet6.c ---- linux-5.4/net/ipv6/af_inet6.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/af_inet6.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv6/af_inet6.c linux-5.4.64.mptcp/net/ipv6/af_inet6.c +--- linux-5.4.64/net/ipv6/af_inet6.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv6/af_inet6.c 2020-09-10 19:25:10.507220869 +0200 @@ -104,8 +104,7 @@ return (struct ipv6_pinfo *)(((u8 *)sk) + offset); } @@ -6617,9 +6618,9 @@ diff -aurN linux-5.4/net/ipv6/af_inet6.c mptcp-mptcp_trunk/net/ipv6/af_inet6.c { struct inet_sock *inet; struct ipv6_pinfo *np; -diff -aurN linux-5.4/net/ipv6/ipv6_sockglue.c mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c ---- linux-5.4/net/ipv6/ipv6_sockglue.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/ipv6_sockglue.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv6/ipv6_sockglue.c linux-5.4.64.mptcp/net/ipv6/ipv6_sockglue.c +--- linux-5.4.64/net/ipv6/ipv6_sockglue.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv6/ipv6_sockglue.c 2020-09-10 19:25:10.507220869 +0200 @@ -44,6 +44,8 @@ #include #include @@ -6629,7 +6630,7 @@ diff -aurN linux-5.4/net/ipv6/ipv6_sockglue.c mptcp-mptcp_trunk/net/ipv6/ipv6_so #include #include #include -@@ -214,7 +216,12 @@ +@@ -221,7 +223,12 @@ sock_prot_inuse_add(net, &tcp_prot, 1); local_bh_enable(); sk->sk_prot = &tcp_prot; @@ -6643,9 +6644,9 @@ diff -aurN linux-5.4/net/ipv6/ipv6_sockglue.c mptcp-mptcp_trunk/net/ipv6/ipv6_so sk->sk_socket->ops = &inet_stream_ops; sk->sk_family = PF_INET; tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); -diff -aurN linux-5.4/net/ipv6/syncookies.c mptcp-mptcp_trunk/net/ipv6/syncookies.c ---- linux-5.4/net/ipv6/syncookies.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/syncookies.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv6/syncookies.c linux-5.4.64.mptcp/net/ipv6/syncookies.c +--- linux-5.4.64/net/ipv6/syncookies.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv6/syncookies.c 2020-09-10 19:25:10.507220869 +0200 @@ -15,6 +15,8 @@ #include #include @@ -6733,9 +6734,9 @@ diff -aurN linux-5.4/net/ipv6/syncookies.c mptcp-mptcp_trunk/net/ipv6/syncookies out: return ret; out_free: -diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c ---- linux-5.4/net/ipv6/tcp_ipv6.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/ipv6/tcp_ipv6.c linux-5.4.64.mptcp/net/ipv6/tcp_ipv6.c +--- linux-5.4.64/net/ipv6/tcp_ipv6.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/ipv6/tcp_ipv6.c 2020-09-10 19:25:10.507220869 +0200 @@ -58,6 +58,8 @@ #include #include @@ -7336,10 +7337,10 @@ diff -aurN linux-5.4/net/ipv6/tcp_ipv6.c mptcp-mptcp_trunk/net/ipv6/tcp_ipv6.c }; /* thinking of making this const? Don't. -diff -aurN linux-5.4/net/Kconfig mptcp-mptcp_trunk/net/Kconfig ---- linux-5.4/net/Kconfig 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/Kconfig 2020-07-14 19:34:59.000000000 +0200 -@@ -91,6 +91,7 @@ +diff -aurN linux-5.4.64/net/Kconfig linux-5.4.64.mptcp/net/Kconfig +--- linux-5.4.64/net/Kconfig 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/Kconfig 2020-09-10 19:25:10.507220869 +0200 +@@ -94,6 +94,7 @@ source "net/ipv4/Kconfig" source "net/ipv6/Kconfig" source "net/netlabel/Kconfig" @@ -7347,9 +7348,9 @@ diff -aurN linux-5.4/net/Kconfig mptcp-mptcp_trunk/net/Kconfig endif # if INET -diff -aurN linux-5.4/net/Makefile mptcp-mptcp_trunk/net/Makefile ---- linux-5.4/net/Makefile 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/Makefile 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/Makefile linux-5.4.64.mptcp/net/Makefile +--- linux-5.4.64/net/Makefile 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/Makefile 2020-09-10 19:25:10.507220869 +0200 @@ -20,6 +20,7 @@ obj-$(CONFIG_XFRM) += xfrm/ obj-$(CONFIG_UNIX_SCM) += unix/ @@ -7358,9 +7359,9 @@ diff -aurN linux-5.4/net/Makefile mptcp-mptcp_trunk/net/Makefile obj-$(CONFIG_BPFILTER) += bpfilter/ obj-$(CONFIG_PACKET) += packet/ obj-$(CONFIG_NET_KEY) += key/ -diff -aurN linux-5.4/net/mptcp/Kconfig mptcp-mptcp_trunk/net/mptcp/Kconfig ---- linux-5.4/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/Kconfig 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/Kconfig linux-5.4.64.mptcp/net/mptcp/Kconfig +--- linux-5.4.64/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/Kconfig 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,154 @@ +# +# MPTCP configuration @@ -7516,9 +7517,9 @@ diff -aurN linux-5.4/net/mptcp/Kconfig mptcp-mptcp_trunk/net/mptcp/Kconfig + default "redundant" if DEFAULT_REDUNDANT + default "default" + -diff -aurN linux-5.4/net/mptcp/Makefile mptcp-mptcp_trunk/net/mptcp/Makefile ---- linux-5.4/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/Makefile 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/Makefile linux-5.4.64.mptcp/net/mptcp/Makefile +--- linux-5.4.64/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/Makefile 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,25 @@ +# +## Makefile for MultiPath TCP support code. @@ -7545,9 +7546,9 @@ diff -aurN linux-5.4/net/mptcp/Makefile mptcp-mptcp_trunk/net/mptcp/Makefile +obj-$(CONFIG_MPTCP_ECF) += mptcp_ecf.o + +mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o -diff -aurN linux-5.4/net/mptcp/mctcp_desync.c mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c ---- linux-5.4/net/mptcp/mctcp_desync.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mctcp_desync.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mctcp_desync.c linux-5.4.64.mptcp/net/mptcp/mctcp_desync.c +--- linux-5.4.64/net/mptcp/mctcp_desync.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mctcp_desync.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,193 @@ +/* + * Desynchronized Multi-Channel TCP Congestion Control Algorithm @@ -7742,9 +7743,9 @@ diff -aurN linux-5.4/net/mptcp/mctcp_desync.c mptcp-mptcp_trunk/net/mptcp/mctcp_ +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MCTCP: DESYNCHRONIZED MULTICHANNEL TCP CONGESTION CONTROL"); +MODULE_VERSION("1.0"); -diff -aurN linux-5.4/net/mptcp/mptcp_balia.c mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c ---- linux-5.4/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_balia.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_balia.c linux-5.4.64.mptcp/net/mptcp/mptcp_balia.c +--- linux-5.4.64/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_balia.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,261 @@ +/* + * MPTCP implementation - Balia Congestion Control @@ -8007,9 +8008,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_balia.c mptcp-mptcp_trunk/net/mptcp/mptcp_b +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MPTCP BALIA CONGESTION CONTROL ALGORITHM"); +MODULE_VERSION("0.1"); -diff -aurN linux-5.4/net/mptcp/mptcp_binder.c mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c ---- linux-5.4/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_binder.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_binder.c linux-5.4.64.mptcp/net/mptcp/mptcp_binder.c +--- linux-5.4.64/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_binder.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,494 @@ +#include + @@ -8505,9 +8506,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_binder.c mptcp-mptcp_trunk/net/mptcp/mptcp_ +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("BINDER MPTCP"); +MODULE_VERSION("0.1"); -diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c ---- linux-5.4/net/mptcp/mptcp_blest.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_blest.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_blest.c linux-5.4.64.mptcp/net/mptcp/mptcp_blest.c +--- linux-5.4.64/net/mptcp/mptcp_blest.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_blest.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP Scheduler to reduce HoL-blocking and spurious retransmissions. @@ -8794,9 +8795,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_blest.c mptcp-mptcp_trunk/net/mptcp/mptcp_b +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("BLEST scheduler for MPTCP, based on default minimum RTT scheduler"); +MODULE_VERSION("0.95"); -diff -aurN linux-5.4/net/mptcp/mptcp_coupled.c mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c ---- linux-5.4/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_coupled.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_coupled.c linux-5.4.64.mptcp/net/mptcp/mptcp_coupled.c +--- linux-5.4.64/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_coupled.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,262 @@ +/* + * MPTCP implementation - Linked Increase congestion control Algorithm (LIA) @@ -9060,9 +9061,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_coupled.c mptcp-mptcp_trunk/net/mptcp/mptcp +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MPTCP LINKED INCREASE CONGESTION CONTROL ALGORITHM"); +MODULE_VERSION("0.1"); -diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c ---- linux-5.4/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ctrl.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_ctrl.c linux-5.4.64.mptcp/net/mptcp/mptcp_ctrl.c +--- linux-5.4.64/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_ctrl.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,3309 @@ +/* + * MPTCP implementation - MPTCP-control @@ -12373,9 +12374,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ctrl.c mptcp-mptcp_trunk/net/mptcp/mptcp_ct +mptcp_sock_cache_failed: + mptcp_init_failed = true; +} -diff -aurN linux-5.4/net/mptcp/mptcp_ecf.c mptcp-mptcp_trunk/net/mptcp/mptcp_ecf.c ---- linux-5.4/net/mptcp/mptcp_ecf.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ecf.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_ecf.c linux-5.4.64.mptcp/net/mptcp/mptcp_ecf.c +--- linux-5.4.64/net/mptcp/mptcp_ecf.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_ecf.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP ECF Scheduler @@ -12572,9 +12573,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ecf.c mptcp-mptcp_trunk/net/mptcp/mptcp_ecf +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ECF (Earliest Completion First) scheduler for MPTCP, based on default minimum RTT scheduler"); +MODULE_VERSION("0.95"); -diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c ---- linux-5.4/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_fullmesh.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_fullmesh.c linux-5.4.64.mptcp/net/mptcp/mptcp_fullmesh.c +--- linux-5.4.64/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_fullmesh.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,1938 @@ +#include +#include @@ -14514,9 +14515,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_trunk/net/mptcp/mptc +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Full-Mesh MPTCP"); +MODULE_VERSION("0.88"); -diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_input.c ---- linux-5.4/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_input.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_input.c linux-5.4.64.mptcp/net/mptcp/mptcp_input.c +--- linux-5.4.64/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_input.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,2531 @@ +/* + * MPTCP implementation - Sending side @@ -17049,9 +17050,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_input.c mptcp-mptcp_trunk/net/mptcp/mptcp_i + tcp_set_rto(sk); + mptcp_set_rto(sk); +} -diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c ---- linux-5.4/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv4.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_ipv4.c linux-5.4.64.mptcp/net/mptcp/mptcp_ipv4.c +--- linux-5.4.64/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_ipv4.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,431 @@ +/* + * MPTCP implementation - IPv4-specific functions @@ -17484,9 +17485,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv4.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip + kmem_cache_destroy(mptcp_request_sock_ops.slab); + kfree(mptcp_request_sock_ops.slab_name); +} -diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c ---- linux-5.4/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ipv6.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_ipv6.c linux-5.4.64.mptcp/net/mptcp/mptcp_ipv6.c +--- linux-5.4.64/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_ipv6.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,479 @@ +/* + * MPTCP implementation - IPv6-specific functions @@ -17967,9 +17968,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ipv6.c mptcp-mptcp_trunk/net/mptcp/mptcp_ip + kmem_cache_destroy(mptcp6_request_sock_ops.slab); + kfree(mptcp6_request_sock_ops.slab_name); +} -diff -aurN linux-5.4/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c ---- linux-5.4/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_ndiffports.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_ndiffports.c linux-5.4.64.mptcp/net/mptcp/mptcp_ndiffports.c +--- linux-5.4.64/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_ndiffports.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,174 @@ +#include + @@ -18145,9 +18146,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_trunk/net/mptcp/mp +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("NDIFF-PORTS MPTCP"); +MODULE_VERSION("0.88"); -diff -aurN linux-5.4/net/mptcp/mptcp_netlink.c mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c ---- linux-5.4/net/mptcp/mptcp_netlink.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_netlink.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_netlink.c linux-5.4.64.mptcp/net/mptcp/mptcp_netlink.c +--- linux-5.4.64/net/mptcp/mptcp_netlink.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_netlink.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,1271 @@ +// SPDX-License-Identifier: GPL-2.0 +/* MPTCP implementation - Netlink Path Manager @@ -19420,9 +19421,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_netlink.c mptcp-mptcp_trunk/net/mptcp/mptcp +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MPTCP netlink-based path manager"); +MODULE_ALIAS_GENL_FAMILY(MPTCP_GENL_NAME); -diff -aurN linux-5.4/net/mptcp/mptcp_olia.c mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c ---- linux-5.4/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_olia.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_olia.c linux-5.4.64.mptcp/net/mptcp/mptcp_olia.c +--- linux-5.4.64/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_olia.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,318 @@ +/* + * MPTCP implementation - OPPORTUNISTIC LINKED INCREASES CONGESTION CONTROL: @@ -19742,9 +19743,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_olia.c mptcp-mptcp_trunk/net/mptcp/mptcp_ol +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MPTCP COUPLED CONGESTION CONTROL"); +MODULE_VERSION("0.1"); -diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_output.c ---- linux-5.4/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_output.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_output.c linux-5.4.64.mptcp/net/mptcp/mptcp_output.c +--- linux-5.4.64/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_output.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,1997 @@ +/* + * MPTCP implementation - Sending side @@ -21743,9 +21744,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_output.c mptcp-mptcp_trunk/net/mptcp/mptcp_ + return max(xmit_size_goal, mss_now); +} + -diff -aurN linux-5.4/net/mptcp/mptcp_pm.c mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c ---- linux-5.4/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_pm.c linux-5.4.64.mptcp/net/mptcp/mptcp_pm.c +--- linux-5.4.64/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_pm.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,226 @@ +/* + * MPTCP implementation - MPTCP-subflow-management @@ -21973,9 +21974,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_pm.c mptcp-mptcp_trunk/net/mptcp/mptcp_pm.c + return mptcp_set_default_path_manager(CONFIG_DEFAULT_MPTCP_PM); +} +late_initcall(mptcp_path_manager_default); -diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c ---- linux-5.4/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_redundant.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_redundant.c linux-5.4.64.mptcp/net/mptcp/mptcp_redundant.c +--- linux-5.4.64/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_redundant.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,392 @@ +/* + * MPTCP Scheduler to reduce latency and jitter. @@ -22369,9 +22370,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_redundant.c mptcp-mptcp_trunk/net/mptcp/mpt +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("REDUNDANT MPTCP"); +MODULE_VERSION("0.90"); -diff -aurN linux-5.4/net/mptcp/mptcp_rr.c mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c ---- linux-5.4/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_rr.c linux-5.4.64.mptcp/net/mptcp/mptcp_rr.c +--- linux-5.4.64/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_rr.c 2020-09-10 19:25:10.507220869 +0200 @@ -0,0 +1,309 @@ +/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ + @@ -22682,9 +22683,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_rr.c mptcp-mptcp_trunk/net/mptcp/mptcp_rr.c +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ROUNDROBIN MPTCP"); +MODULE_VERSION("0.89"); -diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c ---- linux-5.4/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_sched.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_sched.c linux-5.4.64.mptcp/net/mptcp/mptcp_sched.c +--- linux-5.4.64/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_sched.c 2020-09-10 19:25:10.511220802 +0200 @@ -0,0 +1,647 @@ +/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ + @@ -22759,10 +22760,12 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s + if (in_flight >= tp->snd_cwnd) + return true; + ++ mss_now = tcp_current_mss(sk); ++ + /* Now, check if what is queued in the subflow's send-queue + * already fills the cwnd. + */ -+ space = (tp->snd_cwnd - in_flight) * tp->mss_cache; ++ space = (tp->snd_cwnd - in_flight) * mss_now; + + if (tp->write_seq - tp->snd_nxt >= space) + return true; @@ -22770,8 +22773,6 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s + if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) + return true; + -+ mss_now = tcp_current_mss(sk); -+ + /* Don't send on this subflow if we bypass the allowed send-window at + * the per-subflow level. Similar to tcp_snd_wnd_test, but manually + * calculated end_seq (because here at this point end_seq is still at @@ -23333,9 +23334,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_sched.c mptcp-mptcp_trunk/net/mptcp/mptcp_s + return mptcp_set_default_scheduler(CONFIG_DEFAULT_MPTCP_SCHED); +} +late_initcall(mptcp_scheduler_default); -diff -aurN linux-5.4/net/mptcp/mptcp_wvegas.c mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c ---- linux-5.4/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_trunk/net/mptcp/mptcp_wvegas.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/mptcp/mptcp_wvegas.c linux-5.4.64.mptcp/net/mptcp/mptcp_wvegas.c +--- linux-5.4.64/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-5.4.64.mptcp/net/mptcp/mptcp_wvegas.c 2020-09-10 19:25:10.511220802 +0200 @@ -0,0 +1,271 @@ +/* + * MPTCP implementation - WEIGHTED VEGAS @@ -23608,9 +23609,9 @@ diff -aurN linux-5.4/net/mptcp/mptcp_wvegas.c mptcp-mptcp_trunk/net/mptcp/mptcp_ +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MPTCP wVegas"); +MODULE_VERSION("0.1"); -diff -aurN linux-5.4/net/socket.c mptcp-mptcp_trunk/net/socket.c ---- linux-5.4/net/socket.c 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/net/socket.c 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/net/socket.c linux-5.4.64.mptcp/net/socket.c +--- linux-5.4.64/net/socket.c 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/net/socket.c 2020-09-10 19:25:10.511220802 +0200 @@ -91,6 +91,7 @@ #include @@ -23648,9 +23649,9 @@ diff -aurN linux-5.4/net/socket.c mptcp-mptcp_trunk/net/socket.c /* * Now to bump the refcnt of the [loadable] module that owns this * socket at sock_release time we decrement its refcnt. -diff -aurN linux-5.4/tools/include/uapi/linux/bpf.h mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h ---- linux-5.4/tools/include/uapi/linux/bpf.h 2019-11-25 01:32:01.000000000 +0100 -+++ mptcp-mptcp_trunk/tools/include/uapi/linux/bpf.h 2020-07-14 19:34:59.000000000 +0200 +diff -aurN linux-5.4.64/tools/include/uapi/linux/bpf.h linux-5.4.64.mptcp/tools/include/uapi/linux/bpf.h +--- linux-5.4.64/tools/include/uapi/linux/bpf.h 2020-09-09 19:12:37.000000000 +0200 ++++ linux-5.4.64.mptcp/tools/include/uapi/linux/bpf.h 2020-09-10 19:25:10.511220802 +0200 @@ -3438,6 +3438,7 @@ BPF_TCP_LISTEN, BPF_TCP_CLOSING, /* Now a valid state */ From 7a8708eedad571ef86630aed8fe65653d070db94 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 10 Sep 2020 21:08:15 +0200 Subject: [PATCH 09/27] Update OpenWrt --- build.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index ced3bf33..3b4dffd6 100755 --- a/build.sh +++ b/build.sh @@ -70,9 +70,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "da986035973a8c803e6f193ae502ff65e6d551c3" - _get_repo feeds/packages https://github.com/openwrt/packages "91bf524845d4733c77c11f359b1c915e788ece14" - _get_repo feeds/luci https://github.com/openwrt/luci "b2fa7903ebfdbe9f485a94710b77320fe7897dba" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "38f6d5d217ca0c42f7f42b08f835a8a9cee71ad7" + _get_repo feeds/packages https://github.com/openwrt/packages "7479b3ecfafa6732185080ddfca68b68e27993b2" + _get_repo feeds/luci https://github.com/openwrt/luci "b95ac83ffd4fcf268be964002c45beba17d6e5c1" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" @@ -287,6 +287,7 @@ fi echo "Update feeds index" rm -rf feeds/luci/modules/luci-mod-network +[ -d feeds/${OMR_DIST}/luci-mod-status ] && rm -rf feeds/luci/modules/luci-mod-status cp .config .config.keep scripts/feeds clean From ac362317dd92ddae3a4dbf0433ac95b3d3f9072b Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 10 Sep 2020 21:08:35 +0200 Subject: [PATCH 10/27] Add NanoPI R2S support --- config-r2s | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 config-r2s diff --git a/config-r2s b/config-r2s new file mode 100644 index 00000000..15c5d543 --- /dev/null +++ b/config-r2s @@ -0,0 +1,4 @@ +CONFIG_TARGET_rockchip=y +CONFIG_TARGET_rockchip_armv8=y +CONFIG_TARGET_ramips_armv8_DEVICE_friendlyarm_nanopi-r2s=y +CONFIG_PACKAGE_kmod-6lowpan=y From 16347d37585c215a173fcb80936d650994bff5b3 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 10 Sep 2020 21:08:53 +0200 Subject: [PATCH 11/27] Fix ipq wifi --- root/package/firmware/ipq-wifi/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/root/package/firmware/ipq-wifi/Makefile b/root/package/firmware/ipq-wifi/Makefile index 4b0e29ec..0e56b300 100644 --- a/root/package/firmware/ipq-wifi/Makefile +++ b/root/package/firmware/ipq-wifi/Makefile @@ -114,6 +114,6 @@ $(eval $(call generate-ipq-wifi-package,glinet_gl-s1300,GL.iNet GL-S1300)) $(eval $(call generate-ipq-wifi-package,linksys_ea8300,Linksys EA8300)) $(eval $(call generate-ipq-wifi-package,mobipromo_cm520-79f,MobiPromo CM520-79F)) $(eval $(call generate-ipq-wifi-package,qxwlan_e2600ac,Qxwlan E2600AC)) -$(eval $(call generate-ipq-wifi-package,p2w_r619ac,PW R619AC)) +$(eval $(call generate-ipq-wifi-package,p2w_r619ac,P&W R619AC)) $(foreach PACKAGE,$(ALLWIFIPACKAGES),$(eval $(call BuildPackage,$(PACKAGE)))) From 0ef2739624c3c0456f3a5f73e95d7a0f0026934d Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 10 Sep 2020 21:09:28 +0200 Subject: [PATCH 12/27] Link to wiki for compilation doc --- README.md | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/README.md b/README.md index c8f4068d..c198b1ec 100644 --- a/README.md +++ b/README.md @@ -38,39 +38,8 @@ dd bs=4M if=omr-*.img of=/dev/sdX conv=fsync ## Install from source -### Dependencies +[Create image](https://github.com/Ysurac/openmptcprouter/wiki/Create-image-for-unsupported-platform) -You need a classical build environment like `build-essential` on Debian and `git`. -Some feeds might not available over `git` but only via `subversion` or `mercurial`. - -On Debian you'll need to install the following: - -```sh -sudo apt install build-essential git unzip ncurses-dev libz-dev libssl-dev openssl-1.0-dev - python python3-dev python3.5 libelf-dev subversion gettext gawk wget curl rsync perl -``` - -### Prepare and build - -```sh -git clone https://github.com/ysurac/openmptcprouter.git -cd openmptcprouter -./build.sh -``` - -The script `build.sh` accepts all `make` arguments (like `-j`). -When finished, files are located in the directory `source/bin`. - -### Custom arch build - -By default the build script will create the packages for the `x86_64` architecture. -You can specify a custom build target by adding a `OMR_TARGET` environment variable to the build and the corresponding `config-$OMR_TARGET` file. - -To build the project for the raspberry pi 3: - -```sh -OMR_TARGET="rpi3" ./build.sh -``` ## Credits From 7b363519475790d3daf93b16cb8045f4b91ab730 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Thu, 10 Sep 2020 21:09:48 +0200 Subject: [PATCH 13/27] Disable wolfssl --- config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config b/config index ae512ee1..a07ef7bc 100644 --- a/config +++ b/config @@ -244,3 +244,5 @@ CONFIG_TARGET_ROOTFS_PARTSIZE=512 CONFIG_TARGET_KERNEL_PARTSIZE=64 CONFIG_OPENSSL_WITH_CHACHA_POLY1305=y # CONFIG_LUCI_CSSTIDY is not set +# CONFIG_LIBCURL_WOLFSSL is not set +# CONFIG_PACKAGE_libustream-wolfssl is not set \ No newline at end of file From d8a87ec3dda927e3fc5320d6fd010aecfba2fac3 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 11 Sep 2020 07:45:05 +0200 Subject: [PATCH 14/27] Fix ipq wifi --- config-p2w_r619ac | 6 ++++++ root/package/firmware/ipq-wifi/Makefile | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 config-p2w_r619ac diff --git a/config-p2w_r619ac b/config-p2w_r619ac new file mode 100644 index 00000000..f4d50da2 --- /dev/null +++ b/config-p2w_r619ac @@ -0,0 +1,6 @@ +CONFIG_TARGET_ipq40xx=y +CONFIG_TARGET_ipq40xx_generic=y +CONFIG_TARGET_ipq40xx_generic_DEVICE_p2w_r619ac-128m=y +CONFIG_PACKAGE_kmod-6lowpan=y +# CONFIG_KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE is not set +CONFIG_KERNEL_CC_OPTIMIZE_FOR_SIZE=y diff --git a/root/package/firmware/ipq-wifi/Makefile b/root/package/firmware/ipq-wifi/Makefile index 0e56b300..8bf3b414 100644 --- a/root/package/firmware/ipq-wifi/Makefile +++ b/root/package/firmware/ipq-wifi/Makefile @@ -37,7 +37,7 @@ ALLWIFIBOARDS:= \ ezviz_cs-w3-wd1200g-eup \ glinet_gl-s1300 \ linksys_ea8300 \ - p2w_r619c \ + p2w_r619ac \ mobipromo_cm520-79f \ qxwlan_e2600ac From 4e9d9ff82382fb0b06e5751e3371aacd549a725e Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 11 Sep 2020 10:01:54 +0200 Subject: [PATCH 15/27] Fix config --- config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config b/config index a07ef7bc..c40719ef 100644 --- a/config +++ b/config @@ -245,4 +245,4 @@ CONFIG_TARGET_KERNEL_PARTSIZE=64 CONFIG_OPENSSL_WITH_CHACHA_POLY1305=y # CONFIG_LUCI_CSSTIDY is not set # CONFIG_LIBCURL_WOLFSSL is not set -# CONFIG_PACKAGE_libustream-wolfssl is not set \ No newline at end of file +# CONFIG_PACKAGE_libustream-wolfssl is not set From b8aea8b34c086904d14b3522a70ec575a6f29c8b Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 18 Sep 2020 16:33:44 +0200 Subject: [PATCH 16/27] Update OpenWrt and fix version --- build.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/build.sh b/build.sh index 3b4dffd6..3e96af9f 100755 --- a/build.sh +++ b/build.sh @@ -31,7 +31,8 @@ OMR_TARGET=${OMR_TARGET:-x86_64} OMR_TARGET_CONFIG="config-$OMR_TARGET" OMR_KERNEL=${OMR_KERNEL:-5.4} #OMR_RELEASE=${OMR_RELEASE:-$(git describe --tags `git rev-list --tags --max-count=1` | sed 's/^\([0-9.]*\).*/\1/')} -OMR_RELEASE=${OMR_RELEASE:-$(git tag --sort=committerdate | tail -1)} +#OMR_RELEASE=${OMR_RELEASE:-$(git tag --sort=committerdate | tail -1)} +OMR_RELEASE=${OMR_RELEASE:-$(git describe --tags `git rev-list --tags --max-count=1` | tail -1)} OMR_REPO=${OMR_REPO:-http://$OMR_HOST:$OMR_PORT/release/$OMR_RELEASE/$OMR_TARGET} OMR_FEED_URL="${OMR_FEED_URL:-https://github.com/ysurac/openmptcprouter-feeds}" @@ -70,9 +71,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "38f6d5d217ca0c42f7f42b08f835a8a9cee71ad7" - _get_repo feeds/packages https://github.com/openwrt/packages "7479b3ecfafa6732185080ddfca68b68e27993b2" - _get_repo feeds/luci https://github.com/openwrt/luci "b95ac83ffd4fcf268be964002c45beba17d6e5c1" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "14247c82c0c64bbbf0ce32bfa43de609a0b3c6e4" + _get_repo feeds/packages https://github.com/openwrt/packages "33b6e611955693173f29038bf22fa2e496f460d2" + _get_repo feeds/luci https://github.com/openwrt/luci "32c833571435cf6ac30850315cdd4853ea5c914a" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" @@ -156,7 +157,7 @@ if [ -f "$OMR_TARGET_CONFIG" ]; then CONFIG_VERSIONOPT=y CONFIG_VERSION_DIST="$OMR_DIST" CONFIG_VERSION_REPO="$OMR_REPO" - CONFIG_VERSION_NUMBER="$(git -C "$OMR_FEED" describe --tag --always)" + CONFIG_VERSION_NUMBER="$(git -C "$OMR_FEED" describe --tags `git rev-list --tags --max-count=1`)-$(git rev-parse --short HEAD)" EOF else cat config -> "$OMR_TARGET/source/.config" <<-EOF @@ -164,7 +165,7 @@ else CONFIG_VERSIONOPT=y CONFIG_VERSION_DIST="$OMR_DIST" CONFIG_VERSION_REPO="$OMR_REPO" - CONFIG_VERSION_NUMBER="$(git -C "$OMR_FEED" describe --tag --always)" + CONFIG_VERSION_NUMBER="$(git -C "$OMR_FEED" describe --tags `git rev-list --tags --max-count=1`)-$(git rev-parse --short HEAD)" EOF fi if [ "$OMR_ALL_PACKAGES" = "yes" ]; then From e9157c7828525fe696253f5f9aaac131ea23ed67 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Fri, 18 Sep 2020 17:31:27 +0200 Subject: [PATCH 17/27] Fix version number --- build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 3e96af9f..39601201 100755 --- a/build.sh +++ b/build.sh @@ -157,7 +157,7 @@ if [ -f "$OMR_TARGET_CONFIG" ]; then CONFIG_VERSIONOPT=y CONFIG_VERSION_DIST="$OMR_DIST" CONFIG_VERSION_REPO="$OMR_REPO" - CONFIG_VERSION_NUMBER="$(git -C "$OMR_FEED" describe --tags `git rev-list --tags --max-count=1`)-$(git rev-parse --short HEAD)" + CONFIG_VERSION_NUMBER="$(git -C "$OMR_FEED" tag --sort=committerdate | tail -1)-$(git -C "$OMR_FEED" rev-parse --short HEAD)" EOF else cat config -> "$OMR_TARGET/source/.config" <<-EOF @@ -165,7 +165,7 @@ else CONFIG_VERSIONOPT=y CONFIG_VERSION_DIST="$OMR_DIST" CONFIG_VERSION_REPO="$OMR_REPO" - CONFIG_VERSION_NUMBER="$(git -C "$OMR_FEED" describe --tags `git rev-list --tags --max-count=1`)-$(git rev-parse --short HEAD)" + CONFIG_VERSION_NUMBER="$(git -C "$OMR_FEED" tag --sort=committerdate | tail -1)-$(git -C "$OMR_FEED" rev-parse --short HEAD)" EOF fi if [ "$OMR_ALL_PACKAGES" = "yes" ]; then From db27abcc82ec0da72c7c9a195e80df7dc134dfd0 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 22 Sep 2020 15:07:54 +0200 Subject: [PATCH 18/27] Update OpenWrt and fix ipq compilation --- build.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/build.sh b/build.sh index 39601201..12ee8334 100755 --- a/build.sh +++ b/build.sh @@ -71,9 +71,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "14247c82c0c64bbbf0ce32bfa43de609a0b3c6e4" - _get_repo feeds/packages https://github.com/openwrt/packages "33b6e611955693173f29038bf22fa2e496f460d2" - _get_repo feeds/luci https://github.com/openwrt/luci "32c833571435cf6ac30850315cdd4853ea5c914a" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "d643b10a76965a94684012d2ddf36e2bcc146274" + _get_repo feeds/packages https://github.com/openwrt/packages "0daa9fb1dd48ee63024a5fc24dd3c85e112f7ed6" + _get_repo feeds/luci https://github.com/openwrt/luci "4f6c054d7a468b980538461ede1da40789af4d46" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" @@ -89,7 +89,7 @@ if [ -z "$OMR_FEED" ]; then _get_repo "$OMR_FEED" "$OMR_FEED_URL" "$OMR_FEED_SRC" fi -if [ -n "$CUSTOM_FEED_URL" ]; then +if [ -n "$CUSTOM_FEED_URL" ] && [ -z "$CUSTOM_FEED" ]; then CUSTOM_FEED=feeds/${OMR_DIST} _get_repo "$CUSTOM_FEED" "$CUSTOM_FEED_URL" "master" fi @@ -259,6 +259,10 @@ if [ -f target/linux/mediatek/patches-5.4/0999-hnat.patch ]; then rm -f target/linux/mediatek/patches-5.4/0999-hnat.patch fi +if [ -f target/linux/ipq40xx/patches-5.4/100-GPIO-add-named-gpio-exports.patch ]; then + rm -f target/linux/ipq40xx/patches-5.4/100-GPIO-add-named-gpio-exports.patch +fi + #echo "Patch protobuf wrong hash" #patch -N -R -p1 -s < ../../patches/protobuf_hash.patch #echo "Done" From 6083c17a6352310a12d88664cc8abf4927cb998d Mon Sep 17 00:00:00 2001 From: suyuan <175338101@qq.com> Date: Wed, 23 Sep 2020 15:49:05 +0800 Subject: [PATCH 19/27] =?UTF-8?q?=E4=BF=AE=E5=A4=8DCM520=E7=9A=84op?= =?UTF-8?q?=E5=90=AF=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 32 +- config | 44 +- config-cm520-79f | 6 + .../base-files/files/bin/config_generate | 99 +- .../files/etc/board.d/99-default_network | 1 + .../net/ethernet/qualcomm/essedma/Makefile | 9 + .../net/ethernet/qualcomm/essedma/edma.c | 2177 +++++++++++++++++ .../net/ethernet/qualcomm/essedma/edma.h | 455 ++++ .../net/ethernet/qualcomm/essedma/edma_axi.c | 1359 ++++++++++ .../ethernet/qualcomm/essedma/edma_ethtool.c | 384 +++ .../net/ethernet/qualcomm/essedma/ess_edma.h | 389 +++ .../arm/boot/dts/qcom-ipq4019-cm520-79f.dts | 300 +++ 12 files changed, 5179 insertions(+), 76 deletions(-) create mode 100644 config-cm520-79f create mode 100644 root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/Makefile create mode 100644 root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.c create mode 100644 root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.h create mode 100644 root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_axi.c create mode 100644 root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_ethtool.c create mode 100644 root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/ess_edma.h create mode 100644 root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-cm520-79f.dts diff --git a/.gitignore b/.gitignore index 4bd7ccf9..2d93d211 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,29 @@ -sdk -source -feeds +*.o +.DS_Store +.*.swp +/env +/dl +/.config +/.config.old +/bin +/build_dir +/staging_dir +/tmp +/logs +/feeds +/feeds.conf +/files +/overlay +/package/feeds +/package/openwrt-packages +key-build* +*.orig +*.rej +*~ +.#* +*# +.emacs.desktop* +TAGS*~ +git-src +.git-credentials +/*.log diff --git a/config b/config index c40719ef..51f452ab 100644 --- a/config +++ b/config @@ -38,7 +38,7 @@ CONFIG_BUSYBOX_CONFIG_WATCH=y # CONFIG_GDB is not set CONFIG_GRUB_SERIAL="" CONFIG_GRUB_TIMEOUT="0" -CONFIG_GRUB_TITLE="OpenMPTCProuter" +CONFIG_GRUB_TITLE="antrouter" CONFIG_KERNEL_AIO=y CONFIG_KERNEL_DEBUG_GPIO=y # CONFIG_KERNEL_DEBUG_INFO is not set @@ -206,43 +206,23 @@ CONFIG_KERNEL_MPTCP_REDUNDANT=y CONFIG_KERNEL_DEFAULT_SCHEDULER=y CONFIG_KERNEL_MPTCP=y CONFIG_KERNEL_CRYPTO_SHA256=y -CONFIG_LUCI_LANG_hu=y -CONFIG_LUCI_LANG_pt=y -CONFIG_LUCI_LANG_sk=y -CONFIG_LUCI_LANG_ro=y -CONFIG_LUCI_LANG_en=y -CONFIG_LUCI_LANG_pl=y -CONFIG_LUCI_LANG_uk=y -CONFIG_LUCI_LANG_ja=y -CONFIG_LUCI_LANG_vi=y -CONFIG_LUCI_LANG_de=y -CONFIG_LUCI_LANG_no=y -CONFIG_LUCI_LANG_ms=y CONFIG_LUCI_LANG_zh_Hans=y CONFIG_LUCI_LANG_zh_Hant=y -CONFIG_LUCI_LANG_ko=y -CONFIG_LUCI_LANG_he=y CONFIG_LUCI_LANG_zh-tw=y -CONFIG_LUCI_LANG_tr=y -CONFIG_LUCI_LANG_sv=y -CONFIG_LUCI_LANG_ru=y -CONFIG_LUCI_LANG_el=y -CONFIG_LUCI_LANG_ca=y -CONFIG_LUCI_LANG_es=y -CONFIG_LUCI_LANG_pt_BR=y -CONFIG_LUCI_LANG_cs=y -CONFIG_LUCI_LANG_fr=y -CONFIG_LUCI_LANG_it=y -CONFIG_LUCI_LANG_ar=y -CONFIG_LUCI_LANG_bg=y -CONFIG_LUCI_LANG_bn_BD=y -CONFIG_LUCI_LANG_fi=y -CONFIG_LUCI_LANG_hi=y -CONFIG_LUCI_LANG_mr=y -CONFIG_LUCI_LANG_nb_NO=y CONFIG_TARGET_ROOTFS_PARTSIZE=512 CONFIG_TARGET_KERNEL_PARTSIZE=64 CONFIG_OPENSSL_WITH_CHACHA_POLY1305=y # CONFIG_LUCI_CSSTIDY is not set # CONFIG_LIBCURL_WOLFSSL is not set # CONFIG_PACKAGE_libustream-wolfssl is not set +# CONFIG_PACKAGE_luci-theme-argon=y +CONFIG_PACKAGE_luci-theme-bootstrap=y +CONFIG_PACKAGE_luci-theme-openwrt-2020=y +# CONFIG_PACKAGE_luci-theme-argon is not set +CONFIG_PACKAGE_luci-app-status=m +CONFIG_PACKAGE_luci-mod-status=y +CONFIG_PACKAGE_frpc=y +CONFIG_PACKAGE_rtty-nossl=y +CONFIG_PACKAGE_minicom=y +CONFIG_PACKAGE_irqbalance=y +CONFIG_PACKAGE_mtr=y \ No newline at end of file diff --git a/config-cm520-79f b/config-cm520-79f new file mode 100644 index 00000000..d37328a9 --- /dev/null +++ b/config-cm520-79f @@ -0,0 +1,6 @@ +CONFIG_TARGET_ipq40xx=y +CONFIG_TARGET_ipq40xx_generic=y +CONFIG_TARGET_ipq40xx_generic_DEVICE_mobipromo_cm520-79f=y +CONFIG_PACKAGE_kmod-6lowpan=y +# CONFIG_KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE is not set +CONFIG_KERNEL_CC_OPTIMIZE_FOR_SIZE=y diff --git a/root/package/base-files/files/bin/config_generate b/root/package/base-files/files/bin/config_generate index 1deda8e2..b8665f26 100755 --- a/root/package/base-files/files/bin/config_generate +++ b/root/package/base-files/files/bin/config_generate @@ -15,17 +15,21 @@ generate_static_network() { set network.loopback.proto='static' set network.loopback.ipaddr='127.0.0.1' set network.loopback.netmask='255.0.0.0' - delete network.globals - set network.globals='globals' - set network.globals.ula_prefix='auto' EOF + [ -e /proc/sys/net/ipv6 ] && { + uci -q batch <<-EOF + delete network.globals + set network.globals='globals' + set network.globals.ula_prefix='auto' + EOF + } if json_is_a dsl object; then json_select dsl if json_is_a atmbridge object; then json_select atmbridge - local vpi vci encaps payload - json_get_vars vpi vci encaps payload + local vpi vci encaps payload nameprefix + json_get_vars vpi vci encaps payload nameprefix uci -q batch <<-EOF delete network.atm set network.atm='atm-bridge' @@ -33,6 +37,7 @@ generate_static_network() { set network.atm.vci='$vci' set network.atm.encaps='$encaps' set network.atm.payload='$payload' + set network.atm.nameprefix='$nameprefix' EOF json_select .. fi @@ -67,26 +72,11 @@ generate_network() { [ -n "$ifname" ] || return - case "$1" in - # hack (see /etc/board.d/02_network) - none) return ;; - lan*) proto=${proto:-static} ;; - wan*) proto=${proto:-dhcp} ;; + # force bridge for multi-interface devices (and lan) + case "$1:$ifname" in + *\ * | lan:*) type="bridge" ;; esac - if [ -n "$macaddr" ]; then - type=macvlan # useless, only for legacy - uci -q batch <<-EOF - delete network.${1}_dev - set network.${1}_dev='device' - set network.${1}_dev.name='$1' - set network.${1}_dev.type='$type' - set network.${1}_dev.ifname='$ifname' - set network.${1}_dev.macaddr='$macaddr' - EOF - ifname=$1 - fi - uci -q batch <<-EOF delete network.$1 set network.$1='interface' @@ -95,11 +85,22 @@ generate_network() { set network.$1.proto='none' EOF + if [ -n "$macaddr" ]; then + for name in $ifname; do + uci -q batch <<-EOF + delete network.$1_${name/./_}_dev + set network.$1_${name/./_}_dev='device' + set network.$1_${name/./_}_dev.name='$name' + set network.$1_${name/./_}_dev.macaddr='$macaddr' + EOF + done + fi + case "$protocol" in static) local ipad case "$1" in - lan) ipad=${ipaddr:-"192.168.100.1"} ;; + lan) ipad=${ipaddr:-"192.168.1.1"} ;; *) ipad=${ipaddr:-"192.168.$((addr_offset++)).1"} ;; esac @@ -109,17 +110,23 @@ generate_network() { set network.$1.proto='static' set network.$1.ipaddr='$ipad' set network.$1.netmask='$netm' - set network.$1.ip6assign='60' EOF + [ -e /proc/sys/net/ipv6 ] && uci set network.$1.ip6assign='60' ;; dhcp) # fixup IPv6 slave interface if parent is a bridge [ "$type" = "bridge" ] && ifname="br-$1" - uci -q batch <<-EOF - set network.$1.proto='dhcp' - EOF + uci set network.$1.proto='dhcp' + [ -e /proc/sys/net/ipv6 ] && { + uci -q batch <<-EOF + delete network.${1}6 + set network.${1}6='interface' + set network.${1}6.ifname='$ifname' + set network.${1}6.proto='dhcpv6' + EOF + } ;; pppoe) @@ -127,12 +134,16 @@ generate_network() { set network.$1.proto='pppoe' set network.$1.username='username' set network.$1.password='password' - set network.$1.ipv6='1' - delete network.${1}6 - set network.${1}6='interface' - set network.${1}6.ifname='@${1}' - set network.${1}6.proto='dhcpv6' EOF + [ -e /proc/sys/net/ipv6 ] && { + uci -q batch <<-EOF + set network.$1.ipv6='1' + delete network.${1}6 + set network.${1}6='interface' + set network.${1}6.ifname='@${1}' + set network.${1}6.proto='dhcpv6' + EOF + } ;; esac } @@ -206,7 +217,8 @@ generate_switch() { json_select switch json_select "$key" - json_get_vars enable reset blinkrate cpu_port + json_get_vars enable reset blinkrate cpu_port \ + ar8xxx_mib_type ar8xxx_mib_poll_interval uci -q batch <<-EOF add network switch @@ -214,6 +226,8 @@ generate_switch() { set network.@switch[-1].reset='$reset' set network.@switch[-1].enable_vlan='$enable' set network.@switch[-1].blinkrate='$blinkrate' + set network.@switch[-1].ar8xxx_mib_type='$ar8xxx_mib_type' + set network.@switch[-1].ar8xxx_mib_poll_interval='$ar8xxx_mib_poll_interval' EOF generate_switch_vlans_ports "$1" @@ -227,7 +241,7 @@ generate_static_system() { uci -q batch <<-EOF delete system.@system[0] add system system - set system.@system[-1].hostname='OpenMPTCProuter' + set system.@system[-1].hostname='OpenWrt' set system.@system[-1].timezone='UTC' set system.@system[-1].ttylogin='0' set system.@system[-1].log_size='64' @@ -237,10 +251,10 @@ generate_static_system() { set system.ntp='timeserver' set system.ntp.enabled='1' set system.ntp.enable_server='0' - add_list system.ntp.server='0.openwrt.pool.ntp.org' - add_list system.ntp.server='1.openwrt.pool.ntp.org' - add_list system.ntp.server='2.openwrt.pool.ntp.org' - add_list system.ntp.server='3.openwrt.pool.ntp.org' + add_list system.ntp.server='ntp1.aliyun.com' + add_list system.ntp.server='time1.cloud.tencent.com' + add_list system.ntp.server='time.ustc.edu.cn' + add_list system.ntp.server='cn.pool.ntp.org' EOF if json_is_a system object; then @@ -359,11 +373,12 @@ generate_led() { ;; switch) - local port_mask speed_mask - json_get_vars port_mask speed_mask + local port_mask speed_mask mode + json_get_vars port_mask speed_mask mode uci -q batch <<-EOF set system.$cfg.port_mask='$port_mask' set system.$cfg.speed_mask='$speed_mask' + set system.$cfg.mode='$mode' EOF ;; @@ -411,6 +426,8 @@ generate_gpioswitch() { json_init json_load "$(cat ${CFG})" +umask 077 + if [ ! -s /etc/config/network ]; then touch /etc/config/network generate_static_network diff --git a/root/package/base-files/files/etc/board.d/99-default_network b/root/package/base-files/files/etc/board.d/99-default_network index 55d5d79a..d70aa352 100755 --- a/root/package/base-files/files/etc/board.d/99-default_network +++ b/root/package/base-files/files/etc/board.d/99-default_network @@ -10,6 +10,7 @@ board_config_update json_is_a network object && exit 0 ucidef_set_interface_lan 'eth0' +[ -d /sys/class/net/eth1 ] && ucidef_set_interface_wan 'eth1' board_config_flush diff --git a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/Makefile b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/Makefile new file mode 100644 index 00000000..4e6cd650 --- /dev/null +++ b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/Makefile @@ -0,0 +1,9 @@ +# +## Makefile for the Qualcomm Atheros ethernet edma driver +# + + +obj-$(CONFIG_ESSEDMA) += essedma.o + +essedma-objs := edma_axi.o edma.o edma_ethtool.o + diff --git a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.c b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.c new file mode 100644 index 00000000..5561cc23 --- /dev/null +++ b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.c @@ -0,0 +1,2177 @@ +/* + * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include "ess_edma.h" +#include "edma.h" + +extern struct net_device *edma_netdev[EDMA_MAX_PORTID_SUPPORTED]; +bool edma_stp_rstp; +u16 edma_ath_eth_type; + +/* edma_skb_priority_offset() + * get edma skb priority + */ +static unsigned int edma_skb_priority_offset(struct sk_buff *skb) +{ + return (skb->priority >> 2) & 1; +} + +/* edma_alloc_tx_ring() + * Allocate Tx descriptors ring + */ +static int edma_alloc_tx_ring(struct edma_common_info *edma_cinfo, + struct edma_tx_desc_ring *etdr) +{ + struct platform_device *pdev = edma_cinfo->pdev; + + /* Initialize ring */ + etdr->size = sizeof(struct edma_sw_desc) * etdr->count; + etdr->sw_next_to_fill = 0; + etdr->sw_next_to_clean = 0; + + /* Allocate SW descriptors */ + etdr->sw_desc = vzalloc(etdr->size); + if (!etdr->sw_desc) { + dev_err(&pdev->dev, "buffer alloc of tx ring failed=%p", etdr); + return -ENOMEM; + } + + /* Allocate HW descriptors */ + etdr->hw_desc = dma_alloc_coherent(&pdev->dev, etdr->size, &etdr->dma, + GFP_KERNEL); + if (!etdr->hw_desc) { + dev_err(&pdev->dev, "descriptor allocation for tx ring failed"); + vfree(etdr->sw_desc); + return -ENOMEM; + } + + return 0; +} + +/* edma_free_tx_ring() + * Free tx rings allocated by edma_alloc_tx_rings + */ +static void edma_free_tx_ring(struct edma_common_info *edma_cinfo, + struct edma_tx_desc_ring *etdr) +{ + struct platform_device *pdev = edma_cinfo->pdev; + + if (likely(etdr->dma)) + dma_free_coherent(&pdev->dev, etdr->size, etdr->hw_desc, + etdr->dma); + + vfree(etdr->sw_desc); + etdr->sw_desc = NULL; +} + +/* edma_alloc_rx_ring() + * allocate rx descriptor ring + */ +static int edma_alloc_rx_ring(struct edma_common_info *edma_cinfo, + struct edma_rfd_desc_ring *erxd) +{ + struct platform_device *pdev = edma_cinfo->pdev; + + erxd->size = sizeof(struct edma_sw_desc) * erxd->count; + erxd->sw_next_to_fill = 0; + erxd->sw_next_to_clean = 0; + + /* Allocate SW descriptors */ + erxd->sw_desc = vzalloc(erxd->size); + if (!erxd->sw_desc) + return -ENOMEM; + + /* Alloc HW descriptors */ + erxd->hw_desc = dma_alloc_coherent(&pdev->dev, erxd->size, &erxd->dma, + GFP_KERNEL); + if (!erxd->hw_desc) { + vfree(erxd->sw_desc); + return -ENOMEM; + } + + /* Initialize pending_fill */ + erxd->pending_fill = 0; + + return 0; +} + +/* edma_free_rx_ring() + * Free rx ring allocated by alloc_rx_ring + */ +static void edma_free_rx_ring(struct edma_common_info *edma_cinfo, + struct edma_rfd_desc_ring *rxdr) +{ + struct platform_device *pdev = edma_cinfo->pdev; + + if (likely(rxdr->dma)) + dma_free_coherent(&pdev->dev, rxdr->size, rxdr->hw_desc, + rxdr->dma); + + vfree(rxdr->sw_desc); + rxdr->sw_desc = NULL; +} + +/* edma_configure_tx() + * Configure transmission control data + */ +static void edma_configure_tx(struct edma_common_info *edma_cinfo) +{ + u32 txq_ctrl_data; + + txq_ctrl_data = (EDMA_TPD_BURST << EDMA_TXQ_NUM_TPD_BURST_SHIFT); + txq_ctrl_data |= EDMA_TXQ_CTRL_TPD_BURST_EN; + txq_ctrl_data |= (EDMA_TXF_BURST << EDMA_TXQ_TXF_BURST_NUM_SHIFT); + edma_write_reg(EDMA_REG_TXQ_CTRL, txq_ctrl_data); +} + + +/* edma_configure_rx() + * configure reception control data + */ +static void edma_configure_rx(struct edma_common_info *edma_cinfo) +{ + struct edma_hw *hw = &edma_cinfo->hw; + u32 rss_type, rx_desc1, rxq_ctrl_data; + + /* Set RSS type */ + rss_type = hw->rss_type; + edma_write_reg(EDMA_REG_RSS_TYPE, rss_type); + + /* Set RFD burst number */ + rx_desc1 = (EDMA_RFD_BURST << EDMA_RXQ_RFD_BURST_NUM_SHIFT); + + /* Set RFD prefetch threshold */ + rx_desc1 |= (EDMA_RFD_THR << EDMA_RXQ_RFD_PF_THRESH_SHIFT); + + /* Set RFD in host ring low threshold to generte interrupt */ + rx_desc1 |= (EDMA_RFD_LTHR << EDMA_RXQ_RFD_LOW_THRESH_SHIFT); + edma_write_reg(EDMA_REG_RX_DESC1, rx_desc1); + + /* Set Rx FIFO threshold to start to DMA data to host */ + rxq_ctrl_data = EDMA_FIFO_THRESH_128_BYTE; + + if (!edma_cinfo->is_single_phy) { + /* Set RX remove vlan bit */ + rxq_ctrl_data |= EDMA_RXQ_CTRL_RMV_VLAN; + } + + edma_write_reg(EDMA_REG_RXQ_CTRL, rxq_ctrl_data); +} + +/* edma_alloc_rx_buf() + * does skb allocation for the received packets. + */ +static int edma_alloc_rx_buf(struct edma_common_info + *edma_cinfo, + struct edma_rfd_desc_ring *erdr, + int cleaned_count, int queue_id) +{ + struct platform_device *pdev = edma_cinfo->pdev; + struct edma_rx_free_desc *rx_desc; + struct edma_sw_desc *sw_desc; + struct sk_buff *skb; + unsigned int i; + u16 prod_idx, length; + u32 reg_data; + + if (cleaned_count > erdr->count) + cleaned_count = erdr->count - 1; + + i = erdr->sw_next_to_fill; + + while (cleaned_count) { + sw_desc = &erdr->sw_desc[i]; + length = edma_cinfo->rx_head_buffer_len; + + if (sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_REUSE) { + skb = sw_desc->skb; + + /* Clear REUSE Flag */ + sw_desc->flags &= ~EDMA_SW_DESC_FLAG_SKB_REUSE; + } else { + /* alloc skb */ + skb = netdev_alloc_skb_ip_align(edma_netdev[0], length); + if (!skb) { + /* Better luck next round */ + break; + } + } + + if (edma_cinfo->page_mode) { + struct page *pg = alloc_page(GFP_ATOMIC); + + if (!pg) { + dev_kfree_skb_any(skb); + break; + } + + sw_desc->dma = dma_map_page(&pdev->dev, pg, 0, + edma_cinfo->rx_page_buffer_len, + DMA_FROM_DEVICE); + if (dma_mapping_error(&pdev->dev, + sw_desc->dma)) { + __free_page(pg); + dev_kfree_skb_any(skb); + break; + } + + skb_fill_page_desc(skb, 0, pg, 0, + edma_cinfo->rx_page_buffer_len); + sw_desc->flags = EDMA_SW_DESC_FLAG_SKB_FRAG; + sw_desc->length = edma_cinfo->rx_page_buffer_len; + } else { + sw_desc->dma = dma_map_single(&pdev->dev, skb->data, + length, DMA_FROM_DEVICE); + if (dma_mapping_error(&pdev->dev, + sw_desc->dma)) { + dev_kfree_skb_any(skb); + break; + } + + sw_desc->flags = EDMA_SW_DESC_FLAG_SKB_HEAD; + sw_desc->length = length; + } + + /* Update the buffer info */ + sw_desc->skb = skb; + rx_desc = (&((struct edma_rx_free_desc *)(erdr->hw_desc))[i]); + rx_desc->buffer_addr = cpu_to_le64(sw_desc->dma); + if (++i == erdr->count) + i = 0; + cleaned_count--; + } + + erdr->sw_next_to_fill = i; + + if (i == 0) + prod_idx = erdr->count - 1; + else + prod_idx = i - 1; + + /* Update the producer index */ + edma_read_reg(EDMA_REG_RFD_IDX_Q(queue_id), ®_data); + reg_data &= ~EDMA_RFD_PROD_IDX_BITS; + reg_data |= prod_idx; + edma_write_reg(EDMA_REG_RFD_IDX_Q(queue_id), reg_data); + + /* If we couldn't allocate all the buffers + * we increment the alloc failure counters + */ + if (cleaned_count) + edma_cinfo->edma_ethstats.rx_alloc_fail_ctr++; + + return cleaned_count; +} + +/* edma_init_desc() + * update descriptor ring size, buffer and producer/consumer index + */ +static void edma_init_desc(struct edma_common_info *edma_cinfo) +{ + struct edma_rfd_desc_ring *rfd_ring; + struct edma_tx_desc_ring *etdr; + int i = 0, j = 0; + u32 data = 0; + u16 hw_cons_idx = 0; + + /* Set the base address of every TPD ring. */ + for (i = 0; i < edma_cinfo->num_tx_queues; i++) { + etdr = edma_cinfo->tpd_ring[i]; + + /* Update descriptor ring base address */ + edma_write_reg(EDMA_REG_TPD_BASE_ADDR_Q(i), (u32)etdr->dma); + edma_read_reg(EDMA_REG_TPD_IDX_Q(i), &data); + + /* Calculate hardware consumer index */ + hw_cons_idx = (data >> EDMA_TPD_CONS_IDX_SHIFT) & 0xffff; + etdr->sw_next_to_fill = hw_cons_idx; + etdr->sw_next_to_clean = hw_cons_idx; + data &= ~(EDMA_TPD_PROD_IDX_MASK << EDMA_TPD_PROD_IDX_SHIFT); + data |= hw_cons_idx; + + /* update producer index */ + edma_write_reg(EDMA_REG_TPD_IDX_Q(i), data); + + /* update SW consumer index register */ + edma_write_reg(EDMA_REG_TX_SW_CONS_IDX_Q(i), hw_cons_idx); + + /* Set TPD ring size */ + edma_write_reg(EDMA_REG_TPD_RING_SIZE, + edma_cinfo->tx_ring_count & + EDMA_TPD_RING_SIZE_MASK); + } + + for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { + rfd_ring = edma_cinfo->rfd_ring[j]; + /* Update Receive Free descriptor ring base address */ + edma_write_reg(EDMA_REG_RFD_BASE_ADDR_Q(j), + (u32)(rfd_ring->dma)); + j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); + } + + data = edma_cinfo->rx_head_buffer_len; + if (edma_cinfo->page_mode) + data = edma_cinfo->rx_page_buffer_len; + + data &= EDMA_RX_BUF_SIZE_MASK; + data <<= EDMA_RX_BUF_SIZE_SHIFT; + + /* Update RFD ring size and RX buffer size */ + data |= (edma_cinfo->rx_ring_count & EDMA_RFD_RING_SIZE_MASK) + << EDMA_RFD_RING_SIZE_SHIFT; + + edma_write_reg(EDMA_REG_RX_DESC0, data); + + /* Disable TX FIFO low watermark and high watermark */ + edma_write_reg(EDMA_REG_TXF_WATER_MARK, 0); + + /* Load all of base address above */ + edma_read_reg(EDMA_REG_TX_SRAM_PART, &data); + data |= 1 << EDMA_LOAD_PTR_SHIFT; + edma_write_reg(EDMA_REG_TX_SRAM_PART, data); +} + +/* edma_receive_checksum + * Api to check checksum on receive packets + */ +static void edma_receive_checksum(struct edma_rx_return_desc *rd, + struct sk_buff *skb) +{ + skb_checksum_none_assert(skb); + + /* check the RRD IP/L4 checksum bit to see if + * its set, which in turn indicates checksum + * failure. + */ + if (rd->rrd6 & EDMA_RRD_CSUM_FAIL_MASK) + return; + + skb->ip_summed = CHECKSUM_UNNECESSARY; +} + +/* edma_clean_rfd() + * clean up rx resourcers on error + */ +static void edma_clean_rfd(struct edma_rfd_desc_ring *erdr, u16 index) +{ + struct edma_rx_free_desc *rx_desc; + struct edma_sw_desc *sw_desc; + + rx_desc = (&((struct edma_rx_free_desc *)(erdr->hw_desc))[index]); + sw_desc = &erdr->sw_desc[index]; + if (sw_desc->skb) { + dev_kfree_skb_any(sw_desc->skb); + sw_desc->skb = NULL; + } + + memset(rx_desc, 0, sizeof(struct edma_rx_free_desc)); +} + +/* edma_rx_complete_fraglist() + * Complete Rx processing for fraglist skbs + */ +static void edma_rx_complete_stp_rstp(struct sk_buff *skb, int port_id, struct edma_rx_return_desc *rd) +{ + int i; + u32 priority; + u16 port_type; + u8 mac_addr[EDMA_ETH_HDR_LEN]; + + port_type = (rd->rrd1 >> EDMA_RRD_PORT_TYPE_SHIFT) + & EDMA_RRD_PORT_TYPE_MASK; + /* if port type is 0x4, then only proceed with + * other stp/rstp calculation + */ + if (port_type == EDMA_RX_ATH_HDR_RSTP_PORT_TYPE) { + u8 bpdu_mac[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00}; + + /* calculate the frame priority */ + priority = (rd->rrd1 >> EDMA_RRD_PRIORITY_SHIFT) + & EDMA_RRD_PRIORITY_MASK; + + for (i = 0; i < EDMA_ETH_HDR_LEN; i++) + mac_addr[i] = skb->data[i]; + + /* Check if destination mac addr is bpdu addr */ + if (!memcmp(mac_addr, bpdu_mac, 6)) { + /* destination mac address is BPDU + * destination mac address, then add + * atheros header to the packet. + */ + u16 athr_hdr = (EDMA_RX_ATH_HDR_VERSION << EDMA_RX_ATH_HDR_VERSION_SHIFT) | + (priority << EDMA_RX_ATH_HDR_PRIORITY_SHIFT) | + (EDMA_RX_ATH_HDR_RSTP_PORT_TYPE << EDMA_RX_ATH_PORT_TYPE_SHIFT) | port_id; + skb_push(skb, 4); + memcpy(skb->data, mac_addr, EDMA_ETH_HDR_LEN); + *(uint16_t *)&skb->data[12] = htons(edma_ath_eth_type); + *(uint16_t *)&skb->data[14] = htons(athr_hdr); + } + } +} + +/* + * edma_rx_complete_fraglist() + * Complete Rx processing for fraglist skbs + */ +static int edma_rx_complete_fraglist(struct sk_buff *skb, u16 num_rfds, u16 length, u32 sw_next_to_clean, + u16 *cleaned_count, struct edma_rfd_desc_ring *erdr, struct edma_common_info *edma_cinfo) +{ + struct platform_device *pdev = edma_cinfo->pdev; + struct edma_hw *hw = &edma_cinfo->hw; + struct sk_buff *skb_temp; + struct edma_sw_desc *sw_desc; + int i; + u16 size_remaining; + + skb->data_len = 0; + skb->tail += (hw->rx_head_buff_size - 16); + skb->len = skb->truesize = length; + size_remaining = length - (hw->rx_head_buff_size - 16); + + /* clean-up all related sw_descs */ + for (i = 1; i < num_rfds; i++) { + struct sk_buff *skb_prev; + sw_desc = &erdr->sw_desc[sw_next_to_clean]; + skb_temp = sw_desc->skb; + + dma_unmap_single(&pdev->dev, sw_desc->dma, + sw_desc->length, DMA_FROM_DEVICE); + + if (size_remaining < hw->rx_head_buff_size) + skb_put(skb_temp, size_remaining); + else + skb_put(skb_temp, hw->rx_head_buff_size); + + /* + * If we are processing the first rfd, we link + * skb->frag_list to the skb corresponding to the + * first RFD + */ + if (i == 1) + skb_shinfo(skb)->frag_list = skb_temp; + else + skb_prev->next = skb_temp; + skb_prev = skb_temp; + skb_temp->next = NULL; + + skb->data_len += skb_temp->len; + size_remaining -= skb_temp->len; + + /* Increment SW index */ + sw_next_to_clean = (sw_next_to_clean + 1) & (erdr->count - 1); + (*cleaned_count)++; + } + + return sw_next_to_clean; +} + +/* edma_rx_complete_paged() + * Complete Rx processing for paged skbs + */ +static int edma_rx_complete_paged(struct sk_buff *skb, u16 num_rfds, u16 length, u32 sw_next_to_clean, + u16 *cleaned_count, struct edma_rfd_desc_ring *erdr, struct edma_common_info *edma_cinfo) +{ + struct platform_device *pdev = edma_cinfo->pdev; + struct sk_buff *skb_temp; + struct edma_sw_desc *sw_desc; + int i; + u16 size_remaining; + + skb_frag_t *frag = &skb_shinfo(skb)->frags[0]; + + /* Setup skbuff fields */ + skb->len = length; + + if (likely(num_rfds <= 1)) { + skb->data_len = length; + skb->truesize += edma_cinfo->rx_page_buffer_len; + skb_fill_page_desc(skb, 0, skb_frag_page(frag), + 16, length); + } else { + skb_frag_size_sub(frag, 16); + skb->data_len = skb_frag_size(frag); + skb->truesize += edma_cinfo->rx_page_buffer_len; + size_remaining = length - skb_frag_size(frag); + + skb_fill_page_desc(skb, 0, skb_frag_page(frag), + 16, skb_frag_size(frag)); + + /* clean-up all related sw_descs */ + for (i = 1; i < num_rfds; i++) { + sw_desc = &erdr->sw_desc[sw_next_to_clean]; + skb_temp = sw_desc->skb; + frag = &skb_shinfo(skb_temp)->frags[0]; + dma_unmap_page(&pdev->dev, sw_desc->dma, + sw_desc->length, DMA_FROM_DEVICE); + + if (size_remaining < edma_cinfo->rx_page_buffer_len) + skb_frag_size_set(frag, size_remaining); + + skb_fill_page_desc(skb, i, skb_frag_page(frag), + 0, skb_frag_size(frag)); + + skb_shinfo(skb_temp)->nr_frags = 0; + dev_kfree_skb_any(skb_temp); + + skb->data_len += skb_frag_size(frag); + skb->truesize += edma_cinfo->rx_page_buffer_len; + size_remaining -= skb_frag_size(frag); + + /* Increment SW index */ + sw_next_to_clean = (sw_next_to_clean + 1) & (erdr->count - 1); + (*cleaned_count)++; + } + } + + return sw_next_to_clean; +} + +/* + * edma_rx_complete() + * Main api called from the poll function to process rx packets. + */ +static u16 edma_rx_complete(struct edma_common_info *edma_cinfo, + int *work_done, int work_to_do, int queue_id, + struct napi_struct *napi) +{ + struct platform_device *pdev = edma_cinfo->pdev; + struct edma_rfd_desc_ring *erdr = edma_cinfo->rfd_ring[queue_id]; + struct net_device *netdev; + struct edma_adapter *adapter; + struct edma_sw_desc *sw_desc; + struct sk_buff *skb; + struct edma_rx_return_desc *rd; + u16 hash_type, rrd[8], cleaned_count = 0, length = 0, num_rfds = 1, + sw_next_to_clean, hw_next_to_clean = 0, vlan = 0, ret_count = 0; + u32 data = 0; + u8 *vaddr; + int port_id, i, drop_count = 0; + u32 priority; + u16 count = erdr->count, rfd_avail; + u8 queue_to_rxid[8] = {0, 0, 1, 1, 2, 2, 3, 3}; + + cleaned_count = erdr->pending_fill; + sw_next_to_clean = erdr->sw_next_to_clean; + + edma_read_reg(EDMA_REG_RFD_IDX_Q(queue_id), &data); + hw_next_to_clean = (data >> EDMA_RFD_CONS_IDX_SHIFT) & + EDMA_RFD_CONS_IDX_MASK; + + do { + while (sw_next_to_clean != hw_next_to_clean) { + if (!work_to_do) + break; + + sw_desc = &erdr->sw_desc[sw_next_to_clean]; + skb = sw_desc->skb; + + /* Unmap the allocated buffer */ + if (likely(sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_HEAD)) + dma_unmap_single(&pdev->dev, sw_desc->dma, + sw_desc->length, DMA_FROM_DEVICE); + else + dma_unmap_page(&pdev->dev, sw_desc->dma, + sw_desc->length, DMA_FROM_DEVICE); + + /* Get RRD */ + if (edma_cinfo->page_mode) { + vaddr = kmap_atomic(skb_frag_page(&skb_shinfo(skb)->frags[0])); + memcpy((uint8_t *)&rrd[0], vaddr, 16); + rd = (struct edma_rx_return_desc *)rrd; + kunmap_atomic(vaddr); + } else { + rd = (struct edma_rx_return_desc *)skb->data; + } + + /* Check if RRD is valid */ + if (!(rd->rrd7 & EDMA_RRD_DESC_VALID)) { + edma_clean_rfd(erdr, sw_next_to_clean); + sw_next_to_clean = (sw_next_to_clean + 1) & + (erdr->count - 1); + cleaned_count++; + continue; + } + + /* Get the number of RFDs from RRD */ + num_rfds = rd->rrd1 & EDMA_RRD_NUM_RFD_MASK; + + /* Get Rx port ID from switch */ + port_id = (rd->rrd1 >> EDMA_PORT_ID_SHIFT) & EDMA_PORT_ID_MASK; + if ((!port_id) || (port_id > EDMA_MAX_PORTID_SUPPORTED)) { + dev_err(&pdev->dev, "Invalid RRD source port bit set"); + for (i = 0; i < num_rfds; i++) { + edma_clean_rfd(erdr, sw_next_to_clean); + sw_next_to_clean = (sw_next_to_clean + 1) & (erdr->count - 1); + cleaned_count++; + } + continue; + } + + /* check if we have a sink for the data we receive. + * If the interface isn't setup, we have to drop the + * incoming data for now. + */ + netdev = edma_cinfo->portid_netdev_lookup_tbl[port_id]; + if (!netdev) { + edma_clean_rfd(erdr, sw_next_to_clean); + sw_next_to_clean = (sw_next_to_clean + 1) & + (erdr->count - 1); + cleaned_count++; + continue; + } + adapter = netdev_priv(netdev); + + /* This code is added to handle a usecase where high + * priority stream and a low priority stream are + * received simultaneously on DUT. The problem occurs + * if one of the Rx rings is full and the corresponding + * core is busy with other stuff. This causes ESS CPU + * port to backpressure all incoming traffic including + * high priority one. We monitor free descriptor count + * on each CPU and whenever it reaches threshold (< 80), + * we drop all low priority traffic and let only high + * priotiy traffic pass through. We can hence avoid + * ESS CPU port to send backpressure on high priroity + * stream. + */ + priority = (rd->rrd1 >> EDMA_RRD_PRIORITY_SHIFT) + & EDMA_RRD_PRIORITY_MASK; + if (likely(!priority && !edma_cinfo->page_mode && (num_rfds <= 1))) { + rfd_avail = (count + sw_next_to_clean - hw_next_to_clean - 1) & (count - 1); + if (rfd_avail < EDMA_RFD_AVAIL_THR) { + sw_desc->flags = EDMA_SW_DESC_FLAG_SKB_REUSE; + sw_next_to_clean = (sw_next_to_clean + 1) & (erdr->count - 1); + adapter->stats.rx_dropped++; + cleaned_count++; + drop_count++; + if (drop_count == 3) { + work_to_do--; + (*work_done)++; + drop_count = 0; + } + if (cleaned_count >= EDMA_RX_BUFFER_WRITE) { + /* If buffer clean count reaches 16, we replenish HW buffers. */ + ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); + edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), + sw_next_to_clean); + cleaned_count = ret_count; + erdr->pending_fill = ret_count; + } + continue; + } + } + + work_to_do--; + (*work_done)++; + + /* Increment SW index */ + sw_next_to_clean = (sw_next_to_clean + 1) & + (erdr->count - 1); + + cleaned_count++; + + /* Get the packet size and allocate buffer */ + length = rd->rrd6 & EDMA_RRD_PKT_SIZE_MASK; + + if (edma_cinfo->page_mode) { + /* paged skb */ + sw_next_to_clean = edma_rx_complete_paged(skb, num_rfds, length, sw_next_to_clean, &cleaned_count, erdr, edma_cinfo); + if (!pskb_may_pull(skb, ETH_HLEN)) { + dev_kfree_skb_any(skb); + continue; + } + } else { + /* single or fraglist skb */ + + /* Addition of 16 bytes is required, as in the packet + * first 16 bytes are rrd descriptors, so actual data + * starts from an offset of 16. + */ + skb_reserve(skb, 16); + if (likely((num_rfds <= 1) || !edma_cinfo->fraglist_mode)) { + skb_put(skb, length); + } else { + sw_next_to_clean = edma_rx_complete_fraglist(skb, num_rfds, length, sw_next_to_clean, &cleaned_count, erdr, edma_cinfo); + } + } + + if (edma_stp_rstp) { + edma_rx_complete_stp_rstp(skb, port_id, rd); + } + + skb->protocol = eth_type_trans(skb, netdev); + + /* Record Rx queue for RFS/RPS and fill flow hash from HW */ + skb_record_rx_queue(skb, queue_to_rxid[queue_id]); + if (netdev->features & NETIF_F_RXHASH) { + hash_type = (rd->rrd5 >> EDMA_HASH_TYPE_SHIFT); + if ((hash_type > EDMA_HASH_TYPE_START) && (hash_type < EDMA_HASH_TYPE_END)) + skb_set_hash(skb, rd->rrd2, PKT_HASH_TYPE_L4); + } + +#ifdef CONFIG_NF_FLOW_COOKIE + skb->flow_cookie = rd->rrd3 & EDMA_RRD_FLOW_COOKIE_MASK; +#endif + edma_receive_checksum(rd, skb); + + /* Process VLAN HW acceleration indication provided by HW */ + if (unlikely(adapter->default_vlan_tag != rd->rrd4)) { + vlan = rd->rrd4; + if (likely(rd->rrd7 & EDMA_RRD_CVLAN)) + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan); + else if (rd->rrd1 & EDMA_RRD_SVLAN) + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021AD), vlan); + } + + /* Update rx statistics */ + adapter->stats.rx_packets++; + adapter->stats.rx_bytes += length; + + /* Check if we reached refill threshold */ + if (cleaned_count >= EDMA_RX_BUFFER_WRITE) { + ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); + edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), + sw_next_to_clean); + cleaned_count = ret_count; + erdr->pending_fill = ret_count; + } + + /* At this point skb should go to stack */ + napi_gro_receive(napi, skb); + } + + /* Check if we still have NAPI budget */ + if (!work_to_do) + break; + + /* Read index once again since we still have NAPI budget */ + edma_read_reg(EDMA_REG_RFD_IDX_Q(queue_id), &data); + hw_next_to_clean = (data >> EDMA_RFD_CONS_IDX_SHIFT) & + EDMA_RFD_CONS_IDX_MASK; + } while (hw_next_to_clean != sw_next_to_clean); + + erdr->sw_next_to_clean = sw_next_to_clean; + + /* Refill here in case refill threshold wasn't reached */ + if (likely(cleaned_count)) { + ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); + erdr->pending_fill = ret_count; + if (ret_count) { + if (net_ratelimit()) + dev_dbg(&pdev->dev, "Not all buffers was reallocated"); + } + + edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), + erdr->sw_next_to_clean); + } + + return erdr->pending_fill; +} + +/* edma_delete_rfs_filter() + * Remove RFS filter from switch + */ +static int edma_delete_rfs_filter(struct edma_adapter *adapter, + struct edma_rfs_filter_node *filter_node) +{ + int res = -1; + + struct flow_keys *keys = &filter_node->keys; + + if (likely(adapter->set_rfs_rule)) + res = (*adapter->set_rfs_rule)(adapter->netdev, + flow_get_u32_src(keys), flow_get_u32_dst(keys), + keys->ports.src, keys->ports.dst, + keys->basic.ip_proto, filter_node->rq_id, 0); + + return res; +} + +/* edma_add_rfs_filter() + * Add RFS filter to switch + */ +static int edma_add_rfs_filter(struct edma_adapter *adapter, + struct flow_keys *keys, u16 rq, + struct edma_rfs_filter_node *filter_node) +{ + int res = -1; + + struct flow_keys *dest_keys = &filter_node->keys; + + memcpy(dest_keys, &filter_node->keys, sizeof(*dest_keys)); +/* + dest_keys->control = keys->control; + dest_keys->basic = keys->basic; + dest_keys->addrs = keys->addrs; + dest_keys->ports = keys->ports; + dest_keys.ip_proto = keys->ip_proto; +*/ + /* Call callback registered by ESS driver */ + if (likely(adapter->set_rfs_rule)) + res = (*adapter->set_rfs_rule)(adapter->netdev, flow_get_u32_src(keys), + flow_get_u32_dst(keys), keys->ports.src, keys->ports.dst, + keys->basic.ip_proto, rq, 1); + + return res; +} + +/* edma_rfs_key_search() + * Look for existing RFS entry + */ +static struct edma_rfs_filter_node *edma_rfs_key_search(struct hlist_head *h, + struct flow_keys *key) +{ + struct edma_rfs_filter_node *p; + + hlist_for_each_entry(p, h, node) + if (flow_get_u32_src(&p->keys) == flow_get_u32_src(key) && + flow_get_u32_dst(&p->keys) == flow_get_u32_dst(key) && + p->keys.ports.src == key->ports.src && + p->keys.ports.dst == key->ports.dst && + p->keys.basic.ip_proto == key->basic.ip_proto) + return p; + return NULL; +} + +/* edma_initialise_rfs_flow_table() + * Initialise EDMA RFS flow table + */ +static void edma_initialise_rfs_flow_table(struct edma_adapter *adapter) +{ + int i; + + spin_lock_init(&adapter->rfs.rfs_ftab_lock); + + /* Initialize EDMA flow hash table */ + for (i = 0; i < EDMA_RFS_FLOW_ENTRIES; i++) + INIT_HLIST_HEAD(&adapter->rfs.hlist_head[i]); + + adapter->rfs.max_num_filter = EDMA_RFS_FLOW_ENTRIES; + adapter->rfs.filter_available = adapter->rfs.max_num_filter; + adapter->rfs.hashtoclean = 0; + + /* Add timer to get periodic RFS updates from OS */ + timer_setup(&adapter->rfs.expire_rfs, edma_flow_may_expire, 0); + mod_timer(&adapter->rfs.expire_rfs, jiffies + HZ / 4); +} + +/* edma_free_rfs_flow_table() + * Free EDMA RFS flow table + */ +static void edma_free_rfs_flow_table(struct edma_adapter *adapter) +{ + int i; + + /* Remove sync timer */ + del_timer_sync(&adapter->rfs.expire_rfs); + spin_lock_bh(&adapter->rfs.rfs_ftab_lock); + + /* Free EDMA RFS table entries */ + adapter->rfs.filter_available = 0; + + /* Clean-up EDMA flow hash table */ + for (i = 0; i < EDMA_RFS_FLOW_ENTRIES; i++) { + struct hlist_head *hhead; + struct hlist_node *tmp; + struct edma_rfs_filter_node *filter_node; + int res; + + hhead = &adapter->rfs.hlist_head[i]; + hlist_for_each_entry_safe(filter_node, tmp, hhead, node) { + res = edma_delete_rfs_filter(adapter, filter_node); + if (res < 0) + dev_warn(&adapter->netdev->dev, + "EDMA going down but RFS entry %d not allowed to be flushed by Switch", + filter_node->flow_id); + hlist_del(&filter_node->node); + kfree(filter_node); + } + } + spin_unlock_bh(&adapter->rfs.rfs_ftab_lock); +} + +/* edma_tx_unmap_and_free() + * clean TX buffer + */ +static inline void edma_tx_unmap_and_free(struct platform_device *pdev, + struct edma_sw_desc *sw_desc) +{ + struct sk_buff *skb = sw_desc->skb; + + if (likely((sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_HEAD) || + (sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_FRAGLIST))) + /* unmap_single for skb head area */ + dma_unmap_single(&pdev->dev, sw_desc->dma, + sw_desc->length, DMA_TO_DEVICE); + else if (sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_FRAG) + /* unmap page for paged fragments */ + dma_unmap_page(&pdev->dev, sw_desc->dma, + sw_desc->length, DMA_TO_DEVICE); + + if (likely(sw_desc->flags & EDMA_SW_DESC_FLAG_LAST)) + dev_kfree_skb_any(skb); + + sw_desc->flags = 0; +} + +/* edma_tx_complete() + * Used to clean tx queues and update hardware and consumer index + */ +static void edma_tx_complete(struct edma_common_info *edma_cinfo, int queue_id) +{ + struct edma_tx_desc_ring *etdr = edma_cinfo->tpd_ring[queue_id]; + struct edma_sw_desc *sw_desc; + struct platform_device *pdev = edma_cinfo->pdev; + int i; + + u16 sw_next_to_clean = etdr->sw_next_to_clean; + u16 hw_next_to_clean; + u32 data = 0; + + edma_read_reg(EDMA_REG_TPD_IDX_Q(queue_id), &data); + hw_next_to_clean = (data >> EDMA_TPD_CONS_IDX_SHIFT) & EDMA_TPD_CONS_IDX_MASK; + + /* clean the buffer here */ + while (sw_next_to_clean != hw_next_to_clean) { + sw_desc = &etdr->sw_desc[sw_next_to_clean]; + edma_tx_unmap_and_free(pdev, sw_desc); + sw_next_to_clean = (sw_next_to_clean + 1) & (etdr->count - 1); + } + + etdr->sw_next_to_clean = sw_next_to_clean; + + /* update the TPD consumer index register */ + edma_write_reg(EDMA_REG_TX_SW_CONS_IDX_Q(queue_id), sw_next_to_clean); + + /* Wake the queue if queue is stopped and netdev link is up */ + for (i = 0; i < EDMA_MAX_NETDEV_PER_QUEUE && etdr->nq[i] ; i++) { + if (netif_tx_queue_stopped(etdr->nq[i])) { + if ((etdr->netdev[i]) && netif_carrier_ok(etdr->netdev[i])) + netif_tx_wake_queue(etdr->nq[i]); + } + } +} + +/* edma_get_tx_buffer() + * Get sw_desc corresponding to the TPD + */ +static struct edma_sw_desc *edma_get_tx_buffer(struct edma_common_info *edma_cinfo, + struct edma_tx_desc *tpd, int queue_id) +{ + struct edma_tx_desc_ring *etdr = edma_cinfo->tpd_ring[queue_id]; + return &etdr->sw_desc[tpd - (struct edma_tx_desc *)etdr->hw_desc]; +} + +/* edma_get_next_tpd() + * Return a TPD descriptor for transfer + */ +static struct edma_tx_desc *edma_get_next_tpd(struct edma_common_info *edma_cinfo, + int queue_id) +{ + struct edma_tx_desc_ring *etdr = edma_cinfo->tpd_ring[queue_id]; + u16 sw_next_to_fill = etdr->sw_next_to_fill; + struct edma_tx_desc *tpd_desc = + (&((struct edma_tx_desc *)(etdr->hw_desc))[sw_next_to_fill]); + + etdr->sw_next_to_fill = (etdr->sw_next_to_fill + 1) & (etdr->count - 1); + + return tpd_desc; +} + +/* edma_tpd_available() + * Check number of free TPDs + */ +static inline u16 edma_tpd_available(struct edma_common_info *edma_cinfo, + int queue_id) +{ + struct edma_tx_desc_ring *etdr = edma_cinfo->tpd_ring[queue_id]; + + u16 sw_next_to_fill; + u16 sw_next_to_clean; + u16 count = 0; + + sw_next_to_clean = etdr->sw_next_to_clean; + sw_next_to_fill = etdr->sw_next_to_fill; + + if (likely(sw_next_to_clean <= sw_next_to_fill)) + count = etdr->count; + + return count + sw_next_to_clean - sw_next_to_fill - 1; +} + +/* edma_tx_queue_get() + * Get the starting number of the queue + */ +static inline int edma_tx_queue_get(struct edma_adapter *adapter, + struct sk_buff *skb, int txq_id) +{ + /* skb->priority is used as an index to skb priority table + * and based on packet priority, correspong queue is assigned. + */ + return adapter->tx_start_offset[txq_id] + edma_skb_priority_offset(skb); +} + +/* edma_tx_update_hw_idx() + * update the producer index for the ring transmitted + */ +static void edma_tx_update_hw_idx(struct edma_common_info *edma_cinfo, + struct sk_buff *skb, int queue_id) +{ + struct edma_tx_desc_ring *etdr = edma_cinfo->tpd_ring[queue_id]; + u32 tpd_idx_data; + + /* Read and update the producer index */ + edma_read_reg(EDMA_REG_TPD_IDX_Q(queue_id), &tpd_idx_data); + tpd_idx_data &= ~EDMA_TPD_PROD_IDX_BITS; + tpd_idx_data |= (etdr->sw_next_to_fill & EDMA_TPD_PROD_IDX_MASK) + << EDMA_TPD_PROD_IDX_SHIFT; + + edma_write_reg(EDMA_REG_TPD_IDX_Q(queue_id), tpd_idx_data); +} + +/* edma_rollback_tx() + * Function to retrieve tx resources in case of error + */ +static void edma_rollback_tx(struct edma_adapter *adapter, + struct edma_tx_desc *start_tpd, int queue_id) +{ + struct edma_tx_desc_ring *etdr = adapter->edma_cinfo->tpd_ring[queue_id]; + struct edma_sw_desc *sw_desc; + struct edma_tx_desc *tpd = NULL; + u16 start_index, index; + + start_index = start_tpd - (struct edma_tx_desc *)(etdr->hw_desc); + + index = start_index; + while (index != etdr->sw_next_to_fill) { + tpd = (&((struct edma_tx_desc *)(etdr->hw_desc))[index]); + sw_desc = &etdr->sw_desc[index]; + edma_tx_unmap_and_free(adapter->pdev, sw_desc); + memset(tpd, 0, sizeof(struct edma_tx_desc)); + if (++index == etdr->count) + index = 0; + } + etdr->sw_next_to_fill = start_index; +} + +/* edma_tx_map_and_fill() + * gets called from edma_xmit_frame + * + * This is where the dma of the buffer to be transmitted + * gets mapped + */ +static int edma_tx_map_and_fill(struct edma_common_info *edma_cinfo, + struct edma_adapter *adapter, struct sk_buff *skb, int queue_id, + unsigned int flags_transmit, u16 from_cpu, u16 dp_bitmap, + bool packet_is_rstp, int nr_frags) +{ + struct edma_sw_desc *sw_desc = NULL; + struct platform_device *pdev = edma_cinfo->pdev; + struct edma_tx_desc *tpd = NULL, *start_tpd = NULL; + struct sk_buff *iter_skb; + int i = 0; + u32 word1 = 0, word3 = 0, lso_word1 = 0, svlan_tag = 0; + u16 buf_len, lso_desc_len = 0; + + /* It should either be a nr_frags skb or fraglist skb but not both */ + BUG_ON(nr_frags && skb_has_frag_list(skb)); + + if (skb_is_gso(skb)) { + /* TODO: What additional checks need to be performed here */ + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) { + lso_word1 |= EDMA_TPD_IPV4_EN; + ip_hdr(skb)->check = 0; + tcp_hdr(skb)->check = ~csum_tcpudp_magic(ip_hdr(skb)->saddr, + ip_hdr(skb)->daddr, 0, IPPROTO_TCP, 0); + } else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { + lso_word1 |= EDMA_TPD_LSO_V2_EN; + ipv6_hdr(skb)->payload_len = 0; + tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0); + } else + return -EINVAL; + + lso_word1 |= EDMA_TPD_LSO_EN | ((skb_shinfo(skb)->gso_size & EDMA_TPD_MSS_MASK) << EDMA_TPD_MSS_SHIFT) | + (skb_transport_offset(skb) << EDMA_TPD_HDR_SHIFT); + } else if (flags_transmit & EDMA_HW_CHECKSUM) { + u8 css, cso; + cso = skb_checksum_start_offset(skb); + css = cso + skb->csum_offset; + + word1 |= (EDMA_TPD_CUSTOM_CSUM_EN); + word1 |= (cso >> 1) << EDMA_TPD_HDR_SHIFT; + word1 |= ((css >> 1) << EDMA_TPD_CUSTOM_CSUM_SHIFT); + } + + if (skb->protocol == htons(ETH_P_PPP_SES)) + word1 |= EDMA_TPD_PPPOE_EN; + + if (flags_transmit & EDMA_VLAN_TX_TAG_INSERT_FLAG) { + switch(skb->vlan_proto) { + case htons(ETH_P_8021Q): + word3 |= (1 << EDMA_TX_INS_CVLAN); + word3 |= skb_vlan_tag_get(skb) << EDMA_TX_CVLAN_TAG_SHIFT; + break; + case htons(ETH_P_8021AD): + word1 |= (1 << EDMA_TX_INS_SVLAN); + svlan_tag = skb_vlan_tag_get(skb) << EDMA_TX_SVLAN_TAG_SHIFT; + break; + default: + dev_err(&pdev->dev, "no ctag or stag present\n"); + goto vlan_tag_error; + } + } else if (flags_transmit & EDMA_VLAN_TX_TAG_INSERT_DEFAULT_FLAG) { + word3 |= (1 << EDMA_TX_INS_CVLAN); + word3 |= (adapter->default_vlan_tag) << EDMA_TX_CVLAN_TAG_SHIFT; + } + + if (packet_is_rstp) { + word3 |= dp_bitmap << EDMA_TPD_PORT_BITMAP_SHIFT; + word3 |= from_cpu << EDMA_TPD_FROM_CPU_SHIFT; + } else { + word3 |= adapter->dp_bitmap << EDMA_TPD_PORT_BITMAP_SHIFT; + } + + buf_len = skb_headlen(skb); + + if (lso_word1) { + if (lso_word1 & EDMA_TPD_LSO_V2_EN) { + + /* IPv6 LSOv2 descriptor */ + start_tpd = tpd = edma_get_next_tpd(edma_cinfo, queue_id); + sw_desc = edma_get_tx_buffer(edma_cinfo, tpd, queue_id); + sw_desc->flags |= EDMA_SW_DESC_FLAG_SKB_NONE; + + /* LSOv2 descriptor overrides addr field to pass length */ + tpd->addr = cpu_to_le16(skb->len); + tpd->svlan_tag = svlan_tag; + tpd->word1 = word1 | lso_word1; + tpd->word3 = word3; + } + + tpd = edma_get_next_tpd(edma_cinfo, queue_id); + if (!start_tpd) + start_tpd = tpd; + sw_desc = edma_get_tx_buffer(edma_cinfo, tpd, queue_id); + + /* The last buffer info contain the skb address, + * so skb will be freed after unmap + */ + sw_desc->length = lso_desc_len; + sw_desc->flags |= EDMA_SW_DESC_FLAG_SKB_HEAD; + + sw_desc->dma = dma_map_single(&adapter->pdev->dev, + skb->data, buf_len, DMA_TO_DEVICE); + if (dma_mapping_error(&pdev->dev, sw_desc->dma)) + goto dma_error; + + tpd->addr = cpu_to_le32(sw_desc->dma); + tpd->len = cpu_to_le16(buf_len); + + tpd->svlan_tag = svlan_tag; + tpd->word1 = word1 | lso_word1; + tpd->word3 = word3; + + /* The last buffer info contain the skb address, + * so it will be freed after unmap + */ + sw_desc->length = lso_desc_len; + sw_desc->flags |= EDMA_SW_DESC_FLAG_SKB_HEAD; + + buf_len = 0; + } + + if (likely(buf_len)) { + + /* TODO Do not dequeue descriptor if there is a potential error */ + tpd = edma_get_next_tpd(edma_cinfo, queue_id); + + if (!start_tpd) + start_tpd = tpd; + + sw_desc = edma_get_tx_buffer(edma_cinfo, tpd, queue_id); + + /* The last buffer info contain the skb address, + * so it will be free after unmap + */ + sw_desc->length = buf_len; + sw_desc->flags |= EDMA_SW_DESC_FLAG_SKB_HEAD; + sw_desc->dma = dma_map_single(&adapter->pdev->dev, + skb->data, buf_len, DMA_TO_DEVICE); + if (dma_mapping_error(&pdev->dev, sw_desc->dma)) + goto dma_error; + + tpd->addr = cpu_to_le32(sw_desc->dma); + tpd->len = cpu_to_le16(buf_len); + + tpd->svlan_tag = svlan_tag; + tpd->word1 = word1 | lso_word1; + tpd->word3 = word3; + } + + /* Walk through all paged fragments */ + while (nr_frags--) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + buf_len = skb_frag_size(frag); + tpd = edma_get_next_tpd(edma_cinfo, queue_id); + sw_desc = edma_get_tx_buffer(edma_cinfo, tpd, queue_id); + sw_desc->length = buf_len; + sw_desc->flags |= EDMA_SW_DESC_FLAG_SKB_FRAG; + + sw_desc->dma = skb_frag_dma_map(&pdev->dev, frag, 0, buf_len, DMA_TO_DEVICE); + + if (dma_mapping_error(NULL, sw_desc->dma)) + goto dma_error; + + tpd->addr = cpu_to_le32(sw_desc->dma); + tpd->len = cpu_to_le16(buf_len); + + tpd->svlan_tag = svlan_tag; + tpd->word1 = word1 | lso_word1; + tpd->word3 = word3; + i++; + } + + /* Walk through all fraglist skbs */ + skb_walk_frags(skb, iter_skb) { + buf_len = iter_skb->len; + tpd = edma_get_next_tpd(edma_cinfo, queue_id); + sw_desc = edma_get_tx_buffer(edma_cinfo, tpd, queue_id); + sw_desc->length = buf_len; + sw_desc->dma = dma_map_single(&adapter->pdev->dev, + iter_skb->data, buf_len, DMA_TO_DEVICE); + + if (dma_mapping_error(NULL, sw_desc->dma)) + goto dma_error; + + tpd->addr = cpu_to_le32(sw_desc->dma); + tpd->len = cpu_to_le16(buf_len); + tpd->svlan_tag = svlan_tag; + tpd->word1 = word1 | lso_word1; + tpd->word3 = word3; + sw_desc->flags |= EDMA_SW_DESC_FLAG_SKB_FRAGLIST; + } + + if (tpd) + tpd->word1 |= 1 << EDMA_TPD_EOP_SHIFT; + + sw_desc->skb = skb; + sw_desc->flags |= EDMA_SW_DESC_FLAG_LAST; + + return 0; + +dma_error: + edma_rollback_tx(adapter, start_tpd, queue_id); + dev_err(&pdev->dev, "TX DMA map failed\n"); +vlan_tag_error: + return -ENOMEM; +} + +/* edma_check_link() + * check Link status + */ +static int edma_check_link(struct edma_adapter *adapter) +{ + struct phy_device *phydev = adapter->phydev; + + if (!(adapter->poll_required)) + return __EDMA_LINKUP; + + if (phydev->link) + return __EDMA_LINKUP; + + return __EDMA_LINKDOWN; +} + +/* edma_adjust_link() + * check for edma link status + */ +void edma_adjust_link(struct net_device *netdev) +{ + int status; + struct edma_adapter *adapter = netdev_priv(netdev); + struct phy_device *phydev = adapter->phydev; + + if (!test_bit(__EDMA_UP, &adapter->state_flags)) + return; + + status = edma_check_link(adapter); + + if (status == __EDMA_LINKUP && adapter->link_state == __EDMA_LINKDOWN) { + dev_info(&adapter->pdev->dev, "%s: GMAC Link is up with phy_speed=%d\n", netdev->name, phydev->speed); + adapter->link_state = __EDMA_LINKUP; + if (adapter->edma_cinfo->is_single_phy) { + ess_set_port_status_speed(adapter->edma_cinfo, phydev, + ffs(adapter->dp_bitmap) - 1); + } + netif_carrier_on(netdev); + if (netif_running(netdev)) + netif_tx_wake_all_queues(netdev); + } else if (status == __EDMA_LINKDOWN && adapter->link_state == __EDMA_LINKUP) { + dev_info(&adapter->pdev->dev, "%s: GMAC Link is down\n", netdev->name); + adapter->link_state = __EDMA_LINKDOWN; + netif_carrier_off(netdev); + netif_tx_stop_all_queues(netdev); + } +} + +/* edma_get_stats() + * Statistics api used to retreive the tx/rx statistics + */ +struct net_device_stats *edma_get_stats(struct net_device *netdev) +{ + struct edma_adapter *adapter = netdev_priv(netdev); + + return &adapter->stats; +} + +/* edma_xmit() + * Main api to be called by the core for packet transmission + */ +netdev_tx_t edma_xmit(struct sk_buff *skb, + struct net_device *net_dev) +{ + struct edma_adapter *adapter = netdev_priv(net_dev); + struct edma_common_info *edma_cinfo = adapter->edma_cinfo; + struct edma_tx_desc_ring *etdr; + u16 from_cpu, dp_bitmap, txq_id; + int ret, nr_frags = 0, num_tpds_needed = 1, queue_id; + unsigned int flags_transmit = 0; + bool packet_is_rstp = false; + struct netdev_queue *nq = NULL; + + if (skb_shinfo(skb)->nr_frags) { + nr_frags = skb_shinfo(skb)->nr_frags; + num_tpds_needed += nr_frags; + } else if (skb_has_frag_list(skb)) { + struct sk_buff *iter_skb; + + skb_walk_frags(skb, iter_skb) + num_tpds_needed++; + } + + if (num_tpds_needed > EDMA_MAX_SKB_FRAGS) { + dev_err(&net_dev->dev, + "skb received with fragments %d which is more than %lu", + num_tpds_needed, EDMA_MAX_SKB_FRAGS); + dev_kfree_skb_any(skb); + adapter->stats.tx_errors++; + return NETDEV_TX_OK; + } + + if (edma_stp_rstp) { + u16 ath_hdr, ath_eth_type; + u8 mac_addr[EDMA_ETH_HDR_LEN]; + ath_eth_type = ntohs(*(uint16_t *)&skb->data[12]); + if (ath_eth_type == edma_ath_eth_type) { + packet_is_rstp = true; + ath_hdr = htons(*(uint16_t *)&skb->data[14]); + dp_bitmap = ath_hdr & EDMA_TX_ATH_HDR_PORT_BITMAP_MASK; + from_cpu = (ath_hdr & EDMA_TX_ATH_HDR_FROM_CPU_MASK) >> EDMA_TX_ATH_HDR_FROM_CPU_SHIFT; + memcpy(mac_addr, skb->data, EDMA_ETH_HDR_LEN); + + skb_pull(skb, 4); + + memcpy(skb->data, mac_addr, EDMA_ETH_HDR_LEN); + } + } + + /* this will be one of the 4 TX queues exposed to linux kernel */ + txq_id = skb_get_queue_mapping(skb); + queue_id = edma_tx_queue_get(adapter, skb, txq_id); + etdr = edma_cinfo->tpd_ring[queue_id]; + nq = netdev_get_tx_queue(net_dev, txq_id); + + local_bh_disable(); + /* Tx is not handled in bottom half context. Hence, we need to protect + * Tx from tasks and bottom half + */ + + if (num_tpds_needed > edma_tpd_available(edma_cinfo, queue_id)) { + /* not enough descriptor, just stop queue */ + netif_tx_stop_queue(nq); + local_bh_enable(); + dev_dbg(&net_dev->dev, "Not enough descriptors available"); + edma_cinfo->edma_ethstats.tx_desc_error++; + return NETDEV_TX_BUSY; + } + + /* Check and mark VLAN tag offload */ + if (!adapter->edma_cinfo->is_single_phy) { + if (unlikely(skb_vlan_tag_present(skb))) + flags_transmit |= EDMA_VLAN_TX_TAG_INSERT_FLAG; + else if (adapter->default_vlan_tag) + flags_transmit |= EDMA_VLAN_TX_TAG_INSERT_DEFAULT_FLAG; + } + + /* Check and mark checksum offload */ + if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) + flags_transmit |= EDMA_HW_CHECKSUM; + + /* Map and fill descriptor for Tx */ + ret = edma_tx_map_and_fill(edma_cinfo, adapter, skb, queue_id, + flags_transmit, from_cpu, dp_bitmap, packet_is_rstp, nr_frags); + if (ret) { + dev_kfree_skb_any(skb); + adapter->stats.tx_errors++; + goto netdev_okay; + } + + /* Update SW producer index */ + edma_tx_update_hw_idx(edma_cinfo, skb, queue_id); + + /* update tx statistics */ + adapter->stats.tx_packets++; + adapter->stats.tx_bytes += skb->len; + +netdev_okay: + local_bh_enable(); + return NETDEV_TX_OK; +} + +/* + * edma_flow_may_expire() + * Timer function called periodically to delete the node + */ +void edma_flow_may_expire(struct timer_list *t) +{ + struct edma_rfs_flow_table *table = from_timer(table, t, expire_rfs); + struct edma_adapter *adapter = + container_of(table, typeof(*adapter), rfs); + int j; + + spin_lock_bh(&adapter->rfs.rfs_ftab_lock); + for (j = 0; j < EDMA_RFS_EXPIRE_COUNT_PER_CALL; j++) { + struct hlist_head *hhead; + struct hlist_node *tmp; + struct edma_rfs_filter_node *n; + bool res; + + hhead = &adapter->rfs.hlist_head[adapter->rfs.hashtoclean++]; + hlist_for_each_entry_safe(n, tmp, hhead, node) { + res = rps_may_expire_flow(adapter->netdev, n->rq_id, + n->flow_id, n->filter_id); + if (res) { + int ret; + ret = edma_delete_rfs_filter(adapter, n); + if (ret < 0) + dev_dbg(&adapter->netdev->dev, + "RFS entry %d not allowed to be flushed by Switch", + n->flow_id); + else { + hlist_del(&n->node); + kfree(n); + adapter->rfs.filter_available++; + } + } + } + } + + adapter->rfs.hashtoclean = adapter->rfs.hashtoclean & (EDMA_RFS_FLOW_ENTRIES - 1); + spin_unlock_bh(&adapter->rfs.rfs_ftab_lock); + mod_timer(&adapter->rfs.expire_rfs, jiffies + HZ / 4); +} + +/* edma_rx_flow_steer() + * Called by core to to steer the flow to CPU + */ +int edma_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, + u16 rxq, u32 flow_id) +{ + struct flow_keys keys; + struct edma_rfs_filter_node *filter_node; + struct edma_adapter *adapter = netdev_priv(dev); + u16 hash_tblid; + int res; + + if (skb->protocol == htons(ETH_P_IPV6)) { + dev_err(&adapter->pdev->dev, "IPv6 not supported\n"); + res = -EINVAL; + goto no_protocol_err; + } + + /* Dissect flow parameters + * We only support IPv4 + TCP/UDP + */ + res = skb_flow_dissect_flow_keys(skb, &keys, 0); + if (!((keys.basic.ip_proto == IPPROTO_TCP) || (keys.basic.ip_proto == IPPROTO_UDP))) { + res = -EPROTONOSUPPORT; + goto no_protocol_err; + } + + /* Check if table entry exists */ + hash_tblid = skb_get_hash_raw(skb) & EDMA_RFS_FLOW_ENTRIES_MASK; + + spin_lock_bh(&adapter->rfs.rfs_ftab_lock); + filter_node = edma_rfs_key_search(&adapter->rfs.hlist_head[hash_tblid], &keys); + + if (filter_node) { + if (rxq == filter_node->rq_id) { + res = -EEXIST; + goto out; + } else { + res = edma_delete_rfs_filter(adapter, filter_node); + if (res < 0) + dev_warn(&adapter->netdev->dev, + "Cannot steer flow %d to different queue", + filter_node->flow_id); + else { + adapter->rfs.filter_available++; + res = edma_add_rfs_filter(adapter, &keys, rxq, filter_node); + if (res < 0) { + dev_warn(&adapter->netdev->dev, + "Cannot steer flow %d to different queue", + filter_node->flow_id); + } else { + adapter->rfs.filter_available--; + filter_node->rq_id = rxq; + filter_node->filter_id = res; + } + } + } + } else { + if (adapter->rfs.filter_available == 0) { + res = -EBUSY; + goto out; + } + + filter_node = kmalloc(sizeof(*filter_node), GFP_ATOMIC); + if (!filter_node) { + res = -ENOMEM; + goto out; + } + + res = edma_add_rfs_filter(adapter, &keys, rxq, filter_node); + if (res < 0) { + kfree(filter_node); + goto out; + } + + adapter->rfs.filter_available--; + filter_node->rq_id = rxq; + filter_node->filter_id = res; + filter_node->flow_id = flow_id; + filter_node->keys = keys; + INIT_HLIST_NODE(&filter_node->node); + hlist_add_head(&filter_node->node, &adapter->rfs.hlist_head[hash_tblid]); + } + +out: + spin_unlock_bh(&adapter->rfs.rfs_ftab_lock); +no_protocol_err: + return res; +} + +/* edma_register_rfs_filter() + * Add RFS filter callback + */ +int edma_register_rfs_filter(struct net_device *netdev, + set_rfs_filter_callback_t set_filter) +{ + struct edma_adapter *adapter = netdev_priv(netdev); + + spin_lock_bh(&adapter->rfs.rfs_ftab_lock); + + if (adapter->set_rfs_rule) { + spin_unlock_bh(&adapter->rfs.rfs_ftab_lock); + return -1; + } + + adapter->set_rfs_rule = set_filter; + spin_unlock_bh(&adapter->rfs.rfs_ftab_lock); + + return 0; +} + +/* edma_alloc_tx_rings() + * Allocate rx rings + */ +int edma_alloc_tx_rings(struct edma_common_info *edma_cinfo) +{ + struct platform_device *pdev = edma_cinfo->pdev; + int i, err = 0; + + for (i = 0; i < edma_cinfo->num_tx_queues; i++) { + err = edma_alloc_tx_ring(edma_cinfo, edma_cinfo->tpd_ring[i]); + if (err) { + dev_err(&pdev->dev, "Tx Queue alloc %u failed\n", i); + return err; + } + } + + return 0; +} + +/* edma_free_tx_rings() + * Free tx rings + */ +void edma_free_tx_rings(struct edma_common_info *edma_cinfo) +{ + int i; + + for (i = 0; i < edma_cinfo->num_tx_queues; i++) + edma_free_tx_ring(edma_cinfo, edma_cinfo->tpd_ring[i]); +} + +/* edma_free_tx_resources() + * Free buffers associated with tx rings + */ +void edma_free_tx_resources(struct edma_common_info *edma_cinfo) +{ + struct edma_tx_desc_ring *etdr; + struct edma_sw_desc *sw_desc; + struct platform_device *pdev = edma_cinfo->pdev; + int i, j; + + for (i = 0; i < edma_cinfo->num_tx_queues; i++) { + etdr = edma_cinfo->tpd_ring[i]; + for (j = 0; j < EDMA_TX_RING_SIZE; j++) { + sw_desc = &etdr->sw_desc[j]; + if (sw_desc->flags & (EDMA_SW_DESC_FLAG_SKB_HEAD | + EDMA_SW_DESC_FLAG_SKB_FRAG | EDMA_SW_DESC_FLAG_SKB_FRAGLIST)) + edma_tx_unmap_and_free(pdev, sw_desc); + } + } +} + +/* edma_alloc_rx_rings() + * Allocate rx rings + */ +int edma_alloc_rx_rings(struct edma_common_info *edma_cinfo) +{ + struct platform_device *pdev = edma_cinfo->pdev; + int i, j, err = 0; + + for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { + err = edma_alloc_rx_ring(edma_cinfo, edma_cinfo->rfd_ring[j]); + if (err) { + dev_err(&pdev->dev, "Rx Queue alloc%u failed\n", i); + return err; + } + j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); + } + + return 0; +} + +/* edma_free_rx_rings() + * free rx rings + */ +void edma_free_rx_rings(struct edma_common_info *edma_cinfo) +{ + int i, j; + + for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { + edma_free_rx_ring(edma_cinfo, edma_cinfo->rfd_ring[j]); + j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); + } +} + +/* edma_free_queues() + * Free the queues allocaated + */ +void edma_free_queues(struct edma_common_info *edma_cinfo) +{ + int i , j; + + for (i = 0; i < edma_cinfo->num_tx_queues; i++) { + if (edma_cinfo->tpd_ring[i]) + kfree(edma_cinfo->tpd_ring[i]); + edma_cinfo->tpd_ring[i] = NULL; + } + + for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { + if (edma_cinfo->rfd_ring[j]) + kfree(edma_cinfo->rfd_ring[j]); + edma_cinfo->rfd_ring[j] = NULL; + j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); + } + + edma_cinfo->num_rx_queues = 0; + edma_cinfo->num_tx_queues = 0; + + return; +} + +/* edma_free_rx_resources() + * Free buffers associated with tx rings + */ +void edma_free_rx_resources(struct edma_common_info *edma_cinfo) +{ + struct edma_rfd_desc_ring *erdr; + struct edma_sw_desc *sw_desc; + struct platform_device *pdev = edma_cinfo->pdev; + int i, j, k; + + for (i = 0, k = 0; i < edma_cinfo->num_rx_queues; i++) { + erdr = edma_cinfo->rfd_ring[k]; + for (j = 0; j < EDMA_RX_RING_SIZE; j++) { + sw_desc = &erdr->sw_desc[j]; + if (likely(sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_HEAD)) { + dma_unmap_single(&pdev->dev, sw_desc->dma, + sw_desc->length, DMA_FROM_DEVICE); + edma_clean_rfd(erdr, j); + } else if ((sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_FRAG)) { + dma_unmap_page(&pdev->dev, sw_desc->dma, + sw_desc->length, DMA_FROM_DEVICE); + edma_clean_rfd(erdr, j); + } + } + k += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); + + } +} + +/* edma_alloc_queues_tx() + * Allocate memory for all rings + */ +int edma_alloc_queues_tx(struct edma_common_info *edma_cinfo) +{ + int i; + + for (i = 0; i < edma_cinfo->num_tx_queues; i++) { + struct edma_tx_desc_ring *etdr; + etdr = kzalloc(sizeof(struct edma_tx_desc_ring), GFP_KERNEL); + if (!etdr) + goto err; + etdr->count = edma_cinfo->tx_ring_count; + edma_cinfo->tpd_ring[i] = etdr; + } + + return 0; +err: + edma_free_queues(edma_cinfo); + return -1; +} + +/* edma_alloc_queues_rx() + * Allocate memory for all rings + */ +int edma_alloc_queues_rx(struct edma_common_info *edma_cinfo) +{ + int i, j; + + for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { + struct edma_rfd_desc_ring *rfd_ring; + rfd_ring = kzalloc(sizeof(struct edma_rfd_desc_ring), + GFP_KERNEL); + if (!rfd_ring) + goto err; + rfd_ring->count = edma_cinfo->rx_ring_count; + edma_cinfo->rfd_ring[j] = rfd_ring; + j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); + } + return 0; +err: + edma_free_queues(edma_cinfo); + return -1; +} + +/* edma_clear_irq_status() + * Clear interrupt status + */ +void edma_clear_irq_status() +{ + edma_write_reg(EDMA_REG_RX_ISR, 0xff); + edma_write_reg(EDMA_REG_TX_ISR, 0xffff); + edma_write_reg(EDMA_REG_MISC_ISR, 0x1fff); + edma_write_reg(EDMA_REG_WOL_ISR, 0x1); +}; + +/* edma_configure() + * Configure skb, edma interrupts and control register. + */ +int edma_configure(struct edma_common_info *edma_cinfo) +{ + struct edma_hw *hw = &edma_cinfo->hw; + u32 intr_modrt_data; + u32 intr_ctrl_data = 0; + int i, j, ret_count; + + edma_read_reg(EDMA_REG_INTR_CTRL, &intr_ctrl_data); + intr_ctrl_data &= ~(1 << EDMA_INTR_SW_IDX_W_TYP_SHIFT); + intr_ctrl_data |= hw->intr_sw_idx_w << EDMA_INTR_SW_IDX_W_TYP_SHIFT; + edma_write_reg(EDMA_REG_INTR_CTRL, intr_ctrl_data); + + edma_clear_irq_status(); + + /* Clear any WOL status */ + edma_write_reg(EDMA_REG_WOL_CTRL, 0); + intr_modrt_data = (EDMA_TX_IMT << EDMA_IRQ_MODRT_TX_TIMER_SHIFT); + intr_modrt_data |= (EDMA_RX_IMT << EDMA_IRQ_MODRT_RX_TIMER_SHIFT); + edma_write_reg(EDMA_REG_IRQ_MODRT_TIMER_INIT, intr_modrt_data); + edma_configure_tx(edma_cinfo); + edma_configure_rx(edma_cinfo); + + /* Allocate the RX buffer */ + for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { + struct edma_rfd_desc_ring *ring = edma_cinfo->rfd_ring[j]; + ret_count = edma_alloc_rx_buf(edma_cinfo, ring, ring->count, j); + if (ret_count) { + dev_dbg(&edma_cinfo->pdev->dev, "not all rx buffers allocated\n"); + } + j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); + } + + /* Configure descriptor Ring */ + edma_init_desc(edma_cinfo); + return 0; +} + +/* edma_irq_enable() + * Enable default interrupt generation settings + */ +void edma_irq_enable(struct edma_common_info *edma_cinfo) +{ + struct edma_hw *hw = &edma_cinfo->hw; + int i, j; + + edma_write_reg(EDMA_REG_RX_ISR, 0xff); + for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { + edma_write_reg(EDMA_REG_RX_INT_MASK_Q(j), hw->rx_intr_mask); + j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); + } + edma_write_reg(EDMA_REG_TX_ISR, 0xffff); + for (i = 0; i < edma_cinfo->num_tx_queues; i++) + edma_write_reg(EDMA_REG_TX_INT_MASK_Q(i), hw->tx_intr_mask); +} + +/* edma_irq_disable() + * Disable Interrupt + */ +void edma_irq_disable(struct edma_common_info *edma_cinfo) +{ + int i; + + for (i = 0; i < EDMA_MAX_RECEIVE_QUEUE; i++) + edma_write_reg(EDMA_REG_RX_INT_MASK_Q(i), 0x0); + + for (i = 0; i < EDMA_MAX_TRANSMIT_QUEUE; i++) + edma_write_reg(EDMA_REG_TX_INT_MASK_Q(i), 0x0); + edma_write_reg(EDMA_REG_MISC_IMR, 0); + edma_write_reg(EDMA_REG_WOL_IMR, 0); +} + +/* edma_free_irqs() + * Free All IRQs + */ +void edma_free_irqs(struct edma_adapter *adapter) +{ + struct edma_common_info *edma_cinfo = adapter->edma_cinfo; + int i, j; + int k = ((edma_cinfo->num_rx_queues == 4) ? 1 : 2); + + for (i = 0; i < CONFIG_NR_CPUS; i++) { + for (j = edma_cinfo->edma_percpu_info[i].tx_start; j < (edma_cinfo->edma_percpu_info[i].tx_start + 4); j++) + free_irq(edma_cinfo->tx_irq[j], &edma_cinfo->edma_percpu_info[i]); + + for (j = edma_cinfo->edma_percpu_info[i].rx_start; j < (edma_cinfo->edma_percpu_info[i].rx_start + k); j++) + free_irq(edma_cinfo->rx_irq[j], &edma_cinfo->edma_percpu_info[i]); + } +} + +/* edma_enable_rx_ctrl() + * Enable RX queue control + */ +void edma_enable_rx_ctrl(struct edma_hw *hw) +{ + u32 data; + + edma_read_reg(EDMA_REG_RXQ_CTRL, &data); + data |= EDMA_RXQ_CTRL_EN; + edma_write_reg(EDMA_REG_RXQ_CTRL, data); +} + + +/* edma_enable_tx_ctrl() + * Enable TX queue control + */ +void edma_enable_tx_ctrl(struct edma_hw *hw) +{ + u32 data; + + edma_read_reg(EDMA_REG_TXQ_CTRL, &data); + data |= EDMA_TXQ_CTRL_TXQ_EN; + edma_write_reg(EDMA_REG_TXQ_CTRL, data); +} + +/* edma_stop_rx_tx() + * Disable RX/TQ Queue control + */ +void edma_stop_rx_tx(struct edma_hw *hw) +{ + u32 data; + + edma_read_reg(EDMA_REG_RXQ_CTRL, &data); + data &= ~EDMA_RXQ_CTRL_EN; + edma_write_reg(EDMA_REG_RXQ_CTRL, data); + edma_read_reg(EDMA_REG_TXQ_CTRL, &data); + data &= ~EDMA_TXQ_CTRL_TXQ_EN; + edma_write_reg(EDMA_REG_TXQ_CTRL, data); +} + +/* edma_reset() + * Reset the EDMA + */ +int edma_reset(struct edma_common_info *edma_cinfo) +{ + struct edma_hw *hw = &edma_cinfo->hw; + + edma_irq_disable(edma_cinfo); + + edma_clear_irq_status(); + + edma_stop_rx_tx(hw); + + return 0; +} + +/* edma_fill_netdev() + * Fill netdev for each etdr + */ +int edma_fill_netdev(struct edma_common_info *edma_cinfo, int queue_id, + int dev, int txq_id) +{ + struct edma_tx_desc_ring *etdr; + int i = 0; + + etdr = edma_cinfo->tpd_ring[queue_id]; + + while (etdr->netdev[i]) + i++; + + if (i >= EDMA_MAX_NETDEV_PER_QUEUE) + return -1; + + /* Populate the netdev associated with the tpd ring */ + etdr->netdev[i] = edma_netdev[dev]; + etdr->nq[i] = netdev_get_tx_queue(edma_netdev[dev], txq_id); + + return 0; +} + +/* edma_set_mac() + * Change the Ethernet Address of the NIC + */ +int edma_set_mac_addr(struct net_device *netdev, void *p) +{ + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EINVAL; + + if (netif_running(netdev)) + return -EBUSY; + + memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); + return 0; +} + +/* edma_set_stp_rstp() + * set stp/rstp + */ +void edma_set_stp_rstp(bool rstp) +{ + edma_stp_rstp = rstp; +} + +/* edma_assign_ath_hdr_type() + * assign atheros header eth type + */ +void edma_assign_ath_hdr_type(int eth_type) +{ + edma_ath_eth_type = eth_type & EDMA_ETH_TYPE_MASK; +} + +/* edma_get_default_vlan_tag() + * Used by other modules to get the default vlan tag + */ +int edma_get_default_vlan_tag(struct net_device *netdev) +{ + struct edma_adapter *adapter = netdev_priv(netdev); + + if (adapter->default_vlan_tag) + return adapter->default_vlan_tag; + + return 0; +} + +/* edma_open() + * gets called when netdevice is up, start the queue. + */ +int edma_open(struct net_device *netdev) +{ + struct edma_adapter *adapter = netdev_priv(netdev); + struct platform_device *pdev = adapter->edma_cinfo->pdev; + + netif_tx_start_all_queues(netdev); + edma_initialise_rfs_flow_table(adapter); + set_bit(__EDMA_UP, &adapter->state_flags); + + /* if Link polling is enabled, in our case enabled for WAN, then + * do a phy start, else always set link as UP + */ + if (adapter->poll_required) { + if (!IS_ERR(adapter->phydev)) { + phy_start(adapter->phydev); + phy_start_aneg(adapter->phydev); + adapter->link_state = __EDMA_LINKDOWN; + } else { + dev_dbg(&pdev->dev, "Invalid PHY device for a link polled interface\n"); + } + } else { + adapter->link_state = __EDMA_LINKUP; + netif_carrier_on(netdev); + } + + return 0; +} + + +/* edma_close() + * gets called when netdevice is down, stops the queue. + */ +int edma_close(struct net_device *netdev) +{ + struct edma_adapter *adapter = netdev_priv(netdev); + + edma_free_rfs_flow_table(adapter); + netif_carrier_off(netdev); + netif_tx_stop_all_queues(netdev); + + if (adapter->poll_required) { + if (!IS_ERR(adapter->phydev)) + phy_stop(adapter->phydev); + } + + adapter->link_state = __EDMA_LINKDOWN; + + /* Set GMAC state to UP before link state is checked + */ + clear_bit(__EDMA_UP, &adapter->state_flags); + + return 0; +} + +/* edma_poll + * polling function that gets called when the napi gets scheduled. + * + * Main sequence of task performed in this api + * is clear irq status -> clear_tx_irq -> clean_rx_irq-> + * enable interrupts. + */ +int edma_poll(struct napi_struct *napi, int budget) +{ + struct edma_per_cpu_queues_info *edma_percpu_info = container_of(napi, + struct edma_per_cpu_queues_info, napi); + struct edma_common_info *edma_cinfo = edma_percpu_info->edma_cinfo; + u32 reg_data; + u32 shadow_rx_status, shadow_tx_status; + int queue_id; + int i, work_done = 0; + u16 rx_pending_fill; + + /* Store the Rx/Tx status by ANDing it with + * appropriate CPU RX?TX mask + */ + edma_read_reg(EDMA_REG_RX_ISR, ®_data); + edma_percpu_info->rx_status |= reg_data & edma_percpu_info->rx_mask; + shadow_rx_status = edma_percpu_info->rx_status; + edma_read_reg(EDMA_REG_TX_ISR, ®_data); + edma_percpu_info->tx_status |= reg_data & edma_percpu_info->tx_mask; + shadow_tx_status = edma_percpu_info->tx_status; + + /* Every core will have a start, which will be computed + * in probe and stored in edma_percpu_info->tx_start variable. + * We will shift the status bit by tx_start to obtain + * status bits for the core on which the current processing + * is happening. Since, there are 4 tx queues per core, + * we will run the loop till we get the correct queue to clear. + */ + while (edma_percpu_info->tx_status) { + queue_id = ffs(edma_percpu_info->tx_status) - 1; + edma_tx_complete(edma_cinfo, queue_id); + edma_percpu_info->tx_status &= ~(1 << queue_id); + } + + /* Every core will have a start, which will be computed + * in probe and stored in edma_percpu_info->tx_start variable. + * We will shift the status bit by tx_start to obtain + * status bits for the core on which the current processing + * is happening. Since, there are 4 tx queues per core, we + * will run the loop till we get the correct queue to clear. + */ + while (edma_percpu_info->rx_status) { + queue_id = ffs(edma_percpu_info->rx_status) - 1; + rx_pending_fill = edma_rx_complete(edma_cinfo, &work_done, + budget, queue_id, napi); + + if (likely(work_done < budget)) { + if (rx_pending_fill) { + /* reschedule poll() to refill rx buffer deficit */ + work_done = budget; + break; + } + edma_percpu_info->rx_status &= ~(1 << queue_id); + } else { + break; + } + } + + /* Clear the status register, to avoid the interrupts to + * reoccur.This clearing of interrupt status register is + * done here as writing to status register only takes place + * once the producer/consumer index has been updated to + * reflect that the packet transmission/reception went fine. + */ + edma_write_reg(EDMA_REG_RX_ISR, shadow_rx_status); + edma_write_reg(EDMA_REG_TX_ISR, shadow_tx_status); + + /* If budget not fully consumed, exit the polling mode */ + if (likely(work_done < budget)) { + napi_complete(napi); + + /* re-enable the interrupts */ + for (i = 0; i < edma_cinfo->num_rxq_per_core; i++) + edma_write_reg(EDMA_REG_RX_INT_MASK_Q(edma_percpu_info->rx_start + i), 0x1); + for (i = 0; i < edma_cinfo->num_txq_per_core; i++) + edma_write_reg(EDMA_REG_TX_INT_MASK_Q(edma_percpu_info->tx_start + i), 0x1); + } + + return work_done; +} + +/* edma interrupt() + * interrupt handler + */ +irqreturn_t edma_interrupt(int irq, void *dev) +{ + struct edma_per_cpu_queues_info *edma_percpu_info = (struct edma_per_cpu_queues_info *) dev; + struct edma_common_info *edma_cinfo = edma_percpu_info->edma_cinfo; + int i; + + /* Unmask the TX/RX interrupt register */ + for (i = 0; i < edma_cinfo->num_rxq_per_core; i++) + edma_write_reg(EDMA_REG_RX_INT_MASK_Q(edma_percpu_info->rx_start + i), 0x0); + + for (i = 0; i < edma_cinfo->num_txq_per_core; i++) + edma_write_reg(EDMA_REG_TX_INT_MASK_Q(edma_percpu_info->tx_start + i), 0x0); + + napi_schedule(&edma_percpu_info->napi); + + return IRQ_HANDLED; +} diff --git a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.h b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.h new file mode 100644 index 00000000..015e5f50 --- /dev/null +++ b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.h @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _EDMA_H_ +#define _EDMA_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ess_edma.h" + +#define EDMA_CPU_CORES_SUPPORTED 4 +#define EDMA_MAX_PORTID_SUPPORTED 5 +#define EDMA_MAX_VLAN_SUPPORTED EDMA_MAX_PORTID_SUPPORTED +#define EDMA_MAX_PORTID_BITMAP_INDEX (EDMA_MAX_PORTID_SUPPORTED + 1) +#define EDMA_MAX_PORTID_BITMAP_SUPPORTED 0x1f /* 0001_1111 = 0x1f */ +#define EDMA_MAX_NETDEV_PER_QUEUE 4 /* 3 Netdev per queue, 1 space for indexing */ + +#define EDMA_MAX_RECEIVE_QUEUE 8 +#define EDMA_MAX_TRANSMIT_QUEUE 16 + +/* WAN/LAN adapter number */ +#define EDMA_WAN 0 +#define EDMA_LAN 1 + +/* VLAN tag */ +#define EDMA_LAN_DEFAULT_VLAN 1 +#define EDMA_WAN_DEFAULT_VLAN 2 + +#define EDMA_DEFAULT_GROUP1_VLAN 1 +#define EDMA_DEFAULT_GROUP2_VLAN 2 +#define EDMA_DEFAULT_GROUP3_VLAN 3 +#define EDMA_DEFAULT_GROUP4_VLAN 4 +#define EDMA_DEFAULT_GROUP5_VLAN 5 + +/* Queues exposed to linux kernel */ +#define EDMA_NETDEV_TX_QUEUE 4 +#define EDMA_NETDEV_RX_QUEUE 4 + +/* Number of queues per core */ +#define EDMA_NUM_TXQ_PER_CORE 4 +#define EDMA_NUM_RXQ_PER_CORE 2 + +#define EDMA_TPD_EOP_SHIFT 31 + +#define EDMA_PORT_ID_SHIFT 12 +#define EDMA_PORT_ID_MASK 0x7 + +/* tpd word 3 bit 18-28 */ +#define EDMA_TPD_PORT_BITMAP_SHIFT 18 + +#define EDMA_TPD_FROM_CPU_SHIFT 25 + +#define EDMA_FROM_CPU_MASK 0x80 +#define EDMA_SKB_PRIORITY_MASK 0x38 + +/* TX/RX descriptor ring count */ +/* should be a power of 2 */ +#define EDMA_RX_RING_SIZE 128 +#define EDMA_TX_RING_SIZE 128 + +/* Flags used in paged/non paged mode */ +#define EDMA_RX_HEAD_BUFF_SIZE_JUMBO 256 +#define EDMA_RX_HEAD_BUFF_SIZE 1540 + +/* MAX frame size supported by switch */ +#define EDMA_MAX_JUMBO_FRAME_SIZE 9216 + +/* Configurations */ +#define EDMA_INTR_CLEAR_TYPE 0 +#define EDMA_INTR_SW_IDX_W_TYPE 0 +#define EDMA_FIFO_THRESH_TYPE 0 +#define EDMA_RSS_TYPE 0 +#define EDMA_RX_IMT 0x0020 +#define EDMA_TX_IMT 0x0050 +#define EDMA_TPD_BURST 5 +#define EDMA_TXF_BURST 0x100 +#define EDMA_RFD_BURST 8 +#define EDMA_RFD_THR 16 +#define EDMA_RFD_LTHR 0 + +/* RX/TX per CPU based mask/shift */ +#define EDMA_TX_PER_CPU_MASK 0xF +#define EDMA_RX_PER_CPU_MASK 0x3 +#define EDMA_TX_PER_CPU_MASK_SHIFT 0x2 +#define EDMA_RX_PER_CPU_MASK_SHIFT 0x1 +#define EDMA_TX_CPU_START_SHIFT 0x2 +#define EDMA_RX_CPU_START_SHIFT 0x1 + +/* FLags used in transmit direction */ +#define EDMA_HW_CHECKSUM 0x00000001 +#define EDMA_VLAN_TX_TAG_INSERT_FLAG 0x00000002 +#define EDMA_VLAN_TX_TAG_INSERT_DEFAULT_FLAG 0x00000004 + +#define EDMA_SW_DESC_FLAG_LAST 0x1 +#define EDMA_SW_DESC_FLAG_SKB_HEAD 0x2 +#define EDMA_SW_DESC_FLAG_SKB_FRAG 0x4 +#define EDMA_SW_DESC_FLAG_SKB_FRAGLIST 0x8 +#define EDMA_SW_DESC_FLAG_SKB_NONE 0x10 +#define EDMA_SW_DESC_FLAG_SKB_REUSE 0x20 + + +#define EDMA_MAX_SKB_FRAGS (MAX_SKB_FRAGS + 1) + +/* Ethtool specific list of EDMA supported features */ +#define EDMA_SUPPORTED_FEATURES (SUPPORTED_10baseT_Half \ + | SUPPORTED_10baseT_Full \ + | SUPPORTED_100baseT_Half \ + | SUPPORTED_100baseT_Full \ + | SUPPORTED_1000baseT_Full) + +/* Recevie side atheros Header */ +#define EDMA_RX_ATH_HDR_VERSION 0x2 +#define EDMA_RX_ATH_HDR_VERSION_SHIFT 14 +#define EDMA_RX_ATH_HDR_PRIORITY_SHIFT 11 +#define EDMA_RX_ATH_PORT_TYPE_SHIFT 6 +#define EDMA_RX_ATH_HDR_RSTP_PORT_TYPE 0x4 + +/* Transmit side atheros Header */ +#define EDMA_TX_ATH_HDR_PORT_BITMAP_MASK 0x7F +#define EDMA_TX_ATH_HDR_FROM_CPU_MASK 0x80 +#define EDMA_TX_ATH_HDR_FROM_CPU_SHIFT 7 + +#define EDMA_TXQ_START_CORE0 8 +#define EDMA_TXQ_START_CORE1 12 +#define EDMA_TXQ_START_CORE2 0 +#define EDMA_TXQ_START_CORE3 4 + +#define EDMA_TXQ_IRQ_MASK_CORE0 0x0F00 +#define EDMA_TXQ_IRQ_MASK_CORE1 0xF000 +#define EDMA_TXQ_IRQ_MASK_CORE2 0x000F +#define EDMA_TXQ_IRQ_MASK_CORE3 0x00F0 + +#define EDMA_ETH_HDR_LEN 12 +#define EDMA_ETH_TYPE_MASK 0xFFFF + +#define EDMA_RX_BUFFER_WRITE 16 +#define EDMA_RFD_AVAIL_THR 80 + +#define EDMA_GMAC_NO_MDIO_PHY PHY_MAX_ADDR + +extern int ssdk_rfs_ipct_rule_set(__be32 ip_src, __be32 ip_dst, + __be16 sport, __be16 dport, + uint8_t proto, u16 loadbalance, bool action); +struct edma_ethtool_statistics { + u32 tx_q0_pkt; + u32 tx_q1_pkt; + u32 tx_q2_pkt; + u32 tx_q3_pkt; + u32 tx_q4_pkt; + u32 tx_q5_pkt; + u32 tx_q6_pkt; + u32 tx_q7_pkt; + u32 tx_q8_pkt; + u32 tx_q9_pkt; + u32 tx_q10_pkt; + u32 tx_q11_pkt; + u32 tx_q12_pkt; + u32 tx_q13_pkt; + u32 tx_q14_pkt; + u32 tx_q15_pkt; + u32 tx_q0_byte; + u32 tx_q1_byte; + u32 tx_q2_byte; + u32 tx_q3_byte; + u32 tx_q4_byte; + u32 tx_q5_byte; + u32 tx_q6_byte; + u32 tx_q7_byte; + u32 tx_q8_byte; + u32 tx_q9_byte; + u32 tx_q10_byte; + u32 tx_q11_byte; + u32 tx_q12_byte; + u32 tx_q13_byte; + u32 tx_q14_byte; + u32 tx_q15_byte; + u32 rx_q0_pkt; + u32 rx_q1_pkt; + u32 rx_q2_pkt; + u32 rx_q3_pkt; + u32 rx_q4_pkt; + u32 rx_q5_pkt; + u32 rx_q6_pkt; + u32 rx_q7_pkt; + u32 rx_q0_byte; + u32 rx_q1_byte; + u32 rx_q2_byte; + u32 rx_q3_byte; + u32 rx_q4_byte; + u32 rx_q5_byte; + u32 rx_q6_byte; + u32 rx_q7_byte; + u32 tx_desc_error; + u32 rx_alloc_fail_ctr; +}; + +struct edma_mdio_data { + struct mii_bus *mii_bus; + void __iomem *membase; + int phy_irq[PHY_MAX_ADDR]; +}; + +/* EDMA LINK state */ +enum edma_link_state { + __EDMA_LINKUP, /* Indicate link is UP */ + __EDMA_LINKDOWN /* Indicate link is down */ +}; + +/* EDMA GMAC state */ +enum edma_gmac_state { + __EDMA_UP /* use to indicate GMAC is up */ +}; + +/* edma transmit descriptor */ +struct edma_tx_desc { + __le16 len; /* full packet including CRC */ + __le16 svlan_tag; /* vlan tag */ + __le32 word1; /* byte 4-7 */ + __le32 addr; /* address of buffer */ + __le32 word3; /* byte 12 */ +}; + +/* edma receive return descriptor */ +struct edma_rx_return_desc { + u16 rrd0; + u16 rrd1; + u16 rrd2; + u16 rrd3; + u16 rrd4; + u16 rrd5; + u16 rrd6; + u16 rrd7; +}; + +/* RFD descriptor */ +struct edma_rx_free_desc { + __le32 buffer_addr; /* buffer address */ +}; + +/* edma hw specific data */ +struct edma_hw { + u32 __iomem *hw_addr; /* inner register address */ + struct edma_adapter *adapter; /* netdevice adapter */ + u32 rx_intr_mask; /*rx interrupt mask */ + u32 tx_intr_mask; /* tx interrupt nask */ + u32 misc_intr_mask; /* misc interrupt mask */ + u32 wol_intr_mask; /* wake on lan interrupt mask */ + bool intr_clear_type; /* interrupt clear */ + bool intr_sw_idx_w; /* interrupt software index */ + u32 rx_head_buff_size; /* Rx buffer size */ + u8 rss_type; /* rss protocol type */ +}; + +/* edma_sw_desc stores software descriptor + * SW descriptor has 1:1 map with HW descriptor + */ +struct edma_sw_desc { + struct sk_buff *skb; + dma_addr_t dma; /* dma address */ + u16 length; /* Tx/Rx buffer length */ + u32 flags; +}; + +/* per core related information */ +struct edma_per_cpu_queues_info { + struct napi_struct napi; /* napi associated with the core */ + u32 tx_mask; /* tx interrupt mask */ + u32 rx_mask; /* rx interrupt mask */ + u32 tx_status; /* tx interrupt status */ + u32 rx_status; /* rx interrupt status */ + u32 tx_start; /* tx queue start */ + u32 rx_start; /* rx queue start */ + struct edma_common_info *edma_cinfo; /* edma common info */ +}; + +/* edma specific common info */ +struct edma_common_info { + struct edma_tx_desc_ring *tpd_ring[16]; /* 16 Tx queues */ + struct edma_rfd_desc_ring *rfd_ring[8]; /* 8 Rx queues */ + struct platform_device *pdev; /* device structure */ + struct net_device *netdev[EDMA_MAX_PORTID_SUPPORTED]; + struct net_device *portid_netdev_lookup_tbl[EDMA_MAX_PORTID_BITMAP_INDEX]; + struct ctl_table_header *edma_ctl_table_hdr; + int num_gmac; + struct edma_ethtool_statistics edma_ethstats; /* ethtool stats */ + int num_rx_queues; /* number of rx queue */ + u32 num_tx_queues; /* number of tx queue */ + u32 tx_irq[16]; /* number of tx irq */ + u32 rx_irq[8]; /* number of rx irq */ + u32 from_cpu; /* from CPU TPD field */ + u32 num_rxq_per_core; /* Rx queues per core */ + u32 num_txq_per_core; /* Tx queues per core */ + u16 tx_ring_count; /* Tx ring count */ + u16 rx_ring_count; /* Rx ring*/ + u16 rx_head_buffer_len; /* rx buffer length */ + u16 rx_page_buffer_len; /* rx buffer length */ + u32 page_mode; /* Jumbo frame supported flag */ + u32 fraglist_mode; /* fraglist supported flag */ + struct edma_hw hw; /* edma hw specific structure */ + struct edma_per_cpu_queues_info edma_percpu_info[CONFIG_NR_CPUS]; /* per cpu information */ + spinlock_t stats_lock; /* protect edma stats area for updation */ + struct timer_list edma_stats_timer; + bool is_single_phy; + void __iomem *ess_hw_addr; + struct clk *ess_clk; +}; + +/* transimit packet descriptor (tpd) ring */ +struct edma_tx_desc_ring { + struct netdev_queue *nq[EDMA_MAX_NETDEV_PER_QUEUE]; /* Linux queue index */ + struct net_device *netdev[EDMA_MAX_NETDEV_PER_QUEUE]; + /* Array of netdevs associated with the tpd ring */ + void *hw_desc; /* descriptor ring virtual address */ + struct edma_sw_desc *sw_desc; /* buffer associated with ring */ + int netdev_bmp; /* Bitmap for per-ring netdevs */ + u32 size; /* descriptor ring length in bytes */ + u16 count; /* number of descriptors in the ring */ + dma_addr_t dma; /* descriptor ring physical address */ + u16 sw_next_to_fill; /* next Tx descriptor to fill */ + u16 sw_next_to_clean; /* next Tx descriptor to clean */ +}; + +/* receive free descriptor (rfd) ring */ +struct edma_rfd_desc_ring { + void *hw_desc; /* descriptor ring virtual address */ + struct edma_sw_desc *sw_desc; /* buffer associated with ring */ + u16 size; /* bytes allocated to sw_desc */ + u16 count; /* number of descriptors in the ring */ + dma_addr_t dma; /* descriptor ring physical address */ + u16 sw_next_to_fill; /* next descriptor to fill */ + u16 sw_next_to_clean; /* next descriptor to clean */ + u16 pending_fill; /* fill pending from previous iteration */ +}; + +/* edma_rfs_flter_node - rfs filter node in hash table */ +struct edma_rfs_filter_node { + struct flow_keys keys; + u32 flow_id; /* flow_id of filter provided by kernel */ + u16 filter_id; /* filter id of filter returned by adaptor */ + u16 rq_id; /* desired rq index */ + struct hlist_node node; /* edma rfs list node */ +}; + +/* edma_rfs_flow_tbl - rfs flow table */ +struct edma_rfs_flow_table { + u16 max_num_filter; /* Maximum number of filters edma supports */ + u16 hashtoclean; /* hash table index to clean next */ + int filter_available; /* Number of free filters available */ + struct hlist_head hlist_head[EDMA_RFS_FLOW_ENTRIES]; + spinlock_t rfs_ftab_lock; + struct timer_list expire_rfs; /* timer function for edma_rps_may_expire_flow */ +}; + +/* EDMA net device structure */ +struct edma_adapter { + struct net_device *netdev; /* netdevice */ + struct platform_device *pdev; /* platform device */ + struct edma_common_info *edma_cinfo; /* edma common info */ + struct phy_device *phydev; /* Phy device */ + struct edma_rfs_flow_table rfs; /* edma rfs flow table */ + struct net_device_stats stats; /* netdev statistics */ + set_rfs_filter_callback_t set_rfs_rule; + u32 flags;/* status flags */ + unsigned long state_flags; /* GMAC up/down flags */ + u32 forced_speed; /* link force speed */ + u32 forced_duplex; /* link force duplex */ + u32 link_state; /* phy link state */ + u32 phy_mdio_addr; /* PHY device address on MII interface */ + u32 poll_required; /* check if link polling is required */ + u32 tx_start_offset[CONFIG_NR_CPUS]; /* tx queue start */ + u32 default_vlan_tag; /* vlan tag */ + u32 dp_bitmap; + uint8_t phy_id[MII_BUS_ID_SIZE + 3]; +}; + +int edma_alloc_queues_tx(struct edma_common_info *edma_cinfo); +int edma_alloc_queues_rx(struct edma_common_info *edma_cinfo); +int edma_open(struct net_device *netdev); +int edma_close(struct net_device *netdev); +void edma_free_tx_resources(struct edma_common_info *edma_c_info); +void edma_free_rx_resources(struct edma_common_info *edma_c_info); +int edma_alloc_tx_rings(struct edma_common_info *edma_cinfo); +int edma_alloc_rx_rings(struct edma_common_info *edma_cinfo); +void edma_free_tx_rings(struct edma_common_info *edma_cinfo); +void edma_free_rx_rings(struct edma_common_info *edma_cinfo); +void edma_free_queues(struct edma_common_info *edma_cinfo); +void edma_irq_disable(struct edma_common_info *edma_cinfo); +int edma_reset(struct edma_common_info *edma_cinfo); +int edma_poll(struct napi_struct *napi, int budget); +netdev_tx_t edma_xmit(struct sk_buff *skb, + struct net_device *netdev); +int edma_configure(struct edma_common_info *edma_cinfo); +void edma_irq_enable(struct edma_common_info *edma_cinfo); +void edma_enable_tx_ctrl(struct edma_hw *hw); +void edma_enable_rx_ctrl(struct edma_hw *hw); +void edma_stop_rx_tx(struct edma_hw *hw); +void edma_free_irqs(struct edma_adapter *adapter); +irqreturn_t edma_interrupt(int irq, void *dev); +void edma_write_reg(u16 reg_addr, u32 reg_value); +void edma_read_reg(u16 reg_addr, volatile u32 *reg_value); +struct net_device_stats *edma_get_stats(struct net_device *netdev); +int edma_set_mac_addr(struct net_device *netdev, void *p); +int edma_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, + u16 rxq, u32 flow_id); +int edma_register_rfs_filter(struct net_device *netdev, + set_rfs_filter_callback_t set_filter); +void edma_flow_may_expire(struct timer_list *t); +void edma_set_ethtool_ops(struct net_device *netdev); +void edma_set_stp_rstp(bool tag); +void edma_assign_ath_hdr_type(int tag); +int edma_get_default_vlan_tag(struct net_device *netdev); +void edma_adjust_link(struct net_device *netdev); +int edma_fill_netdev(struct edma_common_info *edma_cinfo, int qid, int num, int txq_id); +void edma_read_append_stats(struct edma_common_info *edma_cinfo); +void edma_change_tx_coalesce(int usecs); +void edma_change_rx_coalesce(int usecs); +void edma_get_tx_rx_coalesce(u32 *reg_val); +void edma_clear_irq_status(void); +void ess_set_port_status_speed(struct edma_common_info *edma_cinfo, + struct phy_device *phydev, uint8_t port_id); +#endif /* _EDMA_H_ */ diff --git a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_axi.c b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_axi.c new file mode 100644 index 00000000..50335b0d --- /dev/null +++ b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_axi.c @@ -0,0 +1,1359 @@ +/* + * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "edma.h" +#include "ess_edma.h" + +/* Weight round robin and virtual QID mask */ +#define EDMA_WRR_VID_SCTL_MASK 0xffff + +/* Weight round robin and virtual QID shift */ +#define EDMA_WRR_VID_SCTL_SHIFT 16 + +char edma_axi_driver_name[] = "ess_edma"; +static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | + NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP; + +static u32 edma_hw_addr; + +char edma_tx_irq[16][64]; +char edma_rx_irq[8][64]; +struct net_device *edma_netdev[EDMA_MAX_PORTID_SUPPORTED]; +static u16 tx_start[4] = {EDMA_TXQ_START_CORE0, EDMA_TXQ_START_CORE1, + EDMA_TXQ_START_CORE2, EDMA_TXQ_START_CORE3}; +static u32 tx_mask[4] = {EDMA_TXQ_IRQ_MASK_CORE0, EDMA_TXQ_IRQ_MASK_CORE1, + EDMA_TXQ_IRQ_MASK_CORE2, EDMA_TXQ_IRQ_MASK_CORE3}; + +static u32 edma_default_ltag __read_mostly = EDMA_LAN_DEFAULT_VLAN; +static u32 edma_default_wtag __read_mostly = EDMA_WAN_DEFAULT_VLAN; +static u32 edma_default_group1_vtag __read_mostly = EDMA_DEFAULT_GROUP1_VLAN; +static u32 edma_default_group2_vtag __read_mostly = EDMA_DEFAULT_GROUP2_VLAN; +static u32 edma_default_group3_vtag __read_mostly = EDMA_DEFAULT_GROUP3_VLAN; +static u32 edma_default_group4_vtag __read_mostly = EDMA_DEFAULT_GROUP4_VLAN; +static u32 edma_default_group5_vtag __read_mostly = EDMA_DEFAULT_GROUP5_VLAN; +static u32 edma_rss_idt_val = EDMA_RSS_IDT_VALUE; +static u32 edma_rss_idt_idx; + +static int edma_weight_assigned_to_q __read_mostly; +static int edma_queue_to_virtual_q __read_mostly; +static bool edma_enable_rstp __read_mostly; +static int edma_athr_hdr_eth_type __read_mostly; + +static int page_mode; +module_param(page_mode, int, 0); +MODULE_PARM_DESC(page_mode, "enable page mode"); + +static int overwrite_mode; +module_param(overwrite_mode, int, 0); +MODULE_PARM_DESC(overwrite_mode, "overwrite default page_mode setting"); + +static int jumbo_mru = EDMA_RX_HEAD_BUFF_SIZE; +module_param(jumbo_mru, int, 0); +MODULE_PARM_DESC(jumbo_mru, "enable fraglist support"); + +static int num_rxq = 4; +module_param(num_rxq, int, 0); +MODULE_PARM_DESC(num_rxq, "change the number of rx queues"); + +void edma_write_reg(u16 reg_addr, u32 reg_value) +{ + writel(reg_value, ((void __iomem *)(edma_hw_addr + reg_addr))); +} + +void edma_read_reg(u16 reg_addr, volatile u32 *reg_value) +{ + *reg_value = readl((void __iomem *)(edma_hw_addr + reg_addr)); +} + +static void ess_write_reg(struct edma_common_info *edma, u16 reg_addr, u32 reg_value) +{ + writel(reg_value, ((void __iomem *) + ((unsigned long)edma->ess_hw_addr + reg_addr))); +} + +static void ess_read_reg(struct edma_common_info *edma, u16 reg_addr, + volatile u32 *reg_value) +{ + *reg_value = readl((void __iomem *) + ((unsigned long)edma->ess_hw_addr + reg_addr)); +} + +static int ess_reset(struct edma_common_info *edma) +{ + struct device_node *switch_node = NULL; + struct reset_control *ess_rst; + u32 regval; + + switch_node = of_find_node_by_name(NULL, "ess-switch"); + if (!switch_node) { + pr_err("switch-node not found\n"); + return -EINVAL; + } + + ess_rst = of_reset_control_get(switch_node, "ess_rst"); + of_node_put(switch_node); + + if (IS_ERR(ess_rst)) { + pr_err("failed to find ess_rst!\n"); + return -ENOENT; + } + + reset_control_assert(ess_rst); + msleep(10); + reset_control_deassert(ess_rst); + msleep(100); + reset_control_put(ess_rst); + + /* Enable only port 5 <--> port 0 + * bits 0:6 bitmap of ports it can fwd to */ +#define SET_PORT_BMP(r,v) \ + ess_read_reg(edma, r, ®val); \ + ess_write_reg(edma, r, ((regval & ~0x3F) | v)); + + SET_PORT_BMP(ESS_PORT0_LOOKUP_CTRL,0x20); + SET_PORT_BMP(ESS_PORT1_LOOKUP_CTRL,0x00); + SET_PORT_BMP(ESS_PORT2_LOOKUP_CTRL,0x00); + SET_PORT_BMP(ESS_PORT3_LOOKUP_CTRL,0x00); + SET_PORT_BMP(ESS_PORT4_LOOKUP_CTRL,0x00); + SET_PORT_BMP(ESS_PORT5_LOOKUP_CTRL,0x01); + ess_write_reg(edma, ESS_RGMII_CTRL, 0x400); + ess_write_reg(edma, ESS_PORT0_STATUS, ESS_PORT_1G_FDX); + ess_write_reg(edma, ESS_PORT5_STATUS, ESS_PORT_1G_FDX); + ess_write_reg(edma, ESS_PORT0_HEADER_CTRL, 0); +#undef SET_PORT_BMP + + /* forward multicast and broadcast frames to CPU */ + ess_write_reg(edma, ESS_FWD_CTRL1, + (ESS_PORTS_ALL << ESS_FWD_CTRL1_UC_FLOOD_S) | + (ESS_PORTS_ALL << ESS_FWD_CTRL1_MC_FLOOD_S) | + (ESS_PORTS_ALL << ESS_FWD_CTRL1_BC_FLOOD_S)); + + return 0; +} + +void ess_set_port_status_speed(struct edma_common_info *edma, + struct phy_device *phydev, uint8_t port_id) +{ + uint16_t reg_off = ESS_PORT0_STATUS + (4 * port_id); + uint32_t reg_val = 0; + + ess_read_reg(edma, reg_off, ®_val); + + /* reset the speed bits [0:1] */ + reg_val &= ~ESS_PORT_STATUS_SPEED_INV; + + /* set the new speed */ + switch(phydev->speed) { + case SPEED_1000: reg_val |= ESS_PORT_STATUS_SPEED_1000; break; + case SPEED_100: reg_val |= ESS_PORT_STATUS_SPEED_100; break; + case SPEED_10: reg_val |= ESS_PORT_STATUS_SPEED_10; break; + default: reg_val |= ESS_PORT_STATUS_SPEED_INV; break; + } + + /* check full/half duplex */ + if (phydev->duplex) { + reg_val |= ESS_PORT_STATUS_DUPLEX_MODE; + } else { + reg_val &= ~ESS_PORT_STATUS_DUPLEX_MODE; + } + + ess_write_reg(edma, reg_off, reg_val); +} + +/* edma_change_tx_coalesce() + * change tx interrupt moderation timer + */ +void edma_change_tx_coalesce(int usecs) +{ + u32 reg_value; + + /* Here, we right shift the value from the user by 1, this is + * done because IMT resolution timer is 2usecs. 1 count + * of this register corresponds to 2 usecs. + */ + edma_read_reg(EDMA_REG_IRQ_MODRT_TIMER_INIT, ®_value); + reg_value = ((reg_value & 0xffff) | ((usecs >> 1) << 16)); + edma_write_reg(EDMA_REG_IRQ_MODRT_TIMER_INIT, reg_value); +} + +/* edma_change_rx_coalesce() + * change rx interrupt moderation timer + */ +void edma_change_rx_coalesce(int usecs) +{ + u32 reg_value; + + /* Here, we right shift the value from the user by 1, this is + * done because IMT resolution timer is 2usecs. 1 count + * of this register corresponds to 2 usecs. + */ + edma_read_reg(EDMA_REG_IRQ_MODRT_TIMER_INIT, ®_value); + reg_value = ((reg_value & 0xffff0000) | (usecs >> 1)); + edma_write_reg(EDMA_REG_IRQ_MODRT_TIMER_INIT, reg_value); +} + +/* edma_get_tx_rx_coalesce() + * Get tx/rx interrupt moderation value + */ +void edma_get_tx_rx_coalesce(u32 *reg_val) +{ + edma_read_reg(EDMA_REG_IRQ_MODRT_TIMER_INIT, reg_val); +} + +void edma_read_append_stats(struct edma_common_info *edma_cinfo) +{ + uint32_t *p; + int i; + u32 stat; + + spin_lock_bh(&edma_cinfo->stats_lock); + p = (uint32_t *)&(edma_cinfo->edma_ethstats); + + for (i = 0; i < EDMA_MAX_TRANSMIT_QUEUE; i++) { + edma_read_reg(EDMA_REG_TX_STAT_PKT_Q(i), &stat); + *p += stat; + p++; + } + + for (i = 0; i < EDMA_MAX_TRANSMIT_QUEUE; i++) { + edma_read_reg(EDMA_REG_TX_STAT_BYTE_Q(i), &stat); + *p += stat; + p++; + } + + for (i = 0; i < EDMA_MAX_RECEIVE_QUEUE; i++) { + edma_read_reg(EDMA_REG_RX_STAT_PKT_Q(i), &stat); + *p += stat; + p++; + } + + for (i = 0; i < EDMA_MAX_RECEIVE_QUEUE; i++) { + edma_read_reg(EDMA_REG_RX_STAT_BYTE_Q(i), &stat); + *p += stat; + p++; + } + + spin_unlock_bh(&edma_cinfo->stats_lock); +} + +static void edma_statistics_timer(struct timer_list *t) +{ + struct edma_common_info *edma_cinfo = + from_timer(edma_cinfo, t, edma_stats_timer); + + edma_read_append_stats(edma_cinfo); + + mod_timer(&edma_cinfo->edma_stats_timer, jiffies + 1*HZ); +} + +static int edma_enable_stp_rstp(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int ret; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (write) + edma_set_stp_rstp(edma_enable_rstp); + + return ret; +} + +static int edma_ath_hdr_eth_type(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int ret; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (write) + edma_assign_ath_hdr_type(edma_athr_hdr_eth_type); + + return ret; +} + +static int edma_change_default_lan_vlan(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + struct edma_adapter *adapter; + int ret; + + if (!edma_netdev[1]) { + pr_err("Netdevice for default_lan does not exist\n"); + return -1; + } + + adapter = netdev_priv(edma_netdev[1]); + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + + if (write) + adapter->default_vlan_tag = edma_default_ltag; + + return ret; +} + +static int edma_change_default_wan_vlan(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + struct edma_adapter *adapter; + int ret; + + if (!edma_netdev[0]) { + pr_err("Netdevice for default_wan does not exist\n"); + return -1; + } + + adapter = netdev_priv(edma_netdev[0]); + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + + if (write) + adapter->default_vlan_tag = edma_default_wtag; + + return ret; +} + +static int edma_change_group1_vtag(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + struct edma_adapter *adapter; + struct edma_common_info *edma_cinfo; + int ret; + + if (!edma_netdev[0]) { + pr_err("Netdevice for Group 1 does not exist\n"); + return -1; + } + + adapter = netdev_priv(edma_netdev[0]); + edma_cinfo = adapter->edma_cinfo; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + + if (write) + adapter->default_vlan_tag = edma_default_group1_vtag; + + return ret; +} + +static int edma_change_group2_vtag(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + struct edma_adapter *adapter; + struct edma_common_info *edma_cinfo; + int ret; + + if (!edma_netdev[1]) { + pr_err("Netdevice for Group 2 does not exist\n"); + return -1; + } + + adapter = netdev_priv(edma_netdev[1]); + edma_cinfo = adapter->edma_cinfo; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + + if (write) + adapter->default_vlan_tag = edma_default_group2_vtag; + + return ret; +} + +static int edma_change_group3_vtag(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + struct edma_adapter *adapter; + struct edma_common_info *edma_cinfo; + int ret; + + if (!edma_netdev[2]) { + pr_err("Netdevice for Group 3 does not exist\n"); + return -1; + } + + adapter = netdev_priv(edma_netdev[2]); + edma_cinfo = adapter->edma_cinfo; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + + if (write) + adapter->default_vlan_tag = edma_default_group3_vtag; + + return ret; +} + +static int edma_change_group4_vtag(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + struct edma_adapter *adapter; + struct edma_common_info *edma_cinfo; + int ret; + + if (!edma_netdev[3]) { + pr_err("Netdevice for Group 4 does not exist\n"); + return -1; + } + + adapter = netdev_priv(edma_netdev[3]); + edma_cinfo = adapter->edma_cinfo; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + + if (write) + adapter->default_vlan_tag = edma_default_group4_vtag; + + return ret; +} + +static int edma_change_group5_vtag(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + struct edma_adapter *adapter; + struct edma_common_info *edma_cinfo; + int ret; + + if (!edma_netdev[4]) { + pr_err("Netdevice for Group 5 does not exist\n"); + return -1; + } + + adapter = netdev_priv(edma_netdev[4]); + edma_cinfo = adapter->edma_cinfo; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + + if (write) + adapter->default_vlan_tag = edma_default_group5_vtag; + + return ret; +} + +static int edma_set_rss_idt_value(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int ret; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (write && !ret) + edma_write_reg(EDMA_REG_RSS_IDT(edma_rss_idt_idx), + edma_rss_idt_val); + return ret; +} + +static int edma_set_rss_idt_idx(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int ret; + u32 old_value = edma_rss_idt_idx; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (!write || ret) + return ret; + + if (edma_rss_idt_idx >= EDMA_NUM_IDT) { + pr_err("Invalid RSS indirection table index %d\n", + edma_rss_idt_idx); + edma_rss_idt_idx = old_value; + return -EINVAL; + } + return ret; +} + +static int edma_weight_assigned_to_queues(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int ret, queue_id, weight; + u32 reg_data, data, reg_addr; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (write) { + queue_id = edma_weight_assigned_to_q & EDMA_WRR_VID_SCTL_MASK; + if (queue_id < 0 || queue_id > 15) { + pr_err("queue_id not within desired range\n"); + return -EINVAL; + } + + weight = edma_weight_assigned_to_q >> EDMA_WRR_VID_SCTL_SHIFT; + if (weight < 0 || weight > 0xF) { + pr_err("queue_id not within desired range\n"); + return -EINVAL; + } + + data = weight << EDMA_WRR_SHIFT(queue_id); + + reg_addr = EDMA_REG_WRR_CTRL_Q0_Q3 + (queue_id & ~0x3); + edma_read_reg(reg_addr, ®_data); + reg_data &= ~(1 << EDMA_WRR_SHIFT(queue_id)); + edma_write_reg(reg_addr, data | reg_data); + } + + return ret; +} + +static int edma_queue_to_virtual_queue_map(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int ret, queue_id, virtual_qid; + u32 reg_data, data, reg_addr; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (write) { + queue_id = edma_queue_to_virtual_q & EDMA_WRR_VID_SCTL_MASK; + if (queue_id < 0 || queue_id > 15) { + pr_err("queue_id not within desired range\n"); + return -EINVAL; + } + + virtual_qid = edma_queue_to_virtual_q >> + EDMA_WRR_VID_SCTL_SHIFT; + if (virtual_qid < 0 || virtual_qid > 8) { + pr_err("queue_id not within desired range\n"); + return -EINVAL; + } + + data = virtual_qid << EDMA_VQ_ID_SHIFT(queue_id); + + reg_addr = EDMA_REG_VQ_CTRL0 + (queue_id & ~0x3); + edma_read_reg(reg_addr, ®_data); + reg_data &= ~(1 << EDMA_VQ_ID_SHIFT(queue_id)); + edma_write_reg(reg_addr, data | reg_data); + } + + return ret; +} + +static struct ctl_table edma_table[] = { + { + .procname = "default_lan_tag", + .data = &edma_default_ltag, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_change_default_lan_vlan + }, + { + .procname = "default_wan_tag", + .data = &edma_default_wtag, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_change_default_wan_vlan + }, + { + .procname = "weight_assigned_to_queues", + .data = &edma_weight_assigned_to_q, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_weight_assigned_to_queues + }, + { + .procname = "queue_to_virtual_queue_map", + .data = &edma_queue_to_virtual_q, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_queue_to_virtual_queue_map + }, + { + .procname = "enable_stp_rstp", + .data = &edma_enable_rstp, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_enable_stp_rstp + }, + { + .procname = "athr_hdr_eth_type", + .data = &edma_athr_hdr_eth_type, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_ath_hdr_eth_type + }, + { + .procname = "default_group1_vlan_tag", + .data = &edma_default_group1_vtag, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_change_group1_vtag + }, + { + .procname = "default_group2_vlan_tag", + .data = &edma_default_group2_vtag, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_change_group2_vtag + }, + { + .procname = "default_group3_vlan_tag", + .data = &edma_default_group3_vtag, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_change_group3_vtag + }, + { + .procname = "default_group4_vlan_tag", + .data = &edma_default_group4_vtag, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_change_group4_vtag + }, + { + .procname = "default_group5_vlan_tag", + .data = &edma_default_group5_vtag, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_change_group5_vtag + }, + { + .procname = "edma_rss_idt_value", + .data = &edma_rss_idt_val, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_set_rss_idt_value + }, + { + .procname = "edma_rss_idt_idx", + .data = &edma_rss_idt_idx, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = edma_set_rss_idt_idx + }, + {} +}; + +static int ess_parse(struct edma_common_info *edma) +{ + struct device_node *switch_node; + int ret = -EINVAL; + + switch_node = of_find_node_by_name(NULL, "ess-switch"); + if (!switch_node) { + pr_err("cannot find ess-switch node\n"); + goto out; + } + + edma->ess_hw_addr = of_io_request_and_map(switch_node, + 0, KBUILD_MODNAME); + if (!edma->ess_hw_addr) { + pr_err("%s ioremap fail.", __func__); + goto out; + } + + edma->ess_clk = of_clk_get_by_name(switch_node, "ess_clk"); + ret = clk_prepare_enable(edma->ess_clk); +out: + of_node_put(switch_node); + return ret; +} + +/* edma_axi_netdev_ops + * Describe the operations supported by registered netdevices + * + * static const struct net_device_ops edma_axi_netdev_ops = { + * .ndo_open = edma_open, + * .ndo_stop = edma_close, + * .ndo_start_xmit = edma_xmit_frame, + * .ndo_set_mac_address = edma_set_mac_addr, + * } + */ +static const struct net_device_ops edma_axi_netdev_ops = { + .ndo_open = edma_open, + .ndo_stop = edma_close, + .ndo_start_xmit = edma_xmit, + .ndo_set_mac_address = edma_set_mac_addr, +#ifdef CONFIG_RFS_ACCEL + .ndo_rx_flow_steer = edma_rx_flow_steer, + .ndo_register_rfs_filter = edma_register_rfs_filter, + .ndo_get_default_vlan_tag = edma_get_default_vlan_tag, +#endif + .ndo_get_stats = edma_get_stats, +}; + +/* edma_axi_probe() + * Initialise an adapter identified by a platform_device structure. + * + * The OS initialization, configuring of the adapter private structure, + * and a hardware reset occur in the probe. + */ +static int edma_axi_probe(struct platform_device *pdev) +{ + struct edma_common_info *edma_cinfo; + struct edma_hw *hw; + struct edma_adapter *adapter[EDMA_MAX_PORTID_SUPPORTED]; + struct resource *res; + struct device_node *np = pdev->dev.of_node; + struct device_node *pnp; + struct device_node *mdio_node = NULL; + struct platform_device *mdio_plat = NULL; + struct mii_bus *miibus = NULL; + struct edma_mdio_data *mdio_data = NULL; + int i, j, k, err = 0; + int portid_bmp; + int idx = 0, idx_mac = 0; + + if (CONFIG_NR_CPUS != EDMA_CPU_CORES_SUPPORTED) { + dev_err(&pdev->dev, "Invalid CPU Cores\n"); + return -EINVAL; + } + + if ((num_rxq != 4) && (num_rxq != 8)) { + dev_err(&pdev->dev, "Invalid RX queue, edma probe failed\n"); + return -EINVAL; + } + edma_cinfo = kzalloc(sizeof(struct edma_common_info), GFP_KERNEL); + if (!edma_cinfo) { + err = -ENOMEM; + goto err_alloc; + } + + edma_cinfo->pdev = pdev; + + of_property_read_u32(np, "qcom,num_gmac", &edma_cinfo->num_gmac); + if (edma_cinfo->num_gmac > EDMA_MAX_PORTID_SUPPORTED) { + pr_err("Invalid DTSI Entry for qcom,num_gmac\n"); + err = -EINVAL; + goto err_cinfo; + } + + /* Initialize the netdev array before allocation + * to avoid double free + */ + for (i = 0 ; i < edma_cinfo->num_gmac ; i++) + edma_netdev[i] = NULL; + + for (i = 0 ; i < edma_cinfo->num_gmac ; i++) { + edma_netdev[i] = alloc_etherdev_mqs(sizeof(struct edma_adapter), + EDMA_NETDEV_TX_QUEUE, EDMA_NETDEV_RX_QUEUE); + + if (!edma_netdev[i]) { + dev_err(&pdev->dev, + "net device alloc fails for index=%d\n", i); + err = -ENODEV; + goto err_ioremap; + } + + SET_NETDEV_DEV(edma_netdev[i], &pdev->dev); + platform_set_drvdata(pdev, edma_netdev[i]); + edma_cinfo->netdev[i] = edma_netdev[i]; + } + + /* Fill ring details */ + edma_cinfo->num_tx_queues = EDMA_MAX_TRANSMIT_QUEUE; + edma_cinfo->num_txq_per_core = (EDMA_MAX_TRANSMIT_QUEUE / 4); + edma_cinfo->tx_ring_count = EDMA_TX_RING_SIZE; + + /* Update num rx queues based on module parameter */ + edma_cinfo->num_rx_queues = num_rxq; + edma_cinfo->num_rxq_per_core = ((num_rxq == 4) ? 1 : 2); + + edma_cinfo->rx_ring_count = EDMA_RX_RING_SIZE; + + hw = &edma_cinfo->hw; + + /* Fill HW defaults */ + hw->tx_intr_mask = EDMA_TX_IMR_NORMAL_MASK; + hw->rx_intr_mask = EDMA_RX_IMR_NORMAL_MASK; + + of_property_read_u32(np, "qcom,page-mode", &edma_cinfo->page_mode); + of_property_read_u32(np, "qcom,rx_head_buf_size", + &hw->rx_head_buff_size); + + if (overwrite_mode) { + dev_info(&pdev->dev, "page mode overwritten"); + edma_cinfo->page_mode = page_mode; + } + + if (jumbo_mru) + edma_cinfo->fraglist_mode = 1; + + if (edma_cinfo->page_mode) + hw->rx_head_buff_size = EDMA_RX_HEAD_BUFF_SIZE_JUMBO; + else if (edma_cinfo->fraglist_mode) + hw->rx_head_buff_size = jumbo_mru; + else if (!hw->rx_head_buff_size) + hw->rx_head_buff_size = EDMA_RX_HEAD_BUFF_SIZE; + + hw->misc_intr_mask = 0; + hw->wol_intr_mask = 0; + + hw->intr_clear_type = EDMA_INTR_CLEAR_TYPE; + hw->intr_sw_idx_w = EDMA_INTR_SW_IDX_W_TYPE; + + /* configure RSS type to the different protocol that can be + * supported + */ + hw->rss_type = EDMA_RSS_TYPE_IPV4TCP | EDMA_RSS_TYPE_IPV6_TCP | + EDMA_RSS_TYPE_IPV4_UDP | EDMA_RSS_TYPE_IPV6UDP | + EDMA_RSS_TYPE_IPV4 | EDMA_RSS_TYPE_IPV6; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + edma_cinfo->hw.hw_addr = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(edma_cinfo->hw.hw_addr)) { + err = PTR_ERR(edma_cinfo->hw.hw_addr); + goto err_ioremap; + } + + edma_hw_addr = (u32)edma_cinfo->hw.hw_addr; + + /* Parse tx queue interrupt number from device tree */ + for (i = 0; i < edma_cinfo->num_tx_queues; i++) + edma_cinfo->tx_irq[i] = platform_get_irq(pdev, i); + + /* Parse rx queue interrupt number from device tree + * Here we are setting j to point to the point where we + * left tx interrupt parsing(i.e 16) and run run the loop + * from 0 to 7 to parse rx interrupt number. + */ + for (i = 0, j = edma_cinfo->num_tx_queues, k = 0; + i < edma_cinfo->num_rx_queues; i++) { + edma_cinfo->rx_irq[k] = platform_get_irq(pdev, j); + k += ((num_rxq == 4) ? 2 : 1); + j += ((num_rxq == 4) ? 2 : 1); + } + + edma_cinfo->rx_head_buffer_len = edma_cinfo->hw.rx_head_buff_size; + edma_cinfo->rx_page_buffer_len = PAGE_SIZE; + + err = edma_alloc_queues_tx(edma_cinfo); + if (err) { + dev_err(&pdev->dev, "Allocation of TX queue failed\n"); + goto err_tx_qinit; + } + + err = edma_alloc_queues_rx(edma_cinfo); + if (err) { + dev_err(&pdev->dev, "Allocation of RX queue failed\n"); + goto err_rx_qinit; + } + + err = edma_alloc_tx_rings(edma_cinfo); + if (err) { + dev_err(&pdev->dev, "Allocation of TX resources failed\n"); + goto err_tx_rinit; + } + + err = edma_alloc_rx_rings(edma_cinfo); + if (err) { + dev_err(&pdev->dev, "Allocation of RX resources failed\n"); + goto err_rx_rinit; + } + + /* Initialize netdev and netdev bitmap for transmit descriptor rings */ + for (i = 0; i < edma_cinfo->num_tx_queues; i++) { + struct edma_tx_desc_ring *etdr = edma_cinfo->tpd_ring[i]; + int j; + + etdr->netdev_bmp = 0; + for (j = 0; j < EDMA_MAX_NETDEV_PER_QUEUE; j++) { + etdr->netdev[j] = NULL; + etdr->nq[j] = NULL; + } + } + + if (of_property_read_bool(np, "qcom,mdio_supported")) { + mdio_node = of_find_compatible_node(NULL, NULL, + "qcom,ipq4019-mdio"); + if (!mdio_node) { + dev_err(&pdev->dev, "cannot find mdio node by phandle"); + err = -EIO; + goto err_mdiobus_init_fail; + } + + mdio_plat = of_find_device_by_node(mdio_node); + if (!mdio_plat) { + dev_err(&pdev->dev, + "cannot find platform device from mdio node"); + of_node_put(mdio_node); + err = -EIO; + goto err_mdiobus_init_fail; + } + + mdio_data = dev_get_drvdata(&mdio_plat->dev); + if (!mdio_data) { + dev_err(&pdev->dev, + "cannot get mii bus reference from device data"); + of_node_put(mdio_node); + err = -EIO; + goto err_mdiobus_init_fail; + } + + miibus = mdio_data->mii_bus; + } + + if (of_property_read_bool(np, "qcom,single-phy") && + edma_cinfo->num_gmac == 1) { + err = ess_parse(edma_cinfo); + if (!err) + err = ess_reset(edma_cinfo); + if (err) + goto err_single_phy_init; + else + edma_cinfo->is_single_phy = true; + } + + for_each_available_child_of_node(np, pnp) { + const char *mac_addr; + + /* this check is needed if parent and daughter dts have + * different number of gmac nodes + */ + if (idx_mac == edma_cinfo->num_gmac) { + of_node_put(np); + break; + } + + mac_addr = of_get_mac_address(pnp); + if (!IS_ERR(mac_addr)) + memcpy(edma_netdev[idx_mac]->dev_addr, mac_addr, ETH_ALEN); + + idx_mac++; + } + + /* Populate the adapter structure register the netdevice */ + for (i = 0; i < edma_cinfo->num_gmac; i++) { + int k, m; + + adapter[i] = netdev_priv(edma_netdev[i]); + adapter[i]->netdev = edma_netdev[i]; + adapter[i]->pdev = pdev; + for (j = 0; j < CONFIG_NR_CPUS; j++) { + m = i % 2; + adapter[i]->tx_start_offset[j] = + ((j << EDMA_TX_CPU_START_SHIFT) + (m << 1)); + /* Share the queues with available net-devices. + * For instance , with 5 net-devices + * eth0/eth2/eth4 will share q0,q1,q4,q5,q8,q9,q12,q13 + * and eth1/eth3 will get the remaining. + */ + for (k = adapter[i]->tx_start_offset[j]; k < + (adapter[i]->tx_start_offset[j] + 2); k++) { + if (edma_fill_netdev(edma_cinfo, k, i, j)) { + pr_err("Netdev overflow Error\n"); + goto err_register; + } + } + } + + adapter[i]->edma_cinfo = edma_cinfo; + edma_netdev[i]->netdev_ops = &edma_axi_netdev_ops; + edma_netdev[i]->max_mtu = 9000; + edma_netdev[i]->features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM + | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_SG | + NETIF_F_TSO | NETIF_F_GRO; + edma_netdev[i]->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM | + NETIF_F_HW_VLAN_CTAG_RX + | NETIF_F_SG | NETIF_F_TSO | NETIF_F_GRO; + edma_netdev[i]->vlan_features = NETIF_F_HW_CSUM | NETIF_F_SG | + NETIF_F_TSO | NETIF_F_GRO; + edma_netdev[i]->wanted_features = NETIF_F_HW_CSUM | NETIF_F_SG | + NETIF_F_TSO | NETIF_F_GRO; + +#ifdef CONFIG_RFS_ACCEL + edma_netdev[i]->features |= NETIF_F_NTUPLE; + edma_netdev[i]->hw_features |= NETIF_F_NTUPLE; + edma_netdev[i]->vlan_features |= NETIF_F_NTUPLE; + edma_netdev[i]->wanted_features |= NETIF_F_NTUPLE; +#endif + edma_set_ethtool_ops(edma_netdev[i]); + + /* This just fill in some default MAC address + */ + if (!is_valid_ether_addr(edma_netdev[i]->dev_addr)) { + random_ether_addr(edma_netdev[i]->dev_addr); + pr_info("EDMA using MAC@ - using"); + pr_info("%02x:%02x:%02x:%02x:%02x:%02x\n", + *(edma_netdev[i]->dev_addr), + *(edma_netdev[i]->dev_addr + 1), + *(edma_netdev[i]->dev_addr + 2), + *(edma_netdev[i]->dev_addr + 3), + *(edma_netdev[i]->dev_addr + 4), + *(edma_netdev[i]->dev_addr + 5)); + } + + err = register_netdev(edma_netdev[i]); + if (err) + goto err_register; + + /* carrier off reporting is important to + * ethtool even BEFORE open + */ + netif_carrier_off(edma_netdev[i]); + + /* Allocate reverse irq cpu mapping structure for + * receive queues + */ +#ifdef CONFIG_RFS_ACCEL + edma_netdev[i]->rx_cpu_rmap = + alloc_irq_cpu_rmap(EDMA_NETDEV_RX_QUEUE); + if (!edma_netdev[i]->rx_cpu_rmap) { + err = -ENOMEM; + goto err_rmap_alloc_fail; + } +#endif + } + + for (i = 0; i < EDMA_MAX_PORTID_BITMAP_INDEX; i++) + edma_cinfo->portid_netdev_lookup_tbl[i] = NULL; + + for_each_available_child_of_node(np, pnp) { + const uint32_t *vlan_tag = NULL; + int len; + + /* this check is needed if parent and daughter dts have + * different number of gmac nodes + */ + if (idx == edma_cinfo->num_gmac) + break; + + /* Populate port-id to netdev lookup table */ + vlan_tag = of_get_property(pnp, "vlan_tag", &len); + if (!vlan_tag) { + pr_err("Vlan tag parsing Failed.\n"); + goto err_rmap_alloc_fail; + } + + adapter[idx]->default_vlan_tag = of_read_number(vlan_tag, 1); + vlan_tag++; + portid_bmp = of_read_number(vlan_tag, 1); + adapter[idx]->dp_bitmap = portid_bmp; + + portid_bmp = portid_bmp >> 1; /* We ignore CPU Port bit 0 */ + while (portid_bmp) { + int port_bit = ffs(portid_bmp); + + if (port_bit > EDMA_MAX_PORTID_SUPPORTED) + goto err_rmap_alloc_fail; + edma_cinfo->portid_netdev_lookup_tbl[port_bit] = + edma_netdev[idx]; + portid_bmp &= ~(1 << (port_bit - 1)); + } + + if (!of_property_read_u32(pnp, "qcom,poll_required", + &adapter[idx]->poll_required)) { + if (adapter[idx]->poll_required) { + of_property_read_u32(pnp, "qcom,phy_mdio_addr", + &adapter[idx]->phy_mdio_addr); + of_property_read_u32(pnp, "qcom,forced_speed", + &adapter[idx]->forced_speed); + of_property_read_u32(pnp, "qcom,forced_duplex", + &adapter[idx]->forced_duplex); + + /* create a phyid using MDIO bus id + * and MDIO bus address + */ + snprintf(adapter[idx]->phy_id, + MII_BUS_ID_SIZE + 3, PHY_ID_FMT, + miibus->id, + adapter[idx]->phy_mdio_addr); + } + } else { + adapter[idx]->poll_required = 0; + adapter[idx]->forced_speed = SPEED_1000; + adapter[idx]->forced_duplex = DUPLEX_FULL; + } + + idx++; + } + + edma_cinfo->edma_ctl_table_hdr = register_net_sysctl(&init_net, + "net/edma", + edma_table); + if (!edma_cinfo->edma_ctl_table_hdr) { + dev_err(&pdev->dev, "edma sysctl table hdr not registered\n"); + goto err_unregister_sysctl_tbl; + } + + /* Disable all 16 Tx and 8 rx irqs */ + edma_irq_disable(edma_cinfo); + + err = edma_reset(edma_cinfo); + if (err) { + err = -EIO; + goto err_reset; + } + + /* populate per_core_info, do a napi_Add, request 16 TX irqs, + * 8 RX irqs, do a napi enable + */ + for (i = 0; i < CONFIG_NR_CPUS; i++) { + u8 rx_start; + + edma_cinfo->edma_percpu_info[i].napi.state = 0; + + netif_napi_add(edma_netdev[0], + &edma_cinfo->edma_percpu_info[i].napi, + edma_poll, 64); + napi_enable(&edma_cinfo->edma_percpu_info[i].napi); + edma_cinfo->edma_percpu_info[i].tx_mask = tx_mask[i]; + edma_cinfo->edma_percpu_info[i].rx_mask = EDMA_RX_PER_CPU_MASK + << (i << EDMA_RX_PER_CPU_MASK_SHIFT); + edma_cinfo->edma_percpu_info[i].tx_start = tx_start[i]; + edma_cinfo->edma_percpu_info[i].rx_start = + i << EDMA_RX_CPU_START_SHIFT; + rx_start = i << EDMA_RX_CPU_START_SHIFT; + edma_cinfo->edma_percpu_info[i].tx_status = 0; + edma_cinfo->edma_percpu_info[i].rx_status = 0; + edma_cinfo->edma_percpu_info[i].edma_cinfo = edma_cinfo; + + /* Request irq per core */ + for (j = edma_cinfo->edma_percpu_info[i].tx_start; + j < tx_start[i] + 4; j++) { + sprintf(&edma_tx_irq[j][0], "edma_eth_tx%d", j); + err = request_irq(edma_cinfo->tx_irq[j], + edma_interrupt, + 0, + &edma_tx_irq[j][0], + &edma_cinfo->edma_percpu_info[i]); + if (err) + goto err_reset; + } + + for (j = edma_cinfo->edma_percpu_info[i].rx_start; + j < (rx_start + + ((edma_cinfo->num_rx_queues == 4) ? 1 : 2)); + j++) { + sprintf(&edma_rx_irq[j][0], "edma_eth_rx%d", j); + err = request_irq(edma_cinfo->rx_irq[j], + edma_interrupt, + 0, + &edma_rx_irq[j][0], + &edma_cinfo->edma_percpu_info[i]); + if (err) + goto err_reset; + } + +#ifdef CONFIG_RFS_ACCEL + for (j = edma_cinfo->edma_percpu_info[i].rx_start; + j < rx_start + 2; j += 2) { + err = irq_cpu_rmap_add(edma_netdev[0]->rx_cpu_rmap, + edma_cinfo->rx_irq[j]); + if (err) + goto err_rmap_add_fail; + } +#endif + } + + /* Used to clear interrupt status, allocate rx buffer, + * configure edma descriptors registers + */ + err = edma_configure(edma_cinfo); + if (err) { + err = -EIO; + goto err_configure; + } + + /* Configure RSS indirection table. + * 128 hash will be configured in the following + * pattern: hash{0,1,2,3} = {Q0,Q2,Q4,Q6} respectively + * and so on + */ + for (i = 0; i < EDMA_NUM_IDT; i++) + edma_write_reg(EDMA_REG_RSS_IDT(i), EDMA_RSS_IDT_VALUE); + + /* Configure load balance mapping table. + * 4 table entry will be configured according to the + * following pattern: load_balance{0,1,2,3} = {Q0,Q1,Q3,Q4} + * respectively. + */ + edma_write_reg(EDMA_REG_LB_RING, EDMA_LB_REG_VALUE); + + /* Configure Virtual queue for Tx rings + * User can also change this value runtime through + * a sysctl + */ + edma_write_reg(EDMA_REG_VQ_CTRL0, EDMA_VQ_REG_VALUE); + edma_write_reg(EDMA_REG_VQ_CTRL1, EDMA_VQ_REG_VALUE); + + /* Configure Max AXI Burst write size to 128 bytes*/ + edma_write_reg(EDMA_REG_AXIW_CTRL_MAXWRSIZE, + EDMA_AXIW_MAXWRSIZE_VALUE); + + /* Enable All 16 tx and 8 rx irq mask */ + edma_irq_enable(edma_cinfo); + edma_enable_tx_ctrl(&edma_cinfo->hw); + edma_enable_rx_ctrl(&edma_cinfo->hw); + + for (i = 0; i < edma_cinfo->num_gmac; i++) { + if (adapter[i]->poll_required) { + int phy_mode = of_get_phy_mode(np); + + if (phy_mode < 0) + phy_mode = PHY_INTERFACE_MODE_SGMII; + adapter[i]->phydev = + phy_connect(edma_netdev[i], + (const char *)adapter[i]->phy_id, + &edma_adjust_link, + phy_mode); + if (IS_ERR(adapter[i]->phydev)) { + dev_dbg(&pdev->dev, "PHY attach FAIL"); + err = -EIO; + goto edma_phy_attach_fail; + } else { + linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, + adapter[i]->phydev->advertising); + linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, + adapter[i]->phydev->advertising); + linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, + adapter[i]->phydev->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, + adapter[i]->phydev->supported); + } + } else { + adapter[i]->phydev = NULL; + } + } + + spin_lock_init(&edma_cinfo->stats_lock); + + timer_setup(&edma_cinfo->edma_stats_timer, edma_statistics_timer, 0); + mod_timer(&edma_cinfo->edma_stats_timer, jiffies + 1*HZ); + + return 0; + +edma_phy_attach_fail: + miibus = NULL; +err_configure: +#ifdef CONFIG_RFS_ACCEL + for (i = 0; i < edma_cinfo->num_gmac; i++) { + free_irq_cpu_rmap(adapter[i]->netdev->rx_cpu_rmap); + adapter[i]->netdev->rx_cpu_rmap = NULL; + } +#endif +err_rmap_add_fail: + edma_free_irqs(adapter[0]); + for (i = 0; i < CONFIG_NR_CPUS; i++) + napi_disable(&edma_cinfo->edma_percpu_info[i].napi); +err_reset: +err_unregister_sysctl_tbl: +err_rmap_alloc_fail: + for (i = 0; i < edma_cinfo->num_gmac; i++) + unregister_netdev(edma_netdev[i]); +err_register: +err_single_phy_init: + iounmap(edma_cinfo->ess_hw_addr); + clk_disable_unprepare(edma_cinfo->ess_clk); +err_mdiobus_init_fail: + edma_free_rx_rings(edma_cinfo); +err_rx_rinit: + edma_free_tx_rings(edma_cinfo); +err_tx_rinit: + edma_free_queues(edma_cinfo); +err_rx_qinit: +err_tx_qinit: + iounmap(edma_cinfo->hw.hw_addr); +err_ioremap: + for (i = 0; i < edma_cinfo->num_gmac; i++) { + if (edma_netdev[i]) + free_netdev(edma_netdev[i]); + } +err_cinfo: + kfree(edma_cinfo); +err_alloc: + return err; +} + +/* edma_axi_remove() + * Device Removal Routine + * + * edma_axi_remove is called by the platform subsystem to alert the driver + * that it should release a platform device. + */ +static int edma_axi_remove(struct platform_device *pdev) +{ + struct edma_adapter *adapter = netdev_priv(edma_netdev[0]); + struct edma_common_info *edma_cinfo = adapter->edma_cinfo; + struct edma_hw *hw = &edma_cinfo->hw; + int i; + + for (i = 0; i < edma_cinfo->num_gmac; i++) + unregister_netdev(edma_netdev[i]); + + edma_stop_rx_tx(hw); + for (i = 0; i < CONFIG_NR_CPUS; i++) + napi_disable(&edma_cinfo->edma_percpu_info[i].napi); + + edma_irq_disable(edma_cinfo); + edma_write_reg(EDMA_REG_RX_ISR, 0xff); + edma_write_reg(EDMA_REG_TX_ISR, 0xffff); +#ifdef CONFIG_RFS_ACCEL + for (i = 0; i < edma_cinfo->num_gmac; i++) { + free_irq_cpu_rmap(edma_netdev[i]->rx_cpu_rmap); + edma_netdev[i]->rx_cpu_rmap = NULL; + } +#endif + + for (i = 0; i < edma_cinfo->num_gmac; i++) { + struct edma_adapter *adapter = netdev_priv(edma_netdev[i]); + + if (adapter->phydev) + phy_disconnect(adapter->phydev); + } + + del_timer_sync(&edma_cinfo->edma_stats_timer); + edma_free_irqs(adapter); + unregister_net_sysctl_table(edma_cinfo->edma_ctl_table_hdr); + iounmap(edma_cinfo->ess_hw_addr); + clk_disable_unprepare(edma_cinfo->ess_clk); + edma_free_tx_resources(edma_cinfo); + edma_free_rx_resources(edma_cinfo); + edma_free_tx_rings(edma_cinfo); + edma_free_rx_rings(edma_cinfo); + edma_free_queues(edma_cinfo); + for (i = 0; i < edma_cinfo->num_gmac; i++) + free_netdev(edma_netdev[i]); + + kfree(edma_cinfo); + + return 0; +} + +static const struct of_device_id edma_of_mtable[] = { + {.compatible = "qcom,ess-edma" }, + {} +}; +MODULE_DEVICE_TABLE(of, edma_of_mtable); + +static struct platform_driver edma_axi_driver = { + .driver = { + .name = edma_axi_driver_name, + .of_match_table = edma_of_mtable, + }, + .probe = edma_axi_probe, + .remove = edma_axi_remove, +}; + +module_platform_driver(edma_axi_driver); + +MODULE_AUTHOR("Qualcomm Atheros Inc"); +MODULE_DESCRIPTION("QCA ESS EDMA driver"); +MODULE_LICENSE("GPL"); diff --git a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_ethtool.c b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_ethtool.c new file mode 100644 index 00000000..1270e20a --- /dev/null +++ b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_ethtool.c @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include "edma.h" + +struct edma_ethtool_stats { + uint8_t stat_string[ETH_GSTRING_LEN]; + uint32_t stat_offset; +}; + +#define EDMA_STAT(m) offsetof(struct edma_ethtool_statistics, m) +#define DRVINFO_LEN 32 + +/* Array of strings describing statistics + */ +static const struct edma_ethtool_stats edma_gstrings_stats[] = { + {"tx_q0_pkt", EDMA_STAT(tx_q0_pkt)}, + {"tx_q1_pkt", EDMA_STAT(tx_q1_pkt)}, + {"tx_q2_pkt", EDMA_STAT(tx_q2_pkt)}, + {"tx_q3_pkt", EDMA_STAT(tx_q3_pkt)}, + {"tx_q4_pkt", EDMA_STAT(tx_q4_pkt)}, + {"tx_q5_pkt", EDMA_STAT(tx_q5_pkt)}, + {"tx_q6_pkt", EDMA_STAT(tx_q6_pkt)}, + {"tx_q7_pkt", EDMA_STAT(tx_q7_pkt)}, + {"tx_q8_pkt", EDMA_STAT(tx_q8_pkt)}, + {"tx_q9_pkt", EDMA_STAT(tx_q9_pkt)}, + {"tx_q10_pkt", EDMA_STAT(tx_q10_pkt)}, + {"tx_q11_pkt", EDMA_STAT(tx_q11_pkt)}, + {"tx_q12_pkt", EDMA_STAT(tx_q12_pkt)}, + {"tx_q13_pkt", EDMA_STAT(tx_q13_pkt)}, + {"tx_q14_pkt", EDMA_STAT(tx_q14_pkt)}, + {"tx_q15_pkt", EDMA_STAT(tx_q15_pkt)}, + {"tx_q0_byte", EDMA_STAT(tx_q0_byte)}, + {"tx_q1_byte", EDMA_STAT(tx_q1_byte)}, + {"tx_q2_byte", EDMA_STAT(tx_q2_byte)}, + {"tx_q3_byte", EDMA_STAT(tx_q3_byte)}, + {"tx_q4_byte", EDMA_STAT(tx_q4_byte)}, + {"tx_q5_byte", EDMA_STAT(tx_q5_byte)}, + {"tx_q6_byte", EDMA_STAT(tx_q6_byte)}, + {"tx_q7_byte", EDMA_STAT(tx_q7_byte)}, + {"tx_q8_byte", EDMA_STAT(tx_q8_byte)}, + {"tx_q9_byte", EDMA_STAT(tx_q9_byte)}, + {"tx_q10_byte", EDMA_STAT(tx_q10_byte)}, + {"tx_q11_byte", EDMA_STAT(tx_q11_byte)}, + {"tx_q12_byte", EDMA_STAT(tx_q12_byte)}, + {"tx_q13_byte", EDMA_STAT(tx_q13_byte)}, + {"tx_q14_byte", EDMA_STAT(tx_q14_byte)}, + {"tx_q15_byte", EDMA_STAT(tx_q15_byte)}, + {"rx_q0_pkt", EDMA_STAT(rx_q0_pkt)}, + {"rx_q1_pkt", EDMA_STAT(rx_q1_pkt)}, + {"rx_q2_pkt", EDMA_STAT(rx_q2_pkt)}, + {"rx_q3_pkt", EDMA_STAT(rx_q3_pkt)}, + {"rx_q4_pkt", EDMA_STAT(rx_q4_pkt)}, + {"rx_q5_pkt", EDMA_STAT(rx_q5_pkt)}, + {"rx_q6_pkt", EDMA_STAT(rx_q6_pkt)}, + {"rx_q7_pkt", EDMA_STAT(rx_q7_pkt)}, + {"rx_q0_byte", EDMA_STAT(rx_q0_byte)}, + {"rx_q1_byte", EDMA_STAT(rx_q1_byte)}, + {"rx_q2_byte", EDMA_STAT(rx_q2_byte)}, + {"rx_q3_byte", EDMA_STAT(rx_q3_byte)}, + {"rx_q4_byte", EDMA_STAT(rx_q4_byte)}, + {"rx_q5_byte", EDMA_STAT(rx_q5_byte)}, + {"rx_q6_byte", EDMA_STAT(rx_q6_byte)}, + {"rx_q7_byte", EDMA_STAT(rx_q7_byte)}, + {"tx_desc_error", EDMA_STAT(tx_desc_error)}, + {"rx_alloc_fail_ctr", EDMA_STAT(rx_alloc_fail_ctr)}, +}; + +#define EDMA_STATS_LEN ARRAY_SIZE(edma_gstrings_stats) + +/* edma_get_strset_count() + * Get strset count + */ +static int edma_get_strset_count(struct net_device *netdev, + int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return EDMA_STATS_LEN; + default: + netdev_dbg(netdev, "%s: Invalid string set", __func__); + return -EOPNOTSUPP; + } +} + + +/* edma_get_strings() + * get stats string + */ +static void edma_get_strings(struct net_device *netdev, uint32_t stringset, + uint8_t *data) +{ + uint8_t *p = data; + uint32_t i; + + switch (stringset) { + case ETH_SS_STATS: + for (i = 0; i < EDMA_STATS_LEN; i++) { + memcpy(p, edma_gstrings_stats[i].stat_string, + min((size_t)ETH_GSTRING_LEN, + strlen(edma_gstrings_stats[i].stat_string) + + 1)); + p += ETH_GSTRING_LEN; + } + break; + } +} + +/* edma_get_ethtool_stats() + * Get ethtool statistics + */ +static void edma_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, uint64_t *data) +{ + struct edma_adapter *adapter = netdev_priv(netdev); + struct edma_common_info *edma_cinfo = adapter->edma_cinfo; + int i; + uint8_t *p = NULL; + + edma_read_append_stats(edma_cinfo); + + for(i = 0; i < EDMA_STATS_LEN; i++) { + p = (uint8_t *)&(edma_cinfo->edma_ethstats) + + edma_gstrings_stats[i].stat_offset; + data[i] = *(uint32_t *)p; + } +} + +/* edma_get_drvinfo() + * get edma driver info + */ +static void edma_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + strlcpy(info->driver, "ess_edma", DRVINFO_LEN); + strlcpy(info->bus_info, "axi", ETHTOOL_BUSINFO_LEN); +} + +/* edma_nway_reset() + * Reset the phy, if available. + */ +static int edma_nway_reset(struct net_device *netdev) +{ + return -EINVAL; +} + +/* edma_get_wol() + * get wake on lan info + */ +static void edma_get_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + wol->supported = 0; + wol->wolopts = 0; +} + +/* edma_get_msglevel() + * get message level. + */ +static uint32_t edma_get_msglevel(struct net_device *netdev) +{ + return 0; +} + +/* edma_get_settings() + * Get edma settings + */ +static int edma_get_settings(struct net_device *netdev, + struct ethtool_link_ksettings *cmd) +{ + struct edma_adapter *adapter = netdev_priv(netdev); + + if (adapter->poll_required) { + struct phy_device *phydev = NULL; + uint16_t phyreg; + + if ((adapter->forced_speed != SPEED_UNKNOWN) + && !(adapter->poll_required)) + return -EPERM; + + phydev = adapter->phydev; + + linkmode_copy(cmd->link_modes.advertising, phydev->advertising); + linkmode_copy(cmd->link_modes.supported, phydev->supported); + + cmd->base.autoneg = phydev->autoneg; + + if (adapter->link_state == __EDMA_LINKDOWN) { + cmd->base.speed = SPEED_UNKNOWN; + cmd->base.duplex = DUPLEX_UNKNOWN; + } else { + cmd->base.speed = phydev->speed; + cmd->base.duplex = phydev->duplex; + } + + cmd->base.phy_address = adapter->phy_mdio_addr; + + phyreg = (uint16_t)phy_read(adapter->phydev, MII_LPA); + if (phyreg & LPA_10HALF) + linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, + cmd->link_modes.lp_advertising); + + if (phyreg & LPA_10FULL) + linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, + cmd->link_modes.lp_advertising); + + if (phyreg & LPA_100HALF) + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, + cmd->link_modes.lp_advertising); + + if (phyreg & LPA_100FULL) + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, + cmd->link_modes.lp_advertising); + + phyreg = (uint16_t)phy_read(adapter->phydev, MII_STAT1000); + if (phyreg & LPA_1000HALF) + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, + cmd->link_modes.lp_advertising); + + if (phyreg & LPA_1000FULL) + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + cmd->link_modes.lp_advertising); + } else { + /* If the speed/duplex for this GMAC is forced and we + * are not polling for link state changes, return the + * values as specified by platform. This will be true + * for GMACs connected to switch, and interfaces that + * do not use a PHY. + */ + if (!(adapter->poll_required)) { + if (adapter->forced_speed != SPEED_UNKNOWN) { + /* set speed and duplex */ + cmd->base.speed = SPEED_1000; + cmd->base.duplex = DUPLEX_FULL; + + /* Populate capabilities advertised by self */ + linkmode_zero(cmd->link_modes.advertising); + cmd->base.autoneg = 0; + cmd->base.port = PORT_TP; + cmd->base.transceiver = XCVR_EXTERNAL; + } else { + /* non link polled and non + * forced speed/duplex interface + */ + return -EIO; + } + } + } + + return 0; +} + +/* edma_set_settings() + * Set EDMA settings + */ +static int edma_set_settings(struct net_device *netdev, + const struct ethtool_link_ksettings *cmd) +{ + struct edma_adapter *adapter = netdev_priv(netdev); + struct phy_device *phydev = NULL; + + if ((adapter->forced_speed != SPEED_UNKNOWN) && + !adapter->poll_required) + return -EPERM; + + phydev = adapter->phydev; + linkmode_copy(phydev->advertising, cmd->link_modes.advertising); + linkmode_copy(phydev->supported, cmd->link_modes.supported); + phydev->autoneg = cmd->base.autoneg; + phydev->speed = cmd->base.speed; + phydev->duplex = cmd->base.duplex; + + genphy_config_aneg(phydev); + + return 0; +} + +/* edma_get_coalesce + * get interrupt mitigation + */ +static int edma_get_coalesce(struct net_device *netdev, + struct ethtool_coalesce *ec) +{ + u32 reg_val; + + edma_get_tx_rx_coalesce(®_val); + + /* We read the Interrupt Moderation Timer(IMT) register value, + * use lower 16 bit for rx and higher 16 bit for Tx. We do a + * left shift by 1, because IMT resolution timer is 2usecs. + * Hence the value given by the register is multiplied by 2 to + * get the actual time in usecs. + */ + ec->tx_coalesce_usecs = (((reg_val >> 16) & 0xffff) << 1); + ec->rx_coalesce_usecs = ((reg_val & 0xffff) << 1); + + return 0; +} + +/* edma_set_coalesce + * set interrupt mitigation + */ +static int edma_set_coalesce(struct net_device *netdev, + struct ethtool_coalesce *ec) +{ + if (ec->tx_coalesce_usecs) + edma_change_tx_coalesce(ec->tx_coalesce_usecs); + if (ec->rx_coalesce_usecs) + edma_change_rx_coalesce(ec->rx_coalesce_usecs); + + return 0; +} + +/* edma_set_priv_flags() + * Set EDMA private flags + */ +static int edma_set_priv_flags(struct net_device *netdev, u32 flags) +{ + return 0; +} + +/* edma_get_priv_flags() + * get edma driver flags + */ +static u32 edma_get_priv_flags(struct net_device *netdev) +{ + return 0; +} + +/* edma_get_ringparam() + * get ring size + */ +static void edma_get_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ring) +{ + struct edma_adapter *adapter = netdev_priv(netdev); + struct edma_common_info *edma_cinfo = adapter->edma_cinfo; + + ring->tx_max_pending = edma_cinfo->tx_ring_count; + ring->rx_max_pending = edma_cinfo->rx_ring_count; +} + +/* Ethtool operations + */ +static const struct ethtool_ops edma_ethtool_ops = { + .get_drvinfo = &edma_get_drvinfo, + .get_link = ðtool_op_get_link, + .get_msglevel = &edma_get_msglevel, + .nway_reset = &edma_nway_reset, + .get_wol = &edma_get_wol, + .get_link_ksettings = &edma_get_settings, + .set_link_ksettings = &edma_set_settings, + .get_strings = &edma_get_strings, + .get_sset_count = &edma_get_strset_count, + .get_ethtool_stats = &edma_get_ethtool_stats, + .get_coalesce = &edma_get_coalesce, + .set_coalesce = &edma_set_coalesce, + .get_priv_flags = edma_get_priv_flags, + .set_priv_flags = edma_set_priv_flags, + .get_ringparam = edma_get_ringparam, +}; + +/* edma_set_ethtool_ops + * Set ethtool operations + */ +void edma_set_ethtool_ops(struct net_device *netdev) +{ + netdev->ethtool_ops = &edma_ethtool_ops; +} diff --git a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/ess_edma.h b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/ess_edma.h new file mode 100644 index 00000000..021be98a --- /dev/null +++ b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/ess_edma.h @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _ESS_EDMA_H_ +#define _ESS_EDMA_H_ + +#include + +struct edma_adapter; +struct edma_hw; + +/* register definition */ +#define EDMA_REG_MAS_CTRL 0x0 +#define EDMA_REG_TIMEOUT_CTRL 0x004 +#define EDMA_REG_DBG0 0x008 +#define EDMA_REG_DBG1 0x00C +#define EDMA_REG_SW_CTRL0 0x100 +#define EDMA_REG_SW_CTRL1 0x104 + +/* Interrupt Status Register */ +#define EDMA_REG_RX_ISR 0x200 +#define EDMA_REG_TX_ISR 0x208 +#define EDMA_REG_MISC_ISR 0x210 +#define EDMA_REG_WOL_ISR 0x218 + +#define EDMA_MISC_ISR_RX_URG_Q(x) (1 << x) + +#define EDMA_MISC_ISR_AXIR_TIMEOUT 0x00000100 +#define EDMA_MISC_ISR_AXIR_ERR 0x00000200 +#define EDMA_MISC_ISR_TXF_DEAD 0x00000400 +#define EDMA_MISC_ISR_AXIW_ERR 0x00000800 +#define EDMA_MISC_ISR_AXIW_TIMEOUT 0x00001000 + +#define EDMA_WOL_ISR 0x00000001 + +/* Interrupt Mask Register */ +#define EDMA_REG_MISC_IMR 0x214 +#define EDMA_REG_WOL_IMR 0x218 + +#define EDMA_RX_IMR_NORMAL_MASK 0x1 +#define EDMA_TX_IMR_NORMAL_MASK 0x1 +#define EDMA_MISC_IMR_NORMAL_MASK 0x80001FFF +#define EDMA_WOL_IMR_NORMAL_MASK 0x1 + +/* Edma receive consumer index */ +#define EDMA_REG_RX_SW_CONS_IDX_Q(x) (0x220 + ((x) << 2)) /* x is the queue id */ +/* Edma transmit consumer index */ +#define EDMA_REG_TX_SW_CONS_IDX_Q(x) (0x240 + ((x) << 2)) /* x is the queue id */ + +/* IRQ Moderator Initial Timer Register */ +#define EDMA_REG_IRQ_MODRT_TIMER_INIT 0x280 +#define EDMA_IRQ_MODRT_TIMER_MASK 0xFFFF +#define EDMA_IRQ_MODRT_RX_TIMER_SHIFT 0 +#define EDMA_IRQ_MODRT_TX_TIMER_SHIFT 16 + +/* Interrupt Control Register */ +#define EDMA_REG_INTR_CTRL 0x284 +#define EDMA_INTR_CLR_TYP_SHIFT 0 +#define EDMA_INTR_SW_IDX_W_TYP_SHIFT 1 +#define EDMA_INTR_CLEAR_TYPE_W1 0 +#define EDMA_INTR_CLEAR_TYPE_R 1 + +/* RX Interrupt Mask Register */ +#define EDMA_REG_RX_INT_MASK_Q(x) (0x300 + ((x) << 2)) /* x = queue id */ + +/* TX Interrupt mask register */ +#define EDMA_REG_TX_INT_MASK_Q(x) (0x340 + ((x) << 2)) /* x = queue id */ + +/* Load Ptr Register + * Software sets this bit after the initialization of the head and tail + */ +#define EDMA_REG_TX_SRAM_PART 0x400 +#define EDMA_LOAD_PTR_SHIFT 16 + +/* TXQ Control Register */ +#define EDMA_REG_TXQ_CTRL 0x404 +#define EDMA_TXQ_CTRL_IP_OPTION_EN 0x10 +#define EDMA_TXQ_CTRL_TXQ_EN 0x20 +#define EDMA_TXQ_CTRL_ENH_MODE 0x40 +#define EDMA_TXQ_CTRL_LS_8023_EN 0x80 +#define EDMA_TXQ_CTRL_TPD_BURST_EN 0x100 +#define EDMA_TXQ_CTRL_LSO_BREAK_EN 0x200 +#define EDMA_TXQ_NUM_TPD_BURST_MASK 0xF +#define EDMA_TXQ_TXF_BURST_NUM_MASK 0xFFFF +#define EDMA_TXQ_NUM_TPD_BURST_SHIFT 0 +#define EDMA_TXQ_TXF_BURST_NUM_SHIFT 16 + +#define EDMA_REG_TXF_WATER_MARK 0x408 /* In 8-bytes */ +#define EDMA_TXF_WATER_MARK_MASK 0x0FFF +#define EDMA_TXF_LOW_WATER_MARK_SHIFT 0 +#define EDMA_TXF_HIGH_WATER_MARK_SHIFT 16 +#define EDMA_TXQ_CTRL_BURST_MODE_EN 0x80000000 + +/* WRR Control Register */ +#define EDMA_REG_WRR_CTRL_Q0_Q3 0x40c +#define EDMA_REG_WRR_CTRL_Q4_Q7 0x410 +#define EDMA_REG_WRR_CTRL_Q8_Q11 0x414 +#define EDMA_REG_WRR_CTRL_Q12_Q15 0x418 + +/* Weight round robin(WRR), it takes queue as input, and computes + * starting bits where we need to write the weight for a particular + * queue + */ +#define EDMA_WRR_SHIFT(x) (((x) * 5) % 20) + +/* Tx Descriptor Control Register */ +#define EDMA_REG_TPD_RING_SIZE 0x41C +#define EDMA_TPD_RING_SIZE_SHIFT 0 +#define EDMA_TPD_RING_SIZE_MASK 0xFFFF + +/* Transmit descriptor base address */ +#define EDMA_REG_TPD_BASE_ADDR_Q(x) (0x420 + ((x) << 2)) /* x = queue id */ + +/* TPD Index Register */ +#define EDMA_REG_TPD_IDX_Q(x) (0x460 + ((x) << 2)) /* x = queue id */ + +#define EDMA_TPD_PROD_IDX_BITS 0x0000FFFF +#define EDMA_TPD_CONS_IDX_BITS 0xFFFF0000 +#define EDMA_TPD_PROD_IDX_MASK 0xFFFF +#define EDMA_TPD_CONS_IDX_MASK 0xFFFF +#define EDMA_TPD_PROD_IDX_SHIFT 0 +#define EDMA_TPD_CONS_IDX_SHIFT 16 + +/* TX Virtual Queue Mapping Control Register */ +#define EDMA_REG_VQ_CTRL0 0x4A0 +#define EDMA_REG_VQ_CTRL1 0x4A4 + +/* Virtual QID shift, it takes queue as input, and computes + * Virtual QID position in virtual qid control register + */ +#define EDMA_VQ_ID_SHIFT(i) (((i) * 3) % 24) + +/* Virtual Queue Default Value */ +#define EDMA_VQ_REG_VALUE 0x240240 + +/* Tx side Port Interface Control Register */ +#define EDMA_REG_PORT_CTRL 0x4A8 +#define EDMA_PAD_EN_SHIFT 15 + +/* Tx side VLAN Configuration Register */ +#define EDMA_REG_VLAN_CFG 0x4AC + +#define EDMA_TX_CVLAN 16 +#define EDMA_TX_INS_CVLAN 17 +#define EDMA_TX_CVLAN_TAG_SHIFT 0 + +#define EDMA_TX_SVLAN 14 +#define EDMA_TX_INS_SVLAN 15 +#define EDMA_TX_SVLAN_TAG_SHIFT 16 + +/* Tx Queue Packet Statistic Register */ +#define EDMA_REG_TX_STAT_PKT_Q(x) (0x700 + ((x) << 3)) /* x = queue id */ + +#define EDMA_TX_STAT_PKT_MASK 0xFFFFFF + +/* Tx Queue Byte Statistic Register */ +#define EDMA_REG_TX_STAT_BYTE_Q(x) (0x704 + ((x) << 3)) /* x = queue id */ + +/* Load Balance Based Ring Offset Register */ +#define EDMA_REG_LB_RING 0x800 +#define EDMA_LB_RING_ENTRY_MASK 0xff +#define EDMA_LB_RING_ID_MASK 0x7 +#define EDMA_LB_RING_PROFILE_ID_MASK 0x3 +#define EDMA_LB_RING_ENTRY_BIT_OFFSET 8 +#define EDMA_LB_RING_ID_OFFSET 0 +#define EDMA_LB_RING_PROFILE_ID_OFFSET 3 +#define EDMA_LB_REG_VALUE 0x6040200 + +/* Load Balance Priority Mapping Register */ +#define EDMA_REG_LB_PRI_START 0x804 +#define EDMA_REG_LB_PRI_END 0x810 +#define EDMA_LB_PRI_REG_INC 4 +#define EDMA_LB_PRI_ENTRY_BIT_OFFSET 4 +#define EDMA_LB_PRI_ENTRY_MASK 0xf + +/* RSS Priority Mapping Register */ +#define EDMA_REG_RSS_PRI 0x820 +#define EDMA_RSS_PRI_ENTRY_MASK 0xf +#define EDMA_RSS_RING_ID_MASK 0x7 +#define EDMA_RSS_PRI_ENTRY_BIT_OFFSET 4 + +/* RSS Indirection Register */ +#define EDMA_REG_RSS_IDT(x) (0x840 + ((x) << 2)) /* x = No. of indirection table */ +#define EDMA_NUM_IDT 16 +#define EDMA_RSS_IDT_VALUE 0x64206420 + +/* Default RSS Ring Register */ +#define EDMA_REG_DEF_RSS 0x890 +#define EDMA_DEF_RSS_MASK 0x7 + +/* RSS Hash Function Type Register */ +#define EDMA_REG_RSS_TYPE 0x894 +#define EDMA_RSS_TYPE_NONE 0x01 +#define EDMA_RSS_TYPE_IPV4TCP 0x02 +#define EDMA_RSS_TYPE_IPV6_TCP 0x04 +#define EDMA_RSS_TYPE_IPV4_UDP 0x08 +#define EDMA_RSS_TYPE_IPV6UDP 0x10 +#define EDMA_RSS_TYPE_IPV4 0x20 +#define EDMA_RSS_TYPE_IPV6 0x40 +#define EDMA_RSS_HASH_MODE_MASK 0x7f + +#define EDMA_REG_RSS_HASH_VALUE 0x8C0 + +#define EDMA_REG_RSS_TYPE_RESULT 0x8C4 + +#define EDMA_HASH_TYPE_START 0 +#define EDMA_HASH_TYPE_END 5 +#define EDMA_HASH_TYPE_SHIFT 12 + +#define EDMA_RFS_FLOW_ENTRIES 1024 +#define EDMA_RFS_FLOW_ENTRIES_MASK (EDMA_RFS_FLOW_ENTRIES - 1) +#define EDMA_RFS_EXPIRE_COUNT_PER_CALL 128 + +/* RFD Base Address Register */ +#define EDMA_REG_RFD_BASE_ADDR_Q(x) (0x950 + ((x) << 2)) /* x = queue id */ + +/* RFD Index Register */ +#define EDMA_REG_RFD_IDX_Q(x) (0x9B0 + ((x) << 2)) + +#define EDMA_RFD_PROD_IDX_BITS 0x00000FFF +#define EDMA_RFD_CONS_IDX_BITS 0x0FFF0000 +#define EDMA_RFD_PROD_IDX_MASK 0xFFF +#define EDMA_RFD_CONS_IDX_MASK 0xFFF +#define EDMA_RFD_PROD_IDX_SHIFT 0 +#define EDMA_RFD_CONS_IDX_SHIFT 16 + +/* Rx Descriptor Control Register */ +#define EDMA_REG_RX_DESC0 0xA10 +#define EDMA_RFD_RING_SIZE_MASK 0xFFF +#define EDMA_RX_BUF_SIZE_MASK 0xFFFF +#define EDMA_RFD_RING_SIZE_SHIFT 0 +#define EDMA_RX_BUF_SIZE_SHIFT 16 + +#define EDMA_REG_RX_DESC1 0xA14 +#define EDMA_RXQ_RFD_BURST_NUM_MASK 0x3F +#define EDMA_RXQ_RFD_PF_THRESH_MASK 0x1F +#define EDMA_RXQ_RFD_LOW_THRESH_MASK 0xFFF +#define EDMA_RXQ_RFD_BURST_NUM_SHIFT 0 +#define EDMA_RXQ_RFD_PF_THRESH_SHIFT 8 +#define EDMA_RXQ_RFD_LOW_THRESH_SHIFT 16 + +/* RXQ Control Register */ +#define EDMA_REG_RXQ_CTRL 0xA18 +#define EDMA_FIFO_THRESH_TYPE_SHIF 0 +#define EDMA_FIFO_THRESH_128_BYTE 0x0 +#define EDMA_FIFO_THRESH_64_BYTE 0x1 +#define EDMA_RXQ_CTRL_RMV_VLAN 0x00000002 +#define EDMA_RXQ_CTRL_EN 0x0000FF00 + +/* AXI Burst Size Config */ +#define EDMA_REG_AXIW_CTRL_MAXWRSIZE 0xA1C +#define EDMA_AXIW_MAXWRSIZE_VALUE 0x0 + +/* Rx Statistics Register */ +#define EDMA_REG_RX_STAT_BYTE_Q(x) (0xA30 + ((x) << 2)) /* x = queue id */ +#define EDMA_REG_RX_STAT_PKT_Q(x) (0xA50 + ((x) << 2)) /* x = queue id */ + +/* WoL Pattern Length Register */ +#define EDMA_REG_WOL_PATTERN_LEN0 0xC00 +#define EDMA_WOL_PT_LEN_MASK 0xFF +#define EDMA_WOL_PT0_LEN_SHIFT 0 +#define EDMA_WOL_PT1_LEN_SHIFT 8 +#define EDMA_WOL_PT2_LEN_SHIFT 16 +#define EDMA_WOL_PT3_LEN_SHIFT 24 + +#define EDMA_REG_WOL_PATTERN_LEN1 0xC04 +#define EDMA_WOL_PT4_LEN_SHIFT 0 +#define EDMA_WOL_PT5_LEN_SHIFT 8 +#define EDMA_WOL_PT6_LEN_SHIFT 16 + +/* WoL Control Register */ +#define EDMA_REG_WOL_CTRL 0xC08 +#define EDMA_WOL_WK_EN 0x00000001 +#define EDMA_WOL_MG_EN 0x00000002 +#define EDMA_WOL_PT0_EN 0x00000004 +#define EDMA_WOL_PT1_EN 0x00000008 +#define EDMA_WOL_PT2_EN 0x00000010 +#define EDMA_WOL_PT3_EN 0x00000020 +#define EDMA_WOL_PT4_EN 0x00000040 +#define EDMA_WOL_PT5_EN 0x00000080 +#define EDMA_WOL_PT6_EN 0x00000100 + +/* MAC Control Register */ +#define EDMA_REG_MAC_CTRL0 0xC20 +#define EDMA_REG_MAC_CTRL1 0xC24 + +/* WoL Pattern Register */ +#define EDMA_REG_WOL_PATTERN_START 0x5000 +#define EDMA_PATTERN_PART_REG_OFFSET 0x40 + + +/* TX descriptor fields */ +#define EDMA_TPD_HDR_SHIFT 0 +#define EDMA_TPD_PPPOE_EN 0x00000100 +#define EDMA_TPD_IP_CSUM_EN 0x00000200 +#define EDMA_TPD_TCP_CSUM_EN 0x0000400 +#define EDMA_TPD_UDP_CSUM_EN 0x00000800 +#define EDMA_TPD_CUSTOM_CSUM_EN 0x00000C00 +#define EDMA_TPD_LSO_EN 0x00001000 +#define EDMA_TPD_LSO_V2_EN 0x00002000 +#define EDMA_TPD_IPV4_EN 0x00010000 +#define EDMA_TPD_MSS_MASK 0x1FFF +#define EDMA_TPD_MSS_SHIFT 18 +#define EDMA_TPD_CUSTOM_CSUM_SHIFT 18 + +/* RRD descriptor fields */ +#define EDMA_RRD_NUM_RFD_MASK 0x000F +#define EDMA_RRD_SVLAN 0x8000 +#define EDMA_RRD_FLOW_COOKIE_MASK 0x07FF; + +#define EDMA_RRD_PKT_SIZE_MASK 0x3FFF +#define EDMA_RRD_CSUM_FAIL_MASK 0xC000 +#define EDMA_RRD_CVLAN 0x0001 +#define EDMA_RRD_DESC_VALID 0x8000 + +#define EDMA_RRD_PRIORITY_SHIFT 4 +#define EDMA_RRD_PRIORITY_MASK 0x7 +#define EDMA_RRD_PORT_TYPE_SHIFT 7 +#define EDMA_RRD_PORT_TYPE_MASK 0x1F + +#define ESS_RGMII_CTRL 0x0004 + +/* Port status registers */ +#define ESS_PORT0_STATUS 0x007C +#define ESS_PORT1_STATUS 0x0080 +#define ESS_PORT2_STATUS 0x0084 +#define ESS_PORT3_STATUS 0x0088 +#define ESS_PORT4_STATUS 0x008C +#define ESS_PORT5_STATUS 0x0090 + +#define ESS_PORT_STATUS_HDX_FLOW_CTL 0x80 +#define ESS_PORT_STATUS_DUPLEX_MODE 0x40 +#define ESS_PORT_STATUS_RX_FLOW_EN 0x20 +#define ESS_PORT_STATUS_TX_FLOW_EN 0x10 +#define ESS_PORT_STATUS_RX_MAC_EN 0x08 +#define ESS_PORT_STATUS_TX_MAC_EN 0x04 +#define ESS_PORT_STATUS_SPEED_INV 0x03 +#define ESS_PORT_STATUS_SPEED_1000 0x02 +#define ESS_PORT_STATUS_SPEED_100 0x01 +#define ESS_PORT_STATUS_SPEED_10 0x00 + +#define ESS_PORT_1G_FDX (ESS_PORT_STATUS_DUPLEX_MODE | ESS_PORT_STATUS_RX_FLOW_EN | \ + ESS_PORT_STATUS_TX_FLOW_EN | ESS_PORT_STATUS_RX_MAC_EN | \ + ESS_PORT_STATUS_TX_MAC_EN | ESS_PORT_STATUS_SPEED_1000) + +#define PHY_STATUS_REG 0x11 +#define PHY_STATUS_SPEED 0xC000 +#define PHY_STATUS_SPEED_SHIFT 14 +#define PHY_STATUS_DUPLEX 0x2000 +#define PHY_STATUS_DUPLEX_SHIFT 13 +#define PHY_STATUS_SPEED_DUPLEX_RESOLVED 0x0800 +#define PHY_STATUS_CARRIER 0x0400 +#define PHY_STATUS_CARRIER_SHIFT 10 + +/* Port lookup control registers */ +#define ESS_PORT0_LOOKUP_CTRL 0x0660 +#define ESS_PORT1_LOOKUP_CTRL 0x066C +#define ESS_PORT2_LOOKUP_CTRL 0x0678 +#define ESS_PORT3_LOOKUP_CTRL 0x0684 +#define ESS_PORT4_LOOKUP_CTRL 0x0690 +#define ESS_PORT5_LOOKUP_CTRL 0x069C + +#define ESS_PORT0_HEADER_CTRL 0x009C + +#define ESS_PORTS_ALL 0x3f + +#define ESS_FWD_CTRL1 0x0624 +#define ESS_FWD_CTRL1_UC_FLOOD BITS(0, 7) +#define ESS_FWD_CTRL1_UC_FLOOD_S 0 +#define ESS_FWD_CTRL1_MC_FLOOD BITS(8, 7) +#define ESS_FWD_CTRL1_MC_FLOOD_S 8 +#define ESS_FWD_CTRL1_BC_FLOOD BITS(16, 7) +#define ESS_FWD_CTRL1_BC_FLOOD_S 16 +#define ESS_FWD_CTRL1_IGMP BITS(24, 7) +#define ESS_FWD_CTRL1_IGMP_S 24 + +#endif /* _ESS_EDMA_H_ */ diff --git a/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-cm520-79f.dts b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-cm520-79f.dts new file mode 100644 index 00000000..019a8a19 --- /dev/null +++ b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-cm520-79f.dts @@ -0,0 +1,300 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qcom-ipq4019.dtsi" +#include +#include +#include + +/ { + model = "MobiPromo CM520-79F"; + compatible = "mobipromo,cm520-79f"; + + aliases { + led-boot = &led_sys; + led-failsafe = &led_sys; + led-running = &led_sys; + led-upgrade = &led_sys; + }; + + chosen { + bootargs-append = " ubi.block=0,1 root=/dev/ubiblock0_1"; + }; + + soc { + rng@22000 { + status = "okay"; + }; + + mdio@90000 { + status = "okay"; + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>; + reset-delay-us = <1000>; + }; + + ess-psgmii@98000 { + status = "okay"; + }; + + tcsr@1949000 { + compatible = "qcom,tcsr"; + reg = <0x1949000 0x100>; + qcom,wifi_glb_cfg = ; + }; + + tcsr@194b000 { + compatible = "qcom,tcsr"; + reg = <0x194b000 0x100>; + qcom,usb-hsphy-mode-select = ; + }; + + ess_tcsr@1953000 { + compatible = "qcom,tcsr"; + reg = <0x1953000 0x1000>; + qcom,ess-interface-select = ; + }; + + tcsr@1957000 { + compatible = "qcom,tcsr"; + reg = <0x1957000 0x100>; + qcom,wifi_noc_memtype_m0_m2 = ; + }; + + usb2@60f8800 { + status = "okay"; + + dwc3@6000000 { + #address-cells = <1>; + #size-cells = <0>; + + usb2_port1: port@1 { + reg = <1>; + #trigger-source-cells = <0>; + }; + }; + }; + + usb3@8af8800 { + status = "okay"; + + dwc3@8a00000 { + #address-cells = <1>; + #size-cells = <0>; + + usb3_port1: port@1 { + reg = <1>; + #trigger-source-cells = <0>; + }; + + usb3_port2: port@2 { + reg = <2>; + #trigger-source-cells = <0>; + }; + }; + }; + + crypto@8e3a000 { + status = "okay"; + }; + + watchdog@b017000 { + status = "okay"; + }; + + ess-switch@c000000 { + status = "okay"; + }; + + edma@c080000 { + status = "okay"; + }; + }; + + led_spi { + compatible = "spi-gpio"; + #address-cells = <1>; + #size-cells = <0>; + + sck-gpios = <&tlmm 40 GPIO_ACTIVE_HIGH>; + mosi-gpios = <&tlmm 36 GPIO_ACTIVE_HIGH>; + num-chipselects = <0>; + + led_gpio: led_gpio@0 { + compatible = "fairchild,74hc595"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + registers-number = <1>; + spi-max-frequency = <1000000>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_usb: usb { + label = "cm520-79f:blue:usb"; + gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "usbport"; + trigger-sources = <&usb3_port1>, <&usb3_port2>, <&usb2_port1>; + }; + + led_sys: can { + label = "cm520-79f:blue:can"; + gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>; + }; + + wan { + label = "cm520-79f:blue:wan"; + gpios = <&led_gpio 0 GPIO_ACTIVE_LOW>; + }; + + lan1 { + label = "cm520-79f:blue:lan1"; + gpios = <&led_gpio 1 GPIO_ACTIVE_LOW>; + }; + + lan2 { + label = "cm520-79f:blue:lan2"; + gpios = <&led_gpio 2 GPIO_ACTIVE_LOW>; + }; + + wlan2g { + label = "cm520-79f:blue:wlan2g"; + gpios = <&led_gpio 5 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0tpt"; + }; + + wlan5g { + label = "cm520-79f:blue:wlan5g"; + gpios = <&led_gpio 6 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy1tpt"; + }; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&tlmm 18 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; +}; + +&blsp_dma { + status = "okay"; +}; + +&blsp1_uart1 { + status = "okay"; +}; + +&blsp1_uart2 { + status = "okay"; +}; + +&cryptobam { + status = "okay"; +}; + +&gmac0 { + mtd-mac-address = <&art 0x1006>; +}; + +&gmac1 { + mtd-mac-address = <&art 0x5006>; +}; + +&nand { + pinctrl-0 = <&nand_pins>; + pinctrl-names = "default"; + status = "okay"; + + nand@0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Bootloader"; + reg = <0x0 0xb00000>; + }; + + art: partition@b00000 { + label = "ART"; + reg = <0xb00000 0x80000>; + read-only; + }; + + partition@b80000 { + label = "rootfs"; + reg = <0xb80000 0x7480000>; + }; + }; + }; +}; + +&qpic_bam { + status = "okay"; +}; + +&tlmm { + mdio_pins: mdio_pinmux { + mux_1 { + pins = "gpio6"; + function = "mdio"; + bias-pull-up; + }; + + mux_2 { + pins = "gpio7"; + function = "mdc"; + bias-pull-up; + }; + }; + + nand_pins: nand_pins { + pullups { + pins = "gpio52", "gpio53", "gpio58", + "gpio59"; + function = "qpic"; + bias-pull-up; + }; + + pulldowns { + pins = "gpio54", "gpio55", "gpio56", + "gpio57", "gpio60", "gpio61", + "gpio62", "gpio63", "gpio64", + "gpio65", "gpio66", "gpio67", + "gpio68", "gpio69"; + function = "qpic"; + bias-pull-down; + }; + }; +}; + +&usb3_ss_phy { + status = "okay"; +}; + +&usb3_hs_phy { + status = "okay"; +}; + +&usb2_hs_phy { + status = "okay"; +}; + +&wifi0 { + status = "okay"; + qcom,ath10k-calibration-variant = "CM520-79F"; +}; + +&wifi1 { + status = "okay"; + qcom,ath10k-calibration-variant = "CM520-79F"; +}; From a66353a01576c5146ae0d72ee1f8b24ba33cb88e Mon Sep 17 00:00:00 2001 From: suyuan <175338101@qq.com> Date: Wed, 23 Sep 2020 16:04:43 +0800 Subject: [PATCH 20/27] =?UTF-8?q?=E4=BF=AE=E5=A4=8DCM520=E5=9C=A8OPBOOT?= =?UTF-8?q?=E7=9A=84=E5=90=AF=E5=8A=A8=E5=88=86=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../arm/boot/dts/qcom-ipq4019-cm520-79f.dts | 300 ++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-cm520-79f.dts diff --git a/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-cm520-79f.dts b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-cm520-79f.dts new file mode 100644 index 00000000..019a8a19 --- /dev/null +++ b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-cm520-79f.dts @@ -0,0 +1,300 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qcom-ipq4019.dtsi" +#include +#include +#include + +/ { + model = "MobiPromo CM520-79F"; + compatible = "mobipromo,cm520-79f"; + + aliases { + led-boot = &led_sys; + led-failsafe = &led_sys; + led-running = &led_sys; + led-upgrade = &led_sys; + }; + + chosen { + bootargs-append = " ubi.block=0,1 root=/dev/ubiblock0_1"; + }; + + soc { + rng@22000 { + status = "okay"; + }; + + mdio@90000 { + status = "okay"; + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>; + reset-delay-us = <1000>; + }; + + ess-psgmii@98000 { + status = "okay"; + }; + + tcsr@1949000 { + compatible = "qcom,tcsr"; + reg = <0x1949000 0x100>; + qcom,wifi_glb_cfg = ; + }; + + tcsr@194b000 { + compatible = "qcom,tcsr"; + reg = <0x194b000 0x100>; + qcom,usb-hsphy-mode-select = ; + }; + + ess_tcsr@1953000 { + compatible = "qcom,tcsr"; + reg = <0x1953000 0x1000>; + qcom,ess-interface-select = ; + }; + + tcsr@1957000 { + compatible = "qcom,tcsr"; + reg = <0x1957000 0x100>; + qcom,wifi_noc_memtype_m0_m2 = ; + }; + + usb2@60f8800 { + status = "okay"; + + dwc3@6000000 { + #address-cells = <1>; + #size-cells = <0>; + + usb2_port1: port@1 { + reg = <1>; + #trigger-source-cells = <0>; + }; + }; + }; + + usb3@8af8800 { + status = "okay"; + + dwc3@8a00000 { + #address-cells = <1>; + #size-cells = <0>; + + usb3_port1: port@1 { + reg = <1>; + #trigger-source-cells = <0>; + }; + + usb3_port2: port@2 { + reg = <2>; + #trigger-source-cells = <0>; + }; + }; + }; + + crypto@8e3a000 { + status = "okay"; + }; + + watchdog@b017000 { + status = "okay"; + }; + + ess-switch@c000000 { + status = "okay"; + }; + + edma@c080000 { + status = "okay"; + }; + }; + + led_spi { + compatible = "spi-gpio"; + #address-cells = <1>; + #size-cells = <0>; + + sck-gpios = <&tlmm 40 GPIO_ACTIVE_HIGH>; + mosi-gpios = <&tlmm 36 GPIO_ACTIVE_HIGH>; + num-chipselects = <0>; + + led_gpio: led_gpio@0 { + compatible = "fairchild,74hc595"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + registers-number = <1>; + spi-max-frequency = <1000000>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_usb: usb { + label = "cm520-79f:blue:usb"; + gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "usbport"; + trigger-sources = <&usb3_port1>, <&usb3_port2>, <&usb2_port1>; + }; + + led_sys: can { + label = "cm520-79f:blue:can"; + gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>; + }; + + wan { + label = "cm520-79f:blue:wan"; + gpios = <&led_gpio 0 GPIO_ACTIVE_LOW>; + }; + + lan1 { + label = "cm520-79f:blue:lan1"; + gpios = <&led_gpio 1 GPIO_ACTIVE_LOW>; + }; + + lan2 { + label = "cm520-79f:blue:lan2"; + gpios = <&led_gpio 2 GPIO_ACTIVE_LOW>; + }; + + wlan2g { + label = "cm520-79f:blue:wlan2g"; + gpios = <&led_gpio 5 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0tpt"; + }; + + wlan5g { + label = "cm520-79f:blue:wlan5g"; + gpios = <&led_gpio 6 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy1tpt"; + }; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&tlmm 18 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; +}; + +&blsp_dma { + status = "okay"; +}; + +&blsp1_uart1 { + status = "okay"; +}; + +&blsp1_uart2 { + status = "okay"; +}; + +&cryptobam { + status = "okay"; +}; + +&gmac0 { + mtd-mac-address = <&art 0x1006>; +}; + +&gmac1 { + mtd-mac-address = <&art 0x5006>; +}; + +&nand { + pinctrl-0 = <&nand_pins>; + pinctrl-names = "default"; + status = "okay"; + + nand@0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Bootloader"; + reg = <0x0 0xb00000>; + }; + + art: partition@b00000 { + label = "ART"; + reg = <0xb00000 0x80000>; + read-only; + }; + + partition@b80000 { + label = "rootfs"; + reg = <0xb80000 0x7480000>; + }; + }; + }; +}; + +&qpic_bam { + status = "okay"; +}; + +&tlmm { + mdio_pins: mdio_pinmux { + mux_1 { + pins = "gpio6"; + function = "mdio"; + bias-pull-up; + }; + + mux_2 { + pins = "gpio7"; + function = "mdc"; + bias-pull-up; + }; + }; + + nand_pins: nand_pins { + pullups { + pins = "gpio52", "gpio53", "gpio58", + "gpio59"; + function = "qpic"; + bias-pull-up; + }; + + pulldowns { + pins = "gpio54", "gpio55", "gpio56", + "gpio57", "gpio60", "gpio61", + "gpio62", "gpio63", "gpio64", + "gpio65", "gpio66", "gpio67", + "gpio68", "gpio69"; + function = "qpic"; + bias-pull-down; + }; + }; +}; + +&usb3_ss_phy { + status = "okay"; +}; + +&usb3_hs_phy { + status = "okay"; +}; + +&usb2_hs_phy { + status = "okay"; +}; + +&wifi0 { + status = "okay"; + qcom,ath10k-calibration-variant = "CM520-79F"; +}; + +&wifi1 { + status = "okay"; + qcom,ath10k-calibration-variant = "CM520-79F"; +}; From 9386655b0212e02f34cfbb44030986ba162fb027 Mon Sep 17 00:00:00 2001 From: suyuan <175338101@qq.com> Date: Wed, 23 Sep 2020 16:07:58 +0800 Subject: [PATCH 21/27] =?UTF-8?q?=E6=96=B0=E5=A2=9Ecm520-79f=20=E6=98=9F?= =?UTF-8?q?=E9=99=85=E5=AE=9D=E7=9B=92=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config-cm520-79f | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 config-cm520-79f diff --git a/config-cm520-79f b/config-cm520-79f new file mode 100644 index 00000000..d37328a9 --- /dev/null +++ b/config-cm520-79f @@ -0,0 +1,6 @@ +CONFIG_TARGET_ipq40xx=y +CONFIG_TARGET_ipq40xx_generic=y +CONFIG_TARGET_ipq40xx_generic_DEVICE_mobipromo_cm520-79f=y +CONFIG_PACKAGE_kmod-6lowpan=y +# CONFIG_KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE is not set +CONFIG_KERNEL_CC_OPTIMIZE_FOR_SIZE=y From 85ca80be4a55a0b91fd703bb538f8a4d05efd82e Mon Sep 17 00:00:00 2001 From: suyuan <175338101@qq.com> Date: Wed, 23 Sep 2020 16:27:14 +0800 Subject: [PATCH 22/27] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=8Bled=E8=BF=98?= =?UTF-8?q?=E6=9C=89ipq40xx=E7=9A=84=E4=B8=AD=E6=96=AD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ipq40xx/base-files/etc/board.d/01_leds | 90 ++++++++++ .../base-files/etc/board.d/03_gpio_switches | 26 +++ .../etc/hotplug.d/net/21_adjust_network | 7 + .../base-files/etc/init.d/adjust_network | 19 +++ .../ipq40xx/base-files/etc/init.d/bootcount | 16 ++ .../ipq40xx/base-files/lib/adjust_network.sh | 89 ++++++++++ .../lib/preinit/05_set_iface_mac_ipq40xx.sh | 40 +++++ .../preinit/06_set_preinit_iface_ipq40xx.sh | 20 +++ .../base-files/lib/upgrade/platform.sh | 159 +++++++++++++++--- 9 files changed, 446 insertions(+), 20 deletions(-) create mode 100644 root/target/linux/ipq40xx/base-files/etc/board.d/01_leds create mode 100644 root/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches create mode 100644 root/target/linux/ipq40xx/base-files/etc/hotplug.d/net/21_adjust_network create mode 100644 root/target/linux/ipq40xx/base-files/etc/init.d/adjust_network create mode 100644 root/target/linux/ipq40xx/base-files/etc/init.d/bootcount create mode 100644 root/target/linux/ipq40xx/base-files/lib/adjust_network.sh create mode 100644 root/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh create mode 100644 root/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh diff --git a/root/target/linux/ipq40xx/base-files/etc/board.d/01_leds b/root/target/linux/ipq40xx/base-files/etc/board.d/01_leds new file mode 100644 index 00000000..4aeeba46 --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/etc/board.d/01_leds @@ -0,0 +1,90 @@ +#!/bin/sh +# +# Copyright (C) 2015 OpenWrt.org +# + +. /lib/functions/uci-defaults.sh + +board_config_update + +board=$(board_name) +boardname="${board##*,}" + +case "$board" in +alfa-network,ap120c-ac) + ucidef_set_led_netdev "wan" "WAN" "${boardname}:amber:wan" "eth1" + ;; +asus,rt-ac58u) + ucidef_set_led_netdev "wan" "WAN" "${boardname}:blue:wan" "eth1" + ucidef_set_led_switch "lan" "LAN" "${boardname}:blue:lan" "switch0" "0x1e" + ;; +asus,rt-acrh17) + ucidef_set_led_default "status" "STATUS" "${boardname}:blue:status" "1" + ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:blue:wlan2g" "phy1tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:blue:wlan5g" "phy0tpt" + ucidef_set_led_netdev "wan" "WAN" "${boardname}:blue:wan" "eth1" + ucidef_set_led_switch "lan1" "LAN1" "${boardname}:blue:lan1" "switch0" "0x02" + ucidef_set_led_switch "lan2" "LAN2" "${boardname}:blue:lan2" "switch0" "0x04" + ucidef_set_led_switch "lan3" "LAN3" "${boardname}:blue:lan3" "switch0" "0x08" + ucidef_set_led_switch "lan4" "LAN4" "${boardname}:blue:lan4" "switch0" "0x10" + ;; +avm,fritzbox-4040) + ucidef_set_led_wlan "wlan" "WLAN" "fritz4040:green:wlan" "phy0tpt" "phy1tpt" + ucidef_set_led_netdev "wan" "WAN" "fritz4040:green:wan" "eth1" + ucidef_set_led_switch "lan" "LAN" "fritz4040:green:lan" "switch0" "0x1e" + ;; +avm,fritzbox-7530 |\ +glinet,gl-b1300) + ucidef_set_led_wlan "wlan" "WLAN" "${boardname}:green:wlan" "phy0tpt" + ;; +engenius,eap1300) + ucidef_set_led_netdev "lan" "LAN" "${boardname}:blue:lan" "eth0" + ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:blue:wlan2g" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:yellow:wlan5g" "phy1tpt" + ucidef_set_led_default "mesh" "MESH" "${boardname}:blue:mesh" "0" + ;; +engenius,eap2200) + ucidef_set_led_netdev "lan1" "LAN1" "${boardname}:blue:lan1" "eth0" + ucidef_set_led_netdev "lan2" "LAN2" "${boardname}:blue:lan2" "eth1" + ;; +engenius,ens620ext) + ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2G" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:green:wlan5G" "phy1tpt" + ucidef_set_led_netdev "lan1" "LAN1" "${boardname}:green:lan1" "eth0" + ucidef_set_led_netdev "lan2" "LAN2" "${boardname}:green:lan2" "eth1" + ;; +mobipromo,cm520-79f) + ucidef_set_led_netdev "wan" "WAN" "${boardname}:blue:wan" "eth1" + ucidef_set_led_switch "lan1" "LAN1" "${boardname}:blue:lan1" "switch0" "0x10" + ucidef_set_led_switch "lan2" "LAN2" "${boardname}:blue:lan2" "switch0" "0x08" + ;; +netgear,ex6100v2 |\ +netgear,ex6150v2) + ucidef_set_led_wlan "wlan2g" "WLAN2G" "ex61x0v2:green:router" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "ex61x0v2:green:client" "phy1tpt" + ;; +p2w,r619ac |\ +p2w,r619ac-128m) + ucidef_set_led_wlan "wlan2g" "WLAN2G" "r619ac:blue:wlan2g" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "r619ac:blue:wlan5g" "phy1tpt" + ;; +qxwlan,e2600ac-c1 |\ +qxwlan,e2600ac-c2) + ucidef_set_led_wlan "wlan2g" "WLAN0" "e2600ac:green:wlan0" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN1" "e2600ac:green:wlan1" "phy1tpt" + ;; +zyxel,nbg6617) + ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2G" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:green:wlan5G" "phy1tpt" + ;; +zyxel,wre6606) + ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2g" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:green:wlan5g" "phy1tpt" + ;; +*) + ;; +esac + +board_config_flush + +exit 0 \ No newline at end of file diff --git a/root/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches b/root/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches new file mode 100644 index 00000000..a483fbc0 --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches @@ -0,0 +1,26 @@ +#!/bin/sh + +. /lib/functions/uci-defaults.sh + +board_config_update + +board=$(board_name) + +case "$board" in +cellc,rtl30vw) + ucidef_add_gpio_switch "w_disable" "W_DISABLE mPCIE pin" "398" "1" + ucidef_add_gpio_switch "pmd_resin_n" "PMD_RESIN_N pin" "399" "1" + ucidef_add_gpio_switch "mcpie_vcc" "LTE power" "400" "0" + ucidef_add_gpio_switch "usb_vcc" "USB power" "401" "0" + ;; +cilab,meshpoint-one) + ucidef_add_gpio_switch "poe_passtrough" "POE passtrough enable" "413" "1" + ;; +compex,wpj428) + ucidef_add_gpio_switch "sim_card_select" "SIM card select" "3" "0" + ;; +esac + +board_config_flush + +exit 0 \ No newline at end of file diff --git a/root/target/linux/ipq40xx/base-files/etc/hotplug.d/net/21_adjust_network b/root/target/linux/ipq40xx/base-files/etc/hotplug.d/net/21_adjust_network new file mode 100644 index 00000000..2caf2494 --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/etc/hotplug.d/net/21_adjust_network @@ -0,0 +1,7 @@ +#!/bin/sh + +[ -f /lib/adjust_network.sh ] && { + . /lib/adjust_network.sh + + adjust_eth_queue +} \ No newline at end of file diff --git a/root/target/linux/ipq40xx/base-files/etc/init.d/adjust_network b/root/target/linux/ipq40xx/base-files/etc/init.d/adjust_network new file mode 100644 index 00000000..b1359597 --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/etc/init.d/adjust_network @@ -0,0 +1,19 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006-2011 OpenWrt.org + +START=11 +STOP=98 + +adjust_smp_affinity() { + test -f /lib/adjust_network.sh && { + . /lib/adjust_network.sh + + adjust_eth_queue + adjust_edma_smp_affinity + adjust_radio_smp_affinity + } +} + +boot() { + adjust_smp_affinity +} \ No newline at end of file diff --git a/root/target/linux/ipq40xx/base-files/etc/init.d/bootcount b/root/target/linux/ipq40xx/base-files/etc/init.d/bootcount new file mode 100644 index 00000000..68c5fc11 --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/etc/init.d/bootcount @@ -0,0 +1,16 @@ +#!/bin/sh /etc/rc.common + +START=99 + +boot() { + case $(board_name) in + alfa-network,ap120c-ac) + [ -n "$(fw_printenv bootcount changed 2>/dev/null)" ] &&\ + echo -e "bootcount\nchanged\n" | /usr/sbin/fw_setenv -s - + ;; + linksys,ea6350v3|\ + linksys,ea8300) + mtd resetbc s_env || true + ;; + esac +} \ No newline at end of file diff --git a/root/target/linux/ipq40xx/base-files/lib/adjust_network.sh b/root/target/linux/ipq40xx/base-files/lib/adjust_network.sh new file mode 100644 index 00000000..d4829b09 --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/lib/adjust_network.sh @@ -0,0 +1,89 @@ +#!/bin/sh +# this scripts is used for adjust cpu's choice of interrupts. +# + +################################################ +# Adjust smp_affinity of edma +# Globals: +# None +# Arguments: +# None +# Returns: +# None +# Remark: +# execute only once on start-up. +################################################ +adjust_edma_smp_affinity() { + grep -q edma_eth_ /proc/interrupts || return 0 + local nr=`cat /proc/cpuinfo | grep processor | wc -l` + local cpu=0 + local tx_irq_num + + for tx_num in `seq 0 1 15` ; do + cpu=`printf "%x" $((1<<((tx_num/4+0)%nr)))` + tx_irq_num=`grep -m1 edma_eth_tx$tx_num /proc/interrupts | cut -d ':' -f 1 | tail -n1 | tr -d ' '` + [ -n "$tx_irq_num" ] && echo $cpu > /proc/irq/$tx_irq_num/smp_affinity + done + + for rx_num in `seq 0 1 7` ; do + cpu=`printf "%x" $((1<<((rx_num/2)%nr)))` + rx_irq_num=`grep -m1 edma_eth_rx$rx_num /proc/interrupts | cut -d ':' -f 1 | tail -n1 | tr -d ' '` + [ -n "$rx_irq_num" ] && echo $cpu > /proc/irq/$rx_irq_num/smp_affinity + done +} + +################################################ +# Adjust smp_affinity of ath10k for 2G and 5G +# Globals: +# None +# Arguments: +# None +# Returns: +# None +# Remark: +# execute only once on start-up. +################################################ +adjust_radio_smp_affinity() { + local irqs="`grep -E 'ath10k' /proc/interrupts | cut -d ':' -f 1 | tr -d ' '`" + local nr=`cat /proc/cpuinfo | grep processor | wc -l` + local idx=2 + + for irq in $irqs; do + cpu=`printf "%x" $((1<<((idx)%nr)))` + echo $cpu > /proc/irq/$irq/smp_affinity + idx=$((idx+1)) + done +} + +################################################ +# Adjust queue of eth +# Globals: +# None +# Arguments: +# None +# Returns: +# None +# Remark: +# Each network reboot needs to be executed. +################################################ +adjust_eth_queue() { + local nr=`cat /proc/cpuinfo | grep processor | wc -l` + local idx=0 + + for epath in /sys/class/net/eth[0-9]*; do + test -e $epath || break + echo $epath | grep -q "\." && continue + eth=`basename $epath` + idx=0 + for exps in /sys/class/net/$eth/queues/rx-[0-9]*/rps_cpus; do + test -e $exps || break + cpu=`printf "%x" $((1<<((idx+1)%nr)))` + idx=$((idx+1)) + echo $cpu > $exps + echo 256 > `dirname $exps`/rps_flow_cnt + done + which ethtool >/dev/null 2>&1 && ethtool -K $eth gro off + done + + echo 1024 > /proc/sys/net/core/rps_sock_flow_entries +} \ No newline at end of file diff --git a/root/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh b/root/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh new file mode 100644 index 00000000..d769f39e --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh @@ -0,0 +1,40 @@ +. /lib/functions.sh + +preinit_set_mac_address() { + case $(board_name) in + asus,map-ac2200) + base_mac=$(mtd_get_mac_binary_ubi Factory 0x1006) + ip link set dev eth0 address $(macaddr_add "$base_mac" +1) + ip link set dev eth1 address $(macaddr_add "$base_mac" +3) + ;; + asus,rt-acrh17|\ + asus,rt-ac58u) + CI_UBIPART=UBI_DEV + base_mac=$(mtd_get_mac_binary_ubi Factory 4102) + ip link set dev eth0 address $(macaddr_add "$base_mac" +1) + ;; + ezviz,cs-w3-wd1200g-eup) + ip link set dev eth0 address $(mtd_get_mac_binary "ART" 0x6) + ip link set dev eth1 address $(mtd_get_mac_binary "ART" 0x0) + ;; + engenius,eap2200) + base_mac=$(cat /sys/class/net/eth0/address) + ip link set dev eth1 address $(macaddr_add "${base_mac}" +1) + ;; + linksys,ea8300) + base_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr) + ip link set dev eth0 address "${base_mac}" + ip link set dev eth1 address $(macaddr_add "${base_mac}" 1) + ;; + meraki,mr33) + mac_lan=$(get_mac_binary "/sys/bus/i2c/devices/0-0050/eeprom" 0x66) + [ -n "$mac_lan" ] && ip link set dev eth0 address "$mac_lan" + ;; + zyxel,nbg6617) + base_mac=$(cat /sys/class/net/eth0/address) + ip link set dev eth0 address $(macaddr_add "$base_mac" +2) + ip link set dev eth1 address $(macaddr_add "$base_mac" +3) + esac +} + +boot_hook_add preinit_main preinit_set_mac_address \ No newline at end of file diff --git a/root/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh b/root/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh new file mode 100644 index 00000000..5ca17622 --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh @@ -0,0 +1,20 @@ +set_preinit_iface() { + . /lib/functions.sh + + case $(board_name) in + aruba,ap-303| \ + asus,rt-ac58u| \ + avm,fritzbox-4040| \ + ezviz,cs-w3-wd1200g-eup| \ + glinet,gl-b1300| \ + linksys,ea8300| \ + meraki,mr33| \ + zyxel,nbg6617) + ifname=eth0 + ;; + *) + ;; + esac +} + +boot_hook_add preinit_main set_preinit_iface \ No newline at end of file diff --git a/root/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/root/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh index f874aa4b..9daa7768 100644 --- a/root/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh +++ b/root/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh @@ -4,28 +4,141 @@ REQUIRE_IMAGE_METADATA=1 RAMFS_COPY_BIN='fw_printenv fw_setenv' RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock' -platform_check_image() { - case "$(board_name)" in - asus,rt-ac58u) - CI_UBIPART="UBI_DEV" - local ubidev=$(nand_find_ubi $CI_UBIPART) - local asus_root=$(nand_find_volume $ubidev jffs2) +ubi_kill_if_exist() { + local ubidev="$( nand_find_ubi "$CI_UBIPART" )" + local c_ubivol="$( nand_find_volume $ubidev $1 )" + umount -f /dev/$c_ubivol 2>/dev/null + [ "$c_ubivol" ] && ubirmvol /dev/$ubidev -N $1 || true + echo "Partition $1 removed." +} - [ -n "$asus_root" ] || return 0 +# idea from @981213 +# Tar sysupgrade for ASUS RT-AC82U/RT-AC58U +# An ubi repartition is required due to the strange partition table created by Asus. +# We create all the factory partitions to make sure that the U-boot tftp recovery still works. +# The reserved kernel partition size should be enough to put the factory image in. +asus_nand_upgrade_tar() { + local kpart_size="$1" + local tar_file="$2" - cat << EOF -jffs2 partition is still present. -There's probably no space left -to install the filesystem. + local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$') + board_dir=${board_dir%/} -You need to delete the jffs2 partition first: -# ubirmvol /dev/ubi0 --name=jffs2 + local kernel_length=`(tar xf $tar_file ${board_dir}/kernel -O | wc -c) 2> /dev/null` + local rootfs_length=`(tar xf $tar_file ${board_dir}/root -O | wc -c) 2> /dev/null` -Once this is done. Retry. -EOF + local mtdnum="$( find_mtd_index "$CI_UBIPART" )" + if [ ! "$mtdnum" ]; then + echo "cannot find ubi mtd partition $CI_UBIPART" return 1 - ;; - esac + fi + + local ubidev="$( nand_find_ubi "$CI_UBIPART" )" + if [ ! "$ubidev" ]; then + ubiattach -m "$mtdnum" + sync + ubidev="$( nand_find_ubi "$CI_UBIPART" )" + fi + + if [ ! "$ubidev" ]; then + echo "cannot find ubi device $CI_UBIPART" + return 1 + fi + + local root_ubivol="$( nand_find_volume $ubidev rootfs )" + # remove ubiblock device of rootfs + local root_ubiblk="ubiblock${root_ubivol:3}" + if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then + echo "removing $root_ubiblk" + if ! ubiblock -r /dev/$root_ubivol; then + echo "cannot remove $root_ubiblk" + return 1; + fi + fi + + ubi_kill_if_exist rootfs_data + ubi_kill_if_exist rootfs + ubi_kill_if_exist jffs2 + ubi_kill_if_exist linux2 + ubi_kill_if_exist linux + + ubimkvol /dev/$ubidev -N linux -s $kpart_size + ubimkvol /dev/$ubidev -N linux2 -s $kpart_size + ubimkvol /dev/$ubidev -N jffs2 -s 2539520 + ubimkvol /dev/$ubidev -N rootfs -s $rootfs_length + ubimkvol /dev/$ubidev -N rootfs_data -m + + local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)" + echo "Kernel at $kern_ubivol.Writing..." + tar xf $tar_file ${board_dir}/kernel -O | \ + ubiupdatevol /dev/$kern_ubivol -s $kernel_length - + echo "Done." + + local root_ubivol="$(nand_find_volume $ubidev rootfs)" + echo "Rootfs at $root_ubivol.Writing..." + tar xf $tar_file ${board_dir}/root -O | \ + ubiupdatevol /dev/$root_ubivol -s $rootfs_length - + echo "Done." + + nand_do_upgrade_success +} + +# idea from @981213 +# Factory image sysupgrade for ASUS RT-AC82U/RT-AC58U +# Delete all the partitions we created before, create "linux" partition and write factory image in. +# Skip the first 64bytes which is an uImage header to verify the firmware. +# The kernel partition size should be the original one. +asus_nand_upgrade_factory() { + local kpart_size="$1" + local fw_file="$2" + + local mtdnum="$( find_mtd_index "$CI_UBIPART" )" + if [ ! "$mtdnum" ]; then + echo "cannot find ubi mtd partition $CI_UBIPART" + return 1 + fi + + local ubidev="$( nand_find_ubi "$CI_UBIPART" )" + if [ ! "$ubidev" ]; then + ubiattach -m "$mtdnum" + sync + ubidev="$( nand_find_ubi "$CI_UBIPART" )" + fi + + if [ ! "$ubidev" ]; then + echo "cannot find ubi device $CI_UBIPART" + return 1 + fi + + local root_ubivol="$( nand_find_volume $ubidev rootfs )" + # remove ubiblock device of rootfs + local root_ubiblk="ubiblock${root_ubivol:3}" + if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then + echo "removing $root_ubiblk" + if ! ubiblock -r /dev/$root_ubivol; then + echo "cannot remove $root_ubiblk" + return 1; + fi + fi + + ubi_kill_if_exist rootfs_data + ubi_kill_if_exist rootfs + ubi_kill_if_exist jffs2 + ubi_kill_if_exist linux2 + ubi_kill_if_exist linux + + ubimkvol /dev/$ubidev -N linux -s $kpart_size + + local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)" + echo "Asus linux at $kern_ubivol.Writing..." + ubiupdatevol /dev/$kern_ubivol --skip=64 $fw_file + echo "Done." + + umount -a + reboot -f +} + +platform_check_image() { return 0; } @@ -64,7 +177,6 @@ platform_do_upgrade() { avm,fritzbox-7530 |\ avm,fritzrepeater-1200 |\ avm,fritzrepeater-3000 |\ - buffalo,wtr-m2133hp |\ cilab,meshpoint-one |\ engenius,eap2200 |\ mobipromo,cm520-79f |\ @@ -86,10 +198,17 @@ platform_do_upgrade() { CI_KERNPART="linux" nand_do_upgrade "$1" ;; + asus,rt-acrh17|\ asus,rt-ac58u) + local magic=$(get_magic_long "$1") CI_UBIPART="UBI_DEV" CI_KERNPART="linux" - nand_do_upgrade "$1" + if [ "$magic" == "27051956" ]; then + echo "Got Asus factory image." + asus_nand_upgrade_factory 50409472 "$1" + else + asus_nand_upgrade_tar 20951040 "$1" + fi ;; cellc,rtl30vw) CI_UBIPART="ubifs" @@ -120,4 +239,4 @@ platform_do_upgrade() { default_do_upgrade "$1" ;; esac -} +} \ No newline at end of file From d168087bb9d8c7690d6317d058069da2f661c108 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 23 Sep 2020 16:56:40 +0200 Subject: [PATCH 23/27] Remove upstreamed patch --- .../0104-dts-add-pause-to-port6.patch | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 root/target/linux/mediatek/patches-5.4/0104-dts-add-pause-to-port6.patch diff --git a/root/target/linux/mediatek/patches-5.4/0104-dts-add-pause-to-port6.patch b/root/target/linux/mediatek/patches-5.4/0104-dts-add-pause-to-port6.patch deleted file mode 100644 index a8bc7979..00000000 --- a/root/target/linux/mediatek/patches-5.4/0104-dts-add-pause-to-port6.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 3a466fd3d5b921c085fd3c863cab3f1afdb90c9c Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 12 Jan 2020 16:46:33 +0100 -Subject: [PATCH] arm: dts: add pause to port6 of switch - -to be same as gmac0 ---- - arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -index 52343bd76fe5..7b8383af87e0 100644 ---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -253,6 +253,7 @@ - fixed-link { - speed = <1000>; - full-duplex; -+ pause; - }; - }; - }; From 21e83ca6fc7ba88df572fed67ea151fffd944915 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 23 Sep 2020 16:57:15 +0200 Subject: [PATCH 24/27] Optimize for size on wrt3200acm --- config-wrt3200acm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config-wrt3200acm b/config-wrt3200acm index 79bae0ff..1c560ff5 100644 --- a/config-wrt3200acm +++ b/config-wrt3200acm @@ -3,3 +3,5 @@ CONFIG_TARGET_mvebu_cortexa9=y CONFIG_TARGET_mvebu_cortexa9_DEVICE_linksys_wrt3200acm=y CONFIG_PACKAGE_kmod-6lowpan=y CONFIG_PACKAGE_luci-app-advanced-reboot=y +# CONFIG_KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE is not set +CONFIG_KERNEL_CC_OPTIMIZE_FOR_SIZE=y From 6c6434a34b60df16513733ee6f8f5fab702e3bc3 Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Wed, 23 Sep 2020 16:57:41 +0200 Subject: [PATCH 25/27] Update OpenWrt --- build.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index 12ee8334..af188018 100755 --- a/build.sh +++ b/build.sh @@ -71,9 +71,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "d643b10a76965a94684012d2ddf36e2bcc146274" - _get_repo feeds/packages https://github.com/openwrt/packages "0daa9fb1dd48ee63024a5fc24dd3c85e112f7ed6" - _get_repo feeds/luci https://github.com/openwrt/luci "4f6c054d7a468b980538461ede1da40789af4d46" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "620f9c773413a0deaeda2bdc22d5e9cb89b9317f" + _get_repo feeds/packages https://github.com/openwrt/packages "ed39c2f02e1f05c40161986c6d0581f7eba58bea" + _get_repo feeds/luci https://github.com/openwrt/luci "6044084a61cdd95e390002cc6a908b33185d457d" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" @@ -293,6 +293,7 @@ fi echo "Update feeds index" rm -rf feeds/luci/modules/luci-mod-network [ -d feeds/${OMR_DIST}/luci-mod-status ] && rm -rf feeds/luci/modules/luci-mod-status +[ -d feeds/${OMR_DIST}/luci-app-statistics ] && rm -rf feeds/luci/applications/luci-app-statistics cp .config .config.keep scripts/feeds clean From 6bead962271be669f7abd23ace1027afd4f975a7 Mon Sep 17 00:00:00 2001 From: suyuan <175338101@qq.com> Date: Thu, 24 Sep 2020 00:08:26 +0800 Subject: [PATCH 26/27] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=AF=86=E7=A0=81=E4=B8=BA=E5=AE=98=E7=BD=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 32 +++++++++++++++++++++--- root/package/base-files/files/etc/shadow | 5 ++++ 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 root/package/base-files/files/etc/shadow diff --git a/.gitignore b/.gitignore index 4bd7ccf9..2d93d211 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,29 @@ -sdk -source -feeds +*.o +.DS_Store +.*.swp +/env +/dl +/.config +/.config.old +/bin +/build_dir +/staging_dir +/tmp +/logs +/feeds +/feeds.conf +/files +/overlay +/package/feeds +/package/openwrt-packages +key-build* +*.orig +*.rej +*~ +.#* +*# +.emacs.desktop* +TAGS*~ +git-src +.git-credentials +/*.log diff --git a/root/package/base-files/files/etc/shadow b/root/package/base-files/files/etc/shadow new file mode 100644 index 00000000..40218708 --- /dev/null +++ b/root/package/base-files/files/etc/shadow @@ -0,0 +1,5 @@ +root:$1$ie.8vTnt$7EzhI1ZYiwp8hSAC4eSId0:18473:0:99999:7::: +daemon:*:0:0:99999:7::: +ftp:*:0:0:99999:7::: +network:*:0:0:99999:7::: +nobody:*:0:0:99999:7::: From ee89739e94412c308229777105e31dd25d53a075 Mon Sep 17 00:00:00 2001 From: suyuan <175338101@qq.com> Date: Mon, 28 Sep 2020 22:52:23 +0800 Subject: [PATCH 27/27] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E4=B8=8B=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base-files/files/bin/config_generate | 2 +- root/package/base-files/files/etc/banner | 40 ++++++++++++++++--- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/root/package/base-files/files/bin/config_generate b/root/package/base-files/files/bin/config_generate index b8665f26..ae48fe5f 100755 --- a/root/package/base-files/files/bin/config_generate +++ b/root/package/base-files/files/bin/config_generate @@ -241,7 +241,7 @@ generate_static_system() { uci -q batch <<-EOF delete system.@system[0] add system system - set system.@system[-1].hostname='OpenWrt' + set system.@system[-1].hostname='antrouter set system.@system[-1].timezone='UTC' set system.@system[-1].ttylogin='0' set system.@system[-1].log_size='64' diff --git a/root/package/base-files/files/etc/banner b/root/package/base-files/files/etc/banner index 01a091a6..fedb02b2 100644 --- a/root/package/base-files/files/etc/banner +++ b/root/package/base-files/files/etc/banner @@ -1,8 +1,38 @@ - ___ __ __ ___ _____ ___ ___ _ - / _ \ _ __ ___ _ _ | \/ | _ \_ _/ __| _ \_ _ ___ _ _| |_ ___ _ _ - | (_) | '_ \/ -_) ' \| |\/| | _/ | || (__| _/ '_/ _ \ || | _/ -_) '_| - \___/| .__/\___|_||_|_| |_|_| |_| \___|_| |_| \___/\_,_|\__\___|_| - |_| + +/*** + * ,s555SB@@& + * :9H####@@@@@Xi + * 1@@@@@@@@@@@@@@8 + * ,8@@@@@@@@@B@@@@@@8 + * :B@@@@X3hi8Bs;B@@@@@Ah, + * ,8i r@@@B: 1S ,M@@@@@@#8; + * 1AB35.i: X@@8 . SGhr ,A@@@@@@@@S + * 1@h31MX8 18Hhh3i .i3r ,A@@@@@@@@@5 + * ;@&i,58r5 rGSS: :B@@@@@@@@@@A + * 1#i . 9i hX. .: .5@@@@@@@@@@@1 + * sG1, ,G53s. 9#Xi;hS5 3B@@@@@@@B1 + * .h8h.,A@@@MXSs, #@H1: 3ssSSX@1 + * s ,@@@@@@@@@@@@Xhi, r#@@X1s9M8 .GA981 + * ,. rS8H#@@@@@@@@@@#HG51;. .h31i;9@r .8@@@@BS;i; + * .19AXXXAB@@@@@@@@@@@@@@#MHXG893hrX#XGGXM@@@@@@@@@@MS + * s@@MM@@@hsX#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&, + * :GB@#3G@@Brs ,1GM@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@B, + * .hM@@@#@@#MX 51 r;iSGAM@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@8 + * :3B@@@@@@@@@@@&9@h :Gs .;sSXH@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@: + * s&HA#@@@@@@@@@@@@@@M89A;.8S. ,r3@@@@@@@@@@@@@@@@@@@@@@@@@@@r + * ,13B@@@@@@@@@@@@@@@@@@@5 5B3 ;. ;@@@@@@@@@@@@@@@@@@@@@@@@@@@i + * 5#@@#&@@@@@@@@@@@@@@@@@@9 .39: ;@@@@@@@@@@@@@@@@@@@@@@@@@@@; + * 9@@@X:MM@@@@@@@@@@@@@@@#; ;31. H@@@@@@@@@@@@@@@@@@@@@@@@@@: + * SH#@B9.rM@@@@@@@@@@@@@B :. 3@@@@@@@@@@@@@@@@@@@@@@@@@@5 + * ,:. 9@@@@@@@@@@@#HB5 .M@@@@@@@@@@@@@@@@@@@@@@@@@B + * ,ssirhSM@&1;i19911i,. s@@@@@@@@@@@@@@@@@@@@@@@@@@S + * ,,,rHAri1h1rh&@#353Sh: 8@@@@@@@@@@@@@@@@@@@@@@@@@#: + * .A3hH@#5S553&@@#h i:i9S #@@@@@@@@@@@@@@@@@@@@@@@@@A. + * + * + * 又看源码,看你妹妹呀! + */ + ------------------------------------------------------------------------------ (%C) ------------------------------------------------------------------------------