mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-22 16:07:49 +08:00
Update On Tue Jul 2 20:34:19 CEST 2024
This commit is contained in:
@@ -690,3 +690,4 @@ Update On Fri Jun 28 20:30:26 CEST 2024
|
||||
Update On Sat Jun 29 20:29:36 CEST 2024
|
||||
Update On Sun Jun 30 20:30:33 CEST 2024
|
||||
Update On Mon Jul 1 20:30:34 CEST 2024
|
||||
Update On Tue Jul 2 20:34:08 CEST 2024
|
||||
|
||||
Generated
+2
-2
@@ -5178,9 +5178,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.119"
|
||||
version = "1.0.120"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8eddb61f0697cc3989c5d64b452f5488e2b8a60fd7d5076a3045076ffef8cb0"
|
||||
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
|
||||
dependencies = [
|
||||
"indexmap 2.2.6",
|
||||
"itoa 1.0.11",
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-error-boundary": "4.0.13",
|
||||
"react-fast-marquee": "1.6.4",
|
||||
"react-hook-form": "7.52.0",
|
||||
"react-fast-marquee": "1.6.5",
|
||||
"react-hook-form": "7.52.1",
|
||||
"react-hook-form-mui": "7.0.0",
|
||||
"react-i18next": "14.1.2",
|
||||
"react-markdown": "9.0.1",
|
||||
@@ -53,8 +53,8 @@
|
||||
"@types/react": "18.3.3",
|
||||
"@types/react-dom": "18.3.0",
|
||||
"@types/react-transition-group": "4.4.10",
|
||||
"@typescript-eslint/eslint-plugin": "7.14.1",
|
||||
"@typescript-eslint/parser": "7.14.1",
|
||||
"@typescript-eslint/eslint-plugin": "7.15.0",
|
||||
"@typescript-eslint/parser": "7.15.0",
|
||||
"@vitejs/plugin-react": "4.3.1",
|
||||
"@vitejs/plugin-react-swc": "3.7.0",
|
||||
"clsx": "2.1.1",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"latest": {
|
||||
"mihomo": "v1.18.5",
|
||||
"mihomo": "v1.18.6",
|
||||
"mihomo_alpha": "alpha-0e22876",
|
||||
"clash_rs": "v0.1.18",
|
||||
"clash_premium": "2023-09-05-gdcc8d87"
|
||||
@@ -36,5 +36,5 @@
|
||||
"darwin-x64": "clash-darwin-amd64-n{}.gz"
|
||||
}
|
||||
},
|
||||
"updated_at": "2024-06-28T22:20:05.617Z"
|
||||
"updated_at": "2024-07-01T22:20:09.970Z"
|
||||
}
|
||||
|
||||
@@ -107,11 +107,11 @@
|
||||
"stylelint-scss": "6.3.2",
|
||||
"tailwindcss": "3.4.4",
|
||||
"tsx": "4.16.0",
|
||||
"typescript": "5.5.2"
|
||||
"typescript": "5.5.3"
|
||||
},
|
||||
"packageManager": "pnpm@9.4.0",
|
||||
"engines": {
|
||||
"node": "22.3.0"
|
||||
"node": "22.4.0"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
|
||||
Generated
+128
-128
@@ -24,7 +24,7 @@ importers:
|
||||
devDependencies:
|
||||
'@commitlint/cli':
|
||||
specifier: 19.3.0
|
||||
version: 19.3.0(@types/node@20.14.9)(typescript@5.5.2)
|
||||
version: 19.3.0(@types/node@20.14.9)(typescript@5.5.3)
|
||||
'@commitlint/config-conventional':
|
||||
specifier: 19.2.2
|
||||
version: 19.2.2
|
||||
@@ -111,25 +111,25 @@ importers:
|
||||
version: 5.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)
|
||||
stylelint:
|
||||
specifier: 16.6.1
|
||||
version: 16.6.1(typescript@5.5.2)
|
||||
version: 16.6.1(typescript@5.5.3)
|
||||
stylelint-config-html:
|
||||
specifier: 1.1.0
|
||||
version: 1.1.0(postcss-html@1.7.0)(stylelint@16.6.1(typescript@5.5.2))
|
||||
version: 1.1.0(postcss-html@1.7.0)(stylelint@16.6.1(typescript@5.5.3))
|
||||
stylelint-config-recess-order:
|
||||
specifier: 5.0.1
|
||||
version: 5.0.1(stylelint@16.6.1(typescript@5.5.2))
|
||||
version: 5.0.1(stylelint@16.6.1(typescript@5.5.3))
|
||||
stylelint-config-standard:
|
||||
specifier: 36.0.1
|
||||
version: 36.0.1(stylelint@16.6.1(typescript@5.5.2))
|
||||
version: 36.0.1(stylelint@16.6.1(typescript@5.5.3))
|
||||
stylelint-declaration-block-no-ignored-properties:
|
||||
specifier: 2.8.0
|
||||
version: 2.8.0(stylelint@16.6.1(typescript@5.5.2))
|
||||
version: 2.8.0(stylelint@16.6.1(typescript@5.5.3))
|
||||
stylelint-order:
|
||||
specifier: 6.0.4
|
||||
version: 6.0.4(stylelint@16.6.1(typescript@5.5.2))
|
||||
version: 6.0.4(stylelint@16.6.1(typescript@5.5.3))
|
||||
stylelint-scss:
|
||||
specifier: 6.3.2
|
||||
version: 6.3.2(stylelint@16.6.1(typescript@5.5.2))
|
||||
version: 6.3.2(stylelint@16.6.1(typescript@5.5.3))
|
||||
tailwindcss:
|
||||
specifier: 3.4.4
|
||||
version: 3.4.4
|
||||
@@ -137,8 +137,8 @@ importers:
|
||||
specifier: 4.16.0
|
||||
version: 4.16.0
|
||||
typescript:
|
||||
specifier: 5.5.2
|
||||
version: 5.5.2
|
||||
specifier: 5.5.3
|
||||
version: 5.5.3
|
||||
|
||||
frontend/interface:
|
||||
dependencies:
|
||||
@@ -243,14 +243,14 @@ importers:
|
||||
specifier: 4.0.13
|
||||
version: 4.0.13(react@19.0.0-rc-fb9a90fa48-20240614)
|
||||
react-fast-marquee:
|
||||
specifier: 1.6.4
|
||||
version: 1.6.4(react-dom@19.0.0-rc-fb9a90fa48-20240614(react@19.0.0-rc-fb9a90fa48-20240614))(react@19.0.0-rc-fb9a90fa48-20240614)
|
||||
specifier: 1.6.5
|
||||
version: 1.6.5(react-dom@19.0.0-rc-fb9a90fa48-20240614(react@19.0.0-rc-fb9a90fa48-20240614))(react@19.0.0-rc-fb9a90fa48-20240614)
|
||||
react-hook-form:
|
||||
specifier: 7.52.0
|
||||
version: 7.52.0(react@19.0.0-rc-fb9a90fa48-20240614)
|
||||
specifier: 7.52.1
|
||||
version: 7.52.1(react@19.0.0-rc-fb9a90fa48-20240614)
|
||||
react-hook-form-mui:
|
||||
specifier: 7.0.0
|
||||
version: 7.0.0(zwihrdjnuz7uekpqkqd7rvdhli)
|
||||
version: 7.0.0(hnsbxdphojlfk7ty6r3hqlevge)
|
||||
react-i18next:
|
||||
specifier: 14.1.2
|
||||
version: 14.1.2(i18next@23.11.5)(react-dom@19.0.0-rc-fb9a90fa48-20240614(react@19.0.0-rc-fb9a90fa48-20240614))(react@19.0.0-rc-fb9a90fa48-20240614)
|
||||
@@ -292,11 +292,11 @@ importers:
|
||||
specifier: 4.4.10
|
||||
version: 4.4.10
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: 7.14.1
|
||||
version: 7.14.1(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)
|
||||
specifier: 7.15.0
|
||||
version: 7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)
|
||||
'@typescript-eslint/parser':
|
||||
specifier: 7.14.1
|
||||
version: 7.14.1(eslint@8.57.0)(typescript@5.5.2)
|
||||
specifier: 7.15.0
|
||||
version: 7.15.0(eslint@8.57.0)(typescript@5.5.3)
|
||||
'@vitejs/plugin-react':
|
||||
specifier: 4.3.1
|
||||
version: 4.3.1(vite@5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0))
|
||||
@@ -329,10 +329,10 @@ importers:
|
||||
version: 1.3.22(postcss@8.4.39)(prettier@3.3.2)(sass@1.77.6)(vite@5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0))
|
||||
vite-plugin-svgr:
|
||||
specifier: 4.2.0
|
||||
version: 4.2.0(rollup@4.17.2)(typescript@5.5.2)(vite@5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0))
|
||||
version: 4.2.0(rollup@4.17.2)(typescript@5.5.3)(vite@5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0))
|
||||
vite-tsconfig-paths:
|
||||
specifier: 4.3.2
|
||||
version: 4.3.2(typescript@5.5.2)(vite@5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0))
|
||||
version: 4.3.2(typescript@5.5.3)(vite@5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0))
|
||||
|
||||
frontend/ui:
|
||||
dependencies:
|
||||
@@ -381,7 +381,7 @@ importers:
|
||||
version: 1.77.6
|
||||
typescript-plugin-css-modules:
|
||||
specifier: 5.1.0
|
||||
version: 5.1.0(typescript@5.5.2)
|
||||
version: 5.1.0(typescript@5.5.3)
|
||||
|
||||
scripts:
|
||||
dependencies:
|
||||
@@ -2103,8 +2103,8 @@ packages:
|
||||
'@types/yauzl@2.10.3':
|
||||
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
|
||||
|
||||
'@typescript-eslint/eslint-plugin@7.14.1':
|
||||
resolution: {integrity: sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==}
|
||||
'@typescript-eslint/eslint-plugin@7.15.0':
|
||||
resolution: {integrity: sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': ^7.0.0
|
||||
@@ -2114,8 +2114,8 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/parser@7.14.1':
|
||||
resolution: {integrity: sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==}
|
||||
'@typescript-eslint/parser@7.15.0':
|
||||
resolution: {integrity: sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
@@ -2124,12 +2124,12 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/scope-manager@7.14.1':
|
||||
resolution: {integrity: sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==}
|
||||
'@typescript-eslint/scope-manager@7.15.0':
|
||||
resolution: {integrity: sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
|
||||
'@typescript-eslint/type-utils@7.14.1':
|
||||
resolution: {integrity: sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==}
|
||||
'@typescript-eslint/type-utils@7.15.0':
|
||||
resolution: {integrity: sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
@@ -2138,12 +2138,12 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/types@7.14.1':
|
||||
resolution: {integrity: sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==}
|
||||
'@typescript-eslint/types@7.15.0':
|
||||
resolution: {integrity: sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
|
||||
'@typescript-eslint/typescript-estree@7.14.1':
|
||||
resolution: {integrity: sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==}
|
||||
'@typescript-eslint/typescript-estree@7.15.0':
|
||||
resolution: {integrity: sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
@@ -2151,14 +2151,14 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/utils@7.14.1':
|
||||
resolution: {integrity: sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==}
|
||||
'@typescript-eslint/utils@7.15.0':
|
||||
resolution: {integrity: sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
|
||||
'@typescript-eslint/visitor-keys@7.14.1':
|
||||
resolution: {integrity: sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==}
|
||||
'@typescript-eslint/visitor-keys@7.15.0':
|
||||
resolution: {integrity: sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==}
|
||||
engines: {node: ^18.18.0 || >=20.0.0}
|
||||
|
||||
'@ungap/structured-clone@1.2.0':
|
||||
@@ -4872,8 +4872,8 @@ packages:
|
||||
react-fast-compare@3.2.2:
|
||||
resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==}
|
||||
|
||||
react-fast-marquee@1.6.4:
|
||||
resolution: {integrity: sha512-LAgvhRmHdqaUQ8R5jCUwzEGFUIjnCCt3T3W8X7j7wF6DWe0SATlpP0JX1V0pp2qX3DYUezmn1Iz5AtRFdL2EWQ==}
|
||||
react-fast-marquee@1.6.5:
|
||||
resolution: {integrity: sha512-swDnPqrT2XISAih0o74zQVE2wQJFMvkx+9VZXYYNSLb/CUcAzU9pNj637Ar2+hyRw6b4tP6xh4GQZip2ZCpQpg==}
|
||||
peerDependencies:
|
||||
react: npm:react@rc
|
||||
react-dom: npm:react-dom@rc
|
||||
@@ -4893,8 +4893,8 @@ packages:
|
||||
'@mui/x-date-pickers':
|
||||
optional: true
|
||||
|
||||
react-hook-form@7.52.0:
|
||||
resolution: {integrity: sha512-mJX506Xc6mirzLsmXUJyqlAI3Kj9Ph2RhplYhUVffeOQSnubK2uVqBFOBJmvKikvbFV91pxVXmDiR+QMF19x6A==}
|
||||
react-hook-form@7.52.1:
|
||||
resolution: {integrity: sha512-uNKIhaoICJ5KQALYZ4TOaOLElyM+xipord+Ha3crEFhTntdLvWZqVY49Wqd/0GiVCA/f9NjemLeiNPjG7Hpurg==}
|
||||
engines: {node: '>=12.22.0'}
|
||||
peerDependencies:
|
||||
react: npm:react@rc
|
||||
@@ -5557,8 +5557,8 @@ packages:
|
||||
peerDependencies:
|
||||
typescript: '>=4.0.0'
|
||||
|
||||
typescript@5.5.2:
|
||||
resolution: {integrity: sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==}
|
||||
typescript@5.5.3:
|
||||
resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
@@ -6048,11 +6048,11 @@ snapshots:
|
||||
'@babel/helper-validator-identifier': 7.24.5
|
||||
to-fast-properties: 2.0.0
|
||||
|
||||
'@commitlint/cli@19.3.0(@types/node@20.14.9)(typescript@5.5.2)':
|
||||
'@commitlint/cli@19.3.0(@types/node@20.14.9)(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@commitlint/format': 19.3.0
|
||||
'@commitlint/lint': 19.2.2
|
||||
'@commitlint/load': 19.2.0(@types/node@20.14.9)(typescript@5.5.2)
|
||||
'@commitlint/load': 19.2.0(@types/node@20.14.9)(typescript@5.5.3)
|
||||
'@commitlint/read': 19.2.1
|
||||
'@commitlint/types': 19.0.3
|
||||
execa: 8.0.1
|
||||
@@ -6099,15 +6099,15 @@ snapshots:
|
||||
'@commitlint/rules': 19.0.3
|
||||
'@commitlint/types': 19.0.3
|
||||
|
||||
'@commitlint/load@19.2.0(@types/node@20.14.9)(typescript@5.5.2)':
|
||||
'@commitlint/load@19.2.0(@types/node@20.14.9)(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@commitlint/config-validator': 19.0.3
|
||||
'@commitlint/execute-rule': 19.0.0
|
||||
'@commitlint/resolve-extends': 19.1.0
|
||||
'@commitlint/types': 19.0.3
|
||||
chalk: 5.3.0
|
||||
cosmiconfig: 9.0.0(typescript@5.5.2)
|
||||
cosmiconfig-typescript-loader: 5.0.0(@types/node@20.14.9)(cosmiconfig@9.0.0(typescript@5.5.2))(typescript@5.5.2)
|
||||
cosmiconfig: 9.0.0(typescript@5.5.3)
|
||||
cosmiconfig-typescript-loader: 5.0.0(@types/node@20.14.9)(cosmiconfig@9.0.0(typescript@5.5.3))(typescript@5.5.3)
|
||||
lodash.isplainobject: 4.0.6
|
||||
lodash.merge: 4.6.2
|
||||
lodash.uniq: 4.5.0
|
||||
@@ -7087,12 +7087,12 @@ snapshots:
|
||||
'@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.24.5)
|
||||
'@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.24.5)
|
||||
|
||||
'@svgr/core@8.1.0(typescript@5.5.2)':
|
||||
'@svgr/core@8.1.0(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.5
|
||||
'@svgr/babel-preset': 8.1.0(@babel/core@7.24.5)
|
||||
camelcase: 6.3.0
|
||||
cosmiconfig: 8.3.6(typescript@5.5.2)
|
||||
cosmiconfig: 8.3.6(typescript@5.5.3)
|
||||
snake-case: 3.0.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -7103,11 +7103,11 @@ snapshots:
|
||||
'@babel/types': 7.24.5
|
||||
entities: 4.5.0
|
||||
|
||||
'@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.5.2))':
|
||||
'@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.5.3))':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.5
|
||||
'@svgr/babel-preset': 8.1.0(@babel/core@7.24.5)
|
||||
'@svgr/core': 8.1.0(typescript@5.5.2)
|
||||
'@svgr/core': 8.1.0(typescript@5.5.3)
|
||||
'@svgr/hast-util-to-babel-ast': 8.0.0
|
||||
svg-parser: 2.0.4
|
||||
transitivePeerDependencies:
|
||||
@@ -7463,85 +7463,85 @@ snapshots:
|
||||
'@types/node': 20.14.9
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/eslint-plugin@7.14.1(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)':
|
||||
'@typescript-eslint/eslint-plugin@7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.10.0
|
||||
'@typescript-eslint/parser': 7.14.1(eslint@8.57.0)(typescript@5.5.2)
|
||||
'@typescript-eslint/scope-manager': 7.14.1
|
||||
'@typescript-eslint/type-utils': 7.14.1(eslint@8.57.0)(typescript@5.5.2)
|
||||
'@typescript-eslint/utils': 7.14.1(eslint@8.57.0)(typescript@5.5.2)
|
||||
'@typescript-eslint/visitor-keys': 7.14.1
|
||||
'@typescript-eslint/parser': 7.15.0(eslint@8.57.0)(typescript@5.5.3)
|
||||
'@typescript-eslint/scope-manager': 7.15.0
|
||||
'@typescript-eslint/type-utils': 7.15.0(eslint@8.57.0)(typescript@5.5.3)
|
||||
'@typescript-eslint/utils': 7.15.0(eslint@8.57.0)(typescript@5.5.3)
|
||||
'@typescript-eslint/visitor-keys': 7.15.0
|
||||
eslint: 8.57.0
|
||||
graphemer: 1.4.0
|
||||
ignore: 5.3.1
|
||||
natural-compare: 1.4.0
|
||||
ts-api-utils: 1.3.0(typescript@5.5.2)
|
||||
ts-api-utils: 1.3.0(typescript@5.5.3)
|
||||
optionalDependencies:
|
||||
typescript: 5.5.2
|
||||
typescript: 5.5.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.5.2)':
|
||||
'@typescript-eslint/parser@7.15.0(eslint@8.57.0)(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 7.14.1
|
||||
'@typescript-eslint/types': 7.14.1
|
||||
'@typescript-eslint/typescript-estree': 7.14.1(typescript@5.5.2)
|
||||
'@typescript-eslint/visitor-keys': 7.14.1
|
||||
'@typescript-eslint/scope-manager': 7.15.0
|
||||
'@typescript-eslint/types': 7.15.0
|
||||
'@typescript-eslint/typescript-estree': 7.15.0(typescript@5.5.3)
|
||||
'@typescript-eslint/visitor-keys': 7.15.0
|
||||
debug: 4.3.4
|
||||
eslint: 8.57.0
|
||||
optionalDependencies:
|
||||
typescript: 5.5.2
|
||||
typescript: 5.5.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/scope-manager@7.14.1':
|
||||
'@typescript-eslint/scope-manager@7.15.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 7.14.1
|
||||
'@typescript-eslint/visitor-keys': 7.14.1
|
||||
'@typescript-eslint/types': 7.15.0
|
||||
'@typescript-eslint/visitor-keys': 7.15.0
|
||||
|
||||
'@typescript-eslint/type-utils@7.14.1(eslint@8.57.0)(typescript@5.5.2)':
|
||||
'@typescript-eslint/type-utils@7.15.0(eslint@8.57.0)(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/typescript-estree': 7.14.1(typescript@5.5.2)
|
||||
'@typescript-eslint/utils': 7.14.1(eslint@8.57.0)(typescript@5.5.2)
|
||||
'@typescript-eslint/typescript-estree': 7.15.0(typescript@5.5.3)
|
||||
'@typescript-eslint/utils': 7.15.0(eslint@8.57.0)(typescript@5.5.3)
|
||||
debug: 4.3.4
|
||||
eslint: 8.57.0
|
||||
ts-api-utils: 1.3.0(typescript@5.5.2)
|
||||
ts-api-utils: 1.3.0(typescript@5.5.3)
|
||||
optionalDependencies:
|
||||
typescript: 5.5.2
|
||||
typescript: 5.5.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/types@7.14.1': {}
|
||||
'@typescript-eslint/types@7.15.0': {}
|
||||
|
||||
'@typescript-eslint/typescript-estree@7.14.1(typescript@5.5.2)':
|
||||
'@typescript-eslint/typescript-estree@7.15.0(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 7.14.1
|
||||
'@typescript-eslint/visitor-keys': 7.14.1
|
||||
'@typescript-eslint/types': 7.15.0
|
||||
'@typescript-eslint/visitor-keys': 7.15.0
|
||||
debug: 4.3.4
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
minimatch: 9.0.4
|
||||
semver: 7.6.1
|
||||
ts-api-utils: 1.3.0(typescript@5.5.2)
|
||||
ts-api-utils: 1.3.0(typescript@5.5.3)
|
||||
optionalDependencies:
|
||||
typescript: 5.5.2
|
||||
typescript: 5.5.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@7.14.1(eslint@8.57.0)(typescript@5.5.2)':
|
||||
'@typescript-eslint/utils@7.15.0(eslint@8.57.0)(typescript@5.5.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
|
||||
'@typescript-eslint/scope-manager': 7.14.1
|
||||
'@typescript-eslint/types': 7.14.1
|
||||
'@typescript-eslint/typescript-estree': 7.14.1(typescript@5.5.2)
|
||||
'@typescript-eslint/scope-manager': 7.15.0
|
||||
'@typescript-eslint/types': 7.15.0
|
||||
'@typescript-eslint/typescript-estree': 7.15.0(typescript@5.5.3)
|
||||
eslint: 8.57.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@typescript-eslint/visitor-keys@7.14.1':
|
||||
'@typescript-eslint/visitor-keys@7.15.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 7.14.1
|
||||
'@typescript-eslint/types': 7.15.0
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@ungap/structured-clone@1.2.0': {}
|
||||
@@ -8048,12 +8048,12 @@ snapshots:
|
||||
dependencies:
|
||||
is-what: 3.14.1
|
||||
|
||||
cosmiconfig-typescript-loader@5.0.0(@types/node@20.14.9)(cosmiconfig@9.0.0(typescript@5.5.2))(typescript@5.5.2):
|
||||
cosmiconfig-typescript-loader@5.0.0(@types/node@20.14.9)(cosmiconfig@9.0.0(typescript@5.5.3))(typescript@5.5.3):
|
||||
dependencies:
|
||||
'@types/node': 20.14.9
|
||||
cosmiconfig: 9.0.0(typescript@5.5.2)
|
||||
cosmiconfig: 9.0.0(typescript@5.5.3)
|
||||
jiti: 1.21.0
|
||||
typescript: 5.5.2
|
||||
typescript: 5.5.3
|
||||
|
||||
cosmiconfig@7.1.0:
|
||||
dependencies:
|
||||
@@ -8063,23 +8063,23 @@ snapshots:
|
||||
path-type: 4.0.0
|
||||
yaml: 1.10.2
|
||||
|
||||
cosmiconfig@8.3.6(typescript@5.5.2):
|
||||
cosmiconfig@8.3.6(typescript@5.5.3):
|
||||
dependencies:
|
||||
import-fresh: 3.3.0
|
||||
js-yaml: 4.1.0
|
||||
parse-json: 5.2.0
|
||||
path-type: 4.0.0
|
||||
optionalDependencies:
|
||||
typescript: 5.5.2
|
||||
typescript: 5.5.3
|
||||
|
||||
cosmiconfig@9.0.0(typescript@5.5.2):
|
||||
cosmiconfig@9.0.0(typescript@5.5.3):
|
||||
dependencies:
|
||||
env-paths: 2.2.1
|
||||
import-fresh: 3.3.0
|
||||
js-yaml: 4.1.0
|
||||
parse-json: 5.2.0
|
||||
optionalDependencies:
|
||||
typescript: 5.5.2
|
||||
typescript: 5.5.3
|
||||
|
||||
create-error-class@3.0.2:
|
||||
dependencies:
|
||||
@@ -10601,20 +10601,20 @@ snapshots:
|
||||
|
||||
react-fast-compare@3.2.2: {}
|
||||
|
||||
react-fast-marquee@1.6.4(react-dom@19.0.0-rc-fb9a90fa48-20240614(react@19.0.0-rc-fb9a90fa48-20240614))(react@19.0.0-rc-fb9a90fa48-20240614):
|
||||
react-fast-marquee@1.6.5(react-dom@19.0.0-rc-fb9a90fa48-20240614(react@19.0.0-rc-fb9a90fa48-20240614))(react@19.0.0-rc-fb9a90fa48-20240614):
|
||||
dependencies:
|
||||
react: 19.0.0-rc-fb9a90fa48-20240614
|
||||
react-dom: 19.0.0-rc-fb9a90fa48-20240614(react@19.0.0-rc-fb9a90fa48-20240614)
|
||||
|
||||
react-hook-form-mui@7.0.0(zwihrdjnuz7uekpqkqd7rvdhli):
|
||||
react-hook-form-mui@7.0.0(hnsbxdphojlfk7ty6r3hqlevge):
|
||||
dependencies:
|
||||
'@mui/material': 5.15.21(@emotion/react@11.11.4(react@19.0.0-rc-fb9a90fa48-20240614)(types-react@19.0.0-rc.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(react@19.0.0-rc-fb9a90fa48-20240614)(types-react@19.0.0-rc.1))(react@19.0.0-rc-fb9a90fa48-20240614)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-fb9a90fa48-20240614(react@19.0.0-rc-fb9a90fa48-20240614))(react@19.0.0-rc-fb9a90fa48-20240614)(types-react@19.0.0-rc.1)
|
||||
react: 19.0.0-rc-fb9a90fa48-20240614
|
||||
react-hook-form: 7.52.0(react@19.0.0-rc-fb9a90fa48-20240614)
|
||||
react-hook-form: 7.52.1(react@19.0.0-rc-fb9a90fa48-20240614)
|
||||
optionalDependencies:
|
||||
'@mui/icons-material': 5.15.21(@mui/material@5.15.21(@emotion/react@11.11.4(react@19.0.0-rc-fb9a90fa48-20240614)(types-react@19.0.0-rc.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(react@19.0.0-rc-fb9a90fa48-20240614)(types-react@19.0.0-rc.1))(react@19.0.0-rc-fb9a90fa48-20240614)(types-react@19.0.0-rc.1))(react@19.0.0-rc-fb9a90fa48-20240614)(types-react@19.0.0-rc.1))(react@19.0.0-rc-fb9a90fa48-20240614)(types-react@19.0.0-rc.1)
|
||||
|
||||
react-hook-form@7.52.0(react@19.0.0-rc-fb9a90fa48-20240614):
|
||||
react-hook-form@7.52.1(react@19.0.0-rc-fb9a90fa48-20240614):
|
||||
dependencies:
|
||||
react: 19.0.0-rc-fb9a90fa48-20240614
|
||||
|
||||
@@ -11071,45 +11071,45 @@ snapshots:
|
||||
dependencies:
|
||||
inline-style-parser: 0.2.3
|
||||
|
||||
stylelint-config-html@1.1.0(postcss-html@1.7.0)(stylelint@16.6.1(typescript@5.5.2)):
|
||||
stylelint-config-html@1.1.0(postcss-html@1.7.0)(stylelint@16.6.1(typescript@5.5.3)):
|
||||
dependencies:
|
||||
postcss-html: 1.7.0
|
||||
stylelint: 16.6.1(typescript@5.5.2)
|
||||
stylelint: 16.6.1(typescript@5.5.3)
|
||||
|
||||
stylelint-config-recess-order@5.0.1(stylelint@16.6.1(typescript@5.5.2)):
|
||||
stylelint-config-recess-order@5.0.1(stylelint@16.6.1(typescript@5.5.3)):
|
||||
dependencies:
|
||||
stylelint: 16.6.1(typescript@5.5.2)
|
||||
stylelint-order: 6.0.4(stylelint@16.6.1(typescript@5.5.2))
|
||||
stylelint: 16.6.1(typescript@5.5.3)
|
||||
stylelint-order: 6.0.4(stylelint@16.6.1(typescript@5.5.3))
|
||||
|
||||
stylelint-config-recommended@14.0.1(stylelint@16.6.1(typescript@5.5.2)):
|
||||
stylelint-config-recommended@14.0.1(stylelint@16.6.1(typescript@5.5.3)):
|
||||
dependencies:
|
||||
stylelint: 16.6.1(typescript@5.5.2)
|
||||
stylelint: 16.6.1(typescript@5.5.3)
|
||||
|
||||
stylelint-config-standard@36.0.1(stylelint@16.6.1(typescript@5.5.2)):
|
||||
stylelint-config-standard@36.0.1(stylelint@16.6.1(typescript@5.5.3)):
|
||||
dependencies:
|
||||
stylelint: 16.6.1(typescript@5.5.2)
|
||||
stylelint-config-recommended: 14.0.1(stylelint@16.6.1(typescript@5.5.2))
|
||||
stylelint: 16.6.1(typescript@5.5.3)
|
||||
stylelint-config-recommended: 14.0.1(stylelint@16.6.1(typescript@5.5.3))
|
||||
|
||||
stylelint-declaration-block-no-ignored-properties@2.8.0(stylelint@16.6.1(typescript@5.5.2)):
|
||||
stylelint-declaration-block-no-ignored-properties@2.8.0(stylelint@16.6.1(typescript@5.5.3)):
|
||||
dependencies:
|
||||
stylelint: 16.6.1(typescript@5.5.2)
|
||||
stylelint: 16.6.1(typescript@5.5.3)
|
||||
|
||||
stylelint-order@6.0.4(stylelint@16.6.1(typescript@5.5.2)):
|
||||
stylelint-order@6.0.4(stylelint@16.6.1(typescript@5.5.3)):
|
||||
dependencies:
|
||||
postcss: 8.4.39
|
||||
postcss-sorting: 8.0.2(postcss@8.4.39)
|
||||
stylelint: 16.6.1(typescript@5.5.2)
|
||||
stylelint: 16.6.1(typescript@5.5.3)
|
||||
|
||||
stylelint-scss@6.3.2(stylelint@16.6.1(typescript@5.5.2)):
|
||||
stylelint-scss@6.3.2(stylelint@16.6.1(typescript@5.5.3)):
|
||||
dependencies:
|
||||
known-css-properties: 0.31.0
|
||||
postcss-media-query-parser: 0.2.3
|
||||
postcss-resolve-nested-selector: 0.1.1
|
||||
postcss-selector-parser: 6.1.0
|
||||
postcss-value-parser: 4.2.0
|
||||
stylelint: 16.6.1(typescript@5.5.2)
|
||||
stylelint: 16.6.1(typescript@5.5.3)
|
||||
|
||||
stylelint@16.6.1(typescript@5.5.2):
|
||||
stylelint@16.6.1(typescript@5.5.3):
|
||||
dependencies:
|
||||
'@csstools/css-parser-algorithms': 2.6.3(@csstools/css-tokenizer@2.3.1)
|
||||
'@csstools/css-tokenizer': 2.3.1
|
||||
@@ -11118,7 +11118,7 @@ snapshots:
|
||||
'@dual-bundle/import-meta-resolve': 4.1.0
|
||||
balanced-match: 2.0.0
|
||||
colord: 2.9.3
|
||||
cosmiconfig: 9.0.0(typescript@5.5.2)
|
||||
cosmiconfig: 9.0.0(typescript@5.5.3)
|
||||
css-functions-list: 3.2.2
|
||||
css-tree: 2.3.1
|
||||
debug: 4.3.4
|
||||
@@ -11332,17 +11332,17 @@ snapshots:
|
||||
|
||||
trough@2.2.0: {}
|
||||
|
||||
ts-api-utils@1.3.0(typescript@5.5.2):
|
||||
ts-api-utils@1.3.0(typescript@5.5.3):
|
||||
dependencies:
|
||||
typescript: 5.5.2
|
||||
typescript: 5.5.3
|
||||
|
||||
ts-custom-error@3.3.1: {}
|
||||
|
||||
ts-interface-checker@0.1.13: {}
|
||||
|
||||
tsconfck@3.0.3(typescript@5.5.2):
|
||||
tsconfck@3.0.3(typescript@5.5.3):
|
||||
optionalDependencies:
|
||||
typescript: 5.5.2
|
||||
typescript: 5.5.3
|
||||
|
||||
tsconfig-paths@3.15.0:
|
||||
dependencies:
|
||||
@@ -11423,7 +11423,7 @@ snapshots:
|
||||
dependencies:
|
||||
csstype: 3.1.3
|
||||
|
||||
typescript-plugin-css-modules@5.1.0(typescript@5.5.2):
|
||||
typescript-plugin-css-modules@5.1.0(typescript@5.5.3):
|
||||
dependencies:
|
||||
'@types/postcss-modules-local-by-default': 4.0.2
|
||||
'@types/postcss-modules-scope': 3.0.4
|
||||
@@ -11441,12 +11441,12 @@ snapshots:
|
||||
source-map-js: 1.2.0
|
||||
stylus: 0.62.0
|
||||
tsconfig-paths: 4.2.0
|
||||
typescript: 5.5.2
|
||||
typescript: 5.5.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
typescript@5.5.2: {}
|
||||
typescript@5.5.3: {}
|
||||
|
||||
ufo@1.5.3: {}
|
||||
|
||||
@@ -11591,22 +11591,22 @@ snapshots:
|
||||
sass: 1.77.6
|
||||
vite: 5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0)
|
||||
|
||||
vite-plugin-svgr@4.2.0(rollup@4.17.2)(typescript@5.5.2)(vite@5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0)):
|
||||
vite-plugin-svgr@4.2.0(rollup@4.17.2)(typescript@5.5.3)(vite@5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0)):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.1.0(rollup@4.17.2)
|
||||
'@svgr/core': 8.1.0(typescript@5.5.2)
|
||||
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.5.2))
|
||||
'@svgr/core': 8.1.0(typescript@5.5.3)
|
||||
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.5.3))
|
||||
vite: 5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0)
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
vite-tsconfig-paths@4.3.2(typescript@5.5.2)(vite@5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0)):
|
||||
vite-tsconfig-paths@4.3.2(typescript@5.5.3)(vite@5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0)):
|
||||
dependencies:
|
||||
debug: 4.3.4
|
||||
globrex: 0.1.2
|
||||
tsconfck: 3.0.3(typescript@5.5.2)
|
||||
tsconfck: 3.0.3(typescript@5.5.3)
|
||||
optionalDependencies:
|
||||
vite: 5.3.2(@types/node@20.14.9)(less@4.2.0)(sass@1.77.6)(stylus@0.62.0)
|
||||
transitivePeerDependencies:
|
||||
|
||||
+1
-1
@@ -2,4 +2,4 @@ pnpm install
|
||||
pnpm check $INPUT_TARGET
|
||||
sed -i "s/#openssl/openssl={version=\"0.10\",features=[\"vendored\"]}/g" src-tauri/Cargo.toml
|
||||
|
||||
cargo tauri build --target $INPUT_TARGET
|
||||
pnpm build --target $INPUT_TARGET
|
||||
|
||||
@@ -5,8 +5,6 @@ tar -Jxvf ./node-v20.10.0-linux-x64.tar.xz
|
||||
export PATH=$(pwd)/node-v20.10.0-linux-x64/bin:$PATH
|
||||
npm install pnpm -g
|
||||
|
||||
cargo install --git https://github.com/tauri-apps/tauri --branch 1.x tauri-cli
|
||||
|
||||
rustup target add "$INPUT_TARGET"
|
||||
|
||||
if [ "$INPUT_TARGET" = "x86_64-unknown-linux-gnu" ]; then
|
||||
|
||||
+2
-16
@@ -49,13 +49,6 @@ jobs:
|
||||
cache-all-crates: true
|
||||
cache-on-failure: true
|
||||
|
||||
- name: Install Tauri CLI
|
||||
uses: baptiste0928/cargo-install@v3
|
||||
with:
|
||||
crate: tauri-cli
|
||||
git: https://github.com/tauri-apps/tauri
|
||||
branch: 1.x # `branch` and `commit` are also supported
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
@@ -90,7 +83,7 @@ jobs:
|
||||
releaseBody: "More new features are now supported."
|
||||
releaseDraft: false
|
||||
prerelease: true
|
||||
tauriScript: cargo tauri
|
||||
tauriScript: pnpm
|
||||
args: --target ${{ matrix.target }}
|
||||
|
||||
- name: Portable Bundle
|
||||
@@ -174,13 +167,6 @@ jobs:
|
||||
cache-all-crates: true
|
||||
cache-on-failure: true
|
||||
|
||||
- name: Install Tauri CLI
|
||||
uses: baptiste0928/cargo-install@v3
|
||||
with:
|
||||
crate: tauri-cli
|
||||
git: https://github.com/tauri-apps/tauri
|
||||
branch: 1.x # `branch` and `commit` are also supported
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
@@ -212,7 +198,7 @@ jobs:
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
with:
|
||||
tauriScript: cargo tauri
|
||||
tauriScript: pnpm
|
||||
args: --target ${{ matrix.target }}
|
||||
|
||||
- name: Rename
|
||||
|
||||
+2
-16
@@ -41,13 +41,6 @@ jobs:
|
||||
workspaces: src-tauri
|
||||
cache-all-crates: true
|
||||
|
||||
- name: Install Tauri CLI
|
||||
uses: baptiste0928/cargo-install@v3
|
||||
with:
|
||||
crate: tauri-cli
|
||||
git: https://github.com/tauri-apps/tauri
|
||||
branch: 1.x # `branch` and `commit` are also supported
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
@@ -80,7 +73,7 @@ jobs:
|
||||
tagName: v__VERSION__
|
||||
releaseName: "Clash Verge Rev v__VERSION__"
|
||||
releaseBody: "More new features are now supported."
|
||||
tauriScript: cargo tauri
|
||||
tauriScript: pnpm
|
||||
args: --target ${{ matrix.target }}
|
||||
|
||||
- name: Portable Bundle
|
||||
@@ -160,13 +153,6 @@ jobs:
|
||||
with:
|
||||
workspaces: src-tauri
|
||||
|
||||
- name: Install Tauri CLI
|
||||
uses: baptiste0928/cargo-install@v3
|
||||
with:
|
||||
crate: tauri-cli
|
||||
git: https://github.com/tauri-apps/tauri
|
||||
branch: 1.x # `branch` and `commit` are also supported
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
@@ -198,7 +184,7 @@ jobs:
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
with:
|
||||
tauriScript: cargo tauri
|
||||
tauriScript: pnpm
|
||||
args: --target ${{ matrix.target }}
|
||||
|
||||
- name: Rename
|
||||
|
||||
@@ -1,3 +1,38 @@
|
||||
## v1.7.0
|
||||
|
||||
### Break Changes
|
||||
|
||||
- 此版本重构了 Merge/Script,更新前请先备份好自定义 Merge 和 Script(更新并不会删除配置文件,但是旧版 Merge 和 Script 在更新后无法从前端访问,备份以防万一)
|
||||
- Merge 改名为 `扩展配置`,分为 `全局扩展配置` 和 `订阅扩展配置`,全局扩展配置对所有订阅生效,订阅扩展配置只对关联的订阅生效
|
||||
- Script 改名为 `扩展脚本`,同样分为 `全局扩展脚本` 和 `订阅扩展脚本`
|
||||
- 执行优先级为: 全局扩展配置 -> 全局扩展脚本 -> 订阅扩展配置 ->订阅扩展脚本
|
||||
- MacOS 用户更新后请重新安装服务模式
|
||||
|
||||
### Features
|
||||
|
||||
- 移除内核授权,改为服务模式实现
|
||||
- 自动填充本地订阅名称
|
||||
- 添加重大更新处理逻辑
|
||||
- 订阅单独指定扩展配置/脚本(需要重新导入订阅)
|
||||
- 添加可视化规则编辑器(需要重新导入订阅)
|
||||
- 编辑器新增工具栏按钮(格式化、最大化/最小化)
|
||||
- WEBUI 使用最新版 metacubex,并解决无法自动登陆问问题
|
||||
- 禁用部分 Webview2 快捷键
|
||||
- 热键配置新增连接符 + 号
|
||||
- 新增部分悬浮提示按钮,用于解释说明
|
||||
- 当日志等级为`Debug`时(更改需重启软件生效),支持点击内存主动内存回收(绿色文字)
|
||||
- 设置页面右上角新增 TG 频道链接
|
||||
|
||||
### Bugs Fixes
|
||||
|
||||
- 修复代理绕过格式检查
|
||||
- 通过进程名称关闭进程
|
||||
- 退出软件时恢复 DNS 设置
|
||||
- 修复创建本地订阅时更新间隔无法保存
|
||||
- 连接页面列宽无法调整
|
||||
|
||||
---
|
||||
|
||||
## v1.6.6
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "clash-verge",
|
||||
"version": "1.6.6",
|
||||
"version": "1.7.0",
|
||||
"license": "GPL-3.0-only",
|
||||
"scripts": {
|
||||
"dev": "tauri dev",
|
||||
@@ -24,11 +24,11 @@
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@emotion/styled": "^11.11.5",
|
||||
"@juggle/resize-observer": "^3.4.0",
|
||||
"@mui/icons-material": "^5.15.20",
|
||||
"@mui/icons-material": "^5.15.21",
|
||||
"@mui/lab": "5.0.0-alpha.149",
|
||||
"@mui/material": "^5.15.20",
|
||||
"@mui/x-data-grid": "^7.7.0",
|
||||
"@tauri-apps/api": "^1.5.6",
|
||||
"@mui/material": "^5.15.21",
|
||||
"@mui/x-data-grid": "^7.8.0",
|
||||
"@tauri-apps/api": "^1.6.0",
|
||||
"@types/json-schema": "^7.0.15",
|
||||
"ahooks": "^3.8.0",
|
||||
"axios": "^1.7.2",
|
||||
@@ -37,18 +37,18 @@
|
||||
"i18next": "^23.11.5",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"meta-json-schema": "1.18.5-alpha6",
|
||||
"meta-json-schema": "1.18.6",
|
||||
"monaco-editor": "^0.49.0",
|
||||
"monaco-yaml": "^5.2.0",
|
||||
"nanoid": "^5.0.7",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-error-boundary": "^3.1.4",
|
||||
"react-hook-form": "^7.52.0",
|
||||
"react-hook-form": "^7.52.1",
|
||||
"react-i18next": "^13.5.0",
|
||||
"react-markdown": "^9.0.1",
|
||||
"react-monaco-editor": "^0.55.0",
|
||||
"react-router-dom": "^6.23.1",
|
||||
"react-router-dom": "^6.24.0",
|
||||
"react-transition-group": "^4.4.5",
|
||||
"react-virtuoso": "^4.7.11",
|
||||
"sockette": "^2.0.6",
|
||||
@@ -58,7 +58,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@actions/github": "^5.1.1",
|
||||
"@tauri-apps/cli": "^1.5.14",
|
||||
"@tauri-apps/cli": "^1.6.0",
|
||||
"@types/fs-extra": "^9.0.13",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
@@ -76,10 +76,10 @@
|
||||
"node-fetch": "^3.3.2",
|
||||
"prettier": "^2.8.8",
|
||||
"pretty-quick": "^3.3.1",
|
||||
"sass": "^1.77.5",
|
||||
"sass": "^1.77.6",
|
||||
"terser": "^5.31.1",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.3.1",
|
||||
"typescript": "^5.5.3",
|
||||
"vite": "^5.3.2",
|
||||
"vite-plugin-monaco-editor": "^1.1.0",
|
||||
"vite-plugin-svgr": "^4.2.0"
|
||||
},
|
||||
|
||||
Generated
+192
-191
File diff suppressed because it is too large
Load Diff
Generated
+22
-15
@@ -784,7 +784,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clash-verge"
|
||||
version = "1.6.6"
|
||||
version = "1.7.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"auto-launch",
|
||||
@@ -5442,8 +5442,9 @@ checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
|
||||
|
||||
[[package]]
|
||||
name = "tauri"
|
||||
version = "1.6.7"
|
||||
source = "git+https://github.com/tauri-apps/tauri?branch=1.x#c2d3afa4fbc0e6d118fe002a1b2ba97b4072438a"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e3b2c32de5bf5bed15a376064286643862b84e4e091d093f7bcdf1fda4b9758"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.21.7",
|
||||
@@ -5505,8 +5506,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-build"
|
||||
version = "1.5.2"
|
||||
source = "git+https://github.com/tauri-apps/tauri?branch=1.x#c2d3afa4fbc0e6d118fe002a1b2ba97b4072438a"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0c6ec7a5c3296330c7818478948b422967ce4649094696c985f61d50076d29c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo_toml",
|
||||
@@ -5523,8 +5525,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-codegen"
|
||||
version = "1.4.3"
|
||||
source = "git+https://github.com/tauri-apps/tauri?branch=1.x#c2d3afa4fbc0e6d118fe002a1b2ba97b4072438a"
|
||||
version = "1.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1aed706708ff1200ec12de9cfbf2582b5d8ec05f6a7293911091effbd22036b"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"brotli",
|
||||
@@ -5548,8 +5551,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-macros"
|
||||
version = "1.4.4"
|
||||
source = "git+https://github.com/tauri-apps/tauri?branch=1.x#c2d3afa4fbc0e6d118fe002a1b2ba97b4072438a"
|
||||
version = "1.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b88f831d2973ae4f81a706a0004e67dac87f2e4439973bbe98efbd73825d8ede"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
@@ -5561,8 +5565,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime"
|
||||
version = "0.14.3"
|
||||
source = "git+https://github.com/tauri-apps/tauri?branch=1.x#c2d3afa4fbc0e6d118fe002a1b2ba97b4072438a"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3068ed62b63dedc705558f4248c7ecbd5561f0f8050949859ea0db2326f26012"
|
||||
dependencies = [
|
||||
"gtk",
|
||||
"http 0.2.12",
|
||||
@@ -5581,8 +5586,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime-wry"
|
||||
version = "0.14.8"
|
||||
source = "git+https://github.com/tauri-apps/tauri?branch=1.x#c2d3afa4fbc0e6d118fe002a1b2ba97b4072438a"
|
||||
version = "0.14.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4c3db170233096aa30330feadcd895bf9317be97e624458560a20e814db7955"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"cocoa 0.24.1",
|
||||
@@ -5601,8 +5607,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-utils"
|
||||
version = "1.5.4"
|
||||
source = "git+https://github.com/tauri-apps/tauri?branch=1.x#c2d3afa4fbc0e6d118fe002a1b2ba97b4072438a"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2826db448309d382dac14d520f0c0a40839b87b57b977e59cf5f296b3ace6a93"
|
||||
dependencies = [
|
||||
"brotli",
|
||||
"ctor",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "clash-verge"
|
||||
version = "1.6.6"
|
||||
version = "1.7.0"
|
||||
description = "clash verge"
|
||||
authors = ["zzzgydi", "wonfen", "MystiPanda"]
|
||||
license = "GPL-3.0-only"
|
||||
@@ -10,7 +10,7 @@ edition = "2021"
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { git="https://github.com/tauri-apps/tauri",branch = "1.x", features = [] }
|
||||
tauri-build = { version="1", features = [] }
|
||||
|
||||
[dependencies]
|
||||
warp = "0.3"
|
||||
@@ -37,7 +37,7 @@ tokio = { version = "1", features = ["full"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
reqwest = { version = "0.12", features = ["json", "rustls-tls"] }
|
||||
sysproxy = { git="https://github.com/zzzgydi/sysproxy-rs", branch = "main" }
|
||||
tauri = { git="https://github.com/tauri-apps/tauri",branch = "1.x", features = [ "fs-read-file", "fs-exists", "path-all", "protocol-asset", "dialog-open", "notification-all", "icon-png", "icon-ico", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all", "devtools"] }
|
||||
tauri = { version="1", features = [ "fs-read-file", "fs-exists", "path-all", "protocol-asset", "dialog-open", "notification-all", "icon-png", "icon-ico", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all", "devtools"] }
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
runas = "=1.2.0"
|
||||
deelevate = "0.2.0"
|
||||
|
||||
@@ -428,8 +428,10 @@ impl PrfItem {
|
||||
/// create the enhanced item by using `merge` rule
|
||||
pub fn from_merge(uid: Option<String>) -> Result<PrfItem> {
|
||||
let mut id = help::get_uid("m");
|
||||
let mut template = tmpl::ITEM_MERGE_EMPTY.into();
|
||||
if let Some(uid) = uid {
|
||||
id = uid;
|
||||
template = tmpl::ITEM_MERGE.into();
|
||||
}
|
||||
let file = format!("{id}.yaml");
|
||||
|
||||
@@ -445,7 +447,7 @@ impl PrfItem {
|
||||
option: None,
|
||||
home: None,
|
||||
updated: Some(chrono::Local::now().timestamp() as usize),
|
||||
file_data: Some(tmpl::ITEM_MERGE.into()),
|
||||
file_data: Some(template),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -138,8 +138,28 @@ pub async fn enhance() -> (Mapping, Vec<String>, HashMap<String, ResultLog>) {
|
||||
let mut result_map = HashMap::new(); // 保存脚本日志
|
||||
let mut exists_keys = use_keys(&config); // 保存出现过的keys
|
||||
|
||||
// 处理用户的profile
|
||||
// 全局Merge和Script
|
||||
if let ChainType::Merge(merge) = global_merge.data {
|
||||
exists_keys.extend(use_keys(&merge));
|
||||
config = use_merge(merge, config.to_owned());
|
||||
}
|
||||
|
||||
if let ChainType::Script(script) = global_script.data {
|
||||
let mut logs = vec![];
|
||||
|
||||
match use_script(script, config.to_owned()) {
|
||||
Ok((res_config, res_logs)) => {
|
||||
exists_keys.extend(use_keys(&res_config));
|
||||
config = res_config;
|
||||
logs.extend(res_logs);
|
||||
}
|
||||
Err(err) => logs.push(("exception".into(), err.to_string())),
|
||||
}
|
||||
|
||||
result_map.insert(global_script.uid, logs);
|
||||
}
|
||||
|
||||
// 订阅关联的Merge、Script、Rules、Proxies、Groups
|
||||
if let ChainType::Rules(rules) = rules_item.data {
|
||||
config = use_seq(rules, config.to_owned(), "rules");
|
||||
}
|
||||
@@ -172,27 +192,6 @@ pub async fn enhance() -> (Mapping, Vec<String>, HashMap<String, ResultLog>) {
|
||||
result_map.insert(script_item.uid, logs);
|
||||
}
|
||||
|
||||
// 全局Merge和Script
|
||||
if let ChainType::Merge(merge) = global_merge.data {
|
||||
exists_keys.extend(use_keys(&merge));
|
||||
config = use_merge(merge, config.to_owned());
|
||||
}
|
||||
|
||||
if let ChainType::Script(script) = global_script.data {
|
||||
let mut logs = vec![];
|
||||
|
||||
match use_script(script, config.to_owned()) {
|
||||
Ok((res_config, res_logs)) => {
|
||||
exists_keys.extend(use_keys(&res_config));
|
||||
config = res_config;
|
||||
logs.extend(res_logs);
|
||||
}
|
||||
Err(err) => logs.push(("exception".into(), err.to_string())),
|
||||
}
|
||||
|
||||
result_map.insert(global_script.uid, logs);
|
||||
}
|
||||
|
||||
// 合并默认的config
|
||||
for (key, value) in clash_config.into_iter() {
|
||||
if key.as_str() == Some("tun") {
|
||||
|
||||
@@ -15,6 +15,13 @@ pub const ITEM_MERGE: &str = "# Profile Enhancement Merge Template for Clash Ver
|
||||
|
||||
profile:
|
||||
store-selected: true
|
||||
|
||||
dns:
|
||||
use-system-hosts: false
|
||||
";
|
||||
|
||||
pub const ITEM_MERGE_EMPTY: &str = "# Profile Enhancement Merge Template for Clash Verge
|
||||
|
||||
";
|
||||
|
||||
/// enhanced profile
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||
"package": {
|
||||
"productName": "Clash Verge",
|
||||
"version": "1.6.6"
|
||||
"version": "1.7.0"
|
||||
},
|
||||
"build": {
|
||||
"distDir": "../dist",
|
||||
|
||||
@@ -9,6 +9,9 @@ import useRegularExpressionIcon from "@/assets/image/component/use_regular_expre
|
||||
|
||||
type SearchProps = {
|
||||
placeholder?: string;
|
||||
matchCase?: boolean;
|
||||
matchWholeWord?: boolean;
|
||||
useRegularExpression?: boolean;
|
||||
onSearch: (
|
||||
match: (content: string) => boolean,
|
||||
state: {
|
||||
@@ -23,9 +26,13 @@ type SearchProps = {
|
||||
export const BaseSearchBox = styled((props: SearchProps) => {
|
||||
const { t } = useTranslation();
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const [matchCase, setMatchCase] = useState(true);
|
||||
const [matchWholeWord, setMatchWholeWord] = useState(false);
|
||||
const [useRegularExpression, setUseRegularExpression] = useState(false);
|
||||
const [matchCase, setMatchCase] = useState(props.matchCase ?? true);
|
||||
const [matchWholeWord, setMatchWholeWord] = useState(
|
||||
props.matchWholeWord ?? false
|
||||
);
|
||||
const [useRegularExpression, setUseRegularExpression] = useState(
|
||||
props.useRegularExpression ?? false
|
||||
);
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
|
||||
const iconStyle = {
|
||||
@@ -89,11 +96,11 @@ export const BaseSearchBox = styled((props: SearchProps) => {
|
||||
return (
|
||||
<Tooltip title={errorMessage} placement="bottom-start">
|
||||
<TextField
|
||||
autoComplete="off"
|
||||
inputRef={inputRef}
|
||||
hiddenLabel
|
||||
fullWidth
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
variant="outlined"
|
||||
spellCheck="false"
|
||||
placeholder={props.placeholder ?? t("Filter conditions")}
|
||||
|
||||
@@ -6,10 +6,10 @@ export const BaseStyledTextField = styled((props: TextFieldProps) => {
|
||||
|
||||
return (
|
||||
<TextField
|
||||
autoComplete="off"
|
||||
hiddenLabel
|
||||
fullWidth
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
variant="outlined"
|
||||
spellCheck="false"
|
||||
placeholder={t("Filter conditions")}
|
||||
|
||||
@@ -1,184 +1,235 @@
|
||||
import { ReactNode, useEffect, useRef } from "react";
|
||||
import { ReactNode, useEffect, useRef, useState } from "react";
|
||||
import { useLockFn } from "ahooks";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
IconButton,
|
||||
} from "@mui/material";
|
||||
import FormatPaintIcon from "@mui/icons-material/FormatPaint";
|
||||
import OpenInFullIcon from "@mui/icons-material/OpenInFull";
|
||||
import CloseFullscreenIcon from "@mui/icons-material/CloseFullscreen";
|
||||
import { useThemeMode } from "@/services/states";
|
||||
import { readProfileFile, saveProfileFile } from "@/services/cmds";
|
||||
import { Notice } from "@/components/base";
|
||||
import { nanoid } from "nanoid";
|
||||
import { appWindow } from "@tauri-apps/api/window";
|
||||
import getSystem from "@/utils/get-system";
|
||||
|
||||
import * as monaco from "monaco-editor";
|
||||
import { editor } from "monaco-editor/esm/vs/editor/editor.api";
|
||||
import MonacoEditor from "react-monaco-editor";
|
||||
import { configureMonacoYaml } from "monaco-yaml";
|
||||
|
||||
import { type JSONSchema7 } from "json-schema";
|
||||
import metaSchema from "meta-json-schema/schemas/meta-json-schema.json";
|
||||
import mergeSchema from "meta-json-schema/schemas/clash-verge-merge-json-schema.json";
|
||||
import pac from "types-pac/pac.d.ts?raw";
|
||||
|
||||
interface Props {
|
||||
title?: string | ReactNode;
|
||||
mode: "profile" | "text";
|
||||
property: string;
|
||||
open: boolean;
|
||||
readOnly?: boolean;
|
||||
language: "yaml" | "javascript" | "css";
|
||||
schema?: "clash" | "merge";
|
||||
onClose: () => void;
|
||||
onChange?: (prev?: string, curr?: string) => void;
|
||||
type Language = "yaml" | "javascript" | "css";
|
||||
type Schema<T extends Language> = LanguageSchemaMap[T];
|
||||
interface LanguageSchemaMap {
|
||||
yaml: "clash" | "merge";
|
||||
javascript: never;
|
||||
css: never;
|
||||
}
|
||||
|
||||
// yaml worker
|
||||
configureMonacoYaml(monaco, {
|
||||
validate: true,
|
||||
enableSchemaRequest: true,
|
||||
schemas: [
|
||||
{
|
||||
uri: "http://example.com/meta-json-schema.json",
|
||||
fileMatch: ["**/*.clash.yaml"],
|
||||
//@ts-ignore
|
||||
schema: metaSchema as JSONSchema7,
|
||||
},
|
||||
{
|
||||
uri: "http://example.com/clash-verge-merge-json-schema.json",
|
||||
fileMatch: ["**/*.merge.yaml"],
|
||||
//@ts-ignore
|
||||
schema: mergeSchema as JSONSchema7,
|
||||
},
|
||||
],
|
||||
});
|
||||
// PAC definition
|
||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(pac, "pac.d.ts");
|
||||
monaco.languages.registerCompletionItemProvider("javascript", {
|
||||
provideCompletionItems: (model, position) => ({
|
||||
suggestions: [
|
||||
interface Props<T extends Language> {
|
||||
open: boolean;
|
||||
title?: string | ReactNode;
|
||||
initialData: Promise<string>;
|
||||
readOnly?: boolean;
|
||||
language: T;
|
||||
schema?: Schema<T>;
|
||||
onChange?: (prev?: string, curr?: string) => void;
|
||||
onSave?: (prev?: string, curr?: string) => void;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
let initialized = false;
|
||||
const monacoInitialization = () => {
|
||||
if (initialized) return;
|
||||
|
||||
// configure yaml worker
|
||||
configureMonacoYaml(monaco, {
|
||||
validate: true,
|
||||
enableSchemaRequest: true,
|
||||
schemas: [
|
||||
{
|
||||
label: "%mixed-port%",
|
||||
kind: monaco.languages.CompletionItemKind.Text,
|
||||
insertText: "%mixed-port%",
|
||||
range: {
|
||||
startLineNumber: position.lineNumber,
|
||||
endLineNumber: position.lineNumber,
|
||||
startColumn: model.getWordUntilPosition(position).startColumn - 1,
|
||||
endColumn: model.getWordUntilPosition(position).endColumn - 1,
|
||||
},
|
||||
uri: "http://example.com/meta-json-schema.json",
|
||||
fileMatch: ["**/*.clash.yaml"],
|
||||
// @ts-ignore
|
||||
schema: metaSchema as JSONSchema7,
|
||||
},
|
||||
{
|
||||
uri: "http://example.com/clash-verge-merge-json-schema.json",
|
||||
fileMatch: ["**/*.merge.yaml"],
|
||||
// @ts-ignore
|
||||
schema: mergeSchema as JSONSchema7,
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
});
|
||||
// configure PAC definition
|
||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(pac, "pac.d.ts");
|
||||
|
||||
export const EditorViewer = (props: Props) => {
|
||||
const {
|
||||
title,
|
||||
mode,
|
||||
property,
|
||||
open,
|
||||
readOnly,
|
||||
language,
|
||||
schema,
|
||||
onClose,
|
||||
onChange,
|
||||
} = props;
|
||||
initialized = true;
|
||||
};
|
||||
|
||||
export const EditorViewer = <T extends Language>(props: Props<T>) => {
|
||||
const { t } = useTranslation();
|
||||
const editorRef = useRef<any>();
|
||||
const instanceRef = useRef<editor.IStandaloneCodeEditor | null>(null);
|
||||
const themeMode = useThemeMode();
|
||||
const prevData = useRef<string>();
|
||||
const [isMaximized, setIsMaximized] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
const {
|
||||
open = false,
|
||||
title = t("Edit File"),
|
||||
initialData = Promise.resolve(""),
|
||||
readOnly = false,
|
||||
language = "yaml",
|
||||
schema,
|
||||
onChange,
|
||||
onSave,
|
||||
onClose,
|
||||
} = props;
|
||||
|
||||
let fetchContent;
|
||||
switch (mode) {
|
||||
case "profile": // profile文件
|
||||
fetchContent = readProfileFile(property);
|
||||
break;
|
||||
case "text": // 文本内容
|
||||
fetchContent = Promise.resolve(property);
|
||||
break;
|
||||
}
|
||||
fetchContent.then((data) => {
|
||||
const dom = editorRef.current;
|
||||
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>();
|
||||
const prevData = useRef<string | undefined>("");
|
||||
const currData = useRef<string | undefined>("");
|
||||
|
||||
if (!dom) return;
|
||||
const editorWillMount = () => {
|
||||
monacoInitialization(); // initialize monaco
|
||||
};
|
||||
|
||||
if (instanceRef.current) instanceRef.current.dispose();
|
||||
const editorDidMount = async (
|
||||
editor: monaco.editor.IStandaloneCodeEditor
|
||||
) => {
|
||||
editorRef.current = editor;
|
||||
|
||||
// retrieve initial data
|
||||
await initialData.then((data) => {
|
||||
prevData.current = data;
|
||||
currData.current = data;
|
||||
|
||||
// create and set model
|
||||
const uri = monaco.Uri.parse(`${nanoid()}.${schema}.${language}`);
|
||||
const model = monaco.editor.createModel(data, language, uri);
|
||||
instanceRef.current = editor.create(editorRef.current, {
|
||||
model: model,
|
||||
language: language,
|
||||
tabSize: ["yaml", "javascript", "css"].includes(language) ? 2 : 4, // 根据语言类型设置缩进大小
|
||||
theme: themeMode === "light" ? "vs" : "vs-dark",
|
||||
minimap: { enabled: dom.clientWidth >= 1000 }, // 超过一定宽度显示minimap滚动条
|
||||
mouseWheelZoom: true, // 按住Ctrl滚轮调节缩放比例
|
||||
readOnly: readOnly, // 只读模式
|
||||
readOnlyMessage: { value: t("ReadOnlyMessage") }, // 只读模式尝试编辑时的提示信息
|
||||
renderValidationDecorations: "on", // 只读模式下显示校验信息
|
||||
quickSuggestions: {
|
||||
strings: true, // 字符串类型的建议
|
||||
comments: true, // 注释类型的建议
|
||||
other: true, // 其他类型的建议
|
||||
},
|
||||
padding: {
|
||||
top: 33, // 顶部padding防止遮挡snippets
|
||||
},
|
||||
fontFamily: `Fira Code, JetBrains Mono, Roboto Mono, "Source Code Pro", Consolas, Menlo, Monaco, monospace, "Courier New", "Apple Color Emoji"${
|
||||
getSystem() === "windows" ? ", twemoji mozilla" : ""
|
||||
}`,
|
||||
fontLigatures: true, // 连字符
|
||||
smoothScrolling: true, // 平滑滚动
|
||||
});
|
||||
|
||||
prevData.current = data;
|
||||
editorRef.current?.setModel(model);
|
||||
});
|
||||
};
|
||||
|
||||
return () => {
|
||||
if (instanceRef.current) {
|
||||
instanceRef.current.dispose();
|
||||
instanceRef.current = null;
|
||||
}
|
||||
};
|
||||
}, [open]);
|
||||
|
||||
const onSave = useLockFn(async () => {
|
||||
const currData = instanceRef.current?.getValue();
|
||||
|
||||
if (currData == null) return;
|
||||
|
||||
const handleChange = useLockFn(async (value: string | undefined) => {
|
||||
try {
|
||||
if (mode === "profile") {
|
||||
await saveProfileFile(property, currData);
|
||||
}
|
||||
onChange?.(prevData.current, currData);
|
||||
currData.current = value;
|
||||
onChange?.(prevData.current, currData.current);
|
||||
} catch (err: any) {
|
||||
Notice.error(err.message || err.toString());
|
||||
}
|
||||
});
|
||||
|
||||
const handleSave = useLockFn(async () => {
|
||||
try {
|
||||
!readOnly && onSave?.(prevData.current, currData.current);
|
||||
onClose();
|
||||
} catch (err: any) {
|
||||
Notice.error(err.message || err.toString());
|
||||
}
|
||||
});
|
||||
|
||||
const handleClose = useLockFn(async () => {
|
||||
try {
|
||||
onClose();
|
||||
} catch (err: any) {
|
||||
Notice.error(err.message || err.toString());
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const unlistenResized = appWindow.onResized(() => {
|
||||
appWindow.isMaximized().then((maximized) => {
|
||||
setIsMaximized(() => maximized);
|
||||
});
|
||||
});
|
||||
|
||||
return () => {
|
||||
unlistenResized.then((fn) => fn());
|
||||
editorRef.current?.dispose();
|
||||
editorRef.current = undefined;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={onClose} maxWidth="xl" fullWidth>
|
||||
<DialogTitle>{title ?? t("Edit File")}</DialogTitle>
|
||||
<DialogTitle>{title}</DialogTitle>
|
||||
|
||||
<DialogContent sx={{ width: "auto", height: "100vh" }}>
|
||||
<div style={{ width: "100%", height: "100%" }} ref={editorRef} />
|
||||
<MonacoEditor
|
||||
language={language}
|
||||
theme={themeMode === "light" ? "vs" : "vs-dark"}
|
||||
options={{
|
||||
tabSize: ["yaml", "javascript", "css"].includes(language) ? 2 : 4, // 根据语言类型设置缩进大小
|
||||
minimap: {
|
||||
enabled: document.documentElement.clientWidth >= 1500, // 超过一定宽度显示minimap滚动条
|
||||
},
|
||||
mouseWheelZoom: true, // 按住Ctrl滚轮调节缩放比例
|
||||
readOnly: readOnly, // 只读模式
|
||||
readOnlyMessage: { value: t("ReadOnlyMessage") }, // 只读模式尝试编辑时的提示信息
|
||||
renderValidationDecorations: "on", // 只读模式下显示校验信息
|
||||
quickSuggestions: {
|
||||
strings: true, // 字符串类型的建议
|
||||
comments: true, // 注释类型的建议
|
||||
other: true, // 其他类型的建议
|
||||
},
|
||||
padding: {
|
||||
top: 33, // 顶部padding防止遮挡snippets
|
||||
},
|
||||
fontFamily: `Fira Code, JetBrains Mono, Roboto Mono, "Source Code Pro", Consolas, Menlo, Monaco, monospace, "Courier New", "Apple Color Emoji"${
|
||||
getSystem() === "windows" ? ", twemoji mozilla" : ""
|
||||
}`,
|
||||
fontLigatures: true, // 连字符
|
||||
smoothScrolling: true, // 平滑滚动
|
||||
}}
|
||||
editorWillMount={editorWillMount}
|
||||
editorDidMount={editorDidMount}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
|
||||
<ButtonGroup
|
||||
variant="contained"
|
||||
sx={{ position: "absolute", left: "14px", bottom: "8px" }}
|
||||
>
|
||||
<IconButton
|
||||
size="medium"
|
||||
color="inherit"
|
||||
sx={{ display: readOnly ? "none" : "" }}
|
||||
title={t("Format document")}
|
||||
onClick={() =>
|
||||
editorRef.current
|
||||
?.getAction("editor.action.formatDocument")
|
||||
?.run()
|
||||
}
|
||||
>
|
||||
<FormatPaintIcon fontSize="inherit" />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
size="medium"
|
||||
color="inherit"
|
||||
title={t(isMaximized ? "Minimize" : "Maximize")}
|
||||
onClick={() =>
|
||||
appWindow.toggleMaximize().then(() => editorRef.current?.layout())
|
||||
}
|
||||
>
|
||||
{isMaximized ? <CloseFullscreenIcon /> : <OpenInFullIcon />}
|
||||
</IconButton>
|
||||
</ButtonGroup>
|
||||
</DialogContent>
|
||||
|
||||
<DialogActions>
|
||||
<Button onClick={onClose} variant="outlined">
|
||||
<Button onClick={handleClose} variant="outlined">
|
||||
{t(readOnly ? "Close" : "Cancel")}
|
||||
</Button>
|
||||
{!readOnly && (
|
||||
<Button onClick={onSave} variant="contained">
|
||||
<Button onClick={handleSave} variant="contained">
|
||||
{t("Save")}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -17,7 +17,12 @@ import {
|
||||
} from "@mui/material";
|
||||
import { RefreshRounded, DragIndicator } from "@mui/icons-material";
|
||||
import { useLoadingCache, useSetLoadingCache } from "@/services/states";
|
||||
import { updateProfile, viewProfile } from "@/services/cmds";
|
||||
import {
|
||||
viewProfile,
|
||||
readProfileFile,
|
||||
updateProfile,
|
||||
saveProfileFile,
|
||||
} from "@/services/cmds";
|
||||
import { Notice } from "@/components/base";
|
||||
import { RulesEditorViewer } from "@/components/profile/rules-editor-viewer";
|
||||
import { EditorViewer } from "@/components/profile/editor-viewer";
|
||||
@@ -37,20 +42,13 @@ interface Props {
|
||||
itemData: IProfileItem;
|
||||
onSelect: (force: boolean) => void;
|
||||
onEdit: () => void;
|
||||
onChange?: (prev?: string, curr?: string) => void;
|
||||
onSave?: (prev?: string, curr?: string) => void;
|
||||
onDelete: () => void;
|
||||
}
|
||||
|
||||
export const ProfileItem = (props: Props) => {
|
||||
const {
|
||||
selected,
|
||||
activating,
|
||||
itemData,
|
||||
onSelect,
|
||||
onEdit,
|
||||
onChange,
|
||||
onDelete,
|
||||
} = props;
|
||||
const { selected, activating, itemData, onSelect, onEdit, onSave, onDelete } =
|
||||
props;
|
||||
const { attributes, listeners, setNodeRef, transform, transition } =
|
||||
useSortable({ id: props.id });
|
||||
|
||||
@@ -215,16 +213,16 @@ export const ProfileItem = (props: Props) => {
|
||||
handler: onEditRules,
|
||||
disabled: option?.rules === null,
|
||||
},
|
||||
{
|
||||
label: "Edit Proxies",
|
||||
handler: onEditProxies,
|
||||
disabled: option?.proxies === null,
|
||||
},
|
||||
{
|
||||
label: "Edit Groups",
|
||||
handler: onEditGroups,
|
||||
disabled: option?.groups === null,
|
||||
},
|
||||
// {
|
||||
// label: "Edit Proxies",
|
||||
// handler: onEditProxies,
|
||||
// disabled: option?.proxies === null,
|
||||
// },
|
||||
// {
|
||||
// label: "Edit Groups",
|
||||
// handler: onEditGroups,
|
||||
// disabled: option?.groups === null,
|
||||
// },
|
||||
{
|
||||
label: "Extend Config",
|
||||
handler: onEditMerge,
|
||||
@@ -256,16 +254,16 @@ export const ProfileItem = (props: Props) => {
|
||||
handler: onEditRules,
|
||||
disabled: option?.rules === null,
|
||||
},
|
||||
{
|
||||
label: "Edit Proxies",
|
||||
handler: onEditProxies,
|
||||
disabled: option?.proxies === null,
|
||||
},
|
||||
{
|
||||
label: "Edit Groups",
|
||||
handler: onEditGroups,
|
||||
disabled: option?.groups === null,
|
||||
},
|
||||
// {
|
||||
// label: "Edit Proxies",
|
||||
// handler: onEditProxies,
|
||||
// disabled: option?.proxies === null,
|
||||
// },
|
||||
// {
|
||||
// label: "Edit Groups",
|
||||
// handler: onEditGroups,
|
||||
// disabled: option?.groups === null,
|
||||
// },
|
||||
{
|
||||
label: "Extend Config",
|
||||
handler: onEditMerge,
|
||||
@@ -474,55 +472,62 @@ export const ProfileItem = (props: Props) => {
|
||||
</Menu>
|
||||
|
||||
<EditorViewer
|
||||
mode="profile"
|
||||
property={uid}
|
||||
open={fileOpen}
|
||||
initialData={readProfileFile(uid)}
|
||||
language="yaml"
|
||||
schema="clash"
|
||||
onChange={onChange}
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(uid, curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setFileOpen(false)}
|
||||
/>
|
||||
<RulesEditorViewer
|
||||
profileUid={uid}
|
||||
property={option?.rules ?? ""}
|
||||
open={rulesOpen}
|
||||
onChange={onChange}
|
||||
onSave={onSave}
|
||||
onClose={() => setRulesOpen(false)}
|
||||
/>
|
||||
<EditorViewer
|
||||
mode="profile"
|
||||
property={option?.proxies ?? ""}
|
||||
open={proxiesOpen}
|
||||
initialData={readProfileFile(option?.proxies ?? "")}
|
||||
language="yaml"
|
||||
schema={undefined}
|
||||
onChange={onChange}
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(option?.proxies ?? "", curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setProxiesOpen(false)}
|
||||
/>
|
||||
<EditorViewer
|
||||
mode="profile"
|
||||
property={option?.groups ?? ""}
|
||||
open={groupsOpen}
|
||||
initialData={readProfileFile(option?.proxies ?? "")}
|
||||
language="yaml"
|
||||
schema={undefined}
|
||||
onChange={onChange}
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(option?.proxies ?? "", curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setGroupsOpen(false)}
|
||||
/>
|
||||
<EditorViewer
|
||||
mode="profile"
|
||||
property={option?.merge ?? ""}
|
||||
open={mergeOpen}
|
||||
initialData={readProfileFile(option?.merge ?? "")}
|
||||
language="yaml"
|
||||
schema="merge"
|
||||
onChange={onChange}
|
||||
schema="clash"
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(option?.merge ?? "", curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setMergeOpen(false)}
|
||||
/>
|
||||
<EditorViewer
|
||||
mode="profile"
|
||||
property={option?.script ?? ""}
|
||||
open={scriptOpen}
|
||||
initialData={readProfileFile(option?.script ?? "")}
|
||||
language="javascript"
|
||||
schema={undefined}
|
||||
onChange={onChange}
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(option?.script ?? "", curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setScriptOpen(false)}
|
||||
/>
|
||||
<ConfirmViewer
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
IconButton,
|
||||
} from "@mui/material";
|
||||
import { FeaturedPlayListRounded } from "@mui/icons-material";
|
||||
import { viewProfile } from "@/services/cmds";
|
||||
import { viewProfile, readProfileFile, saveProfileFile } from "@/services/cmds";
|
||||
import { Notice } from "@/components/base";
|
||||
import { EditorViewer } from "@/components/profile/editor-viewer";
|
||||
import { ProfileBox } from "./profile-box";
|
||||
@@ -20,14 +20,14 @@ import { LogViewer } from "./log-viewer";
|
||||
interface Props {
|
||||
logInfo?: [string, string][];
|
||||
id: "Merge" | "Script";
|
||||
onChange?: (prev?: string, curr?: string) => void;
|
||||
onSave?: (prev?: string, curr?: string) => void;
|
||||
}
|
||||
|
||||
// profile enhanced item
|
||||
export const ProfileMore = (props: Props) => {
|
||||
const { id, logInfo = [], onChange } = props;
|
||||
const { id, logInfo = [], onSave } = props;
|
||||
|
||||
const { t, i18n } = useTranslation();
|
||||
const { t } = useTranslation();
|
||||
const [anchorEl, setAnchorEl] = useState<any>(null);
|
||||
const [position, setPosition] = useState({ left: 0, top: 0 });
|
||||
const [fileOpen, setFileOpen] = useState(false);
|
||||
@@ -169,12 +169,15 @@ export const ProfileMore = (props: Props) => {
|
||||
</Menu>
|
||||
|
||||
<EditorViewer
|
||||
mode="profile"
|
||||
property={id}
|
||||
open={fileOpen}
|
||||
title={`${t("Global " + id)}`}
|
||||
initialData={readProfileFile(id)}
|
||||
language={id === "Merge" ? "yaml" : "javascript"}
|
||||
schema={id === "Merge" ? "merge" : undefined}
|
||||
onChange={onChange}
|
||||
schema={id === "Merge" ? "clash" : undefined}
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(id, curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setFileOpen(false)}
|
||||
/>
|
||||
|
||||
|
||||
@@ -46,10 +46,14 @@ export const RuleItem = (props: Props) => {
|
||||
primary={
|
||||
<>
|
||||
<Typography
|
||||
sx={{ textDecoration: type === "delete" ? "line-through" : "" }}
|
||||
sx={{
|
||||
textDecoration: type === "delete" ? "line-through" : "",
|
||||
overflow: "hidden",
|
||||
whiteSpace: "nowrap",
|
||||
textOverflow: "ellipsis",
|
||||
}}
|
||||
variant="h6"
|
||||
component="span"
|
||||
noWrap
|
||||
title={rule.length === 3 ? rule[1] : "-"}
|
||||
>
|
||||
{rule.length === 3 ? rule[1] : "-"}
|
||||
</Typography>
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
} from "@dnd-kit/sortable";
|
||||
import {
|
||||
Autocomplete,
|
||||
Box,
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
@@ -33,6 +34,8 @@ import { readProfileFile, saveProfileFile } from "@/services/cmds";
|
||||
import { Notice, Switch } from "@/components/base";
|
||||
import getSystem from "@/utils/get-system";
|
||||
import { RuleItem } from "@/components/profile/rule-item";
|
||||
import { BaseSearchBox } from "../base/base-search-box";
|
||||
import { Virtuoso } from "react-virtuoso";
|
||||
|
||||
interface Props {
|
||||
profileUid: string;
|
||||
@@ -40,103 +43,201 @@ interface Props {
|
||||
property: string;
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onChange?: (prev?: string, curr?: string) => void;
|
||||
onSave?: (prev?: string, curr?: string) => void;
|
||||
}
|
||||
|
||||
const RuleTypeList = [
|
||||
"DOMAIN",
|
||||
"DOMAIN-SUFFIX",
|
||||
"DOMAIN-KEYWORD",
|
||||
"DOMAIN-REGEX",
|
||||
"GEOSITE",
|
||||
"IP-CIDR",
|
||||
"IP-SUFFIX",
|
||||
"IP-ASN",
|
||||
"GEOIP",
|
||||
"SRC-GEOIP",
|
||||
"SRC-IP-ASN",
|
||||
"SRC-IP-CIDR",
|
||||
"SRC-IP-SUFFIX",
|
||||
"DST-PORT",
|
||||
"SRC-PORT",
|
||||
"IN-PORT",
|
||||
"IN-TYPE",
|
||||
"IN-USER",
|
||||
"IN-NAME",
|
||||
"PROCESS-PATH",
|
||||
"PROCESS-PATH-REGEX",
|
||||
"PROCESS-NAME",
|
||||
"PROCESS-NAME-REGEX",
|
||||
"UID",
|
||||
"NETWORK",
|
||||
"DSCP",
|
||||
"RULE-SET",
|
||||
"SUB-RULE",
|
||||
"AND",
|
||||
"OR",
|
||||
"NOT",
|
||||
"MATCH",
|
||||
] as const;
|
||||
|
||||
const NoResolveList = [
|
||||
"GEOIP",
|
||||
"IP-ASN",
|
||||
"IP-CIDR",
|
||||
"IP-CIDR6",
|
||||
"IP-SUFFIX",
|
||||
"RULE-SET",
|
||||
];
|
||||
const ExampleMap = {
|
||||
DOMAIN: "example.com",
|
||||
"DOMAIN-SUFFIX": "example.com",
|
||||
"DOMAIN-KEYWORD": "example",
|
||||
"DOMAIN-REGEX": "example.*",
|
||||
GEOSITE: "youtube",
|
||||
"IP-CIDR": "127.0.0.0/8",
|
||||
"IP-SUFFIX": "8.8.8.8/24",
|
||||
"IP-ASN": "13335",
|
||||
GEOIP: "CN",
|
||||
"SRC-GEOIP": "cn",
|
||||
"SRC-IP-ASN": "9808",
|
||||
"SRC-IP-CIDR": "192.168.1.201/32",
|
||||
"SRC-IP-SUFFIX": "192.168.1.201/8",
|
||||
"DST-PORT": "80",
|
||||
"SRC-PORT": "7777",
|
||||
"IN-PORT": "7890",
|
||||
"IN-TYPE": "SOCKS/HTTP",
|
||||
"IN-USER": "mihomo",
|
||||
"IN-NAME": "ss",
|
||||
"PROCESS-PATH":
|
||||
getSystem() === "windows"
|
||||
? "C:Program FilesGoogleChromeApplicationchrome.exe"
|
||||
: "/usr/bin/wget",
|
||||
"PROCESS-PATH-REGEX":
|
||||
getSystem() === "windows" ? "(?i).*Application\\chrome.*" : ".*bin/wget",
|
||||
"PROCESS-NAME": getSystem() === "windows" ? "chrome.exe" : "curl",
|
||||
"PROCESS-NAME-REGEX": ".*telegram.*",
|
||||
UID: "1001",
|
||||
NETWORK: "udp",
|
||||
DSCP: "4",
|
||||
"RULE-SET": "providername",
|
||||
"SUB-RULE": "",
|
||||
AND: "((DOMAIN,baidu.com),(NETWORK,UDP))",
|
||||
OR: "((NETWORK,UDP),(DOMAIN,baidu.com))",
|
||||
NOT: "((DOMAIN,baidu.com))",
|
||||
MATCH: "",
|
||||
const portValidator = (value: string): boolean => {
|
||||
return new RegExp(
|
||||
"^(?:[1-9]\\d{0,3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])$"
|
||||
).test(value);
|
||||
};
|
||||
const ipv4CIDRValidator = (value: string): boolean => {
|
||||
return new RegExp(
|
||||
"^(?:(?:[1-9]?[0-9]|1[0-9][0-9]|2(?:[0-4][0-9]|5[0-5]))\\.){3}(?:[1-9]?[0-9]|1[0-9][0-9]|2(?:[0-4][0-9]|5[0-5]))(?:\\/(?:[12]?[0-9]|3[0-2]))$"
|
||||
).test(value);
|
||||
};
|
||||
const ipv6CIDRValidator = (value: string): boolean => {
|
||||
return new RegExp(
|
||||
"^([0-9a-fA-F]{1,4}(?::[0-9a-fA-F]{1,4}){7}|::|:(?::[0-9a-fA-F]{1,4}){1,6}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,5}|(?:[0-9a-fA-F]{1,4}:){2}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){3}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){4}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){5}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,6}:)\\/(?:12[0-8]|1[01][0-9]|[1-9]?[0-9])$"
|
||||
).test(value);
|
||||
};
|
||||
|
||||
const BuiltinProxyPolicyList = ["DIRECT", "REJECT", "REJECT-DROP", "PASS"];
|
||||
const rules: {
|
||||
name: string;
|
||||
required?: boolean;
|
||||
example?: string;
|
||||
noResolve?: boolean;
|
||||
validator?: (value: string) => boolean;
|
||||
}[] = [
|
||||
{
|
||||
name: "DOMAIN",
|
||||
example: "example.com",
|
||||
},
|
||||
{
|
||||
name: "DOMAIN-SUFFIX",
|
||||
example: "example.com",
|
||||
},
|
||||
{
|
||||
name: "DOMAIN-KEYWORD",
|
||||
example: "example",
|
||||
},
|
||||
{
|
||||
name: "DOMAIN-REGEX",
|
||||
example: "example.*",
|
||||
},
|
||||
{
|
||||
name: "GEOSITE",
|
||||
example: "youtube",
|
||||
},
|
||||
{
|
||||
name: "GEOIP",
|
||||
example: "CN",
|
||||
noResolve: true,
|
||||
},
|
||||
{
|
||||
name: "SRC-GEOIP",
|
||||
example: "CN",
|
||||
},
|
||||
{
|
||||
name: "IP-ASN",
|
||||
example: "13335",
|
||||
noResolve: true,
|
||||
validator: (value) => (+value ? true : false),
|
||||
},
|
||||
{
|
||||
name: "SRC-IP-ASN",
|
||||
example: "9808",
|
||||
validator: (value) => (+value ? true : false),
|
||||
},
|
||||
{
|
||||
name: "IP-CIDR",
|
||||
example: "127.0.0.0/8",
|
||||
noResolve: true,
|
||||
validator: (value) => ipv4CIDRValidator(value) || ipv6CIDRValidator(value),
|
||||
},
|
||||
{
|
||||
name: "IP-CIDR6",
|
||||
example: "2620:0:2d0:200::7/32",
|
||||
noResolve: true,
|
||||
validator: (value) => ipv4CIDRValidator(value) || ipv6CIDRValidator(value),
|
||||
},
|
||||
{
|
||||
name: "SRC-IP-CIDR",
|
||||
example: "192.168.1.201/32",
|
||||
validator: (value) => ipv4CIDRValidator(value) || ipv6CIDRValidator(value),
|
||||
},
|
||||
{
|
||||
name: "IP-SUFFIX",
|
||||
example: "8.8.8.8/24",
|
||||
noResolve: true,
|
||||
validator: (value) => ipv4CIDRValidator(value) || ipv6CIDRValidator(value),
|
||||
},
|
||||
{
|
||||
name: "SRC-IP-SUFFIX",
|
||||
example: "192.168.1.201/8",
|
||||
validator: (value) => ipv4CIDRValidator(value) || ipv6CIDRValidator(value),
|
||||
},
|
||||
{
|
||||
name: "SRC-PORT",
|
||||
example: "7777",
|
||||
validator: (value) => portValidator(value),
|
||||
},
|
||||
{
|
||||
name: "DST-PORT",
|
||||
example: "80",
|
||||
validator: (value) => portValidator(value),
|
||||
},
|
||||
{
|
||||
name: "IN-PORT",
|
||||
example: "7890",
|
||||
validator: (value) => portValidator(value),
|
||||
},
|
||||
{
|
||||
name: "DSCP",
|
||||
example: "4",
|
||||
},
|
||||
{
|
||||
name: "PROCESS-NAME",
|
||||
example: getSystem() === "windows" ? "chrome.exe" : "curl",
|
||||
},
|
||||
{
|
||||
name: "PROCESS-PATH",
|
||||
example:
|
||||
getSystem() === "windows"
|
||||
? "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
|
||||
: "/usr/bin/wget",
|
||||
},
|
||||
{
|
||||
name: "PROCESS-NAME-REGEX",
|
||||
example: ".*telegram.*",
|
||||
},
|
||||
{
|
||||
name: "PROCESS-PATH-REGEX",
|
||||
example:
|
||||
getSystem() === "windows" ? "(?i).*Application\\chrome.*" : ".*bin/wget",
|
||||
},
|
||||
{
|
||||
name: "NETWORK",
|
||||
example: "udp",
|
||||
validator: (value) => ["tcp", "udp"].includes(value),
|
||||
},
|
||||
{
|
||||
name: "UID",
|
||||
example: "1001",
|
||||
validator: (value) => (+value ? true : false),
|
||||
},
|
||||
{
|
||||
name: "IN-TYPE",
|
||||
example: "SOCKS/HTTP",
|
||||
},
|
||||
{
|
||||
name: "IN-USER",
|
||||
example: "mihomo",
|
||||
},
|
||||
{
|
||||
name: "IN-NAME",
|
||||
example: "ss",
|
||||
},
|
||||
{
|
||||
name: "SUB-RULE",
|
||||
example: "(NETWORK,tcp)",
|
||||
},
|
||||
{
|
||||
name: "RULE-SET",
|
||||
example: "providername",
|
||||
noResolve: true,
|
||||
},
|
||||
{
|
||||
name: "AND",
|
||||
example: "((DOMAIN,baidu.com),(NETWORK,UDP))",
|
||||
},
|
||||
{
|
||||
name: "OR",
|
||||
example: "((NETWORK,UDP),(DOMAIN,baidu.com))",
|
||||
},
|
||||
{
|
||||
name: "NOT",
|
||||
example: "((DOMAIN,baidu.com))",
|
||||
},
|
||||
{
|
||||
name: "MATCH",
|
||||
required: false,
|
||||
},
|
||||
];
|
||||
|
||||
const builtinProxyPolicies = ["DIRECT", "REJECT", "REJECT-DROP", "PASS"];
|
||||
|
||||
export const RulesEditorViewer = (props: Props) => {
|
||||
const { title, profileUid, property, open, onClose, onChange } = props;
|
||||
const { title, profileUid, property, open, onClose, onSave } = props;
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [prevData, setPrevData] = useState("");
|
||||
const [ruleType, setRuleType] =
|
||||
useState<(typeof RuleTypeList)[number]>("DOMAIN");
|
||||
const [match, setMatch] = useState(() => (_: string) => true);
|
||||
|
||||
const [ruleType, setRuleType] = useState<(typeof rules)[number]>(rules[0]);
|
||||
const [ruleContent, setRuleContent] = useState("");
|
||||
const [noResolve, setNoResolve] = useState(false);
|
||||
const [proxyPolicy, setProxyPolicy] = useState("DIRECT");
|
||||
const [proxyPolicy, setProxyPolicy] = useState(builtinProxyPolicies[0]);
|
||||
const [proxyPolicyList, setProxyPolicyList] = useState<string[]>([]);
|
||||
const [ruleList, setRuleList] = useState<string[]>([]);
|
||||
const [ruleSetList, setRuleSetList] = useState<string[]>([]);
|
||||
@@ -195,7 +296,7 @@ export const RulesEditorViewer = (props: Props) => {
|
||||
let ruleSetObj = yaml.load(data) as { "rule-providers": [] };
|
||||
let subRuleObj = yaml.load(data) as { "sub-rules": [] };
|
||||
setProxyPolicyList(
|
||||
BuiltinProxyPolicyList.concat(
|
||||
builtinProxyPolicies.concat(
|
||||
groupsObj["proxy-groups"]
|
||||
? groupsObj["proxy-groups"].map((item: any) => item.name)
|
||||
: []
|
||||
@@ -217,7 +318,20 @@ export const RulesEditorViewer = (props: Props) => {
|
||||
fetchProfile();
|
||||
}, [open]);
|
||||
|
||||
const onSave = useLockFn(async () => {
|
||||
const validateRule = () => {
|
||||
if ((ruleType.required ?? true) && !ruleContent) {
|
||||
throw new Error(t("Rule Condition Required"));
|
||||
}
|
||||
if (ruleType.validator && !ruleType.validator(ruleContent)) {
|
||||
throw new Error(t("Invalid Rule"));
|
||||
}
|
||||
|
||||
return `${ruleType.name}${
|
||||
ruleContent ? "," + ruleContent : ""
|
||||
},${proxyPolicy}${ruleType.noResolve && noResolve ? ",no-resolve" : ""}`;
|
||||
};
|
||||
|
||||
const handleSave = useLockFn(async () => {
|
||||
try {
|
||||
let currData = yaml.dump({
|
||||
prepend: prependSeq,
|
||||
@@ -225,7 +339,7 @@ export const RulesEditorViewer = (props: Props) => {
|
||||
delete: deleteSeq,
|
||||
});
|
||||
await saveProfileFile(property, currData);
|
||||
onChange?.(prevData, currData);
|
||||
onSave?.(prevData, currData);
|
||||
onClose();
|
||||
} catch (err: any) {
|
||||
Notice.error(err.message || err.toString());
|
||||
@@ -237,106 +351,106 @@ export const RulesEditorViewer = (props: Props) => {
|
||||
<DialogTitle>{title ?? t("Edit Rules")}</DialogTitle>
|
||||
|
||||
<DialogContent sx={{ display: "flex", width: "auto", height: "100vh" }}>
|
||||
<div
|
||||
style={{
|
||||
<List
|
||||
sx={{
|
||||
height: "calc(100% - 16px)",
|
||||
width: "50%",
|
||||
height: "100%",
|
||||
padding: "0 10px",
|
||||
}}
|
||||
>
|
||||
<List>
|
||||
<Item>
|
||||
<ListItemText primary={t("Rule Type")} />
|
||||
<Item>
|
||||
<ListItemText primary={t("Rule Type")} />
|
||||
<Autocomplete
|
||||
size="small"
|
||||
sx={{ minWidth: "240px" }}
|
||||
renderInput={(params) => <TextField {...params} />}
|
||||
options={rules}
|
||||
value={ruleType}
|
||||
getOptionLabel={(option) => option.name}
|
||||
renderOption={(props, option) => (
|
||||
<li {...props} title={t(option.name)}>
|
||||
{option.name}
|
||||
</li>
|
||||
)}
|
||||
onChange={(_, value) => value && setRuleType(value)}
|
||||
/>
|
||||
</Item>
|
||||
<Item sx={{ display: !(ruleType.required ?? true) ? "none" : "" }}>
|
||||
<ListItemText primary={t("Rule Content")} />
|
||||
|
||||
{ruleType.name === "RULE-SET" && (
|
||||
<Autocomplete
|
||||
size="small"
|
||||
sx={{ minWidth: "240px" }}
|
||||
value={ruleType}
|
||||
options={RuleTypeList}
|
||||
onChange={(_, v) => {
|
||||
if (v) setRuleType(v);
|
||||
}}
|
||||
renderInput={(params) => <TextField {...params} />}
|
||||
options={ruleSetList}
|
||||
value={ruleContent}
|
||||
onChange={(_, value) => value && setRuleContent(value)}
|
||||
/>
|
||||
</Item>
|
||||
<Item>
|
||||
<ListItemText primary={t("Rule Content")} />
|
||||
{ruleType === "RULE-SET" && (
|
||||
<Autocomplete
|
||||
size="small"
|
||||
sx={{ minWidth: "240px" }}
|
||||
value={ruleContent}
|
||||
options={ruleSetList}
|
||||
onChange={(_, v) => {
|
||||
if (v) setRuleContent(v);
|
||||
}}
|
||||
renderInput={(params) => <TextField {...params} />}
|
||||
/>
|
||||
)}
|
||||
{ruleType === "SUB-RULE" && (
|
||||
<Autocomplete
|
||||
size="small"
|
||||
sx={{ minWidth: "240px" }}
|
||||
value={ruleContent}
|
||||
options={subRuleList}
|
||||
onChange={(_, v) => {
|
||||
if (v) setRuleContent(v);
|
||||
}}
|
||||
renderInput={(params) => <TextField {...params} />}
|
||||
/>
|
||||
)}
|
||||
{ruleType !== "RULE-SET" && ruleType !== "SUB-RULE" && (
|
||||
<TextField
|
||||
size="small"
|
||||
sx={{ minWidth: "240px" }}
|
||||
value={ruleContent}
|
||||
placeholder={ExampleMap[ruleType]}
|
||||
onChange={(e) => {
|
||||
setRuleContent(e.target.value);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Item>
|
||||
<Item>
|
||||
<ListItemText primary={t("Proxy Policy")} />
|
||||
<Autocomplete
|
||||
size="small"
|
||||
sx={{ minWidth: "240px" }}
|
||||
value={proxyPolicy}
|
||||
options={proxyPolicyList}
|
||||
onChange={(_, v) => {
|
||||
if (v) setProxyPolicy(v);
|
||||
}}
|
||||
renderInput={(params) => <TextField {...params} />}
|
||||
/>
|
||||
</Item>
|
||||
{NoResolveList.includes(ruleType) && (
|
||||
<Item>
|
||||
<ListItemText primary={t("No Resolve")} />
|
||||
<Switch
|
||||
checked={noResolve}
|
||||
onChange={() => {
|
||||
setNoResolve(!noResolve);
|
||||
}}
|
||||
/>
|
||||
</Item>
|
||||
)}
|
||||
</List>
|
||||
{ruleType.name === "SUB-RULE" && (
|
||||
<Autocomplete
|
||||
size="small"
|
||||
sx={{ minWidth: "240px" }}
|
||||
renderInput={(params) => <TextField {...params} />}
|
||||
options={subRuleList}
|
||||
value={ruleContent}
|
||||
onChange={(_, value) => value && setRuleContent(value)}
|
||||
/>
|
||||
)}
|
||||
{ruleType.name !== "RULE-SET" && ruleType.name !== "SUB-RULE" && (
|
||||
<TextField
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
sx={{ minWidth: "240px" }}
|
||||
value={ruleContent}
|
||||
required={ruleType.required ?? true}
|
||||
error={(ruleType.required ?? true) && !ruleContent}
|
||||
placeholder={ruleType.example}
|
||||
onChange={(e) => setRuleContent(e.target.value)}
|
||||
/>
|
||||
)}
|
||||
</Item>
|
||||
<Item>
|
||||
<ListItemText primary={t("Proxy Policy")} />
|
||||
<Autocomplete
|
||||
size="small"
|
||||
sx={{ minWidth: "240px" }}
|
||||
renderInput={(params) => <TextField {...params} />}
|
||||
options={proxyPolicyList}
|
||||
value={proxyPolicy}
|
||||
renderOption={(props, option) => (
|
||||
<li {...props} title={t(option)}>
|
||||
{option}
|
||||
</li>
|
||||
)}
|
||||
onChange={(_, value) => value && setProxyPolicy(value)}
|
||||
/>
|
||||
</Item>
|
||||
{ruleType.noResolve && (
|
||||
<Item>
|
||||
<ListItemText primary={t("No Resolve")} />
|
||||
<Switch
|
||||
checked={noResolve}
|
||||
onChange={() => setNoResolve(!noResolve)}
|
||||
/>
|
||||
</Item>
|
||||
)}
|
||||
<Item>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
let raw = `${ruleType}${
|
||||
ruleType === "MATCH" ? "" : "," + ruleContent
|
||||
},${proxyPolicy}${
|
||||
NoResolveList.includes(ruleType) && noResolve
|
||||
? ",no-resolve"
|
||||
: ""
|
||||
}`;
|
||||
if (prependSeq.includes(raw)) return;
|
||||
setPrependSeq([...prependSeq, raw]);
|
||||
try {
|
||||
let raw = validateRule();
|
||||
if (prependSeq.includes(raw)) return;
|
||||
setPrependSeq([...prependSeq, raw]);
|
||||
} catch (err: any) {
|
||||
Notice.error(err.message || err.toString());
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t("Add Prepend Rule")}
|
||||
{t("Prepend Rule")}
|
||||
</Button>
|
||||
</Item>
|
||||
<Item>
|
||||
@@ -344,107 +458,119 @@ export const RulesEditorViewer = (props: Props) => {
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
let raw = `${ruleType}${
|
||||
ruleType === "MATCH" ? "" : "," + ruleContent
|
||||
},${proxyPolicy}${
|
||||
NoResolveList.includes(ruleType) && noResolve
|
||||
? ",no-resolve"
|
||||
: ""
|
||||
}`;
|
||||
if (appendSeq.includes(raw)) return;
|
||||
setAppendSeq([...appendSeq, raw]);
|
||||
try {
|
||||
let raw = validateRule();
|
||||
if (appendSeq.includes(raw)) return;
|
||||
setAppendSeq([...appendSeq, raw]);
|
||||
} catch (err: any) {
|
||||
Notice.error(err.message || err.toString());
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t("Add Append Rule")}
|
||||
{t("Append Rule")}
|
||||
</Button>
|
||||
</Item>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: "inline-block",
|
||||
width: "50%",
|
||||
height: "100%",
|
||||
overflow: "auto",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
</List>
|
||||
|
||||
<List
|
||||
sx={{ height: "calc(100% - 16px)", width: "50%", padding: "0 10px" }}
|
||||
>
|
||||
{prependSeq.length > 0 && (
|
||||
<DndContext
|
||||
sensors={sensors}
|
||||
collisionDetection={closestCenter}
|
||||
onDragEnd={onPrependDragEnd}
|
||||
>
|
||||
<List sx={{ borderBottom: "solid 1px var(--divider-color)" }}>
|
||||
<SortableContext
|
||||
items={prependSeq.map((x) => {
|
||||
return x;
|
||||
})}
|
||||
>
|
||||
{prependSeq.map((item, index) => {
|
||||
return (
|
||||
<RuleItem
|
||||
key={`${item}-${index}`}
|
||||
type="prepend"
|
||||
ruleRaw={item}
|
||||
onDelete={() => {
|
||||
setPrependSeq(prependSeq.filter((v) => v !== item));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</SortableContext>
|
||||
</List>
|
||||
</DndContext>
|
||||
)}
|
||||
|
||||
<List>
|
||||
{ruleList.map((item, index) => {
|
||||
return (
|
||||
<RuleItem
|
||||
key={`${item}-${index}`}
|
||||
type={deleteSeq.includes(item) ? "delete" : "original"}
|
||||
ruleRaw={item}
|
||||
onDelete={() => {
|
||||
if (deleteSeq.includes(item)) {
|
||||
setDeleteSeq(deleteSeq.filter((v) => v !== item));
|
||||
} else {
|
||||
setDeleteSeq([...deleteSeq, item]);
|
||||
<BaseSearchBox
|
||||
matchCase={false}
|
||||
onSearch={(match) => setMatch(() => match)}
|
||||
/>
|
||||
<Virtuoso
|
||||
style={{ height: "calc(100% - 16px)", marginTop: "8px" }}
|
||||
totalCount={
|
||||
ruleList.length +
|
||||
(prependSeq.length > 0 ? 1 : 0) +
|
||||
(appendSeq.length > 0 ? 1 : 0)
|
||||
}
|
||||
increaseViewportBy={256}
|
||||
itemContent={(index) => {
|
||||
let shift = prependSeq.length > 0 ? 1 : 0;
|
||||
if (prependSeq.length > 0 && index === 0) {
|
||||
return (
|
||||
<DndContext
|
||||
sensors={sensors}
|
||||
collisionDetection={closestCenter}
|
||||
onDragEnd={onPrependDragEnd}
|
||||
>
|
||||
<SortableContext
|
||||
items={prependSeq.map((x) => {
|
||||
return x;
|
||||
})}
|
||||
>
|
||||
{prependSeq.map((item, index) => {
|
||||
return (
|
||||
<RuleItem
|
||||
key={`${item}-${index}`}
|
||||
type="prepend"
|
||||
ruleRaw={item}
|
||||
onDelete={() => {
|
||||
setPrependSeq(
|
||||
prependSeq.filter((v) => v !== item)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
);
|
||||
} else if (index < ruleList.length + shift) {
|
||||
let newIndex = index - shift;
|
||||
return (
|
||||
<RuleItem
|
||||
key={`${ruleList[newIndex]}-${index}`}
|
||||
type={
|
||||
deleteSeq.includes(ruleList[newIndex])
|
||||
? "delete"
|
||||
: "original"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
|
||||
{appendSeq.length > 0 && (
|
||||
<DndContext
|
||||
sensors={sensors}
|
||||
collisionDetection={closestCenter}
|
||||
onDragEnd={onAppendDragEnd}
|
||||
>
|
||||
<SortableContext
|
||||
items={appendSeq.map((x) => {
|
||||
return x;
|
||||
})}
|
||||
>
|
||||
<List sx={{ borderTop: "solid 1px var(--divider-color)" }}>
|
||||
{appendSeq.map((item, index) => {
|
||||
return (
|
||||
<RuleItem
|
||||
key={`${item}-${index}`}
|
||||
type="append"
|
||||
ruleRaw={item}
|
||||
onDelete={() => {
|
||||
setAppendSeq(appendSeq.filter((v) => v !== item));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
)}
|
||||
</div>
|
||||
ruleRaw={ruleList[newIndex]}
|
||||
onDelete={() => {
|
||||
if (deleteSeq.includes(ruleList[newIndex])) {
|
||||
setDeleteSeq(
|
||||
deleteSeq.filter((v) => v !== ruleList[newIndex])
|
||||
);
|
||||
} else {
|
||||
setDeleteSeq((prev) => [...prev, ruleList[newIndex]]);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<DndContext
|
||||
sensors={sensors}
|
||||
collisionDetection={closestCenter}
|
||||
onDragEnd={onAppendDragEnd}
|
||||
>
|
||||
<SortableContext
|
||||
items={appendSeq.map((x) => {
|
||||
return x;
|
||||
})}
|
||||
>
|
||||
{appendSeq.map((item, index) => {
|
||||
return (
|
||||
<RuleItem
|
||||
key={`${item}-${index}`}
|
||||
type="append"
|
||||
ruleRaw={item}
|
||||
onDelete={() => {
|
||||
setAppendSeq(appendSeq.filter((v) => v !== item));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</List>
|
||||
</DialogContent>
|
||||
|
||||
<DialogActions>
|
||||
@@ -452,7 +578,7 @@ export const RulesEditorViewer = (props: Props) => {
|
||||
{t("Cancel")}
|
||||
</Button>
|
||||
|
||||
<Button onClick={onSave} variant="contained">
|
||||
<Button onClick={handleSave} variant="contained">
|
||||
{t("Save")}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
|
||||
@@ -132,6 +132,7 @@ export const ProxyHead = (props: Props) => {
|
||||
|
||||
{textState === "filter" && (
|
||||
<TextField
|
||||
autoComplete="off"
|
||||
autoFocus={autoFocus}
|
||||
hiddenLabel
|
||||
value={filterText}
|
||||
@@ -145,10 +146,10 @@ export const ProxyHead = (props: Props) => {
|
||||
|
||||
{textState === "url" && (
|
||||
<TextField
|
||||
autoComplete="off"
|
||||
autoFocus={autoFocus}
|
||||
hiddenLabel
|
||||
autoSave="off"
|
||||
autoComplete="off"
|
||||
value={testUrl}
|
||||
size="small"
|
||||
variant="outlined"
|
||||
|
||||
@@ -134,8 +134,8 @@ export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Mixed Port")} />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
sx={{ width: 135 }}
|
||||
value={mixedPort}
|
||||
onChange={(e) =>
|
||||
@@ -146,8 +146,8 @@ export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Socks Port")} />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
sx={{ width: 135 }}
|
||||
value={socksPort}
|
||||
onChange={(e) =>
|
||||
@@ -169,8 +169,8 @@ export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Http Port")} />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
sx={{ width: 135 }}
|
||||
value={port}
|
||||
onChange={(e) =>
|
||||
@@ -193,8 +193,8 @@ export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Redir Port")} />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
sx={{ width: 135 }}
|
||||
value={redirPort}
|
||||
onChange={(e) =>
|
||||
@@ -218,8 +218,8 @@ export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Tproxy Port")} />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
sx={{ width: 135 }}
|
||||
value={tproxyPort}
|
||||
onChange={(e) =>
|
||||
|
||||
@@ -22,15 +22,14 @@ export const ConfigViewer = forwardRef<DialogRef>((_, ref) => {
|
||||
|
||||
return (
|
||||
<EditorViewer
|
||||
open={open}
|
||||
title={
|
||||
<Box>
|
||||
{t("Runtime Config")}
|
||||
<Chip label={t("ReadOnly")} size="small" />
|
||||
</Box>
|
||||
}
|
||||
mode="text"
|
||||
property={runtimeConfig}
|
||||
open={open}
|
||||
initialData={Promise.resolve(runtimeConfig)}
|
||||
readOnly
|
||||
language="yaml"
|
||||
schema="clash"
|
||||
|
||||
@@ -48,8 +48,8 @@ export const ControllerViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("External Controller")} />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
sx={{ width: 175 }}
|
||||
value={controller}
|
||||
placeholder="Required"
|
||||
@@ -60,8 +60,8 @@ export const ControllerViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Core Secret")} />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
sx={{ width: 175 }}
|
||||
value={secret}
|
||||
placeholder={t("Recommended")}
|
||||
|
||||
@@ -198,8 +198,8 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
/>
|
||||
<TooltipIcon title={t("Default Latency Test Info")} />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
@@ -215,9 +215,9 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Default Latency Timeout")} />
|
||||
<TextField
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
type="number"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
|
||||
@@ -188,6 +188,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Guard Duration")} />
|
||||
<TextField
|
||||
autoComplete="off"
|
||||
disabled={!enabled}
|
||||
size="small"
|
||||
value={value.duration}
|
||||
@@ -218,10 +219,10 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<>
|
||||
<ListItemText primary={t("Proxy Bypass")} />
|
||||
<TextField
|
||||
autoComplete="off"
|
||||
error={value.bypass ? !validReg.test(value.bypass) : false}
|
||||
disabled={!enabled}
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
multiline
|
||||
rows={4}
|
||||
sx={{ width: "100%" }}
|
||||
@@ -233,9 +234,9 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItemText primary={t("Bypass")} />
|
||||
<FlexBox>
|
||||
<TextField
|
||||
autoComplete="off"
|
||||
disabled={true}
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
multiline
|
||||
rows={4}
|
||||
sx={{ width: "100%" }}
|
||||
@@ -261,21 +262,18 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
{t("Edit")} PAC
|
||||
</Button>
|
||||
<EditorViewer
|
||||
title={`${t("Edit")} PAC`}
|
||||
mode="text"
|
||||
property={value.pac_content ?? ""}
|
||||
open={editorOpen}
|
||||
title={`${t("Edit")} PAC`}
|
||||
initialData={Promise.resolve(value.pac_content ?? "")}
|
||||
language="javascript"
|
||||
onChange={(_prev, curr) => {
|
||||
onSave={(_prev, curr) => {
|
||||
let pac = DEFAULT_PAC;
|
||||
if (curr && curr.trim().length > 0) {
|
||||
pac = curr;
|
||||
}
|
||||
setValue((v) => ({ ...v, pac_content: pac }));
|
||||
}}
|
||||
onClose={() => {
|
||||
setEditorOpen(false);
|
||||
}}
|
||||
onClose={() => setEditorOpen(false)}
|
||||
/>
|
||||
</ListItem>
|
||||
</>
|
||||
|
||||
@@ -124,12 +124,11 @@ export const ThemeViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
{t("Edit")} CSS
|
||||
</Button>
|
||||
<EditorViewer
|
||||
title={`${t("Edit")} CSS`}
|
||||
mode="text"
|
||||
property={theme.css_injection ?? ""}
|
||||
open={editorOpen}
|
||||
title={`${t("Edit")} CSS`}
|
||||
initialData={Promise.resolve(theme.css_injection ?? "")}
|
||||
language="css"
|
||||
onChange={(_prev, curr) => {
|
||||
onSave={(_prev, curr) => {
|
||||
theme.css_injection = curr;
|
||||
handleChange("css_injection");
|
||||
}}
|
||||
|
||||
@@ -144,8 +144,8 @@ export const TunViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Device")} />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
@@ -190,8 +190,8 @@ export const TunViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("DNS Hijack")} />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
@@ -207,9 +207,9 @@ export const TunViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("MTU")} />
|
||||
<TextField
|
||||
autoComplete="off"
|
||||
size="small"
|
||||
type="number"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
|
||||
@@ -43,12 +43,12 @@ export const WebUIItem = (props: Props) => {
|
||||
<>
|
||||
<Stack spacing={0.75} direction="row" mt={1} mb={1} alignItems="center">
|
||||
<TextField
|
||||
autoComplete="off"
|
||||
fullWidth
|
||||
size="small"
|
||||
value={editValue}
|
||||
onChange={(e) => setEditValue(e.target.value)}
|
||||
placeholder={t("Support %host, %port, %secret")}
|
||||
autoComplete="off"
|
||||
/>
|
||||
<IconButton
|
||||
size="small"
|
||||
|
||||
@@ -125,8 +125,8 @@ const SettingClash = ({ onError }: Props) => {
|
||||
}
|
||||
>
|
||||
<TextField
|
||||
disabled={enable_random_port}
|
||||
autoComplete="off"
|
||||
disabled={enable_random_port}
|
||||
size="small"
|
||||
value={verge_mixed_port ?? 7897}
|
||||
sx={{ width: 100, input: { py: "7.5px", cursor: "pointer" } }}
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
"Close": "Close",
|
||||
"Cancel": "Cancel",
|
||||
"Confirm": "Confirm",
|
||||
"Maximize": "Maximize",
|
||||
"Minimize": "Minimize",
|
||||
"Format document": "Format document",
|
||||
"Empty": "Empty",
|
||||
"New": "New",
|
||||
"Edit": "Edit",
|
||||
@@ -54,11 +57,50 @@
|
||||
"Edit Rules": "Edit Rules",
|
||||
"Rule Type": "Rule Type",
|
||||
"Rule Content": "Rule Content",
|
||||
"Proxy Policy": "roxy Policy",
|
||||
"Proxy Policy": "Proxy Policy",
|
||||
"No Resolve": "No Resolve",
|
||||
"Add Prepend Rule": "Add Prepend Rule",
|
||||
"Add Append Rule": "Add Append Rule",
|
||||
"Prepend Rule": "Prepend Rule",
|
||||
"Append Rule": "Append Rule",
|
||||
"Delete Rule": "Delete Rule",
|
||||
"Rule Condition Required": "Rule Condition Required",
|
||||
"Invalid Rule": "Invalid Rule",
|
||||
"DOMAIN": "Matches the full domain name",
|
||||
"DOMAIN-SUFFIX": "Matches the domain suffix",
|
||||
"DOMAIN-KEYWORD": "Matches the domain keyword",
|
||||
"DOMAIN-REGEX": "Matches the domain using regular expressions",
|
||||
"GEOSITE": "Matches domains within the Geosite",
|
||||
"GEOIP": "Matches the country code of the IP address",
|
||||
"SRC-GEOIP": "Matches the country code of the source IP address",
|
||||
"IP-ASN": "Matches the IP address's ASN",
|
||||
"SRC-IP-ASN": "Matches the source IP address's ASN",
|
||||
"IP-CIDR": "Matches the IP address range",
|
||||
"IP-CIDR6": "Matches the IPv6 address range",
|
||||
"SRC-IP-CIDR": "Matches the source IP address range",
|
||||
"IP-SUFFIX": "Matches the IP address suffix range",
|
||||
"SRC-IP-SUFFIX": "Matches the source IP address suffix range",
|
||||
"SRC-PORT": "Matches the source port range",
|
||||
"DST-PORT": "Matches the destination port range",
|
||||
"IN-PORT": "Matches the inbound port",
|
||||
"DSCP": "DSCP marking (only for tproxy UDP inbound)",
|
||||
"PROCESS-NAME": "Matches the process name (Android package name)",
|
||||
"PROCESS-PATH": "Matches the full process path",
|
||||
"PROCESS-NAME-REGEX": "Matches the full process name using regular expressions (Android package name)",
|
||||
"PROCESS-PATH-REGEX": "Matches the full process path using regular expressions",
|
||||
"NETWORK": "Matches the transport protocol (tcp/udp)",
|
||||
"UID": "Matches the Linux USER ID",
|
||||
"IN-TYPE": "Matches the inbound type",
|
||||
"IN-USER": "Matches the inbound username",
|
||||
"IN-NAME": "Matches the inbound name",
|
||||
"SUB-RULE": "Sub-rule",
|
||||
"RULE-SET": "Matches the rule set",
|
||||
"AND": "Logical AND",
|
||||
"OR": "Logical OR",
|
||||
"NOT": "Logical NOT",
|
||||
"MATCH": "Matches all requests",
|
||||
"DIRECT": "Data goes directly outbound",
|
||||
"REJECT": "Intercepts requests",
|
||||
"REJECT-DROP": "Discards requests",
|
||||
"PASS": "Skips this rule when matched",
|
||||
"Edit Groups": "Edit Proxy Groups",
|
||||
"Extend Config": "Extend Config",
|
||||
"Extend Script": "Extend Script",
|
||||
@@ -162,12 +204,20 @@
|
||||
"Auto Launch": "Auto Launch",
|
||||
"Silent Start": "Silent Start",
|
||||
"Silent Start Info": "Start the program in background mode without displaying the panel",
|
||||
"TG Channel": "Telegram Channel",
|
||||
"Manual": "Manual",
|
||||
"Github Repo": "Github Repo",
|
||||
"Clash Setting": "Clash Setting",
|
||||
"Allow Lan": "Allow Lan",
|
||||
"Allow Lan": "Allow LAN",
|
||||
"IPv6": "IPv6",
|
||||
"Log Level": "Log Level",
|
||||
"Port Config": "Port Config",
|
||||
"Random Port": "Random Port",
|
||||
"Mixed Port": "Mixed Port",
|
||||
"Socks Port": "Socks Port",
|
||||
"Http Port": "Http(s) Port",
|
||||
"Redir Port": "Redir Port",
|
||||
"Tproxy Port": "Tproxy Port",
|
||||
"External": "External",
|
||||
"External Controller": "External Controller",
|
||||
"Core Secret": "Core Secret",
|
||||
@@ -185,9 +235,6 @@
|
||||
"Open UWP tool": "Open UWP tool",
|
||||
"Open UWP tool Info": "Since Windows 8, UWP apps (such as Microsoft Store) are restricted from directly accessing local host network services, and this tool can be used to bypass this restriction",
|
||||
"Update GeoData": "Update GeoData",
|
||||
"TG Channel": "Telegram Channel",
|
||||
"Manual": "Manual",
|
||||
"Github Repo": "Github Repo",
|
||||
"Verge Setting": "Verge Setting",
|
||||
"Language": "Language",
|
||||
"Theme Mode": "Theme Mode",
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
"Close": "بستن",
|
||||
"Cancel": "لغو",
|
||||
"Confirm": "تأیید",
|
||||
"Maximize": "بزرگنمایی",
|
||||
"Minimize": "کوچکنمایی",
|
||||
"Format document": "فرمتبندی سند",
|
||||
"Empty": "خالی خالی",
|
||||
"New": "جدید",
|
||||
"Edit": "ویرایش",
|
||||
@@ -50,6 +53,55 @@
|
||||
"Expire Time": "زمان انقضا",
|
||||
"Create Profile": "ایجاد پروفایل",
|
||||
"Edit Profile": "ویرایش پروفایل",
|
||||
"Edit Proxies": "ویرایش پروکسیها",
|
||||
"Edit Rules": "ویرایش قوانین",
|
||||
"Rule Type": "نوع قانون",
|
||||
"Rule Content": "محتوای قانون",
|
||||
"Proxy Policy": "سیاست پروکسی",
|
||||
"No Resolve": "بدون حل",
|
||||
"Prepend Rule": "اضافه کردن قانون به ابتدا",
|
||||
"Append Rule": "اضافه کردن قانون به انتها",
|
||||
"Delete Rule": "حذف قانون",
|
||||
"Rule Condition Required": "شرط قانون الزامی است",
|
||||
"Invalid Rule": "قانون نامعتبر",
|
||||
"DOMAIN": "مطابقت با نام کامل دامنه",
|
||||
"DOMAIN-SUFFIX": "مطابقت با پسوند دامنه",
|
||||
"DOMAIN-KEYWORD": "مطابقت با کلمه کلیدی دامنه",
|
||||
"DOMAIN-REGEX": "مطابقت با دامنه با استفاده از عبارات منظم",
|
||||
"GEOSITE": "مطابقت با دامنههای درون Geosite",
|
||||
"GEOIP": "مطابقت با کد کشور IP",
|
||||
"SRC-GEOIP": "مطابقت با کد کشور IP مبدا",
|
||||
"IP-ASN": "مطابقت با ASN آدرس IP",
|
||||
"SRC-IP-ASN": "مطابقت با ASN آدرس IP مبدا",
|
||||
"IP-CIDR": "مطابقت با محدوده آدرس IP",
|
||||
"IP-CIDR6": "مطابقت با محدوده آدرس IPv6",
|
||||
"SRC-IP-CIDR": "مطابقت با محدوده آدرس IP مبدا",
|
||||
"IP-SUFFIX": "مطابقت با محدوده پسوند آدرس IP",
|
||||
"SRC-IP-SUFFIX": "مطابقت با محدوده پسوند آدرس IP مبدا",
|
||||
"SRC-PORT": "مطابقت با محدوده پورت مبدا",
|
||||
"DST-PORT": "مطابقت با محدوده پورت مقصد",
|
||||
"IN-PORT": "مطابقت با پورت ورودی",
|
||||
"DSCP": "علامتگذاری DSCP (فقط برای tproxy UDP ورودی)",
|
||||
"PROCESS-NAME": "مطابقت با نام فرآیند (نام بسته Android)",
|
||||
"PROCESS-PATH": "مطابقت با مسیر کامل فرآیند",
|
||||
"PROCESS-NAME-REGEX": "مطابقت با نام فرآیند با استفاده از عبارات منظم (نام بسته Android)",
|
||||
"PROCESS-PATH-REGEX": "مطابقت با مسیر کامل فرآیند با استفاده از عبارات منظم",
|
||||
"NETWORK": "مطابقت با پروتکل انتقال (tcp/udp)",
|
||||
"UID": "مطابقت با شناسه کاربری Linux",
|
||||
"IN-TYPE": "مطابقت با نوع ورودی",
|
||||
"IN-USER": "مطابقت با نام کاربری ورودی",
|
||||
"IN-NAME": "مطابقت با نام ورودی",
|
||||
"SUB-RULE": "قانون فرعی",
|
||||
"RULE-SET": "مطابقت با مجموعه قوانین",
|
||||
"AND": "منطق AND",
|
||||
"OR": "منطق OR",
|
||||
"NOT": "منطق NOT",
|
||||
"MATCH": "مطابقت با تمام درخواستها",
|
||||
"DIRECT": "دادهها به صورت مستقیم خروجی میشوند",
|
||||
"REJECT": "درخواستها را متوقف میکند",
|
||||
"REJECT-DROP": "درخواستها را نادیده میگیرد",
|
||||
"PASS": "این قانون را در صورت تطابق نادیده میگیرد",
|
||||
"Edit Groups": "ویرایش گروههای پروکسی",
|
||||
"Extend Config": "توسعه پیکربندی",
|
||||
"Extend Script": "ادغام اسکریپت",
|
||||
"Global Merge": "تنظیمات گستردهی سراسری",
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
"Close": "Закрыть",
|
||||
"Cancel": "Отмена",
|
||||
"Confirm": "Подтвердить",
|
||||
"Maximize": "Развернуть",
|
||||
"Minimize": "Свернуть",
|
||||
"Format document": "Форматировать документ",
|
||||
"Empty": "Пусто",
|
||||
"New": "Новый",
|
||||
"Edit": "Редактировать",
|
||||
@@ -50,6 +53,55 @@
|
||||
"Expire Time": "Время окончания",
|
||||
"Create Profile": "Создать профиль",
|
||||
"Edit Profile": "Изменить профиль",
|
||||
"Edit Proxies": "Редактировать прокси",
|
||||
"Edit Rules": "Редактировать правила",
|
||||
"Rule Type": "Тип правила",
|
||||
"Rule Content": "Содержимое правила",
|
||||
"Proxy Policy": "Политика прокси",
|
||||
"No Resolve": "Без разрешения",
|
||||
"Prepend Rule": "Добавить правило в начало",
|
||||
"Append Rule": "Добавить правило в конец",
|
||||
"Delete Rule": "Удалить правило",
|
||||
"Rule Condition Required": "Требуется условие правила",
|
||||
"Invalid Rule": "Недействительное правило",
|
||||
"DOMAIN": "Соответствует полному доменному имени",
|
||||
"DOMAIN-SUFFIX": "Соответствует суффиксу домена",
|
||||
"DOMAIN-KEYWORD": "Соответствует ключевому слову домена",
|
||||
"DOMAIN-REGEX": "Соответствует домену с использованием регулярных выражений",
|
||||
"GEOSITE": "Соответствует доменам в Geosite",
|
||||
"GEOIP": "Соответствует коду страны IP-адреса",
|
||||
"SRC-GEOIP": "Соответствует коду страны исходного IP-адреса",
|
||||
"IP-ASN": "Соответствует ASN IP-адреса",
|
||||
"SRC-IP-ASN": "Соответствует ASN исходного IP-адреса",
|
||||
"IP-CIDR": "Соответствует диапазону IP-адресов",
|
||||
"IP-CIDR6": "Соответствует диапазону IPv6-адресов",
|
||||
"SRC-IP-CIDR": "Соответствует диапазону исходных IP-адресов",
|
||||
"IP-SUFFIX": "Соответствует диапазону суффиксов IP-адресов",
|
||||
"SRC-IP-SUFFIX": "Соответствует диапазону суффиксов исходных IP-адресов",
|
||||
"SRC-PORT": "Соответствует диапазону исходных портов",
|
||||
"DST-PORT": "Соответствует диапазону целевых портов",
|
||||
"IN-PORT": "Соответствует входящему порту",
|
||||
"DSCP": "Маркировка DSCP (только для tproxy UDP входящего)",
|
||||
"PROCESS-NAME": "Соответствует имени процесса (имя пакета Android)",
|
||||
"PROCESS-PATH": "Соответствует полному пути процесса",
|
||||
"PROCESS-NAME-REGEX": "Соответствует имени процесса с использованием регулярных выражений (имя пакета Android)",
|
||||
"PROCESS-PATH-REGEX": "Соответствует полному пути процесса с использованием регулярных выражений",
|
||||
"NETWORK": "Соответствует транспортному протоколу (tcp/udp)",
|
||||
"UID": "Соответствует USER ID в Linux",
|
||||
"IN-TYPE": "Соответствует типу входящего соединения",
|
||||
"IN-USER": "Соответствует имени пользователя входящего соединения",
|
||||
"IN-NAME": "Соответствует имени входящего соединения",
|
||||
"SUB-RULE": "Подправило",
|
||||
"RULE-SET": "Соответствует набору правил",
|
||||
"AND": "Логическое И",
|
||||
"OR": "Логическое ИЛИ",
|
||||
"NOT": "Логическое НЕ",
|
||||
"MATCH": "Соответствует всем запросам",
|
||||
"DIRECT": "Данные направляются напрямую наружу",
|
||||
"REJECT": "Перехватывает запросы",
|
||||
"REJECT-DROP": "Отклоняет запросы",
|
||||
"PASS": "Пропускает это правило при совпадении",
|
||||
"Edit Groups": "Редактировать группы прокси",
|
||||
"Extend Config": "Изменить Merge.",
|
||||
"Extend Script": "Изменить Script",
|
||||
"Global Merge": "Глобальный расширенный Настройки",
|
||||
@@ -152,6 +204,9 @@
|
||||
"Auto Launch": "Автозапуск",
|
||||
"Silent Start": "Тихий запуск",
|
||||
"Silent Start Info": "Запускать программу в фоновом режиме без отображения панели",
|
||||
"TG Channel": "Канал Telegram",
|
||||
"Manual": "Документация",
|
||||
"Github Repo": "GitHub репозиторий",
|
||||
"Clash Setting": "Настройки Clash",
|
||||
"Allow Lan": "Разрешить локальную сеть",
|
||||
"IPv6": "IPv6",
|
||||
@@ -180,9 +235,6 @@
|
||||
"Open UWP tool": "Открыть UWP инструмент",
|
||||
"Open UWP tool Info": "С Windows 8 приложения UWP (такие как Microsoft Store) ограничены в прямом доступе к сетевым службам локального хоста, и этот инструмент позволяет обойти это ограничение",
|
||||
"Update GeoData": "Обновление GeoData",
|
||||
"TG Channel": "Канал Telegram",
|
||||
"Manual": "Документация",
|
||||
"Github Repo": "GitHub репозиторий",
|
||||
"Verge Setting": "Настройки Verge",
|
||||
"Language": "Язык",
|
||||
"Theme Mode": "Режим темы",
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
"Close": "关闭",
|
||||
"Cancel": "取消",
|
||||
"Confirm": "确认",
|
||||
"Maximize": "最大化",
|
||||
"Minimize": "最小化",
|
||||
"Format document": "格式化文档",
|
||||
"Empty": "空空如也",
|
||||
"New": "新建",
|
||||
"Edit": "编辑",
|
||||
@@ -56,9 +59,48 @@
|
||||
"Rule Content": "规则内容",
|
||||
"Proxy Policy": "代理策略",
|
||||
"No Resolve": "跳过DNS解析",
|
||||
"Add Prepend Rule": "添加前置规则",
|
||||
"Add Append Rule": "添加后置规则",
|
||||
"Prepend Rule": "添加前置规则",
|
||||
"Append Rule": "添加后置规则",
|
||||
"Delete Rule": "删除规则",
|
||||
"Rule Condition Required": "规则条件缺失",
|
||||
"Invalid Rule": "无效规则",
|
||||
"DOMAIN": "匹配完整域名",
|
||||
"DOMAIN-SUFFIX": "匹配域名后缀",
|
||||
"DOMAIN-KEYWORD": "匹配域名关键字",
|
||||
"DOMAIN-REGEX": "匹配域名正则表达式",
|
||||
"GEOSITE": "匹配Geosite内的域名",
|
||||
"GEOIP": "匹配IP所属国家代码",
|
||||
"SRC-GEOIP": "匹配来源IP所属国家代码",
|
||||
"IP-ASN": "匹配IP所属ASN",
|
||||
"SRC-IP-ASN": "匹配来源IP所属ASN",
|
||||
"IP-CIDR": "匹配IP地址范围",
|
||||
"IP-CIDR6": "匹配IP地址范围",
|
||||
"SRC-IP-CIDR": "匹配来源IP地址范围",
|
||||
"IP-SUFFIX": "匹配IP后缀范围",
|
||||
"SRC-IP-SUFFIX": "匹配来源IP后缀范围",
|
||||
"SRC-PORT": "匹配请求来源端口范围",
|
||||
"DST-PORT": "匹配请求目标端口范围",
|
||||
"IN-PORT": "匹配入站端口",
|
||||
"DSCP": "DSCP标记(仅限tproxy udp入站)",
|
||||
"PROCESS-NAME": "匹配进程名称(Android包名)",
|
||||
"PROCESS-PATH": "匹配完整进程路径",
|
||||
"PROCESS-NAME-REGEX": "正则匹配完整进程名称(Android包名)",
|
||||
"PROCESS-PATH-REGEX": "正则匹配完整进程路径",
|
||||
"NETWORK": "匹配传输协议(tcp/udp)",
|
||||
"UID": "匹配Linux USER ID",
|
||||
"IN-TYPE": "匹配入站类型",
|
||||
"IN-USER": "匹配入站用户名",
|
||||
"IN-NAME": "匹配入站名称",
|
||||
"SUB-RULE": "子规则",
|
||||
"RULE-SET": "匹配规则集",
|
||||
"AND": "逻辑和",
|
||||
"OR": "逻辑或",
|
||||
"NOT": "逻辑非",
|
||||
"MATCH": "匹配所有请求",
|
||||
"DIRECT": "直连",
|
||||
"REJECT": "拦截请求",
|
||||
"REJECT-DROP": "抛弃请求",
|
||||
"PASS": "跳过此规则",
|
||||
"Edit Groups": "编辑代理组",
|
||||
"Extend Config": "扩展配置",
|
||||
"Extend Script": "扩展脚本",
|
||||
|
||||
@@ -50,7 +50,6 @@ import { BaseStyledTextField } from "@/components/base/base-styled-text-field";
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
import { readTextFile } from "@tauri-apps/api/fs";
|
||||
import { readText } from "@tauri-apps/api/clipboard";
|
||||
import { EditorViewer } from "@/components/profile/editor-viewer";
|
||||
|
||||
const ProfilePage = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -378,7 +377,7 @@ const ProfilePage = () => {
|
||||
itemData={item}
|
||||
onSelect={(f) => onSelect(item.uid, f)}
|
||||
onEdit={() => viewerRef.current?.edit(item)}
|
||||
onChange={async (prev, curr) => {
|
||||
onSave={async (prev, curr) => {
|
||||
if (prev !== curr && profiles.current === item.uid) {
|
||||
await onEnhance();
|
||||
}
|
||||
@@ -401,7 +400,7 @@ const ProfilePage = () => {
|
||||
<Grid item xs={12} sm={6} md={6} lg={6}>
|
||||
<ProfileMore
|
||||
id="Merge"
|
||||
onChange={async (prev, curr) => {
|
||||
onSave={async (prev, curr) => {
|
||||
if (prev !== curr) {
|
||||
await onEnhance();
|
||||
}
|
||||
@@ -412,7 +411,7 @@ const ProfilePage = () => {
|
||||
<ProfileMore
|
||||
id="Script"
|
||||
logInfo={chainLogs["Script"]}
|
||||
onChange={async (prev, curr) => {
|
||||
onSave={async (prev, curr) => {
|
||||
if (prev !== curr) {
|
||||
await onEnhance();
|
||||
}
|
||||
|
||||
Vendored
+2
-1
@@ -26,7 +26,8 @@ jobs:
|
||||
steps:
|
||||
- id: set-matrix
|
||||
run: |
|
||||
echo '::set-output name=matrix::{"platform":["amd64","arm64"]}'
|
||||
echo '{"platform": ["amd64", "arm64"]}' > matrix.json
|
||||
echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT
|
||||
|
||||
build-bin:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -10,5 +10,5 @@ type Reloader interface {
|
||||
|
||||
type HealthChecker interface {
|
||||
// get relay by ID and check the connection health
|
||||
HealthCheck(ctx context.Context, RelayID string) error
|
||||
HealthCheck(ctx context.Context, RelayID string) (int64, error)
|
||||
}
|
||||
|
||||
@@ -55,6 +55,10 @@ func (r *Config) GetWSRemoteAddr(baseAddr string) (string, error) {
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
func (r *Config) GetTCPRemotes() string {
|
||||
return fmt.Sprintf("%v", r.TCPRemotes)
|
||||
}
|
||||
|
||||
func (r *Config) Validate() error {
|
||||
if r.Adjust() != nil {
|
||||
return errors.New("adjust config failed")
|
||||
|
||||
@@ -9,10 +9,10 @@ import (
|
||||
|
||||
var _ glue.HealthChecker = (*Server)(nil)
|
||||
|
||||
func (r *Server) HealthCheck(ctx context.Context, relayID string) error {
|
||||
func (r *Server) HealthCheck(ctx context.Context, relayID string) (int64, error) {
|
||||
rs, ok := r.relayM.Load(relayID)
|
||||
if !ok {
|
||||
return fmt.Errorf("label for relay: %s not found,can not health check", relayID)
|
||||
return 0, fmt.Errorf("label for relay: %s not found,can not health check", relayID)
|
||||
}
|
||||
inner, _ := rs.(*Relay)
|
||||
return inner.relayServer.HealthCheck(ctx)
|
||||
|
||||
@@ -101,6 +101,7 @@ func (b *baseTransporter) RelayTCPConn(c net.Conn, handshakeF TCPHandShakeF) err
|
||||
return relayConn.Transport(remote.Label)
|
||||
}
|
||||
|
||||
func (b *baseTransporter) HealthCheck(ctx context.Context) error {
|
||||
return b.relayer.HealthCheck(ctx, b.GetRemote().Clone())
|
||||
func (b *baseTransporter) HealthCheck(ctx context.Context) (int64, error) {
|
||||
remote := b.GetRemote().Clone()
|
||||
return remote.HandShakeDuration.Milliseconds(), b.relayer.HealthCheck(ctx, remote)
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ func newRelayClient(cfg *conf.Config) (RelayClient, error) {
|
||||
type RelayServer interface {
|
||||
ListenAndServe() error
|
||||
Close() error
|
||||
HealthCheck(ctx context.Context) error
|
||||
HealthCheck(ctx context.Context) (int64, error) // latency in ms
|
||||
}
|
||||
|
||||
func NewRelayServer(cfg *conf.Config, cmgr cmgr.Cmgr) (RelayServer, error) {
|
||||
|
||||
@@ -103,11 +103,12 @@ func (s *Server) HandleHealthCheck(c echo.Context) error {
|
||||
if relayLabel == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "relay_label is required")
|
||||
}
|
||||
if err := s.HealthCheck(c.Request().Context(), relayLabel); err != nil {
|
||||
res := CommonResp{Message: err.Error()}
|
||||
latency, err := s.HealthCheck(c.Request().Context(), relayLabel)
|
||||
if err != nil {
|
||||
res := HealthCheckResp{Message: err.Error(), ErrorCode: -1}
|
||||
return c.JSON(http.StatusBadRequest, res)
|
||||
}
|
||||
return c.JSON(http.StatusOK, CommonResp{Message: "connect success"})
|
||||
return c.JSON(http.StatusOK, HealthCheckResp{Message: "connect success", Latency: latency})
|
||||
}
|
||||
|
||||
func (s *Server) CurrentConfig(c echo.Context) error {
|
||||
@@ -158,3 +159,9 @@ func (s *Server) ListConnections(c echo.Context) error {
|
||||
"AllCount": s.connMgr.CountConnection("active") + s.connMgr.CountConnection("closed"),
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Server) ListRules(c echo.Context) error {
|
||||
return c.Render(http.StatusOK, "rule_list.html", map[string]interface{}{
|
||||
"Configs": s.cfg.RelayConfigs,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -102,6 +102,7 @@ func NewServer(
|
||||
|
||||
e.GET("/", s.index)
|
||||
e.GET("/connections/", s.ListConnections)
|
||||
e.GET("/rules/", s.ListRules)
|
||||
e.GET("/clash_proxy_provider/", s.HandleClashProxyProvider)
|
||||
|
||||
// api group
|
||||
|
||||
@@ -70,6 +70,13 @@
|
||||
>Connections</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/rules/"
|
||||
class="button is-info is-light"
|
||||
>Rule List</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/api/v1/config/"
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="ehco web" />
|
||||
<meta name="keywords" content="ehco-relay" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/1.0.1/css/bulma.min.css"
|
||||
/>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
||||
<title>Rules</title>
|
||||
</head>
|
||||
<body>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">Rules</h1>
|
||||
<table class="table is-striped is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Label</th>
|
||||
<th>Listen</th>
|
||||
<th>Listen Type</th>
|
||||
<th>Transport Type</th>
|
||||
<th>Remote</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Configs}}
|
||||
<tr>
|
||||
<td>{{.Label}}</td>
|
||||
<td>{{.Listen}}</td>
|
||||
<td>{{.ListenType}}</td>
|
||||
<td>{{.TransportType}}</td>
|
||||
<td>{{.GetTCPRemotes}}</td>
|
||||
<td>
|
||||
<button
|
||||
class="button is-small is-primary health-check"
|
||||
data-label="{{.Label}}"
|
||||
onclick="checkHealth('{{.Label}}')"
|
||||
>
|
||||
Check Health
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
function checkHealth(label) {
|
||||
$.ajax({
|
||||
url: "/api/v1/health_check/?relay_label=" + label,
|
||||
method: "GET",
|
||||
success: function (response) {
|
||||
// Check if the response includes an error code
|
||||
if (response.error_code === 0) {
|
||||
// If no error, show success message with latency
|
||||
alert(
|
||||
"Health Check for " +
|
||||
label +
|
||||
": " +
|
||||
response.msg + // Use 'msg' as per Go struct
|
||||
" (Latency: " +
|
||||
response.latency + // Ensure this matches the Go struct field name
|
||||
"ms)"
|
||||
);
|
||||
} else {
|
||||
// If error code is not 0, show error message
|
||||
alert("Error for " + label + ": " + response.msg);
|
||||
}
|
||||
},
|
||||
error: function (xhr) {
|
||||
// Parse the response JSON in case of HTTP error
|
||||
var response = JSON.parse(xhr.responseText);
|
||||
alert("Error: " + response.msg); // Use 'msg' as per Go struct
|
||||
},
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +1,7 @@
|
||||
package web
|
||||
|
||||
type CommonResp struct {
|
||||
Message string `json:"msg"`
|
||||
type HealthCheckResp struct {
|
||||
ErrorCode int `json:"error_code"` // code = 0 means success
|
||||
Message string `json:"msg"`
|
||||
Latency int64 `json:"latency"`
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ func (i *Instance) Init(configFile string) error {
|
||||
var content []byte
|
||||
var err error
|
||||
configFile = strings.TrimSpace(configFile)
|
||||
if strings.HasPrefix(configFile, "http://") || strings.HasPrefix(configFile, "https://") {
|
||||
if strings.HasPrefix(strings.ToLower(configFile), "http://") || strings.HasPrefix(strings.ToLower(configFile), "https://") {
|
||||
content, err = getRemoteURLContent(configFile)
|
||||
} else {
|
||||
content, err = os.ReadFile(configFile)
|
||||
|
||||
@@ -165,6 +165,23 @@ part_magic_fat() {
|
||||
[ "$magic" = "FAT" ] || [ "$magic_fat32" = "FAT32" ]
|
||||
}
|
||||
|
||||
fitblk_get_bootdev() {
|
||||
[ -e /sys/firmware/devicetree/base/chosen/rootdisk ] || return
|
||||
|
||||
local rootdisk="$(cat /sys/firmware/devicetree/base/chosen/rootdisk)"
|
||||
local handle bootdev
|
||||
for handle in /sys/class/block/*/of_node/phandle /sys/class/block/*/device/of_node/phandle; do
|
||||
[ ! -e "$handle" ] && continue
|
||||
if [ "$rootdisk" = "$(cat $handle)" ]; then
|
||||
bootdev="${handle%/of_node/phandle}"
|
||||
bootdev="${bootdev%/device}"
|
||||
bootdev="${bootdev#/sys/class/block/}"
|
||||
echo "$bootdev"
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
export_bootdevice() {
|
||||
local cmdline uuid blockdev uevent line class
|
||||
local MAJOR MINOR DEVNAME DEVTYPE
|
||||
@@ -196,6 +213,7 @@ export_bootdevice() {
|
||||
done
|
||||
;;
|
||||
/dev/*)
|
||||
[ "$rootpart" = "/dev/fit0" ] && rootpart="$(fitblk_get_bootdev)"
|
||||
uevent="/sys/class/block/${rootpart##*/}/../uevent"
|
||||
;;
|
||||
0x[a-f0-9][a-f0-9][a-f0-9] | 0x[a-f0-9][a-f0-9][a-f0-9][a-f0-9] | \
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
CI_KERNPART="${CI_KERNPART:-kernel}"
|
||||
|
||||
# 'ubi' partition on NAND contains UBI
|
||||
# There are also CI_KERN_UBIPART and CI_ROOT_UBIPART if kernel
|
||||
# and rootfs are on separated UBIs.
|
||||
CI_UBIPART="${CI_UBIPART:-ubi}"
|
||||
|
||||
# 'rootfs' UBI volume on NAND contains the rootfs
|
||||
@@ -26,7 +28,7 @@ ubi_mknod() {
|
||||
|
||||
nand_find_volume() {
|
||||
local ubidevdir ubivoldir
|
||||
ubidevdir="/sys/devices/virtual/ubi/$1"
|
||||
ubidevdir="/sys/class/ubi/"
|
||||
[ ! -d "$ubidevdir" ] && return 1
|
||||
for ubivoldir in $ubidevdir/${1}_*; do
|
||||
[ ! -d "$ubivoldir" ] && continue
|
||||
@@ -39,13 +41,12 @@ nand_find_volume() {
|
||||
}
|
||||
|
||||
nand_find_ubi() {
|
||||
local ubidevdir ubidev mtdnum
|
||||
local ubidevdir ubidev mtdnum cmtdnum
|
||||
mtdnum="$( find_mtd_index $1 )"
|
||||
[ ! "$mtdnum" ] && return 1
|
||||
for ubidevdir in /sys/devices/virtual/ubi/ubi*; do
|
||||
[ ! -d "$ubidevdir" ] && continue
|
||||
for ubidevdir in /sys/class/ubi/ubi*; do
|
||||
[ ! -e "$ubidevdir/mtd_num" ] && continue
|
||||
cmtdnum="$( cat $ubidevdir/mtd_num )"
|
||||
[ ! "$mtdnum" ] && continue
|
||||
if [ "$mtdnum" = "$cmtdnum" ]; then
|
||||
ubidev=$( basename $ubidevdir )
|
||||
ubi_mknod "$ubidevdir"
|
||||
@@ -56,128 +57,175 @@ nand_find_ubi() {
|
||||
}
|
||||
|
||||
nand_get_magic_long() {
|
||||
dd if="$1" skip=$2 bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
|
||||
(${3}cat "$1" | dd bs=4 "skip=${2:-0}" count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null
|
||||
}
|
||||
|
||||
get_magic_long_tar() {
|
||||
( tar xf $1 $2 -O | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null
|
||||
(tar xO${3}f "$1" "$2" | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null
|
||||
}
|
||||
|
||||
identify_magic() {
|
||||
local magic=$1
|
||||
case "$magic" in
|
||||
"55424923")
|
||||
echo "ubi"
|
||||
;;
|
||||
"31181006")
|
||||
echo "ubifs"
|
||||
;;
|
||||
"68737173")
|
||||
echo "squashfs"
|
||||
;;
|
||||
"d00dfeed")
|
||||
echo "fit"
|
||||
;;
|
||||
"4349"*)
|
||||
echo "combined"
|
||||
;;
|
||||
*)
|
||||
echo "unknown $magic"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
identify() {
|
||||
identify_magic $(nand_get_magic_long "$1" "${2:-0}")
|
||||
identify_magic_long $(nand_get_magic_long "$@")
|
||||
}
|
||||
|
||||
identify_tar() {
|
||||
identify_magic $(get_magic_long_tar "$1" "$2")
|
||||
identify_magic_long $(get_magic_long_tar "$@")
|
||||
}
|
||||
|
||||
identify_if_gzip() {
|
||||
if [ "$(identify "$1")" = gzip ]; then echo -n z; fi
|
||||
}
|
||||
|
||||
nand_restore_config() {
|
||||
sync
|
||||
local ubidev=$( nand_find_ubi $CI_UBIPART )
|
||||
local ubidev=$( nand_find_ubi "${CI_ROOT_UBIPART:-$CI_UBIPART}" )
|
||||
local ubivol="$( nand_find_volume $ubidev rootfs_data )"
|
||||
[ ! "$ubivol" ] &&
|
||||
ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
|
||||
if [ ! "$ubivol" ]; then
|
||||
ubivol="$( nand_find_volume $ubidev "$CI_ROOTPART" )"
|
||||
if [ ! "$ubivol" ]; then
|
||||
echo "cannot find ubifs data volume"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
mkdir /tmp/new_root
|
||||
if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then
|
||||
echo "mounting ubifs $ubivol failed"
|
||||
echo "cannot mount ubifs volume $ubivol"
|
||||
rmdir /tmp/new_root
|
||||
return 1
|
||||
fi
|
||||
mv "$1" "/tmp/new_root/$BACKUP_FILE"
|
||||
umount /tmp/new_root
|
||||
sync
|
||||
if mv "$1" "/tmp/new_root/$BACKUP_FILE"; then
|
||||
if umount /tmp/new_root; then
|
||||
echo "configuration saved"
|
||||
rmdir /tmp/new_root
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
umount /tmp/new_root
|
||||
fi
|
||||
echo "could not save configuration to ubifs volume $ubivol"
|
||||
rmdir /tmp/new_root
|
||||
return 1
|
||||
}
|
||||
|
||||
nand_remove_ubiblock() {
|
||||
local ubivol="$1"
|
||||
|
||||
local ubiblk="ubiblock${ubivol:3}"
|
||||
if [ -e "/dev/$ubiblk" ]; then
|
||||
umount "/dev/$ubiblk" 2>/dev/null && echo "unmounted /dev/$ubiblk" || :
|
||||
if ! ubiblock -r "/dev/$ubivol"; then
|
||||
echo "cannot remove $ubiblk"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
nand_attach_ubi() {
|
||||
local ubipart="$1"
|
||||
local has_env="${2:-0}"
|
||||
|
||||
local mtdnum="$( find_mtd_index "$ubipart" )"
|
||||
if [ ! "$mtdnum" ]; then
|
||||
>&2 echo "cannot find ubi mtd partition $ubipart"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local ubidev="$( nand_find_ubi "$ubipart" )"
|
||||
if [ ! "$ubidev" ]; then
|
||||
>&2 ubiattach -m "$mtdnum"
|
||||
ubidev="$( nand_find_ubi "$ubipart" )"
|
||||
|
||||
if [ ! "$ubidev" ]; then
|
||||
>&2 ubiformat /dev/mtd$mtdnum -y
|
||||
>&2 ubiattach -m "$mtdnum"
|
||||
ubidev="$( nand_find_ubi "$ubipart" )"
|
||||
|
||||
if [ ! "$ubidev" ]; then
|
||||
>&2 echo "cannot attach ubi mtd partition $ubipart"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$has_env" -gt 0 ]; then
|
||||
>&2 ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB
|
||||
>&2 ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$ubidev"
|
||||
return 0
|
||||
}
|
||||
|
||||
nand_detach_ubi() {
|
||||
local ubipart="$1"
|
||||
|
||||
local mtdnum="$( find_mtd_index "$ubipart" )"
|
||||
if [ ! "$mtdnum" ]; then
|
||||
echo "cannot find ubi mtd partition $ubipart"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local ubidev="$( nand_find_ubi "$ubipart" )"
|
||||
if [ "$ubidev" ]; then
|
||||
for ubivol in $(find /dev -name "${ubidev}_*" -maxdepth 1 | sort); do
|
||||
ubivol="${ubivol:5}"
|
||||
nand_remove_ubiblock "$ubivol" || :
|
||||
umount "/dev/$ubivol" && echo "unmounted /dev/$ubivol" || :
|
||||
done
|
||||
if ! ubidetach -m "$mtdnum"; then
|
||||
echo "cannot detach ubi mtd partition $ubipart"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
nand_upgrade_prepare_ubi() {
|
||||
local rootfs_length="$1"
|
||||
local rootfs_type="$2"
|
||||
local rootfs_data_max="$(fw_printenv -n rootfs_data_max 2>/dev/null)"
|
||||
local rootfs_data_max="$(fw_printenv -n rootfs_data_max 2> /dev/null)"
|
||||
[ -n "$rootfs_data_max" ] && rootfs_data_max=$((rootfs_data_max))
|
||||
|
||||
local kernel_length="$3"
|
||||
local has_env="${4:-0}"
|
||||
local kern_ubidev
|
||||
local root_ubidev
|
||||
|
||||
[ -n "$rootfs_length" -o -n "$kernel_length" ] || return 1
|
||||
|
||||
local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
|
||||
if [ ! "$mtdnum" ]; then
|
||||
echo "cannot find ubi mtd partition $CI_UBIPART"
|
||||
return 1
|
||||
if [ -n "$CI_KERN_UBIPART" -a -n "$CI_ROOT_UBIPART" ]; then
|
||||
kern_ubidev="$( nand_attach_ubi "$CI_KERN_UBIPART" "$has_env" )"
|
||||
[ -n "$kern_ubidev" ] || return 1
|
||||
root_ubidev="$( nand_attach_ubi "$CI_ROOT_UBIPART" )"
|
||||
[ -n "$root_ubidev" ] || return 1
|
||||
else
|
||||
kern_ubidev="$( nand_attach_ubi "$CI_UBIPART" "$has_env" )"
|
||||
[ -n "$kern_ubidev" ] || return 1
|
||||
root_ubidev="$kern_ubidev"
|
||||
fi
|
||||
|
||||
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
|
||||
if [ ! "$ubidev" ]; then
|
||||
ubiattach -m "$mtdnum"
|
||||
sync
|
||||
ubidev="$( nand_find_ubi "$CI_UBIPART" )"
|
||||
fi
|
||||
local kern_ubivol="$( nand_find_volume $kern_ubidev "$CI_KERNPART" )"
|
||||
local root_ubivol="$( nand_find_volume $root_ubidev "$CI_ROOTPART" )"
|
||||
local data_ubivol="$( nand_find_volume $root_ubidev rootfs_data )"
|
||||
[ "$root_ubivol" = "$kern_ubivol" ] && root_ubivol=
|
||||
|
||||
if [ ! "$ubidev" ]; then
|
||||
ubiformat /dev/mtd$mtdnum -y
|
||||
ubiattach -m "$mtdnum"
|
||||
sync
|
||||
ubidev="$( nand_find_ubi "$CI_UBIPART" )"
|
||||
[ "$has_env" -gt 0 ] && {
|
||||
ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB
|
||||
ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB
|
||||
}
|
||||
fi
|
||||
|
||||
local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )"
|
||||
local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
|
||||
local data_ubivol="$( nand_find_volume $ubidev rootfs_data )"
|
||||
|
||||
local ubiblk ubiblkvol
|
||||
for ubiblk in /dev/ubiblock*_? ; do
|
||||
[ -e "$ubiblk" ] || continue
|
||||
echo "removing ubiblock${ubiblk:13}"
|
||||
ubiblkvol=ubi${ubiblk:13}
|
||||
if ! ubiblock -r /dev/$ubiblkvol; then
|
||||
echo "cannot remove $ubiblk"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
# remove ubiblocks
|
||||
[ "$kern_ubivol" ] && { nand_remove_ubiblock $kern_ubivol || return 1; }
|
||||
[ "$root_ubivol" ] && { nand_remove_ubiblock $root_ubivol || return 1; }
|
||||
[ "$data_ubivol" ] && { nand_remove_ubiblock $data_ubivol || return 1; }
|
||||
|
||||
# kill volumes
|
||||
[ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_KERNPART || true
|
||||
[ "$root_ubivol" -a "$root_ubivol" != "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_ROOTPART || true
|
||||
[ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true
|
||||
[ "$kern_ubivol" ] && ubirmvol /dev/$kern_ubidev -N "$CI_KERNPART" || :
|
||||
[ "$root_ubivol" ] && ubirmvol /dev/$root_ubidev -N "$CI_ROOTPART" || :
|
||||
[ "$data_ubivol" ] && ubirmvol /dev/$root_ubidev -N rootfs_data || :
|
||||
|
||||
# update kernel
|
||||
# create kernel vol
|
||||
if [ -n "$kernel_length" ]; then
|
||||
if ! ubimkvol /dev/$ubidev -N $CI_KERNPART -s $kernel_length; then
|
||||
if ! ubimkvol /dev/$kern_ubidev -N "$CI_KERNPART" -s $kernel_length; then
|
||||
echo "cannot create kernel volume"
|
||||
return 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
# update rootfs
|
||||
# create rootfs vol
|
||||
if [ -n "$rootfs_length" ]; then
|
||||
local rootfs_size_param
|
||||
if [ "$rootfs_type" = "ubifs" ]; then
|
||||
@@ -185,157 +233,224 @@ nand_upgrade_prepare_ubi() {
|
||||
else
|
||||
rootfs_size_param="-s $rootfs_length"
|
||||
fi
|
||||
if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $rootfs_size_param; then
|
||||
if ! ubimkvol /dev/$root_ubidev -N "$CI_ROOTPART" $rootfs_size_param; then
|
||||
echo "cannot create rootfs volume"
|
||||
return 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
# create rootfs_data for non-ubifs rootfs
|
||||
# create rootfs_data vol for non-ubifs rootfs
|
||||
if [ "$rootfs_type" != "ubifs" ]; then
|
||||
local availeb=$(cat /sys/devices/virtual/ubi/$ubidev/avail_eraseblocks)
|
||||
local ebsize=$(cat /sys/devices/virtual/ubi/$ubidev/eraseblock_size)
|
||||
local avail_size=$((availeb * ebsize))
|
||||
local rootfs_data_size_param="-m"
|
||||
if [ -n "$rootfs_data_max" ] &&
|
||||
[ "$rootfs_data_max" != "0" ] &&
|
||||
[ "$rootfs_data_max" -le "$avail_size" ]; then
|
||||
if [ -n "$rootfs_data_max" ]; then
|
||||
rootfs_data_size_param="-s $rootfs_data_max"
|
||||
fi
|
||||
if ! ubimkvol /dev/$ubidev -N rootfs_data $rootfs_data_size_param; then
|
||||
echo "cannot initialize rootfs_data volume"
|
||||
return 1
|
||||
if ! ubimkvol /dev/$root_ubidev -N rootfs_data $rootfs_data_size_param; then
|
||||
if ! ubimkvol /dev/$root_ubidev -N rootfs_data -m; then
|
||||
echo "cannot initialize rootfs_data volume"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
sync
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
nand_do_upgrade_success() {
|
||||
local conf_tar="/tmp/sysupgrade.tgz"
|
||||
|
||||
sync
|
||||
[ -f "$conf_tar" ] && nand_restore_config "$conf_tar"
|
||||
echo "sysupgrade successful"
|
||||
umount -a
|
||||
reboot -f
|
||||
}
|
||||
|
||||
# Flash the UBI image to MTD partition
|
||||
# Write the UBI image to MTD ubi partition
|
||||
nand_upgrade_ubinized() {
|
||||
local ubi_file="$1"
|
||||
local mtdnum="$(find_mtd_index "$CI_UBIPART")"
|
||||
local gz="$2"
|
||||
|
||||
[ ! "$mtdnum" ] && {
|
||||
CI_UBIPART="rootfs"
|
||||
mtdnum="$(find_mtd_index "$CI_UBIPART")"
|
||||
}
|
||||
local ubi_length=$( (${gz}cat "$ubi_file" | wc -c) 2> /dev/null)
|
||||
|
||||
if [ ! "$mtdnum" ]; then
|
||||
echo "cannot find mtd device $CI_UBIPART"
|
||||
umount -a
|
||||
reboot -f
|
||||
fi
|
||||
nand_detach_ubi "$CI_UBIPART" || return 1
|
||||
|
||||
local mtddev="/dev/mtd${mtdnum}"
|
||||
ubidetach -p "${mtddev}" || true
|
||||
sync
|
||||
ubiformat "${mtddev}" -y -f "${ubi_file}"
|
||||
ubiattach -p "${mtddev}"
|
||||
nand_do_upgrade_success
|
||||
local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
|
||||
${gz}cat "$ubi_file" | ubiformat "/dev/mtd$mtdnum" -S "$ubi_length" -y -f - && ubiattach -m "$mtdnum"
|
||||
}
|
||||
|
||||
# Write the UBIFS image to UBI volume
|
||||
# Write the UBIFS image to UBI rootfs volume
|
||||
nand_upgrade_ubifs() {
|
||||
local rootfs_length=$( (cat $1 | wc -c) 2> /dev/null)
|
||||
local ubifs_file="$1"
|
||||
local gz="$2"
|
||||
|
||||
nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "" ""
|
||||
local ubifs_length=$( (${gz}cat "$ubifs_file" | wc -c) 2> /dev/null)
|
||||
|
||||
nand_upgrade_prepare_ubi "$ubifs_length" "ubifs" "" "" || return 1
|
||||
|
||||
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
|
||||
local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)"
|
||||
ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1
|
||||
|
||||
nand_do_upgrade_success
|
||||
local root_ubivol="$(nand_find_volume $ubidev "$CI_ROOTPART")"
|
||||
${gz}cat "$ubifs_file" | ubiupdatevol /dev/$root_ubivol -s "$ubifs_length" -
|
||||
}
|
||||
|
||||
# Write the FIT image to UBI kernel volume
|
||||
nand_upgrade_fit() {
|
||||
local fit_file="$1"
|
||||
local fit_length="$(wc -c < "$fit_file")"
|
||||
local gz="$2"
|
||||
|
||||
nand_upgrade_prepare_ubi "" "" "$fit_length" "1"
|
||||
local fit_length=$( (${gz}cat "$fit_file" | wc -c) 2> /dev/null)
|
||||
|
||||
nand_upgrade_prepare_ubi "" "" "$fit_length" "1" || return 1
|
||||
|
||||
local fit_ubidev="$(nand_find_ubi "$CI_UBIPART")"
|
||||
local fit_ubivol="$(nand_find_volume $fit_ubidev "$CI_KERNPART")"
|
||||
ubiupdatevol /dev/$fit_ubivol -s $fit_length $fit_file
|
||||
|
||||
nand_do_upgrade_success
|
||||
${gz}cat "$fit_file" | ubiupdatevol /dev/$fit_ubivol -s "$fit_length" -
|
||||
}
|
||||
|
||||
# Write images in the TAR file to MTD partitions and/or UBI volumes as required
|
||||
nand_upgrade_tar() {
|
||||
local tar_file="$1"
|
||||
local kernel_mtd="$(find_mtd_index $CI_KERNPART)"
|
||||
local gz="$2"
|
||||
local jffs2_markers="${CI_JFFS2_CLEAN_MARKERS:-0}"
|
||||
|
||||
local board_dir=$(tar tf "$tar_file" | grep -m 1 '^sysupgrade-.*/$')
|
||||
board_dir=${board_dir%/}
|
||||
# WARNING: This fails if tar contains more than one 'sysupgrade-*' directory.
|
||||
local board_dir="$(tar t${gz}f "$tar_file" | grep -m 1 '^sysupgrade-.*/$')"
|
||||
board_dir="${board_dir%/}"
|
||||
|
||||
kernel_length=$( (tar xf "$tar_file" ${board_dir}/kernel -O | wc -c) 2> /dev/null)
|
||||
local has_rootfs=0
|
||||
local rootfs_length
|
||||
local kernel_mtd kernel_length
|
||||
if [ "$CI_KERNPART" != "none" ]; then
|
||||
kernel_mtd="$(find_mtd_index "$CI_KERNPART")"
|
||||
kernel_length=$( (tar xO${gz}f "$tar_file" "$board_dir/kernel" | wc -c) 2> /dev/null)
|
||||
[ "$kernel_length" = 0 ] && kernel_length=
|
||||
fi
|
||||
local rootfs_length=$( (tar xO${gz}f "$tar_file" "$board_dir/root" | wc -c) 2> /dev/null)
|
||||
[ "$rootfs_length" = 0 ] && rootfs_length=
|
||||
local rootfs_type
|
||||
[ "$rootfs_length" ] && rootfs_type="$(identify_tar "$tar_file" "$board_dir/root" "$gz")"
|
||||
|
||||
tar tf "$tar_file" ${board_dir}/root 1>/dev/null 2>/dev/null && has_rootfs=1
|
||||
[ "$has_rootfs" = "1" ] && {
|
||||
rootfs_length=$( (tar xf "$tar_file" ${board_dir}/root -O | wc -c) 2> /dev/null)
|
||||
rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)"
|
||||
}
|
||||
local ubi_kernel_length
|
||||
if [ "$kernel_length" ]; then
|
||||
if [ "$kernel_mtd" ]; then
|
||||
# On some devices, the raw kernel and ubi partitions overlap.
|
||||
# These devices brick if the kernel partition is erased.
|
||||
# Hence only invalidate kernel for now.
|
||||
dd if=/dev/zero bs=4096 count=1 2> /dev/null | \
|
||||
mtd write - "$CI_KERNPART"
|
||||
else
|
||||
ubi_kernel_length="$kernel_length"
|
||||
fi
|
||||
fi
|
||||
|
||||
local has_kernel=1
|
||||
local has_env=0
|
||||
nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$ubi_kernel_length" "$has_env" || return 1
|
||||
|
||||
[ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && {
|
||||
tar xf "$tar_file" ${board_dir}/kernel -O | mtd write - $CI_KERNPART
|
||||
}
|
||||
[ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=
|
||||
if [ "$rootfs_length" ]; then
|
||||
local ubidev="$( nand_find_ubi "${CI_ROOT_UBIPART:-$CI_UBIPART}" )"
|
||||
local root_ubivol="$( nand_find_volume $ubidev "$CI_ROOTPART" )"
|
||||
tar xO${gz}f "$tar_file" "$board_dir/root" | \
|
||||
ubiupdatevol /dev/$root_ubivol -s "$rootfs_length" -
|
||||
fi
|
||||
if [ "$kernel_length" ]; then
|
||||
if [ "$kernel_mtd" ]; then
|
||||
if [ "$jffs2_markers" = 1 ]; then
|
||||
flash_erase -j "/dev/mtd${kernel_mtd}" 0 0
|
||||
tar xO${gz}f "$tar_file" "$board_dir/kernel" | \
|
||||
nandwrite "/dev/mtd${kernel_mtd}" -
|
||||
else
|
||||
tar xO${gz}f "$tar_file" "$board_dir/kernel" | \
|
||||
mtd write - "$CI_KERNPART"
|
||||
fi
|
||||
else
|
||||
local ubidev="$( nand_find_ubi "${CI_KERN_UBIPART:-$CI_UBIPART}" )"
|
||||
local kern_ubivol="$( nand_find_volume $ubidev "$CI_KERNPART" )"
|
||||
tar xO${gz}f "$tar_file" "$board_dir/kernel" | \
|
||||
ubiupdatevol /dev/$kern_ubivol -s "$kernel_length" -
|
||||
fi
|
||||
fi
|
||||
|
||||
nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "${has_kernel:+$kernel_length}" "$has_env"
|
||||
return 0
|
||||
}
|
||||
|
||||
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
|
||||
[ "$has_kernel" = "1" ] && {
|
||||
local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )"
|
||||
tar xf "$tar_file" ${board_dir}/kernel -O | \
|
||||
ubiupdatevol /dev/$kern_ubivol -s $kernel_length -
|
||||
}
|
||||
nand_verify_if_gzip_file() {
|
||||
local file="$1"
|
||||
local gz="$2"
|
||||
|
||||
[ "$has_rootfs" = "1" ] && {
|
||||
local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
|
||||
tar xf "$tar_file" ${board_dir}/root -O | \
|
||||
ubiupdatevol /dev/$root_ubivol -s $rootfs_length -
|
||||
}
|
||||
nand_do_upgrade_success
|
||||
if [ "$gz" = z ]; then
|
||||
echo "verifying compressed sysupgrade file integrity"
|
||||
if ! gzip -t "$file"; then
|
||||
echo "corrupted compressed sysupgrade file"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
nand_verify_tar_file() {
|
||||
local file="$1"
|
||||
local gz="$2"
|
||||
|
||||
echo "verifying sysupgrade tar file integrity"
|
||||
if ! tar xO${gz}f "$file" > /dev/null; then
|
||||
echo "corrupted sysupgrade tar file"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
nand_do_flash_file() {
|
||||
local file="$1"
|
||||
|
||||
local gz="$(identify_if_gzip "$file")"
|
||||
local file_type="$(identify "$file" "" "$gz")"
|
||||
|
||||
[ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART=rootfs
|
||||
|
||||
case "$file_type" in
|
||||
"fit")
|
||||
nand_verify_if_gzip_file "$file" "$gz" || return 1
|
||||
nand_upgrade_fit "$file" "$gz"
|
||||
;;
|
||||
"ubi")
|
||||
nand_verify_if_gzip_file "$file" "$gz" || return 1
|
||||
nand_upgrade_ubinized "$file" "$gz"
|
||||
;;
|
||||
"ubifs")
|
||||
nand_verify_if_gzip_file "$file" "$gz" || return 1
|
||||
nand_upgrade_ubifs "$file" "$gz"
|
||||
;;
|
||||
*)
|
||||
nand_verify_tar_file "$file" "$gz" || return 1
|
||||
nand_upgrade_tar "$file" "$gz"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
nand_do_restore_config() {
|
||||
local conf_tar="/tmp/sysupgrade.tgz"
|
||||
[ ! -f "$conf_tar" ] || nand_restore_config "$conf_tar"
|
||||
}
|
||||
|
||||
# Recognize type of passed file and start the upgrade process
|
||||
nand_do_upgrade() {
|
||||
local file_type=$(identify $1)
|
||||
local file="$1"
|
||||
|
||||
[ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
|
||||
|
||||
case "$file_type" in
|
||||
"fit") nand_upgrade_fit $1;;
|
||||
"ubi") nand_upgrade_ubinized $1;;
|
||||
"ubifs") nand_upgrade_ubifs $1;;
|
||||
*) nand_upgrade_tar $1;;
|
||||
esac
|
||||
sync
|
||||
nand_do_flash_file "$file" && nand_do_upgrade_success
|
||||
nand_do_upgrade_failed
|
||||
}
|
||||
|
||||
# Check if passed file is a valid one for NAND sysupgrade. Currently it accepts
|
||||
# 3 types of files:
|
||||
# 1) UBI - should contain an ubinized image, header is checked for the proper
|
||||
# MAGIC
|
||||
# 2) UBIFS - should contain UBIFS partition that will replace "rootfs" volume,
|
||||
# header is checked for the proper MAGIC
|
||||
# 3) TAR - archive has to include "sysupgrade-BOARD" directory with a non-empty
|
||||
# "CONTROL" file (at this point its content isn't verified)
|
||||
nand_do_upgrade_success() {
|
||||
if nand_do_restore_config && sync; then
|
||||
echo "sysupgrade successful"
|
||||
umount -a
|
||||
reboot -f
|
||||
fi
|
||||
nand_do_upgrade_failed
|
||||
}
|
||||
|
||||
nand_do_upgrade_failed() {
|
||||
sync
|
||||
echo "sysupgrade failed"
|
||||
# Should we reboot or bring up some failsafe mode instead?
|
||||
umount -a
|
||||
reboot -f
|
||||
}
|
||||
|
||||
# Check if passed file is a valid one for NAND sysupgrade.
|
||||
# Currently it accepts 4 types of files:
|
||||
# 1) UBI: a ubinized image containing required UBI volumes.
|
||||
# 2) UBIFS: a UBIFS rootfs volume image.
|
||||
# 3) FIT: a FIT image containing kernel and rootfs.
|
||||
# 4) TAR: an archive that includes directory "sysupgrade-${BOARD_NAME}" containing
|
||||
# a non-empty "CONTROL" file and required partition and/or volume images.
|
||||
#
|
||||
# You usually want to call this function in platform_check_image.
|
||||
#
|
||||
@@ -343,14 +458,25 @@ nand_do_upgrade() {
|
||||
# $(2): file to be checked
|
||||
nand_do_platform_check() {
|
||||
local board_name="$1"
|
||||
local tar_file="$2"
|
||||
local control_length=$( (tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null)
|
||||
local file_type="$(identify $2)"
|
||||
local file="$2"
|
||||
|
||||
[ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" -a "$file_type" != "fit" ] && {
|
||||
echo "Invalid sysupgrade file."
|
||||
return 1
|
||||
}
|
||||
local gz="$(identify_if_gzip "$file")"
|
||||
local file_type="$(identify "$file" "" "$gz")"
|
||||
local control_length=$( (tar xO${gz}f "$file" "sysupgrade-${board_name//,/_}/CONTROL" | wc -c) 2> /dev/null)
|
||||
|
||||
if [ "$control_length" = 0 ]; then
|
||||
control_length=$( (tar xO${gz}f "$file" "sysupgrade-${board_name//_/,}/CONTROL" | wc -c) 2> /dev/null)
|
||||
fi
|
||||
|
||||
if [ "$control_length" != 0 ]; then
|
||||
nand_verify_tar_file "$file" "$gz" || return 1
|
||||
else
|
||||
nand_verify_if_gzip_file "$file" "$gz" || return 1
|
||||
if [ "$file_type" != "fit" -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ]; then
|
||||
echo "invalid sysupgrade file"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -45,7 +45,8 @@ switch_to_ramfs() {
|
||||
mtd partx losetup mkfs.ext4 nandwrite flash_erase \
|
||||
ubiupdatevol ubiattach ubiblock ubiformat \
|
||||
ubidetach ubirsvol ubirmvol ubimkvol \
|
||||
snapshot snapshot_tool date \
|
||||
snapshot snapshot_tool date logger \
|
||||
/usr/sbin/fw_printenv /usr/bin/fwtool \
|
||||
$RAMFS_COPY_LOSETUP $RAMFS_COPY_LVM \
|
||||
$RAMFS_COPY_BIN
|
||||
do
|
||||
|
||||
@@ -14,6 +14,10 @@ PKG_SOURCE_DATE:=2022-12-22
|
||||
PKG_SOURCE_VERSION:=5b509e80384ab019ac11aa90c81ec0dbb5b0d7f2
|
||||
PKG_MIRROR_HASH:=6fc25df4d28becd010ff4971b23731c08b53e69381a9e4c868091899712f78a9
|
||||
PATCH_DIR:=./patches-5.4
|
||||
else ifdef CONFIG_LINUX_6_1
|
||||
PKG_SOURCE_DATE:=2024-02-03
|
||||
PKG_SOURCE_VERSION:=9827df56b241601f29bf496b62545713c67afb61
|
||||
PKG_MIRROR_HASH:=d758db4228eed55c93fff8f87ec92d482b8507a68698b28dcf273e12b02ddf5f
|
||||
else ifdef CONFIG_LINUX_6_6
|
||||
PKG_SOURCE_DATE:=2024-02-03
|
||||
PKG_SOURCE_VERSION:=9827df56b241601f29bf496b62545713c67afb61
|
||||
|
||||
@@ -66,9 +66,7 @@ start()
|
||||
ethtool -K $c tx-checksum-ipv4 on >/dev/null 2>&1
|
||||
ethtool -K $c tx-checksum-ipv6 on >/dev/null 2>&1)
|
||||
ethtool -K $c tx-scatter-gather on >/dev/null 2>&1
|
||||
ethtool -K $c gso on >/dev/null 2>&1
|
||||
ethtool -K $c tso on >/dev/null 2>&1
|
||||
ethtool -K $c ufo on >/dev/null 2>&1
|
||||
done
|
||||
|
||||
[ -f /etc/index.htm ] && mv /etc/index.htm /usr/lib/lua/luci/view/admin_status/index.htm
|
||||
|
||||
@@ -12,15 +12,16 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/fstools.git
|
||||
PKG_MIRROR_HASH:=edda9151c73c1adfe369f5e315347344727a540ad57d3e2b41b9f57f9d4313fe
|
||||
PKG_SOURCE_DATE:=2023-01-22
|
||||
PKG_SOURCE_VERSION:=1ea5855e980cd88766dd9f615e78e7dd6edfbb74
|
||||
PKG_MIRROR_HASH:=32e39891455b602e9deb367c9ce2d099dc72353fad0bf0433307416925f7b393
|
||||
PKG_SOURCE_DATE:=2024-01-22
|
||||
PKG_SOURCE_VERSION:=08cd7083cac4bddf88459efa0881ee52858e7d0a
|
||||
CMAKE_INSTALL:=1
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=
|
||||
|
||||
PKG_USE_MIPS16:=0
|
||||
PKG_BUILD_FLAGS:=no-mips16
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
PKG_BUILD_DEPENDS := util-linux
|
||||
@@ -48,7 +49,7 @@ define Package/fstools/config
|
||||
depends on PACKAGE_fstools
|
||||
depends on NAND_SUPPORT
|
||||
bool "Support extroot functionality with UBIFS"
|
||||
default n
|
||||
default y
|
||||
help
|
||||
This option makes it possible to use extroot functionality if the root filesystem resides on an UBIFS partition
|
||||
|
||||
@@ -82,7 +83,7 @@ define Package/block-mount
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
TITLE:=Block device mounting and checking
|
||||
DEPENDS:=+fstools +ubox +libubox +libuci +libblobmsg-json +libjson-c
|
||||
DEPENDS:=+ubox +libubox +libuci +libblobmsg-json +libjson-c
|
||||
endef
|
||||
|
||||
define Package/blockd
|
||||
|
||||
-129
@@ -1,129 +0,0 @@
|
||||
From: Qi Liu <liuqi_colin@msn.com>
|
||||
|
||||
In order to support extroot, block extroot command has to be able to
|
||||
discover and properly mount the rootfs_data volume in order to discover
|
||||
the extroot volume. Currently this process can only discover MTD devices.
|
||||
This patch leverages libfstools in a similar way as mount_root to
|
||||
discover, initialize, and mount rootfs_data volume. It would enable any
|
||||
device with non-MTD rootfs_data volume to support extroot, including x86.
|
||||
|
||||
Signed-off-by: Qi Liu <liuqi_colin@msn.com>
|
||||
---
|
||||
CMakeLists.txt | 4 ++--
|
||||
block.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||||
libfstools/fstype.h | 12 ++++++++++++
|
||||
libfstools/libfstools.h | 11 +----------
|
||||
4 files changed, 55 insertions(+), 12 deletions(-)
|
||||
create mode 100644 libfstools/fstype.h
|
||||
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -78,9 +78,9 @@ INSTALL(TARGETS blockd RUNTIME DESTINATI
|
||||
ADD_EXECUTABLE(block block.c probe.c probe-libblkid.c)
|
||||
IF(DEFINED CMAKE_UBIFS_EXTROOT)
|
||||
ADD_DEFINITIONS(-DUBIFS_EXTROOT)
|
||||
- TARGET_LINK_LIBRARIES(block blkid-tiny dl uci ubox ubus blobmsg_json ubi-utils ${json})
|
||||
+ TARGET_LINK_LIBRARIES(block fstools blkid-tiny dl uci ubox ubus blobmsg_json ubi-utils ${json})
|
||||
ELSE(DEFINED CMAKE_UBIFS_EXTROOT)
|
||||
- TARGET_LINK_LIBRARIES(block blkid-tiny dl uci ubox ubus blobmsg_json ${json})
|
||||
+ TARGET_LINK_LIBRARIES(block fstools blkid-tiny dl uci ubox ubus blobmsg_json ${json})
|
||||
ENDIF(DEFINED CMAKE_UBIFS_EXTROOT)
|
||||
INSTALL(TARGETS block RUNTIME DESTINATION sbin)
|
||||
|
||||
--- a/block.c
|
||||
+++ b/block.c
|
||||
@@ -44,6 +44,8 @@
|
||||
#include <libubox/vlist.h>
|
||||
#include <libubus.h>
|
||||
|
||||
+#include "libfstools/fstype.h"
|
||||
+#include "libfstools/volume.h"
|
||||
#include "probe.h"
|
||||
|
||||
#define AUTOFS_MOUNT_PATH "/tmp/run/blockd/"
|
||||
@@ -1696,6 +1698,44 @@ static int main_extroot(int argc, char *
|
||||
}
|
||||
#endif
|
||||
|
||||
+ /* Find volume using libfstools */
|
||||
+ struct volume *data = volume_find("rootfs_data");
|
||||
+ if (data) {
|
||||
+ volume_init(data);
|
||||
+
|
||||
+ switch (volume_identify(data)) {
|
||||
+ case FS_EXT4: {
|
||||
+ char cfg[] = "/tmp/ext4_cfg";
|
||||
+
|
||||
+ /* Mount volume and try extroot (using fstab from that vol) */
|
||||
+ mkdir_p(cfg, 0755);
|
||||
+ if (!mount(data->blk, cfg, "ext4", MS_NOATIME, NULL)) {
|
||||
+ err = mount_extroot(cfg);
|
||||
+ umount2(cfg, MNT_DETACH);
|
||||
+ }
|
||||
+ if (err < 0)
|
||||
+ rmdir("/tmp/overlay");
|
||||
+ rmdir(cfg);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ case FS_F2FS: {
|
||||
+ char cfg[] = "/tmp/f2fs_cfg";
|
||||
+
|
||||
+ /* Mount volume and try extroot (using fstab from that vol) */
|
||||
+ mkdir_p(cfg, 0755);
|
||||
+ if (!mount(data->blk, cfg, "f2fs", MS_NOATIME, NULL)) {
|
||||
+ err = mount_extroot(cfg);
|
||||
+ umount2(cfg, MNT_DETACH);
|
||||
+ }
|
||||
+ if (err < 0)
|
||||
+ rmdir("/tmp/overlay");
|
||||
+ rmdir(cfg);
|
||||
+ return err;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* As a last resort look for /etc/config/fstab on "rootfs" partition */
|
||||
return mount_extroot(NULL);
|
||||
}
|
||||
--- /dev/null
|
||||
+++ b/libfstools/fstype.h
|
||||
@@ -0,0 +1,13 @@
|
||||
+#ifndef _FS_TYPE_H__
|
||||
+#define _FS_TYPE_H__
|
||||
+enum {
|
||||
+ FS_NONE,
|
||||
+ FS_SNAPSHOT,
|
||||
+ FS_JFFS2,
|
||||
+ FS_DEADCODE,
|
||||
+ FS_UBIFS,
|
||||
+ FS_F2FS,
|
||||
+ FS_EXT4,
|
||||
+ FS_TARGZ,
|
||||
+};
|
||||
+#endif
|
||||
\ No newline at end of file
|
||||
--- a/libfstools/libfstools.h
|
||||
+++ b/libfstools/libfstools.h
|
||||
@@ -18,20 +18,10 @@
|
||||
#include <libubox/blob.h>
|
||||
#include <libubox/ulog.h>
|
||||
#include <libubox/utils.h>
|
||||
+#include "fstype.h"
|
||||
|
||||
struct volume;
|
||||
|
||||
-enum {
|
||||
- FS_NONE,
|
||||
- FS_SNAPSHOT,
|
||||
- FS_JFFS2,
|
||||
- FS_DEADCODE,
|
||||
- FS_UBIFS,
|
||||
- FS_F2FS,
|
||||
- FS_EXT4,
|
||||
- FS_TARGZ,
|
||||
-};
|
||||
-
|
||||
enum fs_state {
|
||||
FS_STATE_UNKNOWN,
|
||||
FS_STATE_PENDING,
|
||||
@@ -16,7 +16,7 @@ define Package/fitblk
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
TITLE:=fitblk firmware release tool
|
||||
DEPENDS:=@LINUX_6_1
|
||||
DEPENDS:=@!LINUX_5_15
|
||||
endef
|
||||
|
||||
define Package/fitblk/description
|
||||
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
From 66a5c40f60f5d88ad8d47ba6a4ba05892853fa1f Mon Sep 17 00:00:00 2001
|
||||
From: Tanzir Hasan <tanzirh@google.com>
|
||||
Date: Tue, 26 Dec 2023 18:00:00 +0000
|
||||
Subject: [PATCH] kernel.h: removed REPEAT_BYTE from kernel.h
|
||||
|
||||
This patch creates wordpart.h and includes it in asm/word-at-a-time.h
|
||||
for all architectures. WORD_AT_A_TIME_CONSTANTS depends on kernel.h
|
||||
because of REPEAT_BYTE. Moving this to another header and including it
|
||||
where necessary allows us to not include the bloated kernel.h. Making
|
||||
this implicit dependency on REPEAT_BYTE explicit allows for later
|
||||
improvements in the lib/string.c inclusion list.
|
||||
|
||||
Suggested-by: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
|
||||
Signed-off-by: Tanzir Hasan <tanzirh@google.com>
|
||||
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20231226-libstringheader-v6-1-80aa08c7652c@google.com
|
||||
Signed-off-by: Kees Cook <keescook@chromium.org>
|
||||
---
|
||||
arch/arm/include/asm/word-at-a-time.h | 3 ++-
|
||||
arch/arm64/include/asm/word-at-a-time.h | 3 ++-
|
||||
arch/powerpc/include/asm/word-at-a-time.h | 4 ++--
|
||||
arch/riscv/include/asm/word-at-a-time.h | 3 ++-
|
||||
arch/s390/include/asm/word-at-a-time.h | 3 ++-
|
||||
arch/sh/include/asm/word-at-a-time.h | 2 ++
|
||||
arch/x86/include/asm/word-at-a-time.h | 3 ++-
|
||||
arch/x86/kvm/mmu/mmu.c | 1 +
|
||||
fs/namei.c | 2 +-
|
||||
include/asm-generic/word-at-a-time.h | 3 ++-
|
||||
include/linux/kernel.h | 8 --------
|
||||
include/linux/wordpart.h | 13 +++++++++++++
|
||||
12 files changed, 31 insertions(+), 17 deletions(-)
|
||||
create mode 100644 include/linux/wordpart.h
|
||||
|
||||
--- a/arch/arm/include/asm/word-at-a-time.h
|
||||
+++ b/arch/arm/include/asm/word-at-a-time.h
|
||||
@@ -8,7 +8,8 @@
|
||||
* Little-endian word-at-a-time zero byte handling.
|
||||
* Heavily based on the x86 algorithm.
|
||||
*/
|
||||
-#include <linux/kernel.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/wordpart.h>
|
||||
|
||||
struct word_at_a_time {
|
||||
const unsigned long one_bits, high_bits;
|
||||
--- a/arch/arm64/include/asm/word-at-a-time.h
|
||||
+++ b/arch/arm64/include/asm/word-at-a-time.h
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
#ifndef __AARCH64EB__
|
||||
|
||||
-#include <linux/kernel.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/wordpart.h>
|
||||
|
||||
struct word_at_a_time {
|
||||
const unsigned long one_bits, high_bits;
|
||||
--- a/arch/powerpc/include/asm/word-at-a-time.h
|
||||
+++ b/arch/powerpc/include/asm/word-at-a-time.h
|
||||
@@ -4,8 +4,8 @@
|
||||
/*
|
||||
* Word-at-a-time interfaces for PowerPC.
|
||||
*/
|
||||
-
|
||||
-#include <linux/kernel.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/wordpart.h>
|
||||
#include <asm/asm-compat.h>
|
||||
#include <asm/extable.h>
|
||||
|
||||
--- a/arch/sh/include/asm/word-at-a-time.h
|
||||
+++ b/arch/sh/include/asm/word-at-a-time.h
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
# include <asm-generic/word-at-a-time.h>
|
||||
#else
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/wordpart.h>
|
||||
/*
|
||||
* Little-endian version cribbed from x86.
|
||||
*/
|
||||
--- a/arch/x86/include/asm/word-at-a-time.h
|
||||
+++ b/arch/x86/include/asm/word-at-a-time.h
|
||||
@@ -2,7 +2,8 @@
|
||||
#ifndef _ASM_WORD_AT_A_TIME_H
|
||||
#define _ASM_WORD_AT_A_TIME_H
|
||||
|
||||
-#include <linux/kernel.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/wordpart.h>
|
||||
|
||||
/*
|
||||
* This is largely generic for little-endian machines, but the
|
||||
--- a/arch/x86/kvm/mmu/mmu.c
|
||||
+++ b/arch/x86/kvm/mmu/mmu.c
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <linux/kern_levels.h>
|
||||
#include <linux/kstrtox.h>
|
||||
#include <linux/kthread.h>
|
||||
+#include <linux/wordpart.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/memtype.h>
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/export.h>
|
||||
-#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/wordpart.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/pagemap.h>
|
||||
--- a/include/asm-generic/word-at-a-time.h
|
||||
+++ b/include/asm-generic/word-at-a-time.h
|
||||
@@ -2,7 +2,8 @@
|
||||
#ifndef _ASM_WORD_AT_A_TIME_H
|
||||
#define _ASM_WORD_AT_A_TIME_H
|
||||
|
||||
-#include <linux/kernel.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/wordpart.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#ifdef __BIG_ENDIAN
|
||||
--- a/include/linux/kernel.h
|
||||
+++ b/include/linux/kernel.h
|
||||
@@ -36,14 +36,6 @@
|
||||
|
||||
#define STACK_MAGIC 0xdeadbeef
|
||||
|
||||
-/**
|
||||
- * REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value
|
||||
- * @x: value to repeat
|
||||
- *
|
||||
- * NOTE: @x is not checked for > 0xff; larger values produce odd results.
|
||||
- */
|
||||
-#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))
|
||||
-
|
||||
/* generic data direction definitions */
|
||||
#define READ 0
|
||||
#define WRITE 1
|
||||
--- /dev/null
|
||||
+++ b/include/linux/wordpart.h
|
||||
@@ -0,0 +1,13 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+
|
||||
+#ifndef _LINUX_WORDPART_H
|
||||
+#define _LINUX_WORDPART_H
|
||||
+/**
|
||||
+ * REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value
|
||||
+ * @x: value to repeat
|
||||
+ *
|
||||
+ * NOTE: @x is not checked for > 0xff; larger values produce odd results.
|
||||
+ */
|
||||
+#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))
|
||||
+
|
||||
+#endif // _LINUX_WORDPART_H
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
From adeb04362d74188c1e22ccb824b15a0a7b3de2f4 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Date: Wed, 14 Feb 2024 19:26:32 +0200
|
||||
Subject: [PATCH] kernel.h: Move upper_*_bits() and lower_*_bits() to
|
||||
wordpart.h
|
||||
|
||||
The wordpart.h header is collecting APIs related to the handling
|
||||
parts of the word (usually in byte granularity). The upper_*_bits()
|
||||
and lower_*_bits() are good candidates to be moved to there.
|
||||
|
||||
This helps to clean up header dependency hell with regard to kernel.h
|
||||
as the latter gathers completely unrelated stuff together and slows
|
||||
down compilation (especially when it's included into other header).
|
||||
|
||||
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Link: https://lore.kernel.org/r/20240214172752.3605073-1-andriy.shevchenko@linux.intel.com
|
||||
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
|
||||
Signed-off-by: Kees Cook <keescook@chromium.org>
|
||||
---
|
||||
include/linux/kernel.h | 30 ++----------------------------
|
||||
include/linux/wordpart.h | 29 +++++++++++++++++++++++++++++
|
||||
2 files changed, 31 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/include/linux/kernel.h
|
||||
+++ b/include/linux/kernel.h
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/static_call_types.h>
|
||||
#include <linux/instruction_pointer.h>
|
||||
+#include <linux/wordpart.h>
|
||||
+
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#include <uapi/linux/kernel.h>
|
||||
@@ -55,34 +57,6 @@
|
||||
} \
|
||||
)
|
||||
|
||||
-/**
|
||||
- * upper_32_bits - return bits 32-63 of a number
|
||||
- * @n: the number we're accessing
|
||||
- *
|
||||
- * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress
|
||||
- * the "right shift count >= width of type" warning when that quantity is
|
||||
- * 32-bits.
|
||||
- */
|
||||
-#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
|
||||
-
|
||||
-/**
|
||||
- * lower_32_bits - return bits 0-31 of a number
|
||||
- * @n: the number we're accessing
|
||||
- */
|
||||
-#define lower_32_bits(n) ((u32)((n) & 0xffffffff))
|
||||
-
|
||||
-/**
|
||||
- * upper_16_bits - return bits 16-31 of a number
|
||||
- * @n: the number we're accessing
|
||||
- */
|
||||
-#define upper_16_bits(n) ((u16)((n) >> 16))
|
||||
-
|
||||
-/**
|
||||
- * lower_16_bits - return bits 0-15 of a number
|
||||
- * @n: the number we're accessing
|
||||
- */
|
||||
-#define lower_16_bits(n) ((u16)((n) & 0xffff))
|
||||
-
|
||||
struct completion;
|
||||
struct user;
|
||||
|
||||
--- a/include/linux/wordpart.h
|
||||
+++ b/include/linux/wordpart.h
|
||||
@@ -2,6 +2,35 @@
|
||||
|
||||
#ifndef _LINUX_WORDPART_H
|
||||
#define _LINUX_WORDPART_H
|
||||
+
|
||||
+/**
|
||||
+ * upper_32_bits - return bits 32-63 of a number
|
||||
+ * @n: the number we're accessing
|
||||
+ *
|
||||
+ * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress
|
||||
+ * the "right shift count >= width of type" warning when that quantity is
|
||||
+ * 32-bits.
|
||||
+ */
|
||||
+#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
|
||||
+
|
||||
+/**
|
||||
+ * lower_32_bits - return bits 0-31 of a number
|
||||
+ * @n: the number we're accessing
|
||||
+ */
|
||||
+#define lower_32_bits(n) ((u32)((n) & 0xffffffff))
|
||||
+
|
||||
+/**
|
||||
+ * upper_16_bits - return bits 16-31 of a number
|
||||
+ * @n: the number we're accessing
|
||||
+ */
|
||||
+#define upper_16_bits(n) ((u16)((n) >> 16))
|
||||
+
|
||||
+/**
|
||||
+ * lower_16_bits - return bits 0-15 of a number
|
||||
+ * @n: the number we're accessing
|
||||
+ */
|
||||
+#define lower_16_bits(n) ((u16)((n) & 0xffff))
|
||||
+
|
||||
/**
|
||||
* REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value
|
||||
* @x: value to repeat
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
From 8e7daa85641c9559c113f6b217bdc923397de77c Mon Sep 17 00:00:00 2001
|
||||
From: William Zhang <william.zhang@broadcom.com>
|
||||
Date: Thu, 22 Feb 2024 19:47:58 -0800
|
||||
Subject: [PATCH] mtd: rawnand: brcmnand: Support write protection setting from
|
||||
dts
|
||||
|
||||
The write protection feature is controlled by the module parameter wp_on
|
||||
with default set to enabled. But not all the board use this feature
|
||||
especially in BCMBCA broadband board. And module parameter is not
|
||||
sufficient as different board can have different option. Add a device
|
||||
tree property and allow this feature to be configured through the board
|
||||
dts on per board basis.
|
||||
|
||||
Signed-off-by: William Zhang <william.zhang@broadcom.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Reviewed-by: Kamal Dasu <kamal.dasu@broadcom.com>
|
||||
Reviewed-by: David Regan <dregan@broadcom.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20240223034758.13753-14-william.zhang@broadcom.com
|
||||
---
|
||||
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
|
||||
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
|
||||
@@ -3188,6 +3188,10 @@ int brcmnand_probe(struct platform_devic
|
||||
/* Disable XOR addressing */
|
||||
brcmnand_rmw_reg(ctrl, BRCMNAND_CS_XOR, 0xff, 0, 0);
|
||||
|
||||
+ /* Check if the board connects the WP pin */
|
||||
+ if (of_property_read_bool(dn, "brcm,wp-not-connected"))
|
||||
+ wp_on = 0;
|
||||
+
|
||||
if (ctrl->features & BRCMNAND_HAS_WP) {
|
||||
/* Permanently disable write protection */
|
||||
if (wp_on == 2)
|
||||
+1
-1
@@ -10,7 +10,7 @@ This adds support for "linux,rootfs" binding that is used to mark flash
|
||||
partition containing rootfs. It's useful for devices using device tree
|
||||
that don't have bootloader passing root info in cmdline.
|
||||
|
||||
Signed-off-by: Rafa? Mi?ecki <rafal@milecki.pl>
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20221022211318.32009-2-zajec5@gmail.com
|
||||
---
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
From 773bbe10449731c9525457873e0c2342e5cf883b Mon Sep 17 00:00:00 2001
|
||||
From: Michael Walle <michael@walle.cc>
|
||||
Date: Thu, 11 Aug 2022 00:06:53 +0200
|
||||
Subject: [PATCH] mtd: spi-nor: add generic flash driver
|
||||
|
||||
Our SFDP parsing is everything we need to support all basic operations
|
||||
of a flash device. If the flash isn't found in our in-kernel flash
|
||||
database, gracefully fall back to a driver described solely by its SFDP
|
||||
tables.
|
||||
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
|
||||
Tested-by: Tudor Ambarus <tudor.ambarus@microchip.com>
|
||||
Reviewed-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
|
||||
Link: https://lore.kernel.org/r/20220810220654.1297699-7-michael@walle.cc
|
||||
---
|
||||
drivers/mtd/spi-nor/core.c | 26 ++++++++++++++++++++++++--
|
||||
drivers/mtd/spi-nor/core.h | 1 +
|
||||
drivers/mtd/spi-nor/sfdp.c | 27 +++++++++++++++++++++++++++
|
||||
3 files changed, 52 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/core.c
|
||||
+++ b/drivers/mtd/spi-nor/core.c
|
||||
@@ -1636,6 +1636,16 @@ static const struct spi_nor_manufacturer
|
||||
&spi_nor_xmc,
|
||||
};
|
||||
|
||||
+static const struct flash_info spi_nor_generic_flash = {
|
||||
+ .name = "spi-nor-generic",
|
||||
+ /*
|
||||
+ * JESD216 rev A doesn't specify the page size, therefore we need a
|
||||
+ * sane default.
|
||||
+ */
|
||||
+ .page_size = 256,
|
||||
+ .parse_sfdp = true,
|
||||
+};
|
||||
+
|
||||
static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
|
||||
const u8 *id)
|
||||
{
|
||||
@@ -1669,6 +1679,14 @@ static const struct flash_info *spi_nor_
|
||||
}
|
||||
|
||||
info = spi_nor_match_id(nor, id);
|
||||
+
|
||||
+ /* Fallback to a generic flash described only by its SFDP data. */
|
||||
+ if (!info) {
|
||||
+ ret = spi_nor_check_sfdp_signature(nor);
|
||||
+ if (!ret)
|
||||
+ info = &spi_nor_generic_flash;
|
||||
+ }
|
||||
+
|
||||
if (!info) {
|
||||
dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n",
|
||||
SPI_NOR_MAX_ID_LEN, id);
|
||||
@@ -2105,8 +2123,12 @@ static int spi_nor_select_pp(struct spi_
|
||||
* spi_nor_select_uniform_erase() - select optimum uniform erase type
|
||||
* @map: the erase map of the SPI NOR
|
||||
* @wanted_size: the erase type size to search for. Contains the value of
|
||||
- * info->sector_size or of the "small sector" size in case
|
||||
- * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined.
|
||||
+ * info->sector_size, the "small sector" size in case
|
||||
+ * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined or 0 if
|
||||
+ * there is no information about the sector size. The
|
||||
+ * latter is the case if the flash parameters are parsed
|
||||
+ * solely by SFDP, then the largest supported erase type
|
||||
+ * is selected.
|
||||
*
|
||||
* Once the optimum uniform sector erase command is found, disable all the
|
||||
* other.
|
||||
--- a/drivers/mtd/spi-nor/core.h
|
||||
+++ b/drivers/mtd/spi-nor/core.h
|
||||
@@ -708,6 +708,8 @@ int spi_nor_controller_ops_read_reg(stru
|
||||
int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode,
|
||||
const u8 *buf, size_t len);
|
||||
|
||||
+int spi_nor_check_sfdp_signature(struct spi_nor *nor);
|
||||
+
|
||||
static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
|
||||
{
|
||||
return container_of(mtd, struct spi_nor, mtd);
|
||||
--- a/drivers/mtd/spi-nor/sfdp.c
|
||||
+++ b/drivers/mtd/spi-nor/sfdp.c
|
||||
@@ -1250,6 +1250,33 @@ static void spi_nor_post_sfdp_fixups(str
|
||||
}
|
||||
|
||||
/**
|
||||
+ * spi_nor_check_sfdp_signature() - check for a valid SFDP signature
|
||||
+ * @nor: pointer to a 'struct spi_nor'
|
||||
+ *
|
||||
+ * Used to detect if the flash supports the RDSFDP command as well as the
|
||||
+ * presence of a valid SFDP table.
|
||||
+ *
|
||||
+ * Return: 0 on success, -errno otherwise.
|
||||
+ */
|
||||
+int spi_nor_check_sfdp_signature(struct spi_nor *nor)
|
||||
+{
|
||||
+ u32 signature;
|
||||
+ int err;
|
||||
+
|
||||
+ /* Get the SFDP header. */
|
||||
+ err = spi_nor_read_sfdp_dma_unsafe(nor, 0, sizeof(signature),
|
||||
+ &signature);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+
|
||||
+ /* Check the SFDP signature. */
|
||||
+ if (le32_to_cpu(signature) != SFDP_SIGNATURE)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters.
|
||||
* @nor: pointer to a 'struct spi_nor'
|
||||
*
|
||||
+5
-5
@@ -1,13 +1,13 @@
|
||||
From f7982c726e02001afc19052fe48f642dfcbc00b2 Mon Sep 17 00:00:00 2001
|
||||
From c67d90e058550403a3e6f9b05bfcdcfa12b1815c Mon Sep 17 00:00:00 2001
|
||||
From: Vincent Tremblay <vincent@vtremblay.dev>
|
||||
Date: Mon, 26 Dec 2022 21:10:37 -0500
|
||||
Subject: [PATCH 1/2] spidev: Add Silicon Labs EM3581 device compatible
|
||||
Date: Mon, 26 Dec 2022 21:35:48 -0500
|
||||
Subject: [PATCH] spidev: Add Silicon Labs EM3581 device compatible
|
||||
|
||||
Add compatible string for Silicon Labs EM3581 device.
|
||||
|
||||
Note: This patch is adapted from a patch submitted to the for-next branch (v6.3).
|
||||
|
||||
Signed-off-by: Vincent Tremblay <vincent@vtremblay.dev>
|
||||
Link: https://lore.kernel.org/r/20221227023550.569547-2-vincent@vtremblay.dev
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/spidev.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
+5
-5
@@ -1,13 +1,13 @@
|
||||
From 536581825219e97fa2ae0c4de35605d2f6311416 Mon Sep 17 00:00:00 2001
|
||||
From 6c9d1fd52956c3148e847a214bae9102b1811de5 Mon Sep 17 00:00:00 2001
|
||||
From: Vincent Tremblay <vincent@vtremblay.dev>
|
||||
Date: Tue, 27 Dec 2022 09:00:58 -0500
|
||||
Subject: [PATCH 2/2] spidev: Add Silicon Labs SI3210 device compatible
|
||||
Date: Tue, 27 Dec 2022 09:10:08 -0500
|
||||
Subject: [PATCH] spidev: Add Silicon Labs SI3210 device compatible
|
||||
|
||||
Add compatible string for Silicon Labs SI3210 device.
|
||||
|
||||
Note: This patch is adapted from a patch submitted to the for-next branch (v6.3).
|
||||
|
||||
Signed-off-by: Vincent Tremblay <vincent@vtremblay.dev>
|
||||
Link: https://lore.kernel.org/r/20221227141011.111410-2-vincent@vtremblay.dev
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/spidev.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
From 1ecf9e390452e73a362ea7fbde8f3f0db83de856 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 22 Dec 2022 19:33:04 +0000
|
||||
Subject: [PATCH] mtd: ubi: wire-up parent MTD device
|
||||
|
||||
Wire up the device parent pointer of UBI devices to their lower MTD
|
||||
device, typically an MTD partition or whole-chip device.
|
||||
|
||||
The most noticeable change is that in sysfs, previously ubi devices
|
||||
would be could in /sys/devices/virtual/ubi while after this change they
|
||||
would be correctly attached to their parent MTD device, e.g.
|
||||
|
||||
/sys/devices/platform/1100d000.spi/spi_master/spi1/spi1.0/mtd/mtd2/ubi0.
|
||||
|
||||
Locating UBI devices using /sys/class/ubi/ of course still works as
|
||||
well.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Richard Weinberger <richard@nod.at>
|
||||
---
|
||||
drivers/mtd/ubi/build.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/mtd/ubi/build.c
|
||||
+++ b/drivers/mtd/ubi/build.c
|
||||
@@ -929,6 +929,7 @@ int ubi_attach_mtd_dev(struct mtd_info *
|
||||
ubi->dev.release = dev_release;
|
||||
ubi->dev.class = &ubi_class;
|
||||
ubi->dev.groups = ubi_dev_groups;
|
||||
+ ubi->dev.parent = &mtd->dev;
|
||||
|
||||
ubi->mtd = mtd;
|
||||
ubi->ubi_num = ubi_num;
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
From 05b8773ca33253ea562be145cf3145b05ef19f86 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 22 Dec 2022 19:33:31 +0000
|
||||
Subject: [PATCH] mtd: ubi: block: wire-up device parent
|
||||
|
||||
ubiblock devices were previously only identifyable by their name, but
|
||||
not connected to their parent UBI volume device e.g. in sysfs.
|
||||
Properly parent ubiblock device as descendant of a UBI volume device
|
||||
to reflect device model hierachy.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Richard Weinberger <richard@nod.at>
|
||||
---
|
||||
drivers/mtd/ubi/block.c | 2 +-
|
||||
drivers/mtd/ubi/kapi.c | 1 +
|
||||
include/linux/mtd/ubi.h | 1 +
|
||||
3 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mtd/ubi/block.c
|
||||
+++ b/drivers/mtd/ubi/block.c
|
||||
@@ -452,7 +452,7 @@ int ubiblock_create(struct ubi_volume_in
|
||||
list_add_tail(&dev->list, &ubiblock_devices);
|
||||
|
||||
/* Must be the last step: anyone can call file ops from now on */
|
||||
- ret = add_disk(dev->gd);
|
||||
+ ret = device_add_disk(vi->dev, dev->gd, NULL);
|
||||
if (ret)
|
||||
goto out_destroy_wq;
|
||||
|
||||
--- a/drivers/mtd/ubi/kapi.c
|
||||
+++ b/drivers/mtd/ubi/kapi.c
|
||||
@@ -79,6 +79,7 @@ void ubi_do_get_volume_info(struct ubi_d
|
||||
vi->name_len = vol->name_len;
|
||||
vi->name = vol->name;
|
||||
vi->cdev = vol->cdev.dev;
|
||||
+ vi->dev = &vol->dev;
|
||||
}
|
||||
|
||||
/**
|
||||
--- a/include/linux/mtd/ubi.h
|
||||
+++ b/include/linux/mtd/ubi.h
|
||||
@@ -110,6 +110,7 @@ struct ubi_volume_info {
|
||||
int name_len;
|
||||
const char *name;
|
||||
dev_t cdev;
|
||||
+ struct device *dev;
|
||||
};
|
||||
|
||||
/**
|
||||
+2306
File diff suppressed because it is too large
Load Diff
+183
@@ -0,0 +1,183 @@
|
||||
From e1fbfa4a995d42e02e22b0dff2f8b4fdee1504b3 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Tue, 14 Nov 2023 15:08:42 +0100
|
||||
Subject: [PATCH 2/3] net: phy: aquantia: move MMD_VEND define to header
|
||||
|
||||
Move MMD_VEND define to header to clean things up and in preparation for
|
||||
firmware loading support that require some define placed in
|
||||
aquantia_main.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/aquantia/aquantia.h | 69 +++++++++++++++++++++++
|
||||
drivers/net/phy/aquantia/aquantia_hwmon.c | 14 -----
|
||||
drivers/net/phy/aquantia/aquantia_main.c | 55 ------------------
|
||||
3 files changed, 69 insertions(+), 69 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/aquantia/aquantia.h
|
||||
+++ b/drivers/net/phy/aquantia/aquantia.h
|
||||
@@ -9,6 +9,75 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
+/* Vendor specific 1, MDIO_MMD_VEND1 */
|
||||
+#define VEND1_GLOBAL_FW_ID 0x0020
|
||||
+#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
|
||||
+#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
|
||||
+
|
||||
+/* The following registers all have similar layouts; first the registers... */
|
||||
+#define VEND1_GLOBAL_CFG_10M 0x0310
|
||||
+#define VEND1_GLOBAL_CFG_100M 0x031b
|
||||
+#define VEND1_GLOBAL_CFG_1G 0x031c
|
||||
+#define VEND1_GLOBAL_CFG_2_5G 0x031d
|
||||
+#define VEND1_GLOBAL_CFG_5G 0x031e
|
||||
+#define VEND1_GLOBAL_CFG_10G 0x031f
|
||||
+/* ...and now the fields */
|
||||
+#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
|
||||
+#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
|
||||
+#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
|
||||
+#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
|
||||
+
|
||||
+/* Vendor specific 1, MDIO_MMD_VEND2 */
|
||||
+#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
|
||||
+#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
|
||||
+#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
|
||||
+#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
|
||||
+#define VEND1_THERMAL_STAT1 0xc820
|
||||
+#define VEND1_THERMAL_STAT2 0xc821
|
||||
+#define VEND1_THERMAL_STAT2_VALID BIT(0)
|
||||
+#define VEND1_GENERAL_STAT1 0xc830
|
||||
+#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
|
||||
+#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
|
||||
+#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
|
||||
+#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
|
||||
+
|
||||
+#define VEND1_GLOBAL_GEN_STAT2 0xc831
|
||||
+#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
|
||||
+
|
||||
+#define VEND1_GLOBAL_RSVD_STAT1 0xc885
|
||||
+#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
|
||||
+#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
|
||||
+
|
||||
+#define VEND1_GLOBAL_RSVD_STAT9 0xc88d
|
||||
+#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
|
||||
+#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
|
||||
+
|
||||
+#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
|
||||
+#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
|
||||
+
|
||||
+#define VEND1_GLOBAL_INT_STD_MASK 0xff00
|
||||
+#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15)
|
||||
+#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14)
|
||||
+#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13)
|
||||
+#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12)
|
||||
+#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11)
|
||||
+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10)
|
||||
+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9)
|
||||
+#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8)
|
||||
+#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7)
|
||||
+#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6)
|
||||
+#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0)
|
||||
+
|
||||
+#define VEND1_GLOBAL_INT_VEND_MASK 0xff01
|
||||
+#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15)
|
||||
+#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14)
|
||||
+#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13)
|
||||
+#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12)
|
||||
+#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11)
|
||||
+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2)
|
||||
+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
|
||||
+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
|
||||
+
|
||||
#if IS_REACHABLE(CONFIG_HWMON)
|
||||
int aqr_hwmon_probe(struct phy_device *phydev);
|
||||
#else
|
||||
--- a/drivers/net/phy/aquantia/aquantia_hwmon.c
|
||||
+++ b/drivers/net/phy/aquantia/aquantia_hwmon.c
|
||||
@@ -13,20 +13,6 @@
|
||||
|
||||
#include "aquantia.h"
|
||||
|
||||
-/* Vendor specific 1, MDIO_MMD_VEND2 */
|
||||
-#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
|
||||
-#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
|
||||
-#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
|
||||
-#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
|
||||
-#define VEND1_THERMAL_STAT1 0xc820
|
||||
-#define VEND1_THERMAL_STAT2 0xc821
|
||||
-#define VEND1_THERMAL_STAT2_VALID BIT(0)
|
||||
-#define VEND1_GENERAL_STAT1 0xc830
|
||||
-#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
|
||||
-#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
|
||||
-#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
|
||||
-#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
|
||||
-
|
||||
#if IS_REACHABLE(CONFIG_HWMON)
|
||||
|
||||
static umode_t aqr_hwmon_is_visible(const void *data,
|
||||
--- a/drivers/net/phy/aquantia/aquantia_main.c
|
||||
+++ b/drivers/net/phy/aquantia/aquantia_main.c
|
||||
@@ -89,61 +89,6 @@
|
||||
#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a
|
||||
#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b
|
||||
|
||||
-/* Vendor specific 1, MDIO_MMD_VEND1 */
|
||||
-#define VEND1_GLOBAL_FW_ID 0x0020
|
||||
-#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
|
||||
-#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
|
||||
-
|
||||
-#define VEND1_GLOBAL_GEN_STAT2 0xc831
|
||||
-#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
|
||||
-
|
||||
-/* The following registers all have similar layouts; first the registers... */
|
||||
-#define VEND1_GLOBAL_CFG_10M 0x0310
|
||||
-#define VEND1_GLOBAL_CFG_100M 0x031b
|
||||
-#define VEND1_GLOBAL_CFG_1G 0x031c
|
||||
-#define VEND1_GLOBAL_CFG_2_5G 0x031d
|
||||
-#define VEND1_GLOBAL_CFG_5G 0x031e
|
||||
-#define VEND1_GLOBAL_CFG_10G 0x031f
|
||||
-/* ...and now the fields */
|
||||
-#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
|
||||
-#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
|
||||
-#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
|
||||
-#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
|
||||
-
|
||||
-#define VEND1_GLOBAL_RSVD_STAT1 0xc885
|
||||
-#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
|
||||
-#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
|
||||
-
|
||||
-#define VEND1_GLOBAL_RSVD_STAT9 0xc88d
|
||||
-#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
|
||||
-#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
|
||||
-
|
||||
-#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
|
||||
-#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
|
||||
-
|
||||
-#define VEND1_GLOBAL_INT_STD_MASK 0xff00
|
||||
-#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15)
|
||||
-#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14)
|
||||
-#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13)
|
||||
-#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12)
|
||||
-#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11)
|
||||
-#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10)
|
||||
-#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9)
|
||||
-#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8)
|
||||
-#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7)
|
||||
-#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6)
|
||||
-#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0)
|
||||
-
|
||||
-#define VEND1_GLOBAL_INT_VEND_MASK 0xff01
|
||||
-#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15)
|
||||
-#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14)
|
||||
-#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13)
|
||||
-#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12)
|
||||
-#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11)
|
||||
-#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2)
|
||||
-#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
|
||||
-#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
|
||||
-
|
||||
/* Sleep and timeout for checking if the Processor-Intensive
|
||||
* MDIO operation is finished
|
||||
*/
|
||||
+504
@@ -0,0 +1,504 @@
|
||||
From e93984ebc1c82bd34f7a1b3391efaceee0a8ae96 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robimarko@gmail.com>
|
||||
Date: Tue, 14 Nov 2023 15:08:43 +0100
|
||||
Subject: [PATCH 3/3] net: phy: aquantia: add firmware load support
|
||||
|
||||
Aquantia PHY-s require firmware to be loaded before they start operating.
|
||||
It can be automatically loaded in case when there is a SPI-NOR connected
|
||||
to Aquantia PHY-s or can be loaded from the host via MDIO.
|
||||
|
||||
This patch adds support for loading the firmware via MDIO as in most cases
|
||||
there is no SPI-NOR being used to save on cost.
|
||||
Firmware loading code itself is ported from mainline U-boot with cleanups.
|
||||
|
||||
The firmware has mixed values both in big and little endian.
|
||||
PHY core itself is big-endian but it expects values to be in little-endian.
|
||||
The firmware is little-endian but CRC-16 value for it is stored at the end
|
||||
of firmware in big-endian.
|
||||
|
||||
It seems the PHY does the conversion internally from firmware that is
|
||||
little-endian to the PHY that is big-endian on using the mailbox
|
||||
but mailbox returns a big-endian CRC-16 to verify the written data
|
||||
integrity.
|
||||
|
||||
Co-developed-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/aquantia/Kconfig | 1 +
|
||||
drivers/net/phy/aquantia/Makefile | 2 +-
|
||||
drivers/net/phy/aquantia/aquantia.h | 32 ++
|
||||
drivers/net/phy/aquantia/aquantia_firmware.c | 370 +++++++++++++++++++
|
||||
drivers/net/phy/aquantia/aquantia_main.c | 6 +
|
||||
5 files changed, 410 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/phy/aquantia/aquantia_firmware.c
|
||||
|
||||
--- a/drivers/net/phy/aquantia/Kconfig
|
||||
+++ b/drivers/net/phy/aquantia/Kconfig
|
||||
@@ -1,5 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config AQUANTIA_PHY
|
||||
tristate "Aquantia PHYs"
|
||||
+ select CRC_CCITT
|
||||
help
|
||||
Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
|
||||
--- a/drivers/net/phy/aquantia/Makefile
|
||||
+++ b/drivers/net/phy/aquantia/Makefile
|
||||
@@ -1,5 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
-aquantia-objs += aquantia_main.o
|
||||
+aquantia-objs += aquantia_main.o aquantia_firmware.o
|
||||
ifdef CONFIG_HWMON
|
||||
aquantia-objs += aquantia_hwmon.o
|
||||
endif
|
||||
--- a/drivers/net/phy/aquantia/aquantia.h
|
||||
+++ b/drivers/net/phy/aquantia/aquantia.h
|
||||
@@ -10,10 +10,35 @@
|
||||
#include <linux/phy.h>
|
||||
|
||||
/* Vendor specific 1, MDIO_MMD_VEND1 */
|
||||
+#define VEND1_GLOBAL_SC 0x0
|
||||
+#define VEND1_GLOBAL_SC_SOFT_RESET BIT(15)
|
||||
+#define VEND1_GLOBAL_SC_LOW_POWER BIT(11)
|
||||
+
|
||||
#define VEND1_GLOBAL_FW_ID 0x0020
|
||||
#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
|
||||
#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
|
||||
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE1 0x0200
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE BIT(15)
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE BIT(14)
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET BIT(12)
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_BUSY BIT(8)
|
||||
+
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE2 0x0201
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE3 0x0202
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK GENMASK(15, 0)
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK, (u16)((x) >> 16))
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE4 0x0203
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK GENMASK(15, 2)
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK, (u16)(x))
|
||||
+
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE5 0x0204
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK GENMASK(15, 0)
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK, (u16)((x) >> 16))
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE6 0x0205
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK GENMASK(15, 0)
|
||||
+#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK, (u16)(x))
|
||||
+
|
||||
/* The following registers all have similar layouts; first the registers... */
|
||||
#define VEND1_GLOBAL_CFG_10M 0x0310
|
||||
#define VEND1_GLOBAL_CFG_100M 0x031b
|
||||
@@ -28,6 +53,11 @@
|
||||
#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
|
||||
|
||||
/* Vendor specific 1, MDIO_MMD_VEND2 */
|
||||
+#define VEND1_GLOBAL_CONTROL2 0xc001
|
||||
+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST BIT(15)
|
||||
+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD BIT(6)
|
||||
+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL BIT(0)
|
||||
+
|
||||
#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
|
||||
#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
|
||||
#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
|
||||
@@ -83,3 +113,5 @@ int aqr_hwmon_probe(struct phy_device *p
|
||||
#else
|
||||
static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; }
|
||||
#endif
|
||||
+
|
||||
+int aqr_firmware_load(struct phy_device *phydev);
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/phy/aquantia/aquantia_firmware.c
|
||||
@@ -0,0 +1,370 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/firmware.h>
|
||||
+#include <linux/crc-ccitt.h>
|
||||
+#include <linux/nvmem-consumer.h>
|
||||
+
|
||||
+#include <asm/unaligned.h>
|
||||
+
|
||||
+#include "aquantia.h"
|
||||
+
|
||||
+#define UP_RESET_SLEEP 100
|
||||
+
|
||||
+/* addresses of memory segments in the phy */
|
||||
+#define DRAM_BASE_ADDR 0x3FFE0000
|
||||
+#define IRAM_BASE_ADDR 0x40000000
|
||||
+
|
||||
+/* firmware image format constants */
|
||||
+#define VERSION_STRING_SIZE 0x40
|
||||
+#define VERSION_STRING_OFFSET 0x0200
|
||||
+/* primary offset is written at an offset from the start of the fw blob */
|
||||
+#define PRIMARY_OFFSET_OFFSET 0x8
|
||||
+/* primary offset needs to be then added to a base offset */
|
||||
+#define PRIMARY_OFFSET_SHIFT 12
|
||||
+#define PRIMARY_OFFSET(x) ((x) << PRIMARY_OFFSET_SHIFT)
|
||||
+#define HEADER_OFFSET 0x300
|
||||
+
|
||||
+struct aqr_fw_header {
|
||||
+ u32 padding;
|
||||
+ u8 iram_offset[3];
|
||||
+ u8 iram_size[3];
|
||||
+ u8 dram_offset[3];
|
||||
+ u8 dram_size[3];
|
||||
+} __packed;
|
||||
+
|
||||
+enum aqr_fw_src {
|
||||
+ AQR_FW_SRC_NVMEM = 0,
|
||||
+ AQR_FW_SRC_FS,
|
||||
+};
|
||||
+
|
||||
+static const char * const aqr_fw_src_string[] = {
|
||||
+ [AQR_FW_SRC_NVMEM] = "NVMEM",
|
||||
+ [AQR_FW_SRC_FS] = "FS",
|
||||
+};
|
||||
+
|
||||
+/* AQR firmware doesn't have fixed offsets for iram and dram section
|
||||
+ * but instead provide an header with the offset to use on reading
|
||||
+ * and parsing the firmware.
|
||||
+ *
|
||||
+ * AQR firmware can't be trusted and each offset is validated to be
|
||||
+ * not negative and be in the size of the firmware itself.
|
||||
+ */
|
||||
+static bool aqr_fw_validate_get(size_t size, size_t offset, size_t get_size)
|
||||
+{
|
||||
+ return offset + get_size <= size;
|
||||
+}
|
||||
+
|
||||
+static int aqr_fw_get_be16(const u8 *data, size_t offset, size_t size, u16 *value)
|
||||
+{
|
||||
+ if (!aqr_fw_validate_get(size, offset, sizeof(u16)))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ *value = get_unaligned_be16(data + offset);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int aqr_fw_get_le16(const u8 *data, size_t offset, size_t size, u16 *value)
|
||||
+{
|
||||
+ if (!aqr_fw_validate_get(size, offset, sizeof(u16)))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ *value = get_unaligned_le16(data + offset);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int aqr_fw_get_le24(const u8 *data, size_t offset, size_t size, u32 *value)
|
||||
+{
|
||||
+ if (!aqr_fw_validate_get(size, offset, sizeof(u8) * 3))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ *value = get_unaligned_le24(data + offset);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* load data into the phy's memory */
|
||||
+static int aqr_fw_load_memory(struct phy_device *phydev, u32 addr,
|
||||
+ const u8 *data, size_t len)
|
||||
+{
|
||||
+ u16 crc = 0, up_crc;
|
||||
+ size_t pos;
|
||||
+
|
||||
+ /* PHY expect addr in LE */
|
||||
+ addr = (__force u32)cpu_to_le32(addr);
|
||||
+
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
|
||||
+ VEND1_GLOBAL_MAILBOX_INTERFACE1,
|
||||
+ VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET);
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
|
||||
+ VEND1_GLOBAL_MAILBOX_INTERFACE3,
|
||||
+ VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(addr));
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
|
||||
+ VEND1_GLOBAL_MAILBOX_INTERFACE4,
|
||||
+ VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(addr));
|
||||
+
|
||||
+ /* We assume and enforce the size to be word aligned.
|
||||
+ * If a firmware that is not word aligned is found, please report upstream.
|
||||
+ */
|
||||
+ for (pos = 0; pos < len; pos += sizeof(u32)) {
|
||||
+ u32 word;
|
||||
+
|
||||
+ /* FW data is always stored in little-endian */
|
||||
+ word = get_unaligned((const u32 *)(data + pos));
|
||||
+
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE5,
|
||||
+ VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(word));
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE6,
|
||||
+ VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(word));
|
||||
+
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE1,
|
||||
+ VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE |
|
||||
+ VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE);
|
||||
+
|
||||
+ /* calculate CRC as we load data to the mailbox.
|
||||
+ * We convert word to big-endian as PHY is BE and mailbox will
|
||||
+ * return a BE CRC.
|
||||
+ */
|
||||
+ word = (__force u32)cpu_to_be32(word);
|
||||
+ crc = crc_ccitt_false(crc, (u8 *)&word, sizeof(word));
|
||||
+ }
|
||||
+
|
||||
+ up_crc = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE2);
|
||||
+ if (crc != up_crc) {
|
||||
+ phydev_err(phydev, "CRC mismatch: calculated 0x%04x PHY 0x%04x\n",
|
||||
+ crc, up_crc);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int aqr_fw_boot(struct phy_device *phydev, const u8 *data, size_t size,
|
||||
+ enum aqr_fw_src fw_src)
|
||||
+{
|
||||
+ u16 calculated_crc, read_crc, read_primary_offset;
|
||||
+ u32 iram_offset = 0, iram_size = 0;
|
||||
+ u32 dram_offset = 0, dram_size = 0;
|
||||
+ char version[VERSION_STRING_SIZE];
|
||||
+ u32 primary_offset = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* extract saved CRC at the end of the fw
|
||||
+ * CRC is saved in big-endian as PHY is BE
|
||||
+ */
|
||||
+ ret = aqr_fw_get_be16(data, size - sizeof(u16), size, &read_crc);
|
||||
+ if (ret) {
|
||||
+ phydev_err(phydev, "bad firmware CRC in firmware\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ calculated_crc = crc_ccitt_false(0, data, size - sizeof(u16));
|
||||
+ if (read_crc != calculated_crc) {
|
||||
+ phydev_err(phydev, "bad firmware CRC: file 0x%04x calculated 0x%04x\n",
|
||||
+ read_crc, calculated_crc);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Get the primary offset to extract DRAM and IRAM sections. */
|
||||
+ ret = aqr_fw_get_le16(data, PRIMARY_OFFSET_OFFSET, size, &read_primary_offset);
|
||||
+ if (ret) {
|
||||
+ phydev_err(phydev, "bad primary offset in firmware\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ primary_offset = PRIMARY_OFFSET(read_primary_offset);
|
||||
+
|
||||
+ /* Find the DRAM and IRAM sections within the firmware file.
|
||||
+ * Make sure the fw_header is correctly in the firmware.
|
||||
+ */
|
||||
+ if (!aqr_fw_validate_get(size, primary_offset + HEADER_OFFSET,
|
||||
+ sizeof(struct aqr_fw_header))) {
|
||||
+ phydev_err(phydev, "bad fw_header in firmware\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* offset are in LE and values needs to be converted to cpu endian */
|
||||
+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
|
||||
+ offsetof(struct aqr_fw_header, iram_offset),
|
||||
+ size, &iram_offset);
|
||||
+ if (ret) {
|
||||
+ phydev_err(phydev, "bad iram offset in firmware\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
|
||||
+ offsetof(struct aqr_fw_header, iram_size),
|
||||
+ size, &iram_size);
|
||||
+ if (ret) {
|
||||
+ phydev_err(phydev, "invalid iram size in firmware\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
|
||||
+ offsetof(struct aqr_fw_header, dram_offset),
|
||||
+ size, &dram_offset);
|
||||
+ if (ret) {
|
||||
+ phydev_err(phydev, "bad dram offset in firmware\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
|
||||
+ offsetof(struct aqr_fw_header, dram_size),
|
||||
+ size, &dram_size);
|
||||
+ if (ret) {
|
||||
+ phydev_err(phydev, "invalid dram size in firmware\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Increment the offset with the primary offset.
|
||||
+ * Validate iram/dram offset and size.
|
||||
+ */
|
||||
+ iram_offset += primary_offset;
|
||||
+ if (iram_size % sizeof(u32)) {
|
||||
+ phydev_err(phydev, "iram size if not aligned to word size. Please report this upstream!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (!aqr_fw_validate_get(size, iram_offset, iram_size)) {
|
||||
+ phydev_err(phydev, "invalid iram offset for iram size\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ dram_offset += primary_offset;
|
||||
+ if (dram_size % sizeof(u32)) {
|
||||
+ phydev_err(phydev, "dram size if not aligned to word size. Please report this upstream!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (!aqr_fw_validate_get(size, dram_offset, dram_size)) {
|
||||
+ phydev_err(phydev, "invalid iram offset for iram size\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ phydev_dbg(phydev, "primary %d IRAM offset=%d size=%d DRAM offset=%d size=%d\n",
|
||||
+ primary_offset, iram_offset, iram_size, dram_offset, dram_size);
|
||||
+
|
||||
+ if (!aqr_fw_validate_get(size, dram_offset + VERSION_STRING_OFFSET,
|
||||
+ VERSION_STRING_SIZE)) {
|
||||
+ phydev_err(phydev, "invalid version in firmware\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ strscpy(version, (char *)data + dram_offset + VERSION_STRING_OFFSET,
|
||||
+ VERSION_STRING_SIZE);
|
||||
+ if (version[0] == '\0') {
|
||||
+ phydev_err(phydev, "invalid version in firmware\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ phydev_info(phydev, "loading firmware version '%s' from '%s'\n", version,
|
||||
+ aqr_fw_src_string[fw_src]);
|
||||
+
|
||||
+ /* stall the microcprocessor */
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
|
||||
+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL | VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD);
|
||||
+
|
||||
+ phydev_dbg(phydev, "loading DRAM 0x%08x from offset=%d size=%d\n",
|
||||
+ DRAM_BASE_ADDR, dram_offset, dram_size);
|
||||
+ ret = aqr_fw_load_memory(phydev, DRAM_BASE_ADDR, data + dram_offset,
|
||||
+ dram_size);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ phydev_dbg(phydev, "loading IRAM 0x%08x from offset=%d size=%d\n",
|
||||
+ IRAM_BASE_ADDR, iram_offset, iram_size);
|
||||
+ ret = aqr_fw_load_memory(phydev, IRAM_BASE_ADDR, data + iram_offset,
|
||||
+ iram_size);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* make sure soft reset and low power mode are clear */
|
||||
+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_SC,
|
||||
+ VEND1_GLOBAL_SC_SOFT_RESET | VEND1_GLOBAL_SC_LOW_POWER);
|
||||
+
|
||||
+ /* Release the microprocessor. UP_RESET must be held for 100 usec. */
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
|
||||
+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL |
|
||||
+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD |
|
||||
+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST);
|
||||
+ usleep_range(UP_RESET_SLEEP, UP_RESET_SLEEP * 2);
|
||||
+
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
|
||||
+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int aqr_firmware_load_nvmem(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct nvmem_cell *cell;
|
||||
+ size_t size;
|
||||
+ u8 *buf;
|
||||
+ int ret;
|
||||
+
|
||||
+ cell = nvmem_cell_get(&phydev->mdio.dev, "firmware");
|
||||
+ if (IS_ERR(cell))
|
||||
+ return PTR_ERR(cell);
|
||||
+
|
||||
+ buf = nvmem_cell_read(cell, &size);
|
||||
+ if (IS_ERR(buf)) {
|
||||
+ ret = PTR_ERR(buf);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ ret = aqr_fw_boot(phydev, buf, size, AQR_FW_SRC_NVMEM);
|
||||
+ if (ret)
|
||||
+ phydev_err(phydev, "firmware loading failed: %d\n", ret);
|
||||
+
|
||||
+ kfree(buf);
|
||||
+exit:
|
||||
+ nvmem_cell_put(cell);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int aqr_firmware_load_fs(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct device *dev = &phydev->mdio.dev;
|
||||
+ const struct firmware *fw;
|
||||
+ const char *fw_name;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = of_property_read_string(dev->of_node, "firmware-name",
|
||||
+ &fw_name);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = request_firmware(&fw, fw_name, dev);
|
||||
+ if (ret) {
|
||||
+ phydev_err(phydev, "failed to find FW file %s (%d)\n",
|
||||
+ fw_name, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = aqr_fw_boot(phydev, fw->data, fw->size, AQR_FW_SRC_FS);
|
||||
+ if (ret)
|
||||
+ phydev_err(phydev, "firmware loading failed: %d\n", ret);
|
||||
+
|
||||
+ release_firmware(fw);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int aqr_firmware_load(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Check if the firmware is not already loaded by pooling
|
||||
+ * the current version returned by the PHY. If 0 is returned,
|
||||
+ * no firmware is loaded.
|
||||
+ */
|
||||
+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);
|
||||
+ if (ret > 0)
|
||||
+ goto exit;
|
||||
+
|
||||
+ ret = aqr_firmware_load_nvmem(phydev);
|
||||
+ if (!ret)
|
||||
+ goto exit;
|
||||
+
|
||||
+ ret = aqr_firmware_load_fs(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+exit:
|
||||
+ return 0;
|
||||
+}
|
||||
--- a/drivers/net/phy/aquantia/aquantia_main.c
|
||||
+++ b/drivers/net/phy/aquantia/aquantia_main.c
|
||||
@@ -656,11 +656,17 @@ static int aqr107_resume(struct phy_devi
|
||||
|
||||
static int aqr107_probe(struct phy_device *phydev)
|
||||
{
|
||||
+ int ret;
|
||||
+
|
||||
phydev->priv = devm_kzalloc(&phydev->mdio.dev,
|
||||
sizeof(struct aqr107_priv), GFP_KERNEL);
|
||||
if (!phydev->priv)
|
||||
return -ENOMEM;
|
||||
|
||||
+ ret = aqr_firmware_load(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
return aqr_hwmon_probe(phydev);
|
||||
}
|
||||
|
||||
+326
@@ -0,0 +1,326 @@
|
||||
From 4e4aafcddbbfcdd6eed5780e190fcbfac8b4685a Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Lunn <andrew@lunn.ch>
|
||||
Date: Mon, 9 Jan 2023 16:30:41 +0100
|
||||
Subject: [PATCH] net: mdio: Add dedicated C45 API to MDIO bus drivers
|
||||
|
||||
Currently C22 and C45 transactions are mixed over a combined API calls
|
||||
which make use of a special bit in the reg address to indicate if a
|
||||
C45 transaction should be performed. This makes it impossible to know
|
||||
if the bus driver actually supports C45. Additionally, many C22 only
|
||||
drivers don't return -EOPNOTSUPP when asked to perform a C45
|
||||
transaction, they mistaking perform a C22 transaction.
|
||||
|
||||
This is the first step to cleanly separate C22 from C45. To maintain
|
||||
backwards compatibility until all drivers which are capable of
|
||||
performing C45 are converted to this new API, the helper functions
|
||||
will fall back to the older API if the new API is not
|
||||
supported. Eventually this fallback will be removed.
|
||||
|
||||
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: Michael Walle <michael@walle.cc>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/mdio_bus.c | 189 +++++++++++++++++++++++++++++++++++++
|
||||
include/linux/mdio.h | 39 ++++----
|
||||
include/linux/phy.h | 5 +
|
||||
3 files changed, 214 insertions(+), 19 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/mdio_bus.c
|
||||
+++ b/drivers/net/phy/mdio_bus.c
|
||||
@@ -832,6 +832,100 @@ int __mdiobus_modify_changed(struct mii_
|
||||
EXPORT_SYMBOL_GPL(__mdiobus_modify_changed);
|
||||
|
||||
/**
|
||||
+ * __mdiobus_c45_read - Unlocked version of the mdiobus_c45_read function
|
||||
+ * @bus: the mii_bus struct
|
||||
+ * @addr: the phy address
|
||||
+ * @devad: device address to read
|
||||
+ * @regnum: register number to read
|
||||
+ *
|
||||
+ * Read a MDIO bus register. Caller must hold the mdio bus lock.
|
||||
+ *
|
||||
+ * NOTE: MUST NOT be called from interrupt context.
|
||||
+ */
|
||||
+int __mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum)
|
||||
+{
|
||||
+ int retval;
|
||||
+
|
||||
+ lockdep_assert_held_once(&bus->mdio_lock);
|
||||
+
|
||||
+ if (bus->read_c45)
|
||||
+ retval = bus->read_c45(bus, addr, devad, regnum);
|
||||
+ else
|
||||
+ retval = bus->read(bus, addr, mdiobus_c45_addr(devad, regnum));
|
||||
+
|
||||
+ trace_mdio_access(bus, 1, addr, regnum, retval, retval);
|
||||
+ mdiobus_stats_acct(&bus->stats[addr], true, retval);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+EXPORT_SYMBOL(__mdiobus_c45_read);
|
||||
+
|
||||
+/**
|
||||
+ * __mdiobus_c45_write - Unlocked version of the mdiobus_write function
|
||||
+ * @bus: the mii_bus struct
|
||||
+ * @addr: the phy address
|
||||
+ * @devad: device address to read
|
||||
+ * @regnum: register number to write
|
||||
+ * @val: value to write to @regnum
|
||||
+ *
|
||||
+ * Write a MDIO bus register. Caller must hold the mdio bus lock.
|
||||
+ *
|
||||
+ * NOTE: MUST NOT be called from interrupt context.
|
||||
+ */
|
||||
+int __mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
|
||||
+ u16 val)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ lockdep_assert_held_once(&bus->mdio_lock);
|
||||
+
|
||||
+ if (bus->write_c45)
|
||||
+ err = bus->write_c45(bus, addr, devad, regnum, val);
|
||||
+ else
|
||||
+ err = bus->write(bus, addr, mdiobus_c45_addr(devad, regnum),
|
||||
+ val);
|
||||
+
|
||||
+ trace_mdio_access(bus, 0, addr, regnum, val, err);
|
||||
+ mdiobus_stats_acct(&bus->stats[addr], false, err);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+EXPORT_SYMBOL(__mdiobus_c45_write);
|
||||
+
|
||||
+/**
|
||||
+ * __mdiobus_c45_modify_changed - Unlocked version of the mdiobus_modify function
|
||||
+ * @bus: the mii_bus struct
|
||||
+ * @addr: the phy address
|
||||
+ * @devad: device address to read
|
||||
+ * @regnum: register number to modify
|
||||
+ * @mask: bit mask of bits to clear
|
||||
+ * @set: bit mask of bits to set
|
||||
+ *
|
||||
+ * Read, modify, and if any change, write the register value back to the
|
||||
+ * device. Any error returns a negative number.
|
||||
+ *
|
||||
+ * NOTE: MUST NOT be called from interrupt context.
|
||||
+ */
|
||||
+static int __mdiobus_c45_modify_changed(struct mii_bus *bus, int addr,
|
||||
+ int devad, u32 regnum, u16 mask,
|
||||
+ u16 set)
|
||||
+{
|
||||
+ int new, ret;
|
||||
+
|
||||
+ ret = __mdiobus_c45_read(bus, addr, devad, regnum);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ new = (ret & ~mask) | set;
|
||||
+ if (new == ret)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = __mdiobus_c45_write(bus, addr, devad, regnum, new);
|
||||
+
|
||||
+ return ret < 0 ? ret : 1;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* mdiobus_read_nested - Nested version of the mdiobus_read function
|
||||
* @bus: the mii_bus struct
|
||||
* @addr: the phy address
|
||||
@@ -879,6 +973,29 @@ int mdiobus_read(struct mii_bus *bus, in
|
||||
EXPORT_SYMBOL(mdiobus_read);
|
||||
|
||||
/**
|
||||
+ * mdiobus_c45_read - Convenience function for reading a given MII mgmt register
|
||||
+ * @bus: the mii_bus struct
|
||||
+ * @addr: the phy address
|
||||
+ * @devad: device address to read
|
||||
+ * @regnum: register number to read
|
||||
+ *
|
||||
+ * NOTE: MUST NOT be called from interrupt context,
|
||||
+ * because the bus read/write functions may wait for an interrupt
|
||||
+ * to conclude the operation.
|
||||
+ */
|
||||
+int mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum)
|
||||
+{
|
||||
+ int retval;
|
||||
+
|
||||
+ mutex_lock(&bus->mdio_lock);
|
||||
+ retval = __mdiobus_c45_read(bus, addr, devad, regnum);
|
||||
+ mutex_unlock(&bus->mdio_lock);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+EXPORT_SYMBOL(mdiobus_c45_read);
|
||||
+
|
||||
+/**
|
||||
* mdiobus_write_nested - Nested version of the mdiobus_write function
|
||||
* @bus: the mii_bus struct
|
||||
* @addr: the phy address
|
||||
@@ -928,6 +1045,31 @@ int mdiobus_write(struct mii_bus *bus, i
|
||||
EXPORT_SYMBOL(mdiobus_write);
|
||||
|
||||
/**
|
||||
+ * mdiobus_c45_write - Convenience function for writing a given MII mgmt register
|
||||
+ * @bus: the mii_bus struct
|
||||
+ * @addr: the phy address
|
||||
+ * @devad: device address to read
|
||||
+ * @regnum: register number to write
|
||||
+ * @val: value to write to @regnum
|
||||
+ *
|
||||
+ * NOTE: MUST NOT be called from interrupt context,
|
||||
+ * because the bus read/write functions may wait for an interrupt
|
||||
+ * to conclude the operation.
|
||||
+ */
|
||||
+int mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
|
||||
+ u16 val)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ mutex_lock(&bus->mdio_lock);
|
||||
+ err = __mdiobus_c45_write(bus, addr, devad, regnum, val);
|
||||
+ mutex_unlock(&bus->mdio_lock);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+EXPORT_SYMBOL(mdiobus_c45_write);
|
||||
+
|
||||
+/**
|
||||
* mdiobus_modify - Convenience function for modifying a given mdio device
|
||||
* register
|
||||
* @bus: the mii_bus struct
|
||||
@@ -949,6 +1091,30 @@ int mdiobus_modify(struct mii_bus *bus,
|
||||
EXPORT_SYMBOL_GPL(mdiobus_modify);
|
||||
|
||||
/**
|
||||
+ * mdiobus_c45_modify - Convenience function for modifying a given mdio device
|
||||
+ * register
|
||||
+ * @bus: the mii_bus struct
|
||||
+ * @addr: the phy address
|
||||
+ * @devad: device address to read
|
||||
+ * @regnum: register number to write
|
||||
+ * @mask: bit mask of bits to clear
|
||||
+ * @set: bit mask of bits to set
|
||||
+ */
|
||||
+int mdiobus_c45_modify(struct mii_bus *bus, int addr, int devad, u32 regnum,
|
||||
+ u16 mask, u16 set)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ mutex_lock(&bus->mdio_lock);
|
||||
+ err = __mdiobus_c45_modify_changed(bus, addr, devad, regnum,
|
||||
+ mask, set);
|
||||
+ mutex_unlock(&bus->mdio_lock);
|
||||
+
|
||||
+ return err < 0 ? err : 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(mdiobus_c45_modify);
|
||||
+
|
||||
+/**
|
||||
* mdiobus_modify_changed - Convenience function for modifying a given mdio
|
||||
* device register and returning if it changed
|
||||
* @bus: the mii_bus struct
|
||||
@@ -971,6 +1137,29 @@ int mdiobus_modify_changed(struct mii_bu
|
||||
EXPORT_SYMBOL_GPL(mdiobus_modify_changed);
|
||||
|
||||
/**
|
||||
+ * mdiobus_c45_modify_changed - Convenience function for modifying a given mdio
|
||||
+ * device register and returning if it changed
|
||||
+ * @bus: the mii_bus struct
|
||||
+ * @addr: the phy address
|
||||
+ * @devad: device address to read
|
||||
+ * @regnum: register number to write
|
||||
+ * @mask: bit mask of bits to clear
|
||||
+ * @set: bit mask of bits to set
|
||||
+ */
|
||||
+int mdiobus_c45_modify_changed(struct mii_bus *bus, int devad, int addr,
|
||||
+ u32 regnum, u16 mask, u16 set)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ mutex_lock(&bus->mdio_lock);
|
||||
+ err = __mdiobus_c45_modify_changed(bus, addr, devad, regnum, mask, set);
|
||||
+ mutex_unlock(&bus->mdio_lock);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(mdiobus_c45_modify_changed);
|
||||
+
|
||||
+/**
|
||||
* mdio_bus_match - determine if given MDIO driver supports the given
|
||||
* MDIO device
|
||||
* @dev: target MDIO device
|
||||
--- a/include/linux/mdio.h
|
||||
+++ b/include/linux/mdio.h
|
||||
@@ -423,6 +423,17 @@ int mdiobus_modify(struct mii_bus *bus,
|
||||
u16 set);
|
||||
int mdiobus_modify_changed(struct mii_bus *bus, int addr, u32 regnum,
|
||||
u16 mask, u16 set);
|
||||
+int __mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum);
|
||||
+int mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum);
|
||||
+int __mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
|
||||
+ u16 val);
|
||||
+int mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
|
||||
+ u16 val);
|
||||
+int mdiobus_c45_modify(struct mii_bus *bus, int addr, int devad, u32 regnum,
|
||||
+ u16 mask, u16 set);
|
||||
+
|
||||
+int mdiobus_c45_modify_changed(struct mii_bus *bus, int addr, int devad,
|
||||
+ u32 regnum, u16 mask, u16 set);
|
||||
|
||||
static inline int mdiodev_read(struct mdio_device *mdiodev, u32 regnum)
|
||||
{
|
||||
@@ -463,29 +474,19 @@ static inline u16 mdiobus_c45_devad(u32
|
||||
return FIELD_GET(MII_DEVADDR_C45_MASK, regnum);
|
||||
}
|
||||
|
||||
-static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
|
||||
- u16 regnum)
|
||||
-{
|
||||
- return __mdiobus_read(bus, prtad, mdiobus_c45_addr(devad, regnum));
|
||||
-}
|
||||
-
|
||||
-static inline int __mdiobus_c45_write(struct mii_bus *bus, int prtad, int devad,
|
||||
- u16 regnum, u16 val)
|
||||
-{
|
||||
- return __mdiobus_write(bus, prtad, mdiobus_c45_addr(devad, regnum),
|
||||
- val);
|
||||
-}
|
||||
-
|
||||
-static inline int mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
|
||||
- u16 regnum)
|
||||
+static inline int mdiodev_c45_modify(struct mdio_device *mdiodev, int devad,
|
||||
+ u32 regnum, u16 mask, u16 set)
|
||||
{
|
||||
- return mdiobus_read(bus, prtad, mdiobus_c45_addr(devad, regnum));
|
||||
+ return mdiobus_c45_modify(mdiodev->bus, mdiodev->addr, devad, regnum,
|
||||
+ mask, set);
|
||||
}
|
||||
|
||||
-static inline int mdiobus_c45_write(struct mii_bus *bus, int prtad, int devad,
|
||||
- u16 regnum, u16 val)
|
||||
+static inline int mdiodev_c45_modify_changed(struct mdio_device *mdiodev,
|
||||
+ int devad, u32 regnum, u16 mask,
|
||||
+ u16 set)
|
||||
{
|
||||
- return mdiobus_write(bus, prtad, mdiobus_c45_addr(devad, regnum), val);
|
||||
+ return mdiobus_c45_modify_changed(mdiodev->bus, mdiodev->addr, devad,
|
||||
+ regnum, mask, set);
|
||||
}
|
||||
|
||||
int mdiobus_register_device(struct mdio_device *mdiodev);
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -364,6 +364,11 @@ struct mii_bus {
|
||||
int (*read)(struct mii_bus *bus, int addr, int regnum);
|
||||
/** @write: Perform a write transfer on the bus */
|
||||
int (*write)(struct mii_bus *bus, int addr, int regnum, u16 val);
|
||||
+ /** @read_c45: Perform a C45 read transfer on the bus */
|
||||
+ int (*read_c45)(struct mii_bus *bus, int addr, int devnum, int regnum);
|
||||
+ /** @write_c45: Perform a C45 write transfer on the bus */
|
||||
+ int (*write_c45)(struct mii_bus *bus, int addr, int devnum,
|
||||
+ int regnum, u16 val);
|
||||
/** @reset: Perform a reset of the bus */
|
||||
int (*reset)(struct mii_bus *bus);
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
From 9a0e95e34e9c0a713ddfd48c3a88a20d2bdfd514 Mon Sep 17 00:00:00 2001
|
||||
From: Gabor Juhos <j4g8y7@gmail.com>
|
||||
Date: Fri, 11 Aug 2023 13:10:07 +0200
|
||||
Subject: [PATCH] net: phy: Introduce PSGMII PHY interface mode
|
||||
|
||||
The PSGMII interface is similar to QSGMII. The main difference
|
||||
is that the PSGMII interface combines five SGMII lines into a
|
||||
single link while in QSGMII only four lines are combined.
|
||||
|
||||
Similarly to the QSGMII, this interface mode might also needs
|
||||
special handling within the MAC driver.
|
||||
|
||||
It is commonly used by Qualcomm with their QCA807x PHY series and
|
||||
modern WiSoC-s.
|
||||
|
||||
Add definitions for the PHY layer to allow to express this type
|
||||
of connection between the MAC and PHY.
|
||||
|
||||
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
|
||||
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
Documentation/networking/phy.rst | 4 ++++
|
||||
drivers/net/phy/phy-core.c | 2 ++
|
||||
drivers/net/phy/phylink.c | 3 +++
|
||||
include/linux/phy.h | 4 ++++
|
||||
4 files changed, 13 insertions(+)
|
||||
|
||||
--- a/Documentation/networking/phy.rst
|
||||
+++ b/Documentation/networking/phy.rst
|
||||
@@ -323,6 +323,10 @@ Some of the interface modes are describe
|
||||
contrast with the 1000BASE-X phy mode used for Clause 38 and 39 PMDs, this
|
||||
interface mode has different autonegotiation and only supports full duplex.
|
||||
|
||||
+``PHY_INTERFACE_MODE_PSGMII``
|
||||
+ This is the Penta SGMII mode, it is similar to QSGMII but it combines 5
|
||||
+ SGMII lines into a single link compared to 4 on QSGMII.
|
||||
+
|
||||
Pause frames / flow control
|
||||
===========================
|
||||
|
||||
--- a/drivers/net/phy/phy-core.c
|
||||
+++ b/drivers/net/phy/phy-core.c
|
||||
@@ -140,6 +140,8 @@ int phy_interface_num_ports(phy_interfac
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
case PHY_INTERFACE_MODE_QUSGMII:
|
||||
return 4;
|
||||
+ case PHY_INTERFACE_MODE_PSGMII:
|
||||
+ return 5;
|
||||
case PHY_INTERFACE_MODE_MAX:
|
||||
WARN_ONCE(1, "PHY_INTERFACE_MODE_MAX isn't a valid interface mode");
|
||||
return 0;
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -187,6 +187,7 @@ static int phylink_interface_max_speed(p
|
||||
case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
+ case PHY_INTERFACE_MODE_PSGMII:
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
case PHY_INTERFACE_MODE_QUSGMII:
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
@@ -448,6 +449,7 @@ unsigned long phylink_get_capabilities(p
|
||||
case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
+ case PHY_INTERFACE_MODE_PSGMII:
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
case PHY_INTERFACE_MODE_QUSGMII:
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
@@ -814,6 +816,7 @@ static int phylink_parse_mode(struct phy
|
||||
|
||||
switch (pl->link_config.interface) {
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
+ case PHY_INTERFACE_MODE_PSGMII:
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
case PHY_INTERFACE_MODE_QUSGMII:
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -103,6 +103,7 @@ extern const int phy_10gbit_features_arr
|
||||
* @PHY_INTERFACE_MODE_XGMII: 10 gigabit media-independent interface
|
||||
* @PHY_INTERFACE_MODE_XLGMII:40 gigabit media-independent interface
|
||||
* @PHY_INTERFACE_MODE_MOCA: Multimedia over Coax
|
||||
+ * @PHY_INTERFACE_MODE_PSGMII: Penta SGMII
|
||||
* @PHY_INTERFACE_MODE_QSGMII: Quad SGMII
|
||||
* @PHY_INTERFACE_MODE_TRGMII: Turbo RGMII
|
||||
* @PHY_INTERFACE_MODE_100BASEX: 100 BaseX
|
||||
@@ -140,6 +141,7 @@ typedef enum {
|
||||
PHY_INTERFACE_MODE_XGMII,
|
||||
PHY_INTERFACE_MODE_XLGMII,
|
||||
PHY_INTERFACE_MODE_MOCA,
|
||||
+ PHY_INTERFACE_MODE_PSGMII,
|
||||
PHY_INTERFACE_MODE_QSGMII,
|
||||
PHY_INTERFACE_MODE_TRGMII,
|
||||
PHY_INTERFACE_MODE_100BASEX,
|
||||
@@ -247,6 +249,8 @@ static inline const char *phy_modes(phy_
|
||||
return "xlgmii";
|
||||
case PHY_INTERFACE_MODE_MOCA:
|
||||
return "moca";
|
||||
+ case PHY_INTERFACE_MODE_PSGMII:
|
||||
+ return "psgmii";
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
return "qsgmii";
|
||||
case PHY_INTERFACE_MODE_TRGMII:
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
From a593a2fcfdfb92cfd0ffc54bc81b07e6bfaaaf46 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Date: Thu, 16 Mar 2023 14:08:26 +0200
|
||||
Subject: [PATCH] net: phy: at803x: Replace of_gpio.h with what indeed is used
|
||||
|
||||
of_gpio.h in this driver is solely used as a proxy to other headers.
|
||||
This is incorrect usage of the of_gpio.h. Replace it .h with what
|
||||
indeed is used in the code.
|
||||
|
||||
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -13,12 +13,11 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool_netlink.h>
|
||||
-#include <linux/of_gpio.h>
|
||||
#include <linux/bitfield.h>
|
||||
-#include <linux/gpio/consumer.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
+#include <linux/of.h>
|
||||
#include <linux/phylink.h>
|
||||
#include <linux/sfp.h>
|
||||
#include <dt-bindings/net/qca-ar803x.h>
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
From 8b8bc13d89a7d23d14b0e041c73f037c9db997b1 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Sun, 16 Jul 2023 16:49:19 +0800
|
||||
Subject: [PATCH 1/6] net: phy: at803x: support qca8081
|
||||
genphy_c45_pma_read_abilities
|
||||
|
||||
qca8081 PHY supports to use genphy_c45_pma_read_abilities for
|
||||
getting the PHY features supported except for the autoneg ability
|
||||
|
||||
but autoneg ability exists in MDIO_STAT1 instead of MMD7.1, add it
|
||||
manually after calling genphy_c45_pma_read_abilities.
|
||||
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 28 ++++++++++++++++++----------
|
||||
1 file changed, 18 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -902,15 +902,6 @@ static int at803x_get_features(struct ph
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- if (phydev->drv->phy_id == QCA8081_PHY_ID) {
|
||||
- err = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_NG_EXTABLE);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
-
|
||||
- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported,
|
||||
- err & MDIO_PMA_NG_EXTABLE_2_5GBT);
|
||||
- }
|
||||
-
|
||||
if (phydev->drv->phy_id != ATH8031_PHY_ID)
|
||||
return 0;
|
||||
|
||||
@@ -1996,6 +1987,23 @@ static int qca808x_cable_test_get_status
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int qca808x_get_features(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = genphy_c45_pma_read_abilities(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* The autoneg ability is not existed in bit3 of MMD7.1,
|
||||
+ * but it is supported by qca808x PHY, so we add it here
|
||||
+ * manually.
|
||||
+ */
|
||||
+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static struct phy_driver at803x_driver[] = {
|
||||
{
|
||||
/* Qualcomm Atheros AR8035 */
|
||||
@@ -2163,7 +2171,7 @@ static struct phy_driver at803x_driver[]
|
||||
.set_tunable = at803x_set_tunable,
|
||||
.set_wol = at803x_set_wol,
|
||||
.get_wol = at803x_get_wol,
|
||||
- .get_features = at803x_get_features,
|
||||
+ .get_features = qca808x_get_features,
|
||||
.config_aneg = at803x_config_aneg,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
From f3db55ae860a82e1224a909072783ef850e5d228 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Sun, 16 Jul 2023 16:49:20 +0800
|
||||
Subject: [PATCH 2/6] net: phy: at803x: merge qca8081 slave seed function
|
||||
|
||||
merge the seed enablement and seed value configuration into
|
||||
one function, since the random seed value is needed to be
|
||||
configured when the seed is enabled.
|
||||
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 29 +++++++++--------------------
|
||||
1 file changed, 9 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -1730,24 +1730,19 @@ static int qca808x_phy_fast_retrain_conf
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int qca808x_phy_ms_random_seed_set(struct phy_device *phydev)
|
||||
-{
|
||||
- u16 seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE);
|
||||
-
|
||||
- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
|
||||
- QCA808X_MASTER_SLAVE_SEED_CFG,
|
||||
- FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value));
|
||||
-}
|
||||
-
|
||||
static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable)
|
||||
{
|
||||
- u16 seed_enable = 0;
|
||||
+ u16 seed_value;
|
||||
|
||||
- if (enable)
|
||||
- seed_enable = QCA808X_MASTER_SLAVE_SEED_ENABLE;
|
||||
+ if (!enable)
|
||||
+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
|
||||
+ QCA808X_MASTER_SLAVE_SEED_ENABLE, 0);
|
||||
|
||||
+ seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE);
|
||||
return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
|
||||
- QCA808X_MASTER_SLAVE_SEED_ENABLE, seed_enable);
|
||||
+ QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE,
|
||||
+ FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) |
|
||||
+ QCA808X_MASTER_SLAVE_SEED_ENABLE);
|
||||
}
|
||||
|
||||
static int qca808x_config_init(struct phy_device *phydev)
|
||||
@@ -1771,12 +1766,7 @@ static int qca808x_config_init(struct ph
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- /* Configure lower ramdom seed to make phy linked as slave mode */
|
||||
- ret = qca808x_phy_ms_random_seed_set(phydev);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- /* Enable seed */
|
||||
+ /* Enable seed and configure lower ramdom seed to make phy linked as slave mode */
|
||||
ret = qca808x_phy_ms_seed_enable(phydev, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -1821,7 +1811,6 @@ static int qca808x_read_status(struct ph
|
||||
if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR) {
|
||||
qca808x_phy_ms_seed_enable(phydev, false);
|
||||
} else {
|
||||
- qca808x_phy_ms_random_seed_set(phydev);
|
||||
qca808x_phy_ms_seed_enable(phydev, true);
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
From 7cc3209558002d95c0d45a1276ba4f5f741eec42 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Sun, 16 Jul 2023 16:49:21 +0800
|
||||
Subject: [PATCH 3/6] net: phy: at803x: enable qca8081 slave seed conditionally
|
||||
|
||||
qca8081 is the single port PHY, the slave prefer mode is used
|
||||
by default.
|
||||
|
||||
if the phy master perfer mode is configured, the slave seed
|
||||
configuration should not be enabled, since the slave seed
|
||||
enablement is for making PHY linked as slave mode easily.
|
||||
|
||||
disable slave seed if the master mode is preferred.
|
||||
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 25 ++++++++++++++++++++-----
|
||||
1 file changed, 20 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -1745,6 +1745,12 @@ static int qca808x_phy_ms_seed_enable(st
|
||||
QCA808X_MASTER_SLAVE_SEED_ENABLE);
|
||||
}
|
||||
|
||||
+static bool qca808x_is_prefer_master(struct phy_device *phydev)
|
||||
+{
|
||||
+ return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) ||
|
||||
+ (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED);
|
||||
+}
|
||||
+
|
||||
static int qca808x_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
@@ -1766,11 +1772,17 @@ static int qca808x_config_init(struct ph
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- /* Enable seed and configure lower ramdom seed to make phy linked as slave mode */
|
||||
- ret = qca808x_phy_ms_seed_enable(phydev, true);
|
||||
- if (ret)
|
||||
+ ret = genphy_read_master_slave(phydev);
|
||||
+ if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+ if (!qca808x_is_prefer_master(phydev)) {
|
||||
+ /* Enable seed and configure lower ramdom seed to make phy linked as slave mode */
|
||||
+ ret = qca808x_phy_ms_seed_enable(phydev, true);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
/* Configure adc threshold as 100mv for the link 10M */
|
||||
return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
|
||||
QCA808X_ADC_THRESHOLD_MASK, QCA808X_ADC_THRESHOLD_100MV);
|
||||
@@ -1802,13 +1814,16 @@ static int qca808x_read_status(struct ph
|
||||
phydev->interface = PHY_INTERFACE_MODE_SGMII;
|
||||
} else {
|
||||
/* generate seed as a lower random value to make PHY linked as SLAVE easily,
|
||||
- * except for master/slave configuration fault detected.
|
||||
+ * except for master/slave configuration fault detected or the master mode
|
||||
+ * preferred.
|
||||
+ *
|
||||
* the reason for not putting this code into the function link_change_notify is
|
||||
* the corner case where the link partner is also the qca8081 PHY and the seed
|
||||
* value is configured as the same value, the link can't be up and no link change
|
||||
* occurs.
|
||||
*/
|
||||
- if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR) {
|
||||
+ if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
|
||||
+ qca808x_is_prefer_master(phydev)) {
|
||||
qca808x_phy_ms_seed_enable(phydev, false);
|
||||
} else {
|
||||
qca808x_phy_ms_seed_enable(phydev, true);
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
From fea7cfb83d1a2782e39cd101dd44ed2548539de5 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Sun, 16 Jul 2023 16:49:22 +0800
|
||||
Subject: [PATCH 4/6] net: phy: at803x: support qca8081 1G chip type
|
||||
|
||||
The qca8081 1G chip version does not support 2.5 capability, which
|
||||
is distinguished from qca8081 2.5G chip according to the bit0 of
|
||||
register mmd7.0x901d, the 1G version chip also has the same PHY ID
|
||||
as the normal qca8081 2.5G chip.
|
||||
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -272,6 +272,10 @@
|
||||
#define QCA808X_CDT_STATUS_STAT_OPEN 2
|
||||
#define QCA808X_CDT_STATUS_STAT_SHORT 3
|
||||
|
||||
+/* QCA808X 1G chip type */
|
||||
+#define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d
|
||||
+#define QCA808X_PHY_CHIP_TYPE_1G BIT(0)
|
||||
+
|
||||
MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
|
||||
MODULE_AUTHOR("Matus Ujhelyi");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -2005,6 +2009,17 @@ static int qca808x_get_features(struct p
|
||||
*/
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
|
||||
|
||||
+ /* As for the qca8081 1G version chip, the 2500baseT ability is also
|
||||
+ * existed in the bit0 of MMD1.21, we need to remove it manually if
|
||||
+ * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d.
|
||||
+ */
|
||||
+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (QCA808X_PHY_CHIP_TYPE_1G & ret)
|
||||
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
From df9401ff3e6eeaa42bfb06761967f1b71f5afce7 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Sun, 16 Jul 2023 16:49:23 +0800
|
||||
Subject: [PATCH 5/6] net: phy: at803x: remove qca8081 1G fast retrain and
|
||||
slave seed config
|
||||
|
||||
The fast retrain and slave seed configs are only applicable when the 2.5G
|
||||
ability is supported.
|
||||
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 50 +++++++++++++++++++++++++---------------
|
||||
1 file changed, 32 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -1755,6 +1755,11 @@ static bool qca808x_is_prefer_master(str
|
||||
(phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED);
|
||||
}
|
||||
|
||||
+static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev)
|
||||
+{
|
||||
+ return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
|
||||
+}
|
||||
+
|
||||
static int qca808x_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
@@ -1771,20 +1776,24 @@ static int qca808x_config_init(struct ph
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- /* Config the fast retrain for the link 2500M */
|
||||
- ret = qca808x_phy_fast_retrain_config(phydev);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = genphy_read_master_slave(phydev);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- if (!qca808x_is_prefer_master(phydev)) {
|
||||
- /* Enable seed and configure lower ramdom seed to make phy linked as slave mode */
|
||||
- ret = qca808x_phy_ms_seed_enable(phydev, true);
|
||||
+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
|
||||
+ /* Config the fast retrain for the link 2500M */
|
||||
+ ret = qca808x_phy_fast_retrain_config(phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
+
|
||||
+ ret = genphy_read_master_slave(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!qca808x_is_prefer_master(phydev)) {
|
||||
+ /* Enable seed and configure lower ramdom seed to make phy
|
||||
+ * linked as slave mode.
|
||||
+ */
|
||||
+ ret = qca808x_phy_ms_seed_enable(phydev, true);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Configure adc threshold as 100mv for the link 10M */
|
||||
@@ -1826,11 +1835,13 @@ static int qca808x_read_status(struct ph
|
||||
* value is configured as the same value, the link can't be up and no link change
|
||||
* occurs.
|
||||
*/
|
||||
- if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
|
||||
- qca808x_is_prefer_master(phydev)) {
|
||||
- qca808x_phy_ms_seed_enable(phydev, false);
|
||||
- } else {
|
||||
- qca808x_phy_ms_seed_enable(phydev, true);
|
||||
+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
|
||||
+ if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
|
||||
+ qca808x_is_prefer_master(phydev)) {
|
||||
+ qca808x_phy_ms_seed_enable(phydev, false);
|
||||
+ } else {
|
||||
+ qca808x_phy_ms_seed_enable(phydev, true);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1845,7 +1856,10 @@ static int qca808x_soft_reset(struct phy
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- return qca808x_phy_ms_seed_enable(phydev, true);
|
||||
+ if (qca808x_has_fast_retrain_or_slave_seed(phydev))
|
||||
+ ret = qca808x_phy_ms_seed_enable(phydev, true);
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static bool qca808x_cdt_fault_length_valid(int cdt_code)
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
From 723970affdd8766fa0d91cd34bf2ffc861538b5f Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Sun, 16 Jul 2023 16:49:24 +0800
|
||||
Subject: [PATCH 6/6] net: phy: at803x: add qca8081 fifo reset on the link
|
||||
changed
|
||||
|
||||
The qca8081 sgmii fifo needs to be reset on link down and
|
||||
released on the link up in case of any abnormal issue
|
||||
such as the packet blocked on the PHY.
|
||||
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -276,6 +276,9 @@
|
||||
#define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d
|
||||
#define QCA808X_PHY_CHIP_TYPE_1G BIT(0)
|
||||
|
||||
+#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072
|
||||
+#define QCA8081_PHY_FIFO_RSTN BIT(11)
|
||||
+
|
||||
MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
|
||||
MODULE_AUTHOR("Matus Ujhelyi");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -2037,6 +2040,16 @@ static int qca808x_get_features(struct p
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void qca808x_link_change_notify(struct phy_device *phydev)
|
||||
+{
|
||||
+ /* Assert interface sgmii fifo on link down, deassert it on link up,
|
||||
+ * the interface device address is always phy address added by 1.
|
||||
+ */
|
||||
+ mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
|
||||
+ MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
|
||||
+ QCA8081_PHY_FIFO_RSTN, phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
|
||||
+}
|
||||
+
|
||||
static struct phy_driver at803x_driver[] = {
|
||||
{
|
||||
/* Qualcomm Atheros AR8035 */
|
||||
@@ -2213,6 +2226,7 @@ static struct phy_driver at803x_driver[]
|
||||
.soft_reset = qca808x_soft_reset,
|
||||
.cable_test_start = qca808x_cable_test_start,
|
||||
.cable_test_get_status = qca808x_cable_test_get_status,
|
||||
+ .link_change_notify = qca808x_link_change_notify,
|
||||
}, };
|
||||
|
||||
module_phy_driver(at803x_driver);
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
From 6a3b8c573b5a152a6aa7a0b54c5e18b84c6ba6f5 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 8 Dec 2023 15:51:49 +0100
|
||||
Subject: [PATCH 02/13] net: phy: at803x: move disable WOL to specific at8031
|
||||
probe
|
||||
|
||||
Move the WOL disable call to specific at8031 probe to make at803x_probe
|
||||
more generic and drop extra check for PHY ID.
|
||||
|
||||
Keep the same previous behaviour by first calling at803x_probe and then
|
||||
disabling WOL.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 27 +++++++++++++++++----------
|
||||
1 file changed, 17 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -886,15 +886,6 @@ static int at803x_probe(struct phy_devic
|
||||
priv->is_fiber = true;
|
||||
break;
|
||||
}
|
||||
-
|
||||
- /* Disable WoL in 1588 register which is enabled
|
||||
- * by default
|
||||
- */
|
||||
- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
|
||||
- AT803X_PHY_MMD3_WOL_CTRL,
|
||||
- AT803X_WOL_EN, 0);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1591,6 +1582,22 @@ static int at803x_cable_test_start(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int at8031_probe(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = at803x_probe(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Disable WoL in 1588 register which is enabled
|
||||
+ * by default
|
||||
+ */
|
||||
+ return phy_modify_mmd(phydev, MDIO_MMD_PCS,
|
||||
+ AT803X_PHY_MMD3_WOL_CTRL,
|
||||
+ AT803X_WOL_EN, 0);
|
||||
+}
|
||||
+
|
||||
static int qca83xx_config_init(struct phy_device *phydev)
|
||||
{
|
||||
u8 switch_revision;
|
||||
@@ -2092,7 +2099,7 @@ static struct phy_driver at803x_driver[]
|
||||
PHY_ID_MATCH_EXACT(ATH8031_PHY_ID),
|
||||
.name = "Qualcomm Atheros AR8031/AR8033",
|
||||
.flags = PHY_POLL_CABLE_TEST,
|
||||
- .probe = at803x_probe,
|
||||
+ .probe = at8031_probe,
|
||||
.config_init = at803x_config_init,
|
||||
.config_aneg = at803x_config_aneg,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
From 07b1ad83b9ed6db1735ba10baf67b7a565ac0cef Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 8 Dec 2023 15:51:50 +0100
|
||||
Subject: [PATCH 03/13] net: phy: at803x: raname hw_stats functions to qca83xx
|
||||
specific name
|
||||
|
||||
The function and the struct related to hw_stats were specific to qca83xx
|
||||
PHY but were called following the convention in the driver of calling
|
||||
everything with at803x prefix.
|
||||
|
||||
To better organize the code, rename these function a more specific name
|
||||
to better describe that they are specific to 83xx PHY family.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 44 ++++++++++++++++++++--------------------
|
||||
1 file changed, 22 insertions(+), 22 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -295,7 +295,7 @@ struct at803x_hw_stat {
|
||||
enum stat_access_type access_type;
|
||||
};
|
||||
|
||||
-static struct at803x_hw_stat at803x_hw_stats[] = {
|
||||
+static struct at803x_hw_stat qca83xx_hw_stats[] = {
|
||||
{ "phy_idle_errors", 0xa, GENMASK(7, 0), PHY},
|
||||
{ "phy_receive_errors", 0x15, GENMASK(15, 0), PHY},
|
||||
{ "eee_wake_errors", 0x16, GENMASK(15, 0), MMD},
|
||||
@@ -311,7 +311,7 @@ struct at803x_priv {
|
||||
bool is_1000basex;
|
||||
struct regulator_dev *vddio_rdev;
|
||||
struct regulator_dev *vddh_rdev;
|
||||
- u64 stats[ARRAY_SIZE(at803x_hw_stats)];
|
||||
+ u64 stats[ARRAY_SIZE(qca83xx_hw_stats)];
|
||||
};
|
||||
|
||||
struct at803x_context {
|
||||
@@ -529,24 +529,24 @@ static void at803x_get_wol(struct phy_de
|
||||
wol->wolopts |= WAKE_MAGIC;
|
||||
}
|
||||
|
||||
-static int at803x_get_sset_count(struct phy_device *phydev)
|
||||
+static int qca83xx_get_sset_count(struct phy_device *phydev)
|
||||
{
|
||||
- return ARRAY_SIZE(at803x_hw_stats);
|
||||
+ return ARRAY_SIZE(qca83xx_hw_stats);
|
||||
}
|
||||
|
||||
-static void at803x_get_strings(struct phy_device *phydev, u8 *data)
|
||||
+static void qca83xx_get_strings(struct phy_device *phydev, u8 *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++) {
|
||||
+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) {
|
||||
strscpy(data + i * ETH_GSTRING_LEN,
|
||||
- at803x_hw_stats[i].string, ETH_GSTRING_LEN);
|
||||
+ qca83xx_hw_stats[i].string, ETH_GSTRING_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
-static u64 at803x_get_stat(struct phy_device *phydev, int i)
|
||||
+static u64 qca83xx_get_stat(struct phy_device *phydev, int i)
|
||||
{
|
||||
- struct at803x_hw_stat stat = at803x_hw_stats[i];
|
||||
+ struct at803x_hw_stat stat = qca83xx_hw_stats[i];
|
||||
struct at803x_priv *priv = phydev->priv;
|
||||
int val;
|
||||
u64 ret;
|
||||
@@ -567,13 +567,13 @@ static u64 at803x_get_stat(struct phy_de
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static void at803x_get_stats(struct phy_device *phydev,
|
||||
- struct ethtool_stats *stats, u64 *data)
|
||||
+static void qca83xx_get_stats(struct phy_device *phydev,
|
||||
+ struct ethtool_stats *stats, u64 *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++)
|
||||
- data[i] = at803x_get_stat(phydev, i);
|
||||
+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++)
|
||||
+ data[i] = qca83xx_get_stat(phydev, i);
|
||||
}
|
||||
|
||||
static int at803x_suspend(struct phy_device *phydev)
|
||||
@@ -2175,9 +2175,9 @@ static struct phy_driver at803x_driver[]
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.config_init = qca83xx_config_init,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
- .get_sset_count = at803x_get_sset_count,
|
||||
- .get_strings = at803x_get_strings,
|
||||
- .get_stats = at803x_get_stats,
|
||||
+ .get_sset_count = qca83xx_get_sset_count,
|
||||
+ .get_strings = qca83xx_get_strings,
|
||||
+ .get_stats = qca83xx_get_stats,
|
||||
.suspend = qca83xx_suspend,
|
||||
.resume = qca83xx_resume,
|
||||
}, {
|
||||
@@ -2191,9 +2191,9 @@ static struct phy_driver at803x_driver[]
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.config_init = qca83xx_config_init,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
- .get_sset_count = at803x_get_sset_count,
|
||||
- .get_strings = at803x_get_strings,
|
||||
- .get_stats = at803x_get_stats,
|
||||
+ .get_sset_count = qca83xx_get_sset_count,
|
||||
+ .get_strings = qca83xx_get_strings,
|
||||
+ .get_stats = qca83xx_get_stats,
|
||||
.suspend = qca83xx_suspend,
|
||||
.resume = qca83xx_resume,
|
||||
}, {
|
||||
@@ -2207,9 +2207,9 @@ static struct phy_driver at803x_driver[]
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.config_init = qca83xx_config_init,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
- .get_sset_count = at803x_get_sset_count,
|
||||
- .get_strings = at803x_get_strings,
|
||||
- .get_stats = at803x_get_stats,
|
||||
+ .get_sset_count = qca83xx_get_sset_count,
|
||||
+ .get_strings = qca83xx_get_strings,
|
||||
+ .get_stats = qca83xx_get_stats,
|
||||
.suspend = qca83xx_suspend,
|
||||
.resume = qca83xx_resume,
|
||||
}, {
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
From d43cff3f82336c0bd965ea552232d9f4ddac71a6 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 8 Dec 2023 15:51:51 +0100
|
||||
Subject: [PATCH 04/13] net: phy: at803x: move qca83xx specific check in
|
||||
dedicated functions
|
||||
|
||||
Rework qca83xx specific check to dedicated function to tidy things up
|
||||
and drop useless phy_id check.
|
||||
|
||||
Also drop an useless link_change_notify for QCA8337 as it did nothing an
|
||||
returned early.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 68 ++++++++++++++++++++++------------------
|
||||
1 file changed, 37 insertions(+), 31 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -1623,27 +1623,26 @@ static int qca83xx_config_init(struct ph
|
||||
break;
|
||||
}
|
||||
|
||||
+ /* Following original QCA sourcecode set port to prefer master */
|
||||
+ phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int qca8327_config_init(struct phy_device *phydev)
|
||||
+{
|
||||
/* QCA8327 require DAC amplitude adjustment for 100m set to +6%.
|
||||
* Disable on init and enable only with 100m speed following
|
||||
* qca original source code.
|
||||
*/
|
||||
- if (phydev->drv->phy_id == QCA8327_A_PHY_ID ||
|
||||
- phydev->drv->phy_id == QCA8327_B_PHY_ID)
|
||||
- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
|
||||
- QCA8327_DEBUG_MANU_CTRL_EN, 0);
|
||||
+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
|
||||
+ QCA8327_DEBUG_MANU_CTRL_EN, 0);
|
||||
|
||||
- /* Following original QCA sourcecode set port to prefer master */
|
||||
- phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER);
|
||||
-
|
||||
- return 0;
|
||||
+ return qca83xx_config_init(phydev);
|
||||
}
|
||||
|
||||
static void qca83xx_link_change_notify(struct phy_device *phydev)
|
||||
{
|
||||
- /* QCA8337 doesn't require DAC Amplitude adjustement */
|
||||
- if (phydev->drv->phy_id == QCA8337_PHY_ID)
|
||||
- return;
|
||||
-
|
||||
/* Set DAC Amplitude adjustment to +6% for 100m on link running */
|
||||
if (phydev->state == PHY_RUNNING) {
|
||||
if (phydev->speed == SPEED_100)
|
||||
@@ -1686,19 +1685,6 @@ static int qca83xx_resume(struct phy_dev
|
||||
|
||||
static int qca83xx_suspend(struct phy_device *phydev)
|
||||
{
|
||||
- u16 mask = 0;
|
||||
-
|
||||
- /* Only QCA8337 support actual suspend.
|
||||
- * QCA8327 cause port unreliability when phy suspend
|
||||
- * is set.
|
||||
- */
|
||||
- if (phydev->drv->phy_id == QCA8337_PHY_ID) {
|
||||
- genphy_suspend(phydev);
|
||||
- } else {
|
||||
- mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX);
|
||||
- phy_modify(phydev, MII_BMCR, mask, 0);
|
||||
- }
|
||||
-
|
||||
at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN,
|
||||
AT803X_DEBUG_GATE_CLK_IN1000, 0);
|
||||
|
||||
@@ -1709,6 +1695,27 @@ static int qca83xx_suspend(struct phy_de
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int qca8337_suspend(struct phy_device *phydev)
|
||||
+{
|
||||
+ /* Only QCA8337 support actual suspend. */
|
||||
+ genphy_suspend(phydev);
|
||||
+
|
||||
+ return qca83xx_suspend(phydev);
|
||||
+}
|
||||
+
|
||||
+static int qca8327_suspend(struct phy_device *phydev)
|
||||
+{
|
||||
+ u16 mask = 0;
|
||||
+
|
||||
+ /* QCA8327 cause port unreliability when phy suspend
|
||||
+ * is set.
|
||||
+ */
|
||||
+ mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX);
|
||||
+ phy_modify(phydev, MII_BMCR, mask, 0);
|
||||
+
|
||||
+ return qca83xx_suspend(phydev);
|
||||
+}
|
||||
+
|
||||
static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
@@ -2170,7 +2177,6 @@ static struct phy_driver at803x_driver[]
|
||||
.phy_id_mask = QCA8K_PHY_ID_MASK,
|
||||
.name = "Qualcomm Atheros 8337 internal PHY",
|
||||
/* PHY_GBIT_FEATURES */
|
||||
- .link_change_notify = qca83xx_link_change_notify,
|
||||
.probe = at803x_probe,
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.config_init = qca83xx_config_init,
|
||||
@@ -2178,7 +2184,7 @@ static struct phy_driver at803x_driver[]
|
||||
.get_sset_count = qca83xx_get_sset_count,
|
||||
.get_strings = qca83xx_get_strings,
|
||||
.get_stats = qca83xx_get_stats,
|
||||
- .suspend = qca83xx_suspend,
|
||||
+ .suspend = qca8337_suspend,
|
||||
.resume = qca83xx_resume,
|
||||
}, {
|
||||
/* QCA8327-A from switch QCA8327-AL1A */
|
||||
@@ -2189,12 +2195,12 @@ static struct phy_driver at803x_driver[]
|
||||
.link_change_notify = qca83xx_link_change_notify,
|
||||
.probe = at803x_probe,
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
- .config_init = qca83xx_config_init,
|
||||
+ .config_init = qca8327_config_init,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_sset_count = qca83xx_get_sset_count,
|
||||
.get_strings = qca83xx_get_strings,
|
||||
.get_stats = qca83xx_get_stats,
|
||||
- .suspend = qca83xx_suspend,
|
||||
+ .suspend = qca8327_suspend,
|
||||
.resume = qca83xx_resume,
|
||||
}, {
|
||||
/* QCA8327-B from switch QCA8327-BL1A */
|
||||
@@ -2205,12 +2211,12 @@ static struct phy_driver at803x_driver[]
|
||||
.link_change_notify = qca83xx_link_change_notify,
|
||||
.probe = at803x_probe,
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
- .config_init = qca83xx_config_init,
|
||||
+ .config_init = qca8327_config_init,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_sset_count = qca83xx_get_sset_count,
|
||||
.get_strings = qca83xx_get_strings,
|
||||
.get_stats = qca83xx_get_stats,
|
||||
- .suspend = qca83xx_suspend,
|
||||
+ .suspend = qca8327_suspend,
|
||||
.resume = qca83xx_resume,
|
||||
}, {
|
||||
/* Qualcomm QCA8081 */
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
From 900eef75cc5018e149c52fe305c9c3fe424c52a7 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 8 Dec 2023 15:51:52 +0100
|
||||
Subject: [PATCH 05/13] net: phy: at803x: move specific DT option for at8031 to
|
||||
specific probe
|
||||
|
||||
Move specific DT options for at8031 to specific probe to tidy things up
|
||||
and make at803x_parse_dt more generic.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 55 ++++++++++++++++++++++------------------
|
||||
1 file changed, 31 insertions(+), 24 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -825,30 +825,6 @@ static int at803x_parse_dt(struct phy_de
|
||||
}
|
||||
}
|
||||
|
||||
- /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping
|
||||
- * options.
|
||||
- */
|
||||
- if (phydev->drv->phy_id == ATH8031_PHY_ID) {
|
||||
- if (of_property_read_bool(node, "qca,keep-pll-enabled"))
|
||||
- priv->flags |= AT803X_KEEP_PLL_ENABLED;
|
||||
-
|
||||
- ret = at8031_register_regulators(phydev);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- ret = devm_regulator_get_enable_optional(&phydev->mdio.dev,
|
||||
- "vddio");
|
||||
- if (ret) {
|
||||
- phydev_err(phydev, "failed to get VDDIO regulator\n");
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- /* Only AR8031/8033 support 1000Base-X for SFP modules */
|
||||
- ret = phy_sfp_probe(phydev, &at803x_sfp_ops);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1582,6 +1558,30 @@ static int at803x_cable_test_start(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int at8031_parse_dt(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct device_node *node = phydev->mdio.dev.of_node;
|
||||
+ struct at803x_priv *priv = phydev->priv;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (of_property_read_bool(node, "qca,keep-pll-enabled"))
|
||||
+ priv->flags |= AT803X_KEEP_PLL_ENABLED;
|
||||
+
|
||||
+ ret = at8031_register_regulators(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = devm_regulator_get_enable_optional(&phydev->mdio.dev,
|
||||
+ "vddio");
|
||||
+ if (ret) {
|
||||
+ phydev_err(phydev, "failed to get VDDIO regulator\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Only AR8031/8033 support 1000Base-X for SFP modules */
|
||||
+ return phy_sfp_probe(phydev, &at803x_sfp_ops);
|
||||
+}
|
||||
+
|
||||
static int at8031_probe(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
@@ -1590,6 +1590,13 @@ static int at8031_probe(struct phy_devic
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping
|
||||
+ * options.
|
||||
+ */
|
||||
+ ret = at8031_parse_dt(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
/* Disable WoL in 1588 register which is enabled
|
||||
* by default
|
||||
*/
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
From 25d2ba94005fac18fe68878cddff59a67e115554 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 8 Dec 2023 15:51:53 +0100
|
||||
Subject: [PATCH 06/13] net: phy: at803x: move specific at8031 probe mode check
|
||||
to dedicated probe
|
||||
|
||||
Move specific at8031 probe mode check to dedicated probe to make
|
||||
at803x_probe more generic and keep code tidy.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 39 +++++++++++++++++++--------------------
|
||||
1 file changed, 19 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -844,26 +844,6 @@ static int at803x_probe(struct phy_devic
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- if (phydev->drv->phy_id == ATH8031_PHY_ID) {
|
||||
- int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
|
||||
- int mode_cfg;
|
||||
-
|
||||
- if (ccr < 0)
|
||||
- return ccr;
|
||||
- mode_cfg = ccr & AT803X_MODE_CFG_MASK;
|
||||
-
|
||||
- switch (mode_cfg) {
|
||||
- case AT803X_MODE_CFG_BX1000_RGMII_50OHM:
|
||||
- case AT803X_MODE_CFG_BX1000_RGMII_75OHM:
|
||||
- priv->is_1000basex = true;
|
||||
- fallthrough;
|
||||
- case AT803X_MODE_CFG_FX100_RGMII_50OHM:
|
||||
- case AT803X_MODE_CFG_FX100_RGMII_75OHM:
|
||||
- priv->is_fiber = true;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1584,6 +1564,9 @@ static int at8031_parse_dt(struct phy_de
|
||||
|
||||
static int at8031_probe(struct phy_device *phydev)
|
||||
{
|
||||
+ struct at803x_priv *priv = phydev->priv;
|
||||
+ int mode_cfg;
|
||||
+ int ccr;
|
||||
int ret;
|
||||
|
||||
ret = at803x_probe(phydev);
|
||||
@@ -1597,6 +1580,22 @@ static int at8031_probe(struct phy_devic
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
|
||||
+ if (ccr < 0)
|
||||
+ return ccr;
|
||||
+ mode_cfg = ccr & AT803X_MODE_CFG_MASK;
|
||||
+
|
||||
+ switch (mode_cfg) {
|
||||
+ case AT803X_MODE_CFG_BX1000_RGMII_50OHM:
|
||||
+ case AT803X_MODE_CFG_BX1000_RGMII_75OHM:
|
||||
+ priv->is_1000basex = true;
|
||||
+ fallthrough;
|
||||
+ case AT803X_MODE_CFG_FX100_RGMII_50OHM:
|
||||
+ case AT803X_MODE_CFG_FX100_RGMII_75OHM:
|
||||
+ priv->is_fiber = true;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
/* Disable WoL in 1588 register which is enabled
|
||||
* by default
|
||||
*/
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
From 3ae3bc426eaf57ca8f53d75777d9a5ef779bc7b7 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 8 Dec 2023 15:51:54 +0100
|
||||
Subject: [PATCH 07/13] net: phy: at803x: move specific at8031 config_init to
|
||||
dedicated function
|
||||
|
||||
Move specific at8031 config_init to dedicated function to make
|
||||
at803x_config_init more generic and tidy things up.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 45 ++++++++++++++++++++++------------------
|
||||
1 file changed, 25 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -951,27 +951,8 @@ static int at803x_hibernation_mode_confi
|
||||
|
||||
static int at803x_config_init(struct phy_device *phydev)
|
||||
{
|
||||
- struct at803x_priv *priv = phydev->priv;
|
||||
int ret;
|
||||
|
||||
- if (phydev->drv->phy_id == ATH8031_PHY_ID) {
|
||||
- /* Some bootloaders leave the fiber page selected.
|
||||
- * Switch to the appropriate page (fiber or copper), as otherwise we
|
||||
- * read the PHY capabilities from the wrong page.
|
||||
- */
|
||||
- phy_lock_mdio_bus(phydev);
|
||||
- ret = at803x_write_page(phydev,
|
||||
- priv->is_fiber ? AT803X_PAGE_FIBER :
|
||||
- AT803X_PAGE_COPPER);
|
||||
- phy_unlock_mdio_bus(phydev);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = at8031_pll_config(phydev);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
/* The RX and TX delay default is:
|
||||
* after HW reset: RX delay enabled and TX delay disabled
|
||||
* after SW reset: RX delay enabled, while TX delay retains the
|
||||
@@ -1604,6 +1585,30 @@ static int at8031_probe(struct phy_devic
|
||||
AT803X_WOL_EN, 0);
|
||||
}
|
||||
|
||||
+static int at8031_config_init(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct at803x_priv *priv = phydev->priv;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Some bootloaders leave the fiber page selected.
|
||||
+ * Switch to the appropriate page (fiber or copper), as otherwise we
|
||||
+ * read the PHY capabilities from the wrong page.
|
||||
+ */
|
||||
+ phy_lock_mdio_bus(phydev);
|
||||
+ ret = at803x_write_page(phydev,
|
||||
+ priv->is_fiber ? AT803X_PAGE_FIBER :
|
||||
+ AT803X_PAGE_COPPER);
|
||||
+ phy_unlock_mdio_bus(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = at8031_pll_config(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return at803x_config_init(phydev);
|
||||
+}
|
||||
+
|
||||
static int qca83xx_config_init(struct phy_device *phydev)
|
||||
{
|
||||
u8 switch_revision;
|
||||
@@ -2113,7 +2118,7 @@ static struct phy_driver at803x_driver[]
|
||||
.name = "Qualcomm Atheros AR8031/AR8033",
|
||||
.flags = PHY_POLL_CABLE_TEST,
|
||||
.probe = at8031_probe,
|
||||
- .config_init = at803x_config_init,
|
||||
+ .config_init = at8031_config_init,
|
||||
.config_aneg = at803x_config_aneg,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.set_wol = at803x_set_wol,
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
From 27b89c9dc1b0393090d68d651b82f30ad2696baa Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 8 Dec 2023 15:51:55 +0100
|
||||
Subject: [PATCH 08/13] net: phy: at803x: move specific at8031 WOL bits to
|
||||
dedicated function
|
||||
|
||||
Move specific at8031 WOL enable/disable to dedicated function to make
|
||||
at803x_set_wol more generic.
|
||||
|
||||
This is needed in preparation for PHY driver split as qca8081 share the
|
||||
same function to toggle WOL settings.
|
||||
|
||||
In this new implementation WOL module in at8031 is enabled after the
|
||||
generic interrupt is setup. This should not cause any problem as the
|
||||
WOL_INT has a separate implementation and only relay on MAC bits.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 42 ++++++++++++++++++++++++----------------
|
||||
1 file changed, 25 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -466,27 +466,11 @@ static int at803x_set_wol(struct phy_dev
|
||||
phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
|
||||
mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
|
||||
|
||||
- /* Enable WOL function for 1588 */
|
||||
- if (phydev->drv->phy_id == ATH8031_PHY_ID) {
|
||||
- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
|
||||
- AT803X_PHY_MMD3_WOL_CTRL,
|
||||
- 0, AT803X_WOL_EN);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- }
|
||||
/* Enable WOL interrupt */
|
||||
ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
- /* Disable WoL function for 1588 */
|
||||
- if (phydev->drv->phy_id == ATH8031_PHY_ID) {
|
||||
- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
|
||||
- AT803X_PHY_MMD3_WOL_CTRL,
|
||||
- AT803X_WOL_EN, 0);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- }
|
||||
/* Disable WOL interrupt */
|
||||
ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
|
||||
if (ret)
|
||||
@@ -1609,6 +1593,30 @@ static int at8031_config_init(struct phy
|
||||
return at803x_config_init(phydev);
|
||||
}
|
||||
|
||||
+static int at8031_set_wol(struct phy_device *phydev,
|
||||
+ struct ethtool_wolinfo *wol)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* First setup MAC address and enable WOL interrupt */
|
||||
+ ret = at803x_set_wol(phydev, wol);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (wol->wolopts & WAKE_MAGIC)
|
||||
+ /* Enable WOL function for 1588 */
|
||||
+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
|
||||
+ AT803X_PHY_MMD3_WOL_CTRL,
|
||||
+ 0, AT803X_WOL_EN);
|
||||
+ else
|
||||
+ /* Disable WoL function for 1588 */
|
||||
+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
|
||||
+ AT803X_PHY_MMD3_WOL_CTRL,
|
||||
+ AT803X_WOL_EN, 0);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int qca83xx_config_init(struct phy_device *phydev)
|
||||
{
|
||||
u8 switch_revision;
|
||||
@@ -2121,7 +2129,7 @@ static struct phy_driver at803x_driver[]
|
||||
.config_init = at8031_config_init,
|
||||
.config_aneg = at803x_config_aneg,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
- .set_wol = at803x_set_wol,
|
||||
+ .set_wol = at8031_set_wol,
|
||||
.get_wol = at803x_get_wol,
|
||||
.suspend = at803x_suspend,
|
||||
.resume = at803x_resume,
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
From 30dd62191d3dd97c08f7f9dc9ce77ffab457e4fb Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 8 Dec 2023 15:51:56 +0100
|
||||
Subject: [PATCH 09/13] net: phy: at803x: move specific at8031 config_intr to
|
||||
dedicated function
|
||||
|
||||
Move specific at8031 config_intr bits to dedicated function to make
|
||||
at803x_config_initr more generic.
|
||||
|
||||
This is needed in preparation for PHY driver split as qca8081 share the
|
||||
same function to setup interrupts.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 30 ++++++++++++++++++++++++------
|
||||
1 file changed, 24 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -990,7 +990,6 @@ static int at803x_ack_interrupt(struct p
|
||||
|
||||
static int at803x_config_intr(struct phy_device *phydev)
|
||||
{
|
||||
- struct at803x_priv *priv = phydev->priv;
|
||||
int err;
|
||||
int value;
|
||||
|
||||
@@ -1007,10 +1006,6 @@ static int at803x_config_intr(struct phy
|
||||
value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
|
||||
value |= AT803X_INTR_ENABLE_LINK_FAIL;
|
||||
value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
|
||||
- if (priv->is_fiber) {
|
||||
- value |= AT803X_INTR_ENABLE_LINK_FAIL_BX;
|
||||
- value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX;
|
||||
- }
|
||||
|
||||
err = phy_write(phydev, AT803X_INTR_ENABLE, value);
|
||||
} else {
|
||||
@@ -1617,6 +1612,29 @@ static int at8031_set_wol(struct phy_dev
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int at8031_config_intr(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct at803x_priv *priv = phydev->priv;
|
||||
+ int err, value = 0;
|
||||
+
|
||||
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED &&
|
||||
+ priv->is_fiber) {
|
||||
+ /* Clear any pending interrupts */
|
||||
+ err = at803x_ack_interrupt(phydev);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ value |= AT803X_INTR_ENABLE_LINK_FAIL_BX;
|
||||
+ value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX;
|
||||
+
|
||||
+ err = phy_set_bits(phydev, AT803X_INTR_ENABLE, value);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return at803x_config_intr(phydev);
|
||||
+}
|
||||
+
|
||||
static int qca83xx_config_init(struct phy_device *phydev)
|
||||
{
|
||||
u8 switch_revision;
|
||||
@@ -2137,7 +2155,7 @@ static struct phy_driver at803x_driver[]
|
||||
.write_page = at803x_write_page,
|
||||
.get_features = at803x_get_features,
|
||||
.read_status = at803x_read_status,
|
||||
- .config_intr = at803x_config_intr,
|
||||
+ .config_intr = at8031_config_intr,
|
||||
.handle_interrupt = at803x_handle_interrupt,
|
||||
.get_tunable = at803x_get_tunable,
|
||||
.set_tunable = at803x_set_tunable,
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
From a5ab9d8e7ae0da8328ac1637a9755311508dc8ab Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 8 Dec 2023 15:51:57 +0100
|
||||
Subject: [PATCH 10/13] net: phy: at803x: make at8031 related DT functions name
|
||||
more specific
|
||||
|
||||
Rename at8031 related DT function name to a more specific name
|
||||
referencing they are only related to at8031 and not to the generic
|
||||
at803x PHY family.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -583,7 +583,7 @@ static int at803x_resume(struct phy_devi
|
||||
return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0);
|
||||
}
|
||||
|
||||
-static int at803x_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev,
|
||||
+static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct phy_device *phydev = rdev_get_drvdata(rdev);
|
||||
@@ -596,7 +596,7 @@ static int at803x_rgmii_reg_set_voltage_
|
||||
AT803X_DEBUG_RGMII_1V8, 0);
|
||||
}
|
||||
|
||||
-static int at803x_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev)
|
||||
+static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct phy_device *phydev = rdev_get_drvdata(rdev);
|
||||
int val;
|
||||
@@ -610,8 +610,8 @@ static int at803x_rgmii_reg_get_voltage_
|
||||
|
||||
static const struct regulator_ops vddio_regulator_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
- .set_voltage_sel = at803x_rgmii_reg_set_voltage_sel,
|
||||
- .get_voltage_sel = at803x_rgmii_reg_get_voltage_sel,
|
||||
+ .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel,
|
||||
+ .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel,
|
||||
};
|
||||
|
||||
static const unsigned int vddio_voltage_table[] = {
|
||||
@@ -666,7 +666,7 @@ static int at8031_register_regulators(st
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
|
||||
+static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
|
||||
{
|
||||
struct phy_device *phydev = upstream;
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support);
|
||||
@@ -710,10 +710,10 @@ static int at803x_sfp_insert(void *upstr
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static const struct sfp_upstream_ops at803x_sfp_ops = {
|
||||
+static const struct sfp_upstream_ops at8031_sfp_ops = {
|
||||
.attach = phy_sfp_attach,
|
||||
.detach = phy_sfp_detach,
|
||||
- .module_insert = at803x_sfp_insert,
|
||||
+ .module_insert = at8031_sfp_insert,
|
||||
};
|
||||
|
||||
static int at803x_parse_dt(struct phy_device *phydev)
|
||||
@@ -1519,7 +1519,7 @@ static int at8031_parse_dt(struct phy_de
|
||||
}
|
||||
|
||||
/* Only AR8031/8033 support 1000Base-X for SFP modules */
|
||||
- return phy_sfp_probe(phydev, &at803x_sfp_ops);
|
||||
+ return phy_sfp_probe(phydev, &at8031_sfp_ops);
|
||||
}
|
||||
|
||||
static int at8031_probe(struct phy_device *phydev)
|
||||
+297
@@ -0,0 +1,297 @@
|
||||
From f932a6dc8bae0dae9645b5b1b4c65aed8a8acb2a Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 8 Dec 2023 15:51:58 +0100
|
||||
Subject: [PATCH 11/13] net: phy: at803x: move at8031 functions in dedicated
|
||||
section
|
||||
|
||||
Move at8031 functions in dedicated section with dedicated at8031
|
||||
parse_dt and probe.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 266 +++++++++++++++++++--------------------
|
||||
1 file changed, 133 insertions(+), 133 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -583,139 +583,6 @@ static int at803x_resume(struct phy_devi
|
||||
return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0);
|
||||
}
|
||||
|
||||
-static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev,
|
||||
- unsigned int selector)
|
||||
-{
|
||||
- struct phy_device *phydev = rdev_get_drvdata(rdev);
|
||||
-
|
||||
- if (selector)
|
||||
- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
|
||||
- 0, AT803X_DEBUG_RGMII_1V8);
|
||||
- else
|
||||
- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
|
||||
- AT803X_DEBUG_RGMII_1V8, 0);
|
||||
-}
|
||||
-
|
||||
-static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev)
|
||||
-{
|
||||
- struct phy_device *phydev = rdev_get_drvdata(rdev);
|
||||
- int val;
|
||||
-
|
||||
- val = at803x_debug_reg_read(phydev, AT803X_DEBUG_REG_1F);
|
||||
- if (val < 0)
|
||||
- return val;
|
||||
-
|
||||
- return (val & AT803X_DEBUG_RGMII_1V8) ? 1 : 0;
|
||||
-}
|
||||
-
|
||||
-static const struct regulator_ops vddio_regulator_ops = {
|
||||
- .list_voltage = regulator_list_voltage_table,
|
||||
- .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel,
|
||||
- .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel,
|
||||
-};
|
||||
-
|
||||
-static const unsigned int vddio_voltage_table[] = {
|
||||
- 1500000,
|
||||
- 1800000,
|
||||
-};
|
||||
-
|
||||
-static const struct regulator_desc vddio_desc = {
|
||||
- .name = "vddio",
|
||||
- .of_match = of_match_ptr("vddio-regulator"),
|
||||
- .n_voltages = ARRAY_SIZE(vddio_voltage_table),
|
||||
- .volt_table = vddio_voltage_table,
|
||||
- .ops = &vddio_regulator_ops,
|
||||
- .type = REGULATOR_VOLTAGE,
|
||||
- .owner = THIS_MODULE,
|
||||
-};
|
||||
-
|
||||
-static const struct regulator_ops vddh_regulator_ops = {
|
||||
-};
|
||||
-
|
||||
-static const struct regulator_desc vddh_desc = {
|
||||
- .name = "vddh",
|
||||
- .of_match = of_match_ptr("vddh-regulator"),
|
||||
- .n_voltages = 1,
|
||||
- .fixed_uV = 2500000,
|
||||
- .ops = &vddh_regulator_ops,
|
||||
- .type = REGULATOR_VOLTAGE,
|
||||
- .owner = THIS_MODULE,
|
||||
-};
|
||||
-
|
||||
-static int at8031_register_regulators(struct phy_device *phydev)
|
||||
-{
|
||||
- struct at803x_priv *priv = phydev->priv;
|
||||
- struct device *dev = &phydev->mdio.dev;
|
||||
- struct regulator_config config = { };
|
||||
-
|
||||
- config.dev = dev;
|
||||
- config.driver_data = phydev;
|
||||
-
|
||||
- priv->vddio_rdev = devm_regulator_register(dev, &vddio_desc, &config);
|
||||
- if (IS_ERR(priv->vddio_rdev)) {
|
||||
- phydev_err(phydev, "failed to register VDDIO regulator\n");
|
||||
- return PTR_ERR(priv->vddio_rdev);
|
||||
- }
|
||||
-
|
||||
- priv->vddh_rdev = devm_regulator_register(dev, &vddh_desc, &config);
|
||||
- if (IS_ERR(priv->vddh_rdev)) {
|
||||
- phydev_err(phydev, "failed to register VDDH regulator\n");
|
||||
- return PTR_ERR(priv->vddh_rdev);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
|
||||
-{
|
||||
- struct phy_device *phydev = upstream;
|
||||
- __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support);
|
||||
- __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
|
||||
- DECLARE_PHY_INTERFACE_MASK(interfaces);
|
||||
- phy_interface_t iface;
|
||||
-
|
||||
- linkmode_zero(phy_support);
|
||||
- phylink_set(phy_support, 1000baseX_Full);
|
||||
- phylink_set(phy_support, 1000baseT_Full);
|
||||
- phylink_set(phy_support, Autoneg);
|
||||
- phylink_set(phy_support, Pause);
|
||||
- phylink_set(phy_support, Asym_Pause);
|
||||
-
|
||||
- linkmode_zero(sfp_support);
|
||||
- sfp_parse_support(phydev->sfp_bus, id, sfp_support, interfaces);
|
||||
- /* Some modules support 10G modes as well as others we support.
|
||||
- * Mask out non-supported modes so the correct interface is picked.
|
||||
- */
|
||||
- linkmode_and(sfp_support, phy_support, sfp_support);
|
||||
-
|
||||
- if (linkmode_empty(sfp_support)) {
|
||||
- dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- iface = sfp_select_interface(phydev->sfp_bus, sfp_support);
|
||||
-
|
||||
- /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes
|
||||
- * interface for use with SFP modules.
|
||||
- * However, some copper modules detected as having a preferred SGMII
|
||||
- * interface do default to and function in 1000Base-X mode, so just
|
||||
- * print a warning and allow such modules, as they may have some chance
|
||||
- * of working.
|
||||
- */
|
||||
- if (iface == PHY_INTERFACE_MODE_SGMII)
|
||||
- dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n");
|
||||
- else if (iface != PHY_INTERFACE_MODE_1000BASEX)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static const struct sfp_upstream_ops at8031_sfp_ops = {
|
||||
- .attach = phy_sfp_attach,
|
||||
- .detach = phy_sfp_detach,
|
||||
- .module_insert = at8031_sfp_insert,
|
||||
-};
|
||||
-
|
||||
static int at803x_parse_dt(struct phy_device *phydev)
|
||||
{
|
||||
struct device_node *node = phydev->mdio.dev.of_node;
|
||||
@@ -1498,6 +1365,139 @@ static int at803x_cable_test_start(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev,
|
||||
+ unsigned int selector)
|
||||
+{
|
||||
+ struct phy_device *phydev = rdev_get_drvdata(rdev);
|
||||
+
|
||||
+ if (selector)
|
||||
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
|
||||
+ 0, AT803X_DEBUG_RGMII_1V8);
|
||||
+ else
|
||||
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
|
||||
+ AT803X_DEBUG_RGMII_1V8, 0);
|
||||
+}
|
||||
+
|
||||
+static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev)
|
||||
+{
|
||||
+ struct phy_device *phydev = rdev_get_drvdata(rdev);
|
||||
+ int val;
|
||||
+
|
||||
+ val = at803x_debug_reg_read(phydev, AT803X_DEBUG_REG_1F);
|
||||
+ if (val < 0)
|
||||
+ return val;
|
||||
+
|
||||
+ return (val & AT803X_DEBUG_RGMII_1V8) ? 1 : 0;
|
||||
+}
|
||||
+
|
||||
+static const struct regulator_ops vddio_regulator_ops = {
|
||||
+ .list_voltage = regulator_list_voltage_table,
|
||||
+ .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel,
|
||||
+ .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel,
|
||||
+};
|
||||
+
|
||||
+static const unsigned int vddio_voltage_table[] = {
|
||||
+ 1500000,
|
||||
+ 1800000,
|
||||
+};
|
||||
+
|
||||
+static const struct regulator_desc vddio_desc = {
|
||||
+ .name = "vddio",
|
||||
+ .of_match = of_match_ptr("vddio-regulator"),
|
||||
+ .n_voltages = ARRAY_SIZE(vddio_voltage_table),
|
||||
+ .volt_table = vddio_voltage_table,
|
||||
+ .ops = &vddio_regulator_ops,
|
||||
+ .type = REGULATOR_VOLTAGE,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static const struct regulator_ops vddh_regulator_ops = {
|
||||
+};
|
||||
+
|
||||
+static const struct regulator_desc vddh_desc = {
|
||||
+ .name = "vddh",
|
||||
+ .of_match = of_match_ptr("vddh-regulator"),
|
||||
+ .n_voltages = 1,
|
||||
+ .fixed_uV = 2500000,
|
||||
+ .ops = &vddh_regulator_ops,
|
||||
+ .type = REGULATOR_VOLTAGE,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int at8031_register_regulators(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct at803x_priv *priv = phydev->priv;
|
||||
+ struct device *dev = &phydev->mdio.dev;
|
||||
+ struct regulator_config config = { };
|
||||
+
|
||||
+ config.dev = dev;
|
||||
+ config.driver_data = phydev;
|
||||
+
|
||||
+ priv->vddio_rdev = devm_regulator_register(dev, &vddio_desc, &config);
|
||||
+ if (IS_ERR(priv->vddio_rdev)) {
|
||||
+ phydev_err(phydev, "failed to register VDDIO regulator\n");
|
||||
+ return PTR_ERR(priv->vddio_rdev);
|
||||
+ }
|
||||
+
|
||||
+ priv->vddh_rdev = devm_regulator_register(dev, &vddh_desc, &config);
|
||||
+ if (IS_ERR(priv->vddh_rdev)) {
|
||||
+ phydev_err(phydev, "failed to register VDDH regulator\n");
|
||||
+ return PTR_ERR(priv->vddh_rdev);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
|
||||
+{
|
||||
+ struct phy_device *phydev = upstream;
|
||||
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support);
|
||||
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
|
||||
+ DECLARE_PHY_INTERFACE_MASK(interfaces);
|
||||
+ phy_interface_t iface;
|
||||
+
|
||||
+ linkmode_zero(phy_support);
|
||||
+ phylink_set(phy_support, 1000baseX_Full);
|
||||
+ phylink_set(phy_support, 1000baseT_Full);
|
||||
+ phylink_set(phy_support, Autoneg);
|
||||
+ phylink_set(phy_support, Pause);
|
||||
+ phylink_set(phy_support, Asym_Pause);
|
||||
+
|
||||
+ linkmode_zero(sfp_support);
|
||||
+ sfp_parse_support(phydev->sfp_bus, id, sfp_support, interfaces);
|
||||
+ /* Some modules support 10G modes as well as others we support.
|
||||
+ * Mask out non-supported modes so the correct interface is picked.
|
||||
+ */
|
||||
+ linkmode_and(sfp_support, phy_support, sfp_support);
|
||||
+
|
||||
+ if (linkmode_empty(sfp_support)) {
|
||||
+ dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ iface = sfp_select_interface(phydev->sfp_bus, sfp_support);
|
||||
+
|
||||
+ /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes
|
||||
+ * interface for use with SFP modules.
|
||||
+ * However, some copper modules detected as having a preferred SGMII
|
||||
+ * interface do default to and function in 1000Base-X mode, so just
|
||||
+ * print a warning and allow such modules, as they may have some chance
|
||||
+ * of working.
|
||||
+ */
|
||||
+ if (iface == PHY_INTERFACE_MODE_SGMII)
|
||||
+ dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n");
|
||||
+ else if (iface != PHY_INTERFACE_MODE_1000BASEX)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct sfp_upstream_ops at8031_sfp_ops = {
|
||||
+ .attach = phy_sfp_attach,
|
||||
+ .detach = phy_sfp_detach,
|
||||
+ .module_insert = at8031_sfp_insert,
|
||||
+};
|
||||
+
|
||||
static int at8031_parse_dt(struct phy_device *phydev)
|
||||
{
|
||||
struct device_node *node = phydev->mdio.dev.of_node;
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
From 21a2802a8365cfa82cc02187c1f95136d85592ad Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 8 Dec 2023 15:51:59 +0100
|
||||
Subject: [PATCH 12/13] net: phy: at803x: move at8035 specific DT parse to
|
||||
dedicated probe
|
||||
|
||||
Move at8035 specific DT parse for clock out frequency to dedicated probe
|
||||
to make at803x probe function more generic.
|
||||
|
||||
This is to tidy code and no behaviour change are intended.
|
||||
|
||||
Detection logic is changed, we check if the clk 25m mask is set and if
|
||||
it's not zero, we assume the qca,clk-out-frequency property is set.
|
||||
|
||||
The property is checked in the generic at803x_parse_dt called by
|
||||
at803x_probe.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 60 +++++++++++++++++++++++++++-------------
|
||||
1 file changed, 41 insertions(+), 19 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -638,23 +638,6 @@ static int at803x_parse_dt(struct phy_de
|
||||
|
||||
priv->clk_25m_reg |= FIELD_PREP(AT803X_CLK_OUT_MASK, sel);
|
||||
priv->clk_25m_mask |= AT803X_CLK_OUT_MASK;
|
||||
-
|
||||
- /* Fixup for the AR8030/AR8035. This chip has another mask and
|
||||
- * doesn't support the DSP reference. Eg. the lowest bit of the
|
||||
- * mask. The upper two bits select the same frequencies. Mask
|
||||
- * the lowest bit here.
|
||||
- *
|
||||
- * Warning:
|
||||
- * There was no datasheet for the AR8030 available so this is
|
||||
- * just a guess. But the AR8035 is listed as pin compatible
|
||||
- * to the AR8030 so there might be a good chance it works on
|
||||
- * the AR8030 too.
|
||||
- */
|
||||
- if (phydev->drv->phy_id == ATH8030_PHY_ID ||
|
||||
- phydev->drv->phy_id == ATH8035_PHY_ID) {
|
||||
- priv->clk_25m_reg &= AT8035_CLK_OUT_MASK;
|
||||
- priv->clk_25m_mask &= AT8035_CLK_OUT_MASK;
|
||||
- }
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(node, "qca,clk-out-strength", &strength);
|
||||
@@ -1635,6 +1618,45 @@ static int at8031_config_intr(struct phy
|
||||
return at803x_config_intr(phydev);
|
||||
}
|
||||
|
||||
+static int at8035_parse_dt(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct at803x_priv *priv = phydev->priv;
|
||||
+
|
||||
+ /* Mask is set by the generic at803x_parse_dt
|
||||
+ * if property is set. Assume property is set
|
||||
+ * with the mask not zero.
|
||||
+ */
|
||||
+ if (priv->clk_25m_mask) {
|
||||
+ /* Fixup for the AR8030/AR8035. This chip has another mask and
|
||||
+ * doesn't support the DSP reference. Eg. the lowest bit of the
|
||||
+ * mask. The upper two bits select the same frequencies. Mask
|
||||
+ * the lowest bit here.
|
||||
+ *
|
||||
+ * Warning:
|
||||
+ * There was no datasheet for the AR8030 available so this is
|
||||
+ * just a guess. But the AR8035 is listed as pin compatible
|
||||
+ * to the AR8030 so there might be a good chance it works on
|
||||
+ * the AR8030 too.
|
||||
+ */
|
||||
+ priv->clk_25m_reg &= AT8035_CLK_OUT_MASK;
|
||||
+ priv->clk_25m_mask &= AT8035_CLK_OUT_MASK;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* AR8030 and AR8035 shared the same special mask for clk_25m */
|
||||
+static int at8035_probe(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = at803x_probe(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return at8035_parse_dt(phydev);
|
||||
+}
|
||||
+
|
||||
static int qca83xx_config_init(struct phy_device *phydev)
|
||||
{
|
||||
u8 switch_revision;
|
||||
@@ -2107,7 +2129,7 @@ static struct phy_driver at803x_driver[]
|
||||
PHY_ID_MATCH_EXACT(ATH8035_PHY_ID),
|
||||
.name = "Qualcomm Atheros AR8035",
|
||||
.flags = PHY_POLL_CABLE_TEST,
|
||||
- .probe = at803x_probe,
|
||||
+ .probe = at8035_probe,
|
||||
.config_aneg = at803x_config_aneg,
|
||||
.config_init = at803x_config_init,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
@@ -2128,7 +2150,7 @@ static struct phy_driver at803x_driver[]
|
||||
.phy_id = ATH8030_PHY_ID,
|
||||
.name = "Qualcomm Atheros AR8030",
|
||||
.phy_id_mask = AT8030_PHY_ID_MASK,
|
||||
- .probe = at803x_probe,
|
||||
+ .probe = at8035_probe,
|
||||
.config_init = at803x_config_init,
|
||||
.link_change_notify = at803x_link_change_notify,
|
||||
.set_wol = at803x_set_wol,
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
From ef9df47b449e32e06501a11272809be49019bdb6 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 8 Dec 2023 15:52:00 +0100
|
||||
Subject: [PATCH 13/13] net: phy: at803x: drop specific PHY ID check from cable
|
||||
test functions
|
||||
|
||||
Drop specific PHY ID check for cable test functions for at803x. This is
|
||||
done to make functions more generic. While at it better describe what
|
||||
the functions does by using more symbolic function names.
|
||||
|
||||
PHYs that requires to set additional reg are moved to specific function
|
||||
calling the more generic one.
|
||||
|
||||
cdt_start and cdt_wait_for_completion are changed to take an additional
|
||||
arg to pass specific values specific to the PHY.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 95 +++++++++++++++++++++-------------------
|
||||
1 file changed, 50 insertions(+), 45 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -1222,31 +1222,16 @@ static int at803x_cdt_fault_length(u16 s
|
||||
return (dt * 824) / 10;
|
||||
}
|
||||
|
||||
-static int at803x_cdt_start(struct phy_device *phydev, int pair)
|
||||
+static int at803x_cdt_start(struct phy_device *phydev,
|
||||
+ u32 cdt_start)
|
||||
{
|
||||
- u16 cdt;
|
||||
-
|
||||
- /* qca8081 takes the different bit 15 to enable CDT test */
|
||||
- if (phydev->drv->phy_id == QCA8081_PHY_ID)
|
||||
- cdt = QCA808X_CDT_ENABLE_TEST |
|
||||
- QCA808X_CDT_LENGTH_UNIT |
|
||||
- QCA808X_CDT_INTER_CHECK_DIS;
|
||||
- else
|
||||
- cdt = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) |
|
||||
- AT803X_CDT_ENABLE_TEST;
|
||||
-
|
||||
- return phy_write(phydev, AT803X_CDT, cdt);
|
||||
+ return phy_write(phydev, AT803X_CDT, cdt_start);
|
||||
}
|
||||
|
||||
-static int at803x_cdt_wait_for_completion(struct phy_device *phydev)
|
||||
+static int at803x_cdt_wait_for_completion(struct phy_device *phydev,
|
||||
+ u32 cdt_en)
|
||||
{
|
||||
int val, ret;
|
||||
- u16 cdt_en;
|
||||
-
|
||||
- if (phydev->drv->phy_id == QCA8081_PHY_ID)
|
||||
- cdt_en = QCA808X_CDT_ENABLE_TEST;
|
||||
- else
|
||||
- cdt_en = AT803X_CDT_ENABLE_TEST;
|
||||
|
||||
/* One test run takes about 25ms */
|
||||
ret = phy_read_poll_timeout(phydev, AT803X_CDT, val,
|
||||
@@ -1266,11 +1251,13 @@ static int at803x_cable_test_one_pair(st
|
||||
};
|
||||
int ret, val;
|
||||
|
||||
- ret = at803x_cdt_start(phydev, pair);
|
||||
+ val = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) |
|
||||
+ AT803X_CDT_ENABLE_TEST;
|
||||
+ ret = at803x_cdt_start(phydev, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = at803x_cdt_wait_for_completion(phydev);
|
||||
+ ret = at803x_cdt_wait_for_completion(phydev, AT803X_CDT_ENABLE_TEST);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1292,19 +1279,11 @@ static int at803x_cable_test_one_pair(st
|
||||
}
|
||||
|
||||
static int at803x_cable_test_get_status(struct phy_device *phydev,
|
||||
- bool *finished)
|
||||
+ bool *finished, unsigned long pair_mask)
|
||||
{
|
||||
- unsigned long pair_mask;
|
||||
int retries = 20;
|
||||
int pair, ret;
|
||||
|
||||
- if (phydev->phy_id == ATH9331_PHY_ID ||
|
||||
- phydev->phy_id == ATH8032_PHY_ID ||
|
||||
- phydev->phy_id == QCA9561_PHY_ID)
|
||||
- pair_mask = 0x3;
|
||||
- else
|
||||
- pair_mask = 0xf;
|
||||
-
|
||||
*finished = false;
|
||||
|
||||
/* According to the datasheet the CDT can be performed when
|
||||
@@ -1331,7 +1310,7 @@ static int at803x_cable_test_get_status(
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int at803x_cable_test_start(struct phy_device *phydev)
|
||||
+static void at803x_cable_test_autoneg(struct phy_device *phydev)
|
||||
{
|
||||
/* Enable auto-negotiation, but advertise no capabilities, no link
|
||||
* will be established. A restart of the auto-negotiation is not
|
||||
@@ -1339,11 +1318,11 @@ static int at803x_cable_test_start(struc
|
||||
*/
|
||||
phy_write(phydev, MII_BMCR, BMCR_ANENABLE);
|
||||
phy_write(phydev, MII_ADVERTISE, ADVERTISE_CSMA);
|
||||
- if (phydev->phy_id != ATH9331_PHY_ID &&
|
||||
- phydev->phy_id != ATH8032_PHY_ID &&
|
||||
- phydev->phy_id != QCA9561_PHY_ID)
|
||||
- phy_write(phydev, MII_CTRL1000, 0);
|
||||
+}
|
||||
|
||||
+static int at803x_cable_test_start(struct phy_device *phydev)
|
||||
+{
|
||||
+ at803x_cable_test_autoneg(phydev);
|
||||
/* we do all the (time consuming) work later */
|
||||
return 0;
|
||||
}
|
||||
@@ -1618,6 +1597,29 @@ static int at8031_config_intr(struct phy
|
||||
return at803x_config_intr(phydev);
|
||||
}
|
||||
|
||||
+/* AR8031 and AR8035 share the same cable test get status reg */
|
||||
+static int at8031_cable_test_get_status(struct phy_device *phydev,
|
||||
+ bool *finished)
|
||||
+{
|
||||
+ return at803x_cable_test_get_status(phydev, finished, 0xf);
|
||||
+}
|
||||
+
|
||||
+/* AR8031 and AR8035 share the same cable test start logic */
|
||||
+static int at8031_cable_test_start(struct phy_device *phydev)
|
||||
+{
|
||||
+ at803x_cable_test_autoneg(phydev);
|
||||
+ phy_write(phydev, MII_CTRL1000, 0);
|
||||
+ /* we do all the (time consuming) work later */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* AR8032, AR9331 and QCA9561 share the same cable test get status reg */
|
||||
+static int at8032_cable_test_get_status(struct phy_device *phydev,
|
||||
+ bool *finished)
|
||||
+{
|
||||
+ return at803x_cable_test_get_status(phydev, finished, 0x3);
|
||||
+}
|
||||
+
|
||||
static int at8035_parse_dt(struct phy_device *phydev)
|
||||
{
|
||||
struct at803x_priv *priv = phydev->priv;
|
||||
@@ -2041,11 +2043,14 @@ static int qca808x_cable_test_get_status
|
||||
|
||||
*finished = false;
|
||||
|
||||
- ret = at803x_cdt_start(phydev, 0);
|
||||
+ val = QCA808X_CDT_ENABLE_TEST |
|
||||
+ QCA808X_CDT_LENGTH_UNIT |
|
||||
+ QCA808X_CDT_INTER_CHECK_DIS;
|
||||
+ ret = at803x_cdt_start(phydev, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = at803x_cdt_wait_for_completion(phydev);
|
||||
+ ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -2143,8 +2148,8 @@ static struct phy_driver at803x_driver[]
|
||||
.handle_interrupt = at803x_handle_interrupt,
|
||||
.get_tunable = at803x_get_tunable,
|
||||
.set_tunable = at803x_set_tunable,
|
||||
- .cable_test_start = at803x_cable_test_start,
|
||||
- .cable_test_get_status = at803x_cable_test_get_status,
|
||||
+ .cable_test_start = at8031_cable_test_start,
|
||||
+ .cable_test_get_status = at8031_cable_test_get_status,
|
||||
}, {
|
||||
/* Qualcomm Atheros AR8030 */
|
||||
.phy_id = ATH8030_PHY_ID,
|
||||
@@ -2181,8 +2186,8 @@ static struct phy_driver at803x_driver[]
|
||||
.handle_interrupt = at803x_handle_interrupt,
|
||||
.get_tunable = at803x_get_tunable,
|
||||
.set_tunable = at803x_set_tunable,
|
||||
- .cable_test_start = at803x_cable_test_start,
|
||||
- .cable_test_get_status = at803x_cable_test_get_status,
|
||||
+ .cable_test_start = at8031_cable_test_start,
|
||||
+ .cable_test_get_status = at8031_cable_test_get_status,
|
||||
}, {
|
||||
/* Qualcomm Atheros AR8032 */
|
||||
PHY_ID_MATCH_EXACT(ATH8032_PHY_ID),
|
||||
@@ -2197,7 +2202,7 @@ static struct phy_driver at803x_driver[]
|
||||
.config_intr = at803x_config_intr,
|
||||
.handle_interrupt = at803x_handle_interrupt,
|
||||
.cable_test_start = at803x_cable_test_start,
|
||||
- .cable_test_get_status = at803x_cable_test_get_status,
|
||||
+ .cable_test_get_status = at8032_cable_test_get_status,
|
||||
}, {
|
||||
/* ATHEROS AR9331 */
|
||||
PHY_ID_MATCH_EXACT(ATH9331_PHY_ID),
|
||||
@@ -2210,7 +2215,7 @@ static struct phy_driver at803x_driver[]
|
||||
.config_intr = at803x_config_intr,
|
||||
.handle_interrupt = at803x_handle_interrupt,
|
||||
.cable_test_start = at803x_cable_test_start,
|
||||
- .cable_test_get_status = at803x_cable_test_get_status,
|
||||
+ .cable_test_get_status = at8032_cable_test_get_status,
|
||||
.read_status = at803x_read_status,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.config_aneg = at803x_config_aneg,
|
||||
@@ -2226,7 +2231,7 @@ static struct phy_driver at803x_driver[]
|
||||
.config_intr = at803x_config_intr,
|
||||
.handle_interrupt = at803x_handle_interrupt,
|
||||
.cable_test_start = at803x_cable_test_start,
|
||||
- .cable_test_get_status = at803x_cable_test_get_status,
|
||||
+ .cable_test_get_status = at8032_cable_test_get_status,
|
||||
.read_status = at803x_read_status,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.config_aneg = at803x_config_aneg,
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
From 8e732f1c6f2dc5e18f766d0f1b11df9db2dd044a Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Thu, 14 Dec 2023 01:44:31 +0100
|
||||
Subject: [PATCH 1/2] net: phy: at803x: move specific qca808x config_aneg to
|
||||
dedicated function
|
||||
|
||||
Move specific qca808x config_aneg to dedicated function to permit easier
|
||||
split of qca808x portion from at803x driver.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 66 ++++++++++++++++++++++++----------------
|
||||
1 file changed, 40 insertions(+), 26 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -1045,9 +1045,8 @@ static int at803x_config_mdix(struct phy
|
||||
FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val));
|
||||
}
|
||||
|
||||
-static int at803x_config_aneg(struct phy_device *phydev)
|
||||
+static int at803x_prepare_config_aneg(struct phy_device *phydev)
|
||||
{
|
||||
- struct at803x_priv *priv = phydev->priv;
|
||||
int ret;
|
||||
|
||||
ret = at803x_config_mdix(phydev, phydev->mdix_ctrl);
|
||||
@@ -1064,33 +1063,22 @@ static int at803x_config_aneg(struct phy
|
||||
return ret;
|
||||
}
|
||||
|
||||
- if (priv->is_1000basex)
|
||||
- return genphy_c37_config_aneg(phydev);
|
||||
-
|
||||
- /* Do not restart auto-negotiation by setting ret to 0 defautly,
|
||||
- * when calling __genphy_config_aneg later.
|
||||
- */
|
||||
- ret = 0;
|
||||
-
|
||||
- if (phydev->drv->phy_id == QCA8081_PHY_ID) {
|
||||
- int phy_ctrl = 0;
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
- /* The reg MII_BMCR also needs to be configured for force mode, the
|
||||
- * genphy_config_aneg is also needed.
|
||||
- */
|
||||
- if (phydev->autoneg == AUTONEG_DISABLE)
|
||||
- genphy_c45_pma_setup_forced(phydev);
|
||||
+static int at803x_config_aneg(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct at803x_priv *priv = phydev->priv;
|
||||
+ int ret;
|
||||
|
||||
- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
|
||||
- phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
|
||||
+ ret = at803x_prepare_config_aneg(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
|
||||
- MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
- }
|
||||
+ if (priv->is_1000basex)
|
||||
+ return genphy_c37_config_aneg(phydev);
|
||||
|
||||
- return __genphy_config_aneg(phydev, ret);
|
||||
+ return genphy_config_aneg(phydev);
|
||||
}
|
||||
|
||||
static int at803x_get_downshift(struct phy_device *phydev, u8 *d)
|
||||
@@ -2118,6 +2106,32 @@ static int qca808x_get_features(struct p
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int qca808x_config_aneg(struct phy_device *phydev)
|
||||
+{
|
||||
+ int phy_ctrl = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = at803x_prepare_config_aneg(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* The reg MII_BMCR also needs to be configured for force mode, the
|
||||
+ * genphy_config_aneg is also needed.
|
||||
+ */
|
||||
+ if (phydev->autoneg == AUTONEG_DISABLE)
|
||||
+ genphy_c45_pma_setup_forced(phydev);
|
||||
+
|
||||
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
|
||||
+ phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
|
||||
+
|
||||
+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
|
||||
+ MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return __genphy_config_aneg(phydev, ret);
|
||||
+}
|
||||
+
|
||||
static void qca808x_link_change_notify(struct phy_device *phydev)
|
||||
{
|
||||
/* Assert interface sgmii fifo on link down, deassert it on link up,
|
||||
@@ -2295,7 +2309,7 @@ static struct phy_driver at803x_driver[]
|
||||
.set_wol = at803x_set_wol,
|
||||
.get_wol = at803x_get_wol,
|
||||
.get_features = qca808x_get_features,
|
||||
- .config_aneg = at803x_config_aneg,
|
||||
+ .config_aneg = qca808x_config_aneg,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.read_status = qca808x_read_status,
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
From 38eb804e8458ba181a03a0498ce4bf84eebd1931 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Thu, 14 Dec 2023 01:44:32 +0100
|
||||
Subject: [PATCH 2/2] net: phy: at803x: make read specific status function more
|
||||
generic
|
||||
|
||||
Rework read specific status function to be more generic. The function
|
||||
apply different speed mask based on the PHY ID. Make it more generic by
|
||||
adding an additional arg to pass the specific speed (ss) mask and use
|
||||
the provided mask to parse the speed value.
|
||||
|
||||
This is needed to permit an easier deatch of qca808x code from the
|
||||
at803x driver.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 26 ++++++++++++++++++--------
|
||||
1 file changed, 18 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -301,6 +301,11 @@ static struct at803x_hw_stat qca83xx_hw_
|
||||
{ "eee_wake_errors", 0x16, GENMASK(15, 0), MMD},
|
||||
};
|
||||
|
||||
+struct at803x_ss_mask {
|
||||
+ u16 speed_mask;
|
||||
+ u8 speed_shift;
|
||||
+};
|
||||
+
|
||||
struct at803x_priv {
|
||||
int flags;
|
||||
u16 clk_25m_reg;
|
||||
@@ -921,7 +926,8 @@ static void at803x_link_change_notify(st
|
||||
}
|
||||
}
|
||||
|
||||
-static int at803x_read_specific_status(struct phy_device *phydev)
|
||||
+static int at803x_read_specific_status(struct phy_device *phydev,
|
||||
+ struct at803x_ss_mask ss_mask)
|
||||
{
|
||||
int ss;
|
||||
|
||||
@@ -940,11 +946,8 @@ static int at803x_read_specific_status(s
|
||||
if (sfc < 0)
|
||||
return sfc;
|
||||
|
||||
- /* qca8081 takes the different bits for speed value from at803x */
|
||||
- if (phydev->drv->phy_id == QCA8081_PHY_ID)
|
||||
- speed = FIELD_GET(QCA808X_SS_SPEED_MASK, ss);
|
||||
- else
|
||||
- speed = FIELD_GET(AT803X_SS_SPEED_MASK, ss);
|
||||
+ speed = ss & ss_mask.speed_mask;
|
||||
+ speed >>= ss_mask.speed_shift;
|
||||
|
||||
switch (speed) {
|
||||
case AT803X_SS_SPEED_10:
|
||||
@@ -989,6 +992,7 @@ static int at803x_read_specific_status(s
|
||||
static int at803x_read_status(struct phy_device *phydev)
|
||||
{
|
||||
struct at803x_priv *priv = phydev->priv;
|
||||
+ struct at803x_ss_mask ss_mask = { 0 };
|
||||
int err, old_link = phydev->link;
|
||||
|
||||
if (priv->is_1000basex)
|
||||
@@ -1012,7 +1016,9 @@ static int at803x_read_status(struct phy
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
- err = at803x_read_specific_status(phydev);
|
||||
+ ss_mask.speed_mask = AT803X_SS_SPEED_MASK;
|
||||
+ ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK);
|
||||
+ err = at803x_read_specific_status(phydev, ss_mask);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@@ -1869,6 +1875,7 @@ static int qca808x_config_init(struct ph
|
||||
|
||||
static int qca808x_read_status(struct phy_device *phydev)
|
||||
{
|
||||
+ struct at803x_ss_mask ss_mask = { 0 };
|
||||
int ret;
|
||||
|
||||
ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
|
||||
@@ -1882,7 +1889,10 @@ static int qca808x_read_status(struct ph
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = at803x_read_specific_status(phydev);
|
||||
+ /* qca8081 takes the different bits for speed value from at803x */
|
||||
+ ss_mask.speed_mask = QCA808X_SS_SPEED_MASK;
|
||||
+ ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK);
|
||||
+ ret = at803x_read_specific_status(phydev, ss_mask);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
From fc9d7264ddc32eaa647d6bfcdc25cdf9f786fde0 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Mon, 18 Dec 2023 00:27:39 +0100
|
||||
Subject: [PATCH 1/2] net: phy: at803x: remove extra space after cast
|
||||
|
||||
Remove extra space after cast as reported by checkpatch to keep code
|
||||
clean.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://lore.kernel.org/r/20231217232739.27065-1-ansuelsmth@gmail.com
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -462,7 +462,7 @@ static int at803x_set_wol(struct phy_dev
|
||||
if (!ndev)
|
||||
return -ENODEV;
|
||||
|
||||
- mac = (const u8 *) ndev->dev_addr;
|
||||
+ mac = (const u8 *)ndev->dev_addr;
|
||||
|
||||
if (!is_valid_ether_addr(mac))
|
||||
return -EINVAL;
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
From 3ab5720881a924fb6405d9e6a3b09f1026467c47 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Mon, 18 Dec 2023 00:25:08 +0100
|
||||
Subject: [PATCH 2/2] net: phy: at803x: replace msleep(1) with usleep_range
|
||||
|
||||
Replace msleep(1) with usleep_range as suggested by timers-howto guide.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://lore.kernel.org/r/20231217232508.26470-1-ansuelsmth@gmail.com
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -916,9 +916,9 @@ static void at803x_link_change_notify(st
|
||||
at803x_context_save(phydev, &context);
|
||||
|
||||
phy_device_reset(phydev, 1);
|
||||
- msleep(1);
|
||||
+ usleep_range(1000, 2000);
|
||||
phy_device_reset(phydev, 0);
|
||||
- msleep(1);
|
||||
+ usleep_range(1000, 2000);
|
||||
|
||||
at803x_context_restore(phydev, &context);
|
||||
|
||||
@@ -1733,7 +1733,7 @@ static int qca83xx_resume(struct phy_dev
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- msleep(1);
|
||||
+ usleep_range(1000, 2000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
From 7961ef1fa10ec35ad6923fb5751877116e4b035b Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Tue, 19 Dec 2023 21:21:24 +0100
|
||||
Subject: [PATCH] net: phy: at803x: better align function varibles to open
|
||||
parenthesis
|
||||
|
||||
Better align function variables to open parenthesis as suggested by
|
||||
checkpatch script for qca808x function to make code cleaner.
|
||||
|
||||
For cable_test_get_status function some additional rework was needed to
|
||||
handle too long functions.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 67 ++++++++++++++++++++++------------------
|
||||
1 file changed, 37 insertions(+), 30 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -1781,27 +1781,27 @@ static int qca808x_phy_fast_retrain_conf
|
||||
return ret;
|
||||
|
||||
phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1,
|
||||
- QCA808X_TOP_OPTION1_DATA);
|
||||
+ QCA808X_TOP_OPTION1_DATA);
|
||||
phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB,
|
||||
- QCA808X_MSE_THRESHOLD_20DB_VALUE);
|
||||
+ QCA808X_MSE_THRESHOLD_20DB_VALUE);
|
||||
phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB,
|
||||
- QCA808X_MSE_THRESHOLD_17DB_VALUE);
|
||||
+ QCA808X_MSE_THRESHOLD_17DB_VALUE);
|
||||
phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB,
|
||||
- QCA808X_MSE_THRESHOLD_27DB_VALUE);
|
||||
+ QCA808X_MSE_THRESHOLD_27DB_VALUE);
|
||||
phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB,
|
||||
- QCA808X_MSE_THRESHOLD_28DB_VALUE);
|
||||
+ QCA808X_MSE_THRESHOLD_28DB_VALUE);
|
||||
phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1,
|
||||
- QCA808X_MMD3_DEBUG_1_VALUE);
|
||||
+ QCA808X_MMD3_DEBUG_1_VALUE);
|
||||
phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4,
|
||||
- QCA808X_MMD3_DEBUG_4_VALUE);
|
||||
+ QCA808X_MMD3_DEBUG_4_VALUE);
|
||||
phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5,
|
||||
- QCA808X_MMD3_DEBUG_5_VALUE);
|
||||
+ QCA808X_MMD3_DEBUG_5_VALUE);
|
||||
phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3,
|
||||
- QCA808X_MMD3_DEBUG_3_VALUE);
|
||||
+ QCA808X_MMD3_DEBUG_3_VALUE);
|
||||
phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6,
|
||||
- QCA808X_MMD3_DEBUG_6_VALUE);
|
||||
+ QCA808X_MMD3_DEBUG_6_VALUE);
|
||||
phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2,
|
||||
- QCA808X_MMD3_DEBUG_2_VALUE);
|
||||
+ QCA808X_MMD3_DEBUG_2_VALUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1838,13 +1838,14 @@ static int qca808x_config_init(struct ph
|
||||
|
||||
/* Active adc&vga on 802.3az for the link 1000M and 100M */
|
||||
ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7,
|
||||
- QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
|
||||
+ QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Adjust the threshold on 802.3az for the link 1000M */
|
||||
ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
|
||||
- QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, QCA808X_MMD3_AZ_TRAINING_VAL);
|
||||
+ QCA808X_PHY_MMD3_AZ_TRAINING_CTRL,
|
||||
+ QCA808X_MMD3_AZ_TRAINING_VAL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1870,7 +1871,8 @@ static int qca808x_config_init(struct ph
|
||||
|
||||
/* Configure adc threshold as 100mv for the link 10M */
|
||||
return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
|
||||
- QCA808X_ADC_THRESHOLD_MASK, QCA808X_ADC_THRESHOLD_100MV);
|
||||
+ QCA808X_ADC_THRESHOLD_MASK,
|
||||
+ QCA808X_ADC_THRESHOLD_100MV);
|
||||
}
|
||||
|
||||
static int qca808x_read_status(struct phy_device *phydev)
|
||||
@@ -1883,7 +1885,7 @@ static int qca808x_read_status(struct ph
|
||||
return ret;
|
||||
|
||||
linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
|
||||
- ret & MDIO_AN_10GBT_STAT_LP2_5G);
|
||||
+ ret & MDIO_AN_10GBT_STAT_LP2_5G);
|
||||
|
||||
ret = genphy_read_status(phydev);
|
||||
if (ret)
|
||||
@@ -1913,7 +1915,7 @@ static int qca808x_read_status(struct ph
|
||||
*/
|
||||
if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
|
||||
if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
|
||||
- qca808x_is_prefer_master(phydev)) {
|
||||
+ qca808x_is_prefer_master(phydev)) {
|
||||
qca808x_phy_ms_seed_enable(phydev, false);
|
||||
} else {
|
||||
qca808x_phy_ms_seed_enable(phydev, true);
|
||||
@@ -2070,18 +2072,22 @@ static int qca808x_cable_test_get_status
|
||||
ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D,
|
||||
qca808x_cable_test_result_trans(pair_d));
|
||||
|
||||
- if (qca808x_cdt_fault_length_valid(pair_a))
|
||||
- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A,
|
||||
- qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A));
|
||||
- if (qca808x_cdt_fault_length_valid(pair_b))
|
||||
- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B,
|
||||
- qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B));
|
||||
- if (qca808x_cdt_fault_length_valid(pair_c))
|
||||
- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C,
|
||||
- qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C));
|
||||
- if (qca808x_cdt_fault_length_valid(pair_d))
|
||||
- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D,
|
||||
- qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D));
|
||||
+ if (qca808x_cdt_fault_length_valid(pair_a)) {
|
||||
+ val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A);
|
||||
+ ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
|
||||
+ }
|
||||
+ if (qca808x_cdt_fault_length_valid(pair_b)) {
|
||||
+ val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B);
|
||||
+ ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
|
||||
+ }
|
||||
+ if (qca808x_cdt_fault_length_valid(pair_c)) {
|
||||
+ val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C);
|
||||
+ ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
|
||||
+ }
|
||||
+ if (qca808x_cdt_fault_length_valid(pair_d)) {
|
||||
+ val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D);
|
||||
+ ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
|
||||
+ }
|
||||
|
||||
*finished = true;
|
||||
|
||||
@@ -2148,8 +2154,9 @@ static void qca808x_link_change_notify(s
|
||||
* the interface device address is always phy address added by 1.
|
||||
*/
|
||||
mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
|
||||
- MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
|
||||
- QCA8081_PHY_FIFO_RSTN, phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
|
||||
+ MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
|
||||
+ QCA8081_PHY_FIFO_RSTN,
|
||||
+ phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
|
||||
}
|
||||
|
||||
static struct phy_driver at803x_driver[] = {
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user