From 5fd8ba6f313f7ae0bb151efc1f093d4fd0306461 Mon Sep 17 00:00:00 2001 From: George Moussalem Date: Mon, 7 Oct 2024 16:09:40 +0400 Subject: [PATCH] qualcommax: ipq50xx: add support for Linksys MX2000 and MX5500 Add support for Linksys MX2000 (Atlas 6) and MX5500 (Atlas 6 Pro). These devices are completely identical except for the secondary wifi chip used for 5Ghz: QCN6102 is used on MX2000 while QCN9024 is used on MX5500 Speficiations: * SoC: Qualcomm IPQ5018 (64-bit dual-core ARM Cortex-A53 @ 1.0Ghz) * Memory: Winbond W634GU6NB-11 (512 MiB DDR3-933) * Serial Port: 3v3 TTL 115200n8 * Wi-Fi: IPQ5018 (2x2 2.4 Ghz 802.11b/g/n/ax) * Wi-Fi: MX2000: QCN6102 (2x2:2 5 Ghz 802.11an/ac/ax) MX5500: QCN9024 (4x4:4 5 Ghz 802.11an/ac/ax) * Ethernet: IPQ5018 integrated virtual switch connected to an external QCA8337 switch (4 Ports 10/100/1000 GBASE-T) * Flash: Macronix MX35UF2GE4AD (256 MiB) * LEDs: 1x multi-color PWM LED * Buttons: 1x WPS (GPIO 27 Active Low) 1x Reset (GPIO 28 Acive Low) Flash instructions (in case of MX2000, else replace with MX5500 images): 1. On OEM firmware, login to the device (typically at http://192.168.1.1) and click 'CA' in the bottom right corner -> Connectivity -> Manual Upgrade. Alternatively, browse to http:///fwupdate.html. Upgrade firmware using openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin image. Optionally install on second partition, after first boot check actual partition: fw_printenv -n boot_part and install firmware on second partition using command in case of 2: mtd -r -e kernel -n write openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin kernel and in case of 1: mtd -r -e alt_kernel -n write openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin alt_kernel 2. Installation using serial connection from OEM firmware (default login: root, password: admin): fw_printenv -n boot_part In case of 2: flash_erase /dev/mtd12 0 0 nandwrite -p /dev/mtd12 openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin or in case of 1: flash_erase /dev/mtd14 0 0 nandwrite -p /dev/mtd14 openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin After first boot install firmware on second partition: mtd -r -e kernel -n write openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin kernel or: mtd -r -e alt_kernel -n write openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin alt_kernel 3. Back to the OEM firmware. Download firmware from OEM website: MX2000: https://support.linksys.com/kb/article/585-en/ MX5500: https://support.linksys.com/kb/article/587-en/ From serial or SSH: fw_printenv boot_part in case of 1: mtd -r -e alt_kernel -n write FW_MX2000_1.1.7.210469_prod.img alt_kernel else in case of 2: mtd -r -e kernel -n write FW_MX2000_1.1.7.210469_prod.img kernel Signed-off-by: George Moussalem --- package/base-files/files/sbin/sysupgrade | 4 + .../uboot-envtools/files/qualcommax_ipq50xx | 22 + package/firmware/ipq-wifi/Makefile | 4 + .../ipq-wifi/src/board-linksys_mx2000.ipq5018 | Bin 0 -> 131180 bytes .../ipq-wifi/src/board-linksys_mx2000.qcn6122 | Bin 0 -> 131180 bytes .../ipq-wifi/src/board-linksys_mx5500.ipq5018 | Bin 0 -> 131180 bytes .../ipq-wifi/src/board-linksys_mx5500.qcn9074 | Bin 0 -> 131180 bytes .../arm64/boot/dts/qcom/ipq5018-mx2000.dts | 695 ++++++++++++++++++ .../arm64/boot/dts/qcom/ipq5018-mx5500.dts | 612 +++++++++++++++ target/linux/qualcommax/image/ipq50xx.mk | 35 + .../ipq50xx/base-files/etc/board.d/02_network | 45 ++ .../etc/hotplug.d/firmware/11-ath11k-caldata | 47 ++ .../ipq50xx/base-files/etc/init.d/bootcount | 12 + .../ipq50xx/base-files/lib/upgrade/linksys.sh | 125 ++++ .../base-files/lib/upgrade/platform.sh | 32 + 15 files changed, 1633 insertions(+) create mode 100644 package/boot/uboot-envtools/files/qualcommax_ipq50xx create mode 100644 package/firmware/ipq-wifi/src/board-linksys_mx2000.ipq5018 create mode 100644 package/firmware/ipq-wifi/src/board-linksys_mx2000.qcn6122 create mode 100644 package/firmware/ipq-wifi/src/board-linksys_mx5500.ipq5018 create mode 100644 package/firmware/ipq-wifi/src/board-linksys_mx5500.qcn9074 create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx2000.dts create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx5500.dts create mode 100644 target/linux/qualcommax/ipq50xx/base-files/etc/board.d/02_network create mode 100644 target/linux/qualcommax/ipq50xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata create mode 100755 target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount create mode 100644 target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/linksys.sh create mode 100644 target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade index 611d8830bfd1ff..c91cd615374b5f 100755 --- a/package/base-files/files/sbin/sysupgrade +++ b/package/base-files/files/sbin/sysupgrade @@ -20,6 +20,7 @@ CONF_IMAGE= CONF_BACKUP_LIST=0 CONF_BACKUP= CONF_RESTORE= +CURR_PARTITION=0 NEED_IMAGE= HELP=0 TEST=0 @@ -50,6 +51,7 @@ while [ -n "$1" ]; do -r|--restore-backup) CONF_RESTORE="$2" NEED_IMAGE=1; shift;; -l|--list-backup) CONF_BACKUP_LIST=1;; -f) CONF_IMAGE="$2"; shift;; + -s) CURR_PARTITION=1;; -F|--force) export FORCE=1;; -T|--test) TEST=1;; -h|--help) HELP=1; break;; @@ -79,6 +81,7 @@ upgrade-option: -p do not attempt to restore the partition table after flash. -k include in backup a list of current installed packages at $INSTALLED_PACKAGES + -s stay on current partition (for dual firmware devices) -T | --test Verify image and config .tar.gz but do not actually flash. -F | --force @@ -416,6 +419,7 @@ else json_add_string command "$COMMAND" json_add_object options json_add_int save_partitions "$SAVE_PARTITIONS" + [ $CURR_PARTITION -eq 1 ] && json_add_boolean curr_partition 1 json_close_object ubus call system sysupgrade "$(json_dump)" diff --git a/package/boot/uboot-envtools/files/qualcommax_ipq50xx b/package/boot/uboot-envtools/files/qualcommax_ipq50xx new file mode 100644 index 00000000000000..97b01df0399245 --- /dev/null +++ b/package/boot/uboot-envtools/files/qualcommax_ipq50xx @@ -0,0 +1,22 @@ +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(board_name) + +case "$board" in +linksys,mx2000|\ +linksys,mx5500) + idx="$(find_mtd_index u_env)" + [ -n "$idx" ] && \ + ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x40000" "0x20000" "2" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config + +exit 0 diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile index d684e7f6296210..3e2953be6ecb21 100644 --- a/package/firmware/ipq-wifi/Makefile +++ b/package/firmware/ipq-wifi/Makefile @@ -37,8 +37,10 @@ ALLWIFIBOARDS:= \ dynalink_dl-wrx36 \ edgecore_eap102 \ edimax_cax1800 \ + linksys_mx2000 \ linksys_mx4200 \ linksys_mx5300 \ + linksys_mx5500 \ linksys_mx8500 \ linksys_whw03 \ netgear_lbr20 \ @@ -168,8 +170,10 @@ $(eval $(call generate-ipq-wifi-package,compex_wpq873,Compex WPQ-873)) $(eval $(call generate-ipq-wifi-package,dynalink_dl-wrx36,Dynalink DL-WRX36)) $(eval $(call generate-ipq-wifi-package,edgecore_eap102,Edgecore EAP102)) $(eval $(call generate-ipq-wifi-package,edimax_cax1800,Edimax CAX1800)) +$(eval $(call generate-ipq-wifi-package,linksys_mx2000,Linksys MX2000)) $(eval $(call generate-ipq-wifi-package,linksys_mx4200,Linksys MX4200)) $(eval $(call generate-ipq-wifi-package,linksys_mx5300,Linksys MX5300)) +$(eval $(call generate-ipq-wifi-package,linksys_mx5500,Linksys MX5500)) $(eval $(call generate-ipq-wifi-package,linksys_mx8500,Linksys MX8500)) $(eval $(call generate-ipq-wifi-package,linksys_whw03,Linksys WHW03)) $(eval $(call generate-ipq-wifi-package,netgear_lbr20,Netgear LBR20)) diff --git a/package/firmware/ipq-wifi/src/board-linksys_mx2000.ipq5018 b/package/firmware/ipq-wifi/src/board-linksys_mx2000.ipq5018 new file mode 100644 index 0000000000000000000000000000000000000000..ac297e4e3f510d980983184adf74d0da5bd62315 GIT binary patch literal 131180 zcmeHQ32#)3DA=-E;Z{yf&{9+m77{X~F zlT${eN>=#Go^UWXoOAAgeNPMq%mc{V!))&N#uEJiNO@M(p}_=nj)ttJwx=uUtjoZ)CDJ@ z=%Uwx)lH(f7P&+WoY{Se3}0fiMqY~R?>#SZ^+EG)DzdJ}!ITL_4C6U0`p-?M%xqP5 z8}AZ7H7EnKhJggC3GM?U8)abMZD7+k&dxis*sRBiv`_a6v%Z(7M+1{6&zhfjz5D$6 z^LOV<$au?fZ-ginfuWJ%B+iZZWJ;^#mL5nsoN|B4V<}IkJeP8wMn8%^PgM9BqTCM= zWgjBSyqakKR-)uGqJ$`RMnzvE%E$gE=YvF9w-ROSAxaCNdxJ8M z{0rB+Ks!QKG&UIq4qylNGmmb;4~d)uGIe=-$vD|M82;Rm7@GYl+WLd@~h!PF3SIA{PN-hY?Pmc56{5H z1Mq=)SPvh#9e*C*hX2R#0c|J+55*6{2X4bE_~1qPUyom&eW+v~&=)1>iz4(zE zdwd)0gYRYVfHo{d`Me?cuny&MicbCg_~pfiAHoLn!0nhsUsQ4%93H`g@OXLjJhBgd z_Tej5e=fWS{kaG2sD+JWwBvWFKMfvHK5sX8tU>uqls`9qdB+Eyo2B4kGGj`{ z6V6m6pMej@!2|k2`Z5bX{3S{sczuA4GPI)@{h7~W3hl_`@$k#>Z3qwGak6upd8mdD zmEfTqV`>rRRsrUwtTAcuA&NDo${tUp7}GK)xee>k7ZaEl;=?!K18gk9+$`7$A69|~ zw(;*#@W4Kx{8W5c3>%f0o8{<>Mfbr6v?B*|Gn41m8&UWG9%Y?G`Gpt{c{{+vTJVs9 z@==Uw?u*4gfDh=;a*WAE$8cWXMdZc2$j-r8{a54r;Kv#l9Mj-2A3RRvdL!e3d3YIP zl6`Q-1FyBwjtBT4JYZe~c~~<+9$-WI0ybnkV66`JMHJ&fuDciya@|E==A*puumF7# z#dVi?h<9KgK5+k@J2xJzx-zdbV#u0LFHO>SQ(?U6@@kFGsXeuWqJ8=dg*6TSCc zeoM)Sr`Jg#di)=D-%)pM#c(d}2|D4_69f0IzPaq`oE|3ydXMh9d;RskQT2Y}v5}J- zk5(SwzH!2b9@=$#-Tv~yaC^r-IP%cuBmRBi=cPLz+)8YG&?16{`%OShd13` zb#2~IDD7j9?7Cyab(O<;VeR+hqUVY~#=D9so_OZu@?p=Gc?`m&Y zJ3fBu%A<7$Dt6|E**o<(+Iv$(dmkCTqwc!$;hZpDPJX!mcHfP`A1u9cK}SgM=!f?_yz%zR{kd3YobaJjJC3fs zZgjtW;>j!STX&0ZB)lDt{&??^JKpj1>D;&)s-O%g1LH6dIqxFzQtUOVv1hBqo~;bm z`GwfC<*mdu&V%c06xX*UKf<~2tGG_%JXMNwWfArnxtC*~f%8~e6nj3tHZ6J0wt;hD z$uY}D-bUEKxiUS9b7i%2jYoOe>+Hr}2j|LcoGa6!JXbD(jVhcgeK=Q^J^&w>hxJxF z(xW(6F2=dC5 z_-I4f8Sr55JH2(*-Zw4EbEWhr_O3qcpG$C#D8$~?y8=FB!-pu&mFxrW`Q!|M@&&kt zde>Qd-?S*tl}mnza~<=5c1)%({O}=ouf*B2VN7O%$FwMT0p(~Eda@|a!+A8;m& zdS0*(-+&LWQHr@)g!54DO7OroqBuv04=69^(nGSX9%QXYUxu&s(egkVlz}?0GcvQX z7kF~Kxq118Mfm<4hoo`Bx%2OyCrYAB%A*qUQw^=9E!2v?m)k*mXdm53N9Y)xpwsjb zIz!LVi*%O0DG#eh&LZtJwDzD>$pt#)%t*kWFX?M*Y8LzbK3_=*zG#cD+U}raGBPb@r8A`sqg$(z4PB zh&{kK`4tsD2+Ed}m!f5)u;P<)PMlNf<~ax2(~Q@$zwkqo?l{11qK<*PCoPjA0C)^3qpbRJj z%D}`Jm`7j2-DoHDS%G?bdb+l@HrLy4nek}u>ZIBTB^tMESi82ire^8Vh&;>O zrfH!$+LuvCn(vS?2j53VM)vO6IlRMu>x+Ev>FMZbY;;m>BqjQ~IcLL$h&;<&pK97f zM8nc(&PJhO4j7l(PcjbUJMu>L%;<5i{bY5`w3zo%^wS(%>b1$rfHI&ACn@oP>FzfLZclyJGqN`AHC9GiF`^cVlM7CO(k5FcaG&|if9 zqA2@|&|if9qNw}p5Pm`DsWH7a(f;yP)>f9GzYsQC@riT8C8k?{nWpKIDdsX=WBTS2 zCYXt+7yWLc-|@suk4-R>Q7^`inG)Of9!R-3Nt?802eGiGzyg}Lm)Tz18H zE+0<01HZ@?TCWaATwNk@aY-?*8NSW@9?QV9jCTgSFNo!gD=po;nP(2a$1;R^WM;-< z$yGFUWng;6gUO7C?xTXg!&UK4->hE@#GRE@$doj&?X- zG(C^!qM3@Bp_%A&R-EQ?R-EQ?md@pv%?GEVf&wQtbKYm7&+*t_Ppdj7dcSz0&QJ9I z@xvt!Cuh%PIyt*#!mwA3!) zd+Xt0tWJ2Y#$(Aq$@0j%pp~nvPm4lc6!>T23LNr(HpNPoFOO(W<*HQ?DPwga6comc z0elXJkGeVFvnkxf=TGIPvffYkvhn)-FJ8RF>vP9=wRg7eTWWo^OO}jU6>6&@_bp?0 zGBp<}wQSiaI|`HmWni{4Fn0f3wc7f2L8!%J_s?TXg|s!M3@8J$oq@4uw5rvsBN{zc zCqhA?GN261DF)*8UBGyqH{?8bT4jlbn{$M|pg;?=*yp65M}dVd=AiE`NU(VR!4)+S>8 zx(VnnuL@lt`Dp4)_T`nKbSF*Um4WHb0M1`Q7jae##&J#y#=~`ji5gJ`rXd62=acZW zOL+P;bX#3g1}?}zBKGt0Q%!SZKc9&Gd?NPqiP+EMIqUcHiP+C4Vn3faNA~l_Jzu`y zZu_|B+xQQPW5au;S1#r0vQ+lpR{Vm~M-!*WK&jjg^b600@`p%P$`s9N@dySiR;%PI zOUiHrITsO*U12n3CNgjlhlH9^29$wm&cIAuqvo>D(|kCod&s_^97t0k2IWnk(IBzwJ6H=-7l0cBuLF%Yl+2jHBOV*MVk z|3eV#b~^RN>;E4(^~d^ss`nG7dLLn`_Yd^G!JJxtwXw5|0Z-XX{7)jYtP`|3%D^NU zNG~dyWJxWi3@8KfW*}bw6D!u|9H+i`{Vy)3{#d`q>wkd7x}8pa6FtvP^!z%}^QxXt z&cB%EG0hP= zkaB+tV}ne3^2ukO;rQ9J6jhvUxZNXk#B(+$+541tDmK>T=I8&l;9G^0vB5rTPzIEN zsWXsH?!2j6Q47j|GN2471ImChpbRJj%78MU3|w3WYR>ax_y6(Z_4E9gi2ctJKfZsS zAHBqnq4WHhhz-?M29yD1Kp9X5lmTTx8Bhjh2Ll=SPe`+)CE5yQKp9X5lmTTx8JH*o znRH;HMW&>mMZ;452j(_oN`@|2IGc{@w;L|Vj3z1r%78MU3@8K2fHI&AC>w6ALU$m*At0$-1cJlmTTx8Bhk40cGG4G2kJ$ zpG~`I4N;((#eW9)UHSv?4i>@5lHWmr4hyI8w<8*dStLJ`>c|N662yN720WtQNP$Kx z|1p#8x3P$Rk=SpcK#PS-=pgcYSS0^)st4|55u79C2PrUUVISQ}X@P!%NPT{(ua5$K zR{kQ|i1NcMQhq7dSKrGbxQ2#+TUi9Jq#oc#7Qw5i6u6#6@QrN0euxFQgw_gfqWUH) zzmMyyA7&B#4fH$UP8PviM8A*fZT}j@pKVmX&B||<`~cMlEZjkVqNMsBf=K)Jh<+E< zcUk!(qTfRGHh%*yZeKHt)OQQ#x3{tgKEk-6lSS}R^bj=!SOlM7`|U$4f=@DTXlC*A z0C|kd_cgLe{zvFlN@(aHi1_z$8ialqi{yV&%I}~Cd;B~vcpEj??L8~Fof_IL{jUq| zp$5DEj~QHl8;jU`nd@)uVG+E*+>QJ}7Qx@){DvVG!QT@+ObvE_yu!G#okj9rqfFpV z7QwG`e>HAn5&Q<@rUn+lD_ym~Ei8h6!v6LSun7Jg+iz-O5&Rp$ebi+4_n#Rzx3ft8 z?*(t8X1l)s65K}3c6aoXjo=PyvFHCP1N^i!vPk*0lHW}&-4@0B&UQcVqnDDEix}ZM&6!i{K_| zv-u2gd)hi#r2G-19k_!<@KMq4qc*!e_Ze>zZS7={{4HF5YZHs$(+1YRt=m`xpE6Eh zeh#w;e$1!>ZekJqQR5wQxAzc4_!ROBopyb#CdNZ&D~sg6A^F>>)9#O-2=1Xyd%XTka6fh0{=LBSXQ+=w%D-v+ z5%zYl2yS8f&7CZQ-;(l;)M=0JKMHQ3PJ2B#C++Q`PJ6t(E%{Bn z8ubNO#Qr|M-gI`d2zHylBI*jT2u?G93Ea&hIFqk`T^%ffv*mi&MFG41BFS%{F5ADw zCfe6E%p&@=Civ}YVG-PDVt#gZ6GX<#a&CWD8;j)EiM@X6viaL&V*YhCvq*lu-RLV2tF=&8}-=j zyVu0^y{Df=@*m*(dj?qqpJe^|4i>?u827fa2>vi%uiCp<1V6#Jqk%>6ldRv_%p&-s zjJrEo1V7Dqpn*m3O+3E_ds*cA{7I>=lX`9aXW75rJ{Hk`-dq73U=jQU6YEcJ7mMH* zxqMGAi{O`}d<*s3{oxh+JE+&5FE0yjr(U~%za_YhdhPM^T`oTyU=e$-aeh-Ti{Lj! zzlVD5`Fff#UOU=ZB>%TO-g>vP2tFtJP1NhmFUAe6ERz2;U$6THSp?U+Fu(eSSp@%$ z{po9E5lqZqUki)ym&W_2zCISo_we<;uZu-+p6K^bpY3mv=r>TG-5({4`&(E<-{;x{ z9AFWg>B4#)Xkrmu=X#4=E%gME@!0C}lF{Ew5W!6*<4%GI9(G|r+CRi1<#)1w{lhF) zecZl*eip&ITxGybEP}r&`CT-C_VD$r$A$SY&_)okzmwO;ffg3gKOp0)nFj6gcpKxP zCKk#6KJ!03$RhZJ@pD|Sx>*FjkimGxY6pLju#0SHVUheV5%_3mWDyLPG)#d37m=BX z-_Fb;!z{rsXqJ*`mXVoIM=n}VE^{-v60&j1TR;g^PKl<663I(Rlus#G2~x2d&oh2c zY4lr~kCBjR)>4*PL)lpM7MPpJWBMq^te_mKB(LeGT(gSuu!81eRVgsHQlZ&SMP?5z z#HznAp^1vk0V+-iP;p{CEy9(j#JrM9&0SPxwo;k9fy$D0Q@Oc~e6*b^%weiD2dT=$ z&^B+RYV#mfC;WyMC;W^SCmy0D3BRJHxEd}qe?iL=j?-oCr>Mqtf@<6k(F*s!(MtDE z>2mkaX_b2q)uvvB=UzOorqwC$!*hgIC%>O+llS9!4b`UX!}D4^58#&P#Y|856J;d)h1QsF(OUCuT9@z+)wyq_^$GZ$Qv4pr+^N3W zdUnAtg6S(g$346bX5s0?xn3vE<()XU#fkGDZ8-7lP#p6qm~J|D9Nt(T`QbWz`gH7= zmdzh}&e)u+^l+Sr(~l$GP07NE6X&{|IQ!tl*-tA@Vft3zIXWSmgxMF;4@(z6ZGCAA z$NlgjWIs8mI#n+icXi;@%g44OUJ6qiWk^A?59;%mltgztL*DJ%(dg*o zZ>7Z9X0~^)*Rf;8Ejvz}?Ofyi9(1h!a^h^$iF4bXIFDf~Zt>})v!71fviVcCX{Jm1 z+rf5S*cU`h>Q2Ck=0*n)^j z2`S;&!1dJ$mcHA8WZ}dh?nW$J9~T(lkOz!SGLoGFHcoQz#eUB;%tRNtvg&NZ7Iu%q zZc556X}1(OKiuC;G80Wobcz$_Cs2BBO|6y0*iDJy<*_3Hwo6#~Nx7>w+4j+TH)ZCR zJNbeWL)ZZO;!md(KzU%c-{oM`2Y;RNPW?8nF-`PlY9UU75^Br@u7NKJHa3Bi7X&dz zxtrWMWx?`-vzFTa)|jctPg%IQ!zs@=t@yHlgSkDaS^jmSaG|d;9J{kBn?_?_i;dxp zN%L)OBK9Bl3ahq+@(tXFcR~%c4Qg{B#vhk=+qGNeU6hc$-qy&3J*+H216vZfzuZ|B zj=#d6+f&_a6{rEla(P#* z*(@5IpMYP1Ub)tCiThW^OM_*=X}`}l!0mHUN`ccJtNzr&R;PaChtIbyF022SJNXyD zn9Xi8%hF(dgO=IaL|ZW0dHht^Dd%C|qzv3BumWQjWt2Jzj=$C0to%qE9KUte_+|dl ze(-ONZ`Myhecjt}ww+;t*9p^f$>N4Ng*7ud85?l$<7SH83H(ZlSlbd4lkl1VedLOM zBBjkIN=uuM*CaAhIXxAx$=J6OrSl7=%nR91BR4F&`Gw|DMkY~4MkZc0TwDg6>$g#y zK*4z4dBo*fPDXK-6E}^#c}|>+bdFp50HfFpOE;XjY2>D2ParyEWc`nmPKGZR>38y8 zK{gt9=36>A%m()mym7lT|J4H4VIP8Vl+`fv7|6u3dnU|nVDk)_SPiUT<;zkb2{oc0 z+NW7KY#%21Sa9rcOmJvlX6a)QvV(;~`IdfgTZX$O>`#iULtF&;z^U_`@)y8pPnwfW zTcrL_eUUh*s1apghA@CBfNMKn^>KyASWm!x#YF6%lW-3)nNleQSLReK)bk|Qi`-mX z&GRXPHsIcfvtx>HV+~(?>(|V^tV`4Gi~ee+U-Af;>3x}tgNgP*e+&; zZv9PLzb}?!xpY!myY_s1ALr@sKdfKcANzV3|2^keEvQHLSAvH z?DCxV3sqV`FRr>!x~3@u%78MU3@8K2fHI&ACV4_b~qwQp)#NhC<8HPV6z5gKp9X5lmTU61~L%y3#L}6 z3@8K2fX%=RTr$;VWk4BF29yD1!1~7sdNo%DlmTTR4h-lLtPCgv%78MU49r9Z;&92- zDwP3cKp7AQX5yNuJ}U#tfHI&AC;WguP*=nAY1Ca#MS3@8K2fHE-AD|j)zQ83Xms;>+v1ImChpbRJj%78MU3@8K2fHI&ACk5BtMl_%i1Nc2w@9j40dUkwYZSvP3?d&3K(M47!sNcBp3t6 z1P{xEu!Sb_0!jEnAcO{oPD4Y|`O=eo3CRS~O@GrN>7+x_Ne=n{Sw`~zcJrWzFTuvZkG2g^1fBxx5@i}y#JX<<88-f9Qz4g zrD+^p#f(pLn5O$(!e@R2V%;WV5*J3-*k zX@n*z%SS&MEpC!bPAfC(e?WBLheZGI7SV=(glj)1dhS<=bMdL8Pab{hNaD(y>XMB7 zG~el7@UK1*KKiNHUXRbLFvB>GN&onnDbE}&!-%Y5C00t_Nj>))ZxFvUC<3zvfh4Mv zu5VzEZ7iZJ=agX9)bDImB$;;2>b=6*z)WqP83HMk?=DTtZXFpJxwTkA)*pOM7(9MF zE32Zyww}zHXI9V*)Jmm{YIb|%G{>SJ5f%RpQT{Md?tY@IZA2Lt6Q!2ms>1I^#;tYv zn?#FVB`SK7DDO_999*TysDpk0`u}@;{ZD=p`tYIXnC*kL*YRN;Y%GF}-;Zyj4111} zZ@|VEiGtA2<~m^an3@CqpN+3CKKvN^u#tZVXY9AZ2V8f_SPvVeu<`HX+bH{A@Zp<8 zg@@t8?eO6v&|d}pAoPDRzJ8PsuyKM9|7Uy~WjJ?P2pkL17D2RSfN@w29}3{ZzmBgT z<%5gEfCq;dd?-a*EPR=$U>N-gZ4qD`*T9D&`0(o(eVAZ>D24vQzlIN}LoV7fupK^J z2p=%?&39w-fix%rihv?;3Iv89AG{}YOYO%BFt@m2_};-!hpwx=w4mEfAsYVt;AcWN z*IrYAdDIQV_d#w5ay@PecKrZZ& zbN%y{`@rD7&<(X$6!d!J{&MhO=u@@3qw4Y5!P`S0hg@GoPGb{8z}|L?vEZhhELF_#{p}!LPI0s1g+|W9eCEhody^iw;*eJLQ zd#)>R9?)g`kb(Of=_#kujHH*N4(vk#_Rj3X0!Ke{Q5-(NM)48Yz}`0(IOJe{4K$!0 zWv~%-&ool5H^x3JWFMd(%Y@~WiJ9)hPb;pN0;KLO*4mlU0 z4va$#ZOLs>j`m#0IP7!k!R^WYAx0Y&@L|zWoDTtqJlBWwZT*ZGaVY=03HksWr4GO$ zZxA>D#~k*d6nps?`V-^8<3jrN?Y0dI<05A*Y;d3SpB#U0s_5e!g2zQ3`V)_f9Gp*O z;yfZQA6y%#hxmZ=A+Zrde_$ULJqaHi9HM-PL0@oi+H z0R1Uu99$o6bFlRK5X0CU^?`BN2^>362aN4N9Q~n+eK?GMeW%kOyzLnS4%N^vWqros za`@2h_)rcUVjLIMXwT9ku)+1X0yZ|l2KsfNA~qZ1!%@eFotR^ITrdu0v9|@=ScES|6xXZfAEdl3RUx$C6hkxF>*>d}> zT^_l=l6pk@{Or)-@Wb%gEBE5im%~rg-)jwdbf1IVBlUMh$-Ol6bodMP_gR1Lk$d(e zZDiNuzeizpvbJ_r1r-jFcQ5D=jN8FR$REqJpDfByL2DDW?d` zc?8^R5~uoHhHLqYU%@*0MXWJcXBU11Yi&LDEEe_(zZ@ACzoob*Qu8uVCDzEY16U_7 z#X5_%DQ7;`rWo%HEyV+`VgqYj>0aAL{zb5n1s`I#AF&ws0;<1>a{=ftf_~9uSR=7d z$jO5bG2V|@3L7=JuTqIUQ`vs_z&PN30@oumhI>Ox-h>app#nIR-UT0kLlA3x4raKF z81Kt0VIR;Im1v7nv_%oF69&;1ISb&!hvT=!VzfmS>QFum9I#g?#C5?S&O-w8;KRR- zug`lGX-{BT`4oJ(9X_y)bKye{eE48|8|*{%tH1$uSOopTZP3SgNFW_P{C0eO@!`ir zwTuJmaVBk1%Q!&496prro(VWw=fQ^s@F4~q*@tE9!#7}u`}J)Y7dy}&um{gc1rEO% zzaERxr>oE(%8$Ya=oelFAL`&k06x4ozP{@NkIgFJP<|JDxD-C1Pg&?wnKAUKTJ)!? zzlQFU@L?ZtKwDU7%Rn}K_(NA``41azyWm# zVr&O6wliWF+tMH41NVn2v}YM`;IS!lOa^SkFvl!LTUJBA0)1NgB=_kH;6ps)f_?ZK z_y8Ma7@Ni0;X^%eU>pAw0}kv1^e5tj^hu1(Dzrrz`gJktk;h|`$JX01_<%adJPG|p z=nsWkfdkG712{L&h@nqQpZuXSF3=~-(4NvKF)plJ^vPe1?}IzXRX|_nIN&IAoCP0Z zSZ}010L$7}o%zA-4?Ne#+8;131P6?ZQ5^W3FdiIWqn6tOHl#mbju~x>82W>ZEA$7M z>(Q3pxjt4LNP{9U#}OF2ubty?P#V>yFb1YSDK$MKGb@mtv%ty?=H(X@78NfnS%h=v z3OqtLk}^)PakQwE>S#5sr*?c(ZY%AeU34AYM0@D~-A|9uFnx)hqhs{9^j&&m%yA64 zd!bWDsdVB4Im3gY+5#!0vZ~Tc?+rlSz%Gl(pUhPVoLGU%s_L5B#pBlDKd>C7QUTS{ z8rnd8w4JV`PtdJ&4?PIqkK)@oFVM^MI{iKUklvzyqIaT>5!8xnumg3kqkJ2XsQ2Na za6OhS1S=;eke!t|e?C?qgyXHFbzuLkX!vdKmn>a2z1m^%;@aBkYPT&a-&;Id2dR_3 zoiPHHl@*|>^0Kmu^0M->F)a1~fT2Ti5F)a2VXE{Go@jphQ6OWa6P1pm+ zo071&5zHtlDX*@suC=UuJUd(x%~cn}6Fg{~l$1n%92#Z|0_o(Jb;hj^E+?NhxN>v# zb1j}<;ip%=pW7UK6W8wFnP8Z!IBLC5j=;GS3@5j$sfvIipa`5AfqC=-u133|-wxE< z+uO6Dy|vN#xOnX6nl-Ce*VVbH4hN0q^=ntJZm6qUwrotEZSLY}AsOvU6erbp!I*=e zgM))RcWfWn>U{K%{p{`S>S}IwQyoq;`oo;FcI}uv+g!g&IzYsNQZ!~!+yDpkOKm6V zhf~}0qFN@p-)lSBO*1XVeGKh1NmIRFKyXDZ!WG<@_mW8T01h z{;7mS>p8{hha#W|C<2OrBA^J&ECe#>jf3p5&%_U-n)vM|kl~ZxNgcN$MlytxA)gYX zd@AHqA)gkT{O+_T+&xf~FT2ye6jypf!#V`-JM-~}q9WEQFX#8%Tz)^ZP+H1*)z$oN z$2k^%AhZ|%+!h+ohyv(T4BCs(UKC?{5!#E;UKDeC?Mb^a?a>ojE#CI3tZt|-M|&Zx zv*Yn&!y41Ay-d^e$q@6IzEd^P*+@5&Q7+ouM7!gKk)D`frlMT*A2Thn_1&E|IsLG- zytce_U3G0kZS^`kerEkJkyl(O3@XSdO(jPnw)%O`55M8JdYcXHU^s&Yq&NoULOyVdKFq zsIbtD&79Af=<}&}!E+=h-s{Ej!V>TG<#_GKc|AH_^Zac79(gK1Ud?FvwRpaN4}O~` zIyHWd?Tr7cmgCz!r=nr;;;5;mVJTl*_l6T?ytx`rBm$)?#$E-jUTNPgig;02I}>N% zi2t)GR=Q%vnCeuoTsbD?M42%H$|ei}+=s)hZVtFNg^T!nS8n`SbmmG-)&0MzLTsw; zJ5E)7XY0PDp|WA=(x_RXp=Rv9<;0y#-O03;FORaLj3S^2%vJvY#%9)cC~x z^NCs!X^klYiok3~;KXyZnpLaDRQg1jF#^ge0*b(#LSU+%1)Qq$&8d0@amwmDMbAD? zRef8nA?qRQ=HT~&ADq!Wj8@!Jw} zYKqdzDgrYGfwFU=pJv7vFlxQd7cGu{!g{Q{S61VSfFh7s1j^1iC#t})XVGKxqlA@F z1QdZOMZk~mw)t^y+@Ij@woTRfjvwEt^W!^petf46uUY*p0AuXO`K%w`>h&R!@vJHOjk847(OZ`L zJpY+J%^$He(dYVIOA~#*-?byp`Om@mNvo^~C<14WKxXkw{8iyIudiw<0*b)I5l9UN zCvHS7C<2PWoI+r#{tv)CPfGOXRQ(S@qU-6FH&y?C;Fh20&xu}7nCNwciC#a@>jrab z`qj$LG6byhnfOm4v#b%cI*Py{U=tU&vV@Jrs}`A-0~Cs zIaU7wmgsuA<;8nG8}IpRyyvTWemd1NoR&YC2%Pv^>yv3+Z7BkYMZn@ede@)`%n}6L zeUN@C0@TD*k=ujfFdw) z1Tx8=KXEIGv9K_M4=!uNd_JOM5g#s^&qsuh#4btWgUJ1KbM8pv!{r`I=3{FLA9mVZ zDSWv3MDP3Gms$0v{-4TcBxgFu6u;@*I&;^zH;9j2Q3ugwf8wKVgpWs@gJ_8yx#T@& zDstOK_;@DjI8|Nxh>z&n6L~GXHDVv9vY_dTfFhs>C<2PWR3q>O{5IiD&MS6b?0tg0 zFR)j_*md2tawYL$ucr3u8IKK>RRk0PML-cy1QY>9KoL*`W(NXU_$Q>#XU%gA*U+Cv+}K1vbLbX%x?xZ7PCT#lOz^efo59}% z|0w^MQu!^SMMsGWZzl@wBwDb6DCc6L%o3vX81Cv0W-|?Z##vxD+eV;3J`cJP9`Bysi z0G5FY*hoITF6WNw?}HCld2rx5#GoH#12{02(iXsh`$H@?s=oysk3?`>;NXy13jG-S z!>ElrJpEy{<3kKKMsa|?^au8V+mhQNRvfrb9Y#Iahn>KI$A#OkW3a*FVzf^WdT=a` z9fxvYx$r1a0er}X4>{i>szLqucv#i1{UpQyjr8uFxl19FG!AF%d#(!M_Q#qj6r@3B7SNqcGN>F^hz zd#xw!`JpGnkJW$1y2g|C0(2jTu4h3ScICYGz9zbNTUUE@zczF<{Am5%)-F%lbCPx- zD(x#nPlP{Pf4g;sNA9abhr$ol@3*e>q;O_5l{pa0YyL&Py`eKML-cy1QY>9KoL*`6ahtG_93vqd8%T^Z=>sGM6=2% z0*Zhlpa>`eioh&Hz#@MwSIbYhi5Y5TsvQP@oc;~`Rwm(7CBKV8T{fS=Pe(KlFiC!Z z){qhEBT(%y3|J!HOrd5w|3Q=OcQA>3vDj~;P@Bz{(zVF%Ws>~!s1bZOlkmBszlB0u zY`&5{K^dV<1d{SP-Bao-_PYW4ls%QTKWz6ZYJT^i+n#dI{r0_KO3oWqn+O> z`5|fy*?brMo>Cfn2_*H~A@V)c*kk7pihLV2I{0n&as67Eq`Z%FerG$A@Ha8v)XgOP zEodQX3NZng z+n9v^p6~Jl*KTK_5n_p{SK4{xSAn|{_v4@h|`UxcbIv@Mj#w7af#wPIF zn1t_Q`|bTq!uJ?>z@ojIN%%0Aw>iWld_UKxy@yHot-^OwyMy<3mT%w0B>6j-@91L^ zeh~gqM-P+myNnR{W~SOO`u}wze+hM5V&{Kc_!jDL@C51Ow}^Z{ zbvX68!}ukBET)@D^4GKeh88B_?>8|2ZP>^p{Jq8jjL!ik;U6?=z_&07|CsS1`8#_F zB=|nT<#ldhlKihQ-?f=Z_@@}3u0|%|pO*YS>T>XSQTPt(a{9wD;rpq}@&9GvH&K^^ z=PPWldn1$BtKs@|cQOh89hUFj!X*6vGz!3PV-o%c#-D-T%q09Jn`a^d+ zljOfG`Ik_)(;ojUd@pr7{q-H;H&M6a-?Kb^w)HcK{x6N+!QNIT;oI1LYd4ed?~8sj zbvyn0cfvPOw=*BSC-v>2Zl}L|Ao(rS?X<^-!uL_PgXeK$G0F=uiTz!?-gI{}3GX+5 zMbr~w5^>i@_pCjvG4~3laizUB_dK~|jn5bXR0F%f!n83HEjY;@s z6XUZxOd#nmE4cnW9ZZtHM(k~(9tXdRO^m;uRwl`Bl>Cj<?DUWA!naV^!FPx7?G$$U!!9mA+{GmN zyM^zku+!c*a(%-Y9C3IB@dw^5(d z9zn6cmHM3V@~ZHi)aSJCYr=O>pVNQ7!}!FRZ+#n>gnv)uTd2<+U(7ePGfDmvyk7TjVG_R4hw;@vz$E;Cu|NIoOu`f6*Wbn@ z_+{|^slT5|@-1HP`+Jy#&lmY#>UaDt7WpRXciN+r`Auz1B46pl1G}3-Ou`3zn6E=E zOv116y-&WjMgmEHZ1)Ap*wjZL;ag1Ry9p%xfDil8P1~46e>?lPX@JQtkL$O26O-_l z`pUt#FbV&+lHWs{Q6FBz?3_P6u=xVeo<qrhD<%HC z$k^$2+?KcFd5#R{^Xt*HXVNV6Q9J(pX#DB4R}f!MEI*O3V!@{uxMg)Yam=3d)Pi4( zrq^5hES?9m@p9u_t{Z24H_ml&87)vZrrx{Gq!1FO8N(* z^|~s^aoY!uyY+J8t~~o}m-~`OhU0b{T@{pcX={$NtSx^ZFn8;ck~i#>^>(l-&n@?Y zyf=%GE`8pObA7AutIM2jw}p*Ar@I(>G2uF%jSwJ8Hav!H-W*M-L(IT>>W1}*n3R;} zKbtP6qldu&wybj`^cA#ucJt?d4Ck| zr8@y$EN566(w(E`gT>hd05eE*Ry}%l+if zEqDB>!^{Uhdzs^JotX|kZQ+tGSD*Qel5;{X&-F>quDu|NFREwR|n zuW<8E!ecc1&1_qOJ%$cdF*nk5cKSS(K;&)2M+?Jf2 zg7+lIBUj{;DPumqA(t^9?)-Oi#Mu#!VwH9eV|p21R3Qm< zA|KhO*}P{TCi$3foUm8;$iB>$$0Xzgn~&t%@}t`_TrFXL(qtZD7370YpXchIghzcc z+-&DFQl6bKmLDUotRgUt5#XJW4{JD|FJTXi^?W|AI9gc0bFprxQyR^~dp_PdH;CLk ztme2UIE{i)IgOlAR}=w7KoK}g2;|a#oh8dN!))+W^$%nt;2L0LdpR>I6sMPYbWkpI zE*Y8HW36@2`mS|L?)ULOep`ck`U&XR3w0h*^#|ZJEVYVQUPutIGRSNid1cc(^ zit5tRit5u9R!GmSJYBx#DFTXsBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H; z0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2Or zA`lM(MfB}>#HX!nG3^!KjFgm{{;<~hp(oqhto3#Hu~Wpe-hKD@aehfU|5DuKhK00x zU~(<0HAO%XPz2&fV4VgOb!AwaLQDd6#+#+5l{pa z0sD^;CTA&BD~f<3pa{f;fKI`RfFhs>C<2PWOhh2A#ZHA40YyL&m_!6-;+&~ID*}pu zBA^H;0+YBDswqW45l{r;LO^F=ML-cy1QY>9U?w6E*J7u_ihv@Z2uvaZGjYyTpA`W` zKoL*`6oE-x3e}V%pa>`eaUq~Hup*!cC<2OrA}|vXh-C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs> RC<2OrBA^H;0#k#){|77V5sv@> literal 0 HcmV?d00001 diff --git a/package/firmware/ipq-wifi/src/board-linksys_mx5500.ipq5018 b/package/firmware/ipq-wifi/src/board-linksys_mx5500.ipq5018 new file mode 100644 index 0000000000000000000000000000000000000000..59620c04fd26ecd9c5a132018164bda6343e17a2 GIT binary patch literal 131180 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 XKnW-TC7=Y9fD%vwNM?nqM#@WN);@Ky--9{ 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 literal 0 HcmV?d00001 diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx2000.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx2000.dts new file mode 100644 index 00000000000000..00bfe4315d66dd --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx2000.dts @@ -0,0 +1,695 @@ +/dts-v1/; + +#include "ipq5018.dtsi" +#include "ipq5018-ess.dtsi" + +#include +#include +#include + +/ { + model = "Linksys MX2000"; + compatible = "linksys,mx2000", "qcom,ipq5018"; + + aliases { + ethernet0 = &dp1; + ethernet1 = &dp2; + led-boot = &led_system_blue; + led-failsafe = &led_system_red; + led-running = &led_system_blue; + led-upgrade = &led_system_red; + serial0 = &blsp1_uart1; + }; + + chosen { + bootargs-append = " root=/dev/ubiblock0_0 coherent_pool=2M"; + stdout-path = "serial0:115200n8"; + }; + + keys { + compatible = "gpio-keys"; + pinctrl-0 = <&button_pins>; + pinctrl-names = "default"; + + wps-button { + label = "wps"; + gpios = <&tlmm 27 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + reset-button { + label = "reset"; + gpios = <&tlmm 28 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "pwm-leds"; + + led_system_red: red { + label = "red:system"; + pwms = <&pwm 3 1250000>; + max-brightness = <255>; + }; + + green { + label = "green:system"; + pwms = <&pwm 0 1250000>; + max-brightness = <255>; + }; + + led_system_blue: blue { + label = "blue:system"; + pwms = <&pwm 1 1250000>; + max-brightness = <255>; + //linux,default-trigger = "default-on"; + }; + }; + + reserved-memory { + tz_appps@4a400000 { + no-map; + reg = <0x0 0x4a400000 0x0 0x400000>; + }; + + q6_mem_regions: q6_mem_regions@4b000000 { + no-map; + reg = <0x0 0x4b000000 0x0 0x3000000>; + }; + + /* from stock DTS: + q6_code_data: q6_code_data@4b000000 { + no-map; + reg = <0x0 0x4b000000 0x0 0x60000>; + }; + + q6_ipq5018_data: q6_ipq5018_data@4c400000 { + no-map; + reg = <0x0 0x4c400000 0x0 0xe00000>; + }; + + q6_m3_region: m3_dump@4d200000 { + no-map; + reg = <0x0 0x4d200000 0x0 0x100000>; + }; + + q6_etr_region: q6_etr_dump@4d300000 { + no-map; + reg = <0x0 0x4d300000 0x0 0x100000>; + }; + + q6_caldb_region: q6_caldb_region@4d400000 { + no-map; + reg = <0x0 0x4d400000 0x0 0x200000>; + }; + + q6_qcn6122_data1: q6_qcn6122_data1@4d600000 { + no-map; + reg = <0x0 0x4d600000 0x0 0x1000000>; + }; + + q6_qcn6122_m3_1: q6_qcn6122_m3_1@4e600000 { + no-map; + reg = <0x0 0x4e600000 0x0 0x100000>; + }; + + q6_qcn6122_etr_1: q6_qcn6122_etr_1@4e700000 { + no-map; + reg = <0x0 0x4e700000 0x0 0x100000>; + }; + + q6_qcn6122_caldb_1: q6_qcn6122_caldb_1@4e800000 { + no-map; + reg = <0x0 0x4e800000 0x0 0x500000>; + }; + + q6_qcn6122_data2: q6_qcn6122_data20@4ed00000 { + no-map; + reg = <0x0 0x4ed00000 0x0 0x1000000>; + }; + + q6_qcn6122_m3_2: q6_qcn6122_m3_2@4fd00000 { + no-map; + reg = <0x0 0x4fd00000 0x0 0x100000>; + }; + + q6_qcn6122_etr_2: q6_qcn6122_etr_2@4fe00000 { + no-map; + reg = <0x0 0x4fe00000 0x0 0x100000>; + }; + + q6_qcn6122_caldb_2: q6_qcn6122_caldb_2@4ff00000 { + no-map; + reg = <0x0 0x4ff00000 0x0 0x500000>; + }; + */ + }; +}; + +&switch { + status = "okay"; + + switch_mac_mode = ; + + qcom,port_phyinfo { + // MAC0 -> GE Phy -> QCA8337 Phy4 + port@0 { + port_id = <1>; + mdiobus = <&mdio0>; + phy_address = <7>; + // status = "disabled"; + }; + + // MAC1 ---SGMII---> QCA8337 SerDes + port@1 { + port_id = <2>; + forced-speed = <1000>; + forced-duplex = <1>; + }; + }; +}; + +// MAC0 -> GE Phy +&dp1 { + /* + * =============================================================== + * _______________________ _______________________ + * | IPQ5018 | | QCA8337 | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC0 |---| GE Phy |-+--UTP--+-| Phy4 |---| MAC5 | | + * | +------+ +--------+ | | +--------+ +------+ | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC1 |---| Uniphy |-+-SGMII-+-| SerDes |---| MAC0 | | + * | +------+ +--------+ | | +--------+ +------+ | + * |_______________________| |_______________________| + * + * =============================================================== + * + * Current drivers don't support such topology. So dp1 and ge_phy + * are useless. But they can't be disabled dut to qca-ssdk use + * ge_phy to detect IPQ5018 dummy switch. + */ + status = "okay"; +}; + +// MAC1 ---SGMII---> QCA8337 SerDes +&dp2 { + status = "okay"; + phy-mode = "sgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&mdio0 { + status = "okay"; +}; + +// IPQ5018 GE Phy -> QCA8337 Phy1 +&ge_phy { + status = "okay"; +}; + +&mdio1 { + status = "okay"; + + pinctrl-0 = <&mdio1_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>; + + // QCA8337 Phy0 -> IPQ5018 GE Phy + qca8337_0: ethernet-phy@0 { + reg = <0>; + }; + + // QCA8337 Phy1 -> WAN + qca8337_1: ethernet-phy@1 { + reg = <1>; + }; + + // QCA8337 Phy2 -> LAN1 + qca8337_2: ethernet-phy@2 { + reg = <2>; + }; + + // QCA8337 Phy3 -> LAN2 + qca8337_3: ethernet-phy@3 { + reg = <3>; + }; + + // QCA8337 Phy4 -> LAN3 + qca8337_4: ethernet-phy@4 { + reg = <4>; + }; + + // QCA8337 switch + switch1: ethernet-switch@17 { + compatible = "qca,qca8337"; + reg = <17>; + #address-cells = <1>; + #size-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + label = "cpu1"; + phy-handle = <&qca8337_0>; + status = "disabled"; + }; + + port@2 { + reg = <2>; + label = "wan"; + phy-handle = <&qca8337_1>; + }; + + port@3 { + reg = <3>; + label = "lan1"; + phy-handle = <&qca8337_2>; + }; + + port@4 { + reg = <4>; + label = "lan2"; + phy-handle = <&qca8337_3>; + }; + + port@5 { + reg = <5>; + label = "lan3"; + phy-handle = <&qca8337_4>; + }; + + port@6 { + reg = <6>; + label = "cpu"; + phy-mode = "sgmii"; + ethernet = <&dp2>; + qca,sgmii-enable-pll; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; +}; + +&sleep_clk { + clock-frequency = <32000>; +}; + +&xo_board_clk { + clock-frequency = <24000000>; +}; + +&blsp1_uart1 { + status = "okay"; + + pinctrl-0 = <&serial_0_pins>; + pinctrl-names = "default"; +}; + +&crypto { + status = "okay"; +}; + +&cryptobam { + status = "okay"; +}; + +&prng { + status = "okay"; +}; + +&pwm { + status = "okay"; + + #pwm-cells = <2>; + pinctrl-0 = <&pwm_pins>; + pinctrl-names = "default"; +}; + +&qfprom { + status = "okay"; +}; + +&qpic_bam { + status = "okay"; +}; + +&qpic_nand { + pinctrl-0 = <&qpic_pins>; + pinctrl-names = "default"; + status = "okay"; + + partitions { + status = "disabled"; + }; + + nand@0 { + compatible = "spi-nand"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + nand-ecc-engine = <&qpic_nand>; + + nand-ecc-strength = <8>; + nand-ecc-step-size = <512>; + nand-bus-width = <8>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "0:SBL1"; + reg = <0x00000000 0x80000>; + read-only; + }; + + partition@80000 { + label = "0:MIBIB"; + reg = <0x00080000 0x20000>; + read-only; + }; + + partition@100000 { + label = "0:QSEE"; + reg = <0x00100000 0x100000>; + read-only; + }; + + partition@200000 { + label = "0:DEVCFG"; + reg = <0x00200000 0x40000>; + read-only; + }; + + partition@240000 { + label = "0:CDT"; + reg = <0x00240000 0x40000>; + read-only; + }; + + partition@280000 { + label = "0:APPSBLENV"; + reg = <0x00280000 0x20000>; + }; + + partition@300000 { + label = "0:APPSBL"; + reg = <0x00300000 0x140000>; + read-only; + }; + + partition@440000 { + compatible = "nvmem-cells"; + label = "0:ART"; + reg = <0x00440000 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + read-only; + }; + + partition@540000 { + label = "0:TRAINING"; + reg = <0x00540000 0x80000>; + read-only; + }; + + partition@5c0000 { + label = "u_env"; + reg = <0x005c0000 0x80000>; + }; + + partition@640000 { + label = "s_env"; + reg = <0x00640000 0x40000>; + }; + + partition@680000 { + label = "devinfo"; + reg = <0x00680000 0x40000>; + read-only; + }; + + partition@6c0000 { + label = "kernel"; + reg = <0x006c0000 0x5200000>; + }; + + partition@ec0000 { + label = "rootfs"; + reg = <0x0ec0000 0x4a00000>; + }; + + partition@58c0000 { + label = "alt_kernel"; + reg = <0x058c0000 0x5200000>; + }; + + partition@60c0000 { + label = "alt_rootfs"; + reg = <0x060c0000 0x4a00000>; + }; + + partition@aac0000 { + label = "sysdiag"; + reg = <0x0aac0000 0x200000>; + read-only; + }; + + partition@acc0000 { + label = "syscfg"; + reg = <0x0acc0000 0x4400000>; + read-only; + }; + }; + }; +}; + +&tlmm { + button_pins: button-state { + pins = "gpio27", "gpio28"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + + mdio1_pins: mdio-state { + mdc-pins { + pins = "gpio36"; + function = "mdc"; + drive-strength = <8>; + bias-pull-up; + }; + + mdio-pins { + pins = "gpio37"; + function = "mdio"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + pwm_pins: pwm-state { + mux_1 { + pins = "gpio1"; + function = "pwm1"; + drive-strength = <8>; + }; + + mux_2 { + pins = "gpio30"; + function = "pwm3"; + drive-strength = <8>; + }; + + mux_3 { + pins = "gpio46"; + function = "pwm0"; + drive-strength = <8>; + }; + }; + + qpic_pins: qpic-state { + clock-pins { + pins = "gpio9"; + function = "qspi_clk"; + drive-strength = <8>; + bias-disable; + }; + + cs-pins { + pins = "gpio8"; + function = "qspi_cs"; + drive-strength = <8>; + bias-disable; + }; + + data-pins { + pins = "gpio4", "gpio5", "gpio6", "gpio7"; + function = "qspi_data"; + drive-strength = <8>; + bias-disable; + }; + }; + + serial_0_pins: uart0-state { + pins = "gpio20", "gpio21"; + function = "blsp0_uart0"; + bias-disable; + }; +}; + +&tsens { + status = "okay"; +}; + +&q6v5_wcss { + status = "okay"; + + memory-region = <&q6_mem_regions>; + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt", + "ath11k/IPQ5018/hw1.0/m3_fw.mdt", + "ath11k/qcn6122/hw1.0/m3_fw.mdt"; + + /*qcom,bootargs_smem = <507>;*/ /* hard-coded in mpd driver */ + boot-args = + ; + + // IPQ5018 + q6_wcss_pd1: pd-1 { + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt"; + + resets = + <&gcc GCC_WCSSAON_RESET>, + <&gcc GCC_WCSS_BCR>, + <&gcc GCC_CE_BCR>; + reset-names = + "wcss_aon_reset", + "wcss_reset", + "ce_reset"; + + clocks = + <&gcc GCC_WCSS_AHB_S_CLK>, + <&gcc GCC_WCSS_ACMT_CLK>, + <&gcc GCC_WCSS_AXI_M_CLK>; + clock-names = + "gcc_wcss_ahb_s_clk", + "gcc_wcss_acmt_clk", + "gcc_wcss_axi_m_clk"; + + // qcom,halt-regs = <&tcsr_q6_block 0xa000 0xd000 0x0>; + interrupts-extended = + <&wcss_smp2p_in 8 0>, + <&wcss_smp2p_in 9 0>, + <&wcss_smp2p_in 12 0>, + <&wcss_smp2p_in 11 0>; + interrupt-names = + "fatal", + "ready", + "spawn-ack", + "stop-ack"; + + qcom,smem-states = + <&wcss_smp2p_out 8>, + <&wcss_smp2p_out 9>, + <&wcss_smp2p_out 10>; + qcom,smem-state-names = + "shutdown", + "stop", + "spawn"; + status = "okay"; + }; + + // QCN6102 6G + q6_wcss_pd2: pd-2 { + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt"; + + interrupts-extended = + <&wcss_smp2p_in 16 0>, + <&wcss_smp2p_in 17 0>, + <&wcss_smp2p_in 20 0>, + <&wcss_smp2p_in 19 0>; + interrupt-names = + "fatal", + "ready", + "spawn-ack", + "stop-ack"; + + qcom,smem-states = + <&wcss_smp2p_out 16>, + <&wcss_smp2p_out 17>, + <&wcss_smp2p_out 18>; + qcom,smem-state-names = + "shutdown", + "stop", + "spawn"; + status = "disabled"; + }; + + // QCN6102 5G + q6_wcss_pd3: pd-3 { + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt"; + + interrupts-extended = + <&wcss_smp2p_in 24 0>, + <&wcss_smp2p_in 25 0>, + <&wcss_smp2p_in 28 0>, + <&wcss_smp2p_in 27 0>; + interrupt-names = + "fatal", + "ready", + "spawn-ack", + "stop-ack"; + + qcom,smem-states = + <&wcss_smp2p_out 24>, + <&wcss_smp2p_out 25>, + <&wcss_smp2p_out 26>; + qcom,smem-state-names = + "shutdown", + "stop", + "spawn"; + status = "okay"; + }; +}; + +&wifi0 { + // IPQ5018 + qcom,rproc = <&q6_wcss_pd1>; + qcom,userpd-subsys-name = "q6v5_wcss_userpd1"; + qcom,ath11k-calibration-variant = "Linksys-MX2000"; + qcom,ath11k-fw-memory-mode = <2>; + qcom,bdf-addr = <0x4c400000>; + + status = "okay"; +}; + +&wifi1 { + // QCN6102 5G + qcom,rproc = <&q6_wcss_pd3>; + qcom,userpd-subsys-name = "q6v5_wcss_userpd3"; + qcom,ath11k-calibration-variant = "Linksys-MX2000"; + qcom,ath11k-fw-memory-mode = <2>; + qcom,bdf-addr = <0x4d100000>; + qcom,m3-dump-addr = <0x4df00000>; + + status = "okay"; +}; \ No newline at end of file diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx5500.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx5500.dts new file mode 100644 index 00000000000000..e5ca2d49fb1b8e --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx5500.dts @@ -0,0 +1,612 @@ +/dts-v1/; + +#include "ipq5018.dtsi" +#include "ipq5018-ess.dtsi" + +#include +#include +#include + +/ { + model = "Linksys MX5500"; + compatible = "linksys,mx5500", "qcom,ipq5018"; + + aliases { + ethernet0 = &dp1; + ethernet1 = &dp2; + led-boot = &led_system_blue; + led-failsafe = &led_system_red; + led-running = &led_system_blue; + led-upgrade = &led_system_red; + serial0 = &blsp1_uart1; + }; + + chosen { + bootargs-append = " root=/dev/ubiblock0_0 coherent_pool=2M"; + stdout-path = "serial0:115200n8"; + }; + + keys { + compatible = "gpio-keys"; + pinctrl-0 = <&button_pins>; + pinctrl-names = "default"; + + wps-button { + label = "wps"; + gpios = <&tlmm 27 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + reset-button { + label = "reset"; + gpios = <&tlmm 28 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "pwm-leds"; + + led_system_red: red { + label = "red:system"; + pwms = <&pwm 3 1250000>; + max-brightness = <255>; + }; + + green { + label = "green:system"; + pwms = <&pwm 0 1250000>; + max-brightness = <255>; + }; + + led_system_blue: blue { + label = "blue:system"; + pwms = <&pwm 1 1250000>; + max-brightness = <255>; + linux,default-trigger = "default-on"; + }; + }; + + reserved-memory { + q6_mem_regions: q6_mem_regions@4b000000 { + no-map; + reg = <0x0 0x4b000000 0x0 0x3000000>; + }; + + /* + q6_region: wcnss@4b000000 { + no-map; + reg = <0x0 0x4b000000 0x0 0x01800000>; + }; + + q6_m3_region: m3_dump@4c800000 { + no-map; + reg = <0x0 0x4c800000 0x0 0x100000>; + }; + + q6_etr_region: q6_etr_dump@4c900000 { + no-map; + reg = <0x0 0x4c900000 0x0 0x100000>; + }; + + q6_caldb_region: q6_caldb_region@4cd00000 { + no-map; + reg = <0x0 0x4cd00000 0x0 0x200000>; + }; + + qcn9000_pcie0@4cc00000 { + no-map; + reg = <0x0 0x4cc00000 0x0 0x01e00000>; + }; + */ + + mhi_region1: dma_pool1@4ea00000 { + compatible = "shared-dma-pool"; + no-map; + reg = <0x0 0x4ea00000 0x0 0x01000000>; + }; + }; +}; + +&switch { + status = "okay"; + + switch_mac_mode = ; + + qcom,port_phyinfo { + // MAC0 -> GE Phy -> QCA8337 Phy4 + port@0 { + port_id = <1>; + mdiobus = <&mdio0>; + phy_address = <7>; + // status = "disabled"; + }; + + // MAC1 ---SGMII---> QCA8337 SerDes + port@1 { + port_id = <2>; + forced-speed = <1000>; + forced-duplex = <1>; + }; + }; +}; + +// MAC0 -> GE Phy +&dp1 { + /* + * =============================================================== + * _______________________ _______________________ + * | IPQ5018 | | QCA8337 | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC0 |---| GE Phy |-+--UTP--+-| Phy4 |---| MAC5 | | + * | +------+ +--------+ | | +--------+ +------+ | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC1 |---| Uniphy |-+-SGMII-+-| SerDes |---| MAC0 | | + * | +------+ +--------+ | | +--------+ +------+ | + * |_______________________| |_______________________| + * + * =============================================================== + * + * Current drivers don't support such topology. So dp1 and ge_phy + * are useless. But they can't be disabled dut to qca-ssdk use + * ge_phy to detect IPQ5018 dummy switch. + */ + status = "okay"; +}; + +// MAC1 ---SGMII---> QCA8337 SerDes +&dp2 { + status = "okay"; + phy-mode = "sgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&mdio0 { + status = "okay"; +}; + +// IPQ5018 GE Phy -> QCA8337 Phy1 +&ge_phy { + status = "okay"; +}; + +&mdio1 { + status = "okay"; + + pinctrl-0 = <&mdio1_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>; + + // QCA8337 Phy0 -> IPQ5018 GE Phy + qca8337_0: ethernet-phy@0 { + reg = <0>; + }; + + // QCA8337 Phy1 -> WAN + qca8337_1: ethernet-phy@1 { + reg = <1>; + }; + + // QCA8337 Phy2 -> LAN1 + qca8337_2: ethernet-phy@2 { + reg = <2>; + }; + + // QCA8337 Phy3 -> LAN2 + qca8337_3: ethernet-phy@3 { + reg = <3>; + }; + + // QCA8337 Phy4 -> LAN3 + qca8337_4: ethernet-phy@4 { + reg = <4>; + }; + + // QCA8337 switch + switch1: ethernet-switch@10 { + compatible = "qca,qca8337"; + #address-cells = <1>; + #size-cells = <0>; + + reg = <10>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + label = "cpu1"; + phy-handle = <&qca8337_0>; + status = "disabled"; + }; + + port@2 { + reg = <2>; + label = "wan"; + phy-handle = <&qca8337_1>; + }; + + port@3 { + reg = <3>; + label = "lan1"; + phy-handle = <&qca8337_2>; + }; + + port@4 { + reg = <4>; + label = "lan2"; + phy-handle = <&qca8337_3>; + }; + + port@5 { + reg = <5>; + label = "lan3"; + phy-handle = <&qca8337_4>; + }; + + port@6 { + reg = <6>; + label = "cpu"; + phy-mode = "sgmii"; + ethernet = <&dp2>; + qca,sgmii-enable-pll; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; +}; + +&sleep_clk { + clock-frequency = <32000>; +}; + +&xo_board_clk { + clock-frequency = <24000000>; +}; + +&blsp1_uart1 { + status = "okay"; + + pinctrl-0 = <&serial_0_pins>; + pinctrl-names = "default"; +}; + +&crypto { + status = "okay"; +}; + +&cryptobam { + status = "okay"; +}; + +&prng { + status = "okay"; +}; + +&pwm { + status = "okay"; + + #pwm-cells = <2>; + + pinctrl-0 = <&pwm_pins>; + pinctrl-names = "default"; +}; + +&qfprom { + status = "okay"; +}; + +&qpic_bam { + status = "okay"; +}; + +&qpic_nand { + pinctrl-0 = <&qpic_pins>; + pinctrl-names = "default"; + status = "okay"; + + partitions { + status = "disabled"; + }; + + nand@0 { + compatible = "spi-nand"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + nand-ecc-engine = <&qpic_nand>; + + nand-ecc-strength = <8>; + nand-ecc-step-size = <512>; + nand-bus-width = <8>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "0:SBL1"; + reg = <0x00000000 0x80000>; + read-only; + }; + + partition@80000 { + label = "0:MIBIB"; + reg = <0x00080000 0x20000>; + read-only; + }; + + partition@100000 { + label = "0:QSEE"; + reg = <0x00100000 0x100000>; + read-only; + }; + + partition@200000 { + label = "0:DEVCFG"; + reg = <0x00200000 0x40000>; + read-only; + }; + + partition@240000 { + label = "0:CDT"; + reg = <0x00240000 0x40000>; + read-only; + }; + + partition@280000 { + label = "0:APPSBLENV"; + reg = <0x00280000 0x20000>; + }; + + partition@300000 { + label = "0:APPSBL"; + reg = <0x00300000 0x140000>; + read-only; + }; + + partition@440000 { + compatible = "nvmem-cells"; + label = "0:ART"; + reg = <0x00440000 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + read-only; + }; + + partition@540000 { + label = "0:TRAINING"; + reg = <0x00540000 0x80000>; + read-only; + }; + + partition@5c0000 { + label = "u_env"; + reg = <0x005c0000 0x80000>; + }; + + partition@640000 { + label = "s_env"; + reg = <0x00640000 0x40000>; + }; + + partition@680000 { + label = "devinfo"; + reg = <0x00680000 0x40000>; + read-only; + }; + + partition@6c0000 { + label = "kernel"; + reg = <0x006c0000 0x5200000>; + }; + + partition@ec0000 { + label = "rootfs"; + reg = <0x0ec0000 0x4a00000>; + }; + + partition@58c0000 { + label = "alt_kernel"; + reg = <0x058c0000 0x5200000>; + }; + + partition@60c0000 { + label = "alt_rootfs"; + reg = <0x060c0000 0x4a00000>; + }; + + partition@aac0000 { + label = "sysdiag"; + reg = <0x0aac0000 0x200000>; + read-only; + }; + + partition@acc0000 { + label = "syscfg"; + reg = <0x0acc0000 0x4400000>; + read-only; + }; + }; + }; +}; + +&tlmm { + button_pins: button-state { + pins = "gpio27", "gpio28"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + + mdio1_pins: mdio-state { + mdc-pins { + pins = "gpio36"; + function = "mdc"; + drive-strength = <8>; + bias-pull-up; + }; + + mdio-pins { + pins = "gpio37"; + function = "mdio"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + pwm_pins: pwm-state { + mux_1 { + pins = "gpio1"; + function = "pwm1"; + drive-strength = <8>; + }; + + mux_2 { + pins = "gpio30"; + function = "pwm3"; + drive-strength = <8>; + }; + + mux_3 { + pins = "gpio46"; + function = "pwm0"; + drive-strength = <8>; + }; + }; + + qpic_pins: qpic-state { + clock-pins { + pins = "gpio9"; + function = "qspi_clk"; + drive-strength = <8>; + bias-disable; + }; + + cs-pins { + pins = "gpio8"; + function = "qspi_cs"; + drive-strength = <8>; + bias-disable; + }; + + data-pins { + pins = "gpio4", "gpio5", "gpio6", "gpio7"; + function = "qspi_data"; + drive-strength = <8>; + bias-disable; + }; + }; + + serial_0_pins: uart0-state { + pins = "gpio20", "gpio21"; + function = "blsp0_uart0"; + bias-disable; + }; +}; + +&tsens { + status = "okay"; +}; + +&pcie_x2phy { + status = "okay"; +}; + +&pcie_x2 { + status = "okay"; + + perst-gpios = <&tlmm 15 GPIO_ACTIVE_LOW>; + + bridge@0,0 { + reg = <0x00000000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + ranges; + + wifi@1,0 { + status = "okay"; + + /* QCN9074: ath11k lacks DT compatible for PCI cards */ + compatible = "pci17cb,1104"; + reg = <0x00010000 0 0 0 0>; + + qcom,ath11k-calibration-variant = "Linksys-MX5500"; + }; + }; +}; + +&q6v5_wcss { + status = "okay"; + + memory-region = <&q6_mem_regions>; + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt", + "ath11k/IPQ5018/hw1.0/m3_fw.mdt"; + + // IPQ5018 + q6_wcss_pd1: pd-1 { + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt"; + + resets = + <&gcc GCC_WCSSAON_RESET>, + <&gcc GCC_WCSS_BCR>, + <&gcc GCC_CE_BCR>; + reset-names = + "wcss_aon_reset", + "wcss_reset", + "ce_reset"; + + clocks = + <&gcc GCC_WCSS_AHB_S_CLK>, + <&gcc GCC_WCSS_ACMT_CLK>, + <&gcc GCC_WCSS_AXI_M_CLK>; + clock-names = + "gcc_wcss_ahb_s_clk", + "gcc_wcss_acmt_clk", + "gcc_wcss_axi_m_clk"; + + // qcom,halt-regs = <&tcsr_q6_block 0xa000 0xd000 0x0>; + interrupts-extended = + <&wcss_smp2p_in 8 0>, + <&wcss_smp2p_in 9 0>, + <&wcss_smp2p_in 12 0>, + <&wcss_smp2p_in 11 0>; + interrupt-names = + "fatal", + "ready", + "spawn-ack", + "stop-ack"; + + qcom,smem-states = + <&wcss_smp2p_out 8>, + <&wcss_smp2p_out 9>, + <&wcss_smp2p_out 10>; + qcom,smem-state-names = + "shutdown", + "stop", + "spawn"; + status = "okay"; + }; +}; + +&wifi0 { + // IPQ5018 + qcom,rproc = <&q6_wcss_pd1>; + //qcom,userpd-subsys-name = "q6v5_wcss_userpd1"; + qcom,ath11k-calibration-variant = "Linksys-MX5500"; + qcom,ath11k-fw-memory-mode = <2>; + qcom,bdf-addr = <0x4c400000>; + + status = "okay"; +}; \ No newline at end of file diff --git a/target/linux/qualcommax/image/ipq50xx.mk b/target/linux/qualcommax/image/ipq50xx.mk index 8b137891791fe9..997a2ecf67e793 100644 --- a/target/linux/qualcommax/image/ipq50xx.mk +++ b/target/linux/qualcommax/image/ipq50xx.mk @@ -1 +1,36 @@ +define Device/linksys_mx2000 + $(call Device/FitImageLzma) + DEVICE_VENDOR := Linksys + DEVICE_MODEL := MX2000 + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_SIZE := 8192k + IMAGE_SIZE := 83968k + DEVICE_DTS_CONFIG := config@mp03.5-c1 + SOC := ipq5018 + 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=MX2000 + DEVICE_PACKAGES := ath11k-firmware-qcn6122 \ + ipq-wifi-linksys_mx2000 +endef +TARGET_DEVICES += linksys_mx2000 +define Device/linksys_mx5500 + $(call Device/FitImageLzma) + DEVICE_VENDOR := Linksys + DEVICE_MODEL := MX5500 + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_SIZE := 8192k + IMAGE_SIZE := 83968k + DEVICE_DTS_CONFIG := config@mp03.1 + SOC := ipq5018 + 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=MX5500 + DEVICE_PACKAGES := kmod-ath11k-pci \ + ath11k-firmware-qcn9074 \ + ipq-wifi-linksys_mx5500 +endef +TARGET_DEVICES += linksys_mx5500 \ No newline at end of file diff --git a/target/linux/qualcommax/ipq50xx/base-files/etc/board.d/02_network b/target/linux/qualcommax/ipq50xx/base-files/etc/board.d/02_network new file mode 100644 index 00000000000000..bcf606c75680b9 --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/etc/board.d/02_network @@ -0,0 +1,45 @@ +#!/bin/sh + +. /lib/functions/uci-defaults.sh +. /lib/functions/system.sh + +ipq50xx_setup_interfaces() +{ + local board="$1" + case $board in + linksys,mx2000|\ + linksys,mx5500) + ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan" + ;; + esac +} + +ipq50xx_setup_macs() +{ + local board="$1" + local lan_mac="" + local wan_mac="" + local label_mac="" + + case "$board" in + linksys,mx2000|\ + linksys,mx5500) + label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr) + lan_mac=$label_mac + wan_mac=$label_mac + ucidef_set_network_device_mac eth1 $label_mac + ;; + esac + + [ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac + [ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac + [ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac +} + +board_config_update +board=$(board_name) +ipq50xx_setup_interfaces $board +ipq50xx_setup_macs $board +board_config_flush + +exit 0 diff --git a/target/linux/qualcommax/ipq50xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata b/target/linux/qualcommax/ipq50xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata new file mode 100644 index 00000000000000..ad1e0f153528ad --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata @@ -0,0 +1,47 @@ +#!/bin/sh + +[ -e /lib/firmware/$FIRMWARE ] && exit 0 + +. /lib/functions/caldata.sh + +board=$(board_name) + +case "$FIRMWARE" in +"ath11k/IPQ5018/hw1.0/cal-ahb-c000000.wifi.bin") + case "$board" in + linksys,mx2000|\ + linksys,mx5500) + caldata_extract "0:ART" 0x1000 0x20000 + label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr) + ath11k_patch_mac $(macaddr_add $label_mac 1) 0 + ath11k_remove_regdomain + ath11k_set_macflag + ;; + esac + ;; +"ath11k/qcn6122/hw1.0/cal-ahb-soc@0:wifi1@c000000.bin") + case "$board" in + linksys,mx2000) + caldata_extract "0:ART" 0x26800 0x20000 + label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr) + ath11k_patch_mac $(macaddr_add $label_mac 2) 0 + ath11k_remove_regdomain + ath11k_set_macflag + ;; + esac + ;; +"ath11k/QCN9074/hw1.0/cal-pci-0001:01:00.0.bin") + case "$board" in + linksys,mx5500) + caldata_extract "0:ART" 0x26800 0x20000 + label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr) + ath11k_patch_mac $(macaddr_add $label_mac 2) 0 + ath11k_remove_regdomain + ath11k_set_macflag + ;; + esac + ;; +*) + exit 1 + ;; +esac diff --git a/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount b/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount new file mode 100755 index 00000000000000..b570428aef089d --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount @@ -0,0 +1,12 @@ +#!/bin/sh /etc/rc.common + +START=99 + +boot() { + case $(board_name) in + linksys,mx2000|\ + linksys,mx5500) + mtd resetbc s_env || true + ;; + esac +} diff --git a/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/linksys.sh b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/linksys.sh new file mode 100644 index 00000000000000..18366fc622a478 --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/linksys.sh @@ -0,0 +1,125 @@ +linksys_get_target_firmware() { + local cur_boot_part mtd_ubi0 + + cur_boot_part="$(/usr/sbin/fw_printenv -n boot_part)" + if [ -z "${cur_boot_part}" ]; then + mtd_ubi0=$(cat /sys/class/ubi/ubi0/mtd_num) + case "$(grep -E "^mtd${mtd_ubi0}:" /proc/mtd | cut -d '"' -f 2)" in + kernel|rootfs) + cur_boot_part=1 + ;; + alt_kernel|alt_rootfs) + cur_boot_part=2 + ;; + esac + >&2 printf "Current boot_part='%s' selected from ubi0/mtd_num='%s'" \ + "${cur_boot_part}" "${mtd_ubi0}" + fi + + # OEM U-Boot for EA6350v3, EA8300 and MR8300; bootcmd= + # if test $auto_recovery = no; + # then bootipq; + # elif test $boot_part = 1; + # then run bootpart1; + # else run bootpart2; + # fi + + case "$cur_boot_part" in + 1) + fw_setenv -s - <<-EOF + boot_part 2 + auto_recovery yes + EOF + printf "alt_kernel" + return + ;; + 2) + fw_setenv -s - <<-EOF + boot_part 1 + auto_recovery yes + EOF + printf "kernel" + return + ;; + *) + return + ;; + esac +} + +linksys_is_factory_image() { + local board=$(board_name) + board=${board##*,} + + # check matching footer signature + tail -c 256 $1 | grep -q -i "\.LINKSYS\.........${board}" +} + +platform_do_upgrade_linksys() { + local magic_long="$(get_magic_long "$1")" + + local rm_oem_fw_vols="squashfs ubifs" # from OEM [alt_]rootfs UBI + local vol + + mkdir -p /var/lock + local part_label="$(linksys_get_target_firmware)" + touch /var/lock/fw_printenv.lock + + if [ -z "$part_label" ]; then + echo "cannot find target partition" + exit 1 + fi + + local target_mtd=$(find_mtd_part "$part_label") + + [ "$magic_long" = "73797375" ] && { + CI_KERNPART="$part_label" + if [ "$part_label" = "kernel" ]; then + CI_UBIPART="rootfs" + else + CI_UBIPART="alt_rootfs" + fi + + 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 + for vol in $rm_oem_fw_vols; do + ubirmvol "/dev/$ubidev" -N "$vol" 2>/dev/null + done + fi + + # complete std upgrade + if nand_upgrade_tar "$1" ; then + nand_do_upgrade_success + else + nand_do_upgrade_failed + fi + + } + + [ "$magic_long" = "27051956" ] && { + echo "writing \"$1\" image to \"$part_label\"" + get_image "$1" | mtd write - "$part_label" + } + + [ "$magic_long" = "d00dfeed" ] && { + if ! linksys_is_factory_image "$1"; then + echo "factory image doesn't match device" + return 1 + fi + + echo "writing \"$1\" factory image to \"$part_label\"" + get_image "$1" | mtd -e "$part_label" write - "$part_label" + } +} diff --git a/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh new file mode 100644 index 00000000000000..5be51c77fd68d1 --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh @@ -0,0 +1,32 @@ +PART_NAME=firmware +REQUIRE_IMAGE_METADATA=1 + +RAMFS_COPY_BIN='fw_printenv fw_setenv head' +RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock' + +platform_check_image() { + return 0; +} + +platform_do_upgrade() { + case "$(board_name)" in + linksys,mx2000|\ + linksys,mx5500) + boot_part="$(fw_printenv -n boot_part)" + if [ "$boot_part" -eq "1" ]; then + fw_setenv boot_part 2 + CI_KERNPART="alt_kernel" + CI_UBIPART="alt_rootfs" + else + fw_setenv boot_part 1 + CI_UBIPART="rootfs" + fi + fw_setenv boot_part_ready 3 + fw_setenv auto_recovery yes + nand_do_upgrade "$1" + ;; + *) + default_do_upgrade "$1" + ;; + esac +}