Compare commits

...

7 Commits

Author SHA1 Message Date
hzy
6faaa1504f Add Readme 2024-07-24 23:31:43 +08:00
hzy
0625e8ac88 Use GHA to build 2024-07-24 23:31:43 +08:00
hzy
5c222bf0b3 Drop origin CI and README 2024-07-24 23:31:43 +08:00
hzy
d8011a7e99 ipq50xx: Add CMCC RAX3000Q support 2024-07-24 23:31:43 +08:00
hzy
a07ca07fa8 ipq50xx: Add Xiaomi CR881x support 2024-07-20 00:04:10 +08:00
hzy
f446dc1366 generic: Add motorcomm yt9215 support 2024-07-20 00:04:10 +08:00
hzy
c8cc4b1fc3 ipq50xx: Add Redmi AX3000 2024-07-20 00:04:10 +08:00
43 changed files with 3167 additions and 709 deletions

1
.github/FUNDING.yml vendored
View File

@ -1 +0,0 @@
custom: [ 'https://openwrt.org/donate' ]

View File

@ -1,84 +0,0 @@
name: Bug report
description: Create a bug report to help us improve
labels:
- bug
body:
- type: textarea
id: description
attributes:
label: Describe the bug
description: A clear and concise description of the bug.
validations:
required: true
- type: input
id: version
attributes:
label: OpenWrt version
description: |
The OpenWrt release or commit hash where this bug occurs (use command below).
```. /etc/openwrt_release && echo $DISTRIB_REVISION```
validations:
required: true
- type: input
id: target
attributes:
label: OpenWrt target/subtarget
description: |
The OpenWrt target and subtarget where this bug is observed (use command below).
```. /etc/openwrt_release && echo $DISTRIB_TARGET```
validations:
required: true
- type: input
id: device
attributes:
label: Device
description: |
The device exhibiting this bug (if unsure, use command below).
```cat /tmp/sysinfo/model```
validations:
required: true
- type: dropdown
id: image_kind
attributes:
label: Image kind
options:
- Official downloaded image
- Self-built image
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: Steps to reproduce
description: Steps to reproduce the reported behaviour.
- type: textarea
id: behaviour
attributes:
label: Actual behaviour
description: A clear and concise description of what actually happens.
- type: textarea
id: expected
attributes:
label: Expected behaviour
description: A clear and concise description of what you expected to happen.
- type: textarea
id: additional
attributes:
label: Additional info
description: Add any additional info you think might be helfpul.
- type: textarea
id: diffconfig
attributes:
label: Diffconfig
description: |
In case of a self-built image, please attach diffconfig.
```./scripts/diffconfig.sh```
render: text
- type: checkboxes
id: terms
attributes:
label: Terms
description: By submitting this issue, you agree to the terms below.
options:
- label: I am reporting an issue for OpenWrt, not an unsupported fork.
required: true

View File

@ -1,12 +0,0 @@
---
blank_issues_enabled: false
contact_links:
- name: Feature request
url: https://forum.openwrt.org/c/feature-requests
about: The OpenWrt project relies on volunteers. While we appreciate feature requests, we might lack the manpower to handle them. Ideally, you get familiar with the codebase and attempt to contribute the feature yourself. We recommend to post in the forum, as this is the most likely place to receive feedback on feature requests.
- name: OpenWrt community
url: https://openwrt.org/contact
about: Consider reaching out to our community to get help. OpenWrt is a complex software project with many pitfalls; there is a good chance someone can help you solve your issue in no time.
- name: OpenWrt documentation
url: https://openwrt.org/docs/start
about: The OpenWrt documentation contains a lot of valuable information.

138
.github/labeler.yml vendored
View File

@ -1,138 +0,0 @@
# target/*
"target/airoha":
- "target/linux/airoha/**"
"target/apm821xx":
- "target/linux/apm821xx/**"
"target/archs38":
- "target/linux/archs38/**"
"target/armsr":
- "target/linux/armsr/**"
"target/at91":
- "target/linux/at91/**"
- "package/boot/at91bootstrap/**"
- "package/boot/uboot-at91/**"
"target/ath25":
- "target/linux/ath25/**"
"target/ath79":
- "target/linux/ath79/**"
"target/bcm27xx":
- "target/linux/bcm27xx/**"
- "package/kernel/bcm27xx-gpu-fw/**"
"target/bcm47xx":
- "target/linux/bcm47xx/**"
"target/bcm4908":
- "target/linux/bcm4908/**"
- "package/boot/uboot-bcm4908/**"
"target/bcm53xx":
- "target/linux/bcm53xx/**"
"target/bcm63xx":
- "target/linux/bcm63xx/**"
- "package/kernel/bcm63xx-cfe/**"
- "package/boot/arm-trusted-firmware-bcm63xx/**"
"target/bmips":
- "target/linux/bmips/**"
"target/gemini":
- "target/linux/gemini/**"
"target/imx":
- "target/linux/imx/**"
- "package/boot/imx-bootlets/**"
- "package/boot/uboot-imx/**"
"target/ipq40xx":
- "target/linux/ipq40xx/**"
"target/ipq806x":
- "target/linux/ipq806x/**"
"target/ipq807x":
- "target/linux/ipq807x/**"
"target/kirkwood":
- "target/linux/kirkwood/**"
- "package/boot/uboot-kirkwood/**"
"target/lantiq":
- "target/linux/lantiq/**"
- "package/kernel/lantiq/**"
- "package/firmware/lantiq/**"
- "package/boot/uboot-lantiq/**"
"target/layerscape":
- "target/linux/layerscape/**"
- "package/firmware/layerscape/**"
- "package/boot/tfa-layerscape/**"
- "package/boot/uboot-layerscape/**"
- "package/network/utils/layerscape/**"
"target/malta":
- "target/linux/malta/**"
"target/mediatek":
- "target/linux/mediatek/**"
- "package/boot/arm-trusted-firmware-mediatek/**"
- "package/boot/uboot-mediatek/**"
"target/mpc85xx":
- "target/linux/mpc85xx/**"
"target/mvebu":
- "target/linux/mvebu/**"
- "package/boot/arm-trusted-firmware-mvebu/**"
- "package/boot/uboot-mvebu/**"
"target/mxs":
- "target/linux/mxs/**"
- "package/boot/uboot-mxs/**"
"target/octeon":
- "target/linux/octeon/**"
"target/octeontx":
- "target/linux/octeontx/**"
"target/omap":
- "target/linux/omap/**"
- "package/boot/uboot-omap/**"
"target/oxnas":
- "target/linux/oxnas/**"
- "package/boot/uboot-oxnas/**"
"target/pistachio":
- "target/linux/pistachio/**"
"target/qoriq":
- "target/linux/qoriq/**"
"target/ramips":
- "target/linux/ramips/**"
"target/realtek":
- "target/linux/realtek/**"
"target/rockchip":
- "target/linux/rockchip/**"
- "package/boot/arm-trusted-firmware-rockchip/**"
- "package/boot/uboot-rockchip/**"
"target/sifiveu":
- "target/linux/sifiveu/**"
- "package/boot/uboot-sifiveu/**"
- "package/boot/opensbi/**"
"target/sunxi":
- "target/linux/sunxi/**"
- "package/boot/arm-trusted-firmware-sunxi/**"
- "package/boot/uboot-sunxi/**"
"target/tegra":
- "target/linux/tegra/**"
- "package/boot/uboot-tegra/**"
"target/uml":
- "target/linux/uml/**"
"target/x86":
- "target/linux/x86/**"
"target/zynq":
- "target/linux/zynq/**"
- "package/boot/uboot-zynq/**"
# target/imagebuilder
"target/imagebuilder":
- "target/imagebuilder/**"
# kernel
"kernel":
- "target/linux/generic/**"
- "target/linux/**/config-*"
- "target/linux/**/patches-*"
- "target/linux/**/files/**"
- "package/kernel/linux/**"
# core packages
"core packages":
- "package/**"
# build/scripts/tools
"build/scripts/tools":
- "include/**"
- "scripts/**"
- "tools/**"
# toolchain
"toolchain":
- "toolchain/**"
# GitHub/CI
"GitHub/CI":
- ".github/**"

View File

@ -1,8 +0,0 @@
Thanks for your contribution to OpenWrt!
To help keep the codebase consistent and readable,
and to help people review your contribution,
we ask you to follow the rules you find in the wiki at this link
https://openwrt.org/submitting-patches
Please remove this message before posting the pull request.

200
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,200 @@
name: CI
on:
workflow_dispatch:
push:
jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Free disk space
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android
- name: Install dependencies
run: |
sudo apt update
sudo apt install build-essential clang flex g++ gawk gcc-multilib gettext \
git libncurses5-dev libssl-dev python3-distutils rsync unzip zlib1g-dev
- name: Checkout
uses: actions/checkout@v3
- name: Hook the openwrt_core URL for opkg
run: |
OWNER="${GITHUB_REPOSITORY%%/*}"
REPO="${GITHUB_REPOSITORY#*/}"
TIME="$(curl "https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" | jq -r .created_at)"
echo "ci-$(date -d "${TIME}" -u +'%Y%m%d-%H%M%S')-${GITHUB_SHA:0:8}" >version
sed -i "s|%U/targets/%S/packages|https://${OWNER}.github.io/${REPO}/${GITHUB_REF_NAME}/%R|" include/feeds.mk
- name: Update and install feeds
run: |
./scripts/feeds update -a
./scripts/feeds install -a
- name: Configure
run: |
cat <<EOF | sed -E 's/^ //' >.config
CONFIG_TARGET_ipq50xx=y
CONFIG_TARGET_ipq50xx_arm=y
CONFIG_TARGET_MULTI_PROFILE=y
CONFIG_TARGET_ALL_PROFILES=y
CONFIG_TARGET_PER_DEVICE_ROOTFS=y
CONFIG_IB=y
# CONFIG_IB_STANDALONE is not set
CONFIG_SDK=y
CONFIG_MAKE_TOOLCHAIN=y
CONFIG_ALL_NONSHARED=y
CONFIG_REPRODUCIBLE_DEBUG_INFO=y
CONFIG_PACKAGE_luci=y
EOF
make defconfig
- name: Download
run: |
make -j16 download
- name: Build tools
run: |
make -j$(nproc) tools/install
- name: Build toolchain
run: |
make -j$(nproc) toolchain/install
- name: Build all
run: |
make -j$(nproc) IGNORE_ERRORS=1
- name: Upload bin to artifacts
uses: actions/upload-artifact@v3
with:
name: bin-ipq50xx-arm
path: bin/targets/ipq50xx/arm/*
- name: Upload dl to artifacts
uses: actions/upload-artifact@v3
with:
name: dl
path: dl/*
gh-pages:
needs: [ build ]
runs-on: ubuntu-20.04
permissions:
contents: write
steps:
- name: Checkout gh-pages
uses: actions/checkout@v3
with:
path: 'gh-pages'
ref: 'gh-pages'
fetch-depth: 0
- name: Configure the git user
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
- name: Drop old versions
run: |
cd gh-pages
readarray -t old_version < <(git log --format='%h' -- "${GITHUB_REF_NAME}" | tail -n +10)
GIT_SEQUENCE_EDITOR="sed -i '1 i break'" git rebase --interactive --committer-date-is-author-date --root
for commit in "${old_version[@]}"; do
sed -i "/${commit}/d" .git/rebase-merge/git-rebase-todo
done
git rebase --continue
- name: Download bin from artifacts
uses: actions/download-artifact@v3
with:
name: bin-ipq50xx-arm
path: bin/
- name: Copy contents
run: |
version="$(cat "bin/version.buildinfo")"
mkdir -p "gh-pages/${GITHUB_REF_NAME}/${version}/"
cp -avr bin/packages/* "gh-pages/${GITHUB_REF_NAME}/${version}/"
- name: Commit
run: |
cd gh-pages
git add .
git commit -m "Add: ${GITHUB_REF_NAME}: $(cat ../bin/version.buildinfo)"
- name: Publish
run: |
cd gh-pages
git push -f origin gh-pages
release:
needs: [ build ]
runs-on: ubuntu-20.04
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Download dl from artifacts
uses: actions/download-artifact@v3
with:
name: dl
path: dl/
- name: Download bin from artifacts
uses: actions/download-artifact@v3
with:
name: bin-ipq50xx-arm
path: bin/targets/ipq50xx/arm/
- name: Tar
run: |
tar cvf dl.tar -C dl/ .
tar cvf bin-ipq50xx.tar -C bin/targets/ipq50xx/arm/ .
- name: Generate release informations
run: |
TIME="$(curl "https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" | jq -r .created_at)"
TAG="ci-${GITHUB_REF_NAME}-$(date -d "${TIME}" -u +'%Y%m%d-%H%M%S-%Z')"
echo "TAG=$TAG" >>$GITHUB_ENV
cat <<EOF | sed -E 's/^ //' >Release.md
CI ${GITHUB_REF_NAME} $(date -d "${TIME}" -u +'%Y-%m-%d %H:%M:%S %Z(%:z)')
# ${GITHUB_REF_NAME}
Build time: \`$(date -d "${TIME}" -u +'%Y-%m-%d %H:%M:%S %Z(%:z)')\`
Release version: ${TAG}
## Sources
$(cat bin/targets/ipq50xx/arm/feeds.buildinfo | awk -F'[ ^]' '{printf "%s: `%s`\n", $2, $4}')
## SHA256
$(cat bin/targets/ipq50xx/arm/sha256sums | awk '{printf "%s: `%s`\n", $2, $1}' | sed -E 's/^\*//')
EOF
echo "NAME=$(head --line=1 Release.md)" >>$GITHUB_ENV
tail --line=+2 Release.md >Body.md
- name: Release
uses: softprops/action-gh-release@v1
with:
prerelease: true
tag_name: ${{ env.TAG }}
target_commitish: ${{ github.sha }}
name: ${{ env.NAME }}
body_path: Body.md
files: |
bin/targets/ipq50xx/arm/sha256sums
bin/targets/ipq50xx/arm/*.*
*.tar

View File

@ -1,19 +0,0 @@
name: Coverity scan build
on:
schedule:
- cron: '30 2 * * 6'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
jobs:
coverity_build:
name: Coverity x86/64 build
secrets:
coverity_api_token: ${{ secrets.COVERITY_API_TOKEN }}
permissions:
contents: read
packages: read
actions: write
uses: openwrt/actions-shared-workflows/.github/workflows/coverity.yml@main

View File

@ -1,73 +0,0 @@
name: Test Formalities
on:
pull_request:
permissions:
contents: read
jobs:
build:
name: Test Formalities
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Determine branch name
run: |
BRANCH="${GITHUB_BASE_REF#refs/heads/}"
echo "Building for $BRANCH"
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
- name: Test formalities
run: |
source .github/workflows/scripts/ci_helpers.sh
RET=0
for commit in $(git rev-list HEAD ^origin/$BRANCH); do
info "=== Checking commit '$commit'"
if git show --format='%P' -s $commit | grep -qF ' '; then
err "Pull request should not include merge commits"
RET=1
fi
author="$(git show -s --format=%aN $commit)"
if echo $author | grep -q '\S\+\s\+\S\+'; then
success "Author name ($author) seems ok"
else
err "Author name ($author) need to be your real name 'firstname lastname'"
RET=1
fi
subject="$(git show -s --format=%s $commit)"
if echo "$subject" | grep -q -e '^[0-9A-Za-z,+/_\.-]\+: ' -e '^Revert '; then
success "Commit subject line seems ok ($subject)"
else
err "Commit subject line MUST start with '<area>: ' ($subject)"
RET=1
fi
body="$(git show -s --format=%b $commit)"
sob="$(git show -s --format='Signed-off-by: %aN <%aE>' $commit)"
if echo "$body" | grep -qF "$sob"; then
success "Signed-off-by match author"
else
err "Signed-off-by is missing or doesn't match author (should be '$sob')"
RET=1
fi
if echo "$body" | grep -v "Signed-off-by:"; then
success "A commit message exists"
else
err "Missing commit message. Please describe your changes"
RET=1
fi
done
exit $RET

View File

@ -1,24 +0,0 @@
name: Create GitHub release
permissions:
contents: write
on:
push:
tags:
- "v*"
workflow_dispatch:
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Release
uses: softprops/action-gh-release@v1
with:
draft: true
prerelease: true

View File

@ -1,42 +0,0 @@
name: Build Kernel
on:
pull_request:
paths:
- '.github/workflows/check-kernel-patches.yml'
- '.github/workflows/build.yml'
- '.github/workflows/kernel.yml'
- 'include/kernel*'
- 'package/kernel/**'
- 'target/linux/**'
push:
paths:
- '.github/workflows/check-kernel-patches.yml'
- '.github/workflows/build.yml'
- '.github/workflows/kernel.yml'
- 'include/kernel*'
- 'package/kernel/**'
- 'target/linux/**'
branches-ignore:
- master
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build-kernels:
name: Build all affected Kernels
permissions:
contents: read
packages: read
actions: write
secrets:
ccache_s3_endpoint: ${{ secrets.CCACHE_S3_ENDPOINT }}
ccache_s3_bucket: ${{ secrets.CCACHE_S3_BUCKET }}
ccache_s3_access_key: ${{ secrets.CCACHE_S3_ACCESS_KEY }}
ccache_s3_secret_key: ${{ secrets.CCACHE_S3_SECRET_KEY }}
uses: openwrt/actions-shared-workflows/.github/workflows/kernel.yml@main

View File

@ -1,16 +0,0 @@
# ci:kernel:x86:64 is going to trigger CI kernel check jobs for x86/64 target
name: Build kernel and check patches for target specified in labels
on:
pull_request:
types:
- labeled
jobs:
build-kernels-label:
name: Build all affected Kernels from defined label
permissions:
contents: read
packages: read
actions: write
uses: openwrt/actions-shared-workflows/.github/workflows/label-kernel.yml@main

View File

@ -1,16 +0,0 @@
# ci:target:x86:64 is going to trigger CI target check jobs for x86/64 target
name: Build check target specified in labels
on:
pull_request:
types:
- labeled
jobs:
build-target-label:
name: Build target from defined label
permissions:
contents: read
packages: read
actions: write
uses: openwrt/actions-shared-workflows/.github/workflows/label-target.yml@main

View File

@ -1,33 +0,0 @@
name: 'Pull Request Labeler'
on:
- pull_request_target
permissions:
contents: read
jobs:
labeler:
permissions:
contents: read # to determine modified files (actions/labeler)
pull-requests: write # to add labels to PRs (actions/labeler)
name: Pull Request Labeler
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v4
with:
repo-token: '${{ secrets.GITHUB_TOKEN }}'
- name: Check Branch
id: check-branch
run: |
if echo "${{ github.base_ref }}" | grep -q -E 'openwrt-[0-9][0-9]\.[0-9][0-9]'; then
echo "release-tag=$(echo ${{ github.base_ref }} | sed 's/openwrt-/release\//')" >> $GITHUB_OUTPUT
fi
- uses: buildsville/add-remove-label@v2.0.0
if: ${{ steps.check-branch.outputs.release-tag }}
with:
token: ${{secrets.GITHUB_TOKEN}}
labels: ${{ steps.check-branch.outputs.release-tag }}
type: add

View File

@ -1,42 +0,0 @@
name: Build all core packages
on:
pull_request:
paths:
- '.github/workflows/packages.yml'
- 'config/**'
- 'include/**'
- 'package/**'
- 'target/linux/generic/**'
- 'toolchain/**'
push:
paths:
- '.github/workflows/packages.yml'
- 'config/**'
- 'include/**'
- 'package/**'
- 'target/linux/generic/**'
- 'toolchain/**'
branches-ignore:
- master
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build-packages:
name: Build all core packages for selected target
permissions:
contents: read
packages: read
actions: write
secrets:
ccache_s3_endpoint: ${{ secrets.CCACHE_S3_ENDPOINT }}
ccache_s3_bucket: ${{ secrets.CCACHE_S3_BUCKET }}
ccache_s3_access_key: ${{ secrets.CCACHE_S3_ACCESS_KEY }}
ccache_s3_secret_key: ${{ secrets.CCACHE_S3_SECRET_KEY }}
uses: openwrt/actions-shared-workflows/.github/workflows/packages.yml@main

View File

@ -1,28 +0,0 @@
name: Build and Push prebuilt tools container
on:
push:
paths:
- 'include/version.mk'
- 'include/cmake.mk'
- 'tools/**'
- '.github/workflows/push-containers.yml'
- 'toolchain/**'
branches-ignore:
- master
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-push-containers:
name: Build and Push all prebuilt containers
permissions:
contents: read
packages: write
actions: write
uses: openwrt/actions-shared-workflows/.github/workflows/push-containers.yml@main

View File

@ -1,26 +0,0 @@
#!/bin/sh
color_out() {
printf "\e[0;$1m%s\e[0;0m\n" "$2"
}
success() {
color_out 32 "$1"
}
info() {
color_out 36 "$1"
}
err() {
color_out 31 "$1"
}
warn() {
color_out 33 "$1"
}
err_die() {
err "$1"
exit 1
}

View File

@ -1,15 +0,0 @@
#!/bin/bash
original_exit_code="${ret:-1}"
log_dir_path="${1:-logs}"
context="${2:-10}"
show_make_build_errors() {
grep -slr 'make\[[[:digit:]]\+\].*Error [[:digit:]]\+$' "$log_dir_path" | while IFS= read -r log_file; do
printf "====== Make errors from %s ======\n" "$log_file";
grep -r -C"$context" 'make\[[[:digit:]]\+\].*Error [[:digit:]]\+$' "$log_file" ;
done
}
show_make_build_errors
exit "$original_exit_code"

View File

@ -1,29 +0,0 @@
name: Build Toolchains
on:
pull_request:
paths:
- '.github/workflows/toolchain.yml'
- 'toolchain/**'
push:
paths:
- '.github/workflows/toolchain.yml'
- 'toolchain/**'
branches-ignore:
- master
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build-toolchains:
name: Build Toolchains for each target
permissions:
contents: read
packages: read
actions: write
uses: openwrt/actions-shared-workflows/.github/workflows/toolchain.yml@main

View File

@ -1,27 +0,0 @@
name: Build host tools
on:
pull_request:
paths:
- 'include/**'
- 'tools/**'
- '.github/workflows/tools.yml'
push:
paths:
- 'include/**'
- 'tools/**'
- '.github/workflows/tools.yml'
branches-ignore:
- master
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build-tools:
name: Build host tools for linux and macos based systems
uses: openwrt/actions-shared-workflows/.github/workflows/tools.yml@main

228
README.md
View File

@ -1,108 +1,188 @@
![OpenWrt logo](include/logo.png)
# openwrt-redmi-ax3000
OpenWrt Project is a Linux operating system targeting embedded devices. Instead
of trying to create a single, static firmware, OpenWrt provides a fully
writable filesystem with package management. This frees you from the
application selection and configuration provided by the vendor and allows you
to customize the device through the use of packages to suit any application.
For developers, OpenWrt is the framework to build an application without having
to build a complete firmware around it; for users this means the ability for
full customization, to use the device in ways never envisioned.
`Openwrt` for `Redmi AX3000` / `Xiaomi CR880x` / `Xiaomi CR881x`
Sunshine!
**!!! NOTE: This is the main development branch which using mainline `Linux LTS 5.15` !!!**
## Download
If you need more stable versions, please checkout the following branches which using QSDK kernel
- [`ipq50xx-qsdk-kernel-5.4-openwrt-21.02-qsdk-11.5.05.841.1029`](https://github.com/hzyitc/openwrt-redmi-ax3000/tree/ipq50xx-qsdk-kernel-5.4-openwrt-21.02-qsdk-11.5.05.841.1029)
- [`ipq50xx-qsdk-kernel-4.4-openwrt-21.02-qsdk-11.4.0.5.7418`](https://github.com/hzyitc/openwrt-redmi-ax3000/tree/ipq50xx-qsdk-kernel-4.4-openwrt-21.02-qsdk-11.4.0.5.7418)
Built firmware images are available for many architectures and come with a
package selection to be used as WiFi home router. To quickly find a factory
image usable to migrate from a vendor stock firmware to OpenWrt, try the
*Firmware Selector*.
| Device | Boot | Switch | CPU Ethernet | NSS NAT | 2.4G WiFi | 5G WiFi |
| :-: | :-: | :-: | :-: | :-: | :-: | :-: |
| Xiaomi CR880x <br /> (M79 version) | ✔️ | ✔️ | ✔️ | ❌ | ⚠️ Without `NSS Offload` | See Note¹ <br /> ⚠️ Without `NSS Offload` |
| Redmi AX3000 <br /> Xiaomi CR880x <br /> (M81 version) | ✔️ | ✔️ | ✔️ | ❌ | ⚠️ Without `NSS Offload` | See Note¹ <br /> ⚠️ Without `NSS Offload` |
| Xiaomi CR881x | ✔️ | ✔️ | ✔️ | ❌ | ⚠️ Without `NSS Offload` | See Note¹ <br /> ⚠️ Without `NSS Offload` |
| CMCC RAX3000Q | ⚠️ No test ⚠️ |
>
> NOTE¹: For 160MHz, `Country Code`, `Width` and `Channel` need to be set correctly. And wait 1 minute for radar detection, then the WiFi will be appeareed.
>
> ```
> uci -q batch <<-EOF
> wireless.radio1.country='CN'
> wireless.radio1.htmode='HE160'
> wireless.radio1.channel='64'
> EOF
> ```
* [OpenWrt Firmware Selector](https://firmware-selector.openwrt.org/)
## How to build
If your device is supported, please follow the **Info** link to see install
instructions or consult the support resources listed below.
OS: `Ubuntu 20.04 (focal)`
##
```bash
# Install dependencies
sudo apt update
sudo apt install build-essential clang flex g++ gawk gcc-multilib gettext \
git libncurses5-dev libssl-dev python3-distutils rsync unzip zlib1g-dev
An advanced user may require additional or specific package. (Toolchain, SDK, ...) For everything else than simple firmware download, try the wiki download page:
# Clone this repo
git clone https://github.com/hzyitc/openwrt-redmi-ax3000
cd openwrt-redmi-ax3000
* [OpenWrt Wiki Download](https://openwrt.org/downloads)
# Update and install feeds
./scripts/feeds update -a
./scripts/feeds install -a
## Development
# Configure
make menuconfig
To build your own firmware you need a GNU/Linux, BSD or MacOSX system (case
sensitive filesystem required). Cygwin is unsupported because of the lack of a
case sensitive file system.
# Download
make -j16 download
### Requirements
You need the following tools to compile OpenWrt, the package names vary between
distributions. A complete list with distribution specific packages is found in
the [Build System Setup](https://openwrt.org/docs/guide-developer/build-system/install-buildsystem)
documentation.
```
binutils bzip2 diff find flex gawk gcc-6+ getopt grep install libc-dev libz-dev
make4.1+ perl python3.6+ rsync subversion unzip which
# Build
make -j$(nproc)
```
### Quickstart
## How to install
1. Run `./scripts/feeds update -a` to obtain all the latest package definitions
defined in feeds.conf / feeds.conf.default
### Get `UART` access
2. Run `./scripts/feeds install -a` to install symlinks for all obtained
packages into package/feeds/
> Input from `UART` will be allowed after a successful `TFTP recovery`.
3. Run `make menuconfig` to select your preferred configuration for the
toolchain, target system & firmware packages.
1. Connect `UART` and `LAN`.
4. Run `make` to build your firmware. This will download all sources, build the
cross-compile toolchain and then cross-compile the GNU/Linux kernel & all chosen
applications for your target system.
2. Download the vendor firmware:
### Related Repositories
Offical website: https://www.miwifi.com/miwifi_download.html
The main repository uses multiple sub-repositories to manage packages of
different categories. All packages are installed via the OpenWrt package
manager called `opkg`. If you're looking to develop the web interface or port
packages to OpenWrt, please find the fitting repository below.
| Device | URL |
| :-: | :-: |
| Redmi AX3000 | https://cdn.cnbj1.fds.api.mi-img.com/xiaoqiang/rom/ra81/miwifi_ra81_firmware_1dd69c_1.0.33.bin |
| Xiaomi CR8806 | https://cdn.cnbj1.fds.api.mi-img.com/xiaoqiang/rom/cr8806/miwifi_cr8806_firmware_fe70b_6.2.14.bin |
| Xiaomi CR8808 | https://cdn.cnbj1.fds.api.mi-img.com/xiaoqiang/rom/cr8808/miwifi_cr8808_firmware_9d216_6.2.11.bin |
| Xiaomi CR8809 | https://cdn.cnbj1.fds.api.mi-img.com/xiaoqiang/rom/cr8809/miwifi_cr8809_firmware_b814a_6.2.102.bin |
* [LuCI Web Interface](https://github.com/openwrt/luci): Modern and modular
interface to control the device via a web browser.
3. Use [`MIWIFIRepairTool`](https://bigota.miwifi.com/xiaoqiang/tools/MIWIFIRepairTool.x86.zip) to recover the device's firmware.
* [OpenWrt Packages](https://github.com/openwrt/packages): Community repository
of ported packages.
Offical tutorial: https://www.xiaomi.cn/post/19134127
* [OpenWrt Routing](https://github.com/openwrt/routing): Packages specifically
focused on (mesh) routing.
> This tool simply does `TFTP recovery`. You can use other `DHCP` and `TFTP` server as well.
>
> Here are some useful links:
>
>> https://forum.openwrt.org/t/adding-openwrt-support-for-xiaomi-redmi-router-ax6s-xiaomi-router-ax3200/111085/513
>>
>> https://github.com/mikeeq/xiaomi_ax3200_openwrt#uart-flash
>>
>> https://openwrt.org/inbox/toh/xiaomi/xiaomi_ax3600#tftp_recovery
* [OpenWrt Video](https://github.com/openwrt/video): Packages specifically
focused on display servers and clients (Xorg and Wayland).
4. Hold the `reset` button and reboot the router until the `system` LED blink.
## Support Information
5. Wait until the firmware being flashed.
For a list of supported devices see the [OpenWrt Hardware Database](https://openwrt.org/supported_devices)
6. Unplug then plug back in the power.
### Documentation
7. Send any key stroke to `UART` to interrupt the `U-boot`.
* [Quick Start Guide](https://openwrt.org/docs/guide-quick-start/start)
* [User Guide](https://openwrt.org/docs/guide-user/start)
* [Developer Documentation](https://openwrt.org/docs/guide-developer/start)
* [Technical Reference](https://openwrt.org/docs/techref/start)
8. Run the following command inside `U-boot`:
### Support Community
```shell
setenv boot_wait on
setenv uart_en 1
saveenv
```
* [Forum](https://forum.openwrt.org): For usage, projects, discussions and hardware advise.
* [Support Chat](https://webchat.oftc.net/#openwrt): Channel `#openwrt` on **oftc.net**.
Now we have enabled `UART`.
### Developer Community
### Flash Openwrt
* [Bug Reports](https://bugs.openwrt.org): Report bugs in OpenWrt
* [Dev Mailing List](https://lists.openwrt.org/mailman/listinfo/openwrt-devel): Send patches
* [Dev Chat](https://webchat.oftc.net/#openwrt-devel): Channel `#openwrt-devel` on **oftc.net**.
#### a. Use `U-boot` to flash
## License
Download [`openwrt-ipq50xx-arm-redmi_ax3000-squashfs-nand-factory.ubi`](https://github.com/hzyitc/openwrt-redmi-ax3000/releases/latest/download/openwrt-ipq50xx-arm-redmi_ax3000-squashfs-nand-factory.ubi) and put it into TFTP root.
OpenWrt is licensed under GPL-2.0
Then run the following command inside `U-boot`:
```shell
# This router ip
setenv ipaddr 192.168.1.2
# TFTP server ip
setenv serverip 192.168.1.1
# Download the firmware to the RAM
tftpboot openwrt-ipq50xx-arm-redmi_ax3000-squashfs-nand-factory.ubi
# Flash it as system 2
flash rootfs_1
setenv flag_try_sys2_failed 0
setenv flag_boot_rootfs 1
setenv flag_last_success 1
saveenv
# Flash it as system 1
# flash rootfs
# setenv flag_try_sys1_failed 0
# setenv flag_boot_rootfs 0
# setenv flag_last_success 0
# saveenv
# Reboot
reset
```
#### b. Use `miwifi` (the vendor firmware) to flash
```bash
cd /tmp
wget https://github.com/hzyitc/openwrt-redmi-ax3000/releases/latest/download/openwrt-ipq50xx-arm-redmi_ax3000-squashfs-nand-factory.ubi
# Check your partition table
# cat /proc/mtd
[[ "$(grep '"rootfs"' /proc/mtd | cut -d':' -f1)" == "mtd18" ]] || exit
[[ "$(grep '"rootfs_1"' /proc/mtd | cut -d':' -f1)" == "mtd19" ]] || exit
# Detect the current system slot and flash into the other one
# cat /proc/cmdline
mtd="$(grep -oE 'ubi.mtd=[a-zA-Z0-9\-\_]*' /proc/cmdline | cut -d'=' -f2)"
if [[ "$mtd" == "rootfs" ]]; then
# Flash it as system 2
ubiformat /dev/mtd19 -f openwrt-ipq50xx-arm-redmi_ax3000-squashfs-nand-factory.ubi
nvram set flag_try_sys2_failed=0
nvram set flag_boot_rootfs=1
nvram set flag_last_success=1
nvram commit
elif [[ "$mtd" == "rootfs_1" ]]; then
# Flash it as system 1
ubiformat /dev/mtd18 -f openwrt-ipq50xx-arm-redmi_ax3000-squashfs-nand-factory.ubi
nvram set flag_try_sys1_failed=0
nvram set flag_boot_rootfs=0
nvram set flag_last_success=0
nvram commit
fi
# Reboot
reboot
```
## Related links
[`openwrt/openwrt`](https://github.com/openwrt/openwrt) - Openwrt official repository
[`qsdk`](https://git.codelinaro.org/clo/qsdk) - QSDK official repository
[`quic/qca-sdk-nss-fw`](https://github.com/quic/qca-sdk-nss-fw) - NSS firmware
[`quic/upstream-wifi-fw`](https://github.com/quic/upstream-wifi-fw) - WiFi firmware
[`qca/qca-swiss-army-knife`](https://github.com/qca/qca-swiss-army-knife) - BDF tools
[`Telecominfraproject/wlan-ap`](https://github.com/Telecominfraproject/wlan-ap) - another Openwrt which support `ipq50xx`

View File

@ -0,0 +1,22 @@
#!/bin/sh
[ -e /etc/config/ubootenv ] && exit 0
touch /etc/config/ubootenv
. /lib/uboot-envtools.sh
. /lib/functions.sh
board=$(board_name)
case "$board" in
cmcc,rax3000q|\
redmi,ax3000|\
xiaomi,cr881x)
ubootenv_add_uci_config "/dev/mtd10" "0x0" "0x10000" "0x20000"
;;
esac
config_load ubootenv
config_foreach ubootenv_add_app_config ubootenv
exit 0

View File

@ -29,6 +29,7 @@ endef
ALLWIFIBOARDS:= \
buffalo_wxr-5950ax12 \
cmcc_rax3000q \
compex_wpq873 \
dynalink_dl-wrx36 \
edgecore_eap102 \
@ -36,10 +37,12 @@ ALLWIFIBOARDS:= \
netgear_wax218 \
prpl_haze \
qnap_301w \
redmi_ax3000 \
redmi_ax6 \
wallys_dr40x9 \
xiaomi_ax3600 \
xiaomi_ax9000 \
xiaomi_cr881x \
zte_mf289f \
zte_mf287 \
zte_mf287plus \
@ -122,6 +125,7 @@ endef
# Add $(eval $(call generate-ipq-wifi-package,<devicename>,<display name>))
$(eval $(call generate-ipq-wifi-package,buffalo_wxr-5950ax12,Buffalo WXR-5950AX12))
$(eval $(call generate-ipq-wifi-package,cmcc_rax3000q,CMCC RAX3000Q))
$(eval $(call generate-ipq-wifi-package,compex_wpq873,Compex WPQ-873))
$(eval $(call generate-ipq-wifi-package,dynalink_dl-wrx36,Dynalink DL-WRX36))
$(eval $(call generate-ipq-wifi-package,edgecore_eap102,Edgecore EAP102))
@ -129,10 +133,12 @@ $(eval $(call generate-ipq-wifi-package,edimax_cax1800,Edimax CAX1800))
$(eval $(call generate-ipq-wifi-package,netgear_wax218,Netgear WAX218))
$(eval $(call generate-ipq-wifi-package,qnap_301w,QNAP 301w))
$(eval $(call generate-ipq-wifi-package,prpl_haze,prpl Haze))
$(eval $(call generate-ipq-wifi-package,redmi_ax3000,Redmi AX3000))
$(eval $(call generate-ipq-wifi-package,redmi_ax6,Redmi AX6))
$(eval $(call generate-ipq-wifi-package,wallys_dr40x9,Wallys DR40X9))
$(eval $(call generate-ipq-wifi-package,xiaomi_ax3600,Xiaomi AX3600))
$(eval $(call generate-ipq-wifi-package,xiaomi_ax9000,Xiaomi AX9000))
$(eval $(call generate-ipq-wifi-package,xiaomi_cr881x,Xiaomi CR881x))
$(eval $(call generate-ipq-wifi-package,zte_mf289f,ZTE MF289F))
$(eval $(call generate-ipq-wifi-package,zte_mf287,ZTE MF287))
$(eval $(call generate-ipq-wifi-package,zte_mf287plus,ZTE MF287Plus))

View File

@ -0,0 +1,834 @@
#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/phy.h>
#include <linux/switch.h>
#define RESET_TIMEOUT_US 100000
#define INTIF_MDIO_TIMEOUT_US 100000
#define YT9215_FAKE_PHY_ID 0xdeaddead
#define YT9215_FAKE_PHY_ID_MASK 0xffffffff
#define YT9215_CHIP_ID 0x90020000
#define YT9215_CHIP_ID_MASK 0xffff0000
#define MDIO_ADDR_SWITCHID_MASK GENMASK(3, 2)
#define MDIO_ADDR_SWITCHID(x) FIELD_PREP(MDIO_ADDR_SWITCHID_MASK, (x))
#define MDIO_ADDR_AD_MASK GENMASK(1, 1)
#define MDIO_ADDR_AD(x) FIELD_PREP(MDIO_ADDR_AD_MASK, (x))
#define MDIO_ADDR_AD_ADDR MDIO_ADDR_AD(0)
#define MDIO_ADDR_AD_DATA MDIO_ADDR_AD(1)
#define MDIO_ADDR_RW_MASK GENMASK(0, 0)
#define MDIO_ADDR_RW(x) FIELD_PREP(MDIO_ADDR_RW_MASK, (x))
#define MDIO_ADDR_RW_WRITE MDIO_ADDR_RW(0)
#define MDIO_ADDR_RW_READ MDIO_ADDR_RW(1)
#define RESET_CTRL 0x80000
#define RESET_CTRL_HW BIT(31)
#define RESET_CTRL_SW BIT(1)
#define FUNC_CTRL 0x80004
#define FUNC_CTRL_MIB BIT(1)
#define CHIP_ID 0x80008
#define PORT_IGR_LOOKUP_SVLAN 0x80014
#define EXTIF_CTRL 0x80028
#define EXTIF_CTRL_EXTIF1_ENABLE BIT(1)
#define EXTIF_CTRL_EXTIF0_ENABLE BIT(0)
#define SGMII_CTRL(port) (0x8008c + 4 * (port))
#define SGMII_CTRL_MODE_MASK GENMASK(9, 7)
#define SGMII_CTRL_MODE(x) FIELD_PREP(SGMII_CTRL_MODE_MASK, (x))
#define SGMII_CTRL_MODE_SGMII_MAC SGMII_CTRL_MODE(0)
#define SGMII_CTRL_MODE_SGMII_PHY SGMII_CTRL_MODE(1)
#define SGMII_CTRL_MODE_1000BASEX SGMII_CTRL_MODE(2)
#define SGMII_CTRL_MODE_100BASEX SGMII_CTRL_MODE(3)
#define SGMII_CTRL_MODE_2500BASEX SGMII_CTRL_MODE(4)
#define SGMII_CTRL_MODE_BASEX SGMII_CTRL_MODE(5)
#define SGMII_CTRL_MODE_DISABLE SGMII_CTRL_MODE(6)
#define SGMII_CTRL_LINK BIT(4)
#define SGMII_CTRL_DUPLEX_MASK GENMASK(3, 3)
#define SGMII_CTRL_DUPLEX(x) FIELD_PREP(SGMII_CTRL_DUPLEX_MASK, (x))
#define SGMII_CTRL_DUPLEX_HALF SGMII_CTRL_DUPLEX(0)
#define SGMII_CTRL_DUPLEX_FULL SGMII_CTRL_DUPLEX(1)
#define SGMII_CTRL_SPEED_MASK GENMASK(2, 0)
#define SGMII_CTRL_SPEED(x) FIELD_PREP(SGMII_CTRL_SPEED_MASK, (x))
#define SGMII_CTRL_SPEED_10 SGMII_CTRL_SPEED(0)
#define SGMII_CTRL_SPEED_100 SGMII_CTRL_SPEED(1)
#define SGMII_CTRL_SPEED_1000 SGMII_CTRL_SPEED(2)
#define SGMII_CTRL_SPEED_2500 SGMII_CTRL_SPEED(4)
#define PORT_CTRL(port) (0x80100 + 4 * (port))
#define PORT_CTRL_FLOWCONTROL_AN BIT(10)
#define PORT_CTRL_LINK_AN BIT(9)
#define PORT_CTRL_DUPLEX_MASK GENMASK(7, 7)
#define PORT_CTRL_DUPLEX(x) FIELD_PREP(PORT_CTRL_DUPLEX_MASK, (x))
#define PORT_CTRL_DUPLEX_HALF PORT_CTRL_DUPLEX(0)
#define PORT_CTRL_DUPLEX_FULL PORT_CTRL_DUPLEX(1)
#define PORT_CTRL_RX_FLOWCONTROL BIT(6)
#define PORT_CTRL_TX_FLOWCONTROL BIT(5)
#define PORT_CTRL_RX_MAC_EN BIT(4)
#define PORT_CTRL_TX_MAC_EN BIT(3)
#define PORT_CTRL_SPEED_MASK GENMASK(2, 0)
#define PORT_CTRL_SPEED(x) FIELD_PREP(PORT_CTRL_SPEED_MASK, (x))
#define PORT_CTRL_SPEED_10 PORT_CTRL_SPEED(0)
#define PORT_CTRL_SPEED_100 PORT_CTRL_SPEED(1)
#define PORT_CTRL_SPEED_1000 PORT_CTRL_SPEED(2)
#define PORT_CTRL_SPEED_2500 PORT_CTRL_SPEED(4)
#define PORT_STATUS(port) (0x80200 + 4 * (port))
#define PORT_STATUS_LINK BIT(8)
#define PORT_STATUS_DUPLEX_MASK GENMASK(7, 7)
#define PORT_STATUS_DUPLEX(x) FIELD_PREP(PORT_STATUS_DUPLEX_MASK, (x))
#define PORT_STATUS_DUPLEX_HALF PORT_STATUS_DUPLEX(0)
#define PORT_STATUS_DUPLEX_FULL PORT_STATUS_DUPLEX(1)
#define PORT_STATUS_RX_FLOWCONTROL BIT(6)
#define PORT_STATUS_TX_FLOWCONTROL BIT(5)
#define PORT_STATUS_RX_MAC_EN BIT(4)
#define PORT_STATUS_TX_MAC_EN BIT(3)
#define PORT_STATUS_SPEED_MASK GENMASK(2, 0)
#define PORT_STATUS_SPEED(x) FIELD_PREP(PORT_STATUS_SPEED_MASK, (x))
#define PORT_STATUS_SPEED_10 PORT_STATUS_SPEED(0)
#define PORT_STATUS_SPEED_100 PORT_STATUS_SPEED(1)
#define PORT_STATUS_SPEED_1000 PORT_STATUS_SPEED(2)
#define PORT_STATUS_SPEED_2500 PORT_STATUS_SPEED(4)
#define EXTIF_SEL 0x80394
#define EXTIF_SEL_EXTIF0_MASK GENMASK(1, 1)
#define EXTIF_SEL_EXTIF0(x) FIELD_PREP(EXTIF_SEL_EXTIF0_MASK, (x))
#define EXTIF_SEL_EXTIF0_SERDES EXTIF_SEL_EXTIF0(0)
#define EXTIF_SEL_EXTIF0_XMII EXTIF_SEL_EXTIF0(1)
#define EXTIF_SEL_EXTIF1_MASK GENMASK(0, 0)
#define EXTIF_SEL_EXTIF1(x) FIELD_PREP(EXTIF_SEL_EXTIF1_MASK, (x))
#define EXTIF_SEL_EXTIF1_SERDES EXTIF_SEL_EXTIF1(0)
#define EXTIF_SEL_EXTIF1_XMII EXTIF_SEL_EXTIF1(1)
#define MIB_CTRL 0xc0004
#define MIB_CTRL_OP_CLEAN BIT(30)
#define MIB_CTRL_PORT_MASK GENMASK(6, 3)
#define MIB_CTRL_PORT(port) FIELD_PREP(MIB_CTRL_PORT_MASK, (port))
#define MIB_CTRL_PORT_SEL_MASK GENMASK(1, 0)
#define MIB_CTRL_PORT_SEL(x) FIELD_PREP(MIB_CTRL_PORT_SEL_MASK, (x))
#define MIB_CTRL_PORT_SEL_ALL MIB_CTRL_PORT_SEL(0)
#define MIB_CTRL_PORT_SEL_SINGLE MIB_CTRL_PORT_SEL(2)
#define MIB_DATA(port, offset) (0xc0100 + (0x100 * (port)) + (4 * (offset)))
#define INTIF_MDIO_OP 0xf0000
#define INTIF_MDIO_OP_IDLE 0
#define INTIF_MDIO_OP_DO 1
#define INTIF_MDIO_CTRL 0xf0004
#define INTIF_MDIO_CTRL_ADDR_MASK GENMASK(25, 21)
#define INTIF_MDIO_CTRL_ADDR(x) FIELD_PREP(INTIF_MDIO_CTRL_ADDR_MASK, (x))
#define INTIF_MDIO_CTRL_REG_MASK GENMASK(20, 16)
#define INTIF_MDIO_CTRL_REG(x) FIELD_PREP(INTIF_MDIO_CTRL_REG_MASK, (x))
#define INTIF_MDIO_CTRL_OP_MASK GENMASK(3, 2)
#define INTIF_MDIO_CTRL_OP(x) FIELD_PREP(INTIF_MDIO_CTRL_OP_MASK, (x))
#define INTIF_MDIO_CTRL_OP_WRITE INTIF_MDIO_CTRL_OP(1)
#define INTIF_MDIO_CTRL_OP_READ INTIF_MDIO_CTRL_OP(2)
#define INTIF_MDIO_WRITE_DATA 0xf0008
#define INTIF_MDIO_READ_DATA 0xf000c
#define PORT_EGR_CTRL(port) (0x100000 + 4 * (port))
#define PORT_EGR_CTRL_CTAG_TPID_SEL_MASK GENMASK(5, 4)
#define PORT_EGR_CTRL_CTAG_TPID_SEL(x) FIELD_PREP(PORT_EGR_CTRL_CTAG_TPID_SEL_MASK, (x))
#define PORT_EGR_CTRL_STAG_TPID_SEL_MASK GENMASK(3, 2)
#define PORT_EGR_CTRL_STAG_TPID_SEL(x) FIELD_PREP(PORT_EGR_CTRL_STAG_TPID_SEL_MASK, (x))
#define PORT_EGR_VLAN(port) (0x100080 + 4 * (port))
#define PORT_EGR_VLAN_STAG_KEEP_MASK GENMASK(31, 31)
#define PORT_EGR_VLAN_STAG_KEEP(x) FIELD_PREP(PORT_EGR_VLAN_STAG_KEEP_MASK, (x))
#define PORT_EGR_VLAN_STAG_KEEP_ALL PORT_EGR_VLAN_STAG_KEEP(0)
#define PORT_EGR_VLAN_STAG_KEEP_TAG_MODE PORT_EGR_VLAN_STAG_KEEP(1)
#define PORT_EGR_VLAN_CTAG_KEEP_MASK GENMASK(30, 30)
#define PORT_EGR_VLAN_CTAG_KEEPK(x) FIELD_PREP(PORT_EGR_VLAN_CTAG_KEEP_MASK, (x))
#define PORT_EGR_VLAN_CTAG_KEEP_ALL PORT_EGR_VLAN_CTAG_KEEP(0)
#define PORT_EGR_VLAN_CTAG_KEEP_TAG_MODE PORT_EGR_VLAN_CTAG_KEEP(1)
#define PORT_EGR_VLAN_STAG_MODE_MASK GENMASK(29, 27)
#define PORT_EGR_VLAN_STAG_MODE(x) FIELD_PREP(PORT_EGR_VLAN_STAG_MODE_MASK, (x))
#define PORT_EGR_VLAN_STAG_MODE_UNTAG PORT_EGR_VLAN_STAG_MODE(0)
#define PORT_EGR_VLAN_STAG_MODE_TAG PORT_EGR_VLAN_STAG_MODE(1)
#define PORT_EGR_VLAN_STAG_MODE_TAG_EXCEPT_PVID PORT_EGR_VLAN_STAG_MODE(2)
#define PORT_EGR_VLAN_STAG_MODE_PRIO_TAG PORT_EGR_VLAN_STAG_MODE(3)
#define PORT_EGR_VLAN_STAG_MODE_KEEP PORT_EGR_VLAN_STAG_MODE(4)
#define PORT_EGR_VLAN_STAG_MODE_LOOKUP PORT_EGR_VLAN_STAG_MODE(5)
#define PORT_EGR_VLAN_PVID_SVID_MASK GENMASK(26, 15)
#define PORT_EGR_VLAN_PVID_SVID(x) FIELD_PREP(PORT_EGR_VLAN_PVID_SVID_MASK, (x))
#define PORT_EGR_VLAN_CTAG_MODE_MASK GENMASK(14, 12)
#define PORT_EGR_VLAN_CTAG_MODE(x) FIELD_PREP(PORT_EGR_VLAN_CTAG_MODE_MASK, (x))
#define PORT_EGR_VLAN_CTAG_MODE_UNTAG PORT_EGR_VLAN_CTAG_MODE(0)
#define PORT_EGR_VLAN_CTAG_MODE_TAG PORT_EGR_VLAN_CTAG_MODE(1)
#define PORT_EGR_VLAN_CTAG_MODE_TAG_EXCEPT_PVID PORT_EGR_VLAN_CTAG_MODE(2)
#define PORT_EGR_VLAN_CTAG_MODE_PRIO_TAG PORT_EGR_VLAN_CTAG_MODE(3)
#define PORT_EGR_VLAN_CTAG_MODE_KEEP PORT_EGR_VLAN_CTAG_MODE(4)
#define PORT_EGR_VLAN_CTAG_MODE_LOOKUP PORT_EGR_VLAN_CTAG_MODE(5)
#define PORT_EGR_VLAN_PVID_CVID_MASK GENMASK(11, 0)
#define PORT_EGR_VLAN_PVID_CVID(x) FIELD_PREP(PORT_EGR_VLAN_PVID_CVID_MASK, (x))
#define EGR_TPID(x) (0x100300 + 4 * (x))
#define PORT_IGR_VLAN_FILTER 0x180280
#define PORT_EGR_VLAN_FILTER 0x180598
#define VLAN_CTRL1(vlan) (0x188000 + 8 * (vlan))
#define VLAN_CTRL1_MEMBER_MASK GENMASK(17, 7)
#define VLAN_CTRL1_MEMBER(x) FIELD_PREP(VLAN_CTRL1_MEMBER_MASK, (x))
#define VLAN_CTRL2(vlan) (0x188004 + 8 * (vlan))
#define VLAN_CTRL2_UNTAG_MEMBER_MASK GENMASK(18, 8)
#define VLAN_CTRL2_UNTAG_MEMBER(x) FIELD_PREP(VLAN_CTRL2_UNTAG_MEMBER_MASK, (x))
#define IGR_TPID(x) (0x210000 + 4 * (x))
#define PORT_IGR_TPID(port) (0x210010 + 4 * (port))
#define PORT_IGR_TPID_STAG_BITMAP_MASK GENMASK(7, 4)
#define PORT_IGR_TPID_STAG_BITMAP(x) FIELD_PREP(PORT_IGR_TPID_STAG_BITMAP_MASK, (x))
#define PORT_IGR_TPID_CTAG_BITMAP_MASK GENMASK(3, 0)
#define PORT_IGR_TPID_CTAG_BITMAP(x) FIELD_PREP(PORT_IGR_TPID_CTAG_BITMAP_MASK, (x))
#define PORT_IGR_PVID(port) (0x230010 + 4 * (port))
#define PORT_IGR_PVID_SVID_MASK GENMASK(29, 18)
#define PORT_IGR_PVID_SVID(x) FIELD_PREP(PORT_IGR_PVID_SVID_MASK, (x))
#define PORT_IGR_PVID_CVID_MASK GENMASK(17, 6)
#define PORT_IGR_PVID_CVID(x) FIELD_PREP(PORT_IGR_PVID_CVID_MASK, (x))
struct yt9215_priv {
struct mdio_device *mdiodev;
int switchid;
struct mii_bus *int_mdio_bus;
struct switch_dev swdev;
};
static u32 yt9215_smi_read(struct yt9215_priv *priv, int reg)
{
struct mii_bus *bus = priv->mdiodev->bus;
int addr = priv->mdiodev->addr;
u32 val;
mutex_lock(&bus->mdio_lock);
bus->write(bus, addr, (MDIO_ADDR_SWITCHID(priv->switchid) | MDIO_ADDR_AD_ADDR | MDIO_ADDR_RW_READ), ((reg >> 16) & 0xffff));
bus->write(bus, addr, (MDIO_ADDR_SWITCHID(priv->switchid) | MDIO_ADDR_AD_ADDR | MDIO_ADDR_RW_READ), ((reg >> 0) & 0xffff));
val = (bus->read(bus, addr, (MDIO_ADDR_SWITCHID(priv->switchid) | MDIO_ADDR_AD_DATA | MDIO_ADDR_RW_READ)) & 0xffff) << 16;
val |= bus->read(bus, addr, (MDIO_ADDR_SWITCHID(priv->switchid) | MDIO_ADDR_AD_DATA | MDIO_ADDR_RW_READ)) & 0xffff;
mutex_unlock(&bus->mdio_lock);
return val;
}
static int yt9215_smi_write(struct yt9215_priv *priv, int reg, u32 val)
{
struct mii_bus *bus = priv->mdiodev->bus;
int addr = priv->mdiodev->addr;
mutex_lock(&bus->mdio_lock);
bus->write(bus, addr, (MDIO_ADDR_SWITCHID(priv->switchid) | MDIO_ADDR_AD_ADDR | MDIO_ADDR_RW_WRITE), ((reg >> 16) & 0xffff));
bus->write(bus, addr, (MDIO_ADDR_SWITCHID(priv->switchid) | MDIO_ADDR_AD_ADDR | MDIO_ADDR_RW_WRITE), ((reg >> 0) & 0xffff));
bus->write(bus, addr, (MDIO_ADDR_SWITCHID(priv->switchid) | MDIO_ADDR_AD_DATA | MDIO_ADDR_RW_WRITE), ((val >> 16) & 0xffff));
bus->write(bus, addr, (MDIO_ADDR_SWITCHID(priv->switchid) | MDIO_ADDR_AD_DATA | MDIO_ADDR_RW_WRITE), ((val >> 0) & 0xffff));
mutex_unlock(&bus->mdio_lock);
return 0;
}
static int yt9215_smi_rmw(struct yt9215_priv *priv, int reg, u32 mask, u32 val)
{
u32 v;
v = yt9215_smi_read(priv, reg);
v &= ~mask;
v |= val;
return yt9215_smi_write(priv, reg, v);
}
static int yt9215_int_mdio_wait(struct yt9215_priv *priv)
{
u32 val;
return read_poll_timeout(yt9215_smi_read, val,
val == INTIF_MDIO_OP_IDLE,
1000, INTIF_MDIO_TIMEOUT_US, false,
priv, INTIF_MDIO_OP);
}
static int yt9215_int_mdio_read(struct mii_bus *bus, int addr, int regnum)
{
struct yt9215_priv *priv = bus->priv;
int ret;
ret = yt9215_int_mdio_wait(priv);
if(ret)
return ret;
yt9215_smi_rmw(priv, INTIF_MDIO_CTRL,
(INTIF_MDIO_CTRL_OP_MASK | INTIF_MDIO_CTRL_ADDR_MASK
| INTIF_MDIO_CTRL_REG_MASK),
(INTIF_MDIO_CTRL_OP_READ | INTIF_MDIO_CTRL_ADDR(addr)
| INTIF_MDIO_CTRL_REG(regnum)));
yt9215_smi_write(priv, INTIF_MDIO_OP, INTIF_MDIO_OP_DO);
ret = yt9215_int_mdio_wait(priv);
if(ret)
return ret;
return yt9215_smi_read(priv, INTIF_MDIO_READ_DATA);
}
static int yt9215_int_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
{
struct yt9215_priv *priv = bus->priv;
int ret;
ret = yt9215_int_mdio_wait(priv);
if(ret)
return ret;
yt9215_smi_rmw(priv, INTIF_MDIO_CTRL,
(INTIF_MDIO_CTRL_OP_MASK | INTIF_MDIO_CTRL_ADDR_MASK
| INTIF_MDIO_CTRL_REG_MASK),
(INTIF_MDIO_CTRL_OP_WRITE | INTIF_MDIO_CTRL_ADDR(addr)
| INTIF_MDIO_CTRL_REG(regnum)));
yt9215_smi_write(priv, INTIF_MDIO_WRITE_DATA, val);
yt9215_smi_write(priv, INTIF_MDIO_OP, INTIF_MDIO_OP_DO);
ret = yt9215_int_mdio_wait(priv);
if(ret)
return ret;
return 0;
}
static void yt9215_init_ports(struct yt9215_priv *priv)
{
struct device_node *ports, *port, *fixed;
struct device *dev = &priv->mdiodev->dev;
phy_interface_t mode;
u32 reg, speed, full_duplex;
u32 val;
ports = of_get_child_by_name(dev_of_node(dev), "ports");
if (!ports)
return;
for_each_available_child_of_node(ports, port) {
speed = 0;
full_duplex = 0;
if (of_property_read_u32(port, "reg", &reg))
continue;
if (reg > priv->swdev.ports)
continue;
val = PORT_CTRL_RX_MAC_EN | PORT_CTRL_TX_MAC_EN;
fixed = of_get_child_by_name(port, "fixed-link");
if (fixed) {
if (!of_property_read_u32(fixed, "speed", &speed)) {
switch (speed) {
case 10:
val |= PORT_CTRL_SPEED_10;
break;
case 100:
val |= PORT_CTRL_SPEED_100;
break;
case 1000:
val |= PORT_CTRL_SPEED_1000;
break;
case 2500:
val |= PORT_CTRL_SPEED_2500;
break;
}
}
if (of_property_read_bool(fixed, "full-duplex")) {
full_duplex = 1;
val |= PORT_CTRL_DUPLEX_FULL;
} else
val |= PORT_CTRL_DUPLEX_HALF;
if (of_property_read_bool(fixed, "pause"))
val |= PORT_CTRL_RX_FLOWCONTROL;
if (of_property_read_bool(fixed, "asym-pause"))
val |= PORT_CTRL_TX_FLOWCONTROL;
/* TODO: phy setting */
} else { /* !fixed */
val |= PORT_CTRL_LINK_AN | PORT_CTRL_FLOWCONTROL_AN;
}
yt9215_smi_write(priv, PORT_CTRL(reg), val);
of_get_phy_mode(port, &mode);
switch(mode) {
case PHY_INTERFACE_MODE_INTERNAL:
break;
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_2500BASEX:
if (reg != 8)
break;
yt9215_smi_rmw(priv, EXTIF_CTRL,
EXTIF_CTRL_EXTIF0_ENABLE,
EXTIF_CTRL_EXTIF0_ENABLE);
yt9215_smi_rmw(priv, EXTIF_SEL,
EXTIF_SEL_EXTIF1_MASK,
EXTIF_SEL_EXTIF1_XMII);
yt9215_smi_rmw(priv, EXTIF_SEL,
EXTIF_SEL_EXTIF0_MASK,
EXTIF_SEL_EXTIF0_SERDES);
val = SGMII_CTRL_LINK;
switch (mode) {
case PHY_INTERFACE_MODE_SGMII:
val |= SGMII_CTRL_MODE_SGMII_PHY;
break;
case PHY_INTERFACE_MODE_2500BASEX:
val |= SGMII_CTRL_MODE_2500BASEX;
break;
default: /* avoid warning */
break;
}
switch (speed) {
case 10:
val |= SGMII_CTRL_SPEED_10;
break;
case 100:
val |= SGMII_CTRL_SPEED_100;
break;
case 1000:
val |= SGMII_CTRL_SPEED_1000;
break;
case 2500:
val |= SGMII_CTRL_SPEED_2500;
break;
}
if (full_duplex)
val |= SGMII_CTRL_DUPLEX_FULL;
else
val |= SGMII_CTRL_DUPLEX_HALF;
yt9215_smi_write(priv, SGMII_CTRL(0), val);
break;
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
/* TODO */
break;
default:
break;
}
}
}
static int yt9215_config(struct yt9215_priv *priv)
{
u32 val;
int i;
/* Reset */
yt9215_smi_write(priv, RESET_CTRL, RESET_CTRL_HW);
if (read_poll_timeout(yt9215_smi_read, val, val == 0,
10000, RESET_TIMEOUT_US, false,
priv, RESET_CTRL))
dev_err(&priv->mdiodev->dev, "reset timeout");
/* RESET_CTRL_HW is almost same as GPIO hard reset.
* So we need this delay.
*/
msleep(10);
/* MIB */
yt9215_smi_rmw(priv, FUNC_CTRL, FUNC_CTRL_MIB, FUNC_CTRL_MIB);
yt9215_smi_write(priv, MIB_CTRL, MIB_CTRL_PORT_SEL_ALL | MIB_CTRL_OP_CLEAN);
/* VLAN */
yt9215_smi_write(priv, EGR_TPID(0), ETH_P_8021Q);
yt9215_smi_write(priv, PORT_EGR_VLAN_FILTER, GENMASK(10, 0));
yt9215_smi_write(priv, IGR_TPID(0), ETH_P_8021Q);
yt9215_smi_write(priv, IGR_TPID(1), ETH_P_8021AD);
yt9215_smi_write(priv, PORT_IGR_LOOKUP_SVLAN, 0x00000);
yt9215_smi_write(priv, PORT_IGR_VLAN_FILTER, GENMASK(10, 0));
yt9215_smi_write(priv, VLAN_CTRL1(1),
VLAN_CTRL1_MEMBER(GENMASK(10, 0)));
yt9215_smi_write(priv, VLAN_CTRL2(1),
VLAN_CTRL2_UNTAG_MEMBER(GENMASK(10, 0)));
for(i = 0; i < 11; i++) {
yt9215_smi_write(priv, PORT_EGR_CTRL(i),
PORT_EGR_CTRL_CTAG_TPID_SEL(0));
yt9215_smi_write(priv, PORT_EGR_VLAN(i),
(PORT_EGR_VLAN_STAG_MODE_UNTAG |
PORT_EGR_VLAN_CTAG_MODE_LOOKUP));
/* only care about the outer VID */
yt9215_smi_write(priv, PORT_IGR_TPID(i),
(PORT_IGR_TPID_STAG_BITMAP(0) |
PORT_IGR_TPID_CTAG_BITMAP(BIT(0) | BIT(1))));
yt9215_smi_write(priv, PORT_IGR_PVID(i),
PORT_IGR_PVID_CVID(1));
}
/* MAC */
yt9215_init_ports(priv);
return 0;
}
static int yt9215_get_pvid(struct switch_dev *dev, int port, int *vlan)
{
struct yt9215_priv *priv = container_of(dev, struct yt9215_priv, swdev);
*vlan = FIELD_GET(PORT_IGR_PVID_CVID_MASK,
yt9215_smi_read(priv, PORT_IGR_PVID(port)));
return 0;
}
static int yt9215_set_pvid(struct switch_dev *dev, int port, int vlan)
{
struct yt9215_priv *priv = container_of(dev, struct yt9215_priv, swdev);
dev_info(&priv->mdiodev->dev, "Set Port%d default VLAN to %d", port, vlan);
yt9215_smi_rmw(priv, PORT_IGR_PVID(port),
PORT_IGR_PVID_CVID_MASK,
PORT_IGR_PVID_CVID(vlan));
return 0;
}
static int yt9215_get_vlan(struct switch_dev *dev, struct switch_val *val)
{
struct yt9215_priv *priv = container_of(dev, struct yt9215_priv, swdev);
u32 members, untag_members;
int i, num;
if (val->port_vlan >= dev->vlans || val->port_vlan < 0)
return -EINVAL;
members = FIELD_GET(VLAN_CTRL1_MEMBER_MASK,
yt9215_smi_read(priv, VLAN_CTRL1(val->port_vlan)));
untag_members = FIELD_GET(VLAN_CTRL2_UNTAG_MEMBER_MASK,
yt9215_smi_read(priv, VLAN_CTRL2(val->port_vlan)));
num = 0;
for(i = 0; i < dev->ports; i++)
if(members & (1 << i)) {
val->value.ports[num].id = i;
val->value.ports[num].flags = (!(untag_members & (1 << i))) << SWITCH_PORT_FLAG_TAGGED;
num++;
}
val->len = num;
return 0;
}
static int yt9215_set_vlan(struct switch_dev *dev, struct switch_val *val)
{
struct yt9215_priv *priv = container_of(dev, struct yt9215_priv, swdev);
u32 members, untag_members;
int i;
dev_info(&priv->mdiodev->dev, "Set VLAN%d members:", val->port_vlan);
if (val->port_vlan >= dev->vlans || val->port_vlan < 0)
return -EINVAL;
members = 0;
untag_members = 0;
for(i = 0; i < val->len; i++) {
members |= 1 << val->value.ports[i].id;
if (!(val->value.ports[i].flags & (1 << SWITCH_PORT_FLAG_TAGGED)))
untag_members |= 1 << val->value.ports[i].id;
dev_info(&priv->mdiodev->dev, "\t%d: %s", val->value.ports[i].id,
((val->value.ports[i].flags & (1 << SWITCH_PORT_FLAG_TAGGED)) ? "tag" : "untag"));
}
yt9215_smi_write(priv, VLAN_CTRL1(val->port_vlan),
VLAN_CTRL1_MEMBER(members));
yt9215_smi_write(priv, VLAN_CTRL2(val->port_vlan),
VLAN_CTRL2_UNTAG_MEMBER(untag_members));
return 0;
}
// static int yt9215_apply(struct switch_dev *dev)
// {
// struct yt9215_priv *priv = container_of(dev, struct yt9215_priv, swdev);
// dev_info(&priv->mdiodev->dev, "%s", __FUNCTION__);
// return 0;
// }
static int yt9215_reset_switch(struct switch_dev *dev)
{
struct yt9215_priv *priv = container_of(dev, struct yt9215_priv, swdev);
return yt9215_config(priv);
}
static int yt9215_get_link(struct switch_dev *dev, int port,
struct switch_port_link *link)
{
struct yt9215_priv *priv = container_of(dev, struct yt9215_priv, swdev);
u32 val;
val = yt9215_smi_read(priv, PORT_STATUS(port));
link->aneg = true;
link->link = (val & PORT_STATUS_RX_MAC_EN) && (val & PORT_STATUS_TX_MAC_EN);
link->duplex = ((val & PORT_STATUS_DUPLEX_MASK) == PORT_STATUS_DUPLEX_FULL);
link->tx_flow = !!(val & PORT_STATUS_TX_FLOWCONTROL);
link->rx_flow = !!(val & PORT_STATUS_RX_FLOWCONTROL);
if((val & PORT_STATUS_SPEED_MASK) == PORT_STATUS_SPEED_10)
link->speed = SWITCH_PORT_SPEED_10;
else if((val & PORT_STATUS_SPEED_MASK) == PORT_STATUS_SPEED_100)
link->speed = SWITCH_PORT_SPEED_100;
else if((val & PORT_STATUS_SPEED_MASK) == PORT_STATUS_SPEED_1000)
link->speed = SWITCH_PORT_SPEED_1000;
else if((val & PORT_STATUS_SPEED_MASK) == PORT_STATUS_SPEED_2500)
link->speed = SWITCH_PORT_SPEED_2500;
else
link->speed = SWITCH_PORT_SPEED_UNKNOWN;
return 0;
}
static int yt9215_get_stats(struct switch_dev *dev, int port,
struct switch_port_stats *stats)
{
struct yt9215_priv *priv = container_of(dev, struct yt9215_priv, swdev);
stats->tx_bytes = (unsigned long long) yt9215_smi_read(priv, MIB_DATA(port, 33));
stats->tx_bytes |= (unsigned long long) yt9215_smi_read(priv, MIB_DATA(port, 34)) << 32;
stats->rx_bytes = (unsigned long long) yt9215_smi_read(priv, MIB_DATA(port, 15));
stats->rx_bytes |= (unsigned long long) yt9215_smi_read(priv, MIB_DATA(port, 16)) << 32;
return 0;
}
static int yt9215_port_get_mib(struct switch_dev *dev, const struct switch_attr *attr,
struct switch_val *val)
{
struct yt9215_priv *priv = container_of(dev, struct yt9215_priv, swdev);
val->value.i = yt9215_smi_read(priv, MIB_DATA(val->port_vlan, attr->ofs));
return 0;
}
static int yt9215_port_get_mib_dword(struct switch_dev *dev, const struct switch_attr *attr,
struct switch_val *val)
{
struct yt9215_priv *priv = container_of(dev, struct yt9215_priv, swdev);
static char buf[64];
u64 v;
v = (u64) yt9215_smi_read(priv, MIB_DATA(val->port_vlan, attr->ofs));
v |= (u64) yt9215_smi_read(priv, MIB_DATA(val->port_vlan, attr->ofs + 1)) << 32;
val->len = snprintf(buf, sizeof(buf), "%llu", v);
val->value.s = buf;
return 0;
}
static struct switch_attr yt9215_global_attrs[] = {
// {
// .type = SWITCH_TYPE_INT,
// .name = "enable_vlan",
// .description = "Enable VLANs",
// .set = yt9215_set_enable_vlan,
// .get = yt9215_get_enable_vlan,
// },
};
#define YT9215_PORT_ATTR_MIB(attr, offset) \
{ \
.type = SWITCH_TYPE_INT, \
.name = attr, \
.description = "Get port's " attr " counters", \
.get = yt9215_port_get_mib, \
.set = NULL, \
.ofs = offset, \
}
/* switch_attr doesn't support 64bit int. So we need to use string. */
#define YT9215_PORT_ATTR_MIB_DWORD(attr, offset) \
{ \
.type = SWITCH_TYPE_STRING, \
.name = attr, \
.description = "Get port's " attr " counters", \
.get = yt9215_port_get_mib_dword, \
.set = NULL, \
.ofs = offset, \
}
static struct switch_attr yt9215_port_attrs[] = {
YT9215_PORT_ATTR_MIB("RX_BROADCAST", 0),
YT9215_PORT_ATTR_MIB("RX_PAUSE", 1),
YT9215_PORT_ATTR_MIB("RX_MULTICAST", 2),
YT9215_PORT_ATTR_MIB("RX_FCS_ERR", 3),
YT9215_PORT_ATTR_MIB("RX_ALIGNMENT_ERR", 4),
YT9215_PORT_ATTR_MIB("RX_UNDERSIZE", 5),
YT9215_PORT_ATTR_MIB("RX_FRAGMENT", 6),
YT9215_PORT_ATTR_MIB("RX_64B", 7),
YT9215_PORT_ATTR_MIB("RX_65_127B", 8),
YT9215_PORT_ATTR_MIB("RX_128_255B", 9),
YT9215_PORT_ATTR_MIB("RX_256_511B", 10),
YT9215_PORT_ATTR_MIB("RX_512_1023B", 11),
YT9215_PORT_ATTR_MIB("RX_1024_1518B", 12),
YT9215_PORT_ATTR_MIB("RX_JUMBO", 13),
YT9215_PORT_ATTR_MIB_DWORD("RX_OKBYTE", 15),
YT9215_PORT_ATTR_MIB_DWORD("RX_NOT_OKBYTE", 17),
YT9215_PORT_ATTR_MIB("RX_OVERSIZE", 19),
YT9215_PORT_ATTR_MIB("RX_DISCARD", 20),
YT9215_PORT_ATTR_MIB("TX_BROADCAST", 21),
YT9215_PORT_ATTR_MIB("TX_PAUSE", 22),
YT9215_PORT_ATTR_MIB("TX_MULTICAST", 23),
YT9215_PORT_ATTR_MIB("TX_UNDERSIZE", 24),
YT9215_PORT_ATTR_MIB("TX_64B", 25),
YT9215_PORT_ATTR_MIB("TX_65_127B", 26),
YT9215_PORT_ATTR_MIB("TX_128_255B", 27),
YT9215_PORT_ATTR_MIB("TX_256_511B", 28),
YT9215_PORT_ATTR_MIB("TX_512_1023B", 29),
YT9215_PORT_ATTR_MIB("TX_1024_1518B", 30),
YT9215_PORT_ATTR_MIB("TX_JUMBO", 31),
YT9215_PORT_ATTR_MIB_DWORD("TX_OKBYTE", 33),
YT9215_PORT_ATTR_MIB("TX_COLLISION", 35),
YT9215_PORT_ATTR_MIB("TX_EXCESSIVE_COLLISION", 36),
YT9215_PORT_ATTR_MIB("TX_MULTI_COLLISION", 37),
YT9215_PORT_ATTR_MIB("TX_SINGLE_COLLISION", 38),
YT9215_PORT_ATTR_MIB("TX_OK_PKT", 39),
YT9215_PORT_ATTR_MIB("TX_DEFER", 40),
YT9215_PORT_ATTR_MIB("TX_LATE_COLLISION", 41),
YT9215_PORT_ATTR_MIB("RX_OAM_COUNTER", 42),
YT9215_PORT_ATTR_MIB("TX_OAM_COUNTER", 43),
};
static struct switch_attr yt9215_vlan_attrs[] = {
};
static const struct switch_dev_ops yt9215_ops = {
.attr_global = {
.attr = yt9215_global_attrs,
.n_attr = ARRAY_SIZE(yt9215_global_attrs),
},
.attr_port = {
.attr = yt9215_port_attrs,
.n_attr = ARRAY_SIZE(yt9215_port_attrs),
},
.attr_vlan = {
.attr = yt9215_vlan_attrs,
.n_attr = ARRAY_SIZE(yt9215_vlan_attrs),
},
.get_port_pvid = yt9215_get_pvid,
.set_port_pvid = yt9215_set_pvid,
.get_vlan_ports = yt9215_get_vlan,
.set_vlan_ports = yt9215_set_vlan,
// .apply_config = yt9215_apply,
.reset_switch = yt9215_reset_switch,
.get_port_link = yt9215_get_link,
// .set_port_link = yt9215_set_link,
.get_port_stats = yt9215_get_stats,
};
static int yt9215_smi_probe(struct mdio_device *mdiodev)
{
struct device *dev = &mdiodev->dev;
struct yt9215_priv *priv;
struct switch_dev *swdev;
static int index;
u32 chipid;
int ret;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if(!priv)
return -ENOMEM;
dev_set_drvdata(&mdiodev->dev, priv);
priv->mdiodev = mdiodev;
if (!of_property_read_u32(dev_of_node(dev), "switchid", &priv->switchid))
priv->switchid = 0;
chipid = yt9215_smi_read(priv, CHIP_ID);
if ((chipid & YT9215_CHIP_ID_MASK) != YT9215_CHIP_ID)
dev_err(dev, "chipid incorrect: %08x", chipid);
else
dev_info(dev, "detected chipid: %08x", chipid);
priv->int_mdio_bus = devm_mdiobus_alloc(dev);
if (priv->int_mdio_bus == NULL)
goto out_free_priv;
priv->int_mdio_bus->name = "YT9215 internal mdio";
priv->int_mdio_bus->read = yt9215_int_mdio_read;
priv->int_mdio_bus->write = yt9215_int_mdio_write;
snprintf(priv->int_mdio_bus->id, MII_BUS_ID_SIZE, "YT9215-%d-int", index);
priv->int_mdio_bus->parent = dev;
priv->int_mdio_bus->phy_mask = (u32) ~GENMASK(7, 0);
priv->int_mdio_bus->priv = priv;
ret = mdiobus_register(priv->int_mdio_bus);
if(ret < 0)
goto out_free_priv;
swdev = &priv->swdev;
swdev->name = "YT9215";
swdev->cpu_port = 8;
swdev->ports = 11;
swdev->vlans = 4096;
swdev->ops = &yt9215_ops;
swdev->alias = dev_name(dev);
ret = register_switch(swdev, NULL);
if(ret < 0)
goto out_unregister_mdio;
dev_info(dev, "Registered %s as %s\n", swdev->name, swdev->devname);
ret = yt9215_config(priv);
if(ret < 0)
goto out_free_switch;
index++;
return 0;
out_free_switch:
unregister_switch(&priv->swdev);
out_unregister_mdio:
mdiobus_unregister(priv->int_mdio_bus);
out_free_priv:
kfree(priv);
return ret;
}
static void yt9215_smi_remove(struct mdio_device *mdiodev)
{
struct yt9215_priv *priv = dev_get_drvdata(&mdiodev->dev);
unregister_switch(&priv->swdev);
mdiobus_unregister(priv->int_mdio_bus);
kfree(priv);
return;
}
static const struct of_device_id yt9215_of_match[] = {
{ .compatible = "motorcomm,yt9215-smi" },
{},
};
static struct mdio_driver yt9215_mdio_driver = {
.probe = yt9215_smi_probe,
.remove = yt9215_smi_remove,
.mdiodrv.driver = {
.name = "yt9215-smi",
.of_match_table = yt9215_of_match,
},
};
mdio_module_driver(yt9215_mdio_driver);

View File

@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -62,6 +62,80 @@ config SFP
@@ -62,6 +62,84 @@ config SFP
depends on HWMON || HWMON=n
select MDIO_I2C
@ -89,13 +89,17 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ select SWCONFIG
+
+endif # RTL8366_SMI
+
+config YT9215_PHY
+ tristate "Motorcomm YT9215 switch"
+ select SWCONFIG
+
comment "MII PHY device drivers"
config AMD_PHY
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -24,6 +24,21 @@ libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_
@@ -24,6 +24,22 @@ libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_
obj-$(CONFIG_PHYLINK) += phylink.o
obj-$(CONFIG_PHYLIB) += libphy.o
@ -113,6 +117,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o
+obj-$(CONFIG_RTL8367_PHY) += rtl8367.o
+obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o
+obj-$(CONFIG_YT9215_PHY) += yt9215.o
+
obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o

View File

@ -0,0 +1,32 @@
#!/bin/sh
. /lib/functions/uci-defaults.sh
bits() {
local val
val=0
while [ -n "$1" ]; do
val=$(( val | (1 << $1) ))
shift 1
done
printf "0x%x" "$val"
}
board_config_update
board=$(board_name)
case $board in
redmi,ax3000)
ucidef_set_led_switch "wan" "WAN" "blue:internet" "switch1" "$( bits 4 )"
;;
xiaomi,cr881x)
ucidef_set_led_switch "wan" "WAN" "blue:internet" "switch0" "$( bits 3 )"
;;
esac
board_config_flush
exit 0

View File

@ -0,0 +1,35 @@
#!/bin/sh
. /lib/functions/uci-defaults.sh
ipq50xx_setup_interfaces()
{
local board="$1"
case $board in
redmi,ax3000)
ucidef_add_switch "switch1" \
"6u@eth1" "5u@eth0" \
"1:lan:1" "2:lan:2" "3:lan:3" \
"4:wan"
;;
xiaomi,cr881x)
ucidef_add_switch "switch0" \
"8u@eth1" "4u@eth0" \
"0:lan:1" "1:lan:2" "2:lan:3" \
"3:wan"
;;
cmcc,rax3000q)
ucidef_add_switch "switch1" \
"6u@eth1" "3u@eth0" \
"2:lan:1" "4:lan:2" "5:lan:3" \
"1:wan"
;;
esac
}
board_config_update
board=$(board_name)
ipq50xx_setup_interfaces $board
board_config_flush
exit 0

View File

@ -0,0 +1,25 @@
#!/bin/sh
[ -e /lib/firmware/$FIRMWARE ] && exit 0
set_board_id() {
echo "$1" >/lib/firmware/$FIRMWARE
}
board=$(board_name)
case "$FIRMWARE" in
"ath11k/IPQ5018/hw1.0/board_id-ahb-c000000.wifi")
case "$board" in
redmi,ax3000)
case "$(strings /dev/mtdblock15 | grep wl_pa_type= | cut -d= -f2)" in
epa) set_board_id 0x24 ;;
ipa|*) set_board_id 0x10 ;;
esac
;;
esac
;;
*)
exit 1
;;
esac

View File

@ -0,0 +1,31 @@
#!/bin/sh
[ -e /lib/firmware/$FIRMWARE ] && exit 0
. /lib/functions/caldata.sh
board=$(board_name)
case "$FIRMWARE" in
"ath11k/IPQ5018/hw1.0/caldata.bin")
case "$board" in
cmcc,rax3000q|\
redmi,ax3000|\
xiaomi,cr881x)
caldata_extract "0:ART" 0x1000 0x20000
;;
esac
;;
"ath11k/qcn6122/hw1.0/caldata_1.bin")
case "$board" in
cmcc,rax3000q|\
redmi,ax3000|\
xiaomi,cr881x)
caldata_extract "0:ART" 0x26800 0x20000
;;
esac
;;
*)
exit 1
;;
esac

View File

@ -0,0 +1,35 @@
#!/bin/sh /etc/rc.common
START=99
. /lib/functions.sh
boot() {
case $(board_name) in
redmi,ax3000|\
xiaomi,cr881x)
fw_printenv >/dev/null || return 0
local flag_ota_reboot="$(fw_printenv flag_ota_reboot | cut -d'=' -f2)"
if [[ "$flag_ota_reboot" == 1 ]]; then
local mtd="$(grep -oE 'ubi.mtd=[a-zA-Z0-9\-\_]*' /proc/cmdline | cut -d'=' -f2)"
case $mtd in
rootfs)
fw_setenv flag_last_success 0
fw_setenv flag_ota_reboot 0
fw_setenv flag_boot_success 1
;;
rootfs_1)
fw_setenv flag_last_success 1
fw_setenv flag_ota_reboot 0
fw_setenv flag_boot_success 1
;;
*)
echo "Unable to determine UBIPART: ubi.mtd=$mtd"
return 1
;;
esac
fi
;;
esac
}

View File

@ -0,0 +1,80 @@
. /lib/functions.sh
mi_dualboot_check_image() {
local ret=0
local file_type="$( identify "$1" )"
if [ "${file_type}" != ubi ]; then
v "Unsupport file type: ${file_type}"
v "Please use ubi file"
ret=1
fi
local mtd="$( grep -oE 'ubi.mtd=[a-zA-Z0-9\-\_]*' /proc/cmdline | cut -d'=' -f2 )"
if [[ "${mtd}" != "rootfs" ]] && [[ "${mtd}" != "rootfs_1" ]]; then
v "Unable to determine UBIPART: ubi.mtd=${mtd}"
ret=1
fi
if ! fw_printenv >/dev/null; then
v "Fail to read U-Boot env"
ret=1
fi
return ${ret}
}
mi_dualboot_do_upgrade() {
mkdir -p /var/lock
fw_printenv >/dev/null || return 1
# Determine UBIPART
local mtd="$( grep -oE 'ubi.mtd=[a-zA-Z0-9\-\_]*' /proc/cmdline | cut -d'=' -f2 )"
case "${mtd}" in
rootfs)
CI_UBIPART="rootfs_1"
local current=0
;;
rootfs_1)
CI_UBIPART="rootfs"
local current=1
;;
*)
v "Unable to determine UBIPART: ubi.mtd=$mtd"
return 1
;;
esac
local mtdnum="$( find_mtd_index "${CI_UBIPART}" )"
v "Flashing to ${CI_UBIPART}(mtd${mtdnum})"
ubiformat "/dev/mtd${mtdnum}" -f "$1" -y || return 1
sync
ubiattach --mtdn "${mtdnum}"
# Check to avoid the bug of the vendor U-Boot
local ubidev="$( nand_find_ubi "${CI_UBIPART}" )"
if [ -z "$( nand_find_volume "${ubidev}" "kernel" )" ]; then
v "\"kernel\" volume doesn't exist, which causes a bug of the vendor U-Boot."
v "When try to boot this system, U-Boot will always set flag_try_sys1_failed=0 even if this is the sysem 2"
return 1
fi
# Restore configurations
[ -f "${UPGRADE_BACKUP}" ] && CI_UBIPART="${CI_UBIPART}" nand_restore_config "${UPGRADE_BACKUP}"
# Clean the failed flag. So we can boot to them.
fw_setenv flag_try_sys1_failed 0 || return 1
fw_setenv flag_try_sys2_failed 0 || return 1
# Tell u-boot that the current is able to boot.
fw_setenv flag_last_success ${current} || return 1
# Tell u-boot to try to boot the other system.
# If it failed, it will clean this flag.
fw_setenv flag_ota_reboot 1 || return 1
# When this flag is set to 0 and the `flag_ota_reboot` is 1,
# the u-boot will roll back to `flag_last_success`.
fw_setenv flag_boot_success || return 1
}

View File

@ -1,8 +1,16 @@
. /lib/functions.sh
RAMFS_COPY_BIN='fw_printenv fw_setenv'
RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
platform_check_image() {
local board=$(board_name)
case $board in
redmi,ax3000|\
xiaomi,cr881x)
mi_dualboot_check_image "$1"
return $?
;;
*)
v "Sysupgrade is not supported on your board($board) yet."
return 1
@ -13,6 +21,10 @@ platform_check_image() {
platform_do_upgrade() {
local board=$(board_name)
case $board in
redmi,ax3000|\
xiaomi,cr881x)
mi_dualboot_do_upgrade "$1"
;;
*)
default_do_upgrade "$1"
;;

View File

@ -1296,7 +1296,10 @@ CONFIG_ARCH_IPQ50XX=y
CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT=y
# CONFIG_MTD_UBI_GLUEBI is not set
CONFIG_MDIO_IPQ4019=y
CONFIG_YT9215_PHY=y
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_LEDS_GPIO=y
CONFIG_SWCONFIG_LEDS=y
CONFIG_IPQ_APSS_PLL=y
CONFIG_IPQ_APSS_6018=y

View File

@ -0,0 +1,556 @@
// SPDX-License-Identifier: (GPL-2.0+)
/dts-v1/;
#include "ipq5018.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
model = "Redmi AX3000";
compatible = "redmi,ax3000", "qcom,ipq5018";
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&intc>;
aliases {
serial0 = &blsp1_uart1;
ethernet0 = &mac0;
ethernet1 = &mac1;
led-boot = &led_system_blue;
led-failsafe = &led_system_yellow;
led-running = &led_system_blue;
led-upgrade = &led_system_yellow;
};
chosen {
// Override the root parameter from u-boot
// Increase coherent_pool size for WiFi
bootargs-append = " root=/dev/ubiblock0_1 coherent_pool=2M";
stdout-path = "serial0:115200n8";
};
reserved-memory {
// Not sure why but without this, WiFi will crash
tz_apps@4a400000 {
no-map;
// The size is incorrent, but it works
reg = <0x0 0x4a400000 0x0 0x700000>;
};
q6_mem_regions: q6_mem_regions@4b000000 {
no-map;
// reg = <0x0 0x4b000000 0x0 0x3b00000>;
reg = <0x0 0x4b000000 0x0 0x3000000>;
};
};
thermal-zones {
status = "ok";
};
};
&tlmm {
blsp_uart0_pins: blsp_uart0_pins {
pins =
"gpio28", // RX
"gpio29"; // TX
function = "blsp0_uart1";
drive-strength = <8>;
bias-disable;
};
qspi_nand_pins: qspi_nand_pins {
clock {
pins = "gpio9";
function = "qspi_clk";
drive-strength = <8>;
bias-disable;
};
cs {
pins = "gpio8";
function = "qspi_cs";
drive-strength = <8>;
bias-disable;
};
data0 {
pins = "gpio7";
function = "qspi0";
drive-strength = <8>;
bias-disable;
};
data1 {
pins = "gpio6";
function = "qspi1";
drive-strength = <8>;
bias-disable;
};
data2 {
pins = "gpio5";
function = "qspi2";
drive-strength = <8>;
bias-disable;
};
data3 {
pins = "gpio4";
function = "qspi3";
drive-strength = <8>;
bias-disable;
};
};
mdio1_pins: mdio1_pins {
mdc {
pins = "gpio36";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mdio {
pins = "gpio37";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
};
leds_pins: leds_pins {
led_system_blue {
pins = "gpio19";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_system_yellow {
pins = "gpio17";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_internet_blue {
pins = "gpio22";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_internet_yellow {
pins = "gpio20";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
button_pins: button_pins {
button_reset {
pins = "gpio25";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
button_mesh {
pins = "gpio23";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
};
&blsp1_uart1 {
pinctrl-0 = <&blsp_uart0_pins>;
pinctrl-names = "default";
status = "ok";
};
&qpic_bam {
status = "ok";
};
&nand {
pinctrl-0 = <&qspi_nand_pins>;
pinctrl-names = "default";
status = "ok";
};
&soc {
leds {
compatible = "gpio-leds";
pinctrl-0 = <&leds_pins>;
pinctrl-names = "default";
led_system_blue: led_system_blue {
label = "blue:system";
gpio = <&tlmm 19 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
led_system_yellow: led_system_yellow {
label = "yellow:system";
gpio = <&tlmm 17 GPIO_ACTIVE_HIGH>;
};
led_internet_blue: led_internet_blue {
label = "blue:internet";
gpio = <&tlmm 22 GPIO_ACTIVE_HIGH>;
};
led_internet_yellow: led_internet_yellow {
label = "yellow:internet";
gpio = <&tlmm 20 GPIO_ACTIVE_HIGH>;
};
};
button {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
button_reset {
label = "reset";
gpios = <&tlmm 25 GPIO_ACTIVE_LOW>;
linux,input-type = <EV_KEY>;
linux,code = <KEY_RESTART>;
debounce-interval = <60>;
};
button_mesh {
label = "mesh";
gpios = <&tlmm 23 GPIO_ACTIVE_LOW>;
linux,input-type = <EV_KEY>;
linux,code = <KEY_WPS_BUTTON>;
debounce-interval = <60>;
};
};
ess-instance {
num_devices = <2>;
// Dummy switch, to describe how the external ports connects to the MAC
// For example, some chips have PSGMII ports which combine 5 MAC into
// 1 external port.
// For IPQ50xx, this is used to choose SGMII or SGMII-plus
ess-switch@0x39c00000 {
compatible = "qcom,ess-switch-ipq50xx";
device_id = <0>;
cmnblk_clk = "internal_96MHz";
// MAC1 Mode
// switch_mac_mode = <0xc>; // PORT_WRAPPER_SGMII_PLUS
switch_mac_mode = <0xf>; // PORT_WRAPPER_SGMII_CHANNEL0
qcom,port_phyinfo {
// MAC0 -> GE Phy -> QCA8337 Phy4
port@0 {
port_id = <1>;
mdiobus = <&mdio0>;
phy_address = <7>;
phy_dac = <0x10 0x10>;
};
// MAC1 ---SGMII---> QCA8337 SerDes
port@1 {
port_id = <2>;
forced-speed = <1000>;
forced-duplex = <1>;
};
};
};
// QCA8337
ess-switch1@1 {
compatible = "qcom,ess-switch-qca83xx";
device_id = <1>;
reset_gpio = <26>;
switch_access_mode = "mdio";
mdio-bus = <&mdio1>;
qca,ar8327-initvals = <
0x000c 0x00000080 // PAD6_MODE = MAC6_SGMII_EN
0x0010 0x002613a0 // PWS_REG = DEFAULT_VALUE | SERDES_AEN
0x0094 0x000010ce // PORT6_STATUS = DEFAULT_VALUE | DUPLEX_MODE_6 | RXMAC_EN_6 |
// TXMAC_EN_6 | SPEED_6(1000M)
0x00e0 0xc74164de // SGMII_CTRL = DEFAULT_VALUE | MODE_CTRL_25M(SGMII_PHY) | SGMII_EN_SD |
// SGMII_EN_TX | SGMII_EN_RX | SGMII_EN_PLL
>;
switch_cpu_bmp = <0x60>; // CPU port bitmap: 5 6
switch_lan_bmp = <0x0e>; // LAN port bitmap: 1 2 3
switch_wan_bmp = <0x10>; // WAN port bitmap: 4
qcom,port_phyinfo {
// MAC1 -> Phy0 -> LAN1
port@1 {
port_id = <1>;
phy_address = <0>;
};
// MAC2 -> Phy1 -> LAN2
port@2 {
port_id = <2>;
phy_address = <1>;
};
// MAC3 -> Phy2 -> LAN3
port@3 {
port_id = <3>;
phy_address = <2>;
};
// MAC4 -> Phy3 -> WAN
port@4 {
port_id = <4>;
phy_address = <3>;
};
// MAC5 -> Phy4 -> IPQ5000 GE Phy
port@5 {
port_id = <5>;
phy_address = <4>;
};
// MAC6 ---SGMII---> IPQ5000 MAC1
port@6 {
port_id = <6>;
forced-speed = <1000>;
forced-duplex = <1>;
};
};
};
};
// MAC0 -> GE Phy
mac0: dp1 {
compatible = "qcom,nss-dp";
device_type = "network";
qcom,id = <1>;
reg = <0x39C00000 0x10000>;
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_SNOC_GMAC0_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,mactype = <2>; // GMAC_HAL_TYPE_SYN_GMAC
local-mac-address = [000000000000];
phy-handle = <&ge_phy>;
phy-mode = "internal";
};
// MAC1 ---SGMII---> QCA8337 SerDes
mac1: dp2 {
compatible = "qcom,nss-dp";
device_type = "network";
qcom,id = <2>;
reg = <0x39D00000 0x10000>;
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_SNOC_GMAC1_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,mactype = <2>; // GMAC_HAL_TYPE_SYN_GMAC
local-mac-address = [000000000000];
phy-mode = "sgmii";
};
};
&mdio0 {
status = "ok";
resets = <&gcc GCC_GEPHY_MDC_SW_ARES>;
reset-names = "phy";
// IPQ5018 GE Phy -> QCA8337 Phy4
ge_phy: ethernet-phy@0 {
reg = <7>;
};
};
&mdio1 {
pinctrl-0 = <&mdio1_pins>;
pinctrl-names = "default";
status = "ok";
reset-gpios = <&tlmm 26 GPIO_ACTIVE_LOW>;
// QCA8337 Phy0 -> LAN1
ethernet-phy@0 {
reg = <0>;
};
// QCA8337 Phy1 -> LAN2
ethernet-phy@1 {
reg = <1>;
};
// QCA8337 Phy2 -> LAN3
ethernet-phy@2 {
reg = <2>;
};
// QCA8337 Phy3 -> WAN
ethernet-phy@3 {
reg = <3>;
};
// QCA8337 Phy4 -> IPQ5018 GE Phy
ethernet-phy@4 {
reg = <4>;
};
};
&q6v5_wcss {
memory-region = <&q6_mem_regions>;
qcom,rproc = <&q6v5_wcss>;
firmware = "IPQ5018/q6_fw.mdt";
qcom,bootargs_smem = <507>;
boot-args = </* type: */ 0x2 /* PCIE1 */
/* length: */ 4
/* PD id: */ 2
/* reset GPIO: */ 27
/* reserved: */ 0 0>;
status = "ok";
// IPQ5018
q6_wcss_pd1: remoteproc_pd1@4ab000 {
compatible = "qcom,ipq5018-wcss-ahb-mpd";
resets =
<&gcc GCC_WCSSAON_RESET>,
<&gcc GCC_WCSS_BCR>,
<&gcc GCC_CE_BCR>;
reset-names =
"wcss_aon_reset",
"wcss_reset",
"ce_reset";
clocks =
<&gcc GCC_WCSS_AHB_S_CLK>,
<&gcc GCC_WCSS_ACMT_CLK>,
<&gcc GCC_WCSS_AXI_M_CLK>;
clock-names =
"gcc_wcss_ahb_s_clk",
"gcc_wcss_acmt_clk",
"gcc_wcss_axi_m_clk";
reg = <0x4ab000 0x20>;
reg-names = "rmb";
// qcom,halt-regs = <&tcsr_q6_block 0xa000 0xd000 0x0>;
interrupts-extended =
<&wcss_smp2p_in 8 0>,
<&wcss_smp2p_in 9 0>,
<&wcss_smp2p_in 12 0>,
<&wcss_smp2p_in 11 0>;
interrupt-names =
"fatal",
"ready",
"spawn-ack",
"stop-ack";
qcom,smem-states =
<&wcss_smp2p_out 8>,
<&wcss_smp2p_out 9>,
<&wcss_smp2p_out 10>;
qcom,smem-state-names =
"shutdown",
"stop",
"spawn";
firmware = "IPQ5018/q6_fw.mdt";
m3_firmware = "IPQ5018/m3_fw.mdt";
};
// QCN6102
q6_wcss_pd2: remoteproc_pd2 {
compatible = "qcom,ipq5018-wcss-pcie-mpd";
interrupts-extended =
<&wcss_smp2p_in 16 0>,
<&wcss_smp2p_in 17 0>,
<&wcss_smp2p_in 20 0>,
<&wcss_smp2p_in 19 0>;
interrupt-names =
"fatal",
"ready",
"spawn-ack",
"stop-ack";
qcom,smem-states =
<&wcss_smp2p_out 16>,
<&wcss_smp2p_out 17>,
<&wcss_smp2p_out 18>;
qcom,smem-state-names =
"shutdown",
"stop",
"spawn";
firmware = "IPQ5018/q6_fw.mdt";
m3_firmware = "qcn6122/m3_fw.mdt";
};
};
&wifi0 {
// IPQ5000
qcom,multipd_arch;
qcom,rproc = <&q6_wcss_pd1>;
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
// Be overridden by /etc/hotplug.d/firmware/10-ath11k-board_id
// M79: 0x10
// M81: 0x24
qcom,board_id = <0x24>;
// qcom,ath11k-fw-memory-mode = <0>;
// qcom,bdf-addr = <0x4c400000>;
// qcom,caldb-addr = <0x4d200000>;
// qcom,m3-dump-addr = <0x4d400000>;
qcom,ath11k-fw-memory-mode = <2>;
qcom,bdf-addr = <0x4c400000>;
status = "ok";
};
&wifi1 {
// QCN6102
qcom,multipd_arch;
qcom,rproc = <&q6_wcss_pd2>;
qcom,userpd-subsys-name = "q6v5_wcss_userpd2";
qcom,board_id = <0x60>;
// qcom,ath11k-fw-memory-mode = <0>;
// qcom,bdf-addr = <0x4d500000>;
// qcom,caldb-addr = <0x4e500000>;
// qcom,m3-dump-addr = <0x4ea00000>;
qcom,ath11k-fw-memory-mode = <2>;
qcom,bdf-addr = <0x4d100000>;
qcom,m3-dump-addr = <0x4df00000>;
status = "ok";
};

View File

@ -0,0 +1,541 @@
// SPDX-License-Identifier: (GPL-2.0+)
/dts-v1/;
#include "ipq5018.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
model = "CMCC RAX3000Q";
compatible = "cmcc,rax3000q", "qcom,ipq5018";
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&intc>;
aliases {
serial0 = &blsp1_uart1;
ethernet0 = &mac0;
ethernet1 = &mac1;
led-boot = &led_status_green;
led-failsafe = &led_status_red;
led-running = &led_status_green;
led-upgrade = &led_status_blue;
};
chosen {
// Override the root parameter from u-boot
// Increase coherent_pool size for WiFi
bootargs-append = " root=/dev/ubiblock0_1 coherent_pool=2M";
stdout-path = "serial0:115200n8";
};
reserved-memory {
// Not sure why but without this, WiFi will crash
tz_apps@4a400000 {
no-map;
// The size is incorrent, but it works
reg = <0x0 0x4a400000 0x0 0x700000>;
};
q6_mem_regions: q6_mem_regions@4b000000 {
no-map;
// reg = <0x0 0x4b000000 0x0 0x3b00000>;
reg = <0x0 0x4b000000 0x0 0x3000000>;
};
};
thermal-zones {
status = "ok";
};
};
&tlmm {
blsp_uart0_pins: blsp_uart0_pins {
pins =
"gpio28", // RX
"gpio29"; // TX
function = "blsp0_uart1";
drive-strength = <8>;
bias-disable;
};
qspi_nand_pins: qspi_nand_pins {
clock {
pins = "gpio9";
function = "qspi_clk";
drive-strength = <8>;
bias-disable;
};
cs {
pins = "gpio8";
function = "qspi_cs";
drive-strength = <8>;
bias-disable;
};
data0 {
pins = "gpio7";
function = "qspi0";
drive-strength = <8>;
bias-disable;
};
data1 {
pins = "gpio6";
function = "qspi1";
drive-strength = <8>;
bias-disable;
};
data2 {
pins = "gpio5";
function = "qspi2";
drive-strength = <8>;
bias-disable;
};
data3 {
pins = "gpio4";
function = "qspi3";
drive-strength = <8>;
bias-disable;
};
};
mdio1_pins: mdio1_pins {
mdc {
pins = "gpio36";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mdio {
pins = "gpio37";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
};
leds_pins: leds_pins {
led_status_red {
pins = "gpio24";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_status_green {
pins = "gpio19";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_status_blue {
pins = "gpio17";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
button_pins: button_pins {
button_reset {
pins = "gpio23";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
button_mesh {
pins = "gpio38";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
};
&blsp1_uart1 {
pinctrl-0 = <&blsp_uart0_pins>;
pinctrl-names = "default";
status = "ok";
};
&qpic_bam {
status = "ok";
};
&nand {
pinctrl-0 = <&qspi_nand_pins>;
pinctrl-names = "default";
status = "ok";
};
&soc {
leds {
compatible = "gpio-leds";
pinctrl-0 = <&leds_pins>;
pinctrl-names = "default";
led_status_red: led_status_red {
label = "blue:system";
gpio = <&tlmm 24 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
led_status_green: led_status_green {
label = "yellow:system";
gpio = <&tlmm 19 GPIO_ACTIVE_HIGH>;
};
led_status_blue: led_status_blue {
label = "blue:internet";
gpio = <&tlmm 17 GPIO_ACTIVE_HIGH>;
};
};
button {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
button_reset {
label = "reset";
gpios = <&tlmm 23 GPIO_ACTIVE_LOW>;
linux,input-type = <EV_KEY>;
linux,code = <KEY_RESTART>;
debounce-interval = <60>;
};
button_mesh {
label = "mesh";
gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
linux,input-type = <EV_KEY>;
linux,code = <KEY_WPS_BUTTON>;
debounce-interval = <60>;
};
};
ess-instance {
num_devices = <2>;
// Dummy switch, to describe how the external ports connects to the MAC
// For example, some chips have PSGMII ports which combine 5 MAC into
// 1 external port.
// For IPQ50xx, this is used to choose SGMII or SGMII-plus
ess-switch@0x39c00000 {
compatible = "qcom,ess-switch-ipq50xx";
device_id = <0>;
cmnblk_clk = "internal_96MHz";
// MAC1 Mode
// switch_mac_mode = <0xc>; // PORT_WRAPPER_SGMII_PLUS
switch_mac_mode = <0xf>; // PORT_WRAPPER_SGMII_CHANNEL0
qcom,port_phyinfo {
// MAC0 -> GE Phy -> QCA8337 Phy2
port@0 {
port_id = <1>;
mdiobus = <&mdio0>;
phy_address = <7>;
phy_dac = <0x10 0x10>;
};
// MAC1 ---SGMII---> QCA8337 SerDes
port@1 {
port_id = <2>;
forced-speed = <1000>;
forced-duplex = <1>;
};
};
};
// QCA8337
ess-switch1@1 {
compatible = "qcom,ess-switch-qca83xx";
device_id = <1>;
reset_gpio = <26>;
switch_access_mode = "mdio";
mdio-bus = <&mdio1>;
qca,ar8327-initvals = <
0x000c 0x00000080 // PAD6_MODE = MAC6_SGMII_EN
0x0010 0x002613a0 // PWS_REG = DEFAULT_VALUE | SERDES_AEN
0x0094 0x000010ce // PORT6_STATUS = DEFAULT_VALUE | DUPLEX_MODE_6 | RXMAC_EN_6 |
// TXMAC_EN_6 | SPEED_6(1000M)
0x00e0 0xc74164de // SGMII_CTRL = DEFAULT_VALUE | MODE_CTRL_25M(SGMII_PHY) | SGMII_EN_SD |
// SGMII_EN_TX | SGMII_EN_RX | SGMII_EN_PLL
>;
switch_cpu_bmp = <0x48>; // CPU port bitmap: 3 6
switch_lan_bmp = <0x34>; // LAN port bitmap: 2 4 5
switch_wan_bmp = <0x02>; // WAN port bitmap: 1
qcom,port_phyinfo {
// MAC1 -> Phy0 -> WAN
port@1 {
port_id = <1>;
phy_address = <0>;
};
// MAC2 -> Phy1 -> LAN1
port@2 {
port_id = <2>;
phy_address = <1>;
};
// MAC3 -> Phy2 -> IPQ5000 GE Phy
port@3 {
port_id = <3>;
phy_address = <2>;
};
// MAC4 -> Phy3 -> LAN2
port@4 {
port_id = <4>;
phy_address = <3>;
};
// MAC5 -> Phy4 -> LAN3
port@5 {
port_id = <5>;
phy_address = <4>;
};
// MAC6 ---SGMII---> IPQ5000 MAC1
port@6 {
port_id = <6>;
forced-speed = <1000>;
forced-duplex = <1>;
};
};
};
};
// MAC0 -> GE Phy
mac0: dp1 {
compatible = "qcom,nss-dp";
device_type = "network";
qcom,id = <1>;
reg = <0x39C00000 0x10000>;
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_SNOC_GMAC0_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,mactype = <2>; // GMAC_HAL_TYPE_SYN_GMAC
local-mac-address = [000000000000];
phy-handle = <&ge_phy>;
phy-mode = "internal";
};
// MAC1 ---SGMII---> QCA8337 SerDes
mac1: dp2 {
compatible = "qcom,nss-dp";
device_type = "network";
qcom,id = <2>;
reg = <0x39D00000 0x10000>;
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_SNOC_GMAC1_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,mactype = <2>; // GMAC_HAL_TYPE_SYN_GMAC
local-mac-address = [000000000000];
phy-mode = "sgmii";
};
};
&mdio0 {
status = "ok";
resets = <&gcc GCC_GEPHY_MDC_SW_ARES>;
reset-names = "phy";
// IPQ5018 GE Phy -> QCA8337 Phy2
ge_phy: ethernet-phy@0 {
reg = <7>;
};
};
&mdio1 {
pinctrl-0 = <&mdio1_pins>;
pinctrl-names = "default";
status = "ok";
reset-gpios = <&tlmm 26 GPIO_ACTIVE_LOW>;
// QCA8337 Phy0 -> WAN
ethernet-phy@0 {
reg = <0>;
};
// QCA8337 Phy1 -> LAN1
ethernet-phy@1 {
reg = <1>;
};
// QCA8337 Phy2 -> IPQ5018 GE Phy
ethernet-phy@2 {
reg = <2>;
};
// QCA8337 Phy3 -> LAN2
ethernet-phy@3 {
reg = <3>;
};
// QCA8337 Phy4 -> LAN3
ethernet-phy@4 {
reg = <4>;
};
};
&q6v5_wcss {
memory-region = <&q6_mem_regions>;
qcom,rproc = <&q6v5_wcss>;
firmware = "IPQ5018/q6_fw.mdt";
qcom,bootargs_smem = <507>;
boot-args = </* type: */ 0x2 /* PCIE1 */
/* length: */ 4
/* PD id: */ 2
/* reset GPIO: */ 27
/* reserved: */ 0 0>;
status = "ok";
// IPQ5018
q6_wcss_pd1: remoteproc_pd1@4ab000 {
compatible = "qcom,ipq5018-wcss-ahb-mpd";
resets =
<&gcc GCC_WCSSAON_RESET>,
<&gcc GCC_WCSS_BCR>,
<&gcc GCC_CE_BCR>;
reset-names =
"wcss_aon_reset",
"wcss_reset",
"ce_reset";
clocks =
<&gcc GCC_WCSS_AHB_S_CLK>,
<&gcc GCC_WCSS_ACMT_CLK>,
<&gcc GCC_WCSS_AXI_M_CLK>;
clock-names =
"gcc_wcss_ahb_s_clk",
"gcc_wcss_acmt_clk",
"gcc_wcss_axi_m_clk";
reg = <0x4ab000 0x20>;
reg-names = "rmb";
// qcom,halt-regs = <&tcsr_q6_block 0xa000 0xd000 0x0>;
interrupts-extended =
<&wcss_smp2p_in 8 0>,
<&wcss_smp2p_in 9 0>,
<&wcss_smp2p_in 12 0>,
<&wcss_smp2p_in 11 0>;
interrupt-names =
"fatal",
"ready",
"spawn-ack",
"stop-ack";
qcom,smem-states =
<&wcss_smp2p_out 8>,
<&wcss_smp2p_out 9>,
<&wcss_smp2p_out 10>;
qcom,smem-state-names =
"shutdown",
"stop",
"spawn";
firmware = "IPQ5018/q6_fw.mdt";
m3_firmware = "IPQ5018/m3_fw.mdt";
};
// QCN6102
q6_wcss_pd2: remoteproc_pd2 {
compatible = "qcom,ipq5018-wcss-pcie-mpd";
interrupts-extended =
<&wcss_smp2p_in 16 0>,
<&wcss_smp2p_in 17 0>,
<&wcss_smp2p_in 20 0>,
<&wcss_smp2p_in 19 0>;
interrupt-names =
"fatal",
"ready",
"spawn-ack",
"stop-ack";
qcom,smem-states =
<&wcss_smp2p_out 16>,
<&wcss_smp2p_out 17>,
<&wcss_smp2p_out 18>;
qcom,smem-state-names =
"shutdown",
"stop",
"spawn";
firmware = "IPQ5018/q6_fw.mdt";
m3_firmware = "qcn6122/m3_fw.mdt";
};
};
&wifi0 {
// IPQ5000
qcom,multipd_arch;
qcom,rproc = <&q6_wcss_pd1>;
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
qcom,board_id = <0x24>;
// qcom,ath11k-fw-memory-mode = <0>;
// qcom,bdf-addr = <0x4c400000>;
// qcom,caldb-addr = <0x4d200000>;
// qcom,m3-dump-addr = <0x4d400000>;
qcom,ath11k-fw-memory-mode = <2>;
qcom,bdf-addr = <0x4c400000>;
status = "ok";
};
&wifi1 {
// QCN6102
qcom,multipd_arch;
qcom,rproc = <&q6_wcss_pd2>;
qcom,userpd-subsys-name = "q6v5_wcss_userpd2";
qcom,board_id = <0x60>;
// qcom,ath11k-fw-memory-mode = <0>;
// qcom,bdf-addr = <0x4d500000>;
// qcom,caldb-addr = <0x4e500000>;
// qcom,m3-dump-addr = <0x4ea00000>;
qcom,ath11k-fw-memory-mode = <2>;
qcom,bdf-addr = <0x4d100000>;
qcom,m3-dump-addr = <0x4df00000>;
status = "ok";
};

View File

@ -0,0 +1,511 @@
// SPDX-License-Identifier: (GPL-2.0+)
/dts-v1/;
#include "ipq5018.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
model = "Xiaomi CR881x";
compatible = "xiaomi,cr881x", "qcom,ipq5018";
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&intc>;
aliases {
serial0 = &blsp1_uart1;
ethernet0 = &mac0;
ethernet1 = &mac1;
led-boot = &led_system_blue;
led-failsafe = &led_system_red;
led-running = &led_system_blue;
led-upgrade = &led_system_red;
};
chosen {
// Override the root parameter from u-boot
// Increase coherent_pool size for WiFi
bootargs-append = " root=/dev/ubiblock0_1 coherent_pool=2M";
stdout-path = "serial0:115200n8";
};
reserved-memory {
// Not sure why but without this, WiFi will crash
tz_apps@4a400000 {
no-map;
// The size is incorrent, but it works
reg = <0x0 0x4a400000 0x0 0x700000>;
};
q6_mem_regions: q6_mem_regions@4b000000 {
no-map;
// reg = <0x0 0x4b000000 0x0 0x3b00000>;
reg = <0x0 0x4b000000 0x0 0x3000000>;
};
};
thermal-zones {
status = "ok";
};
};
&tlmm {
blsp_uart0_pins: blsp_uart0_pins {
pins =
"gpio20", // RX
"gpio21"; // TX
function = "blsp0_uart0";
drive-strength = <8>;
bias-disable;
};
qspi_nand_pins: qspi_nand_pins {
clock {
pins = "gpio9";
function = "qspi_clk";
drive-strength = <8>;
bias-disable;
};
cs {
pins = "gpio8";
function = "qspi_cs";
drive-strength = <8>;
bias-disable;
};
data0 {
pins = "gpio7";
function = "qspi0";
drive-strength = <8>;
bias-disable;
};
data1 {
pins = "gpio6";
function = "qspi1";
drive-strength = <8>;
bias-disable;
};
data2 {
pins = "gpio5";
function = "qspi2";
drive-strength = <8>;
bias-disable;
};
data3 {
pins = "gpio4";
function = "qspi3";
drive-strength = <8>;
bias-disable;
};
};
mdio1_pins: mdio1_pins {
mdc {
pins = "gpio36";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mdio {
pins = "gpio37";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
};
leds_pins: leds_pins {
led_system_blue {
pins = "gpio24";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_system_red {
pins = "gpio25";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_internet_blue {
pins = "gpio26";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_internet_red {
pins = "gpio27";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
button_pins: button_pins {
button_reset {
pins = "gpio38";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
button_mesh {
pins = "gpio28";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
};
&blsp1_uart1 {
pinctrl-0 = <&blsp_uart0_pins>;
pinctrl-names = "default";
status = "ok";
};
&qpic_bam {
status = "ok";
};
&nand {
pinctrl-0 = <&qspi_nand_pins>;
pinctrl-names = "default";
status = "ok";
};
&soc {
leds {
compatible = "gpio-leds";
pinctrl-0 = <&leds_pins>;
pinctrl-names = "default";
led_system_blue: led_system_blue {
label = "blue:system";
gpio = <&tlmm 24 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
led_system_red: led_system_red {
label = "red:system";
gpio = <&tlmm 25 GPIO_ACTIVE_HIGH>;
};
led_internet_blue: led_internet_blue {
label = "blue:internet";
gpio = <&tlmm 26 GPIO_ACTIVE_HIGH>;
};
led_internet_red: led_internet_red {
label = "red:internet";
gpio = <&tlmm 27 GPIO_ACTIVE_HIGH>;
};
};
button {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
button_reset {
label = "reset";
gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
linux,input-type = <EV_KEY>;
linux,code = <KEY_RESTART>;
debounce-interval = <60>;
};
button_mesh {
label = "mesh";
gpios = <&tlmm 28 GPIO_ACTIVE_LOW>;
linux,input-type = <EV_KEY>;
linux,code = <KEY_WPS_BUTTON>;
debounce-interval = <60>;
};
};
ess-instance {
num_devices = <1>;
// Dummy switch, to describe how the external ports connects to the MAC
// For example, some chips have PSGMII ports which combine 5 MAC into
// 1 external port.
// For IPQ50xx, this is used to choose SGMII or SGMII-plus
ess-switch@0x39c00000 {
compatible = "qcom,ess-switch-ipq50xx";
device_id = <0>;
cmnblk_clk = "internal_96MHz";
// MAC1 Mode
switch_mac_mode = <0xc>; // PORT_WRAPPER_SGMII_PLUS
// switch_mac_mode = <0xf>; // PORT_WRAPPER_SGMII_CHANNEL0
qcom,port_phyinfo {
// MAC0 -> GE Phy -> YT9215 Phy4
port@0 {
port_id = <1>;
mdiobus = <&mdio0>;
phy_address = <7>;
phy_dac = <0x10 0x10>;
};
// MAC1 ---SGMII---> YT9215 SerDes
port@1 {
port_id = <2>;
forced-speed = <2500>;
forced-duplex = <1>;
};
};
};
};
// MAC0 -> GE Phy
mac0: dp1 {
compatible = "qcom,nss-dp";
device_type = "network";
qcom,id = <1>;
reg = <0x39C00000 0x10000>;
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_SNOC_GMAC0_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,mactype = <2>; // GMAC_HAL_TYPE_SYN_GMAC
local-mac-address = [000000000000];
phy-handle = <&ge_phy>;
phy-mode = "internal";
};
// MAC1 ---SGMII---> YT9215 SerDes
mac1: dp2 {
compatible = "qcom,nss-dp";
device_type = "network";
qcom,id = <2>;
reg = <0x39D00000 0x10000>;
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_SNOC_GMAC1_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,mactype = <2>; // GMAC_HAL_TYPE_SYN_GMAC
local-mac-address = [000000000000];
phy-mode = "2500base-x";
};
};
&mdio0 {
status = "ok";
resets = <&gcc GCC_GEPHY_MDC_SW_ARES>;
reset-names = "phy";
// IPQ5018 GE Phy -> YT9215 Phy4
ge_phy: ethernet-phy@0 {
reg = <7>;
};
};
&mdio1 {
pinctrl-0 = <&mdio1_pins>;
pinctrl-names = "default";
status = "ok";
// Motorcomm YT9215
yt9215: switch@1d {
compatible = "motorcomm,yt9215-smi";
reg = <29>;
switchid = <0>;
reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;
reset-assert-us = <10000>; /* 10ms */
reset-deassert-us = <50000>; /* 50ms */
ports {
// MAC0 -> Phy0 -> LAN1
port@0 {
reg = <0>;
};
// MAC1 -> Phy1 -> LAN2
port@1 {
reg = <1>;
};
// MAC2 -> Phy2 -> LAN3
port@2 {
reg = <2>;
};
// MAC3 -> Phy3 -> WAN
port@3 {
reg = <3>;
};
// MAC4 -> Phy4 -> IPQ5018 GE Phy
port@4 {
reg = <4>;
};
// MAC8 ---SGMII+---> IPQ5018 MAC1
port@8 {
reg = <8>;
phy-mode = "2500base-x";
fixed-link {
speed = <2500>;
full-duplex;
};
};
};
};
};
&q6v5_wcss {
memory-region = <&q6_mem_regions>;
qcom,rproc = <&q6v5_wcss>;
firmware = "IPQ5018/q6_fw.mdt";
qcom,bootargs_smem = <507>;
boot-args = </* type: */ 0x2 /* PCIE1 */
/* length: */ 4
/* PD id: */ 2
/* reset GPIO: */ 18
/* reserved: */ 0 0>;
status = "ok";
// IPQ5018
q6_wcss_pd1: remoteproc_pd1@4ab000 {
compatible = "qcom,ipq5018-wcss-ahb-mpd";
resets =
<&gcc GCC_WCSSAON_RESET>,
<&gcc GCC_WCSS_BCR>,
<&gcc GCC_CE_BCR>;
reset-names =
"wcss_aon_reset",
"wcss_reset",
"ce_reset";
clocks =
<&gcc GCC_WCSS_AHB_S_CLK>,
<&gcc GCC_WCSS_ACMT_CLK>,
<&gcc GCC_WCSS_AXI_M_CLK>;
clock-names =
"gcc_wcss_ahb_s_clk",
"gcc_wcss_acmt_clk",
"gcc_wcss_axi_m_clk";
reg = <0x4ab000 0x20>;
reg-names = "rmb";
// qcom,halt-regs = <&tcsr_q6_block 0xa000 0xd000 0x0>;
interrupts-extended =
<&wcss_smp2p_in 8 0>,
<&wcss_smp2p_in 9 0>,
<&wcss_smp2p_in 12 0>,
<&wcss_smp2p_in 11 0>;
interrupt-names =
"fatal",
"ready",
"spawn-ack",
"stop-ack";
qcom,smem-states =
<&wcss_smp2p_out 8>,
<&wcss_smp2p_out 9>,
<&wcss_smp2p_out 10>;
qcom,smem-state-names =
"shutdown",
"stop",
"spawn";
firmware = "IPQ5018/q6_fw.mdt";
m3_firmware = "IPQ5018/m3_fw.mdt";
};
// QCN6102
q6_wcss_pd2: remoteproc_pd2 {
compatible = "qcom,ipq5018-wcss-pcie-mpd";
interrupts-extended =
<&wcss_smp2p_in 16 0>,
<&wcss_smp2p_in 17 0>,
<&wcss_smp2p_in 20 0>,
<&wcss_smp2p_in 19 0>;
interrupt-names =
"fatal",
"ready",
"spawn-ack",
"stop-ack";
qcom,smem-states =
<&wcss_smp2p_out 16>,
<&wcss_smp2p_out 17>,
<&wcss_smp2p_out 18>;
qcom,smem-state-names =
"shutdown",
"stop",
"spawn";
firmware = "IPQ5018/q6_fw.mdt";
m3_firmware = "qcn6122/m3_fw.mdt";
};
};
&wifi0 {
// IPQ5018
qcom,multipd_arch;
qcom,rproc = <&q6_wcss_pd1>;
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
qcom,board_id = <0x23>;
// qcom,ath11k-fw-memory-mode = <0>;
// qcom,bdf-addr = <0x4c400000>;
// qcom,caldb-addr = <0x4d200000>;
// qcom,m3-dump-addr = <0x4d400000>;
qcom,ath11k-fw-memory-mode = <2>;
qcom,bdf-addr = <0x4c400000>;
status = "ok";
};
&wifi1 {
// QCN6102
qcom,multipd_arch;
qcom,rproc = <&q6_wcss_pd2>;
qcom,userpd-subsys-name = "q6v5_wcss_userpd2";
qcom,board_id = <0x60>;
// qcom,ath11k-fw-memory-mode = <0>;
// qcom,bdf-addr = <0x4d500000>;
// qcom,caldb-addr = <0x4e500000>;
// qcom,m3-dump-addr = <0x4ea00000>;
qcom,ath11k-fw-memory-mode = <2>;
qcom,bdf-addr = <0x4d100000>;
qcom,m3-dump-addr = <0x4df00000>;
status = "ok";
};

View File

@ -31,4 +31,61 @@ define Device/UbiFit
IMAGE/nand-sysupgrade.bin := sysupgrade-tar | append-metadata
endef
define Device/cmcc_rax3000q
$(call Device/FitImage)
$(call Device/UbiFit)
SOC := ipq5000
DEVICE_VENDOR := CMCC
DEVICE_MODEL := RAX3000Q
BLOCKSIZE := 128k
PAGESIZE := 2048
DEVICE_DTS_CONFIG := config@mp02.1
IMAGES := nand-factory.ubi
DEVICE_PACKAGES := \
ath11k-firmware-ipq5018 \
ath11k-firmware-qcn6122 \
ipq-wifi-cmcc_rax3000q
endef
TARGET_DEVICES += cmcc_rax3000q
define Device/redmi_ax3000
$(call Device/FitImage)
$(call Device/UbiFit)
SOC := ipq5000
DEVICE_VENDOR := Redmi
DEVICE_MODEL := AX3000
DEVICE_ALT0_VENDOR := Xiaomi
DEVICE_ALT0_MODEL := CR880x
DEVICE_ALT0_VARIANT := (M81 version)
DEVICE_ALT1_VENDOR := Xiaomi
DEVICE_ALT1_MODEL := CR880x
DEVICE_ALT1_VARIANT := (M79 version)
BLOCKSIZE := 128k
PAGESIZE := 2048
DEVICE_DTS_CONFIG := config@mp02.1
IMAGES := nand-factory.ubi
DEVICE_PACKAGES := \
ath11k-firmware-ipq5018 \
ath11k-firmware-qcn6122 \
ipq-wifi-redmi_ax3000
endef
TARGET_DEVICES += redmi_ax3000
define Device/xiaomi_cr881x
$(call Device/FitImage)
$(call Device/UbiFit)
SOC := ipq5018
DEVICE_VENDOR := Xiaomi
DEVICE_MODEL := CR881x
BLOCKSIZE := 128k
PAGESIZE := 2048
DEVICE_DTS_CONFIG := config@mp03.3
IMAGES := nand-factory.ubi
DEVICE_PACKAGES := \
ath11k-firmware-ipq5018 \
ath11k-firmware-qcn6122 \
ipq-wifi-xiaomi_cr881x
endef
TARGET_DEVICES += xiaomi_cr881x
$(eval $(call BuildImage))

View File

@ -0,0 +1,26 @@
From 41d22a684adaaa54f379cd087a73aaa1859415fc Mon Sep 17 00:00:00 2001
From: hzy <hzyitc@outlook.com>
Date: Thu, 13 Jun 2024 22:09:57 +0800
Subject: [PATCH 1/1] mtd: rawnand: winbond: add support for W25N01GW
---
drivers/mtd/nand/raw/nand_ids.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c
index fd64d9f..0f1ef87 100644
--- a/drivers/mtd/nand/raw/nand_ids.c
+++ b/drivers/mtd/nand/raw/nand_ids.c
@@ -74,6 +74,9 @@ struct nand_flash_dev nand_flash_ids[] = {
{"GD5F1GQ5REYIH SPI NAND 1G 1.8V",
{ .id = {0xc8, 0x21} },
SZ_2K, SZ_128, SZ_128K, 0, 2, 64, NAND_ECC_INFO(4, SZ_512) },
+ {"W25N01GW SPI NAND 1.8V 1G-BIT",
+ { .id = {0xef, 0xba} },
+ SZ_2K, SZ_128, SZ_128K, 0, 2, 64, NAND_ECC_INFO(4, SZ_512) },
{"W25N01JW SPI NAND 1.8V 1G-BIT",
{ .id = {0xef, 0xbc} },
SZ_2K, SZ_128, SZ_128K, 0, 2, 64, NAND_ECC_INFO(4, SZ_512) },
--
2.40.1