├── .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 | ![](https://raw.githubusercontent.com/stuarthua/PicGo/master/oh-my-openwrt/Snipaste_2019-09-14_23-31-35.png) 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 | + '' 185 | + '' 186 | + '' 187 | + '' 188 | + '' 189 | + '' 191 | + ''; 192 | } 193 | } 194 | } 195 | listHtml += "
..
' 183 | + '' + o.displayname + '' 184 | + ''+o.owner+''+o.date+''+o.size+''+o.perms+'\ 190 |
"; 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 |
6 | 7 |
8 |
Files List
9 | 10 |
11 |
12 | 13 | 14 |
15 |
16 |
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 | ![](https://files.seeedstudio.com/products/110110110/Openwrt-services.png) 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 | --------------------------------------------------------------------------------