├── .github
└── workflows
│ ├── build-bcm27xx-bcm2711-minimal-23-05-sanpshot.yml
│ ├── build-x86_64-generic-minimal-22-03-snapshot.yml
│ ├── packges-update.yml
│ ├── stale.yml
│ └── sync_issues.yml
├── .gitignore
├── .version
├── configs
├── bcm27xx_bcm2711_22_03_3_minimal
├── bcm27xx_bcm2711_22_03_snapshot_minimal
├── bcm27xx_bcm2711_23_05_5_minimal
├── bcm27xx_bcm2711_23_05_snapshot_minimal
├── x86_64_generic_22_03_3_minimal
└── x86_64_generic_22_03_snapshot_minimal
├── openwrt
├── configs
│ ├── bcm27xx_bcm2711_minimal_22_03_defconfig
│ ├── bcm27xx_bcm2711_minimal_23_05_defconfig
│ └── x86_64_generic_minimal_22_03_deconfig
├── files
│ ├── bcm27xx
│ │ └── bcm2711
│ │ │ ├── entertainment
│ │ │ └── etc
│ │ │ │ ├── 15-automount
│ │ │ │ └── uci-defaults
│ │ │ │ └── luci-base
│ │ │ └── minimal
│ │ │ └── etc
│ │ │ └── config
│ │ │ ├── firewall
│ │ │ ├── luci
│ │ │ └── network
│ ├── readme.md
│ └── x86
│ │ └── 64
│ │ └── minimal
│ │ └── etc
│ │ └── config
│ │ ├── firewall
│ │ ├── luci
│ │ └── network
├── packages
│ ├── README.md
│ ├── luci-app-cifs-mount
│ │ ├── Makefile
│ │ ├── luasrc
│ │ │ ├── controller
│ │ │ │ └── cifs.lua
│ │ │ └── model
│ │ │ │ └── cbi
│ │ │ │ └── cifs.lua
│ │ ├── po
│ │ │ └── zh-cn
│ │ │ │ └── cifs.po
│ │ └── root
│ │ │ └── etc
│ │ │ ├── config
│ │ │ └── cifs
│ │ │ ├── init.d
│ │ │ └── cifs
│ │ │ └── uci-defaults
│ │ │ └── luci-cifs
│ ├── luci-app-fileassistant
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── htdocs
│ │ │ └── luci-static
│ │ │ │ └── resources
│ │ │ │ └── fileassistant
│ │ │ │ ├── fb.css
│ │ │ │ ├── fb.js
│ │ │ │ ├── file-icon.png
│ │ │ │ ├── folder-icon.png
│ │ │ │ └── link-icon.png
│ │ └── luasrc
│ │ │ ├── controller
│ │ │ └── fileassistant.lua
│ │ │ └── view
│ │ │ └── fileassistant.htm
│ ├── luci-app-homeassistant
│ │ ├── Makefile
│ │ └── root
│ │ │ └── usr
│ │ │ └── share
│ │ │ ├── luci
│ │ │ └── menu.d
│ │ │ │ └── luci-app-homeassistant.json
│ │ │ └── rpcd
│ │ │ └── acl.d
│ │ │ └── luci-app-homeassistant.json
│ ├── luci-app-node-red
│ │ ├── Makefile
│ │ ├── htdocs
│ │ │ └── luci-static
│ │ │ │ └── resources
│ │ │ │ └── view
│ │ │ │ └── node-red.js
│ │ └── root
│ │ │ └── usr
│ │ │ ├── libexec
│ │ │ └── node-red-ctrl
│ │ │ └── share
│ │ │ ├── luci
│ │ │ └── menu.d
│ │ │ │ └── luci-app-node-red.json
│ │ │ └── rpcd
│ │ │ └── acl.d
│ │ │ └── luci-app-node-red.json
│ ├── luci-app-syncdial
│ │ ├── Makefile
│ │ ├── luasrc
│ │ │ ├── controller
│ │ │ │ └── syncdial.lua
│ │ │ ├── model
│ │ │ │ └── cbi
│ │ │ │ │ └── syncdial.lua
│ │ │ └── view
│ │ │ │ └── syncdial
│ │ │ │ └── redial_button.htm
│ │ └── root
│ │ │ ├── bin
│ │ │ └── genwancfg
│ │ │ └── etc
│ │ │ ├── config
│ │ │ └── syncdial
│ │ │ ├── hotplug.d
│ │ │ └── iface
│ │ │ │ ├── 01-dialcheck
│ │ │ │ └── 01-mvifcreate
│ │ │ └── uci-defaults
│ │ │ └── luci-syncdial
│ ├── ntfs3-mount
│ │ ├── Makefile
│ │ └── files
│ │ │ └── mount.ntfs
│ ├── ntfs3-oot
│ │ ├── Makefile
│ │ └── patches
│ │ │ └── 100-compat-mount.patch
│ └── packages.list
├── patches
│ └── 0001-lan78xx-fixed-bandwitdh-and-throughput.patch
└── scripts
│ └── readme.md
├── readme.md
├── requirements.txt
└── scripts
├── build.py
└── fetch_packages.py
/.github/workflows/build-bcm27xx-bcm2711-minimal-23-05-sanpshot.yml:
--------------------------------------------------------------------------------
1 | name: Build BCM2711 Minimal OpenWrt-23.05-snapshot
2 | on:
3 | repository_dispatch:
4 | types: [openwrt]
5 | workflow_dispatch:
6 | schedule:
7 | - cron: 0 9 * * 1-5
8 |
9 | env:
10 | BUILD_CONFIG_FILE: bcm27xx_bcm2711_23_05_snapshot_minimal
11 | TARGET: bcm27xx
12 | SUBTARGET: bcm2711
13 | OPENWRT_VERSION: openwrt-23.05
14 | TYPE: minimal
15 |
16 |
17 | jobs:
18 | Build:
19 | runs-on: ubuntu-20.04
20 | steps:
21 | - name: Checkout
22 | uses: actions/checkout@v3
23 | with:
24 | ref: "main"
25 | fetch-depth: 2
26 | - name: Setup Environment
27 | run: |
28 | sudo rm -rf /etc/apt/sources.list.d/* /usr/share/dotnet /usr/local/lib/android /opt/ghc
29 | sudo -E apt-get -qq update
30 | sudo -E apt-get -qq install $(curl -fsSL git.io/depends-ubuntu-2004) tree
31 | sudo -E apt-get -qq install jq
32 | sudo -E apt-get -qq autoremove --purge
33 | sudo -E apt-get -qq clean
34 | sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
35 | git config --global user.name "I'm a Code Bot"
36 | git config --global user.email "baozhu.zuo@gmail.com"
37 | pip3 install -r requirements.txt
38 | - name: Create
39 | run: |
40 | python3 ./scripts/build.py --config configs/${{ env.BUILD_CONFIG_FILE }} --action create
41 | - name: Feeds
42 | run: |
43 | python3 ./scripts/build.py --config configs/${{ env.BUILD_CONFIG_FILE }} --action feeds
44 | - name: Config
45 | run: |
46 | python3 ./scripts/build.py --config configs/${{ env.BUILD_CONFIG_FILE }} --action config
47 | - name: Download
48 | run: |
49 | python3 ./scripts/build.py --config configs/${{ env.BUILD_CONFIG_FILE }} --action download
50 | - name: Compile
51 | run: |
52 | python3 ./scripts/build.py --config configs/${{ env.BUILD_CONFIG_FILE }} --action compile
53 | - name: Install
54 | run: |
55 | python3 ./scripts/build.py --config configs/${{ env.BUILD_CONFIG_FILE }} --action install
56 |
57 | - name: Upload Image
58 | uses: actions/upload-artifact@main
59 | with:
60 | name: ${{ env.BUILD_CONFIG_FILE }}
61 | path: |
62 | ./build/${{env.OPENWRT_VERSION}}/bin/targets/${{ env.TARGET }}/${{ env.SUBTARGET }}/
63 | retention-days: 7
64 |
65 | Upload:
66 | needs: [Build]
67 | runs-on: ubuntu-20.04
68 |
69 | steps:
70 | - name: Checkout
71 | uses: actions/checkout@v3
72 | with:
73 | ref: "main"
74 | fetch-depth: 2
75 | - name: Setup Environment
76 | run: |
77 | curl https://rclone.org/install.sh | sudo bash
78 |
79 | - name: Download Bin Folder
80 | uses: actions/download-artifact@main
81 | with:
82 | name: ${{ env.BUILD_CONFIG_FILE }}
83 | path: ./build/bin
84 |
85 | - name: Upload Image to OneDrive
86 | env:
87 | RCLONE_PACKAGE: ${{ secrets.ONEDRIVE_NAME }}
88 | run: |
89 | mkdir -p ~/.config/rclone/
90 | cat << EOF > /tmp/rclone.de
91 | ${{ secrets.ONEDRIVE_CONF }}
92 | EOF
93 | base64 -d /tmp/rclone.de > ~/.config/rclone/rclone.conf
94 | echo "# Rclone Packages Upload Rule" >> /tmp/upload-rule.txt
95 | echo "- openwrt*" >> /tmp/upload-rule.txt
96 | echo "- sha256sums" >> /tmp/upload-rule.txt
97 | echo "- packages-server.zip" >> /tmp/upload-rule.txt
98 | echo "- *.buildinfo" >> /tmp/upload-rule.txt
99 | echo "+ openwrt-keyring*" >> /tmp/upload-rule.txt
100 | rclone mkdir $RCLONE_PACKAGE:Openwrt/${{env.OPENWRT_VERSION}}/$(date +"%Y-%m-%d")/${{ env.TARGET }}/${{ env.SUBTARGET }}/${{ env.TYPE }}
101 | rclone copy ./build/bin $RCLONE_PACKAGE:Openwrt/${{env.OPENWRT_VERSION}}/$(date +"%Y-%m-%d")/${{ env.TARGET }}/${{ env.SUBTARGET }}/${{ env.TYPE }}
102 | echo "::notice file=Firmware-OneDrive::Download Link: https://1drv.ms/u/s!AqG2uRmVUhlSh0NHMLMmQKLyASvi?e=mup3cd"
103 |
--------------------------------------------------------------------------------
/.github/workflows/build-x86_64-generic-minimal-22-03-snapshot.yml:
--------------------------------------------------------------------------------
1 | name: Build X86_64_Genreic Minimal OpenWrt-22.03-snapshot
2 | on:
3 | repository_dispatch:
4 | types: [openwrt]
5 | workflow_dispatch:
6 | schedule:
7 | - cron: 0 9 * * 1-5
8 |
9 | env:
10 | BUILD_CONFIG_FILE: x86_64_generic_22_03_snapshot_minimal
11 | TARGET: x86
12 | SUBTARGET: 64
13 | OPENWRT_VERSION: openwrt-22.03
14 | TYPE: minimal
15 |
16 |
17 | jobs:
18 | Build:
19 | runs-on: ubuntu-20.04
20 | steps:
21 | - name: Checkout
22 | uses: actions/checkout@v3
23 | with:
24 | ref: "main"
25 | fetch-depth: 2
26 | - name: Setup Environment
27 | run: |
28 | sudo rm -rf /etc/apt/sources.list.d/* /usr/share/dotnet /usr/local/lib/android /opt/ghc
29 | sudo -E apt-get -qq update
30 | sudo -E apt-get -qq install $(curl -fsSL git.io/depends-ubuntu-2004) tree
31 | sudo -E apt-get -qq install jq
32 | sudo -E apt-get -qq autoremove --purge
33 | sudo -E apt-get -qq clean
34 | sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
35 | git config --global user.name "I'm a Code Bot"
36 | git config --global user.email "baozhu.zuo@gmail.com"
37 | pip3 install -r requirements.txt
38 | - name: Create
39 | run: |
40 | python3 ./scripts/build.py --config configs/${{ env.BUILD_CONFIG_FILE }} --action create
41 | - name: Feeds
42 | run: |
43 | python3 ./scripts/build.py --config configs/${{ env.BUILD_CONFIG_FILE }} --action feeds
44 | - name: Config
45 | run: |
46 | python3 ./scripts/build.py --config configs/${{ env.BUILD_CONFIG_FILE }} --action config
47 | - name: Download
48 | run: |
49 | python3 ./scripts/build.py --config configs/${{ env.BUILD_CONFIG_FILE }} --action download
50 | - name: Compile
51 | run: |
52 | python3 ./scripts/build.py --config configs/${{ env.BUILD_CONFIG_FILE }} --action compile
53 | - name: Install
54 | run: |
55 | python3 ./scripts/build.py --config configs/${{ env.BUILD_CONFIG_FILE }} --action install
56 |
57 | - name: Upload Image
58 | uses: actions/upload-artifact@main
59 | with:
60 | name: ${{ env.BUILD_CONFIG_FILE }}
61 | path: |
62 | ./build/${{ env.OPENWRT_VERSION }}/bin/targets/${{ env.TARGET }}/${{ env.SUBTARGET }}/
63 | retention-days: 7
64 |
65 | Upload:
66 | needs: [Build]
67 | runs-on: ubuntu-20.04
68 |
69 | steps:
70 | - name: Checkout
71 | uses: actions/checkout@v3
72 | with:
73 | ref: "main"
74 | fetch-depth: 2
75 | - name: Setup Environment
76 | run: |
77 | curl https://rclone.org/install.sh | sudo bash
78 |
79 | - name: Download Bin Folder
80 | uses: actions/download-artifact@main
81 | with:
82 | name: ${{ env.BUILD_CONFIG_FILE }}
83 | path: ./build/bin
84 |
85 | - name: Upload Image to OneDrive
86 | env:
87 | RCLONE_PACKAGE: ${{ secrets.ONEDRIVE_NAME }}
88 | run: |
89 | mkdir -p ~/.config/rclone/
90 | cat << EOF > /tmp/rclone.de
91 | ${{ secrets.ONEDRIVE_CONF }}
92 | EOF
93 | base64 -d /tmp/rclone.de > ~/.config/rclone/rclone.conf
94 | echo "# Rclone Packages Upload Rule" >> /tmp/upload-rule.txt
95 | echo "- openwrt*" >> /tmp/upload-rule.txt
96 | echo "- sha256sums" >> /tmp/upload-rule.txt
97 | echo "- packages-server.zip" >> /tmp/upload-rule.txt
98 | echo "- *.buildinfo" >> /tmp/upload-rule.txt
99 | echo "+ openwrt-keyring*" >> /tmp/upload-rule.txt
100 | rclone mkdir $RCLONE_PACKAGE:Openwrt/${{env.OPENWRT_VERSION}}/$(date +"%Y-%m-%d")/${{ env.TARGET }}/${{ env.SUBTARGET }}/${{ env.TYPE }}
101 | rclone copy ./build/bin $RCLONE_PACKAGE:Openwrt/${{env.OPENWRT_VERSION}}/$(date +"%Y-%m-%d")/${{ env.TARGET }}/${{ env.SUBTARGET }}/${{ env.TYPE }}
102 | echo "::notice file=Firmware-OneDrive::Download Link: https://1drv.ms/u/s!AqG2uRmVUhlSh0NHMLMmQKLyASvi?e=mup3cd"
103 |
--------------------------------------------------------------------------------
/.github/workflows/packges-update.yml:
--------------------------------------------------------------------------------
1 | name: Packages update
2 | on:
3 | repository_dispatch:
4 | types: [openwrt]
5 | workflow_dispatch:
6 | schedule:
7 | - cron: 0 0 * * 1,2
8 |
9 | jobs:
10 | update:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout
14 | uses: actions/checkout@v2
15 | with:
16 | reff: "main"
17 | fetch-depth: 2
18 | - name: Setup Environment
19 | run: |
20 | sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
21 | git config --global user.name "I'm a Code Bot"
22 | git config --global user.email "baozhu.zuo@gmail.com"
23 | pip3 install -r requirements.txt
24 | - name: Fetch Packages
25 | run: |
26 | python3 ./scripts/fetch_packages.py --list ./openwrt/packages/packages.list
27 |
28 | - name: Push Packages
29 | uses: ad-m/github-push-action@master
30 | with:
31 | github_token: ${{ secrets.GITHUB_TOKEN }}
32 | branch: "packages"
33 | directory: "/tmp/packages"
34 | repository: "Seeed-Studio/seeed-linux-openwrt"
35 | force: true
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: 'Close stale issues and PRs'
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: '0 4 * * *'
7 |
8 | jobs:
9 | stale:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - name: Checkout repository
14 | uses: actions/checkout@v4
15 |
16 | - name: Checkout script repository
17 | uses: actions/checkout@v4
18 | with:
19 | repository: Seeed-Studio/sync-github-all-issues
20 | path: ci
21 |
22 | - name: Run script
23 | run: ./ci/tools/stale.sh
24 | env:
25 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
26 |
--------------------------------------------------------------------------------
/.github/workflows/sync_issues.yml:
--------------------------------------------------------------------------------
1 | name: Automate Issue Management
2 |
3 | on:
4 | issues:
5 | types:
6 | - opened
7 | - edited
8 | - assigned
9 | - unassigned
10 | - labeled
11 | - unlabeled
12 | - reopened
13 |
14 | jobs:
15 | add_issue_to_project:
16 | runs-on: ubuntu-latest
17 | steps:
18 | - name: Add issue to GitHub Project
19 | uses: actions/add-to-project@v1.0.2
20 | with:
21 | project-url: https://github.com/orgs/Seeed-Studio/projects/17
22 | github-token: ${{ secrets.ISSUE_ASSEMBLE }}
23 | labeled: bug
24 | label-operator: NOT
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | build
3 | dl
4 | bin
--------------------------------------------------------------------------------
/.version:
--------------------------------------------------------------------------------
1 | 0.0.1rc
--------------------------------------------------------------------------------
/configs/bcm27xx_bcm2711_22_03_3_minimal:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bcm27xx_bcm2711_22_03_snapshot_minimal",
3 | "description": "Minimal openwrt v22.03.3 config for bcm2711",
4 | "target": "bcm27xx",
5 | "subtarget": "bcm2711",
6 | "version": "v22.03.3",
7 | "config": "bcm27xx_bcm2711_minimal_22_03_defconfig",
8 | "files": ["minimal"],
9 | "patches": [
10 | "0001-lan78xx-fixed-bandwitdh-and-throughput.patch"
11 | ],
12 | "feeds": [],
13 | "action": {
14 | "prefeeds": null,
15 | "postfeeds": null,
16 | "preconfig": null,
17 | "postconfig": null,
18 | "predownload": null,
19 | "postdownload": null,
20 | "precompile": null,
21 | "postcompile": null,
22 | "preinstall": null,
23 | "postinstall": null
24 | }
25 | }
--------------------------------------------------------------------------------
/configs/bcm27xx_bcm2711_22_03_snapshot_minimal:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bcm27xx_bcm2711_22_03_snapshot_minimal",
3 | "description": "Minimal openwrt-22.03 snapshot config for bcm2711",
4 | "target": "bcm27xx",
5 | "subtarget": "bcm2711",
6 | "version": "openwrt-22.03",
7 | "config": "bcm27xx_bcm2711_minimal_22_03_defconfig",
8 | "files": ["minimal"],
9 | "patches": [
10 | "0001-lan78xx-fixed-bandwitdh-and-throughput.patch"
11 | ],
12 | "feeds": [],
13 | "action": {
14 | "prefeeds": null,
15 | "postfeeds": null,
16 | "preconfig": null,
17 | "postconfig": null,
18 | "predownload": null,
19 | "postdownload": null,
20 | "precompile": null,
21 | "postcompile": null,
22 | "preinstall": null,
23 | "postinstall": null
24 | }
25 | }
--------------------------------------------------------------------------------
/configs/bcm27xx_bcm2711_23_05_5_minimal:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bcm27xx_bcm2711_23_05_snapshot_minimal",
3 | "description": "Minimal openwrt v23.05.5 config for bcm2711",
4 | "target": "bcm27xx",
5 | "subtarget": "bcm2711",
6 | "version": "v23.05.5",
7 | "config": "bcm27xx_bcm2711_minimal_23_05_defconfig",
8 | "files": ["minimal"],
9 | "patches": [],
10 | "feeds": [],
11 | "action": {
12 | "prefeeds": null,
13 | "postfeeds": null,
14 | "preconfig": null,
15 | "postconfig": null,
16 | "predownload": null,
17 | "postdownload": null,
18 | "precompile": null,
19 | "postcompile": null,
20 | "preinstall": null,
21 | "postinstall": null
22 | }
23 | }
--------------------------------------------------------------------------------
/configs/bcm27xx_bcm2711_23_05_snapshot_minimal:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bcm27xx_bcm2711_23_05_snapshot_minimal",
3 | "description": "Minimal openwrt v23.05 snapshot config for bcm2711",
4 | "target": "bcm27xx",
5 | "subtarget": "bcm2711",
6 | "version": "openwrt-23.05",
7 | "config": "bcm27xx_bcm2711_minimal_23_05_defconfig",
8 | "files": ["minimal"],
9 | "patches": [],
10 | "feeds": [],
11 | "action": {
12 | "prefeeds": null,
13 | "postfeeds": null,
14 | "preconfig": null,
15 | "postconfig": null,
16 | "predownload": null,
17 | "postdownload": null,
18 | "precompile": null,
19 | "postcompile": null,
20 | "preinstall": null,
21 | "postinstall": null
22 | }
23 | }
--------------------------------------------------------------------------------
/configs/x86_64_generic_22_03_3_minimal:
--------------------------------------------------------------------------------
1 | {
2 | "name": "x86_64_generic_22_03_snapshot_minimal",
3 | "description": "Minimal openwrt v22.03.3 config for x86_64 generic",
4 | "target": "x86",
5 | "subtarget": "64",
6 | "version": "v22.03.3",
7 | "config": "x86_64_generic_minimal_22_03_deconfig",
8 | "files": [
9 | "minimal"
10 | ],
11 | "patches": [],
12 | "feeds": [],
13 | "action": {
14 | "prefeeds": null,
15 | "postfeeds": null,
16 | "preconfig": null,
17 | "postconfig": null,
18 | "predownload": null,
19 | "postdownload": null,
20 | "precompile": null,
21 | "postcompile": null,
22 | "preinstall": null,
23 | "postinstall": null
24 | }
25 | }
--------------------------------------------------------------------------------
/configs/x86_64_generic_22_03_snapshot_minimal:
--------------------------------------------------------------------------------
1 | {
2 | "name": "x86_64_generic_22_03_snapshot_minimal",
3 | "description": "Minimal openwrt-22.03 snapshot config for x86_64 generic",
4 | "target": "x86",
5 | "subtarget": "64",
6 | "version": "openwrt-22.03",
7 | "config": "x86_64_generic_minimal_22_03_deconfig",
8 | "files": [
9 | "minimal"
10 | ],
11 | "patches": [],
12 | "feeds": [],
13 | "action": {
14 | "prefeeds": null,
15 | "postfeeds": null,
16 | "preconfig": null,
17 | "postconfig": null,
18 | "predownload": null,
19 | "postdownload": null,
20 | "precompile": null,
21 | "postcompile": null,
22 | "preinstall": null,
23 | "postinstall": null
24 | }
25 | }
--------------------------------------------------------------------------------
/openwrt/configs/bcm27xx_bcm2711_minimal_22_03_defconfig:
--------------------------------------------------------------------------------
1 | CONFIG_TARGET_bcm27xx=y
2 | CONFIG_TARGET_bcm27xx_bcm2711=y
3 | CONFIG_TARGET_bcm27xx_bcm2711_DEVICE_rpi-4=y
4 | CONFIG_PACKAGE_cgi-io=y
5 | CONFIG_PACKAGE_kmod-usb-ehci=y
6 | CONFIG_PACKAGE_kmod-usb-xhci-hcd=y
7 | CONFIG_PACKAGE_kmod-usb2=y
8 | CONFIG_PACKAGE_kmod-usb2-pci=y
9 | CONFIG_PACKAGE_kmod-usb3=y
10 | CONFIG_PACKAGE_libiwinfo-lua=y
11 | CONFIG_PACKAGE_liblua=y
12 | CONFIG_PACKAGE_liblucihttp=y
13 | CONFIG_PACKAGE_liblucihttp-lua=y
14 | CONFIG_PACKAGE_libubus-lua=y
15 | CONFIG_PACKAGE_lua=y
16 | CONFIG_PACKAGE_luci=y
17 | CONFIG_PACKAGE_luci-app-firewall=y
18 | CONFIG_PACKAGE_luci-app-opkg=y
19 | CONFIG_PACKAGE_luci-base=y
20 | CONFIG_PACKAGE_luci-lib-base=y
21 | CONFIG_PACKAGE_luci-lib-ip=y
22 | CONFIG_PACKAGE_luci-lib-jsonc=y
23 | CONFIG_PACKAGE_luci-lib-nixio=y
24 | CONFIG_PACKAGE_luci-mod-admin-full=y
25 | CONFIG_PACKAGE_luci-mod-network=y
26 | CONFIG_PACKAGE_luci-mod-status=y
27 | CONFIG_PACKAGE_luci-mod-system=y
28 | CONFIG_PACKAGE_luci-proto-ipv6=y
29 | CONFIG_PACKAGE_luci-proto-ppp=y
30 | CONFIG_PACKAGE_luci-theme-bootstrap=y
31 | CONFIG_PACKAGE_rpcd=y
32 | CONFIG_PACKAGE_rpcd-mod-file=y
33 | CONFIG_PACKAGE_rpcd-mod-iwinfo=y
34 | CONFIG_PACKAGE_rpcd-mod-luci=y
35 | CONFIG_PACKAGE_rpcd-mod-rrdns=y
36 | CONFIG_PACKAGE_uhttpd=y
37 | CONFIG_PACKAGE_uhttpd-mod-ubus=y
38 |
--------------------------------------------------------------------------------
/openwrt/configs/bcm27xx_bcm2711_minimal_23_05_defconfig:
--------------------------------------------------------------------------------
1 | CONFIG_TARGET_bcm27xx=y
2 | CONFIG_TARGET_bcm27xx_bcm2711=y
3 | CONFIG_TARGET_bcm27xx_bcm2711_DEVICE_rpi-4=y
4 | CONFIG_PACKAGE_cgi-io=y
5 | CONFIG_PACKAGE_kmod-usb-ehci=y
6 | CONFIG_PACKAGE_kmod-usb-xhci-hcd=y
7 | CONFIG_PACKAGE_kmod-usb2=y
8 | CONFIG_PACKAGE_kmod-usb2-pci=y
9 | CONFIG_PACKAGE_kmod-usb3=y
10 | CONFIG_PACKAGE_libiwinfo-lua=y
11 | CONFIG_PACKAGE_liblua=y
12 | CONFIG_PACKAGE_liblucihttp=y
13 | CONFIG_PACKAGE_liblucihttp-lua=y
14 | CONFIG_PACKAGE_libubus-lua=y
15 | CONFIG_PACKAGE_lua=y
16 | CONFIG_PACKAGE_luci=y
17 | CONFIG_PACKAGE_luci-app-firewall=y
18 | CONFIG_PACKAGE_luci-app-opkg=y
19 | CONFIG_PACKAGE_luci-base=y
20 | CONFIG_PACKAGE_luci-lib-base=y
21 | CONFIG_PACKAGE_luci-lib-ip=y
22 | CONFIG_PACKAGE_luci-lib-jsonc=y
23 | CONFIG_PACKAGE_luci-lib-nixio=y
24 | CONFIG_PACKAGE_luci-mod-admin-full=y
25 | CONFIG_PACKAGE_luci-mod-network=y
26 | CONFIG_PACKAGE_luci-mod-status=y
27 | CONFIG_PACKAGE_luci-mod-system=y
28 | CONFIG_PACKAGE_luci-proto-ipv6=y
29 | CONFIG_PACKAGE_luci-proto-ppp=y
30 | CONFIG_PACKAGE_luci-theme-bootstrap=y
31 | CONFIG_PACKAGE_rpcd=y
32 | CONFIG_PACKAGE_rpcd-mod-file=y
33 | CONFIG_PACKAGE_rpcd-mod-iwinfo=y
34 | CONFIG_PACKAGE_rpcd-mod-luci=y
35 | CONFIG_PACKAGE_rpcd-mod-rrdns=y
36 | CONFIG_PACKAGE_uhttpd=y
37 | CONFIG_PACKAGE_uhttpd-mod-ubus=y
38 |
--------------------------------------------------------------------------------
/openwrt/configs/x86_64_generic_minimal_22_03_deconfig:
--------------------------------------------------------------------------------
1 | CONFIG_TARGET_x86=y
2 | CONFIG_TARGET_x86_64=y
3 | CONFIG_TARGET_x86_64_DEVICE_generic=y
4 | CONFIG_GRUB_BAUDRATE=38400
5 | # CONFIG_PACKAGE_bnx2-firmware is not set
6 | CONFIG_PACKAGE_cgi-io=y
7 | CONFIG_PACKAGE_e100-firmware=y
8 | CONFIG_PACKAGE_kmod-3c59x=y
9 | CONFIG_PACKAGE_kmod-8139too=y
10 | # CONFIG_PACKAGE_kmod-bnx2 is not set
11 | CONFIG_PACKAGE_kmod-e100=y
12 | # CONFIG_PACKAGE_kmod-e1000e is not set
13 | # CONFIG_PACKAGE_kmod-hwmon-core is not set
14 | # CONFIG_PACKAGE_kmod-i2c-algo-bit is not set
15 | # CONFIG_PACKAGE_kmod-i2c-core is not set
16 | CONFIG_PACKAGE_kmod-igb=y
17 | CONFIG_PACKAGE_kmod-igc=y
18 | # CONFIG_PACKAGE_kmod-ixgbe is not set
19 | CONFIG_PACKAGE_kmod-natsemi=y
20 | CONFIG_PACKAGE_kmod-ne2k-pci=y
21 | CONFIG_PACKAGE_kmod-pcnet32=y
22 | CONFIG_PACKAGE_kmod-sis900=y
23 | CONFIG_PACKAGE_kmod-via-rhine=y
24 | CONFIG_PACKAGE_kmod-via-velocity=y
25 | CONFIG_PACKAGE_libiwinfo=y
26 | CONFIG_PACKAGE_libiwinfo-data=y
27 | CONFIG_PACKAGE_libiwinfo-lua=y
28 | CONFIG_PACKAGE_liblua=y
29 | CONFIG_PACKAGE_liblucihttp=y
30 | CONFIG_PACKAGE_liblucihttp-lua=y
31 | CONFIG_PACKAGE_libubus-lua=y
32 | CONFIG_PACKAGE_lua=y
33 | CONFIG_PACKAGE_luci=y
34 | CONFIG_PACKAGE_luci-app-firewall=y
35 | CONFIG_PACKAGE_luci-app-opkg=y
36 | CONFIG_PACKAGE_luci-base=y
37 | CONFIG_PACKAGE_luci-lib-base=y
38 | CONFIG_PACKAGE_luci-lib-ip=y
39 | CONFIG_PACKAGE_luci-lib-jsonc=y
40 | CONFIG_PACKAGE_luci-lib-nixio=y
41 | CONFIG_PACKAGE_luci-mod-admin-full=y
42 | CONFIG_PACKAGE_luci-mod-network=y
43 | CONFIG_PACKAGE_luci-mod-status=y
44 | CONFIG_PACKAGE_luci-mod-system=y
45 | CONFIG_PACKAGE_luci-proto-ipv6=y
46 | CONFIG_PACKAGE_luci-proto-ppp=y
47 | CONFIG_PACKAGE_luci-theme-bootstrap=y
48 | CONFIG_PACKAGE_rpcd=y
49 | CONFIG_PACKAGE_rpcd-mod-file=y
50 | CONFIG_PACKAGE_rpcd-mod-iwinfo=y
51 | CONFIG_PACKAGE_rpcd-mod-luci=y
52 | CONFIG_PACKAGE_rpcd-mod-rrdns=y
53 | CONFIG_PACKAGE_uhttpd=y
54 | CONFIG_PACKAGE_uhttpd-mod-ubus=y
55 |
--------------------------------------------------------------------------------
/openwrt/files/bcm27xx/bcm2711/entertainment/etc/15-automount:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set_fstab(){
4 |
5 | my_fstype="`block info | grep "/dev/$device" | awk -F 'TYPE="' '{print $2}' | sed 's/\"//'`"
6 |
7 | [ -n "$my_fstype" ] && {
8 | logger -t Auto-Mount "New block.File system:${my_fstype}"
9 | if [ "$my_fstype" = 'swap' ]; then
10 |
11 | n=$(uci show fstab | grep "fstab.@swap" | grep -c "=swap")
12 |
13 | [ $n -gt 0 ] && {
14 | for i in $(seq 0 $n)
15 | do
16 | old_swap="$(uci get fstab.@swap[$i].device)"
17 | [ "$old_swap" == "/dev/$device" ] && {
18 | FLAG="SKIP"
19 | break
20 | }
21 | done
22 | }
23 |
24 | [ "$FLAG" != "SKIP" ] && {
25 | uci add fstab swap
26 | uci set fstab.@swap[$n]="swap"
27 | uci set fstab.@swap[$n].enabled='1'
28 | uci set fstab.@swap[$n].device="/dev/$device"
29 | }
30 |
31 | else
32 | n=$(uci show fstab | grep "fstab.@mount" | grep -c "=mount")
33 |
34 | [ $n -gt 0 ] && {
35 | for i in $(seq 0 $n)
36 | do
37 | old_mount="$(uci get fstab.@mount[$i].uuid)"
38 | [ "$old_mount" == "${get_uuid}" ] && {
39 | FLAG="SKIP"
40 | break
41 | }
42 | done
43 | }
44 |
45 | [ "$FLAG" != "SKIP" ] && {
46 | uci add fstab mount
47 | uci set fstab.@mount[$n]="mount"
48 | uci set fstab.@mount[$n].enabled='1'
49 | uci set fstab.@mount[$n].uuid="${get_uuid}"
50 | uci set fstab.@mount[$n].target="/mnt/$device"
51 | uci set fstab.@mount[$n].fstype="$my_fstype"
52 |
53 | case "$my_fstype" in
54 | ext*)
55 | uci set fstab.@mount[$n].options="noatime"
56 | ;;
57 | 'ntfs')
58 | if [ $(lsmod | grep -c ufsd) -ge 1 ]
59 | then
60 | uci set fstab.@mount[$n].fstype="ufsd"
61 | uci set fstab.@mount[$n].options="noatime,nls=utf8,force"
62 | else
63 | uci set fstab.@mount[$n].fstype="ntfs-3g"
64 | uci set fstab.@mount[$n].options="noatime,iocharset=utf8,big_writes"
65 | fi
66 | ;;
67 | 'exfat')
68 | uci set fstab.@mount[$n].options="noatime"
69 | ;;
70 | 'vfat')
71 | uci set fstab.@mount[$n].options="iocharset=utf8,umask=0000,dmask=0000,fmask=0000"
72 | ;;
73 | *)
74 | uci revert fstab
75 | ;;
76 | esac
77 | }
78 | fi
79 | uci commit fstab
80 | }
81 | }
82 |
83 | del_fstab(){
84 |
85 | del_disk=$(uci show fstab | grep "/mnt/$device" | awk -F '[' '{print $2}' | awk -F ']' '{print $1}' | sort -r )
86 | [ -n "$del_disk" ] && {
87 | for i in $del_disk
88 | do
89 | uci delete fstab.@mount[$i]
90 | done
91 | uci commit fstab
92 | }
93 |
94 | }
95 |
96 | [ -e /etc/config/fstab ] || {
97 | block detect > /etc/config/fstab
98 | }
99 |
100 |
101 | [ -e /etc/config/fstab ] && {
102 | del_num=$(uci show fstab | grep ".enabled='0'" | awk -F '[' '{print $2}' | awk -F ']' '{print $1}' | sort -r )
103 | [ -n "$del_num" ] && {
104 | for i in $del_num
105 | do
106 | uci delete fstab.@mount[$i]
107 | done
108 | uci commit fstab
109 | }
110 | }
111 |
112 |
113 | blkdev=`dirname $DEVPATH`
114 |
115 |
116 | if [ `basename $blkdev` == "block" ]; then
117 | device=`basename $DEVPATH`
118 | mountpoint=`sed -ne "s|^[^ ]*/$device ||; T; s/ .*//p" /proc/self/mounts`
119 |
120 | case "$ACTION" in
121 | add)
122 | get_uuid=`block info | grep "/dev/${device}" | awk -F "UUID=" '{print $2}'| awk -F "\"" '{print $2}'`
123 |
124 | [ -n "$get_uuid" ] && {
125 |
126 | mounted=`mount -l | awk '{print $1}'`
127 | flag=0
128 | for dev_mounted in $mounted ; do
129 | if [ "/dev/${device}" == $dev_mounted ]; then
130 | flag=1
131 | fi
132 | done
133 |
134 | [ $flag != 1 ] && {
135 |
136 | logger -t Auto-Mount "Block /dev/${device} added."
137 | logger -t Auto-Mount "UUID=$get_uuid"
138 | have_uuid=$(uci show fstab | grep -c "$get_uuid")
139 |
140 | [ "$have_uuid" = "0" ] && {
141 | mkdir -p /mnt/$device
142 | chmod 777 /mnt/$device
143 | set_fstab
144 | block mount >> /dev/null 2>&1
145 | }
146 | }
147 | }
148 | ;;
149 |
150 | remove)
151 | del_fstab
152 | umount /mnt/$device
153 | if [ $? -eq 0 ]
154 | then
155 | rmdir /mnt/$device
156 | fi
157 | esac
158 | fi
159 |
--------------------------------------------------------------------------------
/openwrt/files/bcm27xx/bcm2711/entertainment/etc/uci-defaults/luci-base:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | str1="cgi-bin/luci"
3 | str2=`uci get uhttpd.main.index_page`
4 | result=$(echo $str2 | grep "$str1")
5 | if [ -z "$result" ]
6 | then
7 | uci -q batch <<-EOF >/dev/null
8 | add_list uhttpd.main.index_page='cgi-bin/luci'
9 | commit uhttpd
10 | EOF
11 | fi
12 | uci -q batch <<-EOF >/dev/null
13 | set luci.main.lang=en
14 | set luci.main.mediaurlbase=/luci-static/argon
15 | commit luci
16 | EOF
17 | exit 0
18 |
--------------------------------------------------------------------------------
/openwrt/files/bcm27xx/bcm2711/minimal/etc/config/firewall:
--------------------------------------------------------------------------------
1 |
2 | config defaults
3 | option syn_flood '1'
4 | option input 'ACCEPT'
5 | option output 'ACCEPT'
6 | option forward 'REJECT'
7 | option fullcone '1'
8 |
9 | config zone
10 | option name 'lan'
11 | list network 'lan'
12 | option input 'ACCEPT'
13 | option output 'ACCEPT'
14 | option forward 'ACCEPT'
15 |
16 | config zone
17 | option name 'wan'
18 | list network 'wan'
19 | list network 'wan6'
20 | option output 'ACCEPT'
21 | option forward 'ACCEPT'
22 | option masq '1'
23 | option mtu_fix '1'
24 | option input 'ACCEPT'
25 |
26 | config forwarding
27 | option src 'lan'
28 | option dest 'wan'
29 |
30 | config rule
31 | option name 'Allow-DHCP-Renew'
32 | option src 'wan'
33 | option proto 'udp'
34 | option dest_port '68'
35 | option target 'ACCEPT'
36 | option family 'ipv4'
37 |
38 | config rule
39 | option name 'Allow-Ping'
40 | option src 'wan'
41 | option proto 'icmp'
42 | option icmp_type 'echo-request'
43 | option family 'ipv4'
44 | option target 'ACCEPT'
45 |
46 | config rule
47 | option name 'Allow-IGMP'
48 | option src 'wan'
49 | option proto 'igmp'
50 | option family 'ipv4'
51 | option target 'ACCEPT'
52 |
53 | config rule
54 | option name 'Allow-DHCPv6'
55 | option src 'wan'
56 | option proto 'udp'
57 | option src_ip 'fc00::/6'
58 | option dest_ip 'fc00::/6'
59 | option dest_port '546'
60 | option family 'ipv6'
61 | option target 'ACCEPT'
62 |
63 | config rule
64 | option name 'Allow-MLD'
65 | option src 'wan'
66 | option proto 'icmp'
67 | option src_ip 'fe80::/10'
68 | list icmp_type '130/0'
69 | list icmp_type '131/0'
70 | list icmp_type '132/0'
71 | list icmp_type '143/0'
72 | option family 'ipv6'
73 | option target 'ACCEPT'
74 |
75 | config rule
76 | option name 'Allow-ICMPv6-Input'
77 | option src 'wan'
78 | option proto 'icmp'
79 | list icmp_type 'echo-request'
80 | list icmp_type 'echo-reply'
81 | list icmp_type 'destination-unreachable'
82 | list icmp_type 'packet-too-big'
83 | list icmp_type 'time-exceeded'
84 | list icmp_type 'bad-header'
85 | list icmp_type 'unknown-header-type'
86 | list icmp_type 'router-solicitation'
87 | list icmp_type 'neighbour-solicitation'
88 | list icmp_type 'router-advertisement'
89 | list icmp_type 'neighbour-advertisement'
90 | option limit '1000/sec'
91 | option family 'ipv6'
92 | option target 'ACCEPT'
93 |
94 | config rule
95 | option name 'Allow-ICMPv6-Forward'
96 | option src 'wan'
97 | option dest '*'
98 | option proto 'icmp'
99 | list icmp_type 'echo-request'
100 | list icmp_type 'echo-reply'
101 | list icmp_type 'destination-unreachable'
102 | list icmp_type 'packet-too-big'
103 | list icmp_type 'time-exceeded'
104 | list icmp_type 'bad-header'
105 | list icmp_type 'unknown-header-type'
106 | option limit '1000/sec'
107 | option family 'ipv6'
108 | option target 'ACCEPT'
109 |
110 | config rule
111 | option name 'Allow-IPSec-ESP'
112 | option src 'wan'
113 | option dest 'lan'
114 | option proto 'esp'
115 | option target 'ACCEPT'
116 |
117 | config rule
118 | option name 'Allow-ISAKMP'
119 | option src 'wan'
120 | option dest 'lan'
121 | option dest_port '500'
122 | option proto 'udp'
123 | option target 'ACCEPT'
124 |
125 | config include
126 | option path '/etc/firewall.user'
127 |
128 | config include 'zerotier'
129 | option type 'script'
130 | option path '/etc/zerotier.start'
131 | option reload '1'
132 |
133 | config include 'miniupnpd'
134 | option type 'script'
135 | option path '/usr/share/miniupnpd/firewall.include'
136 | option family 'any'
137 | option reload '1'
138 |
139 | config include 'gowebdav'
140 | option type 'script'
141 | option path '/var/etc/gowebdav.include'
142 | option reload '1'
143 |
144 | config include 'luci_app_ipsec_server'
145 | option type 'script'
146 | option path '/var/etc/ipsecvpn.include'
147 | option reload '1'
148 |
149 | config include 'passwall'
150 | option type 'script'
151 | option path '/var/etc/passwall.include'
152 | option reload '1'
153 |
154 | config include 'passwall_server'
155 | option type 'script'
156 | option path '/var/etc/passwall_server.include'
157 | option reload '1'
158 |
159 | config include 'luci_app_pptp_server'
160 | option type 'script'
161 | option path '/var/etc/pptpd.include'
162 | option reload '1'
163 |
164 | config include 'socat'
165 | option type 'script'
166 | option path '/var/etc/socat.include'
167 | option reload '1'
168 |
169 | config include 'softethervpn'
170 | option type 'script'
171 | option path '/var/etc/softethervpn.include'
172 | option reload '1'
173 |
174 | config include 'ssr_mudb_server'
175 | option type 'script'
176 | option path '/var/etc/ssr_mudb_server.include'
177 | option reload '1'
178 |
179 | config include 'v2ray_server'
180 | option type 'script'
181 | option path '/var/etc/v2ray_server.include'
182 | option reload '1'
183 |
184 | config rule 'kms'
185 | option name 'kms'
186 | option target 'ACCEPT'
187 | option src 'wan'
188 | option proto 'tcp'
189 | option dest_port '1688'
190 |
191 | config include 'openclash'
192 | option type 'script'
193 | option path '/var/etc/openclash.include'
194 | option reload '1'
195 |
196 | config include 'shadowsocksr'
197 | option type 'script'
198 | option path '/var/etc/shadowsocksr.include'
199 | option reload '1'
200 |
201 | config include 'wrtbwmon'
202 | option type 'script'
203 | option path '/etc/wrtbwmon.include'
204 | option reload '1'
205 |
206 | config include 'mia'
207 | option type 'script'
208 | option path '/etc/mia.include'
209 | option reload '1'
210 |
211 | config rule 'openvpn'
212 | option name 'openvpn'
213 | option target 'ACCEPT'
214 | option src 'wan'
215 | option proto 'tcp udp'
216 | option dest_port '1194'
217 |
218 | config zone 'vpn'
219 | option name 'vpn'
220 | option input 'ACCEPT'
221 | option forward 'ACCEPT'
222 | option output 'ACCEPT'
223 | option masq '1'
224 | option network 'vpn0'
225 |
226 | config forwarding 'vpntowan'
227 | option src 'vpn'
228 | option dest 'wan'
229 |
230 | config forwarding 'vpntolan'
231 | option src 'vpn'
232 | option dest 'lan'
233 |
234 | config forwarding 'lantovpn'
235 | option src 'lan'
236 | option dest 'vpn'
237 |
238 | config include 'unblockmusic'
239 | option type 'script'
240 | option path '/var/etc/unblockmusic.include'
241 | option reload '1'
242 |
243 |
244 |
--------------------------------------------------------------------------------
/openwrt/files/bcm27xx/bcm2711/minimal/etc/config/luci:
--------------------------------------------------------------------------------
1 |
2 | config core 'main'
3 | option resourcebase '/luci-static/resources'
4 | option mediaurlbase '/luci-static/argon'
5 | option lang 'en'
6 |
7 | config extern 'flash_keep'
8 | option uci '/etc/config/'
9 | option dropbear '/etc/dropbear/'
10 | option openvpn '/etc/openvpn/'
11 | option passwd '/etc/passwd'
12 | option opkg '/etc/opkg.conf'
13 | option firewall '/etc/firewall.user'
14 | option uploads '/lib/uci/upload/'
15 |
16 | config internal 'languages'
17 |
18 | config internal 'sauth'
19 | option sessionpath '/tmp/luci-sessions'
20 | option sessiontime '3600'
21 |
22 | config internal 'ccache'
23 | option enable '1'
24 |
25 | config internal 'themes'
26 |
27 | config internal 'diag'
28 | option dns 'openwrt.org'
29 | option ping 'openwrt.org'
30 | option route 'openwrt.org'
31 |
32 | config internal apply
33 | option rollback 90
34 | option holdoff 4
35 | option timeout 5
36 | option display 1.5
37 |
38 |
39 |
--------------------------------------------------------------------------------
/openwrt/files/bcm27xx/bcm2711/minimal/etc/config/network:
--------------------------------------------------------------------------------
1 | config interface 'loopback'
2 | option proto 'static'
3 | option ipaddr '127.0.0.1'
4 | option netmask '255.0.0.0'
5 | option device 'lo'
6 |
7 | config globals 'globals'
8 | option ula_prefix 'fd95:27c5:3e18::/48'
9 | option packet_steering '1'
10 |
11 | config interface 'lan'
12 | option proto 'static'
13 | option ipaddr '192.168.2.1'
14 | option netmask '255.255.255.0'
15 | option ip6assign '60'
16 | option device 'br-lan'
17 |
18 | config interface 'wan'
19 | option proto 'dhcp'
20 | option device 'eth1'
21 |
22 | config interface 'vpn0'
23 | option proto 'none'
24 | option device 'tun0'
25 |
26 | config interface 'docker'
27 | option device 'docker0'
28 | option proto 'none'
29 | option auto '0'
30 |
31 | config device
32 | option type 'bridge'
33 | option name 'docker0'
34 |
35 | config device
36 | option name 'br-lan'
37 | option type 'bridge'
38 | list ports 'eth0'
39 |
--------------------------------------------------------------------------------
/openwrt/files/readme.md:
--------------------------------------------------------------------------------
1 | files for seeed-linux-openwrt
--------------------------------------------------------------------------------
/openwrt/files/x86/64/minimal/etc/config/firewall:
--------------------------------------------------------------------------------
1 |
2 | config defaults
3 | option syn_flood '1'
4 | option input 'ACCEPT'
5 | option output 'ACCEPT'
6 | option forward 'REJECT'
7 | option fullcone '1'
8 |
9 | config zone
10 | option name 'lan'
11 | list network 'lan'
12 | option input 'ACCEPT'
13 | option output 'ACCEPT'
14 | option forward 'ACCEPT'
15 |
16 | config zone
17 | option name 'wan'
18 | list network 'wan'
19 | list network 'wan6'
20 | option output 'ACCEPT'
21 | option forward 'REJECT'
22 | option masq '1'
23 | option mtu_fix '1'
24 | option input 'ACCEPT'
25 |
26 | config forwarding
27 | option src 'lan'
28 | option dest 'wan'
29 |
30 | config rule
31 | option name 'Allow-DHCP-Renew'
32 | option src 'wan'
33 | option proto 'udp'
34 | option dest_port '68'
35 | option target 'ACCEPT'
36 | option family 'ipv4'
37 |
38 | config rule
39 | option name 'Allow-Ping'
40 | option src 'wan'
41 | option proto 'icmp'
42 | option icmp_type 'echo-request'
43 | option family 'ipv4'
44 | option target 'ACCEPT'
45 |
46 | config rule
47 | option name 'Allow-IGMP'
48 | option src 'wan'
49 | option proto 'igmp'
50 | option family 'ipv4'
51 | option target 'ACCEPT'
52 |
53 | config rule
54 | option name 'Allow-DHCPv6'
55 | option src 'wan'
56 | option proto 'udp'
57 | option src_ip 'fc00::/6'
58 | option dest_ip 'fc00::/6'
59 | option dest_port '546'
60 | option family 'ipv6'
61 | option target 'ACCEPT'
62 |
63 | config rule
64 | option name 'Allow-MLD'
65 | option src 'wan'
66 | option proto 'icmp'
67 | option src_ip 'fe80::/10'
68 | list icmp_type '130/0'
69 | list icmp_type '131/0'
70 | list icmp_type '132/0'
71 | list icmp_type '143/0'
72 | option family 'ipv6'
73 | option target 'ACCEPT'
74 |
75 | config rule
76 | option name 'Allow-ICMPv6-Input'
77 | option src 'wan'
78 | option proto 'icmp'
79 | list icmp_type 'echo-request'
80 | list icmp_type 'echo-reply'
81 | list icmp_type 'destination-unreachable'
82 | list icmp_type 'packet-too-big'
83 | list icmp_type 'time-exceeded'
84 | list icmp_type 'bad-header'
85 | list icmp_type 'unknown-header-type'
86 | list icmp_type 'router-solicitation'
87 | list icmp_type 'neighbour-solicitation'
88 | list icmp_type 'router-advertisement'
89 | list icmp_type 'neighbour-advertisement'
90 | option limit '1000/sec'
91 | option family 'ipv6'
92 | option target 'ACCEPT'
93 |
94 | config rule
95 | option name 'Allow-ICMPv6-Forward'
96 | option src 'wan'
97 | option dest '*'
98 | option proto 'icmp'
99 | list icmp_type 'echo-request'
100 | list icmp_type 'echo-reply'
101 | list icmp_type 'destination-unreachable'
102 | list icmp_type 'packet-too-big'
103 | list icmp_type 'time-exceeded'
104 | list icmp_type 'bad-header'
105 | list icmp_type 'unknown-header-type'
106 | option limit '1000/sec'
107 | option family 'ipv6'
108 | option target 'ACCEPT'
109 |
110 | config rule
111 | option name 'Allow-IPSec-ESP'
112 | option src 'wan'
113 | option dest 'lan'
114 | option proto 'esp'
115 | option target 'ACCEPT'
116 |
117 | config rule
118 | option name 'Allow-ISAKMP'
119 | option src 'wan'
120 | option dest 'lan'
121 | option dest_port '500'
122 | option proto 'udp'
123 | option target 'ACCEPT'
124 |
125 | config include
126 | option path '/etc/firewall.user'
127 |
128 | config include 'zerotier'
129 | option type 'script'
130 | option path '/etc/zerotier.start'
131 | option reload '1'
132 |
133 | config include 'miniupnpd'
134 | option type 'script'
135 | option path '/usr/share/miniupnpd/firewall.include'
136 | option family 'any'
137 | option reload '1'
138 |
139 | config include 'gowebdav'
140 | option type 'script'
141 | option path '/var/etc/gowebdav.include'
142 | option reload '1'
143 |
144 | config include 'luci_app_ipsec_server'
145 | option type 'script'
146 | option path '/var/etc/ipsecvpn.include'
147 | option reload '1'
148 |
149 | config include 'passwall'
150 | option type 'script'
151 | option path '/var/etc/passwall.include'
152 | option reload '1'
153 |
154 | config include 'passwall_server'
155 | option type 'script'
156 | option path '/var/etc/passwall_server.include'
157 | option reload '1'
158 |
159 | config include 'luci_app_pptp_server'
160 | option type 'script'
161 | option path '/var/etc/pptpd.include'
162 | option reload '1'
163 |
164 | config include 'socat'
165 | option type 'script'
166 | option path '/var/etc/socat.include'
167 | option reload '1'
168 |
169 | config include 'softethervpn'
170 | option type 'script'
171 | option path '/var/etc/softethervpn.include'
172 | option reload '1'
173 |
174 | config include 'ssr_mudb_server'
175 | option type 'script'
176 | option path '/var/etc/ssr_mudb_server.include'
177 | option reload '1'
178 |
179 | config include 'v2ray_server'
180 | option type 'script'
181 | option path '/var/etc/v2ray_server.include'
182 | option reload '1'
183 |
184 | config rule 'kms'
185 | option name 'kms'
186 | option target 'ACCEPT'
187 | option src 'wan'
188 | option proto 'tcp'
189 | option dest_port '1688'
190 |
191 | config include 'openclash'
192 | option type 'script'
193 | option path '/var/etc/openclash.include'
194 | option reload '1'
195 |
196 | config include 'shadowsocksr'
197 | option type 'script'
198 | option path '/var/etc/shadowsocksr.include'
199 | option reload '1'
200 |
201 | config include 'wrtbwmon'
202 | option type 'script'
203 | option path '/etc/wrtbwmon.include'
204 | option reload '1'
205 |
206 | config include 'mia'
207 | option type 'script'
208 | option path '/etc/mia.include'
209 | option reload '1'
210 |
211 | config rule 'openvpn'
212 | option name 'openvpn'
213 | option target 'ACCEPT'
214 | option src 'wan'
215 | option proto 'tcp udp'
216 | option dest_port '1194'
217 |
218 | config zone 'vpn'
219 | option name 'vpn'
220 | option input 'ACCEPT'
221 | option forward 'ACCEPT'
222 | option output 'ACCEPT'
223 | option masq '1'
224 | option network 'vpn0'
225 |
226 | config forwarding 'vpntowan'
227 | option src 'vpn'
228 | option dest 'wan'
229 |
230 | config forwarding 'vpntolan'
231 | option src 'vpn'
232 | option dest 'lan'
233 |
234 | config forwarding 'lantovpn'
235 | option src 'lan'
236 | option dest 'vpn'
237 |
238 | config include 'unblockmusic'
239 | option type 'script'
240 | option path '/var/etc/unblockmusic.include'
241 | option reload '1'
242 |
243 |
--------------------------------------------------------------------------------
/openwrt/files/x86/64/minimal/etc/config/luci:
--------------------------------------------------------------------------------
1 | config core 'main'
2 | option resourcebase '/luci-static/resources'
3 | option mediaurlbase '/luci-static/argon'
4 | option lang 'en'
5 |
6 | config extern 'flash_keep'
7 | option uci '/etc/config/'
8 | option dropbear '/etc/dropbear/'
9 | option openvpn '/etc/openvpn/'
10 | option passwd '/etc/passwd'
11 | option opkg '/etc/opkg.conf'
12 | option firewall '/etc/firewall.user'
13 | option uploads '/lib/uci/upload/'
14 |
15 | config internal 'languages'
16 |
17 | config internal 'sauth'
18 | option sessionpath '/tmp/luci-sessions'
19 | option sessiontime '3600'
20 |
21 | config internal 'ccache'
22 | option enable '1'
23 |
24 | config internal 'themes'
25 |
26 | config internal 'diag'
27 | option dns 'openwrt.org'
28 | option ping 'openwrt.org'
29 | option route 'openwrt.org'
30 |
31 | config internal apply
32 | option rollback 90
33 | option holdoff 4
34 | option timeout 5
35 | option display 1.5
36 |
--------------------------------------------------------------------------------
/openwrt/files/x86/64/minimal/etc/config/network:
--------------------------------------------------------------------------------
1 | config interface 'loopback'
2 | option ifname 'lo'
3 | option proto 'static'
4 | option ipaddr '127.0.0.1'
5 | option netmask '255.0.0.0'
6 |
7 | config globals 'globals'
8 | option ula_prefix 'fd95:27c5:3e18::/48'
9 | option packet_steering '1'
10 |
11 | config interface 'lan'
12 | option type 'bridge'
13 | option ifname 'eth0'
14 | option proto 'static'
15 | option ipaddr '192.168.2.1'
16 | option netmask '255.255.255.0'
17 | option ip6assign '60'
18 |
19 | config interface 'wan'
20 | option proto 'dhcp'
21 | option ifname 'eth1'
22 |
23 | config interface 'vpn0'
24 | option ifname 'tun0'
25 | option proto 'none'
26 |
27 | config interface 'docker'
28 | option device 'docker0'
29 | option proto 'none'
30 | option auto '0'
31 |
32 | config device
33 | option type 'bridge'
34 | option name 'docker0'
--------------------------------------------------------------------------------
/openwrt/packages/README.md:
--------------------------------------------------------------------------------
1 | # packages set for the project
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-cifs-mount/Makefile:
--------------------------------------------------------------------------------
1 |
2 | # Copyright (C) 2016 Openwrt.org
3 | #
4 | # This is free software, licensed under the Apache License, Version 2.0 .
5 | #
6 |
7 | include $(TOPDIR)/rules.mk
8 |
9 | LUCI_TITLE:=LuCI for SMB/CIFS Mount
10 | LUCI_DEPENDS:=+kmod-fs-cifs +kmod-nls-utf8
11 | LUCI_PKGARCH:=all
12 | PKG_NAME:=luci-app-cifs-mount
13 | PKG_VERSION:=1
14 | PKG_RELEASE:=7
15 |
16 | include $(TOPDIR)/feeds/luci/luci.mk
17 |
18 | # call BuildPackage - OpenWrt buildroot signature
19 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-cifs-mount/luasrc/controller/cifs.lua:
--------------------------------------------------------------------------------
1 |
2 | module("luci.controller.cifs", package.seeall)
3 |
4 | function index()
5 | if not nixio.fs.access("/etc/config/cifs") then
6 | return
7 | end
8 |
9 | entry({"admin", "nas", "cifs"}, cbi("cifs"), _("Mount SMB NetShare")).dependent = true
10 | end
11 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-cifs-mount/luasrc/model/cbi/cifs.lua:
--------------------------------------------------------------------------------
1 | local fs = require "nixio.fs"
2 |
3 | m = Map("cifs", translate("Mount SMB/CIFS Netshare"), translate("Mount SMB/CIFS Netshare for OpenWrt"))
4 |
5 | s = m:section(TypedSection, "cifs")
6 | s.anonymous = true
7 |
8 | switch = s:option(Flag, "enabled", translate("Enable"))
9 | switch.rmempty = false
10 |
11 | workgroup = s:option(Value, "workgroup", translate("Workgroup"))
12 | workgroup.default = "WORKGROUP"
13 |
14 | s = m:section(TypedSection, "natshare", translate("CIFS/SMB Netshare"))
15 | s.anonymous = true
16 | s.addremove = true
17 | s.template = "cbi/tblsection"
18 |
19 | server = s:option(Value, "server", translate("Server IP"))
20 | server.size = 12
21 | server.rmempty = false
22 |
23 | name = s:option(Value, "name", translate("Share Folder"))
24 | name.rmempty = false
25 | name.size = 8
26 |
27 | pth = s:option(Value, "natpath", translate("Mount Path"))
28 | if nixio.fs.access("/etc/config/fstab") then
29 | pth.titleref = luci.dispatcher.build_url("admin", "system", "fstab")
30 | end
31 | pth.rmempty = false
32 | pth.size = 10
33 |
34 | smbver = s:option(Value, "smbver", translate("SMB Version"))
35 | smbver.rmempty = false
36 | smbver:value("1.0","SMB v1")
37 | smbver:value("2.0","SMB v2")
38 | smbver:value("3.0","SMB v3")
39 | smbver.default = "2.0"
40 | smbver.size = 3
41 |
42 | agm = s:option(Value, "agm", translate("Arguments"))
43 | agm:value("ro", translate("Read Only"))
44 | agm:value("rw", translate("Read/Write"))
45 | agm.rmempty = true
46 | agm.default = "ro"
47 |
48 | iocharset = s:option(Value, "iocharset", translate("Charset"))
49 | iocharset:value("utf8", "UTF8")
50 | iocharset.default = "utf8"
51 | iocharset.size = 2
52 |
53 | users = s:option(Value, "users", translate("User"))
54 | users:value("guest", "Guest")
55 | users.rmempty = true
56 | users.default = "guest"
57 |
58 | pwd = s:option(Value, "pwd", translate("Password"))
59 | pwd.rmempty = true
60 | pwd.size = 8
61 |
62 | return m
63 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-cifs-mount/po/zh-cn/cifs.po:
--------------------------------------------------------------------------------
1 | msgid "Mount SMB NetShare"
2 | msgstr "挂载 SMB 网络共享"
3 |
4 | msgid "Mount SMB/CIFS Netshare"
5 | msgstr "挂载 SMB/CIFS 网络共享文件夹"
6 |
7 | msgid "Mount SMB/CIFS Netshare for OpenWrt"
8 | msgstr "可以将 SMB/CIFS 的共享文件夹挂载到本地(修改挂载后,需要重启使用这些文件夹的客户端)"
9 |
10 | msgid "CIFS/SMB Netshare"
11 | msgstr "CIFS/SMB 文件夹共享挂载设置"
12 |
13 | msgid "Server IP"
14 | msgstr "服务器IP"
15 |
16 | msgid "Share Folder"
17 | msgstr "共享文件夹"
18 |
19 | msgid "Mount Path"
20 | msgstr "挂载路径"
21 |
22 | msgid "SMB Version"
23 | msgstr "SMB 版本"
24 |
25 | msgid "Arguments"
26 | msgstr "挂载参数"
27 |
28 | msgid "Charset"
29 | msgstr "字符集"
30 |
31 | msgid "User"
32 | msgstr "用户名"
33 |
34 | msgid "Password"
35 | msgstr "密码"
36 |
37 | msgid "Read Only"
38 | msgstr "只读"
39 |
40 | msgid "Read/Write"
41 | msgstr "可读/写"
42 |
43 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-cifs-mount/root/etc/config/cifs:
--------------------------------------------------------------------------------
1 |
2 | config cifs
3 | option enabled '0'
4 | option workgroup 'WORKGROUP'
5 | option iocharset 'utf8'
6 | option delay '5'
7 | option mountarea '/mnt'
8 |
9 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-cifs-mount/root/etc/init.d/cifs:
--------------------------------------------------------------------------------
1 | #!/bin/sh /etc/rc.common
2 |
3 | START=97
4 |
5 | ENABLED=0
6 | WORKGROUPD=0
7 | IOCHARSET=0
8 | GUEST=""
9 | USERS=""
10 | AGM=""
11 |
12 | cifs_header() {
13 | local enabled
14 | local workgroup
15 |
16 | config_get enabled $1 enabled
17 | config_get workgroup $1 workgroup
18 |
19 | ENABLED=$enabled
20 | WORKGROUPD=$workgroup
21 | }
22 |
23 | mount_natshare() {
24 | local server
25 | local name
26 | local natpath
27 | local guest
28 | local users
29 | local pwd
30 | local agm
31 | local iocharset
32 | local smbver
33 |
34 | config_get server $1 server
35 | config_get name $1 name
36 | config_get natpath $1 natpath
37 | config_get guest $1 guest
38 | config_get users $1 users
39 | config_get pwd $1 pwd
40 | config_get agm $1 agm
41 | config_get iocharset $1 iocharset
42 | config_get smbver $1 smbver
43 |
44 | mkdir -p $natpath && chmod 777 $natpath
45 | #echo "mount -t cifs -o vers=$smbver,user=$users,password=$pwd,iocharset=$iocharset,$agm //$server/$name $natpath"
46 | mount -t cifs -o vers=$smbver,username=$users,password=$pwd,iocharset=$iocharset,$agm //$server/$name $natpath
47 | }
48 |
49 | start() {
50 | config_load cifs
51 | config_foreach cifs_header cifs
52 |
53 | if [ $ENABLED == 1 ]
54 | then {
55 | config_foreach mount_natshare natshare
56 | #echo "Cifs Mount succeed."
57 | }
58 | fi
59 | }
60 |
61 | stop() {
62 | mount | grep '//' | awk -F ' ' '{print$3}' | while read line; do
63 | #echo "umount -d -l $line"
64 | umount -d -l $line 2>/dev/null
65 | done
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-cifs-mount/root/etc/uci-defaults/luci-cifs:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | uci -q batch <<-EOF >/dev/null
4 | delete ucitrack.@cifs[-1]
5 | add ucitrack cifs
6 | set ucitrack.@cifs[-1].init=cifs
7 | commit ucitrack
8 | EOF
9 |
10 | rm -f /tmp/luci-indexcache
11 | exit 0
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-fileassistant/Makefile:
--------------------------------------------------------------------------------
1 | # From https://github.com/DarkDean89/luci-app-filebrowser
2 | # This is free software, licensed under the Apache License, Version 2.0 .
3 |
4 | include $(TOPDIR)/rules.mk
5 |
6 | LUCI_TITLE:=LuCI support for File Assistant
7 | LUCI_PKGARCH:=all
8 | PKG_VERSION:=1.0
9 | PKG_RELEASE:=1
10 |
11 | include $(TOPDIR)/feeds/luci/luci.mk
12 |
13 | # call BuildPackage - OpenWrt buildroot signature
14 |
15 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-fileassistant/README.md:
--------------------------------------------------------------------------------
1 | # luci-app-fileassistant
2 |
3 | > 文件助手
4 |
5 | 效果预览:
6 |
7 | 
8 |
9 | 移植自 [DarkDean89/luci-app-filebrowser](https://github.com/DarkDean89/luci-app-filebrowser)
10 |
11 | 修改说明:
12 |
13 | * 修改 LuCI 菜单目录
14 | * 增加安装 ipk 功能
15 |
16 | 更多描述,详见: [移植软件包 - 文件助手](https://stuarthua.github.io/oh-my-openwrt/mybook/packages/use-package-filetransfer.html)
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-fileassistant/htdocs/luci-static/resources/fileassistant/fb.css:
--------------------------------------------------------------------------------
1 | .fb-container {
2 | margin-top: 1rem;
3 | }
4 | .fb-container .cbi-button {
5 | height: 1.8rem;
6 | }
7 | .fb-container .cbi-input-text {
8 | margin-bottom: 1rem;
9 | width: 100%;
10 | }
11 | .fb-container .panel-title {
12 | padding-bottom: 0;
13 | width: 50%;
14 | border-bottom: none;
15 | }
16 | .fb-container .panel-container {
17 | display: flex;
18 | align-items: center;
19 | justify-content: space-between;
20 | padding-bottom: 1rem;
21 | border-bottom: 1px solid #eee;
22 | }
23 | .fb-container .upload-container {
24 | display: none;
25 | margin: 1rem 0;
26 | }
27 | .fb-container .upload-file {
28 | margin-right: 2rem;
29 | }
30 | .fb-container .cbi-value-field {
31 | text-align: left;
32 | }
33 | .fb-container .parent-icon strong {
34 | margin-left: 1rem;
35 | }
36 | .fb-container td[class$="-icon"] {
37 | cursor: pointer;
38 | }
39 | .fb-container .file-icon, .fb-container .folder-icon, .fb-container .link-icon {
40 | position: relative;
41 | }
42 | .fb-container .file-icon:before, .fb-container .folder-icon:before, .fb-container .link-icon:before {
43 | display: inline-block;
44 | width: 1.5rem;
45 | height: 1.5rem;
46 | content: '';
47 | background-size: contain;
48 | margin: 0 0.5rem 0 1rem;
49 | vertical-align: middle;
50 | }
51 | .fb-container .file-icon:before {
52 | background-image: url(file-icon.png);
53 | }
54 | .fb-container .folder-icon:before {
55 | background-image: url(folder-icon.png);
56 | }
57 | .fb-container .link-icon:before {
58 | background-image: url(link-icon.png);
59 | }
60 | @media screen and (max-width: 480px) {
61 | .fb-container .upload-file {
62 | width: 14.6rem;
63 | }
64 | .fb-container .cbi-value-owner,
65 | .fb-container .cbi-value-perm {
66 | display: none;
67 | }
68 | }
69 |
70 | .cbi-section-table {
71 | width: 100%;
72 | }
73 |
74 | .cbi-section-table-cell {
75 | text-align: right;
76 | }
77 |
78 | .cbi-button-install {
79 | border-color: #c44;
80 | color: #c44;
81 | margin-left: 3px;
82 | }
83 |
84 | .cbi-value-field {
85 | padding: 10px 0;
86 | }
87 |
88 | .parent-icon {
89 | height: 1.8rem;
90 | padding: 10px 0;
91 | }
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-fileassistant/htdocs/luci-static/resources/fileassistant/fb.js:
--------------------------------------------------------------------------------
1 | String.prototype.replaceAll = function(search, replacement) {
2 | var target = this;
3 | return target.replace(new RegExp(search, 'g'), replacement);
4 | };
5 | (function () {
6 | var iwxhr = new XHR();
7 | var listElem = document.getElementById("list-content");
8 | listElem.onclick = handleClick;
9 | var currentPath;
10 | var pathElem = document.getElementById("current-path");
11 | pathElem.onblur = function () {
12 | update_list(this.value.trim());
13 | };
14 | pathElem.onkeyup = function (evt) {
15 | if (evt.keyCode == 13) {
16 | this.blur();
17 | }
18 | };
19 | function removePath(filename, isdir) {
20 | var c = confirm('Are you sure you want to delete ' + filename + ' ?');
21 | if (c) {
22 | iwxhr.get('/cgi-bin/luci/admin/services/fileassistant_delete',
23 | {
24 | path: concatPath(currentPath, filename),
25 | isdir: isdir
26 | },
27 | function (x, res) {
28 | if (res.ec === 0) {
29 | refresh_list(res.data, currentPath);
30 | }
31 | });
32 | }
33 | }
34 |
35 | function installPath(filename, isdir) {
36 | if (isdir === "1") {
37 | alert('This is a directory, please select an ipk file to install!');
38 | return;
39 | }
40 | var isipk = isIPK(filename);
41 | if (isipk === 0) {
42 | alert('Only allow installation of files in ipk format!');
43 | return;
44 | }
45 | var c = confirm('Are you sure you want to install ' + filename + ' ?');
46 | if (c) {
47 | iwxhr.get('/cgi-bin/luci/admin/services/fileassistant_install',
48 | {
49 | filepath: concatPath(currentPath, filename),
50 | isdir: isdir
51 | },
52 | function (x, res) {
53 | if (res.ec === 0) {
54 | location.reload();
55 | alert('Installation successful!');
56 | } else {
57 | alert('Installation failed, please check the file format!');
58 | }
59 | });
60 | }
61 | }
62 |
63 | function isIPK(filename) {
64 | var index= filename.lastIndexOf(".");
65 | var ext = filename.substr(index+1);
66 | if (ext === 'ipk') {
67 | return 1;
68 | } else {
69 | return 0;
70 | }
71 | }
72 |
73 | function renamePath(filename) {
74 | var newname = prompt('Please enter a new file name:', filename);
75 | if (newname) {
76 | newname = newname.trim();
77 | if (newname != filename) {
78 | var newpath = concatPath(currentPath, newname);
79 | iwxhr.get('/cgi-bin/luci/admin/services/fileassistant_rename',
80 | {
81 | filepath: concatPath(currentPath, filename),
82 | newpath: newpath
83 | },
84 | function (x, res) {
85 | if (res.ec === 0) {
86 | refresh_list(res.data, currentPath);
87 | }
88 | }
89 | );
90 | }
91 | }
92 | }
93 |
94 | function openpath(filename, dirname) {
95 | dirname = dirname || currentPath;
96 | window.open('/cgi-bin/luci/admin/services/fileassistant_open?path='
97 | + encodeURIComponent(dirname) + '&filename='
98 | + encodeURIComponent(filename));
99 | }
100 |
101 | function getFileElem(elem) {
102 | if (elem.className.indexOf('-icon') > -1) {
103 | return elem;
104 | }
105 | else if (elem.parentNode.className.indexOf('-icon') > -1) {
106 | return elem.parentNode;
107 | }
108 | }
109 |
110 | function concatPath(path, filename) {
111 | if (path === '/') {
112 | return path + filename;
113 | }
114 | else {
115 | return path.replace(/\/$/, '') + '/' + filename;
116 | }
117 | }
118 |
119 | function handleClick(evt) {
120 | var targetElem = evt.target;
121 | var infoElem;
122 | if (targetElem.className.indexOf('cbi-button-remove') > -1) {
123 | infoElem = targetElem.parentNode.parentNode;
124 | removePath(infoElem.dataset['filename'] , infoElem.dataset['isdir'])
125 | }
126 | else if (targetElem.className.indexOf('cbi-button-install') > -1) {
127 | infoElem = targetElem.parentNode.parentNode;
128 | installPath(infoElem.dataset['filename'] , infoElem.dataset['isdir'])
129 | }
130 | else if (targetElem.className.indexOf('cbi-button-edit') > -1) {
131 | renamePath(targetElem.parentNode.parentNode.dataset['filename']);
132 | }
133 | else if (targetElem = getFileElem(targetElem)) {
134 | if (targetElem.className.indexOf('parent-icon') > -1) {
135 | update_list(currentPath.replace(/\/[^/]+($|\/$)/, ''));
136 | }
137 | else if (targetElem.className.indexOf('file-icon') > -1) {
138 | openpath(targetElem.parentNode.dataset['filename']);
139 | }
140 | else if (targetElem.className.indexOf('link-icon') > -1) {
141 | infoElem = targetElem.parentNode;
142 | var filepath = infoElem.dataset['linktarget'];
143 | if (filepath) {
144 | if (infoElem.dataset['isdir'] === "1") {
145 | update_list(filepath);
146 | }
147 | else {
148 | var lastSlash = filepath.lastIndexOf('/');
149 | openpath(filepath.substring(lastSlash + 1), filepath.substring(0, lastSlash));
150 | }
151 | }
152 | }
153 | else if (targetElem.className.indexOf('folder-icon') > -1) {
154 | update_list(concatPath(currentPath, targetElem.parentNode.dataset['filename']))
155 | }
156 | }
157 | }
158 | function refresh_list(filenames, path) {
159 | var listHtml = '
';
160 | if (path !== '/') {
161 | listHtml += '.. |
';
162 | }
163 | if (filenames) {
164 | for (var i = 0; i < filenames.length; i++) {
165 | var line = filenames[i];
166 | if (line) {
167 | var f = line.match(/(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+([\S\s]+)/);
168 | var isLink = f[1][0] === 'z' || f[1][0] === 'l' || f[1][0] === 'x';
169 | var o = {
170 | displayname: f[9],
171 | filename: isLink ? f[9].split(' -> ')[0] : f[9],
172 | perms: f[1],
173 | date: f[7] + ' ' + f[6] + ' ' + f[8],
174 | size: f[5],
175 | owner: f[3],
176 | icon: (f[1][0] === 'd') ? "folder-icon" : (isLink ? "link-icon" : "file-icon")
177 | };
178 | listHtml += ''
182 | + ''
183 | + '' + o.displayname + ''
184 | + ' | '
185 | + ''+o.owner+' | '
186 | + ''+o.date+' | '
187 | + ''+o.size+' | '
188 | + ''+o.perms+' | '
189 | + '\
190 | | '
191 | + '
';
192 | }
193 | }
194 | }
195 | listHtml += "
";
196 | listElem.innerHTML = listHtml;
197 | }
198 | function update_list(path, opt) {
199 | opt = opt || {};
200 | path = concatPath(path, '');
201 | if (currentPath != path) {
202 | iwxhr.get('/cgi-bin/luci/admin/services/fileassistant_list',
203 | {path: path},
204 | function (x, res) {
205 | if (res.ec === 0) {
206 | refresh_list(res.data, path);
207 | }
208 | else {
209 | refresh_list([], path);
210 | }
211 | }
212 | );
213 | if (!opt.popState) {
214 | history.pushState({path: path}, null, '?path=' + path);
215 | }
216 | currentPath = path;
217 | pathElem.value = currentPath;
218 | }
219 | };
220 |
221 | var uploadToggle = document.getElementById('upload-toggle');
222 | var uploadContainer = document.getElementById('upload-container');
223 | var isUploadHide = true;
224 | uploadToggle.onclick = function() {
225 | if (isUploadHide) {
226 | uploadContainer.style.display = 'inline-flex';
227 | }
228 | else {
229 | uploadContainer.style.display = 'none';
230 | }
231 | isUploadHide = !isUploadHide;
232 | };
233 | var uploadBtn = uploadContainer.getElementsByClassName('cbi-input-apply')[0];
234 | uploadBtn.onclick = function (evt) {
235 | var uploadinput = document.getElementById('upload-file');
236 | var fullPath = uploadinput.value;
237 | if (!fullPath) {
238 | evt.preventDefault();
239 | }
240 | else {
241 | var formData = new FormData();
242 | var startIndex = (fullPath.indexOf('\\') >= 0 ? fullPath.lastIndexOf('\\') : fullPath.lastIndexOf('/'));
243 | formData.append('upload-filename', fullPath.substring(startIndex + 1));
244 | formData.append('upload-dir', concatPath(currentPath, ''));
245 | formData.append('upload-file', uploadinput.files[0]);
246 | var xhr = new XMLHttpRequest();
247 | xhr.open("POST", "/cgi-bin/luci/admin/services/fileassistant_upload", true);
248 | xhr.onload = function() {
249 | if (xhr.status == 200) {
250 | var res = JSON.parse(xhr.responseText);
251 | refresh_list(res.data, currentPath);
252 | uploadinput.value = '';
253 | }
254 | else {
255 | alert('Upload failed, please try again later...');
256 | }
257 | };
258 | xhr.send(formData);
259 | }
260 | };
261 |
262 | document.addEventListener('DOMContentLoaded', function(evt) {
263 | var initPath = '/';
264 | if (/path=([/\w]+)/.test(location.search)) {
265 | initPath = RegExp.$1;
266 | }
267 | update_list(initPath, {popState: true});
268 | });
269 | window.addEventListener('popstate', function (evt) {
270 | var path = '/';
271 | if (evt.state && evt.state.path) {
272 | path = evt.state.path;
273 | }
274 | update_list(path, {popState: true});
275 | });
276 |
277 | })();
278 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-fileassistant/htdocs/luci-static/resources/fileassistant/file-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Seeed-Studio/seeed-linux-openwrt/f8a381d50efbadfeab1e7624311fb1c1ee48edbe/openwrt/packages/luci-app-fileassistant/htdocs/luci-static/resources/fileassistant/file-icon.png
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-fileassistant/htdocs/luci-static/resources/fileassistant/folder-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Seeed-Studio/seeed-linux-openwrt/f8a381d50efbadfeab1e7624311fb1c1ee48edbe/openwrt/packages/luci-app-fileassistant/htdocs/luci-static/resources/fileassistant/folder-icon.png
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-fileassistant/htdocs/luci-static/resources/fileassistant/link-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Seeed-Studio/seeed-linux-openwrt/f8a381d50efbadfeab1e7624311fb1c1ee48edbe/openwrt/packages/luci-app-fileassistant/htdocs/luci-static/resources/fileassistant/link-icon.png
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-fileassistant/luasrc/controller/fileassistant.lua:
--------------------------------------------------------------------------------
1 | module("luci.controller.fileassistant", package.seeall)
2 |
3 | function index()
4 |
5 | entry({"admin", "services"}, firstchild(), "Me", 89).dependent = false
6 |
7 | local page
8 | page = entry({"admin", "services", "fileassistant"}, template("fileassistant"), _("File Assistant"), 800)
9 | page.i18n = "base"
10 | page.dependent = true
11 |
12 | page = entry({"admin", "services", "fileassistant_list"}, call("fileassistant_list"), nil)
13 | page.leaf = true
14 |
15 | page = entry({"admin", "services", "fileassistant_open"}, call("fileassistant_open"), nil)
16 | page.leaf = true
17 |
18 | page = entry({"admin", "services", "fileassistant_delete"}, call("fileassistant_delete"), nil)
19 | page.leaf = true
20 |
21 | page = entry({"admin", "services", "fileassistant_rename"}, call("fileassistant_rename"), nil)
22 | page.leaf = true
23 |
24 | page = entry({"admin", "services", "fileassistant_upload"}, call("fileassistant_upload"), nil)
25 | page.leaf = true
26 |
27 | page = entry({"admin", "services", "fileassistant_install"}, call("fileassistant_install"), nil)
28 | page.leaf = true
29 |
30 | end
31 |
32 | function list_response(path, success)
33 | luci.http.prepare_content("application/json")
34 | local result
35 | if success then
36 | local rv = scandir(path)
37 | result = {
38 | ec = 0,
39 | data = rv
40 | }
41 | else
42 | result = {
43 | ec = 1
44 | }
45 | end
46 | luci.http.write_json(result)
47 | end
48 |
49 | function fileassistant_list()
50 | local path = luci.http.formvalue("path")
51 | list_response(path, true)
52 | end
53 |
54 | function fileassistant_open()
55 | local path = luci.http.formvalue("path")
56 | local filename = luci.http.formvalue("filename")
57 | local io = require "io"
58 | local mime = to_mime(filename)
59 |
60 | file = path..filename
61 |
62 | local download_fpi = io.open(file, "r")
63 | luci.http.header('Content-Disposition', 'inline; filename="'..filename..'"' )
64 | luci.http.prepare_content(mime)
65 | luci.ltn12.pump.all(luci.ltn12.source.file(download_fpi), luci.http.write)
66 | end
67 |
68 | function fileassistant_delete()
69 | local path = luci.http.formvalue("path")
70 | local isdir = luci.http.formvalue("isdir")
71 | path = path:gsub("<>", "/")
72 | path = path:gsub(" ", "\ ")
73 | local success
74 | if isdir then
75 | success = os.execute('rm -r "'..path..'"')
76 | else
77 | success = os.remove(path)
78 | end
79 | list_response(nixio.fs.dirname(path), success)
80 | end
81 |
82 | function fileassistant_rename()
83 | local filepath = luci.http.formvalue("filepath")
84 | local newpath = luci.http.formvalue("newpath")
85 | local success = os.execute('mv "'..filepath..'" "'..newpath..'"')
86 | list_response(nixio.fs.dirname(filepath), success)
87 | end
88 |
89 | function fileassistant_install()
90 | local filepath = luci.http.formvalue("filepath")
91 | local isdir = luci.http.formvalue("isdir")
92 | local ext = filepath:match(".+%.(%w+)$")
93 | filepath = filepath:gsub("<>", "/")
94 | filepath = filepath:gsub(" ", "\ ")
95 | local success
96 | if isdir == "1" then
97 | success = false
98 | elseif ext == "ipk" then
99 | success = installIPK(filepath)
100 | else
101 | success = false
102 | end
103 | list_response(nixio.fs.dirname(filepath), success)
104 | end
105 |
106 | function installIPK(filepath)
107 | luci.sys.exec('opkg --force-depends install "'..filepath..'"')
108 | luci.sys.exec('rm -rf /tmp/luci-*')
109 | return true;
110 | end
111 |
112 | function fileassistant_upload()
113 | local filecontent = luci.http.formvalue("upload-file")
114 | local filename = luci.http.formvalue("upload-filename")
115 | local uploaddir = luci.http.formvalue("upload-dir")
116 | local filepath = uploaddir..filename
117 |
118 | local fp
119 | luci.http.setfilehandler(
120 | function(meta, chunk, eof)
121 | if not fp and meta and meta.name == "upload-file" then
122 | fp = io.open(filepath, "w")
123 | end
124 | if fp and chunk then
125 | fp:write(chunk)
126 | end
127 | if fp and eof then
128 | fp:close()
129 | end
130 | end
131 | )
132 |
133 | list_response(uploaddir, true)
134 | end
135 |
136 | function scandir(directory)
137 | local i, t, popen = 0, {}, io.popen
138 |
139 | local pfile = popen("ls -lh \""..directory.."\" | egrep '^d' ; ls -lh \""..directory.."\" | egrep -v '^d|^l'")
140 | for fileinfo in pfile:lines() do
141 | i = i + 1
142 | t[i] = fileinfo
143 | end
144 | pfile:close()
145 | pfile = popen("ls -lh \""..directory.."\" | egrep '^l' ;")
146 | for fileinfo in pfile:lines() do
147 | i = i + 1
148 | linkindex, _, linkpath = string.find(fileinfo, "->%s+(.+)$")
149 | local finalpath;
150 | if string.sub(linkpath, 1, 1) == "/" then
151 | finalpath = linkpath
152 | else
153 | finalpath = nixio.fs.realpath(directory..linkpath)
154 | end
155 | local linktype;
156 | if not finalpath then
157 | finalpath = linkpath;
158 | linktype = 'x'
159 | elseif nixio.fs.stat(finalpath, "type") == "dir" then
160 | linktype = 'z'
161 | else
162 | linktype = 'l'
163 | end
164 | fileinfo = string.sub(fileinfo, 2, linkindex - 1)
165 | fileinfo = linktype..fileinfo.."-> "..finalpath
166 | t[i] = fileinfo
167 | end
168 | pfile:close()
169 | return t
170 | end
171 |
172 | MIME_TYPES = {
173 | ["txt"] = "text/plain";
174 | ["conf"] = "text/plain";
175 | ["ovpn"] = "text/plain";
176 | ["log"] = "text/plain";
177 | ["js"] = "text/javascript";
178 | ["json"] = "application/json";
179 | ["css"] = "text/css";
180 | ["htm"] = "text/html";
181 | ["html"] = "text/html";
182 | ["patch"] = "text/x-patch";
183 | ["c"] = "text/x-csrc";
184 | ["h"] = "text/x-chdr";
185 | ["o"] = "text/x-object";
186 | ["ko"] = "text/x-object";
187 |
188 | ["bmp"] = "image/bmp";
189 | ["gif"] = "image/gif";
190 | ["png"] = "image/png";
191 | ["jpg"] = "image/jpeg";
192 | ["jpeg"] = "image/jpeg";
193 | ["svg"] = "image/svg+xml";
194 |
195 | ["zip"] = "application/zip";
196 | ["pdf"] = "application/pdf";
197 | ["xml"] = "application/xml";
198 | ["xsl"] = "application/xml";
199 | ["doc"] = "application/msword";
200 | ["ppt"] = "application/vnd.ms-powerpoint";
201 | ["xls"] = "application/vnd.ms-excel";
202 | ["odt"] = "application/vnd.oasis.opendocument.text";
203 | ["odp"] = "application/vnd.oasis.opendocument.presentation";
204 | ["pl"] = "application/x-perl";
205 | ["sh"] = "application/x-shellscript";
206 | ["php"] = "application/x-php";
207 | ["deb"] = "application/x-deb";
208 | ["iso"] = "application/x-cd-image";
209 | ["tgz"] = "application/x-compressed-tar";
210 |
211 | ["mp3"] = "audio/mpeg";
212 | ["ogg"] = "audio/x-vorbis+ogg";
213 | ["wav"] = "audio/x-wav";
214 |
215 | ["mpg"] = "video/mpeg";
216 | ["mpeg"] = "video/mpeg";
217 | ["avi"] = "video/x-msvideo";
218 | }
219 |
220 | function to_mime(filename)
221 | if type(filename) == "string" then
222 | local ext = filename:match("[^%.]+$")
223 |
224 | if ext and MIME_TYPES[ext:lower()] then
225 | return MIME_TYPES[ext:lower()]
226 | end
227 | end
228 |
229 | return "application/octet-stream"
230 | end
231 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-fileassistant/luasrc/view/fileassistant.htm:
--------------------------------------------------------------------------------
1 | <%+header%>
2 |
3 |
4 | File Assistant
5 |
17 |
18 |
19 |
20 | <%+footer%>
21 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-homeassistant/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (C) 2021 Baozhu Zuo
3 | #
4 |
5 | include $(TOPDIR)/rules.mk
6 |
7 | PKG_NAME:=luci-app-homeassistant
8 | LUCI_TITLE:=LuCI support for Home Assistant
9 | LUCI_DEPENDS:=+wget
10 | LUCI_PKGARCH:=all
11 | PKG_VERSION:=1.1
12 | PKG_RELEASE:=5
13 | PKG_MAINTAINER:=
14 |
15 | include $(TOPDIR)/feeds/luci/luci.mk
16 |
17 | # call BuildPackage - OpenWrt buildroot signature
18 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-homeassistant/root/usr/share/luci/menu.d/luci-app-homeassistant.json:
--------------------------------------------------------------------------------
1 | {
2 | "admin/services/homeassiant": {
3 | "title": "Home Assistant",
4 | "order": 90,
5 | "action": {
6 | "type": "view",
7 | "path": "homeassiant",
8 | "post": { "cbi.submit": true }
9 | },
10 | "depends": {
11 | "acl": [ "homeassiant" ],
12 | "uci": { "homeassiant": true }
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-homeassistant/root/usr/share/rpcd/acl.d/luci-app-homeassistant.json:
--------------------------------------------------------------------------------
1 | {
2 | "luci-app-homeassistant": {
3 | "description": "Grant UCI access for luci-app-homeassistant",
4 | "read": {
5 | "uci": [ "homeassistant" ]
6 | },
7 | "write": {
8 | "uci": [ "homeassistant" ]
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-node-red/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (C) 2021 Baozhu Zuo
3 | #
4 |
5 | include $(TOPDIR)/rules.mk
6 |
7 | PKG_NAME:=luci-app-node-red
8 | LUCI_TITLE:=LuCI support for Node RED
9 | LUCI_DEPENDS:=+wget +node-red
10 | LUCI_PKGARCH:=all
11 | PKG_VERSION:=1.1
12 | PKG_RELEASE:=5
13 | PKG_MAINTAINER:=
14 |
15 | include $(TOPDIR)/feeds/luci/luci.mk
16 |
17 | # call BuildPackage - OpenWrt buildroot signature
18 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-node-red/htdocs/luci-static/resources/view/node-red.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | 'require view';
3 | 'require form';
4 | 'require uci';
5 | 'require fs';
6 |
7 |
8 | return view.extend({
9 |
10 | handleToggleNodeRED: function () {
11 | },
12 |
13 | handleOpenWeb: function () {
14 | var port = uci.get('node-red', 'common', 'port');
15 | window.open('//'+window.location.hostname+':' + port);
16 | },
17 |
18 |
19 | load: function () {
20 |
21 | return Promise.all([
22 | uci.load('node-red'),
23 | fs.exec("/usr/libexec/node-red-ctrl", ['--state'])
24 | ]);
25 | },
26 |
27 | render: function (data) {
28 |
29 |
30 | var state = data[1];
31 |
32 |
33 | var m = new form.Map('node-red', _('Node RED'), _('Node Red'));
34 |
35 | var s = m.section(form.NamedSection, 'common', _('Status'));
36 |
37 | var o = s.option(form.Button, 'status', _('status'));
38 |
39 |
40 | if (state["stdout"] === "node-red started...\n") {
41 | o.inputtitle = _('Open Web Interface');
42 | o.inputstyle = 'apply';
43 | o.onclick = L.bind(this.handleOpenWeb, this, m);
44 | } else {
45 | o.inputtitle = _('Please start the node red service first');
46 | o.inputstyle = 'reset';
47 | o.onclick = L.bind(this.handleToggleNodeRED, this, m);
48 | }
49 |
50 |
51 | return m.render();
52 |
53 | }
54 |
55 | });
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-node-red/root/usr/libexec/node-red-ctrl:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # parse commandline options
4 | while [ ! -z "$1" ]; do
5 | case $1 in
6 | --start)
7 |
8 | pid=`pidof node-red`
9 | if [ -z "$pid" ]; then
10 | if [ ! -z $2 ]; then
11 | /usr/bin/node-red --port $2 &
12 | else
13 | /usr/bin/node-red &
14 | fi
15 | else
16 | echo "node-red started..."
17 | fi
18 |
19 | ;;
20 | --state)
21 |
22 | pid=`pidof node-red`
23 | if [ ! -z "$pid" ]; then
24 | echo "node-red started..."
25 | else
26 | echo "node-red stopped..."
27 | fi
28 |
29 | ;;
30 | --stop)
31 | pid=`pidof node-red`
32 |
33 | if [ ! ["" == "$pid"] ]; then
34 | kill -9 $pid
35 | else
36 | echo "node-red stopped..."
37 | fi
38 | ;;
39 |
40 | esac
41 |
42 | shift
43 | done
44 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-node-red/root/usr/share/luci/menu.d/luci-app-node-red.json:
--------------------------------------------------------------------------------
1 | {
2 | "admin/services/node-red": {
3 | "title": "Node RED",
4 | "order": 90,
5 | "action": {
6 | "type": "view",
7 | "path": "node-red",
8 | "post": { "cbi.submit": true }
9 | },
10 | "depends": {
11 | "acl": [ "luci-app-node-red" ],
12 | "uci": { "node-red": true }
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-node-red/root/usr/share/rpcd/acl.d/luci-app-node-red.json:
--------------------------------------------------------------------------------
1 | {
2 | "luci-app-node-red": {
3 | "description": "Grant UCI access for luci-app-node-red",
4 | "read": {
5 | "file": {
6 | "/usr/libexec/node-red-ctrl": [ "exec" ]
7 | },
8 | "uci": [ "node-red" ]
9 | },
10 | "write": {
11 | "uci": [ "node-red" ]
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-syncdial/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (C) 2008-2014 The LuCI Team
3 | #
4 | # This is free software, licensed under the Apache License, Version 2.0 .
5 | #
6 |
7 | include $(TOPDIR)/rules.mk
8 |
9 | LUCI_TITLE:=Virtual WAN config generator
10 | LUCI_DEPENDS:=+kmod-macvlan +luci-app-mwan3
11 | PKG_VERSION:=2.0
12 | PKG_RELEASE:=25
13 |
14 | include $(TOPDIR)/feeds/luci/luci.mk
15 |
16 | # call BuildPackage - OpenWrt buildroot signature
17 | #Makefile for syncdial
18 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-syncdial/luasrc/controller/syncdial.lua:
--------------------------------------------------------------------------------
1 | module("luci.controller.syncdial",package.seeall)
2 | function index()
3 | if not nixio.fs.access("/etc/config/syncdial") then
4 | return
5 | end
6 |
7 | entry({"admin", "network", "syncdial"}, cbi("syncdial"), _("Multi-Lan Multicast"), 103).dependent = true
8 | entry({"admin", "network", "macvlan_redial"}, call("redial"), nil).leaf = true
9 | end
10 |
11 | function redial()
12 | os.execute("killall -9 pppd")
13 | end
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-syncdial/luasrc/model/cbi/syncdial.lua:
--------------------------------------------------------------------------------
1 | local e=require"nixio.fs"
2 | require("luci.tools.webadmin")
3 | local e="mwan3 status | grep -c \"is online and tracking is active\""
4 | local e=io.popen(e,"r")
5 | local t=e:read("*a")
6 | e:close()
7 | m=Map("syncdial",translate("Multi-Lan Multicast"),
8 | translate("Using the macvlan to create more WAN,which support the concurrency of Multicast
THe number of onLine WAN:")..t)
9 | s=m:section(TypedSection,"syncdial",translate(" "))
10 | s.anonymous=true
11 | o=s:option(Flag,"enabled","Enable")
12 | o.rmempty=false
13 | o=s:option(Flag,"syncon","Enable the Concurrency")
14 | o.rmempty=false
15 | o=s:option(ListValue,"dial_type",translate("The type of Multicast"))
16 | o:value("1",translate("single Lan to Multicast"))
17 | o:value("2",translate("Double Lan to Multicast"))
18 | o.rmempty=false
19 | o=s:option(Value,"wanselect",translate("Choose the Interface"),translate("Choose the Interface to Multicast,such as Wan"))
20 | luci.tools.webadmin.cbi_add_networks(o)
21 | o.optional=false
22 | o.rmempty=false
23 | o=s:option(Value,"wannum","The number of virtual Wan")
24 | o.datatype="range(0,249)"
25 | o.optional=false
26 | o.default=1
27 | o=s:option(Flag,"bindwan","Blinding the Entity Interface")
28 | o.rmempty=false
29 | o=s:option(Value,"wanselect2",translate("choose the second Interface to connect Internet"),translate("choose the second Interface to Multicast,such as wan2"))
30 | luci.tools.webadmin.cbi_add_networks(o)
31 | o.optional=false
32 | o:depends("dial_type","2")
33 | o=s:option(Value,"wannum2",translate("The number of Virtual Wan"),translate("Set the number of second Line"))
34 | o.datatype="range(0,249)"
35 | o.optional=false
36 | o.default=1
37 | o:depends("dial_type","2")
38 | o=s:option(Flag,"bindwan2","Blinding the Entity Interface","Blinding the interface of the Entity Interface and Virtual")
39 | o.rmempty=false
40 | o:depends("dial_type","2")
41 | o=s:option(Flag,"dialchk","Enable the scan of the Outline")
42 | o.rmempty=false
43 | o=s:option(Value,"dialnum","The MIN Number of the online interfaces","It will be reconnect if the online interfaces are less than this number")
44 | o.datatype="range(0,248)"
45 | o.optional=false
46 | o.default=2
47 | o=s:option(Value,"dialnum2","The MIN Number of the online interfaces on second Line","It will be reconnect if the online interfaces are less than this number")
48 | o.datatype="range(0,248)"
49 | o.optional=false
50 | o.default=2
51 | o:depends("dial_type","2")
52 | o=s:option(Value,"dialwait","The waitting Time of reconnect","THe waitting time of reconnect. Unit:second MIn:5second")
53 | o.datatype="and(uinteger,min(5))"
54 | o.optional=false
55 | o=s:option(Flag,"old_frame","Using the old_frame of Macvlan")
56 | o.rmempty=false
57 | o=s:option(Flag,"nomwan","Stop the Auto of the Old MWAN3 configuration","choose your own way to configure MWAN")
58 | o.rmempty=false
59 | o=s:option(DummyValue,"_redial","Reconnect")
60 | o.template="syncdial/redial_button"
61 | o.width="10%"
62 | return m
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-syncdial/luasrc/view/syncdial/redial_button.htm:
--------------------------------------------------------------------------------
1 | <%+cbi/valueheader%>
2 |
3 |
15 |
16 |
17 | <%+cbi/valuefooter%>
18 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-syncdial/root/bin/genwancfg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #macvlan及PPPoE拨号接口配置批量自动生成脚本
3 | #Copyright (C) 2016
4 | . /lib/functions.sh
5 |
6 | #检测IP列表
7 | chk_ip_list="www.baidu.com 114.114.114.114 119.29.29.29"
8 | origfirewall=$(uci get firewall.@zone[1].network)
9 | backupdev=$(uci get syncdial.config.devbackup)
10 | norun=$(echo $origfirewall|grep vwan)
11 | nomwan=$(uci get syncdial.config.nomwan)
12 | wanselect=$(uci get syncdial.config.wanselect)
13 | wannum=$(uci get syncdial.config.wannum)
14 | oldframe=$(uci get syncdial.config.old_frame)
15 | bindwan=$(uci -q get syncdial.config.bindwan)
16 |
17 | dial_type=$(uci get syncdial.config.dial_type)
18 | [ "$dial_type" -eq 2 ] && {
19 | wanselect2=$(uci get syncdial.config.wanselect2)
20 | [ $? -ne 0 ] && {
21 | logger -t Syncppp "You must select another pppoe interface ! 启用双线多拨必须同时选择第二个外网接口!"
22 | return 0
23 | }
24 |
25 | wannum2=$(uci get syncdial.config.wannum2)
26 | [ $? -ne 0 ] && {
27 | logger -t Syncppp "When dualdial is enabled, the number of the second virtual WAN cannot be blank! 启用双线多拨时第二个虚拟WAN接口数不能为空!"
28 | return 0
29 | }
30 | bindwan2=$(uci -q get syncdial.config.bindwan2)
31 | }
32 |
33 | #添加MWAN负载均衡相关配置
34 | #$1:接口名称
35 | mwan_cfg_add() {
36 | #gen mwan3_interface
37 | uci set mwan3.${1}=interface
38 | uci set mwan3.${1}.enabled=1
39 | uci set mwan3.${1}.count=2
40 | uci set mwan3.${1}.timeout=2
41 | uci set mwan3.${1}.interval=5
42 | uci set mwan3.${1}.down=4
43 | uci set mwan3.${1}.up=1
44 | for i in $chk_ip_list
45 | do
46 | uci add_list mwan3.${1}.track_ip="$i"
47 | done
48 | uci set mwan3.${1}.reliability=1
49 | uci set mwan3.${1}.initial_state=online
50 | uci set mwan3.${1}.family=ipv4
51 | uci set mwan3.${1}.track_method=ping
52 | uci set mwan3.${1}.size=56
53 | uci set mwan3.${1}.failure_interval=5
54 | uci set mwan3.${1}.recovery_interval=5
55 | uci set mwan3.${1}.flush_conntrack=never
56 | #gen mwan3_member
57 | uci set mwan3.${1}_m1_w1=member
58 | uci set mwan3.${1}_m1_w1.interface=${1}
59 | uci set mwan3.${1}_m1_w1.metric=1
60 | uci set mwan3.${1}_m1_w1.weight=1
61 | #gen mwan3_policy
62 | uci add_list mwan3.balanced.use_member=${1}_m1_w1
63 | }
64 |
65 | #删除MWAN负载均衡相关配置
66 | #$1:接口名称
67 | mwan_cfg_del() {
68 | uci del mwan3.${1}
69 | uci del mwan3.${1}_m1_w1
70 | uci del_list mwan3.balanced.use_member=${1}_m1_w1
71 | }
72 |
73 | #添加macvlan设备
74 | #$1:设虚拟备名称 $2:原始设备名称
75 | macvlan_dev_add() {
76 | uci set network.macvlandev_${1}=device
77 | uci set network.macvlandev_${1}.name=${1}
78 | uci set network.macvlandev_${1}.ifname=${2}
79 | uci set network.macvlandev_${1}.type=macvlan
80 | }
81 |
82 | #添加PPPoE接口
83 | #$1:接口名称 $2:设备名称 $3:账户 $4:密码 $5:网关跃点
84 | pppoe_if_add() {
85 | #gen vwan macaddr
86 | NEW_MACADDR=$(openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/.$//')
87 | #gen wan if
88 | uci set network.${1}=interface
89 | uci set network.${1}.ifname=${3}
90 | uci set network.${1}.proto=pppoe
91 | uci set network.${1}.username=${4}
92 | uci set network.${1}.password=${5}
93 | uci set network.${1}.metric=${2}
94 | uci set network.${1}.macaddr=$NEW_MACADDR
95 | #gen firewall
96 | uci add_list firewall.@zone[1].network=${1}
97 | }
98 |
99 |
100 | orig_firewall_add() {
101 | need_del_rule=`uci -q get firewall.@zone[1].network | awk -F"'" '{print $2}'`
102 | uci del_list firewall.@zone[1].network="$need_del_rule"
103 | for k in $( seq 1 250 )
104 | do
105 | origdev=$(echo $origfirewall | cut -d " " -f$k)
106 | if [ -z "$origdev" ]; then
107 | break
108 | fi
109 | [ -z "$(uci get firewall.@zone[1].network | grep -w $origdev)" ] && uci add_list firewall.@zone[1].network=$origdev
110 | done
111 | }
112 |
113 | apply_cfg() {
114 | uci commit
115 | #/etc/init.d/network restart &
116 | logger -t Syncppp "Apply syncdial configuaration."
117 | ifup wan &
118 | killall pppconnectcheck
119 | }
120 |
121 | general_config_load() {
122 | config_load 'syncdial'
123 | config_get_bool enabled 'config' 'enabled'
124 | config_get_bool old_frame 'config' 'old_frame'
125 | congig_get_bool dial_type 'config' 'dial_type'
126 |
127 | if [ "$enabled" -eq 0 ]; then
128 | if [ "$old_frame" -eq 1 ]; then
129 | mwan_cfg_add $wanselect
130 | if [ "$dial_type" -eq 2 ]; then
131 | mwan_cfg_add $wanselect2
132 | fi
133 | fi
134 | echo "Disabled.Exit now."
135 | apply_cfg
136 | exit 1
137 | fi
138 |
139 | config_load 'network'
140 | config_get pppoe_user $wanselect 'username'
141 | config_get pppoe_password $wanselect 'password'
142 | pppoe_ifname=$(uci get network.$wanselect.ifname)
143 | [ "$dial_type" -eq 2 ] && {
144 | config_get pppoe_user2 $wanselect2 'username'
145 | config_get pppoe_password2 $wanselect2 'password'
146 | pppoe_ifname2=$(uci get network.$wanselect2.ifname)
147 | }
148 |
149 | }
150 |
151 | check_remove_device() {
152 | local devcfg=${1}
153 | [ ${devcfg::11} == 'macvlandev_' ] && uci del network.${devcfg}
154 | }
155 |
156 | check_remove_interface() {
157 | local ifcfg=${1}
158 | [ ${ifcfg::4} == 'vwan' ] && {
159 | uci del network.${ifcfg}
160 | uci del_list firewall.@zone[1].network=${ifcfg}
161 | [ "$nomwan" -ne 1 ] && mwan_cfg_del ${ifcfg}
162 | }
163 | uci set firewall.@zone[1].network="$backupdev"
164 | }
165 |
166 | general_config_remove() {
167 | config_load network
168 | config_foreach check_remove_device 'device'
169 | config_foreach check_remove_interface 'interface'
170 | all_macvlans=`ip link show |grep macvlan | awk -F":" '{print $2}' | awk -F"@" '{print $1}'`
171 | [ -n "$all_macvlans" ] && {
172 | for macvlan in $all_macvlans
173 | do
174 | ip link delete $macvlan
175 | done
176 | }
177 | [ "$(uci get network.$wanselect.proto)" == "none" ] && {
178 | uci set network.$wanselect.proto=pppoe
179 | }
180 |
181 | if [ "$oldframe" -eq 0 ]; then
182 | [ "$wanselect" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f1)" ] && \
183 | [ "$wanselect" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f2)" ] && \
184 | [ "$nomwan" -ne 1 ] && mwan_cfg_del $wanselect
185 | else
186 | [ "$nomwan" -ne 1 ] && mwan_cfg_del $wanselect
187 | fi
188 |
189 | [ "$dial_type" -eq 2 ] && {
190 | [ $(uci get network.$wanselect2.proto) == "none" ] && {
191 | uci set network.$wanselect2.proto=pppoe
192 | }
193 |
194 | if [ "$oldframe" -eq 0 ]; then
195 | [ "$wanselect2" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f1)" ] && \
196 | [ "$wanselect2" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f2)" ] && \
197 | [ "$nomwan" -ne 1 ] && mwan_cfg_del $wanselect2
198 | else
199 | [ "$nomwan" -ne 1 ] && mwan_cfg_del $wanselect2
200 | fi
201 | }
202 | }
203 |
204 |
205 | [ -z "$norun" ] && uci set syncdial.config.devbackup="$origfirewall" && uci commit syncdial
206 | general_config_remove
207 | general_config_load
208 |
209 | uci set network.$wanselect.metric=40
210 | if [ "$wannum" -gt 0 ]; then
211 | [ "$old_frame" -eq 1 ] && {
212 | uci set network.$wanselect.proto=none
213 | ifname=$(uci get network.$wanselect.ifname)
214 | for i in $(seq 1 $wannum)
215 | do
216 | ip link add link $ifname name macvlan$i type macvlan
217 | ifconfig macvlan$i hw ether $(echo $(cat /sys/class/net/$ifname/address|awk -F ":" '{print $1":"$2":"$3":"$4":"$5":" }')$(echo "" | awk -F ":" '{printf("%X\n", 16+i);}' i=$i))
218 | ifconfig macvlan$i up
219 | done
220 | }
221 | [ "$wanselect" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f1)" ] && \
222 | [ "$wanselect" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f2)" ] && \
223 | [ "$old_frame" -eq 0 -a "$nomwan" -ne 1 ] && mwan_cfg_add $wanselect
224 |
225 |
226 | for i in $(seq 1 $wannum)
227 | do
228 | [ "$old_frame" -eq 0 ] && macvlan_dev_add macvlan$i $pppoe_ifname
229 | if [ "$bindwan" != "" -a "$bindwan" == "1" ]; then
230 | pppoe_if_add vwan$i $((40+$i)) $pppoe_ifname $pppoe_user $pppoe_password
231 | else
232 | pppoe_if_add vwan$i $((40+$i)) macvlan$i $pppoe_user $pppoe_password
233 | fi
234 | [ "$nomwan" -ne 1 ] && mwan_cfg_add vwan$i $((40+$i))
235 | done
236 | else
237 | [ "$nomwan" -ne 1 ] && mwan_cfg_add $wanselect
238 | fi
239 |
240 | ###dualdial configuration
241 | [ "$(uci -q get syncdial.config.dial_type)" = "2" ] && {
242 |
243 | uci set network.$wanselect2.metric=60
244 | if [ "$wannum2" -gt 0 ]; then
245 | [ "$old_frame" -eq 1 ] && {
246 | uci set network.$wanselect2.proto=none
247 | ifname2=$(uci get network.$wanselect2.ifname)
248 | for i in $(seq 1 $wannum2)
249 | do
250 | ip link add link $ifname2 name macvlan$(($wannum+$i)) type macvlan
251 | ifconfig macvlan$(($wannum+$i)) hw ether $(echo $(cat /sys/class/net/$ifname2/address|awk -F ":" '{print $1":"$2":"$3":"$4":"$5":" }')$(echo "" | awk -F ":" '{printf("%X\n", 16+i);}' i=$i))
252 | ifconfig macvlan$(($wannum+$i)) up
253 | done
254 | }
255 | [ "$wanselect2" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f1)" ] && \
256 | [ "$wanselect2" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f2)" ] && \
257 | [ "$old_frame" -eq 0 -a "$nomwan" -ne 1 ] && mwan_cfg_add $wanselect2
258 |
259 |
260 | for i in $(seq 1 $wannum2)
261 | do
262 | [ "$old_frame" -eq 0 ] && macvlan_dev_add macvlan$(($wannum+$i)) $pppoe_ifname2
263 | if [ "$bindwan2" != "" -a "$bindwan2" == "1" ]; then
264 | pppoe_if_add vwan$(($wannum+$i)) $((60+$i)) $pppoe_ifname2 $pppoe_user2 $pppoe_password2
265 | else
266 | pppoe_if_add vwan$(($wannum+$i)) $((60+$i)) macvlan$(($wannum+$i)) $pppoe_user2 $pppoe_password2
267 | fi
268 | [ "$nomwan" -ne 1 ] && mwan_cfg_add vwan$(($wannum+$i)) $((60+$i))
269 | done
270 | else
271 | [ "$nomwan" -ne 1 ] && mwan_cfg_add $wanselect2
272 | fi
273 | }
274 |
275 | orig_firewall_add
276 | apply_cfg
277 |
278 | return 0
279 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-syncdial/root/etc/config/syncdial:
--------------------------------------------------------------------------------
1 |
2 | config syncdial 'config'
3 | option syncon '1'
4 | option dialwait '25'
5 | option dialchk '1'
6 | option nomwan '0'
7 | option wanselect 'wan'
8 | option dial_type '2'
9 | option wannum '3'
10 | option wanselect2 'wan2'
11 | option wannum2 '2'
12 | option dialnum '3'
13 | option dialnum2 '2'
14 | option old_frame '1'
15 | option devbackup 'wan wan6 wan2'
16 | option bindwan '0'
17 | option bindwan2 '0'
18 | option enabled '0'
19 |
20 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-syncdial/root/etc/hotplug.d/iface/01-dialcheck:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ "$ACTION" = "ifdown" ] && pppconnectcheck &
3 |
4 | wanselect=$(uci get syncdial.config.wanselect)
5 | [ "$(uci get syncdial.config.dial_type)" = "2" ] && {
6 | wanselect2=$(uci get syncdial.config.wanselect2)
7 | }
8 |
9 | [ "$(uci get syncdial.config.enabled)" = "1" ] && \
10 | [ "$(uci get syncdial.config.old_frame)" = "1" ] && \
11 | [ "$DEVICE" = "$(uci get network.$wanselect.ifname)" ] && \
12 | [ "$ACTION" = "ifup" ] && {
13 | ifname=$(uci get network.$wanselect.ifname)
14 | wannum=$(uci get syncdial.config.wannum)
15 | for i in $(seq 1 $wannum)
16 | do
17 | [ -d /sys/class/net/macvlan$i ] || {
18 | ip link add link $ifname name macvlan$i type macvlan
19 | ifconfig macvlan$i hw ether $(echo $(cat /sys/class/net/$ifname/address|awk -F ":" '{print $1":"$2":"$3":"$4":"$5":" }')$(echo "" | awk -F ":" '{printf("%X\n", 16+i);}' i=$i))
20 | ifconfig macvlan$i up
21 | }
22 | done
23 |
24 | [ "$(uci get syncdial.config.dial_type)" = "2" ] && {
25 | ifname2=$(uci get network.$wanselect2.ifname)
26 | wannum2=$(uci get syncdial.config.wannum2)
27 | for i in $(seq 1 $wannum2)
28 | do
29 | [ -d /sys/class/net/macvlan$(($wannum+$i)) ] || {
30 | ip link add link $ifname2 name macvlan$(($wannum+$i)) type macvlan
31 | ifconfig macvlan$(($wannum+$i)) hw ether $(echo $(cat /sys/class/net/$ifname2/address|awk -F ":" '{print $1":"$2":"$3":"$4":"$5":" }')$(echo "" | awk -F ":" '{printf("%X\n", 16+i);}' i=$i))
32 | ifconfig macvlan$(($wannum+$i)) up
33 | }
34 | done
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-syncdial/root/etc/hotplug.d/iface/01-mvifcreate:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | [ "$(uci get syncdial.config.enabled)" = "1" ] && \
3 | [ "$(uci get syncdial.config.old_frame)" = "1" ] && \
4 | [ "$DEVICE" = "$(uci get network.wan.ifname)" ] && \
5 | [ "$ACTION" = "ifup" ] && {
6 | ifname=$(uci get network.wan.ifname)
7 | wannum=$(uci get syncdial.config.wannum)
8 | for i in $(seq 1 $wannum)
9 | do
10 | [ -d /sys/class/net/macvlan$i ] || {
11 | ip link add link $ifname name macvlan$i type macvlan
12 | ifconfig macvlan$i hw ether $(echo $(cat /sys/class/net/$ifname/address|awk -F ":" '{print $1":"$2":"$3":"$4":"$5":" }')$(echo "" | awk -F ":" '{printf("%X\n", 16+i);}' i=$i))
13 | ifconfig macvlan$i up
14 | }
15 | done
16 | }
17 |
--------------------------------------------------------------------------------
/openwrt/packages/luci-app-syncdial/root/etc/uci-defaults/luci-syncdial:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | touch /etc/config/syncdial
3 |
4 | uci -q batch <<-EOF >/dev/null
5 | delete ucitrack.@syncdial[-1]
6 | add ucitrack syncdial
7 | set ucitrack.@syncdial[-1].exec='/bin/genwancfg'
8 | commit ucitrack
9 | EOF
10 |
11 | rm -f /tmp/luci-indexcache
12 | exit 0
13 |
--------------------------------------------------------------------------------
/openwrt/packages/ntfs3-mount/Makefile:
--------------------------------------------------------------------------------
1 | include $(TOPDIR)/rules.mk
2 |
3 | PKG_NAME:=ntfs3-mount
4 | PKG_RELEASE:=2
5 |
6 | include $(INCLUDE_DIR)/package.mk
7 |
8 | define Package/ntfs3-mount
9 | SECTION:=utils
10 | CATEGORY:=Utilities
11 | SUBMENU:=Filesystem
12 | TITLE:=NTFS mount script for Paragon NTFS3 driver
13 | DEPENDS:=+kmod-fs-ntfs3-oot
14 | PKGARCH:=all
15 | endef
16 |
17 | define Build/Configure
18 | endef
19 |
20 | define Build/Compile
21 | endef
22 |
23 | define Package/ntfs3-mount/install
24 | $(INSTALL_DIR) $(1)/sbin
25 | $(INSTALL_BIN) ./files/mount.ntfs $(1)/sbin
26 | endef
27 |
28 | $(eval $(call BuildPackage,ntfs3-mount))
29 |
--------------------------------------------------------------------------------
/openwrt/packages/ntfs3-mount/files/mount.ntfs:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | mount -t ntfs3 -o iocharset=utf8 "$@"
3 |
--------------------------------------------------------------------------------
/openwrt/packages/ntfs3-oot/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # This is free software, licensed under the GNU General Public License v2.
3 | # See /LICENSE for more information.
4 | #
5 |
6 | include $(TOPDIR)/rules.mk
7 | include $(INCLUDE_DIR)/kernel.mk
8 |
9 | PKG_NAME:=ntfs3-oot
10 | PKG_RELEASE:=2
11 |
12 | PKG_SOURCE_PROTO:=git
13 | PKG_SOURCE_URL:=https://github.com/LGA1150/ntfs3-oot.git
14 | PKG_SOURCE_DATE:=2021-07-05
15 | PKG_SOURCE_VERSION:=46d199e7d7302879b23ad20097ba53b152257288
16 | PKG_MIRROR_HASH:=f07253ec864887c121177fc5b358c21249af0483e4dab0d5157410db618c0990
17 |
18 | PKG_MAINTAINER:=
19 | PKG_LICENSE:=GPL-2.0-only
20 |
21 | include $(INCLUDE_DIR)/package.mk
22 |
23 | define KernelPackage/fs-ntfs3-oot
24 | SECTION:=kernel
25 | CATEGORY:=Kernel modules
26 | SUBMENU:=Filesystems
27 | TITLE:=Fully functional NTFS Read-Write driver
28 | FILES:=$(PKG_BUILD_DIR)/ntfs3.ko
29 | AUTOLOAD:=$(call AutoProbe,ntfs3)
30 | DEPENDS:= +kmod-nls-utf8
31 | endef
32 |
33 | define KernelPackage/fs-ntfs3-oot/description
34 | This package provides the kernel module for ntfs3.
35 | endef
36 |
37 | define Build/Compile
38 | $(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" \
39 | EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
40 | $(PKG_EXTRA_KCONFIG) \
41 | CONFIG_NTFS3_FS=m \
42 | modules
43 | endef
44 |
45 | $(eval $(call KernelPackage,fs-ntfs3-oot))
46 |
--------------------------------------------------------------------------------
/openwrt/packages/ntfs3-oot/patches/100-compat-mount.patch:
--------------------------------------------------------------------------------
1 | --- a/super.c
2 | +++ b/super.c
3 | @@ -219,7 +219,7 @@ enum Opt {
4 | Opt_showmeta,
5 | Opt_acl,
6 | Opt_noatime,
7 | - Opt_nls,
8 | + Opt_iocharset,
9 | Opt_prealloc,
10 | Opt_no_acs_rules,
11 | Opt_err,
12 | @@ -239,7 +239,7 @@ static const match_table_t ntfs_tokens = {
13 | { Opt_acl, "acl" },
14 | { Opt_noatime, "noatime" },
15 | { Opt_showmeta, "showmeta" },
16 | - { Opt_nls, "nls=%s" },
17 | + { Opt_iocharset, "iocharset=%s" },
18 | { Opt_prealloc, "prealloc" },
19 | { Opt_no_acs_rules, "no_acs_rules" },
20 | { Opt_err, NULL },
21 | @@ -342,7 +342,7 @@ static noinline int ntfs_parse_options(struct super_block *sb, char *options,
22 | case Opt_showmeta:
23 | opts->showmeta = 1;
24 | break;
25 | - case Opt_nls:
26 | + case Opt_iocharset:
27 | match_strlcpy(nls_name, &args[0], sizeof(nls_name));
28 | break;
29 | case Opt_prealloc:
30 | @@ -581,9 +581,9 @@ static int ntfs_show_options(struct seq_file *m, struct dentry *root)
31 | if (opts->dmask)
32 | seq_printf(m, ",dmask=%04o", ~opts->fs_dmask_inv);
33 | if (opts->nls)
34 | - seq_printf(m, ",nls=%s", opts->nls->charset);
35 | + seq_printf(m, ",iocharset=%s", opts->nls->charset);
36 | else
37 | - seq_puts(m, ",nls=utf8");
38 | + seq_puts(m, ",iocharset=utf8");
39 | if (opts->sys_immutable)
40 | seq_puts(m, ",sys_immutable");
41 | if (opts->discard)
42 |
--------------------------------------------------------------------------------
/openwrt/packages/packages.list:
--------------------------------------------------------------------------------
1 | {
2 | "repo": "https://github.com/Seeed-Studio/seeed-linux-openwrt",
3 | "branch": "packages",
4 | "packages": [
5 | {
6 | "name": "luci-app-diskman",
7 | "author": "lisaac",
8 | "url": "https://github.com/lisaac/luci-app-diskman",
9 | "branch": "master",
10 | "items": [
11 | "*"
12 | ]
13 | },
14 | {
15 | "name": "luci-app-dockerman",
16 | "author": "lisaac",
17 | "url": "https://github.com/lisaac/luci-app-dockerman",
18 | "branch": "master",
19 | "items": [
20 | "*"
21 | ]
22 | },
23 | {
24 | "name": "luci-lib-docker",
25 | "author": "lisaac",
26 | "url": "https://github.com/lisaac/luci-lib-docker",
27 | "branch": "master",
28 | "items": [
29 | "*"
30 | ]
31 | },
32 | {
33 | "name": "luci-app-UUGameAcc",
34 | "author": "BCYDTZ",
35 | "url": "https://github.com/BCYDTZ/luci-app-UUGameAcc",
36 | "branch": "master",
37 | "items": [
38 | "*"
39 | ]
40 | },
41 | {
42 | "name": "luci-app-LingTiGameAcc",
43 | "author": "esirplayground",
44 | "url": "https://github.com/esirplayground/luci-app-LingTiGameAcc",
45 | "branch": "master",
46 | "items": [
47 | "*"
48 | ]
49 | },
50 | {
51 | "name": "LingTiGameAcc",
52 | "author": "esirplayground",
53 | "url": "https://github.com/esirplayground/LingTiGameAcc",
54 | "branch": "master",
55 | "items": [
56 | "*"
57 | ]
58 | },
59 | {
60 | "name": "luci-app-webadmin",
61 | "author": "awesome-openwrt",
62 | "url": "https://github.com/awesome-openwrt/luci-app-webadmin",
63 | "branch": "master",
64 | "items": [
65 | "*"
66 | ]
67 | },
68 | {
69 | "name": "luci-theme-argon",
70 | "author": "jerrykuku",
71 | "url": "https://github.com/jerrykuku/luci-theme-argon",
72 | "branch": "master",
73 | "items": [
74 | "*"
75 | ]
76 | },
77 | {
78 | "name": "luci-app-argon-config",
79 | "author": "jerrykuku",
80 | "url": "https://github.com/jerrykuku/luci-app-argon-config",
81 | "branch": "master",
82 | "items": [
83 | "*"
84 | ]
85 | },
86 | {
87 | "name": "packages",
88 | "author": "seeed",
89 | "url": "https://github.com/Seeed-Studio/seeed-linux-openwrt",
90 | "branch": "main",
91 | "items": [
92 | "openwrt/packages"
93 | ]
94 | },
95 | {
96 | "name": "lede",
97 | "author": "lean",
98 | "url": "https://github.com/coolsnowwolf/lede",
99 | "branch": "master",
100 | "items": [
101 | "LICENSES",
102 | "package/lean/adbyby",
103 | "package/lean/autocore",
104 | "package/lean/autosamba",
105 | "package/lean/csstidy",
106 | "package/lean/ddns-scripts_aliyun",
107 | "package/lean/ddns-scripts_dnspod",
108 | "package/lean/dsmboot",
109 | "package/lean/ipv6-helper",
110 | "package/lean/k3-brcmfmac4366c-firmware",
111 | "package/lean/k3screenctrl",
112 | "package/lean/libcryptopp",
113 | "package/lean/mentohust",
114 | "package/lean/microsocks",
115 | "package/lean/mt",
116 | "package/lean/n2n_v2",
117 | "package/lean/polarssl",
118 | "package/lean/ps3netsrv",
119 | "package/lean/r8125",
120 | "package/lean/r8152",
121 | "package/lean/rclone",
122 | "package/lean/shortcut-fe",
123 | "package/lean/srelay",
124 | "package/lean/wol",
125 | "package/lean/wxbase"
126 | ]
127 | },
128 | {
129 | "name": "luci",
130 | "author": "lean",
131 | "url": "https://github.com/coolsnowwolf/luci",
132 | "branch": "master",
133 | "items": [
134 | "applications/luci-app-accesscontrol",
135 | "applications/luci-app-adbyby-plus",
136 | "applications/luci-app-amule",
137 | "applications/luci-app-arpbind",
138 | "applications/luci-app-autoreboot",
139 | "applications/luci-app-cifsd",
140 | "applications/luci-app-cpufreq",
141 | "applications/luci-app-dnsforwarder",
142 | "applications/luci-app-easymesh",
143 | "applications/luci-app-familycloud",
144 | "applications/luci-app-fileassistant",
145 | "applications/luci-app-filetransfer",
146 | "applications/luci-app-guest-wifi",
147 | "applications/luci-app-haproxy-tcp",
148 | "applications/luci-app-ipsec-vpnd",
149 | "applications/luci-app-jd-dailybonus",
150 | "applications/luci-app-kodexplorer",
151 | "applications/luci-app-mwan3helper",
152 | "applications/luci-app-n2n_v2",
153 | "applications/luci-app-netdata",
154 | "applications/luci-app-nfs",
155 | "applications/luci-app-pppoe-relay",
156 | "applications/luci-app-pptp-server",
157 | "applications/luci-app-ps3netsrv",
158 | "applications/luci-app-qbittorrent",
159 | "applications/luci-app-ramfree",
160 | "applications/luci-app-rclone",
161 | "applications/luci-app-softethervpn",
162 | "applications/luci-app-ssrserver-python",
163 | "applications/luci-app-turboacc",
164 | "applications/luci-app-usb-printer",
165 | "applications/luci-app-uugamebooster",
166 | "applications/luci-app-v2ray-server",
167 | "applications/luci-app-verysync",
168 | "applications/luci-app-vlmcsd",
169 | "applications/luci-app-wrtbwmon",
170 | "applications/luci-app-xlnetacc",
171 | "libs/luci-lib-fs",
172 | "protocols/luci-proto-bonding"
173 | ]
174 | },
175 | {
176 | "name": "packages",
177 | "author": "lean",
178 | "url": "https://github.com/coolsnowwolf/packages",
179 | "branch": "master",
180 | "items": [
181 | "multimedia/gmediarender",
182 | "net/amule",
183 | "net/dns2socks",
184 | "net/dnsforwarder",
185 | "net/dnsproxy",
186 | "net/ipt2socks",
187 | "net/microsocks",
188 | "net/pdnsd-alt",
189 | "net/polarssl",
190 | "net/qBittorrent-static",
191 | "net/qBittorrent",
192 | "net/rclone-ng",
193 | "net/rclone-webui-react",
194 | "net/rclone",
195 | "net/tcpping",
196 | "net/uugamebooster",
197 | "net/verysync",
198 | "net/vlmcsd",
199 | "libs/qtbase",
200 | "libs/qttools",
201 | "libs/rblibtorrent",
202 | "libs/wxbase"
203 | ]
204 | }
205 | ]
206 | }
--------------------------------------------------------------------------------
/openwrt/patches/0001-lan78xx-fixed-bandwitdh-and-throughput.patch:
--------------------------------------------------------------------------------
1 | From 350f7ca3bdc86f1c3641bfae66491d7cf0e23565 Mon Sep 17 00:00:00 2001
2 | From: LynnL4
3 | Date: Fri, 10 Mar 2023 06:46:44 +0000
4 | Subject: [PATCH] lan78xx: fixed bandwitdh and throughput
5 |
6 | ---
7 | .../patches-5.15/9999-0001-lan78xx.patch | 2896 +++++++++++++++++
8 | 1 file changed, 2896 insertions(+)
9 | create mode 100644 target/linux/bcm27xx/patches-5.15/9999-0001-lan78xx.patch
10 |
11 | diff --git a/target/linux/bcm27xx/patches-5.15/9999-0001-lan78xx.patch b/target/linux/bcm27xx/patches-5.15/9999-0001-lan78xx.patch
12 | new file mode 100644
13 | index 0000000..b3fa826
14 | --- /dev/null
15 | +++ b/target/linux/bcm27xx/patches-5.15/9999-0001-lan78xx.patch
16 | @@ -0,0 +1,2896 @@
17 | +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
18 | +index 2da884e..6fc2808 100644
19 | +--- a/drivers/net/usb/lan78xx.c
20 | ++++ b/drivers/net/usb/lan78xx.c
21 | +@@ -33,7 +33,7 @@
22 | +
23 | + #define DRIVER_AUTHOR "WOOJUNG HUH "
24 | + #define DRIVER_DESC "LAN78XX USB 3.0 Gigabit Ethernet Devices"
25 | +-#define DRIVER_NAME "lan78xx"
26 | ++#define DRIVER_NAME "lan78xx.napi20201111"
27 | +
28 | + #define TX_TIMEOUT_JIFFIES (5 * HZ)
29 | + #define THROTTLE_JIFFIES (HZ / 8)
30 | +@@ -47,25 +47,25 @@
31 | +
32 | + #define MAX_RX_FIFO_SIZE (12 * 1024)
33 | + #define MAX_TX_FIFO_SIZE (12 * 1024)
34 | +-#define DEFAULT_BURST_CAP_SIZE (MAX_TX_FIFO_SIZE)
35 | +-#define DEFAULT_BULK_IN_DELAY (0x0800)
36 | + #define MAX_SINGLE_PACKET_SIZE (9000)
37 | + #define DEFAULT_TX_CSUM_ENABLE (true)
38 | + #define DEFAULT_RX_CSUM_ENABLE (true)
39 | + #define DEFAULT_TSO_CSUM_ENABLE (true)
40 | + #define DEFAULT_VLAN_FILTER_ENABLE (true)
41 | + #define DEFAULT_VLAN_RX_OFFLOAD (true)
42 | +-#define TX_OVERHEAD (8)
43 | ++#define TX_ALIGNMENT (4)
44 | + #define RXW_PADDING 2
45 | +
46 | ++#define DEFAULT_U1_U2_INIT_ENABLE false
47 | ++
48 | ++#define MIN_IPV4_DGRAM 68
49 | ++
50 | + #define LAN78XX_USB_VENDOR_ID (0x0424)
51 | + #define LAN7800_USB_PRODUCT_ID (0x7800)
52 | + #define LAN7850_USB_PRODUCT_ID (0x7850)
53 | + #define LAN7801_USB_PRODUCT_ID (0x7801)
54 | + #define LAN78XX_EEPROM_MAGIC (0x78A5)
55 | + #define LAN78XX_OTP_MAGIC (0x78F3)
56 | +-#define AT29M2AF_USB_VENDOR_ID (0x07C9)
57 | +-#define AT29M2AF_USB_PRODUCT_ID (0x0012)
58 | +
59 | + #define MII_READ 1
60 | + #define MII_WRITE 0
61 | +@@ -80,6 +80,44 @@
62 | + WAKE_MCAST | WAKE_BCAST | \
63 | + WAKE_ARP | WAKE_MAGIC)
64 | +
65 | ++#define LAN78XX_NAPI_WEIGHT 64
66 | ++
67 | ++#define TX_URB_NUM 10
68 | ++#define TX_SS_URB_NUM TX_URB_NUM
69 | ++#define TX_HS_URB_NUM TX_URB_NUM
70 | ++#define TX_FS_URB_NUM TX_URB_NUM
71 | ++
72 | ++/* A single URB buffer must be large enough to hold a complete jumbo packet
73 | ++ */
74 | ++#define TX_SS_URB_SIZE (32 * 1024)
75 | ++#define TX_HS_URB_SIZE (16 * 1024)
76 | ++#define TX_FS_URB_SIZE (10 * 1024)
77 | ++
78 | ++#define RX_SS_URB_NUM 30
79 | ++#define RX_HS_URB_NUM 10
80 | ++#define RX_FS_URB_NUM 10
81 | ++#define RX_SS_URB_SIZE TX_SS_URB_SIZE
82 | ++#define RX_HS_URB_SIZE TX_HS_URB_SIZE
83 | ++#define RX_FS_URB_SIZE TX_FS_URB_SIZE
84 | ++
85 | ++#define SS_BURST_CAP_SIZE RX_SS_URB_SIZE
86 | ++#define SS_BULK_IN_DELAY 0x2000
87 | ++#define HS_BURST_CAP_SIZE RX_HS_URB_SIZE
88 | ++#define HS_BULK_IN_DELAY 0x2000
89 | ++#define FS_BURST_CAP_SIZE RX_FS_URB_SIZE
90 | ++#define FS_BULK_IN_DELAY 0x2000
91 | ++
92 | ++#define TX_CMD_LEN 8
93 | ++#define TX_SKB_MIN_LEN (TX_CMD_LEN + ETH_HLEN)
94 | ++#define LAN78XX_TSO_SIZE(dev) ((dev)->tx_urb_size - TX_SKB_MIN_LEN)
95 | ++
96 | ++#define RX_CMD_LEN 10
97 | ++#define RX_SKB_MIN_LEN (RX_CMD_LEN + ETH_HLEN)
98 | ++#define RX_MAX_FRAME_LEN(mtu) ((mtu) + ETH_HLEN + VLAN_HLEN)
99 | ++
100 | ++#define LAN78XX_MIN_MTU MIN_IPV4_DGRAM
101 | ++#define LAN78XX_MAX_MTU MAX_SINGLE_PACKET_SIZE
102 | ++
103 | + /* USB related defines */
104 | + #define BULK_IN_PIPE 1
105 | + #define BULK_OUT_PIPE 2
106 | +@@ -90,6 +128,15 @@
107 | + /* statistic update interval (mSec) */
108 | + #define STAT_UPDATE_TIMER (1 * 1000)
109 | +
110 | ++/* time to wait for MAC or FCT to stop (msec) */
111 | ++#define HW_DISABLE_TIMEOUT 10
112 | ++
113 | ++/* time to wait between polling MAC or FCT state */
114 | ++#define HW_DISABLE_DELAY 1
115 | ++
116 | ++/* max number of times to poll MAC or FCT state */
117 | ++#define HW_DISABLE_POLL_MAX (HW_DISABLE_TIMEOUT / HW_DISABLE_DELAY)
118 | ++
119 | + /* defines interrupts from interrupt EP */
120 | + #define MAX_INT_EP (32)
121 | + #define INT_EP_INTEP (31)
122 | +@@ -344,6 +391,7 @@ struct usb_context {
123 | + #define EVENT_DEV_ASLEEP 7
124 | + #define EVENT_DEV_OPEN 8
125 | + #define EVENT_STAT_UPDATE 9
126 | ++#define EVENT_DEV_DISCONNECT 10
127 | +
128 | + struct statstage {
129 | + struct mutex access_lock; /* for stats access */
130 | +@@ -368,15 +416,22 @@ struct lan78xx_net {
131 | + struct usb_interface *intf;
132 | + void *driver_priv;
133 | +
134 | +- int rx_qlen;
135 | +- int tx_qlen;
136 | ++ int tx_pend_data_len;
137 | ++ int n_tx_urbs;
138 | ++ int n_rx_urbs;
139 | ++ int rx_urb_size;
140 | ++ int tx_urb_size;
141 | ++
142 | ++ struct sk_buff_head rxq_free;
143 | ++ struct sk_buff_head rxq_overflow;
144 | ++ struct sk_buff_head rxq_done;
145 | + struct sk_buff_head rxq;
146 | ++ struct sk_buff_head txq_free;
147 | + struct sk_buff_head txq;
148 | +- struct sk_buff_head done;
149 | +- struct sk_buff_head rxq_pause;
150 | + struct sk_buff_head txq_pend;
151 | +
152 | +- struct tasklet_struct bh;
153 | ++ struct napi_struct napi;
154 | ++
155 | + struct delayed_work wq;
156 | +
157 | + int msg_enable;
158 | +@@ -384,19 +439,19 @@ struct lan78xx_net {
159 | + struct urb *urb_intr;
160 | + struct usb_anchor deferred;
161 | +
162 | ++ struct mutex dev_mutex; /* serialise open/stop wrt suspend/resume */
163 | + struct mutex phy_mutex; /* for phy access */
164 | + unsigned pipe_in, pipe_out, pipe_intr;
165 | +
166 | +- u32 hard_mtu; /* count any extra framing */
167 | +- size_t rx_urb_size; /* size for rx urbs */
168 | ++ unsigned int bulk_in_delay;
169 | ++ unsigned int burst_cap;
170 | +
171 | + unsigned long flags;
172 | +
173 | + wait_queue_head_t *wait;
174 | + unsigned char suspend_count;
175 | +
176 | +- unsigned maxpacket;
177 | +- struct timer_list delay;
178 | ++ unsigned int maxpacket;
179 | + struct timer_list stat_monitor;
180 | +
181 | + unsigned long data[5];
182 | +@@ -427,25 +482,138 @@ static int msg_level = -1;
183 | + module_param(msg_level, int, 0);
184 | + MODULE_PARM_DESC(msg_level, "Override default message level");
185 | +
186 | +-/* TSO seems to be having some issue with Selective Acknowledge (SACK) that
187 | +- * results in lost data never being retransmitted.
188 | +- * Disable it by default now, but adds a module parameter to enable it for
189 | +- * debug purposes (the full cause is not currently understood).
190 | +- */
191 | +-static bool enable_tso;
192 | +-module_param(enable_tso, bool, 0644);
193 | +-MODULE_PARM_DESC(enable_tso, "Enables TCP segmentation offload");
194 | ++static inline struct sk_buff *lan78xx_get_buf(struct sk_buff_head *buf_pool)
195 | ++{
196 | ++ if (!skb_queue_empty(buf_pool))
197 | ++ return skb_dequeue(buf_pool);
198 | ++ else
199 | ++ return NULL;
200 | ++}
201 | ++
202 | ++static inline void lan78xx_free_buf(struct sk_buff_head *buf_pool,
203 | ++ struct sk_buff *buf)
204 | ++{
205 | ++ buf->data = buf->head;
206 | ++ skb_reset_tail_pointer(buf);
207 | ++ buf->len = 0;
208 | ++ buf->data_len = 0;
209 | ++
210 | ++ skb_queue_tail(buf_pool, buf);
211 | ++}
212 | ++
213 | ++static void lan78xx_free_buf_pool(struct sk_buff_head *buf_pool)
214 | ++{
215 | ++ struct sk_buff *buf;
216 | ++ struct skb_data *entry;
217 | ++
218 | ++ while (!skb_queue_empty(buf_pool)) {
219 | ++ buf = skb_dequeue(buf_pool);
220 | ++ if (buf) {
221 | ++ entry = (struct skb_data *)buf->cb;
222 | ++ usb_free_urb(entry->urb);
223 | ++ dev_kfree_skb_any(buf);
224 | ++ }
225 | ++ }
226 | ++}
227 | ++
228 | ++static int lan78xx_alloc_buf_pool(struct sk_buff_head *buf_pool,
229 | ++ int n_urbs, int urb_size,
230 | ++ struct lan78xx_net *dev)
231 | ++{
232 | ++ int i;
233 | ++ struct sk_buff *buf;
234 | ++ struct skb_data *entry;
235 | ++ struct urb *urb;
236 | ++
237 | ++ skb_queue_head_init(buf_pool);
238 | ++
239 | ++ for (i = 0; i < n_urbs; i++) {
240 | ++ buf = alloc_skb(urb_size, GFP_ATOMIC);
241 | ++ if (!buf)
242 | ++ goto error;
243 | ++
244 | ++ if (skb_linearize(buf) != 0) {
245 | ++ dev_kfree_skb_any(buf);
246 | ++ goto error;
247 | ++ }
248 | ++
249 | ++ urb = usb_alloc_urb(0, GFP_ATOMIC);
250 | ++ if (!urb) {
251 | ++ dev_kfree_skb_any(buf);
252 | ++ goto error;
253 | ++ }
254 | ++
255 | ++ entry = (struct skb_data *)buf->cb;
256 | ++ entry->urb = urb;
257 | ++ entry->dev = dev;
258 | ++ entry->length = 0;
259 | ++ entry->num_of_packet = 0;
260 | ++
261 | ++ skb_queue_tail(buf_pool, buf);
262 | ++ }
263 | ++
264 | ++ return 0;
265 | ++
266 | ++error:
267 | ++ lan78xx_free_buf_pool(buf_pool);
268 | ++
269 | ++ return -ENOMEM;
270 | ++}
271 | ++
272 | ++static inline struct sk_buff *lan78xx_get_rx_buf(struct lan78xx_net *dev)
273 | ++{
274 | ++ return lan78xx_get_buf(&dev->rxq_free);
275 | ++}
276 | ++
277 | ++static inline void lan78xx_free_rx_buf(struct lan78xx_net *dev,
278 | ++ struct sk_buff *rx_buf)
279 | ++{
280 | ++ lan78xx_free_buf(&dev->rxq_free, rx_buf);
281 | ++}
282 | ++
283 | ++static void lan78xx_free_rx_resources(struct lan78xx_net *dev)
284 | ++{
285 | ++ lan78xx_free_buf_pool(&dev->rxq_free);
286 | ++}
287 | ++
288 | ++static int lan78xx_alloc_rx_resources(struct lan78xx_net *dev)
289 | ++{
290 | ++ return lan78xx_alloc_buf_pool(&dev->rxq_free,
291 | ++ dev->n_rx_urbs, dev->rx_urb_size, dev);
292 | ++}
293 | ++
294 | ++static inline struct sk_buff *lan78xx_get_tx_buf(struct lan78xx_net *dev)
295 | ++{
296 | ++ return lan78xx_get_buf(&dev->txq_free);
297 | ++}
298 | ++
299 | ++static inline void lan78xx_free_tx_buf(struct lan78xx_net *dev,
300 | ++ struct sk_buff *tx_buf)
301 | ++{
302 | ++ lan78xx_free_buf(&dev->txq_free, tx_buf);
303 | ++}
304 | ++
305 | ++static void lan78xx_free_tx_resources(struct lan78xx_net *dev)
306 | ++{
307 | ++ lan78xx_free_buf_pool(&dev->txq_free);
308 | ++}
309 | +
310 | +-#define INT_URB_MICROFRAMES_PER_MS 8
311 | +-static int int_urb_interval_ms = 8;
312 | +-module_param(int_urb_interval_ms, int, 0);
313 | +-MODULE_PARM_DESC(int_urb_interval_ms, "Override usb interrupt urb interval");
314 | ++static int lan78xx_alloc_tx_resources(struct lan78xx_net *dev)
315 | ++{
316 | ++ return lan78xx_alloc_buf_pool(&dev->txq_free,
317 | ++ dev->n_tx_urbs, dev->tx_urb_size, dev);
318 | ++}
319 | +
320 | + static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data)
321 | + {
322 | +- u32 *buf = kmalloc(sizeof(u32), GFP_KERNEL);
323 | ++ u32 *buf;
324 | + int ret;
325 | +
326 | ++ if (test_bit(EVENT_DEV_DISCONNECT, &dev->flags))
327 | ++ return -ENODEV;
328 | ++
329 | ++ buf = kmalloc(sizeof(u32), GFP_KERNEL);
330 | ++
331 | + if (!buf)
332 | + return -ENOMEM;
333 | +
334 | +@@ -456,7 +624,7 @@ static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data)
335 | + if (likely(ret >= 0)) {
336 | + le32_to_cpus(buf);
337 | + *data = *buf;
338 | +- } else {
339 | ++ } else if (net_ratelimit()) {
340 | + netdev_warn(dev->net,
341 | + "Failed to read register index 0x%08x. ret = %d",
342 | + index, ret);
343 | +@@ -469,9 +637,13 @@ static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data)
344 | +
345 | + static int lan78xx_write_reg(struct lan78xx_net *dev, u32 index, u32 data)
346 | + {
347 | +- u32 *buf = kmalloc(sizeof(u32), GFP_KERNEL);
348 | ++ u32 *buf;
349 | + int ret;
350 | +
351 | ++ if (test_bit(EVENT_DEV_DISCONNECT, &dev->flags))
352 | ++ return -ENODEV;
353 | ++
354 | ++ buf = kmalloc(sizeof(u32), GFP_KERNEL);
355 | + if (!buf)
356 | + return -ENOMEM;
357 | +
358 | +@@ -482,7 +654,8 @@ static int lan78xx_write_reg(struct lan78xx_net *dev, u32 index, u32 data)
359 | + USB_VENDOR_REQUEST_WRITE_REGISTER,
360 | + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
361 | + 0, index, buf, 4, USB_CTRL_SET_TIMEOUT);
362 | +- if (unlikely(ret < 0)) {
363 | ++ if (unlikely(ret < 0) &&
364 | ++ net_ratelimit()) {
365 | + netdev_warn(dev->net,
366 | + "Failed to write register index 0x%08x. ret = %d",
367 | + index, ret);
368 | +@@ -1155,7 +1328,7 @@ static int lan78xx_update_flowcontrol(struct lan78xx_net *dev, u8 duplex,
369 | + flow |= FLOW_CR_RX_FCEN_;
370 | +
371 | + if (dev->udev->speed == USB_SPEED_SUPER)
372 | +- fct_flow = 0x817;
373 | ++ fct_flow = 0x812;
374 | + else if (dev->udev->speed == USB_SPEED_HIGH)
375 | + fct_flow = 0x211;
376 | +
377 | +@@ -1171,11 +1344,63 @@ static int lan78xx_update_flowcontrol(struct lan78xx_net *dev, u8 duplex,
378 | + return 0;
379 | + }
380 | +
381 | ++static void lan78xx_rx_urb_submit_all(struct lan78xx_net *dev);
382 | ++
383 | ++static int lan78xx_mac_reset(struct lan78xx_net *dev)
384 | ++{
385 | ++ u32 val;
386 | ++ int ret;
387 | ++ unsigned long start_time = jiffies;
388 | ++
389 | ++ mutex_lock(&dev->phy_mutex);
390 | ++
391 | ++ /* confirm MII not busy */
392 | ++ ret = lan78xx_phy_wait_not_busy(dev);
393 | ++ if (ret < 0)
394 | ++ goto done;
395 | ++
396 | ++ ret = lan78xx_read_reg(dev, MAC_CR, &val);
397 | ++ if (unlikely(ret < 0)) {
398 | ++ ret = -EIO;
399 | ++ goto done;
400 | ++ }
401 | ++
402 | ++ val |= MAC_CR_RST_;
403 | ++ ret = lan78xx_write_reg(dev, MAC_CR, val);
404 | ++ if (unlikely(ret < 0)) {
405 | ++ ret = -EIO;
406 | ++ goto done;
407 | ++ }
408 | ++
409 | ++ /* poll for completion */
410 | ++
411 | ++ do {
412 | ++ ret = lan78xx_read_reg(dev, MAC_CR, &val);
413 | ++
414 | ++ if (unlikely(ret < 0)) {
415 | ++ ret = -EIO;
416 | ++ break;
417 | ++ }
418 | ++
419 | ++ if (!(val & MAC_CR_RST_)) {
420 | ++ ret = 0;
421 | ++ break;
422 | ++ }
423 | ++
424 | ++ } while (!time_after(jiffies, start_time + HZ));
425 | ++
426 | ++done:
427 | ++ mutex_unlock(&dev->phy_mutex);
428 | ++
429 | ++ return ret;
430 | ++}
431 | ++
432 | ++
433 | + static int lan78xx_link_reset(struct lan78xx_net *dev)
434 | + {
435 | + struct phy_device *phydev = dev->net->phydev;
436 | + struct ethtool_link_ksettings ecmd;
437 | +- int ladv, radv, ret, link;
438 | ++ int ladv, radv, ret;
439 | + u32 buf;
440 | +
441 | + /* clear LAN78xx interrupt status */
442 | +@@ -1183,33 +1408,24 @@ static int lan78xx_link_reset(struct lan78xx_net *dev)
443 | + if (unlikely(ret < 0))
444 | + return -EIO;
445 | +
446 | +- /* Acknowledge any pending PHY interrupt, lest it be the last */
447 | +- phy_read(phydev, LAN88XX_INT_STS);
448 | +-
449 | +- mutex_lock(&phydev->lock);
450 | + phy_read_status(phydev);
451 | +- link = phydev->link;
452 | +- mutex_unlock(&phydev->lock);
453 | +
454 | +- if (!link && dev->link_on) {
455 | ++ if (!phydev->link && dev->link_on) {
456 | + dev->link_on = false;
457 | +
458 | + /* reset MAC */
459 | +- ret = lan78xx_read_reg(dev, MAC_CR, &buf);
460 | +- if (unlikely(ret < 0))
461 | +- return -EIO;
462 | +- buf |= MAC_CR_RST_;
463 | +- ret = lan78xx_write_reg(dev, MAC_CR, buf);
464 | ++ ret = lan78xx_mac_reset(dev);
465 | + if (unlikely(ret < 0))
466 | + return -EIO;
467 | +
468 | + del_timer(&dev->stat_monitor);
469 | +- } else if (link && !dev->link_on) {
470 | ++ } else if (phydev->link && !dev->link_on) {
471 | + dev->link_on = true;
472 | +
473 | + phy_ethtool_ksettings_get(phydev, &ecmd);
474 | +
475 | +- if (dev->udev->speed == USB_SPEED_SUPER) {
476 | ++ if (DEFAULT_U1_U2_INIT_ENABLE &&
477 | ++ dev->udev->speed == USB_SPEED_SUPER) {
478 | + if (ecmd.base.speed == 1000) {
479 | + /* disable U2 */
480 | + ret = lan78xx_read_reg(dev, USB_CFG1, &buf);
481 | +@@ -1226,6 +1442,11 @@ static int lan78xx_link_reset(struct lan78xx_net *dev)
482 | + buf |= USB_CFG1_DEV_U1_INIT_EN_;
483 | + ret = lan78xx_write_reg(dev, USB_CFG1, buf);
484 | + }
485 | ++ } else {
486 | ++ ret = lan78xx_read_reg(dev, USB_CFG1, &buf);
487 | ++ buf &= ~USB_CFG1_DEV_U2_INIT_EN_;
488 | ++ buf &= ~USB_CFG1_DEV_U1_INIT_EN_;
489 | ++ ret = lan78xx_write_reg(dev, USB_CFG1, buf);
490 | + }
491 | +
492 | + ladv = phy_read(phydev, MII_ADVERTISE);
493 | +@@ -1249,7 +1470,9 @@ static int lan78xx_link_reset(struct lan78xx_net *dev)
494 | + jiffies + STAT_UPDATE_TIMER);
495 | + }
496 | +
497 | +- tasklet_schedule(&dev->bh);
498 | ++ lan78xx_rx_urb_submit_all(dev);
499 | ++
500 | ++ napi_schedule(&dev->napi);
501 | + }
502 | +
503 | + return ret;
504 | +@@ -1493,14 +1716,9 @@ static int lan78xx_set_eee(struct net_device *net, struct ethtool_eee *edata)
505 | +
506 | + static u32 lan78xx_get_link(struct net_device *net)
507 | + {
508 | +- u32 link;
509 | +-
510 | +- mutex_lock(&net->phydev->lock);
511 | + phy_read_status(net->phydev);
512 | +- link = net->phydev->link;
513 | +- mutex_unlock(&net->phydev->lock);
514 | +
515 | +- return link;
516 | ++ return net->phydev->link;
517 | + }
518 | +
519 | + static void lan78xx_get_drvinfo(struct net_device *net,
520 | +@@ -2147,7 +2365,7 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
521 | + if (dev->domain_data.phyirq > 0)
522 | + phydev->irq = dev->domain_data.phyirq;
523 | + else
524 | +- phydev->irq = PHY_POLL;
525 | ++ phydev->irq = 0;
526 | + netdev_dbg(dev->net, "phydev->irq = %d\n", phydev->irq);
527 | +
528 | + /* set to AUTOMDIX */
529 | +@@ -2185,22 +2403,6 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
530 | + mii_adv_to_linkmode_adv_t(fc, mii_adv);
531 | + linkmode_or(phydev->advertising, fc, phydev->advertising);
532 | +
533 | +- if (of_property_read_bool(phydev->mdio.dev.of_node,
534 | +- "microchip,eee-enabled")) {
535 | +- struct ethtool_eee edata;
536 | +- memset(&edata, 0, sizeof(edata));
537 | +- edata.cmd = ETHTOOL_SEEE;
538 | +- edata.advertised = ADVERTISED_1000baseT_Full |
539 | +- ADVERTISED_100baseT_Full;
540 | +- edata.eee_enabled = true;
541 | +- edata.tx_lpi_enabled = true;
542 | +- if (of_property_read_u32(dev->udev->dev.of_node,
543 | +- "microchip,tx-lpi-timer",
544 | +- &edata.tx_lpi_timer))
545 | +- edata.tx_lpi_timer = 600; /* non-aggressive */
546 | +- (void)lan78xx_set_eee(dev->net, &edata);
547 | +- }
548 | +-
549 | + if (phydev->mdio.dev.of_node) {
550 | + u32 reg;
551 | + int len;
552 | +@@ -2247,7 +2449,8 @@ static int lan78xx_set_rx_max_frame_length(struct lan78xx_net *dev, int size)
553 | +
554 | + /* add 4 to size for FCS */
555 | + buf &= ~MAC_RX_MAX_SIZE_MASK_;
556 | +- buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT_) & MAC_RX_MAX_SIZE_MASK_);
557 | ++ buf |= (((size + ETH_FCS_LEN) << MAC_RX_MAX_SIZE_SHIFT_) &
558 | ++ MAC_RX_MAX_SIZE_MASK_);
559 | +
560 | + ret = lan78xx_write_reg(dev, MAC_RX, buf);
561 | +
562 | +@@ -2307,29 +2510,26 @@ static int unlink_urbs(struct lan78xx_net *dev, struct sk_buff_head *q)
563 | + static int lan78xx_change_mtu(struct net_device *netdev, int new_mtu)
564 | + {
565 | + struct lan78xx_net *dev = netdev_priv(netdev);
566 | +- int ll_mtu = new_mtu + netdev->hard_header_len;
567 | +- int old_hard_mtu = dev->hard_mtu;
568 | +- int old_rx_urb_size = dev->rx_urb_size;
569 | ++ int max_frame_len = RX_MAX_FRAME_LEN(new_mtu);
570 | + int ret;
571 | +
572 | ++ if (new_mtu < LAN78XX_MIN_MTU ||
573 | ++ new_mtu > LAN78XX_MAX_MTU)
574 | ++ return -EINVAL;
575 | ++
576 | + /* no second zero-length packet read wanted after mtu-sized packets */
577 | +- if ((ll_mtu % dev->maxpacket) == 0)
578 | ++ if ((max_frame_len % dev->maxpacket) == 0)
579 | + return -EDOM;
580 | +
581 | +- ret = lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN);
582 | ++ ret = usb_autopm_get_interface(dev->intf);
583 | ++ if (ret < 0)
584 | ++ return ret;
585 | ++
586 | ++ ret = lan78xx_set_rx_max_frame_length(dev, max_frame_len);
587 | +
588 | + netdev->mtu = new_mtu;
589 | +
590 | +- dev->hard_mtu = netdev->mtu + netdev->hard_header_len;
591 | +- if (dev->rx_urb_size == old_hard_mtu) {
592 | +- dev->rx_urb_size = dev->hard_mtu;
593 | +- if (dev->rx_urb_size > old_rx_urb_size) {
594 | +- if (netif_running(dev->net)) {
595 | +- unlink_urbs(dev, &dev->rxq);
596 | +- tasklet_schedule(&dev->bh);
597 | +- }
598 | +- }
599 | +- }
600 | ++ usb_autopm_put_interface(dev->intf);
601 | +
602 | + return 0;
603 | + }
604 | +@@ -2359,7 +2559,10 @@ static int lan78xx_set_mac_addr(struct net_device *netdev, void *p)
605 | + ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo);
606 | + ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi);
607 | +
608 | +- /* Added to support MAC address changes */
609 | ++ /* The station MAC address in the perfect address filter table
610 | ++ * must also be updated to ensure frames are received
611 | ++ */
612 | ++ ret = lan78xx_write_reg(dev, MAF_HI(0), 0);
613 | + ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo);
614 | + ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_);
615 | +
616 | +@@ -2489,156 +2692,320 @@ static void lan78xx_init_ltm(struct lan78xx_net *dev)
617 | + lan78xx_write_reg(dev, LTM_INACTIVE1, regs[5]);
618 | + }
619 | +
620 | +-static int lan78xx_reset(struct lan78xx_net *dev)
621 | ++static int lan78xx_urb_config_init(struct lan78xx_net *dev)
622 | + {
623 | +- struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]);
624 | +- u32 buf;
625 | +- int ret = 0;
626 | +- unsigned long timeout;
627 | +- u8 sig;
628 | +- bool has_eeprom;
629 | +- bool has_otp;
630 | ++ int result = 0;
631 | ++
632 | ++ switch (dev->udev->speed) {
633 | ++ case USB_SPEED_SUPER:
634 | ++ dev->rx_urb_size = RX_SS_URB_SIZE;
635 | ++ dev->tx_urb_size = TX_SS_URB_SIZE;
636 | ++ dev->n_rx_urbs = RX_SS_URB_NUM;
637 | ++ dev->n_tx_urbs = TX_SS_URB_NUM;
638 | ++ dev->bulk_in_delay = SS_BULK_IN_DELAY;
639 | ++ dev->burst_cap = SS_BURST_CAP_SIZE / SS_USB_PKT_SIZE;
640 | ++ break;
641 | ++ case USB_SPEED_HIGH:
642 | ++ dev->rx_urb_size = RX_HS_URB_SIZE;
643 | ++ dev->tx_urb_size = TX_HS_URB_SIZE;
644 | ++ dev->n_rx_urbs = RX_HS_URB_NUM;
645 | ++ dev->n_tx_urbs = TX_HS_URB_NUM;
646 | ++ dev->bulk_in_delay = HS_BULK_IN_DELAY;
647 | ++ dev->burst_cap = HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
648 | ++ break;
649 | ++ case USB_SPEED_FULL:
650 | ++ dev->rx_urb_size = RX_FS_URB_SIZE;
651 | ++ dev->tx_urb_size = TX_FS_URB_SIZE;
652 | ++ dev->n_rx_urbs = RX_FS_URB_NUM;
653 | ++ dev->n_tx_urbs = TX_FS_URB_NUM;
654 | ++ dev->bulk_in_delay = FS_BULK_IN_DELAY;
655 | ++ dev->burst_cap = FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
656 | ++ break;
657 | ++ default:
658 | ++ netdev_warn(dev->net, "USB bus speed not supported\n");
659 | ++ result = -EIO;
660 | ++ break;
661 | ++ }
662 | +
663 | +- has_eeprom = !lan78xx_read_eeprom(dev, 0, 0, NULL);
664 | +- has_otp = !lan78xx_read_otp(dev, 0, 0, NULL);
665 | ++ return result;
666 | ++}
667 | +
668 | +- ret = lan78xx_read_reg(dev, HW_CFG, &buf);
669 | +- buf |= HW_CFG_LRST_;
670 | +- ret = lan78xx_write_reg(dev, HW_CFG, buf);
671 | ++static int lan78xx_start_tx_path(struct lan78xx_net *dev)
672 | ++{
673 | ++ int ret;
674 | ++ u32 buf;
675 | +
676 | +- timeout = jiffies + HZ;
677 | +- do {
678 | +- mdelay(1);
679 | +- ret = lan78xx_read_reg(dev, HW_CFG, &buf);
680 | +- if (time_after(jiffies, timeout)) {
681 | +- netdev_warn(dev->net,
682 | +- "timeout on completion of LiteReset");
683 | +- return -EIO;
684 | +- }
685 | +- } while (buf & HW_CFG_LRST_);
686 | ++ netif_dbg(dev, drv, dev->net, "start tx path");
687 | +
688 | +- lan78xx_init_mac_address(dev);
689 | ++ /* Start the MAC transmitter */
690 | +
691 | +- /* save DEVID for later usage */
692 | +- ret = lan78xx_read_reg(dev, ID_REV, &buf);
693 | +- dev->chipid = (buf & ID_REV_CHIP_ID_MASK_) >> 16;
694 | +- dev->chiprev = buf & ID_REV_CHIP_REV_MASK_;
695 | ++ ret = lan78xx_read_reg(dev, MAC_TX, &buf);
696 | ++ buf |= MAC_TX_TXEN_;
697 | ++ ret = lan78xx_write_reg(dev, MAC_TX, buf);
698 | +
699 | +- /* Respond to the IN token with a NAK */
700 | +- ret = lan78xx_read_reg(dev, USB_CFG0, &buf);
701 | +- buf |= USB_CFG_BIR_;
702 | +- ret = lan78xx_write_reg(dev, USB_CFG0, buf);
703 | ++ /* Start the Tx FIFO */
704 | +
705 | +- /* Init LTM */
706 | +- lan78xx_init_ltm(dev);
707 | ++ ret = lan78xx_read_reg(dev, FCT_TX_CTL, &buf);
708 | ++ buf |= FCT_TX_CTL_EN_;
709 | ++ ret = lan78xx_write_reg(dev, FCT_TX_CTL, buf);
710 | +
711 | +- if (dev->udev->speed == USB_SPEED_SUPER) {
712 | +- buf = DEFAULT_BURST_CAP_SIZE / SS_USB_PKT_SIZE;
713 | +- dev->rx_urb_size = DEFAULT_BURST_CAP_SIZE;
714 | +- dev->rx_qlen = 4;
715 | +- dev->tx_qlen = 4;
716 | +- } else if (dev->udev->speed == USB_SPEED_HIGH) {
717 | +- buf = DEFAULT_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
718 | +- dev->rx_urb_size = DEFAULT_BURST_CAP_SIZE;
719 | +- dev->rx_qlen = RX_MAX_QUEUE_MEMORY / dev->rx_urb_size;
720 | +- dev->tx_qlen = RX_MAX_QUEUE_MEMORY / dev->hard_mtu;
721 | +- } else {
722 | +- buf = DEFAULT_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
723 | +- dev->rx_urb_size = DEFAULT_BURST_CAP_SIZE;
724 | +- dev->rx_qlen = 4;
725 | +- dev->tx_qlen = 4;
726 | +- }
727 | ++ return 0;
728 | ++}
729 | +
730 | +- ret = lan78xx_write_reg(dev, BURST_CAP, buf);
731 | +- ret = lan78xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
732 | ++static int lan78xx_stop_tx_path(struct lan78xx_net *dev)
733 | ++{
734 | ++ int ret;
735 | ++ u32 buf = 0;
736 | ++ int i;
737 | +
738 | +- ret = lan78xx_read_reg(dev, HW_CFG, &buf);
739 | +- buf |= HW_CFG_MEF_;
740 | +- /* If no valid EEPROM and no valid OTP, enable the LEDs by default */
741 | +- if (!has_eeprom && !has_otp)
742 | +- buf |= HW_CFG_LED0_EN_ | HW_CFG_LED1_EN_;
743 | +- ret = lan78xx_write_reg(dev, HW_CFG, buf);
744 | ++ netif_dbg(dev, drv, dev->net, "stop tx path");
745 | +
746 | +- ret = lan78xx_read_reg(dev, USB_CFG0, &buf);
747 | +- buf |= USB_CFG_BCE_;
748 | +- ret = lan78xx_write_reg(dev, USB_CFG0, buf);
749 | ++ /* Stop the Tx FIFO (if not already stopped) */
750 | +
751 | +- /* set FIFO sizes */
752 | +- buf = (MAX_RX_FIFO_SIZE - 512) / 512;
753 | +- ret = lan78xx_write_reg(dev, FCT_RX_FIFO_END, buf);
754 | ++ ret = lan78xx_read_reg(dev, FCT_TX_CTL, &buf);
755 | +
756 | +- buf = (MAX_TX_FIFO_SIZE - 512) / 512;
757 | +- ret = lan78xx_write_reg(dev, FCT_TX_FIFO_END, buf);
758 | ++ if ((buf & FCT_TX_CTL_EN_) != 0) {
759 | ++ buf &= ~FCT_TX_CTL_EN_;
760 | ++ ret = lan78xx_write_reg(dev, FCT_TX_CTL, buf);
761 | +
762 | +- ret = lan78xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_);
763 | +- ret = lan78xx_write_reg(dev, FLOW, 0);
764 | +- ret = lan78xx_write_reg(dev, FCT_FLOW, 0);
765 | ++ for (i = 0; i < HW_DISABLE_POLL_MAX; ++i) {
766 | ++ ret = lan78xx_read_reg(dev, FCT_TX_CTL, &buf);
767 | +
768 | +- /* Don't need rfe_ctl_lock during initialisation */
769 | +- ret = lan78xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
770 | +- pdata->rfe_ctl |= RFE_CTL_BCAST_EN_ | RFE_CTL_DA_PERFECT_;
771 | +- ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
772 | ++ if ((buf & FCT_TX_CTL_DIS_) != 0)
773 | ++ break;
774 | +
775 | +- /* Enable or disable checksum offload engines */
776 | +- lan78xx_set_features(dev->net, dev->net->features);
777 | ++ msleep(HW_DISABLE_DELAY);
778 | ++ }
779 | ++ }
780 | +
781 | +- lan78xx_set_multicast(dev->net);
782 | ++ /* Stop the MAC transmitter (if not already stopped) */
783 | +
784 | +- /* reset PHY */
785 | +- ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
786 | +- buf |= PMT_CTL_PHY_RST_;
787 | +- ret = lan78xx_write_reg(dev, PMT_CTL, buf);
788 | ++ ret = lan78xx_read_reg(dev, MAC_TX, &buf);
789 | +
790 | +- timeout = jiffies + HZ;
791 | +- do {
792 | +- mdelay(1);
793 | +- ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
794 | +- if (time_after(jiffies, timeout)) {
795 | +- netdev_warn(dev->net, "timeout waiting for PHY Reset");
796 | +- return -EIO;
797 | +- }
798 | +- } while ((buf & PMT_CTL_PHY_RST_) || !(buf & PMT_CTL_READY_));
799 | ++ if ((buf & MAC_TX_TXEN_) != 0) {
800 | ++ buf &= ~MAC_TX_TXEN_;
801 | ++ ret = lan78xx_write_reg(dev, MAC_TX, buf);
802 | +
803 | +- ret = lan78xx_read_reg(dev, MAC_CR, &buf);
804 | +- /* LAN7801 only has RGMII mode */
805 | +- if (dev->chipid == ID_REV_CHIP_ID_7801_)
806 | +- buf &= ~MAC_CR_GMII_EN_;
807 | ++ for (i = 0; i < HW_DISABLE_POLL_MAX; ++i) {
808 | ++ ret = lan78xx_read_reg(dev, MAC_TX, &buf);
809 | +
810 | +- if (dev->chipid == ID_REV_CHIP_ID_7800_) {
811 | +- ret = lan78xx_read_raw_eeprom(dev, 0, 1, &sig);
812 | +- if (!ret && sig != EEPROM_INDICATOR) {
813 | +- /* Implies there is no external eeprom. Set mac speed */
814 | +- netdev_info(dev->net, "No External EEPROM. Setting MAC Speed\n");
815 | +- buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_;
816 | ++ if ((buf & MAC_TX_TXD_) != 0)
817 | ++ break;
818 | ++
819 | ++ msleep(HW_DISABLE_DELAY);
820 | + }
821 | + }
822 | +- /* If no valid EEPROM and no valid OTP, enable AUTO negotiation */
823 | +- if (!has_eeprom && !has_otp)
824 | +- buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_;
825 | +- ret = lan78xx_write_reg(dev, MAC_CR, buf);
826 | +
827 | +- ret = lan78xx_read_reg(dev, MAC_TX, &buf);
828 | +- buf |= MAC_TX_TXEN_;
829 | +- ret = lan78xx_write_reg(dev, MAC_TX, buf);
830 | ++ return 0;
831 | ++}
832 | ++
833 | ++/* The caller must ensure the Tx path is stopped before calling
834 | ++ * lan78xx_flush_tx_fifo().
835 | ++ */
836 | ++static int lan78xx_flush_tx_fifo(struct lan78xx_net *dev)
837 | ++{
838 | ++ int ret;
839 | ++ u32 buf;
840 | +
841 | + ret = lan78xx_read_reg(dev, FCT_TX_CTL, &buf);
842 | +- buf |= FCT_TX_CTL_EN_;
843 | ++ buf |= FCT_TX_CTL_RST_;
844 | + ret = lan78xx_write_reg(dev, FCT_TX_CTL, buf);
845 | +
846 | +- ret = lan78xx_set_rx_max_frame_length(dev,
847 | +- dev->net->mtu + VLAN_ETH_HLEN);
848 | ++ return 0;
849 | ++}
850 | ++
851 | ++static int lan78xx_start_rx_path(struct lan78xx_net *dev)
852 | ++{
853 | ++ int ret;
854 | ++ u32 buf;
855 | ++
856 | ++ netif_dbg(dev, drv, dev->net, "start rx path");
857 | ++
858 | ++ /* Start the Rx FIFO */
859 | ++
860 | ++ ret = lan78xx_read_reg(dev, FCT_RX_CTL, &buf);
861 | ++ buf |= FCT_RX_CTL_EN_;
862 | ++ ret = lan78xx_write_reg(dev, FCT_RX_CTL, buf);
863 | ++
864 | ++ /* Start the MAC receiver*/
865 | +
866 | + ret = lan78xx_read_reg(dev, MAC_RX, &buf);
867 | + buf |= MAC_RX_RXEN_;
868 | + ret = lan78xx_write_reg(dev, MAC_RX, buf);
869 | +
870 | ++ return 0;
871 | ++}
872 | ++
873 | ++static int lan78xx_stop_rx_path(struct lan78xx_net *dev)
874 | ++{
875 | ++ int ret;
876 | ++ u32 buf;
877 | ++ int i;
878 | ++
879 | ++ netif_dbg(dev, drv, dev->net, "stop rx path");
880 | ++
881 | ++ /* Stop the MAC receiver (if not already running) */
882 | ++
883 | ++ ret = lan78xx_read_reg(dev, MAC_RX, &buf);
884 | ++
885 | ++ if ((buf & MAC_RX_RXEN_) != 0) {
886 | ++ buf &= ~MAC_RX_RXEN_;
887 | ++ ret = lan78xx_write_reg(dev, MAC_RX, buf);
888 | ++
889 | ++ for (i = 0; i < HW_DISABLE_POLL_MAX; ++i) {
890 | ++ ret = lan78xx_read_reg(dev, MAC_RX, &buf);
891 | ++
892 | ++ if ((buf & MAC_RX_RXD_) != 0)
893 | ++ break;
894 | ++
895 | ++ msleep(HW_DISABLE_DELAY);
896 | ++ }
897 | ++ }
898 | ++
899 | ++ /* Stop the Rx FIFO (if not already stopped) */
900 | ++
901 | + ret = lan78xx_read_reg(dev, FCT_RX_CTL, &buf);
902 | +- buf |= FCT_RX_CTL_EN_;
903 | ++
904 | ++ if ((buf & FCT_RX_CTL_EN_) != 0) {
905 | ++ buf &= ~FCT_RX_CTL_EN_;
906 | ++ ret = lan78xx_write_reg(dev, FCT_RX_CTL, buf);
907 | ++
908 | ++ for (i = 0; i < HW_DISABLE_POLL_MAX; ++i) {
909 | ++ ret = lan78xx_read_reg(dev, FCT_RX_CTL, &buf);
910 | ++
911 | ++ if ((buf & FCT_RX_CTL_DIS_) != 0)
912 | ++ break;
913 | ++
914 | ++ msleep(HW_DISABLE_DELAY);
915 | ++ }
916 | ++ }
917 | ++
918 | ++ return 0;
919 | ++}
920 | ++
921 | ++/* The caller must ensure the Rx path is stopped before calling
922 | ++ * lan78xx_flush_rx_fifo().
923 | ++ */
924 | ++static int lan78xx_flush_rx_fifo(struct lan78xx_net *dev)
925 | ++{
926 | ++ int ret;
927 | ++ u32 buf;
928 | ++
929 | ++ ret = lan78xx_read_reg(dev, FCT_RX_CTL, &buf);
930 | ++ buf |= FCT_RX_CTL_RST_;
931 | + ret = lan78xx_write_reg(dev, FCT_RX_CTL, buf);
932 | +
933 | + return 0;
934 | + }
935 | +
936 | ++static int lan78xx_reset(struct lan78xx_net *dev)
937 | ++{
938 | ++ struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]);
939 | ++ u32 buf;
940 | ++ int ret = 0;
941 | ++ unsigned long timeout;
942 | ++ u8 sig;
943 | ++
944 | ++ ret = lan78xx_read_reg(dev, HW_CFG, &buf);
945 | ++ buf |= HW_CFG_LRST_;
946 | ++ ret = lan78xx_write_reg(dev, HW_CFG, buf);
947 | ++
948 | ++ timeout = jiffies + HZ;
949 | ++ do {
950 | ++ mdelay(1);
951 | ++ ret = lan78xx_read_reg(dev, HW_CFG, &buf);
952 | ++ if (time_after(jiffies, timeout)) {
953 | ++ netdev_warn(dev->net,
954 | ++ "timeout on completion of LiteReset");
955 | ++ return -EIO;
956 | ++ }
957 | ++ } while (buf & HW_CFG_LRST_);
958 | ++
959 | ++ lan78xx_init_mac_address(dev);
960 | ++
961 | ++ /* save DEVID for later usage */
962 | ++ ret = lan78xx_read_reg(dev, ID_REV, &buf);
963 | ++ dev->chipid = (buf & ID_REV_CHIP_ID_MASK_) >> 16;
964 | ++ dev->chiprev = buf & ID_REV_CHIP_REV_MASK_;
965 | ++
966 | ++ /* Respond to the IN token with a NAK */
967 | ++ ret = lan78xx_read_reg(dev, USB_CFG0, &buf);
968 | ++ buf |= USB_CFG_BIR_;
969 | ++ ret = lan78xx_write_reg(dev, USB_CFG0, buf);
970 | ++
971 | ++ /* Init LTM */
972 | ++ lan78xx_init_ltm(dev);
973 | ++
974 | ++ ret = lan78xx_write_reg(dev, BURST_CAP, dev->burst_cap);
975 | ++ ret = lan78xx_write_reg(dev, BULK_IN_DLY, dev->bulk_in_delay);
976 | ++
977 | ++ ret = lan78xx_read_reg(dev, HW_CFG, &buf);
978 | ++ buf |= HW_CFG_MEF_;
979 | ++ ret = lan78xx_write_reg(dev, HW_CFG, buf);
980 | ++
981 | ++ ret = lan78xx_read_reg(dev, USB_CFG0, &buf);
982 | ++ buf |= USB_CFG_BCE_;
983 | ++ ret = lan78xx_write_reg(dev, USB_CFG0, buf);
984 | ++
985 | ++ netdev_info(dev->net, "USB_CFG0 0x%08x\n", buf);
986 | ++
987 | ++ /* set FIFO sizes */
988 | ++ buf = (MAX_RX_FIFO_SIZE - 512) / 512;
989 | ++ ret = lan78xx_write_reg(dev, FCT_RX_FIFO_END, buf);
990 | ++
991 | ++ buf = (MAX_TX_FIFO_SIZE - 512) / 512;
992 | ++ ret = lan78xx_write_reg(dev, FCT_TX_FIFO_END, buf);
993 | ++
994 | ++ ret = lan78xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_);
995 | ++ ret = lan78xx_write_reg(dev, FLOW, 0);
996 | ++ ret = lan78xx_write_reg(dev, FCT_FLOW, 0);
997 | ++
998 | ++ /* Don't need rfe_ctl_lock during initialisation */
999 | ++ ret = lan78xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
1000 | ++ pdata->rfe_ctl |= RFE_CTL_BCAST_EN_ | RFE_CTL_DA_PERFECT_;
1001 | ++ ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
1002 | ++
1003 | ++ /* Enable or disable checksum offload engines */
1004 | ++ lan78xx_set_features(dev->net, dev->net->features);
1005 | ++
1006 | ++ lan78xx_set_multicast(dev->net);
1007 | ++
1008 | ++ /* reset PHY */
1009 | ++ ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
1010 | ++ buf |= PMT_CTL_PHY_RST_;
1011 | ++ ret = lan78xx_write_reg(dev, PMT_CTL, buf);
1012 | ++
1013 | ++ timeout = jiffies + HZ;
1014 | ++ do {
1015 | ++ mdelay(1);
1016 | ++ ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
1017 | ++ if (time_after(jiffies, timeout)) {
1018 | ++ netdev_warn(dev->net, "timeout waiting for PHY Reset");
1019 | ++ return -EIO;
1020 | ++ }
1021 | ++ } while ((buf & PMT_CTL_PHY_RST_) || !(buf & PMT_CTL_READY_));
1022 | ++
1023 | ++ ret = lan78xx_read_reg(dev, MAC_CR, &buf);
1024 | ++ /* LAN7801 only has RGMII mode */
1025 | ++ if (dev->chipid == ID_REV_CHIP_ID_7801_)
1026 | ++ buf &= ~MAC_CR_GMII_EN_;
1027 | ++
1028 | ++ if (dev->chipid == ID_REV_CHIP_ID_7800_) {
1029 | ++ ret = lan78xx_read_raw_eeprom(dev, 0, 1, &sig);
1030 | ++ if (!ret && sig != EEPROM_INDICATOR) {
1031 | ++ /* Implies there is no external eeprom. Set mac speed */
1032 | ++ netdev_info(dev->net, "No External EEPROM. Setting MAC Speed\n");
1033 | ++ buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_;
1034 | ++ }
1035 | ++ }
1036 | ++ ret = lan78xx_write_reg(dev, MAC_CR, buf);
1037 | ++
1038 | ++ ret = lan78xx_set_rx_max_frame_length(dev,
1039 | ++ RX_MAX_FRAME_LEN(dev->net->mtu));
1040 | ++
1041 | ++ return 0;
1042 | ++}
1043 | ++
1044 | + static void lan78xx_init_stats(struct lan78xx_net *dev)
1045 | + {
1046 | + u32 *p;
1047 | +@@ -2665,15 +3032,21 @@ static void lan78xx_init_stats(struct lan78xx_net *dev)
1048 | + set_bit(EVENT_STAT_UPDATE, &dev->flags);
1049 | + }
1050 | +
1051 | ++static int rx_submit(struct lan78xx_net *dev, struct sk_buff *rx_buf, gfp_t flags);
1052 | ++
1053 | + static int lan78xx_open(struct net_device *net)
1054 | + {
1055 | + struct lan78xx_net *dev = netdev_priv(net);
1056 | + int ret;
1057 | +
1058 | ++ netif_dbg(dev, ifup, dev->net, "open device");
1059 | ++
1060 | + ret = usb_autopm_get_interface(dev->intf);
1061 | + if (ret < 0)
1062 | + goto out;
1063 | +
1064 | ++ mutex_lock(&dev->dev_mutex);
1065 | ++
1066 | + phy_start(net->phydev);
1067 | +
1068 | + netif_dbg(dev, ifup, dev->net, "phy initialised successfully");
1069 | +@@ -2688,6 +3061,12 @@ static int lan78xx_open(struct net_device *net)
1070 | + }
1071 | + }
1072 | +
1073 | ++ lan78xx_flush_rx_fifo(dev);
1074 | ++ lan78xx_flush_tx_fifo(dev);
1075 | ++
1076 | ++ ret = lan78xx_start_tx_path(dev);
1077 | ++ ret = lan78xx_start_rx_path(dev);
1078 | ++
1079 | + lan78xx_init_stats(dev);
1080 | +
1081 | + set_bit(EVENT_DEV_OPEN, &dev->flags);
1082 | +@@ -2696,19 +3075,25 @@ static int lan78xx_open(struct net_device *net)
1083 | +
1084 | + dev->link_on = false;
1085 | +
1086 | ++ napi_enable(&dev->napi);
1087 | ++
1088 | + lan78xx_defer_kevent(dev, EVENT_LINK_RESET);
1089 | + done:
1090 | +- usb_autopm_put_interface(dev->intf);
1091 | ++ mutex_unlock(&dev->dev_mutex);
1092 | +
1093 | ++ usb_autopm_put_interface(dev->intf);
1094 | + out:
1095 | + return ret;
1096 | + }
1097 | +
1098 | ++static int lan78x_tx_pend_skb_get(struct lan78xx_net *dev, struct sk_buff **skb);
1099 | ++
1100 | + static void lan78xx_terminate_urbs(struct lan78xx_net *dev)
1101 | + {
1102 | + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
1103 | + DECLARE_WAITQUEUE(wait, current);
1104 | + int temp;
1105 | ++ struct sk_buff *skb;
1106 | +
1107 | + /* ensure there are no more active urbs */
1108 | + add_wait_queue(&unlink_wakeup, &wait);
1109 | +@@ -2717,96 +3102,74 @@ static void lan78xx_terminate_urbs(struct lan78xx_net *dev)
1110 | + temp = unlink_urbs(dev, &dev->txq) + unlink_urbs(dev, &dev->rxq);
1111 | +
1112 | + /* maybe wait for deletions to finish. */
1113 | +- while (!skb_queue_empty(&dev->rxq) &&
1114 | +- !skb_queue_empty(&dev->txq) &&
1115 | +- !skb_queue_empty(&dev->done)) {
1116 | ++ while (!skb_queue_empty(&dev->rxq) ||
1117 | ++ !skb_queue_empty(&dev->txq)) {
1118 | + schedule_timeout(msecs_to_jiffies(UNLINK_TIMEOUT_MS));
1119 | + set_current_state(TASK_UNINTERRUPTIBLE);
1120 | + netif_dbg(dev, ifdown, dev->net,
1121 | +- "waited for %d urb completions\n", temp);
1122 | ++ "waited for %d urb completions", temp);
1123 | + }
1124 | + set_current_state(TASK_RUNNING);
1125 | + dev->wait = NULL;
1126 | + remove_wait_queue(&unlink_wakeup, &wait);
1127 | ++
1128 | ++ /* empty Rx done, Rx overflow and Tx pend queues
1129 | ++ */
1130 | ++ while (!skb_queue_empty(&dev->rxq_done)) {
1131 | ++ skb = skb_dequeue(&dev->rxq_done);
1132 | ++ lan78xx_free_rx_buf(dev, skb);
1133 | ++ }
1134 | ++
1135 | ++ skb_queue_purge(&dev->rxq_overflow);
1136 | ++ skb_queue_purge(&dev->txq_pend);
1137 | + }
1138 | +
1139 | + static int lan78xx_stop(struct net_device *net)
1140 | + {
1141 | + struct lan78xx_net *dev = netdev_priv(net);
1142 | +
1143 | ++ netif_dbg(dev, ifup, dev->net, "stop device");
1144 | ++
1145 | ++ mutex_lock(&dev->dev_mutex);
1146 | ++
1147 | + if (timer_pending(&dev->stat_monitor))
1148 | + del_timer_sync(&dev->stat_monitor);
1149 | +
1150 | +- if (net->phydev)
1151 | +- phy_stop(net->phydev);
1152 | +-
1153 | + clear_bit(EVENT_DEV_OPEN, &dev->flags);
1154 | + netif_stop_queue(net);
1155 | ++ napi_disable(&dev->napi);
1156 | ++
1157 | ++ lan78xx_terminate_urbs(dev);
1158 | +
1159 | + netif_info(dev, ifdown, dev->net,
1160 | + "stop stats: rx/tx %lu/%lu, errs %lu/%lu\n",
1161 | + net->stats.rx_packets, net->stats.tx_packets,
1162 | + net->stats.rx_errors, net->stats.tx_errors);
1163 | +
1164 | +- lan78xx_terminate_urbs(dev);
1165 | ++ lan78xx_stop_tx_path(dev);
1166 | ++ lan78xx_stop_rx_path(dev);
1167 | +
1168 | +- usb_kill_urb(dev->urb_intr);
1169 | ++ if (net->phydev)
1170 | ++ phy_stop(net->phydev);
1171 | +
1172 | +- skb_queue_purge(&dev->rxq_pause);
1173 | ++ usb_kill_urb(dev->urb_intr);
1174 | +
1175 | + /* deferred work (task, timer, softirq) must also stop.
1176 | + * can't flush_scheduled_work() until we drop rtnl (later),
1177 | + * else workers could deadlock; so make workers a NOP.
1178 | + */
1179 | +- dev->flags = 0;
1180 | ++ clear_bit(EVENT_TX_HALT, &dev->flags);
1181 | ++ clear_bit(EVENT_RX_HALT, &dev->flags);
1182 | ++ clear_bit(EVENT_LINK_RESET, &dev->flags);
1183 | ++ clear_bit(EVENT_STAT_UPDATE, &dev->flags);
1184 | ++
1185 | + cancel_delayed_work_sync(&dev->wq);
1186 | +- tasklet_kill(&dev->bh);
1187 | +
1188 | + usb_autopm_put_interface(dev->intf);
1189 | +
1190 | +- return 0;
1191 | +-}
1192 | +-
1193 | +-static struct sk_buff *lan78xx_tx_prep(struct lan78xx_net *dev,
1194 | +- struct sk_buff *skb, gfp_t flags)
1195 | +-{
1196 | +- u32 tx_cmd_a, tx_cmd_b;
1197 | +- void *ptr;
1198 | +-
1199 | +- if (skb_cow_head(skb, TX_OVERHEAD)) {
1200 | +- dev_kfree_skb_any(skb);
1201 | +- return NULL;
1202 | +- }
1203 | +-
1204 | +- if (skb_linearize(skb)) {
1205 | +- dev_kfree_skb_any(skb);
1206 | +- return NULL;
1207 | +- }
1208 | +-
1209 | +- tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN_MASK_) | TX_CMD_A_FCS_;
1210 | +-
1211 | +- if (skb->ip_summed == CHECKSUM_PARTIAL)
1212 | +- tx_cmd_a |= TX_CMD_A_IPE_ | TX_CMD_A_TPE_;
1213 | +-
1214 | +- tx_cmd_b = 0;
1215 | +- if (skb_is_gso(skb)) {
1216 | +- u16 mss = max(skb_shinfo(skb)->gso_size, TX_CMD_B_MSS_MIN_);
1217 | +-
1218 | +- tx_cmd_b = (mss << TX_CMD_B_MSS_SHIFT_) & TX_CMD_B_MSS_MASK_;
1219 | +-
1220 | +- tx_cmd_a |= TX_CMD_A_LSO_;
1221 | +- }
1222 | +-
1223 | +- if (skb_vlan_tag_present(skb)) {
1224 | +- tx_cmd_a |= TX_CMD_A_IVTG_;
1225 | +- tx_cmd_b |= skb_vlan_tag_get(skb) & TX_CMD_B_VTAG_MASK_;
1226 | +- }
1227 | +-
1228 | +- ptr = skb_push(skb, 8);
1229 | +- put_unaligned_le32(tx_cmd_a, ptr);
1230 | +- put_unaligned_le32(tx_cmd_b, ptr + 4);
1231 | ++ mutex_unlock(&dev->dev_mutex);
1232 | +
1233 | +- return skb;
1234 | ++ return 0;
1235 | + }
1236 | +
1237 | + static enum skb_state defer_bh(struct lan78xx_net *dev, struct sk_buff *skb,
1238 | +@@ -2817,17 +3180,21 @@ static enum skb_state defer_bh(struct lan78xx_net *dev, struct sk_buff *skb,
1239 | + struct skb_data *entry = (struct skb_data *)skb->cb;
1240 | +
1241 | + spin_lock_irqsave(&list->lock, flags);
1242 | ++
1243 | + old_state = entry->state;
1244 | + entry->state = state;
1245 | +
1246 | + __skb_unlink(skb, list);
1247 | ++
1248 | + spin_unlock(&list->lock);
1249 | +- spin_lock(&dev->done.lock);
1250 | ++ spin_lock(&dev->rxq_done.lock);
1251 | ++
1252 | ++ __skb_queue_tail(&dev->rxq_done, skb);
1253 | +
1254 | +- __skb_queue_tail(&dev->done, skb);
1255 | +- if (skb_queue_len(&dev->done) == 1)
1256 | +- tasklet_schedule(&dev->bh);
1257 | +- spin_unlock_irqrestore(&dev->done.lock, flags);
1258 | ++ if (skb_queue_len(&dev->rxq_done) == 1)
1259 | ++ napi_schedule(&dev->napi);
1260 | ++
1261 | ++ spin_unlock_irqrestore(&dev->rxq_done.lock, flags);
1262 | +
1263 | + return old_state;
1264 | + }
1265 | +@@ -2838,11 +3205,14 @@ static void tx_complete(struct urb *urb)
1266 | + struct skb_data *entry = (struct skb_data *)skb->cb;
1267 | + struct lan78xx_net *dev = entry->dev;
1268 | +
1269 | ++ netif_dbg(dev, tx_done, dev->net,
1270 | ++ "tx done: status %d\n", urb->status);
1271 | ++
1272 | + if (urb->status == 0) {
1273 | + dev->net->stats.tx_packets += entry->num_of_packet;
1274 | + dev->net->stats.tx_bytes += entry->length;
1275 | + } else {
1276 | +- dev->net->stats.tx_errors++;
1277 | ++ dev->net->stats.tx_errors += entry->num_of_packet;
1278 | +
1279 | + switch (urb->status) {
1280 | + case -EPIPE:
1281 | +@@ -2852,23 +3222,35 @@ static void tx_complete(struct urb *urb)
1282 | + /* software-driven interface shutdown */
1283 | + case -ECONNRESET:
1284 | + case -ESHUTDOWN:
1285 | ++ netif_dbg(dev, tx_err, dev->net,
1286 | ++ "tx err interface gone %d\n", entry->urb->status);
1287 | + break;
1288 | +
1289 | + case -EPROTO:
1290 | + case -ETIME:
1291 | + case -EILSEQ:
1292 | + netif_stop_queue(dev->net);
1293 | ++ netif_dbg(dev, tx_err, dev->net,
1294 | ++ "tx err queue stopped %d\n", entry->urb->status);
1295 | + break;
1296 | + default:
1297 | + netif_dbg(dev, tx_err, dev->net,
1298 | +- "tx err %d\n", entry->urb->status);
1299 | ++ "unknown tx err %d\n", entry->urb->status);
1300 | + break;
1301 | + }
1302 | + }
1303 | +
1304 | + usb_autopm_put_interface_async(dev->intf);
1305 | +
1306 | +- defer_bh(dev, skb, &dev->txq, tx_done);
1307 | ++ skb_unlink(skb, &dev->txq);
1308 | ++
1309 | ++ lan78xx_free_tx_buf(dev, skb);
1310 | ++
1311 | ++ /* Re-schedule NAPI if Tx data pending but no URBs in progress.
1312 | ++ */
1313 | ++ if (skb_queue_empty(&dev->txq) &&
1314 | ++ !skb_queue_empty(&dev->txq_pend))
1315 | ++ napi_schedule(&dev->napi);
1316 | + }
1317 | +
1318 | + static void lan78xx_queue_skb(struct sk_buff_head *list,
1319 | +@@ -2880,32 +3262,102 @@ static void lan78xx_queue_skb(struct sk_buff_head *list,
1320 | + entry->state = state;
1321 | + }
1322 | +
1323 | ++#define LAN78XX_TX_URB_SPACE(dev) (skb_queue_len(&(dev)->txq_free) * \
1324 | ++ (dev)->tx_urb_size)
1325 | ++
1326 | ++static int lan78xx_tx_pend_data_len(struct lan78xx_net *dev)
1327 | ++{
1328 | ++ return dev->tx_pend_data_len;
1329 | ++}
1330 | ++
1331 | ++static int lan78x_tx_pend_skb_add(struct lan78xx_net *dev, struct sk_buff *skb)
1332 | ++{
1333 | ++ int tx_pend_data_len;
1334 | ++ unsigned long flags;
1335 | ++
1336 | ++ spin_lock_irqsave(&dev->txq_pend.lock, flags);
1337 | ++
1338 | ++ __skb_queue_tail(&dev->txq_pend, skb);
1339 | ++
1340 | ++ dev->tx_pend_data_len += skb->len;
1341 | ++ tx_pend_data_len = dev->tx_pend_data_len;
1342 | ++
1343 | ++ spin_unlock_irqrestore(&dev->txq_pend.lock, flags);
1344 | ++
1345 | ++ return tx_pend_data_len;
1346 | ++}
1347 | ++
1348 | ++static int lan78x_tx_pend_skb_head_add(struct lan78xx_net *dev, struct sk_buff *skb)
1349 | ++{
1350 | ++ int tx_pend_data_len;
1351 | ++ unsigned long flags;
1352 | ++
1353 | ++ spin_lock_irqsave(&dev->txq_pend.lock, flags);
1354 | ++
1355 | ++ __skb_queue_head(&dev->txq_pend, skb);
1356 | ++
1357 | ++ dev->tx_pend_data_len += skb->len;
1358 | ++ tx_pend_data_len = dev->tx_pend_data_len;
1359 | ++
1360 | ++ spin_unlock_irqrestore(&dev->txq_pend.lock, flags);
1361 | ++
1362 | ++ return tx_pend_data_len;
1363 | ++}
1364 | ++
1365 | ++static int lan78x_tx_pend_skb_get(struct lan78xx_net *dev, struct sk_buff **skb)
1366 | ++{
1367 | ++ int tx_pend_data_len;
1368 | ++ unsigned long flags;
1369 | ++
1370 | ++ spin_lock_irqsave(&dev->txq_pend.lock, flags);
1371 | ++
1372 | ++ *skb = __skb_dequeue(&dev->txq_pend);
1373 | ++
1374 | ++ if (*skb)
1375 | ++ dev->tx_pend_data_len -= (*skb)->len;
1376 | ++ tx_pend_data_len = dev->tx_pend_data_len;
1377 | ++
1378 | ++ spin_unlock_irqrestore(&dev->txq_pend.lock, flags);
1379 | ++
1380 | ++ return tx_pend_data_len;
1381 | ++}
1382 | ++
1383 | + static netdev_tx_t
1384 | + lan78xx_start_xmit(struct sk_buff *skb, struct net_device *net)
1385 | + {
1386 | ++ int tx_pend_data_len;
1387 | ++
1388 | + struct lan78xx_net *dev = netdev_priv(net);
1389 | +- struct sk_buff *skb2 = NULL;
1390 | +
1391 | +- if (skb) {
1392 | +- skb_tx_timestamp(skb);
1393 | +- skb2 = lan78xx_tx_prep(dev, skb, GFP_ATOMIC);
1394 | +- }
1395 | ++ /* Get the deferred work handler to resume the
1396 | ++ * device if it's suspended.
1397 | ++ */
1398 | ++ if (test_bit(EVENT_DEV_ASLEEP, &dev->flags))
1399 | ++ schedule_delayed_work(&dev->wq, 0);
1400 | +
1401 | +- if (skb2) {
1402 | +- skb_queue_tail(&dev->txq_pend, skb2);
1403 | ++ skb_tx_timestamp(skb);
1404 | +
1405 | +- /* throttle TX patch at slower than SUPER SPEED USB */
1406 | +- if ((dev->udev->speed < USB_SPEED_SUPER) &&
1407 | +- (skb_queue_len(&dev->txq_pend) > 10))
1408 | +- netif_stop_queue(net);
1409 | +- } else {
1410 | +- netif_dbg(dev, tx_err, dev->net,
1411 | +- "lan78xx_tx_prep return NULL\n");
1412 | +- dev->net->stats.tx_errors++;
1413 | +- dev->net->stats.tx_dropped++;
1414 | +- }
1415 | ++ tx_pend_data_len = lan78x_tx_pend_skb_add(dev, skb);
1416 | ++
1417 | ++ /* Set up a Tx URB if none is in progress.
1418 | ++ */
1419 | ++ if (skb_queue_empty(&dev->txq))
1420 | ++ napi_schedule(&dev->napi);
1421 | ++
1422 | ++ /* Stop stack Tx queue if we have enough data to fill
1423 | ++ * all the free Tx URBs.
1424 | ++ */
1425 | ++ if (tx_pend_data_len > LAN78XX_TX_URB_SPACE(dev)) {
1426 | ++ netif_stop_queue(net);
1427 | ++
1428 | ++ netif_dbg(dev, hw, dev->net, "tx data len: %d, urb space %d\n",
1429 | ++ tx_pend_data_len, LAN78XX_TX_URB_SPACE(dev));
1430 | +
1431 | +- tasklet_schedule(&dev->bh);
1432 | ++ /* Kick off transmission of pending data */
1433 | ++
1434 | ++ if (!skb_queue_empty(&dev->txq_free))
1435 | ++ napi_schedule(&dev->napi);
1436 | ++ }
1437 | +
1438 | + return NETDEV_TX_OK;
1439 | + }
1440 | +@@ -2944,14 +3396,8 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf)
1441 | + if (DEFAULT_RX_CSUM_ENABLE)
1442 | + dev->net->features |= NETIF_F_RXCSUM;
1443 | +
1444 | +- if (DEFAULT_TSO_CSUM_ENABLE) {
1445 | +- dev->net->features |= NETIF_F_SG;
1446 | +- /* Use module parameter to control TCP segmentation offload as
1447 | +- * it appears to cause issues.
1448 | +- */
1449 | +- if (enable_tso)
1450 | +- dev->net->features |= NETIF_F_TSO | NETIF_F_TSO6;
1451 | +- }
1452 | ++ if (DEFAULT_TSO_CSUM_ENABLE)
1453 | ++ dev->net->features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG;
1454 | +
1455 | + if (DEFAULT_VLAN_RX_OFFLOAD)
1456 | + dev->net->features |= NETIF_F_HW_VLAN_CTAG_RX;
1457 | +@@ -2968,9 +3414,6 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf)
1458 | + goto out1;
1459 | + }
1460 | +
1461 | +- dev->net->hard_header_len += TX_OVERHEAD;
1462 | +- dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
1463 | +-
1464 | + /* Init all registers */
1465 | + ret = lan78xx_reset(dev);
1466 | + if (ret) {
1467 | +@@ -3049,12 +3492,7 @@ static void lan78xx_rx_vlan_offload(struct lan78xx_net *dev,
1468 | +
1469 | + static void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb)
1470 | + {
1471 | +- int status;
1472 | +-
1473 | +- if (test_bit(EVENT_RX_PAUSED, &dev->flags)) {
1474 | +- skb_queue_tail(&dev->rxq_pause, skb);
1475 | +- return;
1476 | +- }
1477 | ++ gro_result_t gro_result;
1478 | +
1479 | + dev->net->stats.rx_packets++;
1480 | + dev->net->stats.rx_bytes += skb->len;
1481 | +@@ -3068,21 +3506,24 @@ static void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb)
1482 | + if (skb_defer_rx_timestamp(skb))
1483 | + return;
1484 | +
1485 | +- status = netif_rx(skb);
1486 | +- if (status != NET_RX_SUCCESS)
1487 | +- netif_dbg(dev, rx_err, dev->net,
1488 | +- "netif_rx status %d\n", status);
1489 | ++ gro_result = napi_gro_receive(&dev->napi, skb);
1490 | ++
1491 | ++ if (gro_result == GRO_DROP)
1492 | ++ netif_dbg(dev, rx_err, dev->net, "GRO packet dropped\n");
1493 | + }
1494 | +
1495 | +-static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb)
1496 | ++static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb,
1497 | ++ int budget, int *work_done)
1498 | + {
1499 | +- if (skb->len < dev->net->hard_header_len)
1500 | +- return 0;
1501 | ++ if (skb->len < RX_SKB_MIN_LEN)
1502 | ++ return -1;
1503 | +
1504 | ++ /* Extract frames from the URB buffer and pass each one to
1505 | ++ * the stack in a new NAPI SKB.
1506 | ++ */
1507 | + while (skb->len > 0) {
1508 | + u32 rx_cmd_a, rx_cmd_b, align_count, size;
1509 | + u16 rx_cmd_c;
1510 | +- struct sk_buff *skb2;
1511 | + unsigned char *packet;
1512 | +
1513 | + rx_cmd_a = get_unaligned_le32(skb->data);
1514 | +@@ -3104,36 +3545,33 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb)
1515 | + netif_dbg(dev, rx_err, dev->net,
1516 | + "Error rx_cmd_a=0x%08x", rx_cmd_a);
1517 | + } else {
1518 | +- /* last frame in this batch */
1519 | +- if (skb->len == size) {
1520 | +- lan78xx_rx_csum_offload(dev, skb,
1521 | +- rx_cmd_a, rx_cmd_b);
1522 | +- lan78xx_rx_vlan_offload(dev, skb,
1523 | +- rx_cmd_a, rx_cmd_b);
1524 | +-
1525 | +- skb_trim(skb, skb->len - 4); /* remove fcs */
1526 | +- skb->truesize = size + sizeof(struct sk_buff);
1527 | ++ struct sk_buff *skb2;
1528 | ++ u32 frame_len = size - ETH_FCS_LEN;
1529 | +
1530 | +- return 1;
1531 | +- }
1532 | +-
1533 | +- skb2 = skb_clone(skb, GFP_ATOMIC);
1534 | +- if (unlikely(!skb2)) {
1535 | ++ skb2 = napi_alloc_skb(&dev->napi, frame_len);
1536 | ++ if (!skb2) {
1537 | + netdev_warn(dev->net, "Error allocating skb");
1538 | +- return 0;
1539 | ++ return -1;
1540 | + }
1541 | +
1542 | +- skb2->len = size;
1543 | +- skb2->data = packet;
1544 | +- skb_set_tail_pointer(skb2, size);
1545 | ++ memcpy(skb2->data, packet, frame_len);
1546 | ++
1547 | ++ skb_put(skb2, frame_len);
1548 | +
1549 | + lan78xx_rx_csum_offload(dev, skb2, rx_cmd_a, rx_cmd_b);
1550 | + lan78xx_rx_vlan_offload(dev, skb2, rx_cmd_a, rx_cmd_b);
1551 | +
1552 | +- skb_trim(skb2, skb2->len - 4); /* remove fcs */
1553 | +- skb2->truesize = size + sizeof(struct sk_buff);
1554 | +-
1555 | +- lan78xx_skb_return(dev, skb2);
1556 | ++ /* Processing of the URB buffer must complete once
1557 | ++ * it has started. If the NAPI work budget is exhausted
1558 | ++ * while frames remain they are added to the overflow
1559 | ++ * queue for delivery in the next NAPI polling cycle.
1560 | ++ */
1561 | ++ if (*work_done < budget) {
1562 | ++ lan78xx_skb_return(dev, skb2);
1563 | ++ ++(*work_done);
1564 | ++ } else {
1565 | ++ skb_queue_tail(&dev->rxq_overflow, skb2);
1566 | ++ }
1567 | + }
1568 | +
1569 | + skb_pull(skb, size);
1570 | +@@ -3143,48 +3581,28 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb)
1571 | + skb_pull(skb, align_count);
1572 | + }
1573 | +
1574 | +- return 1;
1575 | ++ return 0;
1576 | + }
1577 | +
1578 | +-static inline void rx_process(struct lan78xx_net *dev, struct sk_buff *skb)
1579 | ++static inline void rx_process(struct lan78xx_net *dev, struct sk_buff *skb,
1580 | ++ int budget, int *work_done)
1581 | + {
1582 | +- if (!lan78xx_rx(dev, skb)) {
1583 | ++ if (lan78xx_rx(dev, skb, budget, work_done) < 0) {
1584 | ++ netif_dbg(dev, rx_err, dev->net, "drop\n");
1585 | + dev->net->stats.rx_errors++;
1586 | +- goto done;
1587 | +- }
1588 | +-
1589 | +- if (skb->len) {
1590 | +- lan78xx_skb_return(dev, skb);
1591 | +- return;
1592 | + }
1593 | +-
1594 | +- netif_dbg(dev, rx_err, dev->net, "drop\n");
1595 | +- dev->net->stats.rx_errors++;
1596 | +-done:
1597 | +- skb_queue_tail(&dev->done, skb);
1598 | + }
1599 | +
1600 | + static void rx_complete(struct urb *urb);
1601 | +
1602 | +-static int rx_submit(struct lan78xx_net *dev, struct urb *urb, gfp_t flags)
1603 | ++static int rx_submit(struct lan78xx_net *dev, struct sk_buff *skb, gfp_t flags)
1604 | + {
1605 | +- struct sk_buff *skb;
1606 | +- struct skb_data *entry;
1607 | ++ struct skb_data *entry = (struct skb_data *)skb->cb;
1608 | ++ struct urb *urb = entry->urb;
1609 | + unsigned long lockflags;
1610 | + size_t size = dev->rx_urb_size;
1611 | + int ret = 0;
1612 | +
1613 | +- skb = netdev_alloc_skb(dev->net, size);
1614 | +- if (!skb) {
1615 | +- usb_free_urb(urb);
1616 | +- return -ENOMEM;
1617 | +- }
1618 | +-
1619 | +- entry = (struct skb_data *)skb->cb;
1620 | +- entry->urb = urb;
1621 | +- entry->dev = dev;
1622 | +- entry->length = 0;
1623 | +-
1624 | + usb_fill_bulk_urb(urb, dev->udev, dev->pipe_in,
1625 | + skb->data, size, rx_complete, skb);
1626 | +
1627 | +@@ -3194,7 +3612,7 @@ static int rx_submit(struct lan78xx_net *dev, struct urb *urb, gfp_t flags)
1628 | + netif_running(dev->net) &&
1629 | + !test_bit(EVENT_RX_HALT, &dev->flags) &&
1630 | + !test_bit(EVENT_DEV_ASLEEP, &dev->flags)) {
1631 | +- ret = usb_submit_urb(urb, GFP_ATOMIC);
1632 | ++ ret = usb_submit_urb(urb, flags);
1633 | + switch (ret) {
1634 | + case 0:
1635 | + lan78xx_queue_skb(&dev->rxq, skb, rx_start);
1636 | +@@ -3203,25 +3621,28 @@ static int rx_submit(struct lan78xx_net *dev, struct urb *urb, gfp_t flags)
1637 | + lan78xx_defer_kevent(dev, EVENT_RX_HALT);
1638 | + break;
1639 | + case -ENODEV:
1640 | ++ case -ENOENT:
1641 | + netif_dbg(dev, ifdown, dev->net, "device gone\n");
1642 | + netif_device_detach(dev->net);
1643 | + break;
1644 | + case -EHOSTUNREACH:
1645 | + ret = -ENOLINK;
1646 | ++ napi_schedule(&dev->napi);
1647 | + break;
1648 | + default:
1649 | + netif_dbg(dev, rx_err, dev->net,
1650 | + "rx submit, %d\n", ret);
1651 | +- tasklet_schedule(&dev->bh);
1652 | ++ napi_schedule(&dev->napi);
1653 | ++ break;
1654 | + }
1655 | + } else {
1656 | + netif_dbg(dev, ifdown, dev->net, "rx: stopped\n");
1657 | + ret = -ENOLINK;
1658 | + }
1659 | + spin_unlock_irqrestore(&dev->rxq.lock, lockflags);
1660 | ++
1661 | + if (ret) {
1662 | +- dev_kfree_skb_any(skb);
1663 | +- usb_free_urb(urb);
1664 | ++ lan78xx_free_rx_buf(dev, skb);
1665 | + }
1666 | + return ret;
1667 | + }
1668 | +@@ -3236,11 +3657,13 @@ static void rx_complete(struct urb *urb)
1669 | +
1670 | + skb_put(skb, urb->actual_length);
1671 | + state = rx_done;
1672 | +- entry->urb = NULL;
1673 | ++
1674 | ++ if (urb != entry->urb)
1675 | ++ netif_warn(dev, rx_err, dev->net, "URB pointer mismatch\n");
1676 | +
1677 | + switch (urb_status) {
1678 | + case 0:
1679 | +- if (skb->len < dev->net->hard_header_len) {
1680 | ++ if (skb->len < RX_SKB_MIN_LEN) {
1681 | + state = rx_cleanup;
1682 | + dev->net->stats.rx_errors++;
1683 | + dev->net->stats.rx_length_errors++;
1684 | +@@ -3258,16 +3681,12 @@ static void rx_complete(struct urb *urb)
1685 | + netif_dbg(dev, ifdown, dev->net,
1686 | + "rx shutdown, code %d\n", urb_status);
1687 | + state = rx_cleanup;
1688 | +- entry->urb = urb;
1689 | +- urb = NULL;
1690 | + break;
1691 | + case -EPROTO:
1692 | + case -ETIME:
1693 | + case -EILSEQ:
1694 | + dev->net->stats.rx_errors++;
1695 | + state = rx_cleanup;
1696 | +- entry->urb = urb;
1697 | +- urb = NULL;
1698 | + break;
1699 | +
1700 | + /* data overrun ... flush fifo? */
1701 | +@@ -3283,196 +3702,274 @@ static void rx_complete(struct urb *urb)
1702 | + }
1703 | +
1704 | + state = defer_bh(dev, skb, &dev->rxq, state);
1705 | ++}
1706 | +
1707 | +- if (urb) {
1708 | +- if (netif_running(dev->net) &&
1709 | +- !test_bit(EVENT_RX_HALT, &dev->flags) &&
1710 | +- state != unlink_start) {
1711 | +- rx_submit(dev, urb, GFP_ATOMIC);
1712 | +- return;
1713 | +- }
1714 | +- usb_free_urb(urb);
1715 | ++static void lan78xx_fill_tx_cmd_words(struct sk_buff *skb, u8 *buffer)
1716 | ++{
1717 | ++ u32 tx_cmd_a, tx_cmd_b;
1718 | ++
1719 | ++ tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN_MASK_) | TX_CMD_A_FCS_;
1720 | ++
1721 | ++ if (skb->ip_summed == CHECKSUM_PARTIAL)
1722 | ++ tx_cmd_a |= TX_CMD_A_IPE_ | TX_CMD_A_TPE_;
1723 | ++
1724 | ++ tx_cmd_b = 0;
1725 | ++ if (skb_is_gso(skb)) {
1726 | ++ u16 mss = max(skb_shinfo(skb)->gso_size, TX_CMD_B_MSS_MIN_);
1727 | ++
1728 | ++ tx_cmd_b = (mss << TX_CMD_B_MSS_SHIFT_) & TX_CMD_B_MSS_MASK_;
1729 | ++
1730 | ++ tx_cmd_a |= TX_CMD_A_LSO_;
1731 | ++ }
1732 | ++
1733 | ++ if (skb_vlan_tag_present(skb)) {
1734 | ++ tx_cmd_a |= TX_CMD_A_IVTG_;
1735 | ++ tx_cmd_b |= skb_vlan_tag_get(skb) & TX_CMD_B_VTAG_MASK_;
1736 | + }
1737 | +- netif_dbg(dev, rx_err, dev->net, "no read resubmitted\n");
1738 | ++
1739 | ++ put_unaligned_le32(tx_cmd_a, buffer);
1740 | ++ put_unaligned_le32(tx_cmd_b, buffer + 4);
1741 | + }
1742 | +
1743 | +-static void lan78xx_tx_bh(struct lan78xx_net *dev)
1744 | ++static struct skb_data *lan78xx_tx_buf_fill(struct lan78xx_net *dev,
1745 | ++ struct sk_buff *tx_buf)
1746 | + {
1747 | +- int length;
1748 | +- struct urb *urb = NULL;
1749 | ++ int remain;
1750 | ++ u8 *tx_data;
1751 | ++ u32 urb_len;
1752 | + struct skb_data *entry;
1753 | +- unsigned long flags;
1754 | +- struct sk_buff_head *tqp = &dev->txq_pend;
1755 | +- struct sk_buff *skb, *skb2;
1756 | +- int ret;
1757 | +- int count, pos;
1758 | +- int skb_totallen, pkt_cnt;
1759 | +-
1760 | +- skb_totallen = 0;
1761 | +- pkt_cnt = 0;
1762 | +- count = 0;
1763 | +- length = 0;
1764 | +- spin_lock_irqsave(&tqp->lock, flags);
1765 | +- skb_queue_walk(tqp, skb) {
1766 | +- if (skb_is_gso(skb)) {
1767 | +- if (!skb_queue_is_first(tqp, skb)) {
1768 | +- /* handle previous packets first */
1769 | +- break;
1770 | +- }
1771 | +- count = 1;
1772 | +- length = skb->len - TX_OVERHEAD;
1773 | +- __skb_unlink(skb, tqp);
1774 | +- spin_unlock_irqrestore(&tqp->lock, flags);
1775 | +- goto gso_skb;
1776 | +- }
1777 | +
1778 | +- if ((skb_totallen + skb->len) > MAX_SINGLE_PACKET_SIZE)
1779 | ++ tx_data = tx_buf->data;
1780 | ++ entry = (struct skb_data *)tx_buf->cb;
1781 | ++ entry->num_of_packet = 0;
1782 | ++ entry->length = 0;
1783 | ++ urb_len = 0;
1784 | ++ remain = dev->tx_urb_size;
1785 | ++
1786 | ++ /* Work through the pending SKBs and copy the data of each SKB into
1787 | ++ * the URB buffer if there room for all the SKB data.
1788 | ++ *
1789 | ++ * There must be at least DST+SRC+TYPE in the SKB (with padding enabled)
1790 | ++ */
1791 | ++ while (remain >= TX_SKB_MIN_LEN) {
1792 | ++ struct sk_buff *skb;
1793 | ++ unsigned int len, align;
1794 | ++
1795 | ++ lan78x_tx_pend_skb_get(dev, &skb);
1796 | ++
1797 | ++ if (!skb)
1798 | ++ break;
1799 | ++
1800 | ++ align = (TX_ALIGNMENT - (urb_len % TX_ALIGNMENT)) % TX_ALIGNMENT;
1801 | ++ len = align + TX_CMD_LEN + skb->len;
1802 | ++ if (len > remain) {
1803 | ++ lan78x_tx_pend_skb_head_add(dev, skb);
1804 | + break;
1805 | +- skb_totallen = skb->len + roundup(skb_totallen, sizeof(u32));
1806 | +- pkt_cnt++;
1807 | +- }
1808 | +- spin_unlock_irqrestore(&tqp->lock, flags);
1809 | +-
1810 | +- /* copy to a single skb */
1811 | +- skb = alloc_skb(skb_totallen, GFP_ATOMIC);
1812 | +- if (!skb)
1813 | +- goto drop;
1814 | +-
1815 | +- skb_put(skb, skb_totallen);
1816 | +-
1817 | +- for (count = pos = 0; count < pkt_cnt; count++) {
1818 | +- skb2 = skb_dequeue(tqp);
1819 | +- if (skb2) {
1820 | +- length += (skb2->len - TX_OVERHEAD);
1821 | +- memcpy(skb->data + pos, skb2->data, skb2->len);
1822 | +- pos += roundup(skb2->len, sizeof(u32));
1823 | +- dev_kfree_skb(skb2);
1824 | + }
1825 | +- }
1826 | +
1827 | +-gso_skb:
1828 | +- urb = usb_alloc_urb(0, GFP_ATOMIC);
1829 | +- if (!urb)
1830 | +- goto drop;
1831 | ++ tx_data += align;
1832 | +
1833 | +- entry = (struct skb_data *)skb->cb;
1834 | +- entry->urb = urb;
1835 | +- entry->dev = dev;
1836 | +- entry->length = length;
1837 | +- entry->num_of_packet = count;
1838 | ++ lan78xx_fill_tx_cmd_words(skb, tx_data);
1839 | ++ tx_data += TX_CMD_LEN;
1840 | +
1841 | +- spin_lock_irqsave(&dev->txq.lock, flags);
1842 | +- ret = usb_autopm_get_interface_async(dev->intf);
1843 | +- if (ret < 0) {
1844 | +- spin_unlock_irqrestore(&dev->txq.lock, flags);
1845 | +- goto drop;
1846 | ++ len = skb->len;
1847 | ++ if (skb_copy_bits(skb, 0, tx_data, len) < 0) {
1848 | ++ struct net_device_stats *stats = &dev->net->stats;
1849 | ++
1850 | ++ stats->tx_dropped++;
1851 | ++ dev_kfree_skb_any(skb);
1852 | ++ tx_data -= TX_CMD_LEN;
1853 | ++ continue;
1854 | ++ }
1855 | ++
1856 | ++ tx_data += len;
1857 | ++ entry->length += len;
1858 | ++ entry->num_of_packet += skb_shinfo(skb)->gso_segs ?: 1;
1859 | ++
1860 | ++ dev_kfree_skb_any(skb);
1861 | ++
1862 | ++ urb_len = (u32)(tx_data - (u8 *)tx_buf->data);
1863 | ++
1864 | ++ remain = dev->tx_urb_size - urb_len;
1865 | + }
1866 | +
1867 | +- usb_fill_bulk_urb(urb, dev->udev, dev->pipe_out,
1868 | +- skb->data, skb->len, tx_complete, skb);
1869 | ++ skb_put(tx_buf, urb_len);
1870 | ++
1871 | ++ return entry;
1872 | ++}
1873 | +
1874 | +- if (length % dev->maxpacket == 0) {
1875 | +- /* send USB_ZERO_PACKET */
1876 | +- urb->transfer_flags |= URB_ZERO_PACKET;
1877 | ++static void lan78xx_tx_bh(struct lan78xx_net *dev)
1878 | ++{
1879 | ++ int ret;
1880 | ++
1881 | ++ /* Start the stack Tx queue if it was stopped
1882 | ++ */
1883 | ++ netif_tx_lock(dev->net);
1884 | ++ if (netif_queue_stopped(dev->net)) {
1885 | ++ if (lan78xx_tx_pend_data_len(dev) < LAN78XX_TX_URB_SPACE(dev))
1886 | ++ netif_wake_queue(dev->net);
1887 | + }
1888 | ++ netif_tx_unlock(dev->net);
1889 | ++
1890 | ++ /* Go through the Tx pending queue and set up URBs to transfer
1891 | ++ * the data to the device. Stop if no more pending data or URBs,
1892 | ++ * or if an error occurs when a URB is submitted.
1893 | ++ */
1894 | ++ do {
1895 | ++ unsigned long flags;
1896 | ++ struct sk_buff *tx_buf;
1897 | ++ struct skb_data *entry;
1898 | ++
1899 | ++ if (skb_queue_empty(&dev->txq_pend))
1900 | ++ break;
1901 | ++
1902 | ++ tx_buf = lan78xx_get_tx_buf(dev);
1903 | ++ if (!tx_buf)
1904 | ++ break;
1905 | ++
1906 | ++ entry = lan78xx_tx_buf_fill(dev, tx_buf);
1907 | ++
1908 | ++ spin_lock_irqsave(&dev->txq.lock, flags);
1909 | ++ ret = usb_autopm_get_interface_async(dev->intf);
1910 | ++ if (ret < 0) {
1911 | ++ spin_unlock_irqrestore(&dev->txq.lock, flags);
1912 | ++ goto out;
1913 | ++ }
1914 | ++
1915 | ++ usb_fill_bulk_urb(entry->urb, dev->udev, dev->pipe_out,
1916 | ++ tx_buf->data, tx_buf->len, tx_complete, tx_buf);
1917 | ++
1918 | ++ if (tx_buf->len % dev->maxpacket == 0) {
1919 | ++ /* send USB_ZERO_PACKET */
1920 | ++ entry->urb->transfer_flags |= URB_ZERO_PACKET;
1921 | ++ }
1922 | +
1923 | + #ifdef CONFIG_PM
1924 | +- /* if this triggers the device is still a sleep */
1925 | +- if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) {
1926 | +- /* transmission will be done in resume */
1927 | +- usb_anchor_urb(urb, &dev->deferred);
1928 | +- /* no use to process more packets */
1929 | +- netif_stop_queue(dev->net);
1930 | +- usb_put_urb(urb);
1931 | +- spin_unlock_irqrestore(&dev->txq.lock, flags);
1932 | +- netdev_dbg(dev->net, "Delaying transmission for resumption\n");
1933 | +- return;
1934 | +- }
1935 | ++ /* if this triggers the device is still a sleep */
1936 | ++ if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) {
1937 | ++ /* transmission will be done in resume */
1938 | ++ usb_anchor_urb(entry->urb, &dev->deferred);
1939 | ++ /* no use to process more packets */
1940 | ++ netif_stop_queue(dev->net);
1941 | ++ spin_unlock_irqrestore(&dev->txq.lock, flags);
1942 | ++ netdev_dbg(dev->net, "Delaying transmission for resumption\n");
1943 | ++ return;
1944 | ++ }
1945 | + #endif
1946 | +-
1947 | +- ret = usb_submit_urb(urb, GFP_ATOMIC);
1948 | +- switch (ret) {
1949 | +- case 0:
1950 | +- netif_trans_update(dev->net);
1951 | +- lan78xx_queue_skb(&dev->txq, skb, tx_start);
1952 | +- if (skb_queue_len(&dev->txq) >= dev->tx_qlen)
1953 | ++ ret = usb_submit_urb(entry->urb, GFP_ATOMIC);
1954 | ++ switch (ret) {
1955 | ++ case 0:
1956 | ++ netif_trans_update(dev->net);
1957 | ++ lan78xx_queue_skb(&dev->txq, tx_buf, tx_start);
1958 | ++ break;
1959 | ++ case -EPIPE:
1960 | + netif_stop_queue(dev->net);
1961 | +- break;
1962 | +- case -EPIPE:
1963 | +- netif_stop_queue(dev->net);
1964 | +- lan78xx_defer_kevent(dev, EVENT_TX_HALT);
1965 | +- usb_autopm_put_interface_async(dev->intf);
1966 | +- break;
1967 | +- default:
1968 | +- usb_autopm_put_interface_async(dev->intf);
1969 | +- netif_dbg(dev, tx_err, dev->net,
1970 | +- "tx: submit urb err %d\n", ret);
1971 | +- break;
1972 | +- }
1973 | ++ lan78xx_defer_kevent(dev, EVENT_TX_HALT);
1974 | ++ usb_autopm_put_interface_async(dev->intf);
1975 | ++ break;
1976 | ++ case -ENODEV:
1977 | ++ case -ENOENT:
1978 | ++ netif_dbg(dev, tx_err, dev->net,
1979 | ++ "tx: submit urb err %d (disconnected?)", ret);
1980 | ++ netif_device_detach(dev->net);
1981 | ++ break;
1982 | ++ default:
1983 | ++ usb_autopm_put_interface_async(dev->intf);
1984 | ++ netif_dbg(dev, tx_err, dev->net,
1985 | ++ "tx: submit urb err %d\n", ret);
1986 | ++ break;
1987 | ++ }
1988 | +
1989 | +- spin_unlock_irqrestore(&dev->txq.lock, flags);
1990 | ++ spin_unlock_irqrestore(&dev->txq.lock, flags);
1991 | +
1992 | +- if (ret) {
1993 | +- netif_dbg(dev, tx_err, dev->net, "drop, code %d\n", ret);
1994 | +-drop:
1995 | +- dev->net->stats.tx_dropped++;
1996 | +- if (skb)
1997 | +- dev_kfree_skb_any(skb);
1998 | +- usb_free_urb(urb);
1999 | +- } else
2000 | +- netif_dbg(dev, tx_queued, dev->net,
2001 | +- "> tx, len %d, type 0x%x\n", length, skb->protocol);
2002 | ++ if (ret) {
2003 | ++ netdev_warn(dev->net, "failed to tx urb %d\n", ret);
2004 | ++out:
2005 | ++ dev->net->stats.tx_dropped += entry->num_of_packet;
2006 | ++ lan78xx_free_tx_buf(dev, tx_buf);
2007 | ++ }
2008 | ++ } while (ret == 0);
2009 | + }
2010 | +
2011 | +-static void lan78xx_rx_bh(struct lan78xx_net *dev)
2012 | ++static void lan78xx_rx_urb_submit_all(struct lan78xx_net *dev)
2013 | + {
2014 | +- struct urb *urb;
2015 | +- int i;
2016 | +-
2017 | +- if (skb_queue_len(&dev->rxq) < dev->rx_qlen) {
2018 | +- for (i = 0; i < 10; i++) {
2019 | +- if (skb_queue_len(&dev->rxq) >= dev->rx_qlen)
2020 | +- break;
2021 | +- urb = usb_alloc_urb(0, GFP_ATOMIC);
2022 | +- if (urb)
2023 | +- if (rx_submit(dev, urb, GFP_ATOMIC) == -ENOLINK)
2024 | +- return;
2025 | +- }
2026 | ++ struct sk_buff *rx_buf;
2027 | +
2028 | +- if (skb_queue_len(&dev->rxq) < dev->rx_qlen)
2029 | +- tasklet_schedule(&dev->bh);
2030 | ++ /* Ensure the maximum number of Rx URBs is submitted
2031 | ++ */
2032 | ++ while ((rx_buf = lan78xx_get_rx_buf(dev)) != NULL) {
2033 | ++ if (rx_submit(dev, rx_buf, GFP_ATOMIC) != 0)
2034 | ++ break;
2035 | + }
2036 | +- if (skb_queue_len(&dev->txq) < dev->tx_qlen)
2037 | +- netif_wake_queue(dev->net);
2038 | + }
2039 | +
2040 | +-static void lan78xx_bh(unsigned long param)
2041 | ++static void lan78xx_rx_urb_resubmit(struct lan78xx_net *dev,
2042 | ++ struct sk_buff *rx_buf)
2043 | + {
2044 | +- struct lan78xx_net *dev = (struct lan78xx_net *)param;
2045 | +- struct sk_buff *skb;
2046 | ++ /* reset SKB data pointers */
2047 | ++
2048 | ++ rx_buf->data = rx_buf->head;
2049 | ++ skb_reset_tail_pointer(rx_buf);
2050 | ++ rx_buf->len = 0;
2051 | ++ rx_buf->data_len = 0;
2052 | ++
2053 | ++ rx_submit(dev, rx_buf, GFP_ATOMIC);
2054 | ++}
2055 | ++
2056 | ++static int lan78xx_bh(struct lan78xx_net *dev, int budget)
2057 | ++{
2058 | ++ struct sk_buff_head done;
2059 | ++ struct sk_buff *rx_buf;
2060 | + struct skb_data *entry;
2061 | ++ int work_done = 0;
2062 | ++ unsigned long flags;
2063 | +
2064 | +- while ((skb = skb_dequeue(&dev->done))) {
2065 | +- entry = (struct skb_data *)(skb->cb);
2066 | ++ /* Pass frames received in the last NAPI cycle before
2067 | ++ * working on newly completed URBs.
2068 | ++ */
2069 | ++ while (!skb_queue_empty(&dev->rxq_overflow)) {
2070 | ++ lan78xx_skb_return(dev, skb_dequeue(&dev->rxq_overflow));
2071 | ++ ++work_done;
2072 | ++ }
2073 | ++
2074 | ++ /* Take a snapshot of the done queue and move items to a
2075 | ++ * temporary queue. Rx URB completions will continue to add
2076 | ++ * to the done queue.
2077 | ++ */
2078 | ++ __skb_queue_head_init(&done);
2079 | ++
2080 | ++ spin_lock_irqsave(&dev->rxq_done.lock, flags);
2081 | ++ skb_queue_splice_init(&dev->rxq_done, &done);
2082 | ++ spin_unlock_irqrestore(&dev->rxq_done.lock, flags);
2083 | ++
2084 | ++ /* Extract receive frames from completed URBs and
2085 | ++ * pass them to the stack. Re-submit each completed URB.
2086 | ++ */
2087 | ++ while ((work_done < budget) &&
2088 | ++ (rx_buf = __skb_dequeue(&done))) {
2089 | ++ entry = (struct skb_data *)(rx_buf->cb);
2090 | + switch (entry->state) {
2091 | + case rx_done:
2092 | +- entry->state = rx_cleanup;
2093 | +- rx_process(dev, skb);
2094 | +- continue;
2095 | +- case tx_done:
2096 | +- usb_free_urb(entry->urb);
2097 | +- dev_kfree_skb(skb);
2098 | +- continue;
2099 | ++ rx_process(dev, rx_buf, budget, &work_done);
2100 | ++ break;
2101 | + case rx_cleanup:
2102 | +- usb_free_urb(entry->urb);
2103 | +- dev_kfree_skb(skb);
2104 | +- continue;
2105 | ++ break;
2106 | + default:
2107 | +- netdev_dbg(dev->net, "skb state %d\n", entry->state);
2108 | +- return;
2109 | ++ netdev_dbg(dev->net, "rx buf state %d\n", entry->state);
2110 | ++ break;
2111 | + }
2112 | ++
2113 | ++ lan78xx_rx_urb_resubmit(dev, rx_buf);
2114 | + }
2115 | +
2116 | ++ /* If budget was consumed before processing all the URBs put them
2117 | ++ * back on the front of the done queue. They will be first to be
2118 | ++ * processed in the next NAPI cycle.
2119 | ++ */
2120 | ++ spin_lock_irqsave(&dev->rxq_done.lock, flags);
2121 | ++ skb_queue_splice(&done, &dev->rxq_done);
2122 | ++ spin_unlock_irqrestore(&dev->rxq_done.lock, flags);
2123 | ++
2124 | + if (netif_device_present(dev->net) && netif_running(dev->net)) {
2125 | + /* reset update timer delta */
2126 | + if (timer_pending(&dev->stat_monitor) && (dev->delta != 1)) {
2127 | +@@ -3481,13 +3978,61 @@ static void lan78xx_bh(unsigned long param)
2128 | + jiffies + STAT_UPDATE_TIMER);
2129 | + }
2130 | +
2131 | +- if (!skb_queue_empty(&dev->txq_pend))
2132 | +- lan78xx_tx_bh(dev);
2133 | ++ /* Submit all free Rx URBs */
2134 | ++
2135 | ++ if (!test_bit(EVENT_RX_HALT, &dev->flags))
2136 | ++ lan78xx_rx_urb_submit_all(dev);
2137 | ++
2138 | ++ /* Submit new Tx URBs */
2139 | ++
2140 | ++ lan78xx_tx_bh(dev);
2141 | ++ }
2142 | ++
2143 | ++ return work_done;
2144 | ++}
2145 | ++
2146 | ++static int lan78xx_poll(struct napi_struct *napi, int budget)
2147 | ++{
2148 | ++ struct lan78xx_net *dev = container_of(napi, struct lan78xx_net, napi);
2149 | ++ int work_done;
2150 | ++ int result = budget;
2151 | ++
2152 | ++ /* Don't do any work if the device is suspended */
2153 | ++
2154 | ++ if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) {
2155 | ++ napi_complete_done(napi, 0);
2156 | ++ return 0;
2157 | ++ }
2158 | +
2159 | +- if (!timer_pending(&dev->delay) &&
2160 | +- !test_bit(EVENT_RX_HALT, &dev->flags))
2161 | +- lan78xx_rx_bh(dev);
2162 | ++ /* Process completed URBs and submit new URBs */
2163 | ++
2164 | ++ work_done = lan78xx_bh(dev, budget);
2165 | ++
2166 | ++ if (work_done < budget) {
2167 | ++ napi_complete_done(napi, work_done);
2168 | ++
2169 | ++ /* Start a new polling cycle if data was received or
2170 | ++ * data is waiting to be transmitted.
2171 | ++ */
2172 | ++ if (!skb_queue_empty(&dev->rxq_done)) {
2173 | ++ napi_schedule(napi);
2174 | ++ } else if (netif_carrier_ok(dev->net)) {
2175 | ++ if (skb_queue_empty(&dev->txq) &&
2176 | ++ !skb_queue_empty(&dev->txq_pend)) {
2177 | ++ napi_schedule(napi);
2178 | ++ } else {
2179 | ++ netif_tx_lock(dev->net);
2180 | ++ if (netif_queue_stopped(dev->net)) {
2181 | ++ netif_wake_queue(dev->net);
2182 | ++ napi_schedule(napi);
2183 | ++ }
2184 | ++ netif_tx_unlock(dev->net);
2185 | ++ }
2186 | ++ }
2187 | ++ result = work_done;
2188 | + }
2189 | ++
2190 | ++ return result;
2191 | + }
2192 | +
2193 | + static void lan78xx_delayedwork(struct work_struct *work)
2194 | +@@ -3497,18 +4042,20 @@ static void lan78xx_delayedwork(struct work_struct *work)
2195 | +
2196 | + dev = container_of(work, struct lan78xx_net, wq.work);
2197 | +
2198 | ++ if (test_bit(EVENT_DEV_DISCONNECT, &dev->flags))
2199 | ++ return;
2200 | ++
2201 | ++ if (usb_autopm_get_interface(dev->intf) < 0)
2202 | ++ return;
2203 | ++
2204 | + if (test_bit(EVENT_TX_HALT, &dev->flags)) {
2205 | + unlink_urbs(dev, &dev->txq);
2206 | +- status = usb_autopm_get_interface(dev->intf);
2207 | +- if (status < 0)
2208 | +- goto fail_pipe;
2209 | ++
2210 | + status = usb_clear_halt(dev->udev, dev->pipe_out);
2211 | +- usb_autopm_put_interface(dev->intf);
2212 | + if (status < 0 &&
2213 | + status != -EPIPE &&
2214 | + status != -ESHUTDOWN) {
2215 | + if (netif_msg_tx_err(dev))
2216 | +-fail_pipe:
2217 | + netdev_err(dev->net,
2218 | + "can't clear tx halt, status %d\n",
2219 | + status);
2220 | +@@ -3518,41 +4065,31 @@ static void lan78xx_delayedwork(struct work_struct *work)
2221 | + netif_wake_queue(dev->net);
2222 | + }
2223 | + }
2224 | ++
2225 | + if (test_bit(EVENT_RX_HALT, &dev->flags)) {
2226 | + unlink_urbs(dev, &dev->rxq);
2227 | +- status = usb_autopm_get_interface(dev->intf);
2228 | +- if (status < 0)
2229 | +- goto fail_halt;
2230 | + status = usb_clear_halt(dev->udev, dev->pipe_in);
2231 | +- usb_autopm_put_interface(dev->intf);
2232 | + if (status < 0 &&
2233 | + status != -EPIPE &&
2234 | + status != -ESHUTDOWN) {
2235 | + if (netif_msg_rx_err(dev))
2236 | +-fail_halt:
2237 | + netdev_err(dev->net,
2238 | + "can't clear rx halt, status %d\n",
2239 | + status);
2240 | + } else {
2241 | + clear_bit(EVENT_RX_HALT, &dev->flags);
2242 | +- tasklet_schedule(&dev->bh);
2243 | ++ napi_schedule(&dev->napi);
2244 | + }
2245 | ++
2246 | + }
2247 | +
2248 | + if (test_bit(EVENT_LINK_RESET, &dev->flags)) {
2249 | + int ret = 0;
2250 | +
2251 | + clear_bit(EVENT_LINK_RESET, &dev->flags);
2252 | +- status = usb_autopm_get_interface(dev->intf);
2253 | +- if (status < 0)
2254 | +- goto skip_reset;
2255 | + if (lan78xx_link_reset(dev) < 0) {
2256 | +- usb_autopm_put_interface(dev->intf);
2257 | +-skip_reset:
2258 | + netdev_info(dev->net, "link reset failed (%d)\n",
2259 | + ret);
2260 | +- } else {
2261 | +- usb_autopm_put_interface(dev->intf);
2262 | + }
2263 | + }
2264 | +
2265 | +@@ -3566,6 +4103,8 @@ static void lan78xx_delayedwork(struct work_struct *work)
2266 | +
2267 | + dev->delta = min((dev->delta * 2), 50);
2268 | + }
2269 | ++
2270 | ++ usb_autopm_put_interface(dev->intf);
2271 | + }
2272 | +
2273 | + static void intr_complete(struct urb *urb)
2274 | +@@ -3581,6 +4120,7 @@ static void intr_complete(struct urb *urb)
2275 | +
2276 | + /* software-driven interface shutdown */
2277 | + case -ENOENT: /* urb killed */
2278 | ++ case -ENODEV:
2279 | + case -ESHUTDOWN: /* hardware gone */
2280 | + netif_dbg(dev, ifdown, dev->net,
2281 | + "intr shutdown, code %d\n", status);
2282 | +@@ -3594,14 +4134,29 @@ static void intr_complete(struct urb *urb)
2283 | + break;
2284 | + }
2285 | +
2286 | +- if (!netif_running(dev->net))
2287 | ++ if (!netif_device_present(dev->net) ||
2288 | ++ !netif_running(dev->net)) {
2289 | ++ netdev_warn(dev->net, "not submitting new status URB");
2290 | + return;
2291 | ++ }
2292 | +
2293 | + memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);
2294 | ++
2295 | + status = usb_submit_urb(urb, GFP_ATOMIC);
2296 | +- if (status != 0)
2297 | +- netif_err(dev, timer, dev->net,
2298 | +- "intr resubmit --> %d\n", status);
2299 | ++
2300 | ++ switch (status) {
2301 | ++ case 0:
2302 | ++ break;
2303 | ++ case -ENODEV:
2304 | ++ case -ENOENT:
2305 | ++ netif_dbg(dev, timer, dev->net,
2306 | ++ "intr resubmit %d (disconnect?)", status);
2307 | ++ netif_device_detach(dev->net);
2308 | ++ break;
2309 | ++ default:
2310 | ++ netif_err(dev, timer, dev->net, "intr resubmit --> %d\n", status);
2311 | ++ break;
2312 | ++ }
2313 | + }
2314 | +
2315 | + static void lan78xx_disconnect(struct usb_interface *intf)
2316 | +@@ -3616,8 +4171,18 @@ static void lan78xx_disconnect(struct usb_interface *intf)
2317 | + if (!dev)
2318 | + return;
2319 | +
2320 | ++ set_bit(EVENT_DEV_DISCONNECT, &dev->flags);
2321 | ++
2322 | ++ netif_napi_del(&dev->napi);
2323 | ++
2324 | + udev = interface_to_usbdev(intf);
2325 | ++
2326 | + net = dev->net;
2327 | ++
2328 | ++ unregister_netdev(net);
2329 | ++
2330 | ++ cancel_delayed_work_sync(&dev->wq);
2331 | ++
2332 | + phydev = net->phydev;
2333 | +
2334 | + phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0);
2335 | +@@ -3628,14 +4193,16 @@ static void lan78xx_disconnect(struct usb_interface *intf)
2336 | + if (phy_is_pseudo_fixed_link(phydev))
2337 | + fixed_phy_unregister(phydev);
2338 | +
2339 | +- unregister_netdev(net);
2340 | +-
2341 | +- cancel_delayed_work_sync(&dev->wq);
2342 | +-
2343 | + usb_scuttle_anchored_urbs(&dev->deferred);
2344 | +
2345 | ++ if (timer_pending(&dev->stat_monitor))
2346 | ++ del_timer_sync(&dev->stat_monitor);
2347 | ++
2348 | + lan78xx_unbind(dev, intf);
2349 | +
2350 | ++ lan78xx_free_tx_resources(dev);
2351 | ++ lan78xx_free_rx_resources(dev);
2352 | ++
2353 | + usb_kill_urb(dev->urb_intr);
2354 | + usb_free_urb(dev->urb_intr);
2355 | +
2356 | +@@ -3648,14 +4215,16 @@ static void lan78xx_tx_timeout(struct net_device *net, unsigned int txqueue)
2357 | + struct lan78xx_net *dev = netdev_priv(net);
2358 | +
2359 | + unlink_urbs(dev, &dev->txq);
2360 | +- tasklet_schedule(&dev->bh);
2361 | ++ napi_schedule(&dev->napi);
2362 | + }
2363 | +
2364 | + static netdev_features_t lan78xx_features_check(struct sk_buff *skb,
2365 | + struct net_device *netdev,
2366 | + netdev_features_t features)
2367 | + {
2368 | +- if (skb->len + TX_OVERHEAD > MAX_SINGLE_PACKET_SIZE)
2369 | ++ struct lan78xx_net *dev = netdev_priv(netdev);
2370 | ++
2371 | ++ if (skb->len > LAN78XX_TSO_SIZE(dev))
2372 | + features &= ~NETIF_F_GSO_MASK;
2373 | +
2374 | + features = vlan_features_check(skb, features);
2375 | +@@ -3664,6 +4233,15 @@ static netdev_features_t lan78xx_features_check(struct sk_buff *skb,
2376 | + return features;
2377 | + }
2378 | +
2379 | ++static int lan78xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
2380 | ++{
2381 | ++ if (!netif_running(netdev))
2382 | ++ return -EINVAL;
2383 | ++
2384 | ++ return phy_mii_ioctl(netdev->phydev, rq, cmd);
2385 | ++}
2386 | ++
2387 | ++
2388 | + static const struct net_device_ops lan78xx_netdev_ops = {
2389 | + .ndo_open = lan78xx_open,
2390 | + .ndo_stop = lan78xx_stop,
2391 | +@@ -3672,7 +4250,7 @@ static const struct net_device_ops lan78xx_netdev_ops = {
2392 | + .ndo_change_mtu = lan78xx_change_mtu,
2393 | + .ndo_set_mac_address = lan78xx_set_mac_addr,
2394 | + .ndo_validate_addr = eth_validate_addr,
2395 | +- .ndo_do_ioctl = phy_do_ioctl_running,
2396 | ++ .ndo_do_ioctl = lan78xx_ioctl,
2397 | + .ndo_set_rx_mode = lan78xx_set_multicast,
2398 | + .ndo_set_features = lan78xx_set_features,
2399 | + .ndo_vlan_rx_add_vid = lan78xx_vlan_rx_add_vid,
2400 | +@@ -3721,12 +4299,31 @@ static int lan78xx_probe(struct usb_interface *intf,
2401 | +
2402 | + skb_queue_head_init(&dev->rxq);
2403 | + skb_queue_head_init(&dev->txq);
2404 | +- skb_queue_head_init(&dev->done);
2405 | +- skb_queue_head_init(&dev->rxq_pause);
2406 | ++ skb_queue_head_init(&dev->rxq_done);
2407 | + skb_queue_head_init(&dev->txq_pend);
2408 | ++ skb_queue_head_init(&dev->rxq_overflow);
2409 | + mutex_init(&dev->phy_mutex);
2410 | ++ mutex_init(&dev->dev_mutex);
2411 | ++
2412 | ++ ret = lan78xx_urb_config_init(dev);
2413 | ++ if (ret < 0)
2414 | ++ goto out2;
2415 | ++
2416 | ++ ret = lan78xx_alloc_tx_resources(dev);
2417 | ++ if (ret < 0)
2418 | ++ goto out2;
2419 | ++
2420 | ++ ret = lan78xx_alloc_rx_resources(dev);
2421 | ++ if (ret < 0)
2422 | ++ goto out3;
2423 | ++
2424 | ++ /* MTU range: 68 - 9000 */
2425 | ++ netdev->max_mtu = LAN78XX_MAX_MTU;
2426 | ++
2427 | ++ netif_set_gso_max_size(netdev, LAN78XX_TSO_SIZE(dev));
2428 | ++
2429 | ++ netif_napi_add(netdev, &dev->napi, lan78xx_poll, LAN78XX_NAPI_WEIGHT);
2430 | +
2431 | +- tasklet_init(&dev->bh, lan78xx_bh, (unsigned long)dev);
2432 | + INIT_DELAYED_WORK(&dev->wq, lan78xx_delayedwork);
2433 | + init_usb_anchor(&dev->deferred);
2434 | +
2435 | +@@ -3741,27 +4338,27 @@ static int lan78xx_probe(struct usb_interface *intf,
2436 | +
2437 | + if (intf->cur_altsetting->desc.bNumEndpoints < 3) {
2438 | + ret = -ENODEV;
2439 | +- goto out2;
2440 | ++ goto out4;
2441 | + }
2442 | +
2443 | + dev->pipe_in = usb_rcvbulkpipe(udev, BULK_IN_PIPE);
2444 | + ep_blkin = usb_pipe_endpoint(udev, dev->pipe_in);
2445 | + if (!ep_blkin || !usb_endpoint_is_bulk_in(&ep_blkin->desc)) {
2446 | + ret = -ENODEV;
2447 | +- goto out2;
2448 | ++ goto out4;
2449 | + }
2450 | +
2451 | + dev->pipe_out = usb_sndbulkpipe(udev, BULK_OUT_PIPE);
2452 | + ep_blkout = usb_pipe_endpoint(udev, dev->pipe_out);
2453 | + if (!ep_blkout || !usb_endpoint_is_bulk_out(&ep_blkout->desc)) {
2454 | + ret = -ENODEV;
2455 | +- goto out2;
2456 | ++ goto out4;
2457 | + }
2458 | +
2459 | + ep_intr = &intf->cur_altsetting->endpoint[2];
2460 | + if (!usb_endpoint_is_int_in(&ep_intr->desc)) {
2461 | + ret = -ENODEV;
2462 | +- goto out2;
2463 | ++ goto out4;
2464 | + }
2465 | +
2466 | + dev->pipe_intr = usb_rcvintpipe(dev->udev,
2467 | +@@ -3769,57 +4366,38 @@ static int lan78xx_probe(struct usb_interface *intf,
2468 | +
2469 | + ret = lan78xx_bind(dev, intf);
2470 | + if (ret < 0)
2471 | +- goto out2;
2472 | +-
2473 | +- if (netdev->mtu > (dev->hard_mtu - netdev->hard_header_len))
2474 | +- netdev->mtu = dev->hard_mtu - netdev->hard_header_len;
2475 | +-
2476 | +- /* MTU range: 68 - 9000 */
2477 | +- netdev->max_mtu = MAX_SINGLE_PACKET_SIZE;
2478 | +- netif_set_gso_max_size(netdev, MAX_SINGLE_PACKET_SIZE - MAX_HEADER);
2479 | +-
2480 | +- if (int_urb_interval_ms <= 0)
2481 | +- period = ep_intr->desc.bInterval;
2482 | +- else
2483 | +- period = int_urb_interval_ms * INT_URB_MICROFRAMES_PER_MS;
2484 | +-
2485 | +- netif_notice(dev, probe, netdev, "int urb period %d\n", period);
2486 | ++ goto out4;
2487 | +
2488 | ++ period = ep_intr->desc.bInterval;
2489 | + maxp = usb_maxpacket(dev->udev, dev->pipe_intr, 0);
2490 | + buf = kmalloc(maxp, GFP_KERNEL);
2491 | +- if (buf) {
2492 | +- dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL);
2493 | +- if (!dev->urb_intr) {
2494 | +- ret = -ENOMEM;
2495 | +- kfree(buf);
2496 | +- goto out3;
2497 | +- } else {
2498 | +- usb_fill_int_urb(dev->urb_intr, dev->udev,
2499 | +- dev->pipe_intr, buf, maxp,
2500 | +- intr_complete, dev, period);
2501 | +- dev->urb_intr->transfer_flags |= URB_FREE_BUFFER;
2502 | +- }
2503 | ++ if (!buf)
2504 | ++ goto out5;
2505 | ++
2506 | ++ dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL);
2507 | ++ if (!dev->urb_intr) {
2508 | ++ ret = -ENOMEM;
2509 | ++ goto out6;
2510 | ++ } else {
2511 | ++ usb_fill_int_urb(dev->urb_intr, dev->udev,
2512 | ++ dev->pipe_intr, buf, maxp,
2513 | ++ intr_complete, dev, period);
2514 | ++ dev->urb_intr->transfer_flags |= URB_FREE_BUFFER;
2515 | + }
2516 | +
2517 | + dev->maxpacket = usb_maxpacket(dev->udev, dev->pipe_out, 1);
2518 | +
2519 | +- /* Reject broken descriptors. */
2520 | +- if (dev->maxpacket == 0) {
2521 | +- ret = -ENODEV;
2522 | +- goto out4;
2523 | +- }
2524 | +-
2525 | + /* driver requires remote-wakeup capability during autosuspend. */
2526 | + intf->needs_remote_wakeup = 1;
2527 | +
2528 | + ret = lan78xx_phy_init(dev);
2529 | + if (ret < 0)
2530 | +- goto out4;
2531 | ++ goto out7;
2532 | +
2533 | + ret = register_netdev(netdev);
2534 | + if (ret != 0) {
2535 | + netif_err(dev, probe, netdev, "couldn't register the device\n");
2536 | +- goto out5;
2537 | ++ goto out8;
2538 | + }
2539 | +
2540 | + usb_set_intfdata(intf, dev);
2541 | +@@ -3834,12 +4412,19 @@ static int lan78xx_probe(struct usb_interface *intf,
2542 | +
2543 | + return 0;
2544 | +
2545 | +-out5:
2546 | ++out8:
2547 | + phy_disconnect(netdev->phydev);
2548 | +-out4:
2549 | ++out7:
2550 | + usb_free_urb(dev->urb_intr);
2551 | +-out3:
2552 | ++out6:
2553 | ++ kfree(buf);
2554 | ++out5:
2555 | + lan78xx_unbind(dev, intf);
2556 | ++out4:
2557 | ++ netif_napi_del(&dev->napi);
2558 | ++ lan78xx_free_rx_resources(dev);
2559 | ++out3:
2560 | ++ lan78xx_free_tx_resources(dev);
2561 | + out2:
2562 | + free_netdev(netdev);
2563 | + out1:
2564 | +@@ -3873,6 +4458,43 @@ static u16 lan78xx_wakeframe_crc16(const u8 *buf, int len)
2565 | + return crc;
2566 | + }
2567 | +
2568 | ++static int lan78xx_set_auto_suspend(struct lan78xx_net *dev)
2569 | ++{
2570 | ++ u32 buf;
2571 | ++ int ret;
2572 | ++
2573 | ++ lan78xx_stop_tx_path(dev);
2574 | ++ lan78xx_stop_rx_path(dev);
2575 | ++
2576 | ++ /* auto suspend (selective suspend) */
2577 | ++
2578 | ++ ret = lan78xx_write_reg(dev, WUCSR, 0);
2579 | ++ ret = lan78xx_write_reg(dev, WUCSR2, 0);
2580 | ++ ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL);
2581 | ++
2582 | ++ /* set goodframe wakeup */
2583 | ++
2584 | ++ ret = lan78xx_read_reg(dev, WUCSR, &buf);
2585 | ++ buf |= WUCSR_RFE_WAKE_EN_;
2586 | ++ buf |= WUCSR_STORE_WAKE_;
2587 | ++ ret = lan78xx_write_reg(dev, WUCSR, buf);
2588 | ++ ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
2589 | ++ buf &= ~PMT_CTL_RES_CLR_WKP_EN_;
2590 | ++ buf |= PMT_CTL_RES_CLR_WKP_STS_;
2591 | ++ buf |= PMT_CTL_PHY_WAKE_EN_;
2592 | ++ buf |= PMT_CTL_WOL_EN_;
2593 | ++ buf &= ~PMT_CTL_SUS_MODE_MASK_;
2594 | ++ buf |= PMT_CTL_SUS_MODE_3_;
2595 | ++ ret = lan78xx_write_reg(dev, PMT_CTL, buf);
2596 | ++ ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
2597 | ++ buf |= PMT_CTL_WUPS_MASK_;
2598 | ++ ret = lan78xx_write_reg(dev, PMT_CTL, buf);
2599 | ++
2600 | ++ lan78xx_start_rx_path(dev);
2601 | ++
2602 | ++ return 0;
2603 | ++}
2604 | ++
2605 | + static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol)
2606 | + {
2607 | + u32 buf;
2608 | +@@ -3885,12 +4507,8 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol)
2609 | + const u8 ipv6_multicast[3] = { 0x33, 0x33 };
2610 | + const u8 arp_type[2] = { 0x08, 0x06 };
2611 | +
2612 | +- ret = lan78xx_read_reg(dev, MAC_TX, &buf);
2613 | +- buf &= ~MAC_TX_TXEN_;
2614 | +- ret = lan78xx_write_reg(dev, MAC_TX, buf);
2615 | +- ret = lan78xx_read_reg(dev, MAC_RX, &buf);
2616 | +- buf &= ~MAC_RX_RXEN_;
2617 | +- ret = lan78xx_write_reg(dev, MAC_RX, buf);
2618 | ++ lan78xx_stop_tx_path(dev);
2619 | ++ lan78xx_stop_rx_path(dev);
2620 | +
2621 | + ret = lan78xx_write_reg(dev, WUCSR, 0);
2622 | + ret = lan78xx_write_reg(dev, WUCSR2, 0);
2623 | +@@ -4009,9 +4627,7 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol)
2624 | + buf |= PMT_CTL_WUPS_MASK_;
2625 | + ret = lan78xx_write_reg(dev, PMT_CTL, buf);
2626 | +
2627 | +- ret = lan78xx_read_reg(dev, MAC_RX, &buf);
2628 | +- buf |= MAC_RX_RXEN_;
2629 | +- ret = lan78xx_write_reg(dev, MAC_RX, buf);
2630 | ++ lan78xx_start_rx_path(dev);
2631 | +
2632 | + return 0;
2633 | + }
2634 | +@@ -4020,15 +4636,22 @@ static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message)
2635 | + {
2636 | + struct lan78xx_net *dev = usb_get_intfdata(intf);
2637 | + struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]);
2638 | +- u32 buf;
2639 | + int ret;
2640 | ++ bool dev_open;
2641 | ++
2642 | ++ mutex_lock(&dev->dev_mutex);
2643 | ++
2644 | ++ netif_dbg(dev, ifdown, dev->net,
2645 | ++ "suspending: pm event %#x", message.event);
2646 | +
2647 | +- if (!dev->suspend_count++) {
2648 | ++ dev_open = test_bit(EVENT_DEV_OPEN, &dev->flags);
2649 | ++
2650 | ++ if (dev_open) {
2651 | + spin_lock_irq(&dev->txq.lock);
2652 | + /* don't autosuspend while transmitting */
2653 | + if ((skb_queue_len(&dev->txq) ||
2654 | + skb_queue_len(&dev->txq_pend)) &&
2655 | +- PMSG_IS_AUTO(message)) {
2656 | ++ PMSG_IS_AUTO(message)) {
2657 | + spin_unlock_irq(&dev->txq.lock);
2658 | + ret = -EBUSY;
2659 | + goto out;
2660 | +@@ -4037,119 +4660,151 @@ static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message)
2661 | + spin_unlock_irq(&dev->txq.lock);
2662 | + }
2663 | +
2664 | +- /* stop TX & RX */
2665 | +- ret = lan78xx_read_reg(dev, MAC_TX, &buf);
2666 | +- buf &= ~MAC_TX_TXEN_;
2667 | +- ret = lan78xx_write_reg(dev, MAC_TX, buf);
2668 | +- ret = lan78xx_read_reg(dev, MAC_RX, &buf);
2669 | +- buf &= ~MAC_RX_RXEN_;
2670 | +- ret = lan78xx_write_reg(dev, MAC_RX, buf);
2671 | ++ /* stop RX */
2672 | ++ lan78xx_stop_rx_path(dev);
2673 | ++ lan78xx_flush_rx_fifo(dev);
2674 | ++
2675 | ++ /* stop Tx */
2676 | ++ lan78xx_stop_tx_path(dev);
2677 | +
2678 | +- /* empty out the rx and queues */
2679 | ++ /* empty out the Rx and Tx queues */
2680 | + netif_device_detach(dev->net);
2681 | + lan78xx_terminate_urbs(dev);
2682 | + usb_kill_urb(dev->urb_intr);
2683 | +
2684 | + /* reattach */
2685 | + netif_device_attach(dev->net);
2686 | +- }
2687 | +
2688 | +- if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) {
2689 | + del_timer(&dev->stat_monitor);
2690 | +
2691 | + if (PMSG_IS_AUTO(message)) {
2692 | +- /* auto suspend (selective suspend) */
2693 | +- ret = lan78xx_read_reg(dev, MAC_TX, &buf);
2694 | +- buf &= ~MAC_TX_TXEN_;
2695 | +- ret = lan78xx_write_reg(dev, MAC_TX, buf);
2696 | +- ret = lan78xx_read_reg(dev, MAC_RX, &buf);
2697 | +- buf &= ~MAC_RX_RXEN_;
2698 | +- ret = lan78xx_write_reg(dev, MAC_RX, buf);
2699 | +-
2700 | +- ret = lan78xx_write_reg(dev, WUCSR, 0);
2701 | +- ret = lan78xx_write_reg(dev, WUCSR2, 0);
2702 | +- ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL);
2703 | ++ lan78xx_set_auto_suspend(dev);
2704 | ++ } else {
2705 | ++ netif_carrier_off(dev->net);
2706 | ++ lan78xx_set_suspend(dev, pdata->wol);
2707 | ++ }
2708 | ++ } else {
2709 | ++ /* Interface is down; WOL and PHY events
2710 | ++ * will not wake up the host
2711 | ++ */
2712 | ++ u32 buf;
2713 | +
2714 | +- /* set goodframe wakeup */
2715 | +- ret = lan78xx_read_reg(dev, WUCSR, &buf);
2716 | ++ set_bit(EVENT_DEV_ASLEEP, &dev->flags);
2717 | +
2718 | +- buf |= WUCSR_RFE_WAKE_EN_;
2719 | +- buf |= WUCSR_STORE_WAKE_;
2720 | ++ ret = lan78xx_write_reg(dev, WUCSR, 0);
2721 | ++ ret = lan78xx_write_reg(dev, WUCSR2, 0);
2722 | +
2723 | +- ret = lan78xx_write_reg(dev, WUCSR, buf);
2724 | ++ ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
2725 | ++ buf &= ~PMT_CTL_RES_CLR_WKP_EN_;
2726 | ++ buf |= PMT_CTL_RES_CLR_WKP_STS_;
2727 | ++ buf &= ~PMT_CTL_SUS_MODE_MASK_;
2728 | ++ buf |= PMT_CTL_SUS_MODE_3_;
2729 | ++ ret = lan78xx_write_reg(dev, PMT_CTL, buf);
2730 | +
2731 | +- ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
2732 | ++ ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
2733 | ++ buf |= PMT_CTL_WUPS_MASK_;
2734 | ++ ret = lan78xx_write_reg(dev, PMT_CTL, buf);
2735 | ++ }
2736 | +
2737 | +- buf &= ~PMT_CTL_RES_CLR_WKP_EN_;
2738 | +- buf |= PMT_CTL_RES_CLR_WKP_STS_;
2739 | ++ ret = 0;
2740 | ++out:
2741 | ++ mutex_unlock(&dev->dev_mutex);
2742 | +
2743 | +- buf |= PMT_CTL_PHY_WAKE_EN_;
2744 | +- buf |= PMT_CTL_WOL_EN_;
2745 | +- buf &= ~PMT_CTL_SUS_MODE_MASK_;
2746 | +- buf |= PMT_CTL_SUS_MODE_3_;
2747 | ++ return ret;
2748 | ++}
2749 | +
2750 | +- ret = lan78xx_write_reg(dev, PMT_CTL, buf);
2751 | ++static bool lan78xx_submit_deferred_urbs(struct lan78xx_net *dev)
2752 | ++{
2753 | ++ struct urb *urb;
2754 | ++ bool pipe_halted = false;
2755 | +
2756 | +- ret = lan78xx_read_reg(dev, PMT_CTL, &buf);
2757 | ++ while ((urb = usb_get_from_anchor(&dev->deferred))) {
2758 | ++ struct sk_buff *skb = urb->context;
2759 | ++ int ret;
2760 | +
2761 | +- buf |= PMT_CTL_WUPS_MASK_;
2762 | ++ if (!netif_device_present(dev->net) ||
2763 | ++ !netif_carrier_ok(dev->net) ||
2764 | ++ pipe_halted) {
2765 | ++ lan78xx_free_tx_buf(dev, skb);
2766 | ++ continue;
2767 | ++ }
2768 | +
2769 | +- ret = lan78xx_write_reg(dev, PMT_CTL, buf);
2770 | ++ ret = usb_submit_urb(urb, GFP_ATOMIC);
2771 | +
2772 | +- ret = lan78xx_read_reg(dev, MAC_RX, &buf);
2773 | +- buf |= MAC_RX_RXEN_;
2774 | +- ret = lan78xx_write_reg(dev, MAC_RX, buf);
2775 | ++ if (ret == 0) {
2776 | ++ netif_trans_update(dev->net);
2777 | ++ lan78xx_queue_skb(&dev->txq, skb, tx_start);
2778 | + } else {
2779 | +- lan78xx_set_suspend(dev, pdata->wol);
2780 | ++ if (ret == -EPIPE) {
2781 | ++ netif_stop_queue(dev->net);
2782 | ++ pipe_halted = true;
2783 | ++ } else if (ret == -ENODEV) {
2784 | ++ netif_device_detach(dev->net);
2785 | ++ }
2786 | ++
2787 | ++ lan78xx_free_tx_buf(dev, skb);
2788 | + }
2789 | + }
2790 | +
2791 | +- ret = 0;
2792 | +-out:
2793 | +- return ret;
2794 | ++ return pipe_halted;
2795 | + }
2796 | +
2797 | + static int lan78xx_resume(struct usb_interface *intf)
2798 | + {
2799 | + struct lan78xx_net *dev = usb_get_intfdata(intf);
2800 | +- struct sk_buff *skb;
2801 | +- struct urb *res;
2802 | + int ret;
2803 | +- u32 buf;
2804 | ++ bool dev_open;
2805 | +
2806 | +- if (!timer_pending(&dev->stat_monitor)) {
2807 | +- dev->delta = 1;
2808 | +- mod_timer(&dev->stat_monitor,
2809 | +- jiffies + STAT_UPDATE_TIMER);
2810 | +- }
2811 | ++ mutex_lock(&dev->dev_mutex);
2812 | +
2813 | +- if (!--dev->suspend_count) {
2814 | +- /* resume interrupt URBs */
2815 | +- if (dev->urb_intr && test_bit(EVENT_DEV_OPEN, &dev->flags))
2816 | +- usb_submit_urb(dev->urb_intr, GFP_NOIO);
2817 | ++ netif_dbg(dev, ifup, dev->net, "resuming device");
2818 | +
2819 | +- spin_lock_irq(&dev->txq.lock);
2820 | +- while ((res = usb_get_from_anchor(&dev->deferred))) {
2821 | +- skb = (struct sk_buff *)res->context;
2822 | +- ret = usb_submit_urb(res, GFP_ATOMIC);
2823 | ++ dev_open = test_bit(EVENT_DEV_OPEN, &dev->flags);
2824 | ++
2825 | ++ if (dev_open) {
2826 | ++ bool pipe_halted = false;
2827 | ++
2828 | ++ lan78xx_flush_tx_fifo(dev);
2829 | ++
2830 | ++ if (dev->urb_intr) {
2831 | ++ ret = usb_submit_urb(dev->urb_intr, GFP_KERNEL);
2832 | + if (ret < 0) {
2833 | +- dev_kfree_skb_any(skb);
2834 | +- usb_free_urb(res);
2835 | +- usb_autopm_put_interface_async(dev->intf);
2836 | +- } else {
2837 | +- netif_trans_update(dev->net);
2838 | +- lan78xx_queue_skb(&dev->txq, skb, tx_start);
2839 | ++ if (ret == -ENODEV)
2840 | ++ netif_device_detach(dev->net);
2841 | ++
2842 | ++ netdev_warn(dev->net, "Failed to submit intr URB");
2843 | + }
2844 | + }
2845 | +
2846 | ++ spin_lock_irq(&dev->txq.lock);
2847 | ++
2848 | ++ if (netif_device_present(dev->net))
2849 | ++ pipe_halted = lan78xx_submit_deferred_urbs(dev);
2850 | ++
2851 | ++ if (pipe_halted)
2852 | ++ lan78xx_defer_kevent(dev, EVENT_TX_HALT);
2853 | ++
2854 | + clear_bit(EVENT_DEV_ASLEEP, &dev->flags);
2855 | ++
2856 | + spin_unlock_irq(&dev->txq.lock);
2857 | +
2858 | +- if (test_bit(EVENT_DEV_OPEN, &dev->flags)) {
2859 | +- if (!(skb_queue_len(&dev->txq) >= dev->tx_qlen))
2860 | +- netif_start_queue(dev->net);
2861 | +- tasklet_schedule(&dev->bh);
2862 | ++ if (!pipe_halted &&
2863 | ++ netif_device_present(dev->net) &&
2864 | ++ (lan78xx_tx_pend_data_len(dev) < LAN78XX_TX_URB_SPACE(dev)))
2865 | ++ netif_start_queue(dev->net);
2866 | ++
2867 | ++ lan78xx_start_tx_path(dev);
2868 | ++
2869 | ++ napi_schedule(&dev->napi);
2870 | ++
2871 | ++ if (!timer_pending(&dev->stat_monitor)) {
2872 | ++ dev->delta = 1;
2873 | ++ mod_timer(&dev->stat_monitor,
2874 | ++ jiffies + STAT_UPDATE_TIMER);
2875 | + }
2876 | ++
2877 | ++ } else {
2878 | ++ clear_bit(EVENT_DEV_ASLEEP, &dev->flags);
2879 | + }
2880 | +
2881 | + ret = lan78xx_write_reg(dev, WUCSR2, 0);
2882 | +@@ -4169,9 +4824,7 @@ static int lan78xx_resume(struct usb_interface *intf)
2883 | + WUCSR_MPR_ |
2884 | + WUCSR_BCST_FR_);
2885 | +
2886 | +- ret = lan78xx_read_reg(dev, MAC_TX, &buf);
2887 | +- buf |= MAC_TX_TXEN_;
2888 | +- ret = lan78xx_write_reg(dev, MAC_TX, buf);
2889 | ++ mutex_unlock(&dev->dev_mutex);
2890 | +
2891 | + return 0;
2892 | + }
2893 | +@@ -4180,6 +4833,8 @@ static int lan78xx_reset_resume(struct usb_interface *intf)
2894 | + {
2895 | + struct lan78xx_net *dev = usb_get_intfdata(intf);
2896 | +
2897 | ++ netif_dbg(dev, ifup, dev->net, "(reset) resuming device");
2898 | ++
2899 | + lan78xx_reset(dev);
2900 | +
2901 | + phy_start(dev->net->phydev);
2902 | +@@ -4200,10 +4855,6 @@ static const struct usb_device_id products[] = {
2903 | + /* LAN7801 USB Gigabit Ethernet Device */
2904 | + USB_DEVICE(LAN78XX_USB_VENDOR_ID, LAN7801_USB_PRODUCT_ID),
2905 | + },
2906 | +- {
2907 | +- /* ATM2-AF USB Gigabit Ethernet Device */
2908 | +- USB_DEVICE(AT29M2AF_USB_VENDOR_ID, AT29M2AF_USB_PRODUCT_ID),
2909 | +- },
2910 | + {},
2911 | + };
2912 | + MODULE_DEVICE_TABLE(usb, products);
2913 | --
2914 | 2.25.1
2915 |
2916 |
--------------------------------------------------------------------------------
/openwrt/scripts/readme.md:
--------------------------------------------------------------------------------
1 | scripts for seeed-linux-openwrt
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # *EOL warning, this software is already EOL, please use the latest OpenWRT according to the wiki.*
2 | ***https://wiki.seeedstudio.com/OpenWrt-Getting-Started/#run-r235-openwrt***
3 |
4 | # Welcome to Seeed's Openwrt.
5 |
6 | Seeed Openwrt is a great way to add some great Luci applications to the latest version of Openwrt. Our goal is to provide a stable, flexible and easy to use Openwrt system for CM4 and x86 based hardware devices. Seeed's Openwrt system provides not only basic routing functions, but also platform software for HomeLab, AIoT, allowing users to quickly implement different scenarios.
7 |
8 | 
9 | ## Getting Started
10 |
11 | - [Seeed OpenWrt Getting Started](https://wiki.seeedstudio.com/OpenWrt-Getting-Started/)
12 |
13 | ## Daily Image
14 | We compile the latest images every workday.
15 | ```
16 | https://1drv.ms/u/s!AqG2uRmVUhlSh0NHMLMmQKLyASvi?e=mup3cd
17 | ```
18 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | git-filter-repo
--------------------------------------------------------------------------------
/scripts/build.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | import json
4 | import argparse
5 | import stat
6 | import shutil
7 | from multiprocessing import cpu_count
8 |
9 |
10 | ACTION = ['create', 'feeds', 'config', 'download', 'compile',
11 | 'install', 'all', 'clean', 'distclean', 'export']
12 |
13 |
14 | def readonly_handler(func, path, execinfo):
15 | os.chmod(path, stat.S_IWRITE)
16 | func(path)
17 |
18 |
19 | work_dir = os.path.abspath('.')
20 | build_dir = os.path.join(work_dir, 'build')
21 | openwrt_dir = os.path.join(build_dir, 'openwrt')
22 | dl_dir = None
23 | config = None
24 |
25 |
26 | def parse_args():
27 | parser = argparse.ArgumentParser()
28 | parser.add_argument('--build-dir', type=str, default='build')
29 | parser.add_argument('--dl-dir', type=str, default=None)
30 | parser.add_argument('--config', type=str, default='config.json')
31 | parser.add_argument('--action', type=str, default='', choices=ACTION)
32 | return parser.parse_args()
33 |
34 |
35 | def do_create():
36 | print("Create openwrt project...")
37 |
38 | if not os.path.exists(build_dir):
39 | os.mkdir(build_dir)
40 |
41 | print("Download openwrt source code...")
42 |
43 | if os.path.exists(openwrt_dir):
44 | os.chdir(openwrt_dir)
45 | print("Openwrt source code already exists, try to update...")
46 | os.system('git clean -fd')
47 | os.system('git reset --hard')
48 | os.system('git pull')
49 | else:
50 | ret = os.system('git clone https://github.com/openwrt/openwrt -b %s %s --depth 1' %
51 | (config['version'], openwrt_dir))
52 | if ret != 0:
53 | raise Exception('Download openwrt failed.')
54 |
55 | os.chdir(openwrt_dir)
56 |
57 | # copy config file
58 | print("Copy config file to openwrt's source code...")
59 | config_file = os.path.join(
60 | work_dir, 'openwrt', 'configs', config['config'])
61 | if not os.path.exists(config_file):
62 | print("Config file %s not found." % config_file)
63 | sys.exit(1)
64 | ret = os.system('cp -rf %s .config' %
65 | os.path.join(work_dir, 'openwrt', 'configs', config['config']))
66 | if ret != 0:
67 | raise Exception('Copy config file failed.')
68 |
69 | # copy root file
70 | print("Copy root file to openwrt's source code...")
71 | if config['files'] != '':
72 | if os.path.exists('files'):
73 | os.system('rm -rf files')
74 |
75 | os.system('mkdir -p files')
76 | for file in config['files']:
77 | print('cp -r %s %s' % (os.path.join(work_dir, 'openwrt', 'files', config['target'], config['subtarget'], file),
78 | os.path.join(openwrt_dir, 'files')))
79 | ret = os.system('cp -rv %s/* %s' % (os.path.join(work_dir, 'openwrt', 'files', config['target'], config['subtarget'], file),
80 | os.path.join(openwrt_dir, 'files')))
81 | if ret != 0:
82 | raise Exception("Copy root file failed")
83 | else:
84 | print("No root file to copy.")
85 |
86 | # append feeds
87 | print("Append feeds to openwrt's source code...")
88 | if config['feeds'] != '':
89 | feeds = config['feeds']
90 | for feed in feeds:
91 | with open('feeds.conf.default', 'r') as f:
92 | if feed in f.read():
93 | continue
94 | ret = os.system('echo "%s" >> feeds.conf.default' % feed)
95 | if ret != 0:
96 | raise Exception("Append feeds falied")
97 | else:
98 | print("No feeds to append.")
99 |
100 | # ln dl dir
101 | if dl_dir is not None:
102 | print("Link dl dir to openwrt's source code...")
103 | if os.path.exists('dl'):
104 | os.system('rm -rf dl')
105 | os.system('ln -sn %s dl' % dl_dir)
106 |
107 | # apply patches
108 | if config['patches'] != '':
109 | print("Apply patches to openwrt's source code...")
110 | for patch in config['patches']:
111 | ret = os.system('git apply %s' %
112 | os.path.join(work_dir, 'openwrt', 'patches', patch))
113 | if ret != 0:
114 | raise Exception("Apply patches failed.")
115 |
116 | print("Setup openwrt project done.")
117 |
118 |
119 | def do_action_hook(action):
120 | cur_dir = os.getcwd()
121 | os.chdir(openwrt_dir)
122 | if action != '':
123 | if config['action'][action] and config['action'][action] != '':
124 | ret = os.system(config['action'][action])
125 | if ret != 0:
126 | raise Exception("Action %s failed." % action)
127 | os.chdir(cur_dir)
128 |
129 |
130 | def do_feeds():
131 | os.chdir(openwrt_dir)
132 | print("Update feeds...")
133 | do_action_hook('prefeeds')
134 | ret = os.system('./scripts/feeds update -a')
135 | if ret != 0:
136 | raise Exception("Feeds failed.")
137 | ret = os.system('./scripts/feeds install -a')
138 | if ret != 0:
139 | raise Exception("Feeds failed.")
140 | do_action_hook('postfeeds')
141 |
142 |
143 | def do_config():
144 | os.chdir(openwrt_dir)
145 | do_action_hook('preconfig')
146 | ret = os.system('cp -rf %s .config' %
147 | os.path.join(work_dir, 'openwrt', 'configs', config['config']))
148 | if ret != 0:
149 | raise Exception('Copy config file failed.')
150 | ret = os.system('make defconfig')
151 | if ret != 0:
152 | raise Exception("Config failed.")
153 | do_action_hook('postconfig')
154 |
155 |
156 | def do_download():
157 | os.chdir(openwrt_dir)
158 | do_action_hook('predownload')
159 | ret = os.system('make download -j%d' % cpu_count())
160 | if ret != 0:
161 | # try aggin with verbose
162 | ret = os.system('make download -j1 V=s' % cpu_count())
163 | if ret != 0:
164 | raise Exception("Download failed.")
165 | do_action_hook('postdownload')
166 |
167 |
168 | def do_compile():
169 | print("Do compile...")
170 | os.chdir(openwrt_dir)
171 | do_action_hook('precompile')
172 | ret = os.system(
173 | 'make tools/compile -j%d || make tools/compile V=s -j1' % cpu_count())
174 | if ret != 0:
175 | raise Exception("Compile tools failed.")
176 | ret = os.system(
177 | 'make toolchain/compile -j%d || make toolchain/compile V=s -j1' % cpu_count())
178 | if ret != 0:
179 | raise Exception("Compile toolchain failed.")
180 | ret = os.system(
181 | 'make target/compile -j%d || make target/compile V=s -j1' % cpu_count())
182 | if ret != 0:
183 | raise Exception("Compile target failed.")
184 | ret = os.system(
185 | 'make package/compile -j%d || make package/compile V=s -j1' % cpu_count())
186 | if ret != 0:
187 | raise Exception("Compile package failed.")
188 | do_action_hook('postcompile')
189 |
190 |
191 | def do_install():
192 | print("Do install...")
193 | os.chdir(openwrt_dir)
194 | do_action_hook('preinstall')
195 | ret = os.system('make package/install')
196 | if ret != 0:
197 | raise Exception("Install package failed.")
198 | ret = os.system('make target/install')
199 | if ret != 0:
200 | raise Exception("Install target failed.")
201 | do_action_hook('postinstall')
202 |
203 |
204 | def do_export():
205 | print("Do Export...")
206 | os.system("mkdir -p %s" % os.path.join(work_dir, 'bin',
207 | config['version'], 'targets', config['target'], config['subtarget'], config['name'].split('_')[-1]))
208 | os.system('cp -rf %s %s' % (os.path.join(openwrt_dir, 'bin', 'targets', config['target'], config['subtarget']), os.path.join(
209 | work_dir, 'bin', config['version'], 'targets', config['target'], config['subtarget'], config['name'].split('_')[-1])))
210 |
211 |
212 | def do_clean():
213 | print("Do clean...")
214 | do_action_hook('preclean')
215 | ret = os.system('make clean')
216 | if ret != 0:
217 | raise Exception("Clean failed.")
218 | do_action_hook('postclean')
219 |
220 |
221 | def do_upload():
222 | print("Do upload...")
223 | do_action_hook('preupload')
224 | print(os.getenv(''))
225 | do_action_hook('postupload')
226 |
227 |
228 | if __name__ == '__main__':
229 |
230 | args = parse_args()
231 |
232 | if not os.path.isabs(args.build_dir):
233 | build_dir = os.path.join(work_dir, args.build_dir)
234 | else:
235 | build_dir = args.build_dir
236 |
237 | if args.dl_dir is not None:
238 | if not os.path.isabs(args.dl_dir):
239 | dl_dir = os.path.join(work_dir, args.dl_dir)
240 | else:
241 | dl_dir = args.dl_dir
242 |
243 | if args.action == 'distclean':
244 | if os.path.exists(build_dir):
245 | shutil.rmtree(build_dir, onerror=readonly_handler)
246 | sys.exit(0)
247 |
248 | if not os.path.isabs(args.config):
249 | args.config = os.path.join(work_dir, args.config)
250 |
251 | if not os.path.exists(args.config):
252 | print("Config file %s not found." % args.config)
253 | sys.exit(1)
254 |
255 | config = json.load(open(args.config, 'r'))
256 |
257 | print("Build openwrt %s" % config['version'])
258 |
259 | config_dump = json.dumps(config, indent=4)
260 | print("config: ", config_dump)
261 |
262 | openwrt_dir = os.path.join(build_dir, config['version'])
263 |
264 | try:
265 | if args.action == 'create':
266 | do_create()
267 | elif args.action == 'clean':
268 | do_clean()
269 | elif args.action == 'feeds':
270 | do_feeds()
271 | elif args.action == 'config':
272 | do_config()
273 | elif args.action == 'download':
274 | do_download()
275 | elif args.action == 'compile':
276 | do_compile()
277 | elif args.action == 'install':
278 | do_install()
279 | elif args.action == 'export':
280 | do_export()
281 | else:
282 | do_create()
283 | do_feeds()
284 | do_config()
285 | do_download()
286 | do_compile()
287 | do_install()
288 | do_export()
289 |
290 | except Exception as e:
291 | print(e)
292 | sys.exit(1)
293 |
--------------------------------------------------------------------------------
/scripts/fetch_packages.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import os
4 | import sys
5 | import stat
6 | import tempfile
7 | import argparse
8 | import shutil
9 | import json
10 |
11 | def readonly_handler(func, path, execinfo):
12 | os.chmod(path, stat.S_IWRITE)
13 | func(path)
14 |
15 |
16 | tmp_path = ""
17 | packages_path = ""
18 | json_path = ""
19 |
20 | def parse_args():
21 |
22 | parser = argparse.ArgumentParser(description='Fetch packages')
23 | parser.add_argument('--out_dir', type=str, default='/tmp/packages',
24 | help='packages output path')
25 | parser.add_argument('--list', type=str,
26 | default='packages.list', help='packages list file')
27 |
28 | return parser.parse_args()
29 |
30 |
31 | def work_path(path):
32 | return "{}/{}".format(tmp_path, path)
33 |
34 |
35 | def fetch():
36 |
37 | global tmp_path, packages_path, json_path
38 |
39 | tmp_path = tempfile.mkdtemp()
40 |
41 | with open(json_path, 'r') as load_f:
42 | json_dict = json.load(load_f)
43 | repo_url = json_dict['repo']
44 | repo_branch = json_dict['branch']
45 |
46 | if os.path.exists("{}".format(work_path(repo_branch))):
47 | shutil.rmtree("{}".format(work_path(repo_branch)),
48 | onerror=readonly_handler)
49 |
50 | print(work_path(repo_branch))
51 | os.mkdir(work_path(repo_branch))
52 | os.chdir(work_path(repo_branch))
53 | os.system("git init")
54 | os.system("git checkout -b {}".format(repo_branch))
55 | os.system("touch README.md")
56 | os.system("echo \"# Welcom to Seeed's Openwrt Packages\" > README.md")
57 | os.system("git add README.md")
58 | os.system("git commit -m 'An init commit'")
59 |
60 | for package in json_dict['packages']:
61 | name = package['name']
62 | author = package['author']
63 | path = "{}/{}".format(author, name)
64 | package_origin = "origin-{}-{}".format(author, name)
65 | package_branch = "branch-{}-{}".format(author, name)
66 | url = package['url']
67 | branch = package['branch']
68 |
69 | try:
70 | if os.path.exists("{}".format(work_path(path))):
71 | shutil.rmtree("{}".format(work_path(path)),
72 | onerror=readonly_handler)
73 |
74 | os.system(
75 | "git clone {} {} -b {} --single-branch".format(url, work_path(path), branch))
76 |
77 | except:
78 | raise
79 |
80 | filter_path = ""
81 |
82 | for item in package['items']:
83 | if (item == "*"):
84 | filter_path = "*"
85 | break
86 | if os.path.exists("{}".format(work_path("{}/{}".format(path, item)))):
87 | filter_path += " --path {}".format(item)
88 |
89 | if (filter_path == "*"):
90 |
91 | os.chdir("{}".format(work_path(format(repo_branch))))
92 | os.system(
93 | "git remote add -f {} {}".format(package_origin, work_path(path)))
94 | os.system(
95 | "git checkout remotes/{}/{} -b {}".format(package_origin, branch, package_branch))
96 | os.system("git checkout {}".format(repo_branch))
97 | os.system(
98 | "git subtree add --prefix={}/{} {}".format(author, name, package_branch))
99 |
100 | elif (filter_path != ""):
101 | os.chdir("{}".format(work_path(path)))
102 | os.system("git-filter-repo {} --force".format(filter_path))
103 | os.chdir("{}".format(work_path(repo_branch)))
104 | os.system(
105 | "git remote add -f {} {}".format(package_origin, work_path(path)))
106 | os.system("git merge {}/{} --allow-unrelated-histories --commit -m \"merge: {}'s {}\"".format(
107 | package_origin, branch, author, name))
108 |
109 | os.chdir("{}".format(work_path(format(repo_branch))))
110 | if not os.path.exists(author):
111 | os.mkdir(author)
112 | for item in package['items']:
113 | if os.path.exists("{}".format(work_path("{}/{}".format(repo_branch, item)))):
114 | print("git mv {} {}/".format(item, author))
115 | try:
116 | os.system("git mv {} {}/".format(item, author))
117 | except Exception as e:
118 | print(e)
119 |
120 | os.system("git add --all")
121 | os.system(
122 | "git commit -m \"{}'s {}: tidy up\"".format(author, name))
123 |
124 | if os.path.exists("{}".format(packages_path)):
125 | shutil.rmtree("{}".format(packages_path), onerror=readonly_handler)
126 |
127 | os.system("git clone {} {}".format(
128 | work_path(repo_branch), packages_path))
129 | os.chdir(packages_path)
130 |
131 | for home, dirs, files in os.walk(packages_path):
132 | for file in files:
133 | if file == 'Makefile':
134 | with open(os.path.join(home, file), 'r+') as f:
135 | read_data = f.read()
136 | f.seek(0)
137 | f.truncate()
138 | write_data = read_data.replace(
139 | "../../luci.mk", "$(TOPDIR)/feeds/luci/luci.mk")
140 | write_data = write_data.replace(
141 | "../../lang", "$(TOPDIR)/feeds/packages/lang")
142 | f.write(write_data)
143 |
144 | os.system("git add --all")
145 | os.system("git commit -m \"tidy up\"")
146 |
147 | os.system("git remote set-url origin {}".format(repo_url))
148 |
149 | shutil.rmtree("{}".format(tmp_path), onerror=readonly_handler)
150 |
151 |
152 | if __name__ == '__main__':
153 | args = parse_args()
154 | packages_path = args.out_dir
155 | json_path = args.list
156 | try:
157 | fetch()
158 | except Exception as e:
159 | print(e)
160 | if os.path.exists(tmp_path):
161 | shutil.rmtree(tmp_path, onerror=readonly_handler)
162 | sys.exit(1)
163 |
--------------------------------------------------------------------------------