Compare commits

..

1 Commits

Author SHA1 Message Date
jaspreetsachdev
9ea3e4ce9b Merge pull request #480 from Telecominfraproject/main
Various updates
2022-09-26 16:12:15 -04:00
120 changed files with 946 additions and 7014 deletions

View File

@@ -15,7 +15,7 @@ runs:
id: import_snapshot id: import_snapshot
shell: bash shell: bash
run: | run: |
echo "import_task_id=$(aws ec2 import-snapshot --description '${{ inputs.firmware_image_name }}' --disk-container 'Format=raw,UserBucket={S3Bucket=${{ inputs.firmware_image_s3_bucket }},S3Key=${{ inputs.firmware_image_name }}}' | jq -r '.ImportTaskId')" >> $GITHUB_OUTPUT echo ::set-output name=import_task_id::$(aws ec2 import-snapshot --description '${{ inputs.firmware_image_name }}' --disk-container 'Format=raw,UserBucket={S3Bucket=${{ inputs.firmware_image_s3_bucket }},S3Key=${{ inputs.firmware_image_name }}}' | jq -r '.ImportTaskId')
- name: Wait for import task to complete and get snapshot ID - name: Wait for import task to complete and get snapshot ID
id: get_snapshot_id id: get_snapshot_id
@@ -26,7 +26,7 @@ runs:
IMPORT_TASK_STATUS=$(aws ec2 describe-import-snapshot-tasks --import-task-ids ${{ steps.import_snapshot.outputs.import_task_id }} | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.Status') IMPORT_TASK_STATUS=$(aws ec2 describe-import-snapshot-tasks --import-task-ids ${{ steps.import_snapshot.outputs.import_task_id }} | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.Status')
echo "Import task status is $IMPORT_TASK_STATUS, waiting for completion." echo "Import task status is $IMPORT_TASK_STATUS, waiting for completion."
done done
echo "id=$(aws ec2 describe-import-snapshot-tasks --import-task-ids ${{ steps.import_snapshot.outputs.import_task_id }} | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.SnapshotId')" >> $GITHUB_OUTPUT echo ::set-output name=id::$(aws ec2 describe-import-snapshot-tasks --import-task-ids ${{ steps.import_snapshot.outputs.import_task_id }} | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.SnapshotId')
- name: Tag snapshot with image name - name: Tag snapshot with image name
shell: bash shell: bash

View File

@@ -21,10 +21,10 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
target: ['actiontec_web7200', 'cig_wf188n', 'cig_wf194c4', 'cig_wf196', 'cig_wf610d', 'cig_wf808', 'cybertan_eww622-a1', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_eap104', 'liteon_wpx8324', 'edgecore_ecs4100-12ph', 'edgecore_ecw5211', 'edgecore_ecw5410', 'edgecore_oap100', 'edgecore_ssw2ac2600', 'edgecore_spw2ac1200', 'edgecore_spw2ac1200-lan-poe', 'hfcl_ion4', 'hfcl_ion4xe', 'hfcl_ion4xi', 'hfcl_ion4x', 'hfcl_ion4x_2', 'indio_um-305ac', 'indio_um-305ax', 'indio_um-325ac', 'indio_um-510ac-v3', 'indio_um-550ac', 'indio_um-310ax-v1', 'indio_um-510axp-v1', 'indio_um-510axm-v1', 'linksys_ea6350-v4', 'linksys_e8450-ubi', 'linksys_ea8300', 'meshpp_s618_cp03', 'meshpp_s618_cp01', 'udaya_a5-id2', 'wallys_dr40x9', 'wallys_dr6018', 'wallys_dr6018_v4', 'x64_vm', 'yuncore_ax840', 'yuncore_fap640', 'yuncore_fap650' ] target: ['actiontec_web7200', 'cig_wf188n', 'cig_wf196', 'cig_wf610d', 'cig_wf808', 'cybertan_eww622-a1', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_eap104', 'edgecore_ecs4100-12ph', 'edgecore_ecw5211', 'edgecore_ecw5410', 'edgecore_oap100', 'edgecore_ssw2ac2600', 'edgecore_spw2ac1200', 'edgecore_spw2ac1200-lan-poe', 'hfcl_ion4', 'hfcl_ion4xe', 'hfcl_ion4xi', 'indio_um-305ac', 'indio_um-305ax', 'indio_um-325ac', 'indio_um-510ac-v3', 'indio_um-550ac', 'linksys_ea6350-v4', 'linksys_e8450-ubi', 'linksys_ea8300', 'meshpp_s618_cp03', 'meshpp_s618_cp01', 'udaya_a5-id2', 'wallys_dr40x9', 'wallys_dr6018', 'x64_vm' ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Build image for ${{ matrix.target }} - name: Build image for ${{ matrix.target }}
id: build id: build
@@ -72,7 +72,7 @@ jobs:
[ -f openwrt/tmp/image-file ] && aws s3api put-object-tagging --bucket "$AWS_S3_BUCKET_NAME" --key "$JSON_NAME" --tagging "{\"TagSet\":[{\"Key\":\"release\",\"Value\":\"$IS_RELEASE\"}]}" [ -f openwrt/tmp/image-file ] && aws s3api put-object-tagging --bucket "$AWS_S3_BUCKET_NAME" --key "$JSON_NAME" --tagging "{\"TagSet\":[{\"Key\":\"release\",\"Value\":\"$IS_RELEASE\"}]}"
if [ ${{ matrix.target }} == 'x64_vm' ]; then if [ ${{ matrix.target }} == 'x64_vm' ]; then
echo "x64_vm_image_name=$(echo $IMG_NAME)" >> $GITHUB_OUTPUT echo ::set-output name=x64_vm_image_name::"$(echo $IMG_NAME)"
fi fi
trigger-testing: trigger-testing:
@@ -93,7 +93,7 @@ jobs:
needs: build needs: build
if: startsWith(github.ref, 'refs/tags/v') if: startsWith(github.ref, 'refs/tags/v')
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Use create-ami-from-image composite action - name: Use create-ami-from-image composite action
uses: ./.github/actions/create-ami-from-image uses: ./.github/actions/create-ami-from-image

View File

@@ -22,7 +22,7 @@ jobs:
target: ['x64_vm'] target: ['x64_vm']
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Build image for ${{ matrix.target }} - name: Build image for ${{ matrix.target }}
id: build id: build
@@ -70,14 +70,14 @@ jobs:
[ -f openwrt/tmp/image-file ] && aws s3api put-object-tagging --bucket "$AWS_S3_BUCKET_NAME" --key "$JSON_NAME" --tagging "{\"TagSet\":[{\"Key\":\"release\",\"Value\":\"$IS_RELEASE\"}]}" [ -f openwrt/tmp/image-file ] && aws s3api put-object-tagging --bucket "$AWS_S3_BUCKET_NAME" --key "$JSON_NAME" --tagging "{\"TagSet\":[{\"Key\":\"release\",\"Value\":\"$IS_RELEASE\"}]}"
if [[ ${{ matrix.target }} == 'x64_vm' ]]; then if [[ ${{ matrix.target }} == 'x64_vm' ]]; then
echo "x64_vm_image_name=$(echo $IMG_NAME)" >> $GITHUB_OUTPUT echo ::set-output name=x64_vm_image_name::"$(echo $IMG_NAME)"
fi fi
create-x64_vm-ami: create-x64_vm-ami:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
with: with:
ref: WIFI-7206-add-workflow-to-build-virtual-ap-image ref: WIFI-7206-add-workflow-to-build-virtual-ap-image

View File

@@ -1,83 +1,20 @@
# OpenWiFi AP NOS # Setting up your build machine
OpenWrt-based access point network operating system (AP NOS) for TIP OpenWiFi. Requires a recent linux installation. Older systems without python 3.7 will have trouble. See this link for details: https://openwrt.org/docs/guide-developer/quickstart-build-images
Read more at [openwifi.tip.build](https://openwifi.tip.build/).
## Building Install build packages: sudo apt install build-essential libncurses5-dev gawk git libssl-dev gettext zlib1g-dev swig unzip time rsync python3 python3-setuptools python3-yaml.
### Setting up your build machine # Doing a native build on Linux
First we need to clone and setup our tree. This will result in an openwrt/.
Building requires a recent Linux installation. Older systems without Python 3.7
will have trouble. See this guide for details:
https://openwrt.org/docs/guide-developer/toolchain/beginners-build-guide
Install build packages on Debian/Ubuntu (or see above guide for other systems):
``` ```
sudo apt install build-essential libncurses5-dev gawk git libssl-dev gettext zlib1g-dev swig unzip time rsync python3 python3-setuptools python3-yaml ./setup.py --setup
``` ```
Next we need to select the profile and base package selection. This setup will install the feeds, packages and generate the .config file.
### Doing a native build on Linux
Use `./build.sh <target>`, or follow the manual steps below:
1. Clone and set up the tree. This will create an `openwrt/` directory.
```shell
./setup.py --setup # for subsequent builds, use --rebase instead
``` ```
2. Select the profile and base package selection. This setup will install the
feeds and packages and generate the `.config` file.
```shell
cd openwrt cd openwrt
./scripts/gen_config.py linksys_ea8300 ./scripts/gen_config.py linksys_ea8300
``` ```
Finally we can build the tree.
3. Build the tree (replace `-j 8` with the number of cores to use). ```
```shell make -j X V=s
make -j 8 V=s
``` ```
### Build output
The build results are located in the `openwrt/bin/` directory:
| Type | Path |
| ---------------- | ---------------------------------------------------- |
| Firmware images | `openwrt/bin/targets/<target>/<subtarget>/` |
| Kernel modules | `openwrt/bin/targets/<target>/<subtarget>/packages/` |
| Package binaries | `openwrt/bin/packages/<platform>/<feed>/` |
## Developer Notes
### Branching model
- `main` - Stable dev branch
- `next` - Integration branch
- `staging-*` - Feature/bug branches
- `release/v#.#.#` - Release branches (*major.minor.patch*)
### Repository structure
Build files:
- `Makefile` - Calls Docker environment per target
- `dock-run.sh` - Dockerized build environment
- `docker/Dockerfile` - Dockerfile for build image
- `build.sh` - Build script
- `setup.py` - Clone and set up the tree
- `config.yml` - Specifies OpenWrt version and patches to apply
Directories:
- `feeds/` - OpenWiFi feeds
- `patches/` - OpenWiFi patches applied during builds
- `profiles/` - Per-target kernel configs, packages, and feeds
- [wifi-ax](profiles/wifi-ax.yml): Wi-Fi AX packages
- [ucentral-ap](profiles/ucentral-ap.yml): uCentral packages
- [x64_vm](profiles/x64_vm.yml): x86-64 VM image
### uCentral packages
AP-NOS packages implementing the uCentral protocol include the following
repositories (refer to the [ucentral](feeds/ucentral/) feed for a full list):
- ucentral-client: https://github.com/Telecominfraproject/wlan-ucentral-client
- ucentral-schema: https://github.com/Telecominfraproject/wlan-ucentral-schema
- ucentral-wifi: https://github.com/blogic/ucentral-wifi

View File

@@ -34,14 +34,7 @@ edgecore,eap104)
ucidef_set_led_wlan "wlan5g" "WLAN5G" "green:wifi5" "phy1tpt" ucidef_set_led_wlan "wlan5g" "WLAN5G" "green:wifi5" "phy1tpt"
ucidef_set_led_netdev "wan" "wan" "yellow:uplink" "eth0" ucidef_set_led_netdev "wan" "wan" "yellow:uplink" "eth0"
;; ;;
liteon,wpx8324)
ucidef_set_led_wlan "wlan2g" "WLAN2G" "orange:wifi2" "phy0tpt"
ucidef_set_led_wlan "wlan5g" "WLAN5G" "green:wifi5" "phy1tpt"
ucidef_set_led_netdev "wan" "wan" "blue:uplink" "eth0"
;;
hfcl,ion4xi|\ hfcl,ion4xi|\
hfcl,ion4x|\
hfcl,ion4x_2|\
hfcl,ion4xe) hfcl,ion4xe)
ucidef_set_led_wlan "wlan5g" "WLAN5G" "blue:wifi5" "phy0tpt" ucidef_set_led_wlan "wlan5g" "WLAN5G" "blue:wifi5" "phy0tpt"
ucidef_set_led_wlan "wlan2g" "WLAN2G" "blue:wifi2" "phy1tpt" ucidef_set_led_wlan "wlan2g" "WLAN2G" "blue:wifi2" "phy1tpt"
@@ -50,11 +43,6 @@ glinet,ax1800|\
glinet,axt1800) glinet,axt1800)
ucidef_set_led_netdev "wan" "WAN" "blue:wan" "eth0" "tx rx link" ucidef_set_led_netdev "wan" "WAN" "blue:wan" "eth0" "tx rx link"
;; ;;
yuncore,fap650|\
muxi,ap3220l)
ucidef_set_led_wlan "wlan2g" "WLAN2G" "green:wifi2" "phy0tpt"
ucidef_set_led_wlan "wlan5g" "WLAN5G" "green:wifi5" "phy1tpt"
;;
esac esac
board_config_flush board_config_flush

View File

@@ -13,8 +13,6 @@ qcom_setup_interfaces()
case $board in case $board in
hfcl,ion4xi|\ hfcl,ion4xi|\
hfcl,ion4x|\
hfcl,ion4x_2|\
hfcl,ion4xe) hfcl,ion4xe)
ucidef_set_interface_wan "eth0 eth1" ucidef_set_interface_wan "eth0 eth1"
ucidef_set_interface_lan "" ucidef_set_interface_lan ""
@@ -51,18 +49,13 @@ qcom_setup_interfaces()
ucidef_set_interface_wan "eth0" ucidef_set_interface_wan "eth0"
;; ;;
edgecore,eap102|\ edgecore,eap102|\
liteon,wpx8324|\ edgecore,eap104|\
wallys,dr6018|\ wallys,dr6018|\
cig,wf188n|\ cig,wf188n|\
cig,wf196|\ cig,wf196)
muxi,ap3220l)
ucidef_set_interface_lan "eth1" ucidef_set_interface_lan "eth1"
ucidef_set_interface_wan "eth0" ucidef_set_interface_wan "eth0"
;; ;;
yuncore,fap650)
ucidef_set_interface_lan "eth3 eth2 eth1 eth0"
ucidef_set_interface_wan "eth4"
;;
qcom,ipq807x-hk14) qcom,ipq807x-hk14)
ucidef_set_interface_lan "eth0 eth1 eth2 eth3" ucidef_set_interface_lan "eth0 eth1 eth2 eth3"
ucidef_set_interface_wan "eth4" ucidef_set_interface_wan "eth4"
@@ -82,12 +75,6 @@ qcom_setup_interfaces()
ucidef_add_switch_attr "switch1" "enable" "false" ucidef_add_switch_attr "switch1" "enable" "false"
ucidef_add_switch_attr "switch1" "reset" "true" ucidef_add_switch_attr "switch1" "reset" "true"
;; ;;
edgecore,eap104)
ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
ucidef_set_interface_wan "eth0"
ucidef_add_switch "switch1" \
"6@eth1" "1:lan1" "2:lan2" "3:lan3" "4:lan4"
;;
esac esac
} }
@@ -97,24 +84,13 @@ qcom_setup_macs()
case $board in case $board in
cig,wf194c|\ cig,wf194c|\
cig,wf194c4) cig,wf194c4|\
cig,wf196)
mac=$(grep BaseMacAddress= /dev/mtd14 | cut -dx -f2) mac=$(grep BaseMacAddress= /dev/mtd14 | cut -dx -f2)
wan_mac=$(macaddr_canonicalize $mac) wan_mac=$(macaddr_canonicalize $mac)
lan_mac=$(macaddr_add "$wan_mac" 1) lan_mac=$(macaddr_add "$wan_mac" 1)
ucidef_set_network_device_mac eth0 $lan_mac ucidef_set_network_device_mac eth0 $lan_mac
ucidef_set_network_device_mac eth1 $wan_mac ucidef_set_network_device_mac eth1 $wan_mac
ip link set eth0 address $lan_mac
ip link set eth1 address $wan_mac
ucidef_set_label_macaddr $wan_mac
;;
cig,wf196)
mac=$(grep BaseMacAddress= /dev/mtd14 | cut -dx -f2)
wan_mac=$(macaddr_canonicalize $mac)
lan_mac=$(macaddr_add "$wan_mac" 1)
ucidef_set_network_device_mac eth1 $lan_mac
ucidef_set_network_device_mac eth0 $wan_mac
ip link set eth0 address $wan_mac
ip link set eth1 address $lan_mac
ucidef_set_label_macaddr $wan_mac ucidef_set_label_macaddr $wan_mac
;; ;;
cybertan,eww622-a1) cybertan,eww622-a1)
@@ -133,14 +109,6 @@ qcom_setup_macs()
wan_mac=$(cat /sys/class/net/eth1/address) wan_mac=$(cat /sys/class/net/eth1/address)
lan_mac=$(macaddr_add "$wan_mac" 1) lan_mac=$(macaddr_add "$wan_mac" 1)
;; ;;
muxi,ap3220l)
wan_mac=$(mtd_get_mac_binary 0:Product_Info 0x5b)
lan_mac=$(macaddr_add "$wan_mac" 1)
ucidef_set_network_device_mac eth0 $wan_mac
ucidef_set_network_device_mac eth1 $lan_mac
ip link set eth0 address $wan_mac
ip link set eth1 address $lan_mac
;;
*) *)
wan_mac=$(cat /sys/class/net/eth0/address) wan_mac=$(cat /sys/class/net/eth0/address)
lan_mac=$(macaddr_add "$wan_mac" 1) lan_mac=$(macaddr_add "$wan_mac" 1)

View File

@@ -93,6 +93,7 @@ case "$FIRMWARE" in
qcom,ipq807x-hk14|\ qcom,ipq807x-hk14|\
tplink,ex227|\ tplink,ex227|\
tplink,ex447|\ tplink,ex447|\
yuncore,ax840|\
sercomm,wallaby) sercomm,wallaby)
caldata_extract "0:ART" 0x1000 0x20000 caldata_extract "0:ART" 0x1000 0x20000
;; ;;
@@ -104,8 +105,6 @@ case "$FIRMWARE" in
cig,wf188n|\ cig,wf188n|\
edgecore,eap101|\ edgecore,eap101|\
hfcl,ion4xi|\ hfcl,ion4xi|\
hfcl,ion4x_2|\
hfcl,ion4x|\
hfcl,ion4xe|\ hfcl,ion4xe|\
wallys,dr6018|\ wallys,dr6018|\
wallys,dr6018-v4|\ wallys,dr6018-v4|\
@@ -115,8 +114,6 @@ case "$FIRMWARE" in
qcom,ipq6018-cp01|\ qcom,ipq6018-cp01|\
xiaomi,ax1800|\ xiaomi,ax1800|\
glinet,ax1800|\ glinet,ax1800|\
yuncore,ax840|\
yuncore,fap650|\
plasmacloud,pax1800-v1|\ plasmacloud,pax1800-v1|\
plasmacloud,pax1800-v2) plasmacloud,pax1800-v2)
caldata_extract "0:ART" 0x1000 0x20000 caldata_extract "0:ART" 0x1000 0x20000
@@ -127,9 +124,7 @@ ath11k/IPQ5018/hw1.0/caldata.bin)
case "$board" in case "$board" in
cybertan,eww622-a1|\ cybertan,eww622-a1|\
edgecore,eap104|\ edgecore,eap104|\
liteon,wpx8324|\
motorola,q14|\ motorola,q14|\
muxi,ap3220l|\
qcom,ipq5018-mp03.1) qcom,ipq5018-mp03.1)
caldata_extract "0:ART" 0x1000 0x20000 caldata_extract "0:ART" 0x1000 0x20000
;; ;;
@@ -145,13 +140,9 @@ ath11k/qcn6122/hw1.0/caldata_1.bin)
ath11k/qcn6122/hw1.0/caldata_2.bin) ath11k/qcn6122/hw1.0/caldata_2.bin)
case "$board" in case "$board" in
motorola,q14|\ motorola,q14|\
edgecore,eap104|\ edgecore,eap104)
liteon,wpx8324)
caldata_extract "0:ART" 0x4c000 0x20000 caldata_extract "0:ART" 0x4c000 0x20000
;; ;;
muxi,ap3220l)
caldata_extract "0:ART" 0x26800 0x20000
;;
esac esac
;; ;;
ath11k/QCN9074/hw1.0/caldata_1.bin) ath11k/QCN9074/hw1.0/caldata_1.bin)
@@ -176,8 +167,6 @@ ath11k/QCN9074/hw1.0/caldata_2.bin)
ath11k-macs) ath11k-macs)
case "$board" in case "$board" in
hfcl,ion4xi|\ hfcl,ion4xi|\
hfcl,ion4x|\
hfcl,ion4x_2|\
hfcl,ion4xe) hfcl,ion4xe)
ath11k_generate_macs_ion4x ath11k_generate_macs_ion4x
;; ;;
@@ -194,8 +183,7 @@ ath11k-macs)
ath11k_generate_macs ath11k_generate_macs
;; ;;
cig,wf194c|\ cig,wf194c|\
cig,wf194c4|\ cig,wf194c)
cig,wf196)
ath11k_generate_macs_wf194 ath11k_generate_macs_wf194
;; ;;
plasmacloud,pax1800-v1|\ plasmacloud,pax1800-v1|\

View File

@@ -84,20 +84,15 @@ platform_check_image() {
edgecore,eap101|\ edgecore,eap101|\
edgecore,eap102|\ edgecore,eap102|\
edgecore,eap104|\ edgecore,eap104|\
liteon,wpx8324|\
edgecore,eap106|\ edgecore,eap106|\
hfcl,ion4xi|\ hfcl,ion4xi|\
hfcl,ion4x|\
hfcl,ion4x_2|\
hfcl,ion4xe|\ hfcl,ion4xe|\
muxi,ap3220l|\
plasmacloud,pax1800-v1|\ plasmacloud,pax1800-v1|\
plasmacloud,pax1800-v2|\ plasmacloud,pax1800-v2|\
tplink,ex227|\ tplink,ex227|\
tplink,ex447|\ tplink,ex447|\
yuncore,ax840|\ yuncore,ax840|\
motorola,q14|\ motorola,q14|\
muxi,ap3220l|\
qcom,ipq6018-cp01|\ qcom,ipq6018-cp01|\
qcom,ipq807x-hk01|\ qcom,ipq807x-hk01|\
qcom,ipq807x-hk14|\ qcom,ipq807x-hk14|\
@@ -145,8 +140,6 @@ platform_do_upgrade() {
nand_upgrade_tar "$1" nand_upgrade_tar "$1"
;; ;;
hfcl,ion4xi|\ hfcl,ion4xi|\
hfcl,ion4x|\
hfcl,ion4x_2|\
hfcl,ion4xe) hfcl,ion4xe)
if grep -q rootfs_1 /proc/cmdline; then if grep -q rootfs_1 /proc/cmdline; then
CI_UBIPART="rootfs" CI_UBIPART="rootfs"
@@ -158,7 +151,6 @@ platform_do_upgrade() {
nand_upgrade_tar "$1" nand_upgrade_tar "$1"
;; ;;
edgecore,eap104|\ edgecore,eap104|\
liteon,wpx8324|\
edgecore,eap106) edgecore,eap106)
CI_UBIPART="rootfs1" CI_UBIPART="rootfs1"
[ "$(find_mtd_chardev rootfs)" ] && CI_UBIPART="rootfs" [ "$(find_mtd_chardev rootfs)" ] && CI_UBIPART="rootfs"

View File

@@ -1,23 +0,0 @@
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../../../arm64/boot/dts/qcom/qcom-ipq5018-liteon-wpx8324.dts"
/ {
pmuv8: pmu {
compatible = "arm,cortex-a7-pmu";
};
};

View File

@@ -1,23 +0,0 @@
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../../../arm64/boot/dts/qcom/qcom-ipq5018-muxi-ap3220l.dts"
/ {
pmuv8: pmu {
compatible = "arm,cortex-a7-pmu";
};
};

View File

@@ -1,18 +0,0 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../../../arm64/boot/dts/qcom/qcom-ipq6018-hfcl-ion4x.dts"
#include "qcom-ipq6018.dtsi"

View File

@@ -1,18 +0,0 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../../../arm64/boot/dts/qcom/qcom-ipq6018-hfcl-ion4x_2.dts"
#include "qcom-ipq6018.dtsi"

View File

@@ -1,18 +0,0 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../../../arm64/boot/dts/qcom/qcom-ipq6018-yuncore-fap650.dts"
#include "qcom-ipq6018.dtsi"

View File

@@ -1,812 +0,0 @@
/dts-v1/;
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "qcom-ipq5018.dtsi"
/ {
#address-cells = <0x2>;
#size-cells = <0x2>;
model = "Liteon WPX8324";
compatible = "liteon,wpx8324", "qcom,ipq5018-mp03.5-c1", "qcom,ipq5018";
interrupt-parent = <&intc>;
aliases {
sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
serial0 = &blsp1_uart1;
/*serial1 = &blsp1_uart2;*/
ethernet0 = "/soc/dp1";
ethernet1 = "/soc/dp2";
};
chosen {
bootargs = "console=ttyMSM0,115200,n8 rw init=/init";
#ifdef __IPQ_MEM_PROFILE_256_MB__
bootargs-append = " swiotlb=1";
#else
bootargs-append = " swiotlb=1 coherent_pool=2M";
#endif
stdout-path = "serial0";
};
reserved-memory {
#ifdef __IPQ_MEM_PROFILE_256_MB__
/* 256 MB Profile
* +==========+==============+=========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +----------+--------------+-------------------------+
* | NSS | 0x40000000 | 8MB |
* +----------+--------------+-------------------------+
* | Linux | 0x40800000 | Depends on total memory |
* +----------+--------------+-------------------------+
* | uboot | 0x4A600000 | 4MB |
* +----------+--------------+-------------------------+
* | SBL | 0x4AA00000 | 1MB |
* +----------+--------------+-------------------------+
* | smem | 0x4AB00000 | 1MB |
* +----------+--------------+-------------------------+
* | TZ | 0x4AC00000 | 4MB |
* +----------+--------------+-------------------------+
* | Q6 | | |
* | code/ | 0x4B000000 | 20MB |
* | data | | |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | data | 0x4C400000 | 13MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | M3 Dump | 0x4D100000 | 1MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | QDSS | 0x4D200000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | data | 0x4D300000 | 15MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | M3 Dump | 0x4E200000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | QDSS | 0x4E300000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | data | 0x4E400000 | 15MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | M3 Dump | 0x4F300000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | QDSS | 0x4F400000 | 1MB |
* +----------+--------------+-------------------------+
* | |
* | Rest of the memory for Linux |
* | |
* +===================================================+
*/
q6_mem_regions: q6_mem_regions@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 0x4500000>;
};
q6_code_data: q6_code_data@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 0x1400000>;
};
q6_ipq5018_data: q6_ipq5018_data@4C400000 {
no-map;
reg = <0x0 0x4C400000 0x0 0xD00000>;
};
m3_dump: m3_dump@4D100000 {
no-map;
reg = <0x0 0x4D100000 0x0 0x100000>;
};
q6_etr_region: q6_etr_dump@4D200000 {
no-map;
reg = <0x0 0x4D200000 0x0 0x100000>;
};
q6_qcn6122_data1: q6_qcn6122_data1@4D300000 {
no-map;
reg = <0x0 0x4D300000 0x0 0xF00000>;
};
m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E200000 {
no-map;
reg = <0x0 0x4E200000 0x0 0x100000>;
};
q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E300000 {
no-map;
reg = <0x0 0x4E300000 0x0 0x100000>;
};
q6_qcn6122_data2: q6_qcn6122_data2@4E400000 {
no-map;
reg = <0x0 0x4E400000 0x0 0xF00000>;
};
m3_dump_qcn6122_2: m3_dump_qcn6122_2@4F300000 {
no-map;
reg = <0x0 0x4F300000 0x0 0x100000>;
};
q6_qcn6122_etr_2: q6_qcn6122_etr_2@4F400000 {
no-map;
reg = <0x0 0x4F400000 0x0 0x100000>;
};
#else
/* 512MB/1GB Profiles
* +==========+==============+=========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +----------+--------------+-------------------------+
* | NSS | 0x40000000 | 16MB |
* +----------+--------------+-------------------------+
* | Linux | 0x41000000 | Depends on total memory |
* +----------+--------------+-------------------------+
* | uboot | 0x4A600000 | 4MB |
* +----------+--------------+-------------------------+
* | SBL | 0x4AA00000 | 1MB |
* +----------+--------------+-------------------------+
* | smem | 0x4AB00000 | 1MB |
* +----------+--------------+-------------------------+
* | TZ | 0x4AC00000 | 4MB |
* +----------+--------------+-------------------------+
* | Q6 | | |
* | code/ | 0x4B000000 | 20MB |
* | data | | |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | data | 0x4C400000 | 14MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | M3 Dump | 0x4D200000 | 1MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | QDSS | 0x4D300000 | 1MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | Caldb | 0x4D400000 | 2MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | data | 0x4D600000 | 16MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | M3 Dump | 0x4E600000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | QDSS | 0x4E700000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | Caldb | 0x4E800000 | 5MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | data | 0x4ED00000 | 16MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | M3 Dump | 0x4FD00000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | QDSS | 0x4FE00000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | Caldb | 0x4FF00000 | 5MB |
* +----------+--------------+-------------------------+
* | |
* | Rest of the memory for Linux |
* | |
* +===================================================+
*/
q6_mem_regions: q6_mem_regions@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 0x5400000>;
};
q6_code_data: q6_code_data@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 01400000>;
};
q6_ipq5018_data: q6_ipq5018_data@4C400000 {
no-map;
reg = <0x0 0x4C400000 0x0 0xE00000>;
};
m3_dump: m3_dump@4D200000 {
no-map;
reg = <0x0 0x4D200000 0x0 0x100000>;
};
q6_etr_region: q6_etr_dump@4D300000 {
no-map;
reg = <0x0 0x4D300000 0x0 0x100000>;
};
q6_caldb_region: q6_caldb_region@4D400000 {
no-map;
reg = <0x0 0x4D400000 0x0 0x200000>;
};
q6_qcn6122_data1: q6_qcn6122_data1@4D600000 {
no-map;
reg = <0x0 0x4D600000 0x0 0x1000000>;
};
m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E600000 {
no-map;
reg = <0x0 0x4E600000 0x0 0x100000>;
};
q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E700000 {
no-map;
reg = <0x0 0x4E700000 0x0 0x100000>;
};
q6_qcn6122_caldb_1: q6_qcn6122_caldb_1@4E800000 {
no-map;
reg = <0x0 0x4E800000 0x0 0x500000>;
};
q6_qcn6122_data2: q6_qcn6122_data2@4E900000 {
no-map;
reg = <0x0 0x4ED00000 0x0 0x1000000>;
};
m3_dump_qcn6122_2: m3_dump_qcn6122_2@4FD00000 {
no-map;
reg = <0x0 0x4FD00000 0x0 0x100000>;
};
q6_qcn6122_etr_2: q6_qcn6122_etr_2@4FE00000 {
no-map;
reg = <0x0 0x4FE00000 0x0 0x100000>;
};
q6_qcn6122_caldb_2: q6_qcn6122_caldb_2@4FF00000 {
no-map;
reg = <0x0 0x4FF00000 0x0 0x500000>;
};
#endif
};
soc {
serial@78af000 {
status = "ok";
};
qpic_bam: dma@7984000{
status = "ok";
};
nand: qpic-nand@79b0000 {
pinctrl-0 = <&qspi_nand_pins>;
pinctrl-names = "default";
status = "ok";
};
spi_0: spi@78b5000 { /* BLSP1 QUP0 */
pinctrl-0 = <&blsp0_spi_pins>;
pinctrl-names = "default";
cs-select = <0>;
status = "ok";
m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
compatible = "n25q128a11";
linux,modalias = "m25p80", "n25q128a11";
spi-max-frequency = <50000000>;
use-default-sizes;
};
};
spi_2: spi@78b7000 { /* BLSP1 QUP2 */
pinctrl-0 = <&blsp2_spi0_pins>;
pinctrl-names = "default";
cs-select = <0>;
status = "ok";
tpm0: slb9670@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <1>; /* CE1 */
compatible = "infineon,slb9670";
linux,modalias = "slb9670", "slb9670a11";
spi-max-frequency = <50000000>;
use-default-sizes;
};
};
mdio0: mdio@88000 {
status = "ok";
ethernet-phy@0 {
reg = <7>;
};
};
mdio1: mdio@90000 {
status = "ok";
pinctrl-0 = <&mdio1_pins>;
pinctrl-names = "default";
phy-reset-gpio = <&tlmm 26 0>;
ethernet-phy@0 {
reg = <28>;
};
};
ess-instance {
num_devices = <0x1>;
ess-switch@0x39c00000 {
switch_mac_mode = <0xf>; /* mac mode for uniphy instance*/
cmnblk_clk = "internal_96MHz"; /* cmnblk clk*/
qcom,port_phyinfo {
port@0 {
port_id = <1>;
phy_address = <7>;
mdiobus = <&mdio0>;
};
port@1 {
port_id = <2>;
phy_address = <0x1c>;
mdiobus = <&mdio1>;
port_mac_sel = "QGMAC_PORT";
};
};
led_source@0 {
source = <0>;
mode = "normal";
speed = "all";
blink_en = "enable";
active = "high";
};
};
};
wifi0: wifi@c000000 {
status = "ok";
};
dp1 {
device_type = "network";
compatible = "qcom,nss-dp";
clocks = <&gcc GCC_SNOC_GMAC0_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,id = <1>;
reg = <0x39C00000 0x10000>;
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
qcom,mactype = <2>;
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <7>;
mdio-bus = <&mdio0>;
local-mac-address = [000000000000];
phy-mode = "sgmii";
};
dp2 {
device_type = "network";
compatible = "qcom,nss-dp";
clocks = <&gcc GCC_SNOC_GMAC1_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,id = <2>;
reg = <0x39D00000 0x10000>;
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
qcom,mactype = <2>;
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <28>;
mdio-bus = <&mdio1>;
local-mac-address = [000000000000];
phy-mode = "sgmii";
};
qcom,test@0 {
status = "ok";
};
};
thermal-zones {
status = "ok";
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&leds_pins>;
pinctrl-names = "default";
led_blue: led@19 {
label = "blue:uplink";
gpios = <&tlmm 19 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
led_orange: led@18 {
label = "orange:wifi2";
gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
led_green: led@39 {
label = "green:wifi5";
gpios = <&tlmm 39 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
};
};
&tlmm {
pinctrl-0 = <&blsp0_uart_pins &phy_led_pins>;
pinctrl-names = "default";
leds_pins: leds_pins {
led_blue {
pins = "gpio19";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_orange {
pins = "gpio18";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_green {
pins = "gpio39";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
blsp0_uart_pins: uart_pins {
blsp0_uart_rx_tx {
pins = "gpio20", "gpio21";
function = "blsp0_uart0";
bias-disable;
};
};
blsp0_spi_pins: blsp0_spi_pins {
mux {
pins = "gpio10", "gpio11", "gpio12", "gpio13";
function = "blsp0_spi";
drive-strength = <2>;
bias-disable;
};
};
blsp2_spi0_pins: blsp2_spi0_pins {
mux {
pins = "gpio31", "gpio32", "gpio33", "gpio34";
function = "blsp2_spi0";
drive-strength = <2>;
bias-disable;
};
};
qspi_nand_pins: qspi_nand_pins {
qspi_clock {
pins = "gpio9";
function = "qspi_clk";
drive-strength = <8>;
bias-disable;
};
qspi_cs {
pins = "gpio8";
function = "qspi_cs";
drive-strength = <8>;
bias-disable;
};
qspi_data_0 {
pins = "gpio7";
function = "qspi0";
drive-strength = <8>;
bias-disable;
};
qspi_data_1 {
pins = "gpio6";
function = "qspi1";
drive-strength = <8>;
bias-disable;
};
qspi_data_2 {
pins = "gpio5";
function = "qspi2";
drive-strength = <8>;
bias-disable;
};
qspi_data_3 {
pins = "gpio4";
function = "qspi3";
drive-strength = <8>;
bias-disable;
};
};
mdio1_pins: mdio_pinmux {
mux_0 {
pins = "gpio36";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mux_1 {
pins = "gpio37";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
};
phy_led_pins: phy_led_pins {
gephy_led_pin {
pins = "gpio18", "gpio19", "gpio39";
/* function = "led0"; */
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
i2c_pins: i2c_pins {
i2c_scl {
pins = "gpio25";
function = "blsp2_i2c1";
drive-strength = <8>;
bias-disable;
};
i2c_sda {
pins = "gpio26";
function = "blsp2_i2c1";
drive-strength = <8>;
bias-disable;
};
};
button_pins: button_pins {
wps_button {
pins = "gpio29";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
};
&soc {
gpio_keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
button@1 {
label = "wps";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&tlmm 29 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
};
};
&usb3 {
status = "ok";
device-power-gpio = <&tlmm 28 0>;
};
&eud {
status = "ok";
};
&pcie_x1 {
status = "disabled";
perst-gpio = <&tlmm 18 1>;
};
&pcie_x2 {
status = "disabled";
perst-gpio = <&tlmm 15 1>;
};
&dwc_0 {
/delete-property/ #phy-cells;
/delete-property/ phys;
/delete-property/ phy-names;
};
&hs_m31phy_0 {
status = "ok";
};
&pcie_x1phy {
status = "disabled";
};
&pcie_x2phy {
status = "disabled";
};
&pcie_x1_rp {
status = "disabled";
mhi_0: qcom,mhi@0 {
reg = <0 0 0 0 0 >;
};
};
&pcie_x2_rp {
status = "disabled";
mhi_1: qcom,mhi@1 {
reg = <0 0 0 0 0 >;
};
};
&qfprom {
status = "ok";
};
&tsens {
status = "ok";
};
&qcom_q6v5_wcss {
qcom,multipd_arch;
memory-region = <&q6_mem_regions>;
qcom,share_bootargs;
qcom,bootargs_smem = <507>;
boot-args = <0x1 0x4 0x3 0x0F 0x0 0x0>,
<0x2 0x4 0x2 0x12 0x0 0x0>;
/* IPQ5018 */
q6v5_wcss_userpd1 {
m3_firmware = "IPQ5018/m3_fw.mdt";
interrupts-extended = <&wcss_smp2p_in 8 0>,
<&wcss_smp2p_in 9 0>,
<&wcss_smp2p_in 12 0>,
<&wcss_smp2p_in 11 0>;
interrupt-names ="fatal",
"ready",
"spawn_ack",
"stop-ack";
qcom,smem-states = <&wcss_smp2p_out 8>,
<&wcss_smp2p_out 9>,
<&wcss_smp2p_out 10>;
qcom,smem-state-names = "shutdown",
"stop",
"spawn";
qca,asid = <1>;
qca,auto-restart;
qca,int_radio;
#ifdef __IPQ_MEM_PROFILE_256_MB__
memory-region = <&q6_ipq5018_data>, <&m3_dump>,
<&q6_etr_region>;
#else
memory-region = <&q6_ipq5018_data>, <&m3_dump>,
<&q6_etr_region>, <&q6_caldb_region>;
#endif
};
/* QCN6122 6G */
q6v5_wcss_userpd2 {
m3_firmware = "qcn6122/m3_fw.mdt";
interrupts-extended = <&wcss_smp2p_in 16 0>,
<&wcss_smp2p_in 17 0>,
<&wcss_smp2p_in 20 0>,
<&wcss_smp2p_in 19 0>;
interrupt-names ="fatal",
"ready",
"spawn_ack",
"stop-ack";
qcom,smem-states = <&wcss_smp2p_out 16>,
<&wcss_smp2p_out 17>,
<&wcss_smp2p_out 18>;
qcom,smem-state-names = "shutdown",
"stop",
"spawn";
qca,asid = <2>;
qca,auto-restart;
#ifdef __IPQ_MEM_PROFILE_256_MB__
memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>,
<&q6_qcn6122_etr_1>;
#else
memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>,
<&q6_qcn6122_etr_1>, <&q6_qcn6122_caldb_1>;
#endif
};
/* QCN6122 5G */
q6v5_wcss_userpd3 {
m3_firmware = "qcn6122/m3_fw.mdt";
interrupts-extended = <&wcss_smp2p_in 24 0>,
<&wcss_smp2p_in 25 0>,
<&wcss_smp2p_in 28 0>,
<&wcss_smp2p_in 27 0>;
interrupt-names ="fatal",
"ready",
"spawn_ack",
"stop-ack";
qcom,smem-states = <&wcss_smp2p_out 24>,
<&wcss_smp2p_out 25>,
<&wcss_smp2p_out 26>;
qcom,smem-state-names = "shutdown",
"stop",
"spawn";
qca,asid = <3>;
qca,auto-restart;
#ifdef __IPQ_MEM_PROFILE_256_MB__
memory-region = <&q6_qcn6122_data2>, <&m3_dump_qcn6122_2>,
<&q6_qcn6122_etr_2>;
#else
memory-region = <&q6_qcn6122_data2>, <&m3_dump_qcn6122_2>,
<&q6_qcn6122_etr_2>, <&q6_qcn6122_caldb_2>;
#endif
};
};
&qgic_msi_0 {
status = "ok";
};
&qgic_msi_1 {
status = "ok";
};
&wifi0 {
/* IPQ5018 */
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
#ifdef __IPQ_MEM_PROFILE_256_MB__
qcom,tgt-mem-mode = <2>;
#else
qcom,tgt-mem-mode = <1>;
#endif
qcom,board_id = <0x24>;
qcom,bdf-addr = <0x4C400000 0x4C400000 0x4C400000 0x0 0x0>;
#ifdef __CNSS2__
qcom,caldb-addr = <0x4D400000 0x4D400000 0 0 0>;
#else
qcom,caldb-addr = <0x4D400000>;
m3-dump-addr = <0x4D200000>;
#endif
qcom,caldb-size = <0x200000>;
status = "ok";
};
&wifi1 {
/* QCN6122 5G */
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd3";
#ifdef __IPQ_MEM_PROFILE_256_MB__
qcom,tgt-mem-mode = <2>;
#else
qcom,tgt-mem-mode = <1>;
#endif
qcom,board_id = <0x60>;
qcom,bdf-addr = <0x4ED00000 0x4ED00000 0x4E400000 0x0 0x0>;
#ifdef __CNSS2__
qcom,caldb-addr = <0x4FF00000 0x4FF00000 0 0 0>;
#else
qcom,caldb-addr = <0x4FF00000>;
m3-dump-addr = <0x4FD00000>;
#endif
qcom,caldb-size = <0x500000>;
status = "ok";
};

View File

@@ -1,891 +0,0 @@
/dts-v1/;
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "qcom-ipq5018.dtsi"
/ {
#address-cells = <0x2>;
#size-cells = <0x2>;
model = "MUXI AP3220L";
compatible = "muxi,ap3220l", "qcom,ipq5018-mp03.5-c1", "qcom,ipq5018";
interrupt-parent = <&intc>;
aliases {
serial0 = &blsp1_uart1;
serial1 = &blsp1_uart2;
ethernet0 = "/soc/dp1";
ethernet1 = "/soc/dp2";
led-boot = &led_power;
led-failsafe = &led_power;
led-running = &led_power;
led-upgrade = &led_power;
};
chosen {
bootargs = "console=ttyMSM0,115200,n8 rw init=/init";
#ifdef __IPQ_MEM_PROFILE_256_MB__
bootargs-append = " swiotlb=1";
#else
bootargs-append = " swiotlb=1 coherent_pool=2M";
#endif
stdout-path = "serial0";
};
reserved-memory {
#ifdef __IPQ_MEM_PROFILE_256_MB__
/* 256 MB Profile
* +==========+==============+=========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +----------+--------------+-------------------------+
* | NSS | 0x40000000 | 8MB |
* +----------+--------------+-------------------------+
* | Linux | 0x40800000 | Depends on total memory |
* +----------+--------------+-------------------------+
* | uboot | 0x4A600000 | 4MB |
* +----------+--------------+-------------------------+
* | SBL | 0x4AA00000 | 1MB |
* +----------+--------------+-------------------------+
* | smem | 0x4AB00000 | 1MB |
* +----------+--------------+-------------------------+
* | TZ | 0x4AC00000 | 4MB |
* +----------+--------------+-------------------------+
* | Q6 | | |
* | code/ | 0x4B000000 | 20MB |
* | data | | |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | data | 0x4C400000 | 13MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | M3 Dump | 0x4D100000 | 1MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | QDSS | 0x4D200000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | data | 0x4D300000 | 15MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | M3 Dump | 0x4E200000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | QDSS | 0x4E300000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | data | 0x4E400000 | 15MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | M3 Dump | 0x4F300000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | QDSS | 0x4F400000 | 1MB |
* +----------+--------------+-------------------------+
* | |
* | Rest of the memory for Linux |
* | |
* +===================================================+
*/
q6_mem_regions: q6_mem_regions@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 0x4500000>;
};
q6_code_data: q6_code_data@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 0x1400000>;
};
q6_ipq5018_data: q6_ipq5018_data@4C400000 {
no-map;
reg = <0x0 0x4C400000 0x0 0xD00000>;
};
m3_dump: m3_dump@4D100000 {
no-map;
reg = <0x0 0x4D100000 0x0 0x100000>;
};
q6_etr_region: q6_etr_dump@4D200000 {
no-map;
reg = <0x0 0x4D200000 0x0 0x100000>;
};
q6_qcn6122_data1: q6_qcn6122_data1@4D300000 {
no-map;
reg = <0x0 0x4D300000 0x0 0xF00000>;
};
m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E200000 {
no-map;
reg = <0x0 0x4E200000 0x0 0x100000>;
};
q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E300000 {
no-map;
reg = <0x0 0x4E300000 0x0 0x100000>;
};
q6_qcn6122_data2: q6_qcn6122_data2@4E400000 {
no-map;
reg = <0x0 0x4E400000 0x0 0xF00000>;
};
m3_dump_qcn6122_2: m3_dump_qcn6122_2@4F300000 {
no-map;
reg = <0x0 0x4F300000 0x0 0x100000>;
};
q6_qcn6122_etr_2: q6_qcn6122_etr_2@4F400000 {
no-map;
reg = <0x0 0x4F400000 0x0 0x100000>;
};
#else
/* 512MB/1GB Profiles
* +==========+==============+=========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +----------+--------------+-------------------------+
* | NSS | 0x40000000 | 16MB |
* +----------+--------------+-------------------------+
* | Linux | 0x41000000 | Depends on total memory |
* +----------+--------------+-------------------------+
* | uboot | 0x4A600000 | 4MB |
* +----------+--------------+-------------------------+
* | SBL | 0x4AA00000 | 1MB |
* +----------+--------------+-------------------------+
* | smem | 0x4AB00000 | 1MB |
* +----------+--------------+-------------------------+
* | TZ | 0x4AC00000 | 4MB |
* +----------+--------------+-------------------------+
* | Q6 | | |
* | code/ | 0x4B000000 | 20MB |
* | data | | |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | data | 0x4C400000 | 14MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | M3 Dump | 0x4D200000 | 1MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | QDSS | 0x4D300000 | 1MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | Caldb | 0x4D400000 | 2MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | data | 0x4D600000 | 16MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | M3 Dump | 0x4E600000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | QDSS | 0x4E700000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | Caldb | 0x4E800000 | 5MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | data | 0x4ED00000 | 16MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | M3 Dump | 0x4FD00000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | QDSS | 0x4FE00000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | Caldb | 0x4FF00000 | 5MB |
* +----------+--------------+-------------------------+
* | |
* | Rest of the memory for Linux |
* | |
* +===================================================+
*/
q6_mem_regions: q6_mem_regions@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 0x5400000>;
};
q6_code_data: q6_code_data@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 01400000>;
};
q6_ipq5018_data: q6_ipq5018_data@4C400000 {
no-map;
reg = <0x0 0x4C400000 0x0 0xE00000>;
};
m3_dump: m3_dump@4D200000 {
no-map;
reg = <0x0 0x4D200000 0x0 0x100000>;
};
q6_etr_region: q6_etr_dump@4D300000 {
no-map;
reg = <0x0 0x4D300000 0x0 0x100000>;
};
q6_caldb_region: q6_caldb_region@4D400000 {
no-map;
reg = <0x0 0x4D400000 0x0 0x200000>;
};
q6_qcn6122_data1: q6_qcn6122_data1@4D600000 {
no-map;
reg = <0x0 0x4D600000 0x0 0x1000000>;
};
m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E600000 {
no-map;
reg = <0x0 0x4E600000 0x0 0x100000>;
};
q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E700000 {
no-map;
reg = <0x0 0x4E700000 0x0 0x100000>;
};
q6_qcn6122_caldb_1: q6_qcn6122_caldb_1@4E800000 {
no-map;
reg = <0x0 0x4E800000 0x0 0x500000>;
};
q6_qcn6122_data2: q6_qcn6122_data2@4E900000 {
no-map;
reg = <0x0 0x4ED00000 0x0 0x1000000>;
};
m3_dump_qcn6122_2: m3_dump_qcn6122_2@4FD00000 {
no-map;
reg = <0x0 0x4FD00000 0x0 0x100000>;
};
q6_qcn6122_etr_2: q6_qcn6122_etr_2@4FE00000 {
no-map;
reg = <0x0 0x4FE00000 0x0 0x100000>;
};
q6_qcn6122_caldb_2: q6_qcn6122_caldb_2@4FF00000 {
no-map;
reg = <0x0 0x4FF00000 0x0 0x500000>;
};
#endif
};
soc {
blsp1_uart1: serial@78af000 {
pinctrl-0 = <&blsp0_uart_pins>;
pinctrl-names = "default";
status = "okay";
};
blsp1_uart2: serial@78b0000 {
pinctrl-0 = <&blsp1_uart_pins>;
pinctrl-names = "default";
status = "disabled";
};
qpic_bam: dma@7984000{
status = "ok";
};
nand: qpic-nand@79b0000 {
pinctrl-0 = <&qspi_nand_pins>;
pinctrl-names = "default";
status = "ok";
};
spi_0: spi@78b5000 { /* BLSP1 QUP0 */
pinctrl-0 = <&blsp0_spi_pins>;
pinctrl-names = "default";
cs-select = <0>;
status = "ok";
m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
compatible = "n25q128a11";
linux,modalias = "m25p80", "n25q128a11";
spi-max-frequency = <50000000>;
use-default-sizes;
};
};
mdio0: mdio@88000 {
status = "ok";
ethernet-phy@0 {
reg = <7>;
};
};
mdio1: mdio@90000 {
status = "ok";
pinctrl-0 = <&mdio1_pins &phy_pins>;
pinctrl-names = "default";
phy-reset-gpio = <&tlmm 39 0>;
ethernet-phy@0 {
reg = <0>;
};
ethernet-phy@1 {
reg = <1>;
};
ethernet-phy@2 {
reg = <2>;
};
ethernet-phy@3 {
reg = <3>;
};
};
ess-instance {
num_devices = <0x2>;
ess-switch@0x39c00000 {
compatible = "qcom,ess-switch-ipq50xx";
device_id = <0>;
switch_mac_mode = <0xf>; /* mac mode for uniphy instance*/
cmnblk_clk = "internal_96MHz"; /* cmnblk clk*/
qcom,port_phyinfo {
port@0 {
port_id = <1>;
phy_address = <7>;
};
port@1 {
port_id = <2>;
forced-speed = <1000>;
forced-duplex = <1>;
};
};
/*
led_source@0 {
source = <0>;
mode = "normal";
speed = "all";
blink_en = "enable";
active = "high";
};
*/
};
ess-switch1@1 {
compatible = "qcom,ess-switch-qca83xx";
device_id = <1>;
switch_access_mode = "mdio";
mdio-bus = <&mdio1>;
reset_gpio = <0x27>;
switch_cpu_bmp = <0x40>; /* cpu port bitmap */
switch_lan_bmp = <0x1e>; /* lan port bitmap */
switch_wan_bmp = <0x0>; /* wan port bitmap */
qca,ar8327-initvals = <
0x00004 0x7600000 /* PAD0_MODE */
0x00008 0x1000000 /* PAD5_MODE */
0x0000c 0x80 /* PAD6_MODE */
0x00010 0x2613a0 /* PORT6 FORCE MODE*/
0x000e4 0xaa545 /* MAC_POWER_SEL */
0x000e0 0xc74164de /* SGMII_CTRL */
0x0007c 0x4e /* PORT0_STATUS */
0x00094 0x4e /* PORT6_STATUS */
>;
qcom,port_phyinfo {
port@0 {
port_id = <1>;
phy_address = <0>;
};
port@1 {
port_id = <2>;
phy_address = <1>;
};
port@2 {
port_id = <3>;
phy_address = <2>;
};
port@3 {
port_id = <4>;
phy_address = <3>;
};
};
};
};
ess-uniphy@98000 {
status = "disabled";
};
dp1 {
device_type = "network";
compatible = "qcom,nss-dp";
clocks = <&gcc GCC_SNOC_GMAC0_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,id = <1>;
reg = <0x39C00000 0x10000>;
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
qcom,mactype = <2>;
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <7>;
mdio-bus = <&mdio0>;
local-mac-address = [000000000000];
phy-mode = "sgmii";
};
dp2 {
device_type = "network";
compatible = "qcom,nss-dp";
clocks = <&gcc GCC_SNOC_GMAC1_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,id = <2>;
reg = <0x39D00000 0x10000>;
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
qcom,mactype = <2>;
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <3>;
mdio-bus = <&mdio1>;
local-mac-address = [000000000000];
phy-mode = "sgmii";
};
qcom,test@0 {
status = "ok";
};
};
thermal-zones {
status = "ok";
};
};
&tlmm {
//pinctrl-0 = <&phy_led_pins>;
pinctrl-names = "default";
blsp0_uart_pins: uart_pins {
blsp0_uart_rx_tx {
pins = "gpio20", "gpio21";
function = "blsp0_uart0";
bias-disable;
};
};
blsp1_uart_pins: blsp1_uart_pins {
blsp1_uart_rx_tx {
pins = "gpio23", "gpio25";
function = "blsp1_uart2";
bias-disable;
};
};
blsp0_spi_pins: blsp0_spi_pins {
mux {
pins = "gpio10", "gpio11", "gpio12", "gpio13";
function = "blsp0_spi";
drive-strength = <2>;
bias-disable;
};
};
qspi_nand_pins: qspi_nand_pins {
qspi_clock {
pins = "gpio9";
function = "qspi_clk";
drive-strength = <8>;
bias-disable;
};
qspi_cs {
pins = "gpio8";
function = "qspi_cs";
drive-strength = <8>;
bias-disable;
};
qspi_data_0 {
pins = "gpio7";
function = "qspi0";
drive-strength = <8>;
bias-disable;
};
qspi_data_1 {
pins = "gpio6";
function = "qspi1";
drive-strength = <8>;
bias-disable;
};
qspi_data_2 {
pins = "gpio5";
function = "qspi2";
drive-strength = <8>;
bias-disable;
};
qspi_data_3 {
pins = "gpio4";
function = "qspi3";
drive-strength = <8>;
bias-disable;
};
};
phy_pins: phy_pins {
phy_intr {
pins = "gpio29";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
bias-disable;
};
phy_reset {
pins = "gpio39";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
output-low;
};
};
mdio1_pins: mdio_pinmux {
mux_0 {
pins = "gpio36";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mux_1 {
pins = "gpio37";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
};
phy_led_pins: phy_led_pins {
gephy_led_pin {
//pins = "gpio46";
function = "led0";
drive-strength = <8>;
bias-pull-down;
};
};
button_pins: button_pins {
reset_button {
pins = "gpio32";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
led_pins: led_pins {
led_pwr {
pins = "gpio26";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_2g {
pins = "gpio31";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_5g {
pins = "gpio33";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
};
&soc {
gpio_keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
button@1 {
label = "reset_button";
linux,code = <KEY_RESTART>;
gpios = <&tlmm 32 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&led_pins>;
pinctrl-names = "default";
led_power: led_pwr {
label = "green:led_pwr";
gpios = <&tlmm 26 GPIO_ACTIVE_HIGH>;
default-state = "on";
linux,default-trigger = "led_pwr";
};
led_2g {
label = "green:wifi2";
gpio = <&tlmm 33 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
led_5g {
label = "green:wifi5";
gpio = <&tlmm 31 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
};
};
&usb3 {
status = "ok";
device-power-gpio = <&tlmm 30 1>;
};
&eud {
status = "ok";
};
&pcie_x1 {
status = "disabled";
perst-gpio = <&tlmm 18 1>;
};
&pcie_x2 {
status = "disabled";
perst-gpio = <&tlmm 15 1>;
};
&dwc_0 {
/delete-property/ #phy-cells;
/delete-property/ phys;
/delete-property/ phy-names;
};
&hs_m31phy_0 {
status = "ok";
};
&pcie_x1phy {
status = "disabled";
};
&pcie_x2phy {
status = "disabled";
};
&pcie_x1_rp {
status = "disabled";
mhi_0: qcom,mhi@0 {
reg = <0 0 0 0 0 >;
};
};
&pcie_x2_rp {
status = "disabled";
mhi_1: qcom,mhi@1 {
reg = <0 0 0 0 0 >;
};
};
&qfprom {
status = "ok";
};
&tsens {
status = "ok";
};
&qcom_q6v5_wcss {
qcom,multipd_arch;
memory-region = <&q6_mem_regions>;
qcom,share_bootargs;
qcom,bootargs_smem = <507>;
boot-args = <0x2 0x4 0x2 0xF 0x0 0x0>;
/* IPQ5018 */
q6v5_wcss_userpd1 {
m3_firmware = "IPQ5018/m3_fw.mdt";
interrupts-extended = <&wcss_smp2p_in 8 0>,
<&wcss_smp2p_in 9 0>,
<&wcss_smp2p_in 12 0>,
<&wcss_smp2p_in 11 0>;
interrupt-names ="fatal",
"ready",
"spawn_ack",
"stop-ack";
qcom,smem-states = <&wcss_smp2p_out 8>,
<&wcss_smp2p_out 9>,
<&wcss_smp2p_out 10>;
qcom,smem-state-names = "shutdown",
"stop",
"spawn";
qca,asid = <1>;
qca,auto-restart;
qca,int_radio;
#ifdef __IPQ_MEM_PROFILE_256_MB__
memory-region = <&q6_ipq5018_data>, <&m3_dump>,
<&q6_etr_region>;
#else
memory-region = <&q6_ipq5018_data>, <&m3_dump>,
<&q6_etr_region>, <&q6_caldb_region>;
#endif
};
/* QCN6122 6G */
q6v5_wcss_userpd2 {
m3_firmware = "qcn6122/m3_fw.mdt";
interrupts-extended = <&wcss_smp2p_in 16 0>,
<&wcss_smp2p_in 17 0>,
<&wcss_smp2p_in 20 0>,
<&wcss_smp2p_in 19 0>;
interrupt-names ="fatal",
"ready",
"spawn_ack",
"stop-ack";
qcom,smem-states = <&wcss_smp2p_out 16>,
<&wcss_smp2p_out 17>,
<&wcss_smp2p_out 18>;
qcom,smem-state-names = "shutdown",
"stop",
"spawn";
qca,asid = <2>;
qca,auto-restart;
#ifdef __IPQ_MEM_PROFILE_256_MB__
memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>,
<&q6_qcn6122_etr_1>;
#else
memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>,
<&q6_qcn6122_etr_1>, <&q6_qcn6122_caldb_1>;
#endif
};
/* QCN6122 5G */
q6v5_wcss_userpd3 {
m3_firmware = "qcn6122/m3_fw.mdt";
interrupts-extended = <&wcss_smp2p_in 24 0>,
<&wcss_smp2p_in 25 0>,
<&wcss_smp2p_in 28 0>,
<&wcss_smp2p_in 27 0>;
interrupt-names ="fatal",
"ready",
"spawn_ack",
"stop-ack";
qcom,smem-states = <&wcss_smp2p_out 24>,
<&wcss_smp2p_out 25>,
<&wcss_smp2p_out 26>;
qcom,smem-state-names = "shutdown",
"stop",
"spawn";
qca,asid = <3>;
qca,auto-restart;
#ifdef __IPQ_MEM_PROFILE_256_MB__
memory-region = <&q6_qcn6122_data2>, <&m3_dump_qcn6122_2>,
<&q6_qcn6122_etr_2>;
#else
memory-region = <&q6_qcn6122_data2>, <&m3_dump_qcn6122_2>,
<&q6_qcn6122_etr_2>, <&q6_qcn6122_caldb_2>;
#endif
};
};
&qgic_msi_0 {
status = "ok";
};
&qgic_msi_1 {
status = "ok";
};
&wifi0 {
/* IPQ5018 */
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
#ifdef __IPQ_MEM_PROFILE_256_MB__
qcom,tgt-mem-mode = <2>;
#else
qcom,tgt-mem-mode = <1>;
#endif
qcom,board_id = <0x24>;
qcom,bdf-addr = <0x4C400000 0x4C400000 0x4C400000 0x0 0x0>;
#ifdef __CNSS2__
qcom,caldb-addr = <0x4D400000 0x4D400000 0 0 0>;
#else
qcom,caldb-addr = <0x4D400000>;
m3-dump-addr = <0x4D200000>;
#endif
qcom,caldb-size = <0x200000>;
status = "ok";
};
&wifi1 {
/* QCN6122 6G */
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd2";
#ifdef __IPQ_MEM_PROFILE_256_MB__
qcom,tgt-mem-mode = <2>;
#else
qcom,tgt-mem-mode = <1>;
#endif
qcom,board_id = <0x60>;
qcom,bdf-addr = <0x4D600000 0x4D600000 0x4D300000 0x0 0x0>;
#ifdef __CNSS2__
qcom,caldb-addr = <0x4E800000 0x4E800000 0 0 0>;
#else
qcom,caldb-addr = <0x4E800000>;
m3-dump-addr = <0x4E600000>;
#endif
qcom,caldb-size = <0x500000>;
status = "disabled";
};
&wifi2 {
/* QCN6122 5G */
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd3";
#ifdef __IPQ_MEM_PROFILE_256_MB__
qcom,tgt-mem-mode = <2>;
#else
qcom,tgt-mem-mode = <1>;
#endif
qcom,board_id = <0x60>;
qcom,bdf-addr = <0x4ED00000 0x4ED00000 0x4E400000 0x0 0x0>;
#ifdef __CNSS2__
qcom,caldb-addr = <0x4FF00000 0x4FF00000 0 0 0>;
#else
qcom,caldb-addr = <0x4FF00000>;
m3-dump-addr = <0x4FD00000>;
#endif
qcom,caldb-size = <0x500000>;
status = "ok";
};

View File

@@ -1,155 +0,0 @@
/dts-v1/;
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "qcom-ipq6018-cp01-hfcl.dtsi"
#include "qcom-ipq6018-rpm-regulator.dtsi"
#include "qcom-ipq6018-cpr-regulator.dtsi"
#include "qcom-ipq6018-cp-cpu.dtsi"
/ {
model = "HFCL ION4X";
compatible = "hfcl,ion4x", "qcom,ipq6018-cp01", "qcom,ipq6018";
/*
* +=========+==============+========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | | | |
* | | | |
* | Linux | 0x41000000 | 139MB |
* | | | |
* | | | |
* | | | |
* +--------+--------------+-------------------------+
* | TZ App | 0x49B00000 | 6MB |
* +--------+--------------+-------------------------+
*
* From the available 145 MB for Linux in the first 256 MB,
* we are reserving 6 MB for TZAPP.
*
* Refer arch/arm64/boot/dts/qcom/qcom-ipq6018-memory.dtsi
* for memory layout.
*/
/* TZAPP is enabled in default memory profile only */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
reserved-memory {
tzapp:tzapp@49B00000 { /* TZAPPS */
no-map;
reg = <0x0 0x49B00000 0x0 0x00600000>;
};
};
#endif
};
&tlmm {
i2c_1_pins: i2c_1_pins {
mux {
pins = "gpio42", "gpio43";
function = "blsp2_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
i2c_2_pins: i2c_2_pins {
mux {
pins = "gpio55", "gpio56";
function = "blsp4_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
};
&i2c_1 {
pinctrl-0 = <&i2c_1_pins>;
pinctrl-names = "default";
status = "ok";
lm75@48 {
compatible = "lm75";
reg = <0x48>;
status = "okay";
};
};
&i2c_2 {
pinctrl-0 = <&i2c_2_pins>;
pinctrl-names = "default";
status = "ok";
};
&sdhc_2 {
pinctrl-0 = <&sd_pins>;
pinctrl-names = "default";
cd-gpios = <&tlmm 62 1>;
sd-ldo-gpios = <&tlmm 66 0>;
vqmmc-supply = <&ipq6018_l2_corner>;
status = "ok";
};
&soc {
leds {
compatible = "gpio-leds";
pinctrl-0 = <&leds_pins>;
pinctrl-names = "default";
led@60 {
label = "blue:wifi5";
gpios = <&tlmm 60 GPIO_ACTIVE_LOW>;
linux,default-trigger = "led_5g";
default-state = "off";
};
led@61 {
label = "blue:wifi2";
gpios = <&tlmm 61 GPIO_ACTIVE_LOW>;
linux,default-trigger = "led_2g";
default-state = "off";
};
};
};
&tlmm {
leds_pins: leds_pins {
led_5g {
pins = "gpio60";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_2g {
pins = "gpio61";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
};
/* TZAPP is enabled in default memory profile only */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
&qseecom {
mem-start = <0x49B00000>;
mem-size = <0x600000>;
status = "ok";
};
#endif

View File

@@ -1,155 +0,0 @@
/dts-v1/;
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "qcom-ipq6018-cp01-hfcl.dtsi"
#include "qcom-ipq6018-rpm-regulator.dtsi"
#include "qcom-ipq6018-cpr-regulator.dtsi"
#include "qcom-ipq6018-cp-cpu.dtsi"
/ {
model = "HFCL ION4X_2";
compatible = "hfcl,ion4x_2", "qcom,ipq6018-cp01", "qcom,ipq6018";
/*
* +=========+==============+========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | | | |
* | | | |
* | Linux | 0x41000000 | 139MB |
* | | | |
* | | | |
* | | | |
* +--------+--------------+-------------------------+
* | TZ App | 0x49B00000 | 6MB |
* +--------+--------------+-------------------------+
*
* From the available 145 MB for Linux in the first 256 MB,
* we are reserving 6 MB for TZAPP.
*
* Refer arch/arm64/boot/dts/qcom/qcom-ipq6018-memory.dtsi
* for memory layout.
*/
/* TZAPP is enabled in default memory profile only */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
reserved-memory {
tzapp:tzapp@49B00000 { /* TZAPPS */
no-map;
reg = <0x0 0x49B00000 0x0 0x00600000>;
};
};
#endif
};
&tlmm {
i2c_1_pins: i2c_1_pins {
mux {
pins = "gpio42", "gpio43";
function = "blsp2_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
i2c_2_pins: i2c_2_pins {
mux {
pins = "gpio55", "gpio56";
function = "blsp4_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
};
&i2c_1 {
pinctrl-0 = <&i2c_1_pins>;
pinctrl-names = "default";
status = "ok";
lm75@48 {
compatible = "lm75";
reg = <0x48>;
status = "okay";
};
};
&i2c_2 {
pinctrl-0 = <&i2c_2_pins>;
pinctrl-names = "default";
status = "ok";
};
&sdhc_2 {
pinctrl-0 = <&sd_pins>;
pinctrl-names = "default";
cd-gpios = <&tlmm 62 1>;
sd-ldo-gpios = <&tlmm 66 0>;
vqmmc-supply = <&ipq6018_l2_corner>;
status = "ok";
};
&soc {
leds {
compatible = "gpio-leds";
pinctrl-0 = <&leds_pins>;
pinctrl-names = "default";
led@60 {
label = "blue:wifi5";
gpios = <&tlmm 60 GPIO_ACTIVE_LOW>;
linux,default-trigger = "led_5g";
default-state = "off";
};
led@61 {
label = "blue:wifi2";
gpios = <&tlmm 61 GPIO_ACTIVE_LOW>;
linux,default-trigger = "led_2g";
default-state = "off";
};
};
};
&tlmm {
leds_pins: leds_pins {
led_5g {
pins = "gpio60";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_2g {
pins = "gpio61";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
};
/* TZAPP is enabled in default memory profile only */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
&qseecom {
mem-start = <0x49B00000>;
mem-size = <0x600000>;
status = "ok";
};
#endif

View File

@@ -1,423 +0,0 @@
/dts-v1/;
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "qcom-ipq6018.dtsi"
#include "qcom-ipq6018-rpm-regulator.dtsi"
#include "qcom-ipq6018-cpr-regulator.dtsi"
#include "qcom-ipq6018-cp-cpu.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
/ {
#address-cells = <0x2>;
#size-cells = <0x2>;
model = "Qualcomm Technologies, Inc. IPQ6018/AP-CP03-C1";
compatible = "yuncore,fap650", "qcom,ipq6018-cp03", "qcom,ipq6018";
interrupt-parent = <&intc>;
qcom,msm-id = <0x1A5 0x0>;
aliases {
/*
* Aliases as required by u-boot
* to patch MAC addresses
*/
ethernet0 = "/soc/dp1";
ethernet1 = "/soc/dp2";
ethernet2 = "/soc/dp3";
ethernet3 = "/soc/dp4";
ethernet4 = "/soc/dp5";
led-boot = &led_power;
led-failsafe = &led_power;
led-running = &led_power;
led-upgrade = &led_power;
};
chosen {
bootargs = "console=ttyMSM0,115200,n8 rw init=/init";
#ifdef __IPQ_MEM_PROFILE_256_MB__
bootargs-append = " swiotlb=1";
#else
bootargs-append = " swiotlb=1 coherent_pool=2M";
#endif
};
/*
* +=========+==============+========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | | | |
* | | | |
* | Linux | 0x41000000 | 139MB |
* | | | |
* | | | |
* | | | |
* +--------+--------------+-------------------------+
* | TZ App | 0x49B00000 | 6MB |
* +--------+--------------+-------------------------+
*
* From the available 145 MB for Linux in the first 256 MB,
* we are reserving 6 MB for TZAPP.
*
* Refer arch/arm64/boot/dts/qcom/qcom-ipq6018-memory.dtsi
* for memory layout.
*/
/* TZAPP is enabled only in default memory profile */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
reserved-memory {
tzapp:tzapp@49B00000 { /* TZAPPS */
no-map;
reg = <0x0 0x49B00000 0x0 0x00600000>;
};
};
#endif
};
&tlmm {
uart_pins: uart_pins {
mux {
pins = "gpio44", "gpio45";
function = "blsp2_uart";
drive-strength = <8>;
bias-pull-down;
};
};
spi_0_pins: spi_0_pins {
mux {
pins = "gpio38", "gpio39", "gpio40", "gpio41";
function = "blsp0_spi";
drive-strength = <8>;
bias-pull-down;
};
};
qpic_pins: qpic_pins {
data_0 {
pins = "gpio15";
function = "qpic_pad0";
drive-strength = <8>;
bias-pull-down;
};
data_1 {
pins = "gpio12";
function = "qpic_pad1";
drive-strength = <8>;
bias-pull-down;
};
data_2 {
pins = "gpio13";
function = "qpic_pad2";
drive-strength = <8>;
bias-pull-down;
};
data_3 {
pins = "gpio14";
function = "qpic_pad3";
drive-strength = <8>;
bias-pull-down;
};
data_4 {
pins = "gpio5";
function = "qpic_pad4";
drive-strength = <8>;
bias-pull-down;
};
data_5 {
pins = "gpio6";
function = "qpic_pad5";
drive-strength = <8>;
bias-pull-down;
};
data_6 {
pins = "gpio7";
function = "qpic_pad6";
drive-strength = <8>;
bias-pull-down;
};
data_7 {
pins = "gpio8";
function = "qpic_pad7";
drive-strength = <8>;
bias-pull-down;
};
qpic_pad {
pins = "gpio1", "gpio3", "gpio4",
"gpio10", "gpio11", "gpio17";
function = "qpic_pad";
drive-strength = <8>;
bias-pull-down;
};
};
button_pins: button_pins {
wps_button {
pins = "gpio19";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
mdio_pins: mdio_pinmux {
mux_0 {
pins = "gpio64";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mux_1 {
pins = "gpio65";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
mux_2 {
pins = "gpio75";
function = "gpio";
bias-pull-up;
};
};
leds_pins: leds_pins {
led_sys {
pins = "gpio32";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_5g {
pins = "gpio35";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_2g {
pins = "gpio37";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
};
&soc {
mdio@90000 {
pinctrl-0 = <&mdio_pins>;
pinctrl-names = "default";
phy-reset-gpio = <&tlmm 75 0>;
status = "ok";
phy0: ethernet-phy@0 {
reg = <0>;
};
phy1: ethernet-phy@1 {
reg = <1>;
};
phy2: ethernet-phy@2 {
reg = <2>;
};
phy3: ethernet-phy@3 {
reg = <3>;
};
phy4: ethernet-phy@4 {
reg = <4>;
};
};
ess-switch@3a000000 {
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
switch_lan_bmp = <0x1e>; /* lan port bitmap */
switch_wan_bmp = <0x20>; /* wan port bitmap */
switch_inner_bmp = <0xc0>; /*inner port bitmap*/
switch_mac_mode = <0x0>; /* mac mode for uniphy instance0*/
switch_mac_mode1 = <0xff>; /* mac mode for uniphy instance1*/
switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
qcom,port_phyinfo {
port@3 {
port_id = <3>;
phy_address = <4>;
};
port@4 {
port_id = <4>;
phy_address = <3>;
};
};
};
dp1 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <1>;
reg = <0x3a001000 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <0>;
phy-mode = "sgmii";
};
dp2 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <2>;
reg = <0x3a001200 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <1>;
phy-mode = "sgmii";
};
dp3 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <3>;
reg = <0x3a001400 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <2>;
phy-mode = "sgmii";
};
dp4 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <4>;
reg = <0x3a001600 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <3>;
phy-mode = "sgmii";
};
dp5 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <5>;
reg = <0x3a001800 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <4>;
phy-mode = "sgmii";
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&leds_pins>;
pinctrl-names = "default";
led_power: led@32 {
label = "green:power";
gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
led@35 {
label = "green:wifi5";
gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
led@37 {
label = "green:wifi2";
gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
};
gpio_keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
wps {
label = "reset";
linux,code = <KEY_RESTART>;
gpios = <&tlmm 19 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
};
};
&blsp1_uart3 {
pinctrl-0 = <&uart_pins>;
pinctrl-names = "default";
status = "ok";
};
&spi_0 {
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-select = <0>;
status = "ok";
m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
compatible = "n25q128a11";
linux,modalias = "m25p80", "n25q128a11";
spi-max-frequency = <50000000>;
use-default-sizes;
};
};
&qpic_bam {
status = "ok";
};
&nand {
pinctrl-0 = <&qpic_pins>;
pinctrl-names = "default";
status = "ok";
};
&ssphy_0 {
status = "ok";
};
&qusb_phy_0 {
status = "ok";
};
&usb3 {
status = "ok";
};
&nss_crypto {
status = "ok";
};
/* TZAPP is enabled in default memory profile only */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
&qseecom {
mem-start = <0x49B00000>;
mem-size = <0x600000>;
status = "ok";
};
#endif

View File

@@ -50,43 +50,25 @@
bootargs-append = " swiotlb=1 coherent_pool=2M"; bootargs-append = " swiotlb=1 coherent_pool=2M";
#endif #endif
}; };
gpio-export {
compatible = "gpio-export";
#size-cells = <0>;
mcu-enable {
gpio-export,name = "mcu-enable";
gpio-export,output = <1>;
gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
};
usb-enable {
gpio-export,name = "usb-enable";
gpio-export,output = <1>;
gpios = <&tlmm 55 GPIO_ACTIVE_HIGH>;
};
};
}; };
&tlmm { &tlmm {
pinctrl-0 = <&nrf52840_reset &usb_reset>; pinctrl-0 = <&btcoex_pins>;
pinctrl-names = "default"; pinctrl-names = "default";
nrf52840_reset: nrf52840_reset_pins { btcoex_pins: btcoex_pins {
pins = "gpio54"; mux_0 {
function = "gpio"; pins = "gpio64";
drive-strength = <8>; function = "pta1_1";
bias-disable; drive-strength = <6>;
output-high; bias-pull-down;
}; };
mux_1 {
usb_reset: usb_reset_pins { pins = "gpio65";
pins = "gpio55"; function = "pta1_2";
function = "gpio"; drive-strength = <6>;
drive-strength = <8>; bias-pull-down;
bias-disable; };
output-high;
}; };
mdio_pins: mdio_pinmux { mdio_pins: mdio_pinmux {
@@ -190,7 +172,17 @@
}; };
}; };
hsuart_pins: hsuart_pins {
mux {
pins = "gpio49";
function = "blsp2_uart";
drive-strength = <8>;
bias-disable;
};
};
button_pins: button_pins { button_pins: button_pins {
reset_button { reset_button {
pins = "gpio66"; pins = "gpio66";
function = "gpio"; function = "gpio";
@@ -228,6 +220,31 @@
bias-pull-down; bias-pull-down;
}; };
}; };
usb_mux_sel_pins: usb_mux_pins {
mux {
pins = "gpio27";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
pcie0_pins: pcie_pins {
pcie0_rst {
pins = "gpio58";
function = "pcie0_rst";
drive-strength = <8>;
bias-pull-down;
};
pcie0_wake {
pins = "gpio59";
function = "pcie0_wake";
drive-strength = <8>;
bias-pull-down;
};
};
}; };
&soc { &soc {
@@ -716,6 +733,12 @@
}; };
}; };
&serial_blsp2 {
pinctrl-0 = <&hsuart_pins>;
pinctrl-names = "default";
status = "ok";
};
&nss0 { &nss0 {
qcom,low-frequency = <187200000>; qcom,low-frequency = <187200000>;
qcom,mid-frequency = <748800000>; qcom,mid-frequency = <748800000>;
@@ -789,7 +812,7 @@
}; };
&pcie0 { &pcie0 {
status = "disabled"; status = "ok";
}; };
&pcie1 { &pcie1 {

View File

@@ -18,24 +18,6 @@ define Device/edgecore_eap104
endef endef
TARGET_DEVICES += edgecore_eap104 TARGET_DEVICES += edgecore_eap104
define Device/liteon_wpx8324
DEVICE_TITLE := Liteon WPX8324
DEVICE_DTS := qcom-ipq5018-liteon-wpx8324
SUPPORTED_DEVICES := liteon,wpx8324
DEVICE_PACKAGES := ath11k-wifi-liteon-wpx8324 ath11k-firmware-ipq50xx-spruce ath11k-firmware-qcn6122
DEVICE_DTS_CONFIG := config@mp03.5-c1
endef
TARGET_DEVICES += liteon_wpx8324
define Device/muxi_ap3220l
DEVICE_TITLE := MUXI AP3220L
DEVICE_DTS := qcom-ipq5018-muxi-ap3220l
SUPPORTED_DEVICES := muxi,ap3220l
DEVICE_PACKAGES := ath11k-wifi-muxi-ap3220l ath11k-firmware-ipq50xx-spruce ath11k-firmware-qcn6122
DEVICE_DTS_CONFIG := config@mp03.5-c1
endef
TARGET_DEVICES += muxi_ap3220l
define Device/motorola_q14 define Device/motorola_q14
DEVICE_TITLE := Motorola Q14 DEVICE_TITLE := Motorola Q14
DEVICE_DTS := qcom-ipq5018-q14 DEVICE_DTS := qcom-ipq5018-q14

View File

@@ -20,24 +20,6 @@ define Device/hfcl_ion4xe
endef endef
TARGET_DEVICES += hfcl_ion4xe TARGET_DEVICES += hfcl_ion4xe
define Device/hfcl_ion4x
DEVICE_TITLE := HFCL ION4X
DEVICE_DTS := qcom-ipq6018-hfcl-ion4x
DEVICE_DTS_CONFIG := config@cp01-c1
SUPPORTED_DEVICES := hfcl,ion4x
DEVICE_PACKAGES := ath11k-wifi-qcom-ipq6018 uboot-envtools
endef
TARGET_DEVICES += hfcl_ion4x
define Device/hfcl_ion4x_2
DEVICE_TITLE := HFCL ION4X_2
DEVICE_DTS := qcom-ipq6018-hfcl-ion4x_2
DEVICE_DTS_CONFIG := config@cp01-c1
SUPPORTED_DEVICES := hfcl,ion4x_2
DEVICE_PACKAGES := ath11k-wifi-qcom-ipq6018 uboot-envtools
endef
TARGET_DEVICES += hfcl_ion4x_2
define Device/hfcl_ion4xi define Device/hfcl_ion4xi
DEVICE_TITLE := HFCL ION4Xi DEVICE_TITLE := HFCL ION4Xi
DEVICE_DTS := qcom-ipq6018-hfcl-ion4xi DEVICE_DTS := qcom-ipq6018-hfcl-ion4xi
@@ -185,13 +167,3 @@ define Device/meshpp_s618_cp01
DEVICE_PACKAGES := ath11k-wifi-meshpp-s618 -kmod-usb-dwc3-of-simple kmod-usb-dwc3-qcom kmod-usb3 DEVICE_PACKAGES := ath11k-wifi-meshpp-s618 -kmod-usb-dwc3-of-simple kmod-usb-dwc3-qcom kmod-usb3
endef endef
TARGET_DEVICES += meshpp_s618_cp01 TARGET_DEVICES += meshpp_s618_cp01
define Device/yuncore_fap650
DEVICE_TITLE := YunCore FAP 650
DEVICE_DTS := qcom-ipq6018-yuncore-fap650
SUPPORTED_DEVICES := yuncore,fap650
DEVICE_DTS_CONFIG := config@cp03-c1
DEVICE_PACKAGES := ath11k-wifi-yuncore-fap650
endef
TARGET_DEVICES += yuncore_fap650

View File

@@ -1,315 +0,0 @@
From: Jiri Pirko <jiri@mellanox.com>
Date: Thu, 21 Jul 2016 12:03:11 +0200
Subject: [PATCH] net/sched: introduce Match-all classifier
The matchall classifier matches every packet and allows the user to apply
actions on it. This filter is very useful in usecases where every packet
should be matched, for example, packet mirroring (SPAN) can be setup very
easily using that filter.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Yotam Gigi <yotamg@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
create mode 100644 net/sched/cls_matchall.c
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -427,6 +427,17 @@ enum {
#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
+/* Match-all classifier */
+
+enum {
+ TCA_MATCHALL_UNSPEC,
+ TCA_MATCHALL_CLASSID,
+ TCA_MATCHALL_ACT,
+ __TCA_MATCHALL_MAX,
+};
+
+#define TCA_MATCHALL_MAX (__TCA_MATCHALL_MAX - 1)
+
/* Extended Matches */
struct tcf_ematch_tree_hdr {
--- /dev/null
+++ b/net/sched/cls_matchall.c
@@ -0,0 +1,248 @@
+/*
+ * net/sched/cls_matchll.c Match-all classifier
+ *
+ * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <net/sch_generic.h>
+#include <net/pkt_cls.h>
+
+struct cls_mall_filter {
+ struct tcf_exts exts;
+ struct tcf_result res;
+ u32 handle;
+ struct rcu_head rcu;
+};
+
+struct cls_mall_head {
+ struct cls_mall_filter *filter;
+ struct rcu_head rcu;
+};
+
+static int mall_classify(struct sk_buff *skb, const struct tcf_proto *tp,
+ struct tcf_result *res)
+{
+ struct cls_mall_head *head = rcu_dereference_bh(tp->root);
+ struct cls_mall_filter *f = head->filter;
+
+ return tcf_exts_exec(skb, &f->exts, res);
+}
+
+static int mall_init(struct tcf_proto *tp)
+{
+ struct cls_mall_head *head;
+
+ head = kzalloc(sizeof(*head), GFP_KERNEL);
+ if (!head)
+ return -ENOBUFS;
+
+ rcu_assign_pointer(tp->root, head);
+
+ return 0;
+}
+
+static void mall_destroy_filter(struct rcu_head *head)
+{
+ struct cls_mall_filter *f = container_of(head, struct cls_mall_filter, rcu);
+
+ tcf_exts_destroy(&f->exts);
+ kfree(f);
+}
+
+static bool mall_destroy(struct tcf_proto *tp, bool force)
+{
+ struct cls_mall_head *head = rtnl_dereference(tp->root);
+
+ if (!force && head->filter)
+ return false;
+
+ if (head->filter)
+ call_rcu(&head->filter->rcu, mall_destroy_filter);
+ RCU_INIT_POINTER(tp->root, NULL);
+ kfree_rcu(head, rcu);
+ return true;
+}
+
+static unsigned long mall_get(struct tcf_proto *tp, u32 handle)
+{
+ struct cls_mall_head *head = rtnl_dereference(tp->root);
+ struct cls_mall_filter *f = head->filter;
+
+ if (f && f->handle == handle)
+ return (unsigned long) f;
+ return 0;
+}
+
+static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = {
+ [TCA_MATCHALL_UNSPEC] = { .type = NLA_UNSPEC },
+ [TCA_MATCHALL_CLASSID] = { .type = NLA_U32 },
+};
+
+static int mall_set_parms(struct net *net, struct tcf_proto *tp,
+ struct cls_mall_filter *f,
+ unsigned long base, struct nlattr **tb,
+ struct nlattr *est, bool ovr)
+{
+ struct tcf_exts e;
+ int err;
+
+ tcf_exts_init(&e, TCA_MATCHALL_ACT, 0);
+ err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
+ if (err < 0)
+ return err;
+
+ if (tb[TCA_MATCHALL_CLASSID]) {
+ f->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]);
+ tcf_bind_filter(tp, &f->res, base);
+ }
+
+ tcf_exts_change(tp, &f->exts, &e);
+
+ return 0;
+}
+
+static int mall_change(struct net *net, struct sk_buff *in_skb,
+ struct tcf_proto *tp, unsigned long base,
+ u32 handle, struct nlattr **tca,
+ unsigned long *arg, bool ovr)
+{
+ struct cls_mall_head *head = rtnl_dereference(tp->root);
+ struct cls_mall_filter *fold = (struct cls_mall_filter *) *arg;
+ struct cls_mall_filter *f;
+ struct nlattr *tb[TCA_MATCHALL_MAX + 1];
+ int err;
+
+ if (!tca[TCA_OPTIONS])
+ return -EINVAL;
+
+ if (head->filter)
+ return -EBUSY;
+
+ if (fold)
+ return -EINVAL;
+
+ err = nla_parse_nested(tb, TCA_MATCHALL_MAX,
+ tca[TCA_OPTIONS], mall_policy);
+ if (err < 0)
+ return err;
+
+ f = kzalloc(sizeof(*f), GFP_KERNEL);
+ if (!f)
+ return -ENOBUFS;
+
+ tcf_exts_init(&f->exts, TCA_MATCHALL_ACT, 0);
+
+ if (!handle)
+ handle = 1;
+ f->handle = handle;
+
+ err = mall_set_parms(net, tp, f, base, tb, tca[TCA_RATE], ovr);
+ if (err)
+ goto errout;
+
+ *arg = (unsigned long) f;
+ rcu_assign_pointer(head->filter, f);
+
+ return 0;
+
+errout:
+ kfree(f);
+ return err;
+}
+
+static int mall_delete(struct tcf_proto *tp, unsigned long arg)
+{
+ struct cls_mall_head *head = rtnl_dereference(tp->root);
+ struct cls_mall_filter *f = (struct cls_mall_filter *) arg;
+
+ RCU_INIT_POINTER(head->filter, NULL);
+ tcf_unbind_filter(tp, &f->res);
+ call_rcu(&f->rcu, mall_destroy_filter);
+ return 0;
+}
+
+static void mall_walk(struct tcf_proto *tp, struct tcf_walker *arg)
+{
+ struct cls_mall_head *head = rtnl_dereference(tp->root);
+ struct cls_mall_filter *f = head->filter;
+
+ if (arg->count < arg->skip)
+ goto skip;
+ if (arg->fn(tp, (unsigned long) f, arg) < 0)
+ arg->stop = 1;
+skip:
+ arg->count++;
+}
+
+static int mall_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
+ struct sk_buff *skb, struct tcmsg *t)
+{
+ struct cls_mall_filter *f = (struct cls_mall_filter *) fh;
+ struct nlattr *nest;
+
+ if (!f)
+ return skb->len;
+
+ t->tcm_handle = f->handle;
+
+ nest = nla_nest_start(skb, TCA_OPTIONS);
+ if (!nest)
+ goto nla_put_failure;
+
+ if (f->res.classid &&
+ nla_put_u32(skb, TCA_MATCHALL_CLASSID, f->res.classid))
+ goto nla_put_failure;
+
+ if (tcf_exts_dump(skb, &f->exts))
+ goto nla_put_failure;
+
+ nla_nest_end(skb, nest);
+
+ if (tcf_exts_dump_stats(skb, &f->exts) < 0)
+ goto nla_put_failure;
+
+ return skb->len;
+
+nla_put_failure:
+ nla_nest_cancel(skb, nest);
+ return -1;
+}
+
+static struct tcf_proto_ops cls_mall_ops __read_mostly = {
+ .kind = "matchall",
+ .classify = mall_classify,
+ .init = mall_init,
+ .destroy = mall_destroy,
+ .get = mall_get,
+ .change = mall_change,
+ .delete = mall_delete,
+ .walk = mall_walk,
+ .dump = mall_dump,
+ .owner = THIS_MODULE,
+};
+
+static int __init cls_mall_init(void)
+{
+ return register_tcf_proto_ops(&cls_mall_ops);
+}
+
+static void __exit cls_mall_exit(void)
+{
+ unregister_tcf_proto_ops(&cls_mall_ops);
+}
+
+module_init(cls_mall_init);
+module_exit(cls_mall_exit);
+
+MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
+MODULE_DESCRIPTION("Match-all classifier");
+MODULE_LICENSE("GPL v2");
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -526,6 +526,16 @@ config NET_CLS_FLOWER
To compile this code as a module, choose M here: the module will
be called cls_flower.
+config NET_CLS_MATCHALL
+ tristate "Match-all classifier"
+ select NET_CLS
+ ---help---
+ If you say Y here, you will be able to classify packets based on
+ nothing. Every packet will match.
+
+ To compile this code as a module, choose M here: the module will
+ be called cls_matchall.
+
config NET_EMATCH
bool "Extended Matches"
select NET_CLS
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_NET_CLS_FLOW) += cls_flow.o
obj-$(CONFIG_NET_CLS_CGROUP) += cls_cgroup.o
obj-$(CONFIG_NET_CLS_BPF) += cls_bpf.o
obj-$(CONFIG_NET_CLS_FLOWER) += cls_flower.o
+obj-$(CONFIG_NET_CLS_MATCHALL) += cls_matchall.o
obj-$(CONFIG_NET_EMATCH) += ematch.o
obj-$(CONFIG_NET_EMATCH_CMP) += em_cmp.o
obj-$(CONFIG_NET_EMATCH_NBYTE) += em_nbyte.o

View File

@@ -1,162 +0,0 @@
From cc809a441d8f2924f785eb863dfa6aef47a25b0b Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 12 Aug 2014 20:49:27 +0200
Subject: [PATCH 30/36] GPIO: add named gpio exports
Signed-off-by: John Crispin <blogic@openwrt.org>
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -23,6 +23,8 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/slab.h>
#include <linux/gpio/machine.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
#include "gpiolib.h"
@@ -450,3 +452,72 @@ void of_gpiochip_remove(struct gpio_chip
gpiochip_remove_pin_ranges(chip);
of_node_put(chip->of_node);
}
+
+#ifdef CONFIG_GPIO_SYSFS
+
+static struct of_device_id gpio_export_ids[] = {
+ { .compatible = "gpio-export" },
+ { /* sentinel */ }
+};
+
+static int of_gpio_export_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *cnp;
+ u32 val;
+ int nb = 0;
+
+ for_each_child_of_node(np, cnp) {
+ const char *name = NULL;
+ int gpio;
+ bool dmc;
+ int max_gpio = 1;
+ int i;
+
+ of_property_read_string(cnp, "gpio-export,name", &name);
+
+ if (!name)
+ max_gpio = of_gpio_count(cnp);
+
+ for (i = 0; i < max_gpio; i++) {
+ unsigned flags = 0;
+ enum of_gpio_flags of_flags;
+
+ gpio = of_get_gpio_flags(cnp, i, &of_flags);
+ if (!gpio_is_valid(gpio))
+ return gpio;
+
+ if (of_flags == OF_GPIO_ACTIVE_LOW)
+ flags |= GPIOF_ACTIVE_LOW;
+
+ if (!of_property_read_u32(cnp, "gpio-export,output", &val))
+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+ else
+ flags |= GPIOF_IN;
+
+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
+ continue;
+
+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
+ gpio_export_with_name(gpio, dmc, name);
+ nb++;
+ }
+ }
+
+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
+
+ return 0;
+}
+
+static struct platform_driver gpio_export_driver = {
+ .driver = {
+ .name = "gpio-export",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(gpio_export_ids),
+ },
+ .probe = of_gpio_export_probe,
+};
+
+module_platform_driver(gpio_export_driver);
+
+#endif
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -122,6 +122,12 @@ static inline int gpio_export(unsigned g
return gpiod_export(gpio_to_desc(gpio), direction_may_change);
}
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
+{
+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
+}
+
static inline int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
{
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -427,6 +427,7 @@ static inline struct gpio_desc *devm_get
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
int gpiod_export_link(struct device *dev, const char *name,
struct gpio_desc *desc);
@@ -434,6 +435,13 @@ void gpiod_unexport(struct gpio_desc *de
#else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
+static inline int _gpiod_export(struct gpio_desc *desc,
+ bool direction_may_change,
+ const char *name)
+{
+ return -ENOSYS;
+}
+
static inline int gpiod_export(struct gpio_desc *desc,
bool direction_may_change)
{
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -544,7 +544,7 @@ static struct class gpio_class = {
*
* Returns zero on success, else an error.
*/
-int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
{
struct gpio_chip *chip;
struct gpiod_data *data;
@@ -604,6 +604,8 @@ int gpiod_export(struct gpio_desc *desc,
offset = gpio_chip_hwgpio(desc);
if (chip->names && chip->names[offset])
ioname = chip->names[offset];
+ if (name)
+ ioname = name;
dev = device_create_with_groups(&gpio_class, chip->dev,
MKDEV(0, 0), data, gpio_groups,
@@ -625,6 +627,12 @@ err_unlock:
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
return status;
}
+EXPORT_SYMBOL_GPL(__gpiod_export);
+
+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
+{
+ return __gpiod_export(desc, direction_may_change, NULL);
+}
EXPORT_SYMBOL_GPL(gpiod_export);
static int match_export(struct device *dev, const void *desc)

View File

@@ -10,7 +10,6 @@ copy_certificates() {
chown root.network /etc/ucentral/*.pem chown root.network /etc/ucentral/*.pem
chmod 0440 root.network /etc/ucentral/*.pem chmod 0440 root.network /etc/ucentral/*.pem
chmod 0400 /etc/ucentral/dev-id chmod 0400 /etc/ucentral/dev-id
[ -f /certificates/restrictions.json ] && cp /certificates/restrictions.json /etc/ucentral/
exit 0 exit 0
} }

View File

@@ -20,6 +20,7 @@ var callReboot = rpc.declare({
expect: { result: 0 } expect: { result: 0 }
}); });
var mapdata = { actions: {}, config: {} }; var mapdata = { actions: {}, config: {} };
return view.extend({ return view.extend({
@@ -44,26 +45,6 @@ return view.extend({
ui.awaitReconnect('192.168.1.1', 'openwrt.lan'); ui.awaitReconnect('192.168.1.1', 'openwrt.lan');
}, },
handleDiagnostics: function(ev) {
return fs.exec('/sbin/diagnostic-bundle').then(function(result) {
var form = E('form', {
method: 'post',
action: L.env.cgi_base + '/cgi-download',
enctype: 'application/x-www-form-urlencoded'
}, [
E('input', { 'type': 'hidden', 'name': 'sessionid', 'value': L.env.sessionid }),
E('input', { 'type': 'hidden', 'name': 'path', 'value': '/tmp/bundle.maverick.tar.gz' }),
E('input', { 'type': 'hidden', 'name': 'filename', 'value': 'bundle.maverick.tar.gz' }),
E('input', { 'type': 'hidden', 'name': 'mimetype', 'value': 'application/gzip' })
]);
document.body.appendChild(form);
form.submit();
form.parentNode.removeChild(form);
});
},
handleSysupgrade: function(ev) { handleSysupgrade: function(ev) {
return ui.uploadFile('/tmp/firmware.bin', ev.target.firstChild) return ui.uploadFile('/tmp/firmware.bin', ev.target.firstChild)
.then(L.bind(function(btn, reply) { .then(L.bind(function(btn, reply) {
@@ -190,16 +171,6 @@ return view.extend({
o.inputtitle = _('Flash image…'); o.inputtitle = _('Flash image…');
o.onclick = L.bind(this.handleSysupgrade, this); o.onclick = L.bind(this.handleSysupgrade, this);
o = s.option(form.SectionValue, 'actions', form.NamedSection, 'actions', 'actions', _('Diagnostic bundle'),
_('Download the default diagnostic bundle from the AP.'));
ss = o.subsection;
o = ss.option(form.Button, 'Diagnostic');
o.inputstyle = 'action important';
o.inputtitle = _('Download Diagnostics');
o.onclick = L.bind(this.handleDiagnostics, this);
return m.render(); return m.render();
}, },

View File

@@ -1,8 +0,0 @@
#!/usr/bin/ucode
push(REQUIRE_SEARCH_PATH, '/usr/share/ucentral/*.uc');
let bundle = require('bundle');
bundle.init('maverick');
include('/usr/share/ucentral/diagnostic.uc', { bundle });
bundle.complete();
system('chmod +r /tmp/bundle.maverick.tar.gz');

View File

@@ -2,12 +2,10 @@
"luci-mod-ucentral": { "luci-mod-ucentral": {
"description": "Grant access to ucentral configuration", "description": "Grant access to ucentral configuration",
"read": { "read": {
"cgi-io": [ "download" ],
"file": { "file": {
"/etc/ucentral/profile.json": [ "read" ], "/etc/ucentral/profile.json": [ "read" ],
"/proc/mounts": [ "read" ], "/proc/mounts": [ "read" ],
"/proc/mtd": [ "read" ], "/proc/mtd": [ "read" ]
"/tmp/bundle.maverick.tar.gz": [ "read" ]
}, },
"ubus": { "ubus": {
"file": [ "read" ], "file": [ "read" ],
@@ -19,7 +17,6 @@
"file": { "file": {
"/etc/ucentral/profile.json": [ "write" ], "/etc/ucentral/profile.json": [ "write" ],
"/sbin/certupdate": [ "exec" ], "/sbin/certupdate": [ "exec" ],
"/sbin/diagnostic-bundle": [ "exec" ],
"/sbin/firstboot -r -y": [ "exec" ], "/sbin/firstboot -r -y": [ "exec" ],
"/sbin/profileupdate": [ "exec" ], "/sbin/profileupdate": [ "exec" ],
"/sbin/sysupgrade -n /tmp/firmware.bin": [ "exec" ], "/sbin/sysupgrade -n /tmp/firmware.bin": [ "exec" ],

View File

@@ -52,6 +52,6 @@ start_service() {
} }
service_started() { service_started() {
ubus -t 2 wait_for atfpolicy ubus -t 10 wait_for atfpolicy
[ $? = 0 ] && reload_service [ $? = 0 ] && reload_service
} }

View File

@@ -152,13 +152,13 @@ radius_forward_gw(char *buf, enum socket_type type)
} }
static int static int
radius_parse(char *buf, unsigned int len, int port, enum socket_type type, int tx) radius_parse(char *buf, int len, int port, enum socket_type type, int tx)
{ {
struct radius_header *hdr = (struct radius_header *) buf; struct radius_header *hdr = (struct radius_header *) buf;
struct radius_tlv *proxy_state = NULL; struct radius_tlv *proxy_state = NULL;
char proxy_state_str[256] = {}; char proxy_state_str[256] = {};
void *avp = hdr->avp; void *avp = hdr->avp;
unsigned int len_orig = ntohs(hdr->len); int len_orig = ntohs(hdr->len);
uint8_t localhost[] = { 0x7f, 0, 0, 1 }; uint8_t localhost[] = { 0x7f, 0, 0, 1 };
if (len_orig != len) { if (len_orig != len) {
@@ -170,10 +170,10 @@ radius_parse(char *buf, unsigned int len, int port, enum socket_type type, int t
len -= sizeof(*hdr); len -= sizeof(*hdr);
while (len >= sizeof(struct radius_tlv)) { while (len > 0) {
struct radius_tlv *tlv = (struct radius_tlv *)avp; struct radius_tlv *tlv = (struct radius_tlv *)avp;
if (len < tlv->len || tlv->len < sizeof(*tlv)) { if (len < tlv->len) {
ULOG_ERR("invalid TLV length\n"); ULOG_ERR("invalid TLV length\n");
return -1; return -1;
} }
@@ -312,7 +312,7 @@ sock_recv(struct uloop_fd *u, unsigned int events)
inet_ntop(AF_INET, &sin.sin_addr, addr_str, sizeof(addr_str)); inet_ntop(AF_INET, &sin.sin_addr, addr_str, sizeof(addr_str));
printf("RX: src:%s:%d, len=%d\n", addr_str, sin.sin_port, len); printf("RX: src:%s:%d, len=%d\n", addr_str, sin.sin_port, len);
radius_parse(buf, (unsigned int)len, sin.sin_port, sock->type, 1); radius_parse(buf, len, sin.sin_port, sock->type, 1);
} while (1); } while (1);
} }

View File

@@ -3,15 +3,11 @@
[ "${INTERFACE:0:4}" == "wlan" ] || exit 0 [ "${INTERFACE:0:4}" == "wlan" ] || exit 0
[ "$ACTION" == remove ] && { [ "$ACTION" == remove ] && {
[ -f /tmp/run/hostapd-cli-$INTERFACE.pid ] || return ratelimit deliface $INTERFACE
kill "$(cat /tmp/run/hostapd-cli-$INTERFACE.pid)"
rm /tmp/run/hostapd-cli-$INTERFACE.pid
exit 0 exit 0
} }
[ "$ACTION" == add ] && { [ "$ACTION" == add ] && {
[ -f /tmp/run/hostapd-cli-$INTERFACE.pid ] && return ratelimit waitiface $INTERFACE &
touch /tmp/run/hostapd-cli-$INTERFACE.pid
/usr/libexec/ratelimit-wait.sh $INTERFACE &
exit 0 exit 0
} }

View File

@@ -1,37 +0,0 @@
#!/bin/sh /etc/rc.common
START=80
USE_PROCD=1
PROG=/usr/bin/ratelimit
add_rate() {
local cfg="$1"
config_get ssid "$cfg" ssid
config_get ingress "$cfg" ingress
config_get egress "$cfg" egress
ubus call ratelimit defaults_set '{"name": "'$ssid'", "rate_ingress": "'$ingress'mbit", "rate_egress": "'$egress'mbit" }'
}
reload_service() {
logger ratelimit reload
config_load ratelimit
config_foreach add_rate rate
}
service_triggers() {
procd_add_reload_trigger ratelimit
}
start_service() {
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn
procd_close_instance
}
service_started() {
ubus -t 10 wait_for ratelimit
[ $? = 0 ] && reload_service
}

View File

@@ -1,337 +1,174 @@
#!/usr/bin/env ucode #!/bin/sh
'use strict';
import { basename, popen } from 'fs'; . /lib/functions.sh
import * as ubus from 'ubus';
import * as uloop from 'uloop';
let defaults = {}; wrapper() {
let devices = {}; echo calling $*
$*
function cmd(command, ignore_error) {
// if (ignore_error)
// command += "> /dev/null 2>&1";
warn(`> ${command}\n`);
let rc = system(command);
return ignore_error || rc == 0;
} }
function qdisc_add_leaf(iface, id, opts) { TC() {
opts ??= ""; wrapper tc $*
return cmd(`tc class replace dev ${iface} parent 1:1 classid 1:${id} htb rate 1mbit ${opts} burst 2k prio 1`) &&
cmd(`tc qdisc replace dev ${iface} parent 1:${id} handle ${id}: fq_codel flows 128 limit 800 quantum 300 noecn`);
} }
function qdisc_del_leaf(iface, id) { IP() {
cmd(`tc class del dev ${iface} parent 1:1 classid 1:${id}`, true); wrapper ip $*
} }
function qdisc_add(iface) { get_id() {
return cmd(`tc qdisc add dev ${iface} root handle 1: htb default 2`) && addr=$1
cmd(`tc class add dev ${iface} parent 1: classid 1:1 htb rate 1000mbit burst 6k`) && hashval="0x$(echo "$addr" | md5sum | head -c8)"
qdisc_add_leaf(iface, 2, "ceil 1000mbit"); mask=0x4ff
echo $(($hashval & $mask))
} }
function qdisc_del(iface) { delclient() {
cmd(`tc qdisc del dev ${iface} root`, true); local ifb=rateifb$1
local iface=$1
local mac=$2
local id=$3
logger "ratelimit: delete old client entries $1 $2"
id=$(get_id ${mac//:})
TC filter del dev $iface protocol all parent 1: prio 1 u32 match ether dst $mac flowid 1:$id
TC filter del dev $ifb protocol all parent 1: prio 1 u32 match ether src $mac flowid 1:$id
} }
function ifb_dev(iface) { ingress=0
return "ifb-" + iface; egress=0
getrate() {
config_get ssid $1 ssid
[ "$ssid" == "$2" ] || return
config_get ingress $1 ingress
config_get egress $1 egress
} }
function ifb_add(iface, ifbdev) { addclient() {
return cmd(`ip link add ${ifbdev} type ifb`) && local ifb=rateifb$1
cmd(`ip link set ${ifbdev} up`) && local iface=$1
cmd(`tc qdisc add dev ${iface} clsact`, true) && local mac=$2
cmd(`tc filter add dev ${iface} ingress protocol all prio 512 matchall action mirred egress redirect dev ${ifbdev}`); local ssid=$(cat /tmp/ratelimit.$iface)
}
function ifb_del(iface, ifbdev) { egress=$3
cmd(`tc filter del dev ${iface} ingress protocol all prio 512`); ingress=$4
cmd(`ip link set ${ifbdev} down`, true);
cmd(`ip link del ${ifbdev}`, true);
}
function macfilter_add(iface, id, type, mac) { logger "ratelimit: adding client"
return cmd(`tc filter add dev ${iface} protocol all parent 1: prio 1 handle 800::${id} u32 match ether ${type} ${mac} flowid 1:${id}`);
}
function macfilter_del(iface, id) { [ "$egress" -eq 0 -o $ingress -eq 0 ] && {
cmd(`tc filter del dev ${iface} protocol all parent 1: prio 1 handle 800::${id} u32`, true); config_load ratelimit
} config_foreach getrate rate $ssid
function linux_client_del(device, client) {
let ifbdev = ifb_dev(device.name);
let id = client.id + 3;
macfilter_del(device.name, id);
qdisc_del_leaf(device.name, id);
macfilter_del(ifbdev, id);
qdisc_del_leaf(ifbdev, id);
}
function linux_client_set(device, client) {
let ifbdev = ifb_dev(device.name);
let id = client.id + 3;
linux_client_del(device, client);
let ret = qdisc_add_leaf(device.name, id, `ceil ${client.data.rate_egress}`) &&
macfilter_add(device.name, id, "dst", client.address) &&
qdisc_add_leaf(ifbdev, id, `ceil ${client.data.rate_ingress}`) &&
macfilter_add(ifbdev, id, "src", client.address);
if (!ret)
linux_client_del(device, client);
return ret;
}
let ops = {
device: {
add: function(name) {
let ifbdev = ifb_dev(name);
qdisc_del(name);
ifb_del(name, ifbdev);
let ret = qdisc_add(name) &&
ifb_add(name, ifbdev) &&
qdisc_add(ifbdev);
if (!ret) {
qdisc_del(name);
ifb_del(name, ifbdev);
}
return ret;
},
remove: function(name) {
let ifbdev = ifb_dev(name);
qdisc_del(name);
ifb_del(name, ifbdev);
}
},
client: {
set: function(device, client) {
return linux_client_set(device, client);
},
remove: function(device, client) {
linux_client_del(device, client);
}
}
};
function get_device(devices, name) {
let device = devices[name];
if (device)
return device;
if (!ops.device.add(name))
return null;
device = {
name: name,
clients: {},
client_order: [],
};
devices[name] = device;
return device;
}
function del_device(name) {
if (!devices[name])
return;
ops.device.remove(name);
delete devices[name];
}
function get_free_idx(list) {
for (let i = 0; i < length(list); i++)
if (list[i] == null)
return i;
return length(list);
}
function del_client(device, address) {
let client = device.clients[address];
if (!client)
return false;
delete device.clients[address];
device.client_order[client.id] = null;
ops.client.remove(device, client);
return true;
}
function get_client(device, address) {
let client = device.clients[address];
if (client)
return client;
let i = get_free_idx(device.client_order);
client = {};
client.address = address;
client.id = i;
client.data = {};
device.clients[address] = client;
device.client_order[i] = client;
return client;
}
function set_client(device, client, data) {
let update = false;
for (let key in data) {
if (client.data[key] != data[key])
update = true;
client.data[key] = data[key];
} }
if (update && !ops.client.set(device, client)) { [ "$egress" -eq 0 -o $ingress -eq 0 ] && {
del_client(device, client.address); logger "ratelimit: no valid rates"
return false; exit 1
} }
return true; local id=$(get_id ${mac//:})
logger "ratelimit: add new client entries for $1 $2 $egress $ingress"
TC class add dev $iface parent 1:1 classid 1:$id htb rate 1mbit ceil ${egress}mbit burst 2k prio 1
TC qdisc add dev $iface parent 1:$id handle $id: sfq perturb 10
TC filter add dev $iface protocol all parent 1: prio 1 u32 match ether dst $mac flowid 1:$id
TC class add dev $ifb parent 1:1 classid 1:$id htb rate 1mbit ceil ${ingress}mbit burst 2k prio 1
TC filter add dev $ifb protocol all parent 1: prio 1 u32 match ether src $mac flowid 1:$id
} }
function run_service() { deliface() {
let uctx = ubus.connect(); local ifb=rateifb$1
local iface=$1
uctx.publish("ratelimit", { [ -d /sys/class/net/$ifb/ ] || return 0
defaults_set: {
call: function(req) {
let r_i = req.args.rate_ingress ?? req.args.rate;
let r_e = req.args.rate_egress ?? req.args.rate;
let name = req.args.name;
if (!name || !r_i || !r_e) logger "ratelimit: deleting old iface settings"
return ubus.STATUS_INVALID_ARGUMENT;
defaults[name] = [ r_e, r_i ]; IP link set $ifb down
IP link del $ifb
return 0; TC qdisc del dev $iface root &2> /dev/null
},
args: {
name:"",
rate:"",
rate_ingress:"",
rate_egress:"",
}
},
client_set: {
call: function(req) {
let r_i = req.args.rate_ingress ?? req.args.rate;
let r_e = req.args.rate_egress ?? req.args.rate;
if (req.args.defaults && defaults[req.args.defaults]) { rm -f /tmp/ratelimit.$iface
let def = defaults[req.args.defaults]; [ -f /tmp/run/hostapd-cli-$iface.pid ] && kill "$(cat /tmp/run/hostapd-cli-$iface.pid)"
r_e ??= def[0];
r_i ??= def[1];
}
if (!req.args.device || !req.args.address || !r_i || !r_e)
return ubus.STATUS_INVALID_ARGUMENT;
let device = get_device(devices, req.args.device);
if (!device)
return ubus.STATUS_INVALID_ARGUMENT;
let client = get_client(device, req.args.address);
if (!client)
return ubus.STATUS_INVALID_ARGUMENT;
let data = {
rate_ingress: r_i,
rate_egress: r_e
};
if (!set_client(device, client, data))
return ubus.STATUS_UNKNOWN_ERROR;
return 0;
},
args: {
device:"",
defaults:"",
address:"",
rate:"",
rate_ingress:"",
rate_egress:"",
}
},
client_delete: {
call: function(req) {
if (!req.args.address)
return ubus.STATUS_INVALID_ARGUMENT;
if (req.args.device) {
let device = devices[req.args.device];
if (!device)
return ubus.STATUS_NOT_FOUND;
if (!del_client(device, req.args.address))
return ubus.STATUS_NOT_FOUND;
} else {
for (let dev in devices) {
let device = devices[dev];
del_client(device, req.args.address);
}
}
return 0;
},
args: {
device:"",
address:"",
}
},
device_delete: {
call: function(req) {
let name = req.args.device;
if (!name)
return ubus.STATUS_INVALID_ARGUMENT;
if (!devices[name])
return ubus.STATUS_NOT_FOUND;
del_device(name);
return 0;
},
args: {
device:"",
}
}
});
try {
uloop.run();
} catch (e) {
warn(`Error: ${e}\n${e.stacktrace[0].context}`);
}
for (let dev in devices) {
del_device(dev);
}
} }
uloop.init(); found=0
run_service(); find_ssid() {
uloop.done(); local ssid
config_get ssid $1 ssid
[ "$ssid" == "$2" ] || return
found=1
}
addiface() {
local ifb=rateifb$1
local iface=$1
local ssid
[ -f /tmp/ratelimit.$iface -o -d /sys/class/net/$ifb/ ] && {
return 0
}
echo -n startup > /tmp/ratelimit.$iface
sleep 2
ssid=$(ubus call hostapd.$iface get_status | jsonfilter -e '@.ssid')
[ -z "$ssid" ] && {
rm /tmp/ratelimit.$iface
logger "ratelimit: failed to lookup ssid"
exit 1
}
config_load ratelimit
config_foreach find_ssid rate $ssid
[ "$found" -eq 0 ] && {
rm /tmp/ratelimit.$iface
exit 0
}
logger "ratelimit: adding new iface settings"
echo -n $ssid > /tmp/ratelimit.$iface
IP link add name $ifb type ifb
IP link set $ifb up
sleep 1
TC qdisc add dev $iface root handle 1: htb default 30
TC class add dev $iface parent 1: classid 1:1 htb rate 1000mbit burst 6k
TC qdisc add dev $iface ingress
TC filter add dev $iface parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev $ifb
TC qdisc add dev $ifb root handle 1: htb default 10
TC class add dev $ifb parent 1: classid 1:1 htb rate 100mbit
hostapd_cli -a /usr/libexec/ratelimit.sh -i $iface -P /tmp/run/hostapd-cli-$iface.pid -B
for sta in $(ubus call wifi station | jsonfilter -e '@[*][*].mac'); do
addclient $iface $sta
done
}
waitiface() {
local iface=$1
ubus -t 120 wait_for hostapd.$1
[ $? -eq 0 ] || exit 0
addiface $iface
}
flush() {
for a in `ls /sys/class/net/ | grep rateifb`; do
deliface ${a:7}
done
}
cmd=$1
shift
$cmd $@

View File

@@ -1,4 +0,0 @@
#!/bin/sh
[ -f /tmp/run/hostapd-cli-$1.pid ] && kill "$(cat /tmp/run/hostapd-cli-$1.pid)"
ubus -t 120 wait_for hostapd.$1
[ $? = 0 ] && hostapd_cli -a /usr/libexec/ratelimit.sh -i $1 -P /tmp/run/hostapd-cli-$1.pid -B

View File

@@ -2,16 +2,9 @@
case $2 in case $2 in
AP-STA-CONNECTED) AP-STA-CONNECTED)
[ $4 = 0 -o $5 = 0 ] && { ratelimit addclient $1 $3 $4 $5
ubus call ratelimit client_set '{"device": "'$1'", "address": "'$3'", "defaults": "'$(ubus call wifi iface | jsonfilter -e "@['$1'].ssid")'" }'
logger ratelimit addclient $1 $3 $ssid
return
}
ubus call ratelimit client_set '{"device": "'$1'", "address": "'$3'", "rate_ingress": "'$4'mbit", "rate_egress": "'$5'mbit" }'
logger ratelimit addclient $1 $3 $4 $5
;; ;;
AP-STA-DISCONNECTED) AP-STA-DISCONNECTED)
ubus call ratelimit client_delete '{ "address": "'$3'" }' ratelimit delclient $1 $3
logger ratelimit delclient $3
;; ;;
esac esac

View File

@@ -33,18 +33,6 @@ static uint32_t client_gettime(void)
return ts.tv_sec; return ts.tv_sec;
} }
static bool client_is_active(const uint8_t *mac)
{
struct interface *iface;
avl_for_each_element(&interfaces, iface, node) {
if (avl_find(&iface->clients, mac))
return true;
}
return false;
}
static void client_gc(struct uloop_timeout *t) static void client_gc(struct uloop_timeout *t)
{ {
struct cache_entry *c, *tmp; struct cache_entry *c, *tmp;
@@ -53,11 +41,6 @@ static void client_gc(struct uloop_timeout *t)
avl_for_each_element_safe(&cache, c, node, tmp) { avl_for_each_element_safe(&cache, c, node, tmp) {
uint32_t diff; uint32_t diff;
if (client_is_active(c->macaddr)) {
c->time = now;
continue;
}
diff = now - c->time; diff = now - c->time;
if (diff < CACHE_TIMEOUT) if (diff < CACHE_TIMEOUT)
continue; continue;
@@ -82,7 +65,6 @@ static void __client_free(struct interface *iface, struct client *cl)
avl_delete(&iface->client_ids, &cl->id_node); avl_delete(&iface->client_ids, &cl->id_node);
avl_delete(&iface->clients, &cl->node); avl_delete(&iface->clients, &cl->node);
kvlist_free(&cl->kvdata); kvlist_free(&cl->kvdata);
free(cl->device);
spotfilter_bpf_set_client(iface, &cl->key, NULL); spotfilter_bpf_set_client(iface, &cl->key, NULL);
free(cl); free(cl);
} }
@@ -115,8 +97,7 @@ static void client_set_id(struct interface *iface, struct client *cl, const char
} }
int client_set(struct interface *iface, const void *addr, const char *id, int client_set(struct interface *iface, const void *addr, const char *id,
int state, int dns_state, int accounting, struct blob_attr *data, int state, int dns_state, int accounting, struct blob_attr *data)
const char *device, bool flush)
{ {
struct cache_entry *c; struct cache_entry *c;
struct blob_attr *cur; struct blob_attr *cur;
@@ -161,23 +142,12 @@ int client_set(struct interface *iface, const void *addr, const char *id,
kvlist_set(&cl->kvdata, blobmsg_name(cur), cur); kvlist_set(&cl->kvdata, blobmsg_name(cur), cur);
} }
if (device) {
free(cl->device);
cl->device = strdup(device);
}
if (state >= 0) if (state >= 0)
cl->data.cur_class = state; cl->data.cur_class = state;
if (dns_state >= 0) if (dns_state >= 0)
cl->data.dns_class = dns_state; cl->data.dns_class = dns_state;
if (accounting >= 0) if (accounting >= 0)
cl->data.flags = accounting; cl->data.flags = accounting;
if (flush) {
kvlist_free(&cl->kvdata);
cl->data.packets_ul = 0;
cl->data.packets_dl = 0;
cl->data.bytes_ul = 0;
cl->data.bytes_dl = 0;
}
spotfilter_bpf_set_client(iface, &cl->key, &cl->data); spotfilter_bpf_set_client(iface, &cl->key, &cl->data);
if (new_client) if (new_client)

View File

@@ -17,12 +17,10 @@ struct client {
struct spotfilter_client_key key; struct spotfilter_client_key key;
struct spotfilter_client_data data; struct spotfilter_client_data data;
char *device;
}; };
int client_set(struct interface *iface, const void *addr, const char *id, int client_set(struct interface *iface, const void *addr, const char *id,
int state, int dns_state, int accounting, struct blob_attr *data, int state, int dns_state, int accounting, struct blob_attr *data);
const char *device, bool flush);
void client_free(struct interface *iface, struct client *cl); void client_free(struct interface *iface, struct client *cl);
void client_set_ipaddr(const void *mac, const void *addr, bool ipv6); void client_set_ipaddr(const void *mac, const void *addr, bool ipv6);
void client_init_interface(struct interface *iface); void client_init_interface(struct interface *iface);

View File

@@ -32,6 +32,12 @@ void interface_free(struct interface *iface)
free(iface); free(iface);
} }
static inline const char *
device_name(struct device *dev)
{
return dev->node.avl.key;
}
static void static void
interface_check_device(struct interface *iface, struct device *dev) interface_check_device(struct interface *iface, struct device *dev)
{ {

View File

@@ -64,11 +64,6 @@ static inline const char *interface_name(struct interface *iface)
return iface->node.key; return iface->node.key;
} }
static inline const char *device_name(struct device *dev)
{
return dev->node.avl.key;
}
void interface_add(const char *name, struct blob_attr *config, void interface_add(const char *name, struct blob_attr *config,
struct blob_attr *devices); struct blob_attr *devices);
void interface_free(struct interface *iface); void interface_free(struct interface *iface);

View File

@@ -147,7 +147,6 @@ nl80211_device_update(struct interface *iface, struct device *dev)
nl_send_auto_complete(genl, msg); nl_send_auto_complete(genl, msg);
nlmsg_free(msg); nlmsg_free(msg);
nl_wait_for_ack(genl);
} }
static void static void
@@ -156,12 +155,14 @@ nl80211_interface_update(struct interface *iface)
struct client *cl, *tmp; struct client *cl, *tmp;
struct device *dev; struct device *dev;
if (!iface->client_autoremove)
return;
avl_for_each_element_safe(&iface->clients, cl, node, tmp) { avl_for_each_element_safe(&iface->clients, cl, node, tmp) {
if (cl->idle++ < iface->client_timeout) if (cl->idle++ < iface->client_timeout)
continue; continue;
if (iface->client_autoremove) client_free(iface, cl);
client_free(iface, cl);
} }
vlist_for_each_element(&iface->devices, dev, node) vlist_for_each_element(&iface->devices, dev, node)
@@ -217,7 +218,7 @@ found:
if (cl) if (cl)
cl->idle = 0; cl->idle = 0;
else if (iface->client_autocreate) else if (iface->client_autocreate)
client_set(iface, addr, NULL, -1, -1, -1, NULL, device_name(dev), false); client_set(iface, addr, NULL, -1, -1, -1, NULL);
return NL_SKIP; return NL_SKIP;
} }
@@ -248,7 +249,6 @@ int spotfilter_nl80211_init(void)
genl_cb = nl_cb_alloc(NL_CB_DEFAULT); genl_cb = nl_cb_alloc(NL_CB_DEFAULT);
nl_cb_set(genl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_set(genl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
nl_cb_set(genl_cb, NL_CB_VALID, NL_CB_CUSTOM, valid_msg, NULL); nl_cb_set(genl_cb, NL_CB_VALID, NL_CB_CUSTOM, valid_msg, NULL);
nl_socket_set_cb(genl, genl_cb);
genl_fd.fd = nl_socket_get_fd(genl); genl_fd.fd = nl_socket_get_fd(genl);
genl_fd.cb = nl80211_sock_cb; genl_fd.cb = nl80211_sock_cb;

View File

@@ -158,9 +158,9 @@ int spotfilter_out(struct __sk_buff *skb)
return TC_ACT_UNSPEC; return TC_ACT_UNSPEC;
cl = bpf_map_lookup_elem(&client, eth->h_dest); cl = bpf_map_lookup_elem(&client, eth->h_dest);
if (cl && (cl->flags & SPOTFILTER_CLIENT_F_ACCT_DL)) { if (cl) {
cl->packets_dl++; if (cl->flags & SPOTFILTER_CLIENT_F_ACCT_DL)
cl->bytes_dl += skb->len; cl->bytes_dl += skb->len;
} }
skb_parse_vlan(&info); skb_parse_vlan(&info);
@@ -204,10 +204,8 @@ int spotfilter_in(struct __sk_buff *skb)
cl = bpf_map_lookup_elem(&client, eth->h_source); cl = bpf_map_lookup_elem(&client, eth->h_source);
if (cl) { if (cl) {
cldata = *cl; cldata = *cl;
if (cl->flags & SPOTFILTER_CLIENT_F_ACCT_UL) { if (cl->flags & SPOTFILTER_CLIENT_F_ACCT_UL)
cl->packets_ul++;
cl->bytes_ul += skb->len; cl->bytes_ul += skb->len;
}
} }
has_vlan = !!skb_parse_vlan(&info); has_vlan = !!skb_parse_vlan(&info);

View File

@@ -19,8 +19,6 @@ struct spotfilter_client_data {
uint8_t dns_class; uint8_t dns_class;
uint8_t flags; uint8_t flags;
uint64_t packets_ul;
uint64_t packets_dl;
uint64_t bytes_ul; uint64_t bytes_ul;
uint64_t bytes_dl; uint64_t bytes_dl;
}; };

View File

@@ -88,7 +88,6 @@ enum {
CLIENT_ATTR_DNS_STATE, CLIENT_ATTR_DNS_STATE,
CLIENT_ATTR_ACCOUNTING, CLIENT_ATTR_ACCOUNTING,
CLIENT_ATTR_DATA, CLIENT_ATTR_DATA,
CLIENT_ATTR_FLUSH,
__CLIENT_ATTR_MAX __CLIENT_ATTR_MAX
}; };
@@ -100,7 +99,6 @@ static const struct blobmsg_policy client_policy[__CLIENT_ATTR_MAX] = {
[CLIENT_ATTR_DNS_STATE] = { "dns_state", BLOBMSG_TYPE_INT32 }, [CLIENT_ATTR_DNS_STATE] = { "dns_state", BLOBMSG_TYPE_INT32 },
[CLIENT_ATTR_ACCOUNTING] = { "accounting", BLOBMSG_TYPE_ARRAY }, [CLIENT_ATTR_ACCOUNTING] = { "accounting", BLOBMSG_TYPE_ARRAY },
[CLIENT_ATTR_DATA] = { "data", BLOBMSG_TYPE_TABLE }, [CLIENT_ATTR_DATA] = { "data", BLOBMSG_TYPE_TABLE },
[CLIENT_ATTR_FLUSH] = { "flush", BLOBMSG_TYPE_BOOL },
}; };
static int static int
@@ -178,7 +176,6 @@ client_ubus_update(struct ubus_context *ctx, struct ubus_object *obj,
const char *id = NULL; const char *id = NULL;
int state = -1, dns_state = -1; int state = -1, dns_state = -1;
int accounting = -1; int accounting = -1;
bool flush = false;
int ret; int ret;
ret = client_ubus_init(msg, tb, &iface, &addr, &id, &cl); ret = client_ubus_init(msg, tb, &iface, &addr, &id, &cl);
@@ -206,11 +203,8 @@ client_ubus_update(struct ubus_context *ctx, struct ubus_object *obj,
if (!addr) if (!addr)
return UBUS_STATUS_INVALID_ARGUMENT; return UBUS_STATUS_INVALID_ARGUMENT;
if (tb[CLIENT_ATTR_FLUSH])
flush = blobmsg_get_bool(tb[CLIENT_ATTR_FLUSH]);
client_set(iface, addr, id, state, dns_state, accounting, client_set(iface, addr, id, state, dns_state, accounting,
tb[CLIENT_ATTR_DATA], NULL, flush); tb[CLIENT_ATTR_DATA]);
return 0; return 0;
} }
@@ -247,10 +241,8 @@ static void client_dump(struct interface *iface, struct client *cl)
spotfilter_bpf_get_client(iface, &cl->key, &cl->data); spotfilter_bpf_get_client(iface, &cl->key, &cl->data);
if (cl->device) if (iface->client_autoremove)
blobmsg_add_string(&b, "device", cl->device); blobmsg_add_u32(&b, "idle", cl->idle);
blobmsg_add_u32(&b, "idle", cl->idle);
blobmsg_add_u32(&b, "state", cl->data.cur_class); blobmsg_add_u32(&b, "state", cl->data.cur_class);
blobmsg_add_u32(&b, "dns_state", cl->data.dns_class); blobmsg_add_u32(&b, "dns_state", cl->data.dns_class);
@@ -289,8 +281,6 @@ static void client_dump(struct interface *iface, struct client *cl)
interface_dump_action(&b, iface, cl->data.dns_class); interface_dump_action(&b, iface, cl->data.dns_class);
blobmsg_close_table(&b, c); blobmsg_close_table(&b, c);
blobmsg_add_u64(&b, "packets_ul", cl->data.packets_ul);
blobmsg_add_u64(&b, "packets_dl", cl->data.packets_dl);
blobmsg_add_u64(&b, "bytes_ul", cl->data.bytes_ul); blobmsg_add_u64(&b, "bytes_ul", cl->data.bytes_ul);
blobmsg_add_u64(&b, "bytes_dl", cl->data.bytes_dl); blobmsg_add_u64(&b, "bytes_dl", cl->data.bytes_dl);
} }

View File

@@ -4,10 +4,10 @@ PKG_NAME:=ucentral-client
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-client.git PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-client.git
PKG_MIRROR_HASH:=8e53167e08d36e43ad00819f3bbe882f6957e995f075fa37141b3e8944f3688b PKG_MIRROR_HASH:=c2f41ed2506e3cc1a31c9180d567e68a39c30cae0c4421ca1dc8b58e82ab3ed1
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2022-06-22 PKG_SOURCE_DATE:=2022-06-22
PKG_SOURCE_VERSION:=5f69da72973409cc63b9991e4c183f8deb5ab0a9 PKG_SOURCE_VERSION:=154e31dfffba8733895ed2cf87433809b0d19b03
PKG_LICENSE:=BSD-3-Clause PKG_LICENSE:=BSD-3-Clause
PKG_MAINTAINER:=John Crispin <john@phrozen.org> PKG_MAINTAINER:=John Crispin <john@phrozen.org>

View File

@@ -4,11 +4,10 @@ PKG_NAME:=ucentral-schema
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-schema.git PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-schema.git
PKG_MIRROR_HASH:=b1bba8db08a4a1eb4b22500e0598c7940bbf51109add1123bd14e4c14e1ee5be PKG_MIRROR_HASH:=7f11e36e1cb10104bcde0ba0e288f2487fb894a6471605d4dee1460b5be379e0
PKG_MIRROR_HASH:=7dc3e99b5b5937b230a465486fa4ac0f6a25ce2e6d6adf8c6999a32408cd293d
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2022-05-29 PKG_SOURCE_DATE:=2022-05-29
PKG_SOURCE_VERSION:=4278dfb73a5c59dbc8a97b8fd53f0c999e95d6ba PKG_SOURCE_VERSION:=55b8272c9cc4500f813f5f1cccdcbb14725b595b
PKG_MAINTAINER:=John Crispin <john@phrozen.org> PKG_MAINTAINER:=John Crispin <john@phrozen.org>
PKG_LICENSE:=BSD-3-Clause PKG_LICENSE:=BSD-3-Clause

View File

@@ -96,7 +96,6 @@
"auth-server": "radius.hotspotsystem.com", "auth-server": "radius.hotspotsystem.com",
"auth-port": 1812, "auth-port": 1812,
"auth-secret": "hotsys123", "auth-secret": "hotsys123",
"final-redirect-url": "uam",
"walled-garden-fqdn": [ "walled-garden-fqdn": [
"*.google.com", "telecominfraproject.com", "customer.hotspotsystem.com" "*.google.com", "telecominfraproject.com", "customer.hotspotsystem.com"
] ]

View File

@@ -1,138 +0,0 @@
{
"interfaces": [
{
"name": "WAN-GRE",
"role": "upstream",
"services": [
"wifi-steering"
],
"ssids": [
{
"bss-mode": "ap",
"disassoc-low-ack": true,
"encryption": {
"proto": "none"
},
"hidden-ssid": false,
"isolate-clients": true,
"maximum-clients": 64,
"name": "..izzi WiFi",
"services": [
"dhcp-snooping"
],
"wifi-bands": [
"2G",
"5G"
]
},
],
"tunnel": {
"peer-address": "2405:200:802:600:61::2",
"proto": "gre6"
}
},
{
"ethernet": [
{
"select-ports": [
"WAN*"
]
}
],
"ipv4": {
"addressing": "dynamic"
},
"name": "WAN",
"role": "upstream",
"ssids": []
}
],
"metrics": {
"dhcp-snooping": {
"filters": [
"ack",
"discover",
"offer",
"request",
"solicit",
"reply",
"renew"
]
},
"health": {
"interval": 60
},
"statistics": {
"interval": 60,
"types": [
"ssids",
"lldp",
"clients"
]
},
"wifi-frames": {
"filters": [
"probe",
"auth",
"assoc",
"disassoc",
"deauth",
"local-deauth",
"inactive-deauth",
"key-mismatch",
"beacon-report",
"radar-detected"
]
}
},
"radios": [
{
"band": "2G",
"bandwidth": 20,
"beacon-interval": 100,
"channel": "auto",
"channel-mode": "VHT",
"channel-width": 20,
"country": "CA",
"dtim-period": 2,
"maximum-clients": 64,
"mimo": "2x2",
"rates": {
"beacon": 6000,
"multicast": 24000
},
"require-mode": "VHT",
"tx-power": 22
},
{
"band": "5G",
"bandwidth": 20,
"beacon-interval": 100,
"channel": "auto",
"channel-mode": "VHT",
"channel-width": 40,
"country": "CA",
"dtim-period": 2,
"maximum-clients": 64,
"mimo": "2x2",
"rates": {
"beacon": 6000,
"multicast": 24000
},
"require-mode": "VHT",
"tx-power": 22
}
],
"services": {
"wifi-steering": {
"assoc-steering": true,
"auto-channel": false,
"load-kick-threshold": 80,
"mode": "local",
"required-probe-snr": -75,
"required-roam-snr": -70,
"required-snr": 0
}
},
"uuid": 1660159074
}

View File

@@ -1,89 +0,0 @@
{
"uuid": 2,
"radios": [
{
"band": "2G",
"country": "CA",
"channel-mode": "HE",
"channel-width": 80,
"channel": 32
}
],
"interfaces": [
{
"name": "WAN",
"role": "upstream",
"services": [ "lldp" ],
"ethernet": [
{
"select-ports": [
"WAN*"
]
}
],
"ipv4": {
"addressing": "dynamic"
},
"ssids": [
{
"name": "OpenWifi",
"wifi-bands": [
"2G"
],
"bss-mode": "ap",
"encryption": {
"proto": "psk2",
"key": "OpenWifi",
"ieee80211w": "optional"
},
"quality-thresholds" : {
"probe-request-rssi": -35,
"assoctiation-request-rssi": -35,
"client-kick-rssi": -45,
"client-kick-ban-time": 60
}
}
]
},
{
"name": "LAN",
"role": "downstream",
"services": [ "ssh", "lldp" ],
"ethernet": [
{
"select-ports": [
"LAN*"
]
}
],
"ipv4": {
"addressing": "static",
"subnet": "192.168.1.1/24",
"dhcp": {
"lease-first": 10,
"lease-count": 100,
"lease-time": "6h"
}
}
}
],
"metrics": {
"statistics": {
"interval": 120,
"types": [ "ssids", "lldp", "clients" ]
},
"health": {
"interval": 120
}
},
"services": {
"lldp": {
"describe": "uCentral",
"location": "universe"
},
"ssh": {
"port": 22
}
}
}

View File

@@ -1,16 +0,0 @@
bundle.wifi();
let paths = [
[ 'network.wireless', 'status' ],
[ 'network.device', 'status' ],
[ 'network.interface', 'dump' ],
[ 'log', 'read', { stream: false } ],
];
for (let path in paths)
bundle.ubus(path[0], path[1], path[2]);
for (let config in [ 'network', 'wireless', 'dhcp', 'firewall', 'system' ])
bundle.uci(config);
for (let cmd in [ "route", "ifconfig", "logread" ])
bundle.shell(cmd);

View File

@@ -1,64 +0,0 @@
push(REQUIRE_SEARCH_PATH, '/usr/share/ucentral/*.uc');
let ubus = require('ubus').connect();
let uci = require('uci').cursor();
let fs = require('fs');
let w_iface = require('wifi.iface');
let w_sta = require('wifi.station');
return {
init: function(id) {
this.id = id || 0;
this.path = `/tmp/bundle.${this.id}/`;
fs.mkdir(this.path);
},
complete: function() {
if (!this.path)
return;
system(`tar cfz /tmp/bundle.${this.id}.tar.gz ${this.path}`);
system(`rm -r ${this.path}`);
},
add: function(name, data) {
if (!this.path)
return;
let file = fs.open(this.path + name, 'w');
file.write(data);
file.close();
},
ubus: function(object, method, args) {
if (!object || !method)
return;
let data = ubus.call(object, method, args || {});
this.add(`ubus-${object}:${method}`, data);
},
uci: function(config, section) {
if (!config)
return;
let data = uci.get_all(config, section) || {};
let name = `uci-${config}` + (section ? `.${section}` : '');
this.add(name, data);
},
wifi: function() {
this.add('wifi-iface', w_iface);
this.add('wifi-station', w_sta);
},
shell: function(name, command) {
if (!command)
command = name;
let fp = fs.popen(command);
let data = fp.read('all');
fp.close();
this.add(`shell-${name}`, data);
},
};

View File

@@ -306,6 +306,4 @@ VALUE Add-Port-To-IP-Address Yes 1
#$INCLUDE /etc/radcli/dictionary.microsoft #$INCLUDE /etc/radcli/dictionary.microsoft
#$INCLUDE /etc/radcli/dictionary.roaringpenguin #$INCLUDE /etc/radcli/dictionary.roaringpenguin
$INCLUDE /etc/radcli/dictionary.WISPr $INCLUDE /etc/radcli/dictionary.WISPr
$INCLUDE /etc/radcli/dictionary.CoovaChilli
$INCLUDE /etc/radcli/dictionary.chillispot

View File

@@ -1,6 +0,0 @@
VENDOR CoovaChilli 14122 CoovaChilli
ATTRIBUTE CoovaChilli-Max-Input-Octets 1 integer CoovaChilli
ATTRIBUTE CoovaChilli-Max-Output-Octets 2 integer CoovaChilli
ATTRIBUTE CoovaChilli-Max-Total-Octets 3 integer CoovaChilli

View File

@@ -1,14 +0,0 @@
VENDOR ChilliSpot 14559 ChilliSpot
ATTRIBUTE ChilliSpot-Max-Input-Octets 1 integer ChilliSpot
ATTRIBUTE ChilliSpot-Max-Output-Octets 2 integer ChilliSpot
ATTRIBUTE ChilliSpot-Max-Total-Octets 3 integer ChilliSpot
ATTRIBUTE ChilliSpot-Bandwidth-Max-Up 4 integer ChilliSpot
ATTRIBUTE ChilliSpot-Bandwidth-Max-Down 5 integer ChilliSpot
ATTRIBUTE ChilliSpot-Config 6 string ChilliSpot
ATTRIBUTE ChilliSpot-Lang 7 string ChilliSpot
ATTRIBUTE ChilliSpot-Version 8 string ChilliSpot
ATTRIBUTE ChilliSpot-OriginalURL 9 string ChilliSpot
ATTRIBUTE ChilliSpot-UAM-Allowed 100 string ChilliSpot
ATTRIBUTE ChilliSpot-MAC-Allowed 101 string ChilliSpot
ATTRIBUTE ChilliSpot-Interval 102 integer ChilliSpot

View File

@@ -12,10 +12,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/jow-/ucode.git PKG_SOURCE_URL=https://github.com/jow-/ucode.git
PKG_MIRROR_HASH:=413a08ee63c30c44d6f0a5de14b1c84787f9bd1fe8b125c8e4956aa2884cc933 PKG_MIRROR_HASH:=98303ef9d5fa7eca04042792abaf8a2e66082237a23a89a7f5e72e4409714a72
#PKG_MIRROR_HASH:=98303ef9d5fa7eca04042792abaf8a2e66082237a23a89a7f5e72e4409714a72
PKG_SOURCE_DATE:=2022-04-07 PKG_SOURCE_DATE:=2022-04-07
PKG_SOURCE_VERSION:=7fa59ce44b9347528b0e4e44ebcfb04a08479f3f PKG_SOURCE_VERSION:=456d3f1811aaf864ac0071232e6783ae1779c32a
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io> PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
PKG_LICENSE:=ISC PKG_LICENSE:=ISC

View File

@@ -100,3 +100,15 @@ Index: ucode-2022-04-07-33f1e0b0/lib/nl80211.c
static const uc_nl_nested_spec_t nl80211_sta_info_nla = { static const uc_nl_nested_spec_t nl80211_sta_info_nla = {
.headsize = 0, .headsize = 0,
.nattrs = 35, .nattrs = 35,
Index: ucode-2022-04-07-33f1e0b0/lib/rtnl.c
===================================================================
--- ucode-2022-04-07-33f1e0b0.orig/lib/rtnl.c
+++ ucode-2022-04-07-33f1e0b0/lib/rtnl.c
@@ -682,6 +682,7 @@ static const uc_nl_nested_spec_t link_ms
{ IFLA_UNSPEC, "type", DT_U16, 0, MEMBER(ifinfomsg, ifi_type) },
{ IFLA_UNSPEC, "dev", DT_NETDEV, 0, MEMBER(ifinfomsg, ifi_index) },
{ IFLA_UNSPEC, "flags", DT_FLAGS, 0, MEMBER(ifinfomsg, ifi_flags) },
+ { IFLA_UNSPEC, "change", DT_FLAGS, 0, MEMBER(ifinfomsg, ifi_change) },
{ IFLA_ADDRESS, "address", DT_LLADDR, 0, NULL },
{ IFLA_BROADCAST, "broadcast", DT_LLADDR, 0, NULL },
{ IFLA_TXQLEN, "txqlen", DT_U32, 0, NULL },

View File

@@ -1,13 +0,0 @@
Index: ucode-2022-04-07-7fa59ce4/lib/uloop.c
===================================================================
--- ucode-2022-04-07-7fa59ce4.orig/lib/uloop.c
+++ ucode-2022-04-07-7fa59ce4/lib/uloop.c
@@ -971,6 +971,8 @@ uc_uloop_task(uc_vm_t *vm, size_t nargs)
err_return(errno);
if (pid == 0) {
+ uloop_done();
+
patch_devnull(0, false);
patch_devnull(1, true);
patch_devnull(2, true);

View File

@@ -1,34 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ucrun
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/ucentral-io/ucrun.git
PKG_MIRROR_HASH:=52aeece27348611197ae5f4b96b3bdf1b5d028ae4ae284806b216d502300d07a
PKG_SOURCE_DATE:=2022-02-19
PKG_SOURCE_VERSION:=5be6abebc4ae6057b47a5b3f0799d5ff01bc60c3
CMAKE_INSTALL:=1
PKG_LICENSE:=GPL-2.0-only
PKG_LICENSE_FILES:=GPL
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/ucrun
SECTION:=utils
CATEGORY:=Utilities
DEPENDS:=+libubox +ucode +ucode-mod-uci +ucode-mod-ubus +ucode-mod-fs
TITLE:=uCode main-loop daemon
endef
define Package/ucrun/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ucrun $(1)/usr/bin
endef
$(eval $(call BuildPackage,ucrun))

View File

@@ -1,138 +0,0 @@
From b24a5a890ccd19b0f1b50340c79c5087f08d9447 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Fri, 4 Mar 2022 15:56:30 +0100
Subject: [PATCH] ulog: add ringbuffer and log_event notification
Signed-off-by: John Crispin <john@phrozen.org>
---
ucode.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/ucode.c b/ucode.c
index cef50e2..9e0373a 100644
--- a/ucode.c
+++ b/ucode.c
@@ -31,6 +31,17 @@ static const char *exception_types[] = {
[EXCEPTION_EXIT] = "Exit"
};
+struct log_buffer {
+ struct list_head list;
+ int severity;
+ char entry[];
+};
+
+static LIST_HEAD(log_buffer);
+static int log_count;
+static int log_max = 100;
+static uc_value_t *log_event;
+
static void
ucode_handle_exception(uc_vm_t *vm, uc_exception_t *ex)
{
@@ -287,6 +298,7 @@ static uc_value_t *
uc_ulog(uc_vm_t *vm, size_t nargs, int severity)
{
uc_value_t *res;
+ char *entry;
if (!fmtfn) {
fmtfn = (uc_cfunction_t *)ucv_object_get(uc_vm_scope_get(vm), "sprintf", NULL);
@@ -300,7 +312,37 @@ uc_ulog(uc_vm_t *vm, size_t nargs, int severity)
if (!res)
return ucv_int64_new(-1);
- ulog(severity, "%s", ucv_string_get(res));
+ entry = ucv_string_get(res);
+
+ if (log_max) {
+ struct log_buffer *log = calloc(1, sizeof(*log) + strlen(entry) + 1);
+
+ strcpy(log->entry, entry);
+ log->severity = severity;
+ list_add_tail(&log->list, &log_buffer);
+
+ if (log_event) {
+ uc_value_t *event = ucv_array_new(vm);
+
+ ucv_array_push(event, ucv_int64_new(severity));
+ ucv_array_push(event, ucv_string_new(entry));
+
+ uc_vm_stack_push(vm, ucv_get(log_event));
+ uc_vm_stack_push(vm, ucv_get(event));
+ uc_vm_call(vm, false, 1);
+ }
+
+ if (log_count == log_max) {
+ struct log_buffer *first = list_first_entry(&log_buffer, struct log_buffer, list);
+
+ list_del(&first->list);
+ free(first);
+ } else {
+ log_count++;
+ }
+ }
+
+ ulog(severity, "%s", entry);
ucv_put(res);
return ucv_int64_new(0);
@@ -330,11 +372,27 @@ uc_ulog_err(uc_vm_t *vm, size_t nargs)
return uc_ulog(vm, nargs, LOG_ERR);
}
+static uc_value_t *
+uc_ulog_dump(uc_vm_t *vm, size_t nargs)
+{
+ uc_value_t *log = ucv_array_new(vm);
+ struct log_buffer *iter;
+
+ list_for_each_entry(iter, &log_buffer, list) {
+ uc_value_t *entry = ucv_array_new(vm);
+ ucv_array_push(entry, ucv_int64_new(iter->severity));
+ ucv_array_push(entry, ucv_string_new(iter->entry));
+ ucv_array_push(log, entry);
+ }
+
+ return log;
+}
+
static void
ucode_init_ulog(ucrun_ctx_t *ucrun)
{
uc_value_t *ulog = ucv_object_get(ucrun->scope, "ulog", NULL);
- uc_value_t *identity, *channels;
+ uc_value_t *identity, *channels, *logsize;
int flags = 0, channel;
/* make sure the declartion is complete */
@@ -365,6 +423,18 @@ ucode_init_ulog(ucrun_ctx_t *ucrun)
flags |= ULOG_STDIO;
}
+ /* set the internal ring buffer size */
+ logsize = ucv_object_get(ulog, "channels", NULL);
+ if (ucv_type(logsize) == UC_INTEGER && ucv_int64_get(logsize))
+ log_max = ucv_int64_get(logsize);
+
+ /* find out if ucrun wants a notification when a new log entry is generated */
+ log_event = ucv_object_get(ulog, "event", NULL);
+ if (ucv_is_callable(log_event))
+ ucv_get(log_event);
+ else
+ log_event = NULL;
+
/* open the log */
ucrun->ulog_identity = strdup(ucv_string_get(identity));
ulog_open(flags, LOG_DAEMON, ucrun->ulog_identity);
@@ -404,6 +474,7 @@ ucode_init(ucrun_ctx_t *ucrun, int argc, const char **argv, int *rc)
uc_function_register(ucrun->scope, "ulog_note", uc_ulog_note);
uc_function_register(ucrun->scope, "ulog_warn", uc_ulog_warn);
uc_function_register(ucrun->scope, "ulog_err", uc_ulog_err);
+ uc_function_register(ucrun->scope, "ulog_dump", uc_ulog_dump);
/* add commandline parameters */
ARGV = ucv_array_new(&ucrun->vm);
--
2.25.1

View File

@@ -5,9 +5,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/blogic/udevmand.git PKG_SOURCE_URL=https://github.com/blogic/udevmand.git
PKG_MIRROR_HASH:=51bcf59754ef87913c40f2f1c708c8d2d2eb0ad5fc128a5c891e54ea4b3b035e PKG_MIRROR_HASH:=25e47c7f3d454cc5eba4e9c19fc9da8431e3c2b1b97b8f0f49798f51c2722df7
PKG_SOURCE_DATE:=20220112 PKG_SOURCE_DATE:=20220112
PKG_SOURCE_VERSION:=3d2b67b180679a6f5687e8d318a66a7cbad3fa7b PKG_SOURCE_VERSION:=065f75cb88aa317441adffeddc8d5302cfaafc8a
CMAKE_INSTALL:=1 CMAKE_INSTALL:=1
PKG_LICENSE:=LGPL-2.1 PKG_LICENSE:=LGPL-2.1

View File

@@ -27,11 +27,6 @@ struct vlan_hdr {
uint16_t proto; uint16_t proto;
}; };
struct gre_hdr {
uint16_t flags;
uint16_t proto;
};
struct packet { struct packet {
void *buffer; void *buffer;
unsigned int len; unsigned int len;
@@ -96,7 +91,6 @@ dhcpsnoop_packet_cb(struct packet *pkt)
bool ipv6 = false; bool ipv6 = false;
uint32_t rebind = 0; uint32_t rebind = 0;
inside_tunnel:
eth = pkt_pull(pkt, sizeof(*eth)); eth = pkt_pull(pkt, sizeof(*eth));
if (!eth) if (!eth)
return; return;
@@ -135,15 +129,6 @@ inside_tunnel:
return; return;
} }
if (proto == IPPROTO_GRE) {
struct gre_hdr *gre;
gre = pkt_pull(pkt, sizeof(*gre));
if (!gre) return;
proto = be16_to_cpu(gre->proto);
if (proto != 0x6558) return;
goto inside_tunnel;
}
if (proto != IPPROTO_UDP) if (proto != IPPROTO_UDP)
return; return;
@@ -232,37 +217,11 @@ prepare_filter_cmd(char *buf, int len, const char *dev, int prio, bool add, bool
add ? "add" : "del", dev, egress ? "e" : "in", prio); add ? "add" : "del", dev, egress ? "e" : "in", prio);
} }
#define MATCH_GRE_ETH_IP_UDP_DHCP_67 \
" match u16 0x6558 0xffff at 22 " \
" match u16 0x0800 0xffff at 36 " \
" match u8 17 0xff at 47 " \
" match u16 67 0xffff at 58 "
#define MATCH_GRE_ETH_VLAN_IP_UDP_DHCP_67 \
" match u16 0x6558 0xffff at 22 " \
" match u16 0x8100 0xffff at 36 " \
" match u16 0x0800 0xffff at 40 " \
" match u8 17 0xff at 51 " \
" match u16 67 0xffff at 62 "
#define MATCH_GRE_ETH_IP_UDP_DHCP_68 \
" match u16 0x6558 0xffff at 22 " \
" match u16 0x0800 0xffff at 36 " \
" match u8 17 0xff at 47 " \
" match u16 68 0xffff at 58 "
#define MATCH_GRE_ETH_VLAN_IP_UDP_DHCP_68 \
" match u16 0x6558 0xffff at 22 " \
" match u16 0x8100 0xffff at 36 " \
" match u16 0x0800 0xffff at 40 " \
" match u8 17 0xff at 51 " \
" match u16 68 0xffff at 62 "
static void static void
dhcpsnoop_dev_attach_filters(struct device *dev, bool egress) dhcpsnoop_dev_attach_filters(struct device *dev, bool egress)
{ {
int prio = DHCPSNOOP_PRIO_BASE; int prio = DHCPSNOOP_PRIO_BASE;
char buf[350]; char buf[256];
int ofs; int ofs;
ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress); ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress);
@@ -285,32 +244,6 @@ dhcpsnoop_dev_attach_filters(struct device *dev, bool egress)
" flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME); " flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME);
dhcpsnoop_run_cmd(buf, false); dhcpsnoop_run_cmd(buf, false);
/* GRE */
ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress);
APPEND(buf, ofs, " protocol ip u32 match ip protocol 47 0xff"
MATCH_GRE_ETH_IP_UDP_DHCP_67
" flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME);
dhcpsnoop_run_cmd(buf, false);
ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress);
APPEND(buf, ofs, " protocol ip u32 match ip protocol 47 0xff"
MATCH_GRE_ETH_IP_UDP_DHCP_68
" flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME);
dhcpsnoop_run_cmd(buf, false);
ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress);
APPEND(buf, ofs, " protocol ip u32 match ip protocol 47 0xff "
MATCH_GRE_ETH_VLAN_IP_UDP_DHCP_67
" flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME);
dhcpsnoop_run_cmd(buf, false);
ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress);
APPEND(buf, ofs, " protocol ip u32 match ip protocol 47 0xff"
MATCH_GRE_ETH_VLAN_IP_UDP_DHCP_68
" flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME);
dhcpsnoop_run_cmd(buf, false);
/* IPv6 */
ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress); ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress);
APPEND(buf, ofs, " protocol ipv6 u32 match ip6 sport 546 0xfffe" APPEND(buf, ofs, " protocol ipv6 u32 match ip6 sport 546 0xfffe"
" flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME); " flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME);
@@ -328,7 +261,7 @@ dhcpsnoop_dev_cleanup_filters(struct device *dev, bool egress)
char buf[128]; char buf[128];
int i; int i;
for (i = DHCPSNOOP_PRIO_BASE; i < DHCPSNOOP_PRIO_BASE + 10; i++) { for (i = DHCPSNOOP_PRIO_BASE; i < DHCPSNOOP_PRIO_BASE + 6; i++) {
prepare_filter_cmd(buf, sizeof(buf), dev->ifname, i, false, egress); prepare_filter_cmd(buf, sizeof(buf), dev->ifname, i, false, egress);
dhcpsnoop_run_cmd(buf, true); dhcpsnoop_run_cmd(buf, true);
} }

View File

@@ -68,11 +68,11 @@ out:
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
ulog_open(ULOG_STDIO | ULOG_SYSLOG, LOG_DAEMON, "udhcpsnoop"); ulog_open(ULOG_STDIO | ULOG_SYSLOG, LOG_DAEMON, "udhcpsnoop");
uloop_init(); uloop_init();
dhcpsnoop_ubus_init(); dhcpsnoop_ubus_init();
dhcpsnoop_dev_init(); dhcpsnoop_dev_init();
ulog_threshold(LOG_INFO);
uloop_run(); uloop_run();
dhcpsnoop_ubus_done(); dhcpsnoop_ubus_done();

View File

@@ -13,12 +13,12 @@ define Package/uspot
SECTION:=net SECTION:=net
CATEGORY:=Network CATEGORY:=Network
TITLE:=hotspot daemon TITLE:=hotspot daemon
DEPENDS:=+spotfilter +uhttpd-mod-ucode +libradcli +iptables-mod-conntrack-extra +conntrack DEPENDS:=+spotfilter +uhttpd-mod-ucode +libradcli
endef endef
define Package/uspot/install define Package/uspot/install
$(INSTALL_DIR) $(1)/usr/bin/ $(1)/usr/lib/ucode $(INSTALL_DIR) $(1)/usr/bin/ $(1)/usr/lib/ucode
$(INSTALL_BIN) $(PKG_BUILD_DIR)/radius-client $(1)/usr/bin/radius-client $(INSTALL_BIN) $(PKG_BUILD_DIR)/radius-client $(1)/usr/bin
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libuam.so $(1)/usr/lib/ucode/uam.so $(INSTALL_DATA) $(PKG_BUILD_DIR)/libuam.so $(1)/usr/lib/ucode/uam.so
$(CP) ./files/* $(1) $(CP) ./files/* $(1)
endef endef

View File

@@ -1,6 +1,25 @@
config uspot config config uspot config
#option auth_mode 'uam'
#option auth_mode 'radius'
#option auth_mode 'credentials'
option auth_mode 'click-to-continue'
config radius radius config radius radius
# option auth_server 212.24.98.232
# option auth_port 1812
# option auth_secret secret
config uam uam config uam uam
# option port 3990
# option nasid AlmondLabs
# option nasmac 903cb3bb25e3
# option server https://customer.hotspotsystem.com/customer/hotspotlogin.php
# option secret hotsys123
#config credential
# option username abc
# option password def
#config credential
# option username 123
# option password 456

View File

@@ -1,13 +0,0 @@
#!/bin/sh /etc/rc.common
START=80
USE_PROCD=1
PROG=/usr/share/uspot/accounting.uc
start_service() {
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn
procd_close_instance
}

View File

@@ -1,53 +0,0 @@
#!/usr/bin/ucode
let ubus = require('ubus').connect();
let uci = require('uci').cursor();
function restart() {
system('/etc/init.d/spotfilter restart');
system('/etc/init.d/uhttpd restart');
}
switch(ARGV[0]) {
case 'dump':
let clients = ubus.call('spotfilter', 'client_list', { interface: 'hotspot'});
printf('%.J\n', clients);
break;
case 'clients':
let clients = ubus.call('spotfilter', 'client_list', { interface: 'hotspot'});
let res = {};
let t = time();
for (let c, val in clients) {
res[c] = {
status: val.state ? 'Authenticated' : 'Garden',
idle: val.idle || 0,
time: val.data.connect ? t - val.data.connect : 0,
ip4addr: val.ip4addr || '',
ip6addr: val.ip6addr || '',
packets_ul: val.packets_ul || 0,
bytes_ul: val.bytes_ul || 0,
packets_dl: val.packets_dl || 0,
bytes_dl: val.bytes_dl || 0,
};
}
printf('%.J\n', res);
break;
case 'remove':
ubus.call('spotfilter', 'client_remove', { interface: 'hotspot', address: ARGV[1] || ''});
break;
case 'restart':
restart();
break;
case 'log':
system('logread -f | grep uspot:');
break;
case 'debugon':
case 'debugoff':
uci.set('uspot', 'config', 'debug', 1);
uci.commit();
restart();
break;
default:
break;
}

View File

@@ -1,263 +0,0 @@
#!/usr/bin/ucode
'use strict';
let fs = require('fs');
let uloop = require('uloop');
let ubus = require('ubus').connect();
let uci = require('uci').cursor();
let config = uci.get_all('uspot');
let clients = {};
let acct_interval = config.radius?.acct_interval || 600;
let idle_timeout = config.config.idle_timeout || 600;
let session_timeout = config.config.session_timeout || 0;
function syslog(mac, msg) {
let log = sprintf('uspot: %s %s', mac, msg);
system('logger ' + log);
warn(log + '\n');
}
function debug(mac, msg) {
if (config.config.debug)
syslog(mac, msg);
}
function get_idle_timeout(mac) {
if (clients[mac])
return clients[mac].idle;
return idle_timeout;
}
function get_session_timeout(mac) {
if (clients[mac]?.session)
return clients[mac].session;
return session_timeout;
}
function radius_available(mac) {
return !!clients[mac]?.radius;
}
function radius_init(mac, payload) {
for (let key in [ 'server', 'acct_server', 'acct_session', 'client_ip', 'called_station', 'calling_station', 'nas_ip', 'nas_id', 'username' ])
if (clients[mac].radius[key])
payload[key] = clients[mac].radius[key];
return payload;
}
function radius_call(mac, payload) {
let cfg = fs.open('/tmp/acct' + mac + '.json', 'w');
cfg.write(payload);
cfg.close();
system('/usr/bin/radius-client /tmp/acct' + mac + '.json');
}
function radius_stop(mac, payload) {
if (!radius_available(mac))
return;
debug(mac, 'stopping accounting');
ubus.call('spotfilter', 'client_set', payload);
system('conntrack -D -s ' + clients[mac].ip4addr + ' -m 2');
if (clients[mac].accounting)
clients[mac].timeout.cancel();
delete clients[mac];
}
function radius_acct(mac, payload) {
let state = ubus.call('spotfilter', 'client_get', {
interface: 'hotspot',
address: mac
});
if (!state) {
return false;
}
payload = radius_init(mac, payload);
payload.acct = true;
payload.session_time = time() - state.data.connect;
payload.output_octets = state.bytes_dl & 0xffffffff;
payload.input_octets = state.bytes_ul & 0xffffffff;
payload.output_gigawords = state.bytes_dl >> 32;
payload.input_gigawords = state.bytes_ul >> 32;
payload.output_packets = state.packets_dl;
payload.input_packets = state.packets_ul;
if (state.data?.radius?.reply?.Class)
payload.class = state.data.radius.reply.Class;
radius_call(mac, payload);
return true;
}
function radius_idle_time(mac) {
if (!radius_available(mac))
return;
let payload = {
acct_type: 2,
terminate_cause: 4,
};
radius_acct(mac, payload);
}
function radius_session_time(mac) {
if (!radius_available(mac))
return;
let payload = {
acct_type: 2,
terminate_cause: 5,
};
radius_acct(mac, payload);
}
function radius_logoff(mac) {
if (!radius_available(mac))
return;
let payload = {
acct_type: 2,
terminate_cause: 1,
};
radius_acct(mac, payload);
}
function radius_disconnect(mac) {
if (!radius_available(mac))
return;
let payload = {
acct_type: 2,
terminate_cause: 1,
};
radius_acct(mac, payload);
}
function radius_interim(mac) {
if (!radius_available(mac))
return;
let payload = {
acct_type: 3,
};
if (radius_acct(mac, payload))
debug(mac, 'iterim acct call');
else
syslog(mac, 'failed to sent interim accounting frame\n');
clients[mac].timeout.set(clients[mac].interval);
}
function client_add(mac, state) {
if (state.state != 1)
return;
let interval = acct_interval * 1000;
let idle = idle_timeout;
let session = session_timeout;
let accounting = (config.radius?.acct_server && config.radius?.acct_secret);
let max_total = 0;
if (state.data?.radius?.reply) {
interval = (state.data?.radius?.reply['Acct-Interim-Interval'] || acct_interval) * 1000;
idle = (state.data?.radius?.reply['Idle-Timeout'] || idle_timeout);
session = (state.data?.radius?.reply['Session-Timeout'] || session_timeout);
max_total = (state.data?.radius?.reply['ChilliSpot-Max-Total-Octets'] || 0);
}
clients[mac] = {
accounting,
interval,
session,
idle,
max_total,
};
if (state.ip4addr)
clients[mac].ip4addr = state.ip4addr;
if (state.ip6addr)
clients[mac].ip6addr = state.ip6addr;
if (state.data?.radius?.request)
clients[mac].radius= state.data.radius.request;
syslog(mac, 'adding client');
if (accounting)
clients[mac].timeout = uloop.timer(interval, () => radius_interim(mac));
}
function client_remove(mac, reason) {
syslog(mac, reason);
radius_stop(mac, {
interface: "hotspot",
address: mac
});
}
function client_flush(mac) {
syslog(mac, 'logoff event');
radius_stop(mac, {
interface: 'hotspot',
address: mac,
state: 0,
dns_state: 1,
accounting: [],
flush: true
});
}
function client_timeout(mac, reason) {
syslog(mac, reason);
radius_stop(mac, {
interface: "hotspot",
state: 0,
dns_state: 1,
address: mac,
accounting: [],
flush: true,
});
}
uloop.init();
uloop.timer(1000, function() {
let list = ubus.call('spotfilter', 'client_list', { interface: 'hotspot'});
let t = time();
for (let k, v in list)
if (!clients[k])
client_add(k, v);
for (let k, v in clients) {
if (list[k].data?.logoff) {
radius_logoff(k);
client_flush(k);
continue;
}
if (!list[k] || !list[k].state) {
radius_disconnect(k);
client_remove(k, 'disconnect event');
continue;
}
if (list[k].idle > get_idle_timeout(k)) {
if (clients[k])
radius_idle_time(k);
client_remove(k, 'idle event');
continue;
}
let timeout = get_session_timeout(k);
if (timeout && ((t - list[k].data.connect) > timeout)) {
if (clients[k])
radius_session_time(k);
client_timeout(k, 'session timeout');
continue;
}
if (clients[k].max_total) {
let total = list[k].bytes_ul + list[k].bytes_dl;
if (total >= clients[k].max_total) {
radius_session_time(k);
client_timeout(k, 'max octets reached');
}
}
}
this.set(1000);
});
uloop.run();

View File

@@ -26,45 +26,6 @@ return {
header, header,
footer, footer,
// syslog helper
syslog: function(ctx, msg) {
warn('uspot: ' + ctx.env.REMOTE_ADDR + ' - ' + msg + '\n');
},
debug: function(ctx, msg) {
if (config.config.debug)
this.syslog(ctx, msg);
},
// mac re-formater
format_mac: function(mac) {
switch(config.uam.mac_format) {
case 'aabbccddeeff':
case 'AABBCCDDEEFF':
mac = replace(mac, ':', '');
break;
case 'aa-bb-cc-dd-ee-ff':
case 'AA-BB-CC-DD-EE-FF':
mac = replace(mac, ':', '-');
break;
}
switch(config.uam.mac_format) {
case 'aabbccddeeff':
case 'aa-bb-cc-dd-ee-ff':
case 'aa:bb:cc:dd:ee:ff':
mac = lc(mac);
break;
case 'AABBCCDDEEFF':
case 'AA:BB:CC:DD:EE:FF':
case 'AA-BB-CC-DD-EE-FF':
mac = uc(mac);
break;
}
return mac;
},
// wrapper for scraping external tools stdout // wrapper for scraping external tools stdout
fs_popen: function(cmd) { fs_popen: function(cmd) {
let stdout = fs.popen(cmd); let stdout = fs.popen(cmd);
@@ -82,104 +43,45 @@ return {
}, },
// give a client access to the internet // give a client access to the internet
allow_client: function(ctx, data) { allow_client: function(ctx) {
this.syslog(ctx, 'allow client to pass traffic');
ctx.ubus.call('spotfilter', 'client_set', { ctx.ubus.call('spotfilter', 'client_set', {
"interface": "hotspot", "interface": "hotspot",
"address": ctx.mac, "address": replace(ctx.mac, '-', ':'),
"state": 1, "state": 1,
"dns_state": 1, "dns_state": 1,
"accounting": [ "dl", "ul"], "accounting": [ "dl", "ul"],
"data": { "data": {
... data || {}, "connect": time()
"connect": time(),
} }
}); });
if (ctx.query_string.userurl) if (ctx.query_string.userurl)
include('redir.uc', { redir_location: ctx.query_string.userurl }); include('redir.uc', { redir_location: ctx.query_string.userurl });
else else
include('allow.uc', ctx); include('allow.uc', ctx);
//data.radius.reply['WISPr-Bandwidth-Max-Up'] = "20000000";
//data.radius.reply['WISPr-Bandwidth-Max-Down'] = "10000000";
if (data?.radius?.reply && (+data.radius.reply['WISPr-Bandwidth-Max-Up'] && +data.radius.reply['WISPr-Bandwidth-Max-Down']))
ctx.ubus.call('ratelimit', 'client_set', {
device: ctx.device,
address: ctx.mac,
rate_egress: sprintf('%s', data.radius.reply['WISPr-Bandwidth-Max-Down']),
rate_ingress: sprintf('%s', data.radius.reply['WISPr-Bandwidth-Max-Up']),
});
},
// put a client back into pre-auth state
logoff: function(ctx, uam) {
this.syslog(ctx, 'logging client off');
ctx.ubus.call('spotfilter', 'client_set', {
interface: 'hotspot',
address: ctx.mac,
state: 0,
dns_state: 1,
accounting: [],
data: {
logoff : 1
}
});
if (uam)
include('redir.uc', { redir_location: this.uam_url(ctx, 'logoff') });
else
include('logoff.uc', ctx);
}, },
// generate the default radius auth payload // generate the default radius auth payload
radius_init: function(ctx, acct_session) { radius_init: function(ctx) {
let math = require('math');
if (!acct_session) {
acct_session = '';
for (let i = 0; i < 16; i++)
acct_session += sprintf('%d', math.rand() % 10);
}
return { return {
server: sprintf('%s:%s:%s', this.config.radius.auth_server, this.config.radius.auth_port, this.config.radius.auth_secret), server: sprintf('%s:%s:%s', this.config.radius.auth_server, this.config.radius.auth_port, this.config.radius.auth_secret),
acct_server: sprintf('%s:%s:%s', this.config.radius.acct_server, this.config.radius.acct_port, this.config.radius.acct_secret), acct_session: "0123456789",
acct_session,
client_ip: ctx.env.REMOTE_ADDR, client_ip: ctx.env.REMOTE_ADDR,
called_station: this.config.uam.nasmac + ':' + ctx.ssid, called_station: ctx.mac,
calling_station: this.format_mac(ctx.mac), calling_station: this.config.uam.nasmac,
nas_ip: ctx.env.SERVER_ADDR, nas_ip: ctx.env.SERVER_ADDR,
nas_id: this.config.uam.nasid nas_id: this.config.uam.nasid
}; };
}, },
radius_call: function(ctx, payload) { radius_call: function(ctx, payload) {
let type = payload.acct ? 'acct' : 'auth'; let cfg = fs.open('/tmp/' + ctx.mac + '.json', 'w');
let cfg = fs.open('/tmp/' + type + ctx.mac + '.json', 'w');
cfg.write(payload); cfg.write(payload);
cfg.close(); cfg.close();
return this.fs_popen('/usr/bin/radius-client /tmp/' + type + ctx.mac + '.json'); return this.fs_popen('/usr/bin/radius-client /tmp/' + ctx.mac + '.json');
}, },
uam_url: function(ctx, res) { handle_request: function(env) {
let uam_url = this.config.uam.uam_server +
'?res=' + res +
'&uamip=' + ctx.env.SERVER_ADDR +
'&uamport=' + this.config.uam.uam_port +
'&challenge=' + this.uam.md5(this.config.uam.challenge, ctx.format_mac) +
'&mac=' + ctx.format_mac +
'&ip=' + ctx.env.REMOTE_ADDR +
'&called=' + this.config.uam.nasmac +
'&nasid=' + this.config.uam.nasid +
'&ssid=' + ctx.ssid;
if (ctx.query_string?.redir)
uam_url += '&userurl=' + ctx.query_string.redir;
if (this.config.uam.uam_secret)
uam_url += '&md=' + this.uam.md5(uam_url, this.config.uam.uam_secret);
return uam_url;
},
handle_request: function(env, uam) {
let mac; let mac;
let form_data = {}; let form_data = {};
let query_string = {}; let query_string = {};
@@ -189,40 +91,25 @@ return {
// lookup the peers MAC // lookup the peers MAC
let macs = this.rtnl.request(this.rtnl.const.RTM_GETNEIGH, this.rtnl.const.NLM_F_DUMP, { }); let macs = this.rtnl.request(this.rtnl.const.RTM_GETNEIGH, this.rtnl.const.NLM_F_DUMP, { });
for (let m in macs) for (let m in macs)
if (m.dst == env.REMOTE_HOST && m.lladdr) if (m.dst == env.REMOTE_HOST)
ctx.mac = m.lladdr; ctx.mac = replace(m.lladdr, ':', '-');
// if the MAC lookup failed, go to the error page // if the MAC lookup failed, go to the error page
if (!ctx.mac) { if (!ctx.mac) {
this.syslog(ctx, 'failed to look up mac');
include('error.uc', ctx); include('error.uc', ctx);
return NULL; return NULL;
} }
ctx.format_mac = this.format_mac(ctx.mac);
// check if a client is already connected // check if a client is already connected
ctx.ubus = ubus.connect(); ctx.ubus = ubus.connect();
let connected = ctx.ubus.call('spotfilter', 'client_get', { let connected = ctx.ubus.call('spotfilter', 'client_get', {
interface: 'hotspot', 'interface': 'hotspot',
address: ctx.mac, 'address': ctx.mac
}); });
if (!uam && connected?.state) { if (connected?.state) {
include('connected.uc', ctx); include('connected.uc', ctx);
return NULL; return NULL;
} }
if (!connected.data.ssid) {
let hapd = ctx.ubus.call('hostapd.' + connected.device, 'get_status');
ctx.ubus.call('spotfilter', 'client_set', {
interface: 'hotspot',
address: ctx.mac,
data: {
ssid: hapd.ssid || 'unknown'
}
});
connected.data.ssid = hapd.ssid;
}
ctx.device = connected.device;
ctx.ssid = connected.data.ssid;
// split QUERY_STRING // split QUERY_STRING
if (env.QUERY_STRING) if (env.QUERY_STRING)

View File

@@ -1,4 +1,14 @@
Status: 302 Found Status: 200 OK
Location: http://{{env.SERVER_ADDR}}/hotspot/?redir={{env.headers.host}}
Content-Type: text/html Content-Type: text/html
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="refresh" content="0; URL=http://{{env.SERVER_ADDR}}/hotspot/?redir={{env.headers.host}}" />
</head>
<body style="background-color: white">
<a style="color: black; font-family: arial, helvetica, sans-serif;" href="http://{{env.SERVER_ADDR}}/hotspot">HotSpot Login</a>
</body>
</html>

View File

@@ -1,3 +0,0 @@
*mangle
-A POSTROUTING -m mark --mark 0x2 -j CONNMARK --set-mark 0x2
COMMIT

View File

@@ -2,12 +2,7 @@
'use strict'; 'use strict';
let uci = require('uci').cursor();
let config = uci.get_all('uspot');
global.handle_request = function(env) { global.handle_request = function(env) {
if (env.REMOTE_ADDR && config.config.debug)
warn('uspot: ' + env.REMOTE_ADDR + ' - CPD redirect\n');
include('cpd.uc', { env }); include('cpd.uc', { env });
}; };
%} %}

View File

@@ -12,10 +12,10 @@ function auth_client(ctx) {
let password; let password;
let payload = portal.radius_init(ctx); let payload = portal.radius_init(ctx);
payload.logoff_url = sprintf('http://%s:3990/', ctx.env.SERVER_ADDR);
if (ctx.query_string.username && ctx.query_string.response) { if (ctx.query_string.username && ctx.query_string.response) {
let challenge = uam.md5(portal.config.uam.challenge, ctx.format_mac); let challenge = uam.md5(portal.config.uam.challenge, ctx.mac);
payload.type = 'uam-chap-auth';
payload.username = ctx.query_string.username; payload.username = ctx.query_string.username;
payload.chap_password = ctx.query_string.response; payload.chap_password = ctx.query_string.response;
if (portal.config.uam.secret) if (portal.config.uam.secret)
@@ -23,53 +23,24 @@ function auth_client(ctx) {
else else
payload.chap_challenge = challenge; payload.chap_challenge = challenge;
} else if (ctx.query_string.username && ctx.query_string.password) { } else if (ctx.query_string.username && ctx.query_string.password) {
payload.username = ctx.query_string.username; payload.type = 'uam-auth';
payload.password = uam.password(uam.md5(portal.config.uam.challenge, ctx.format_mac), ctx.query_string.password, portal.config.uam.uam_secret); payload.username = ctx.mac;
} else payload.password = uam.password(uam.md5(portal.config.uam.challenge, ctx.mac), ctx.query_string.password, portal.config.uam.uam_secret);
include('error.uc', ctx);
let radius = portal.radius_call(ctx, payload);
if (radius['access-accept']) {
if (portal.config.uam.final_redirect_url == 'uam')
ctx.query_string.userurl = portal.uam_url(ctx, 'success');
portal.allow_client(ctx, { radius: { reply: radius.reply, request: payload } } );
payload = portal.radius_init(ctx, payload.acct_session);
payload.acct = true;
payload.username = ctx.query_string.username;
payload.acct_type = 1;
if (radius.reply.Class)
payload.class = radius.reply.Class;
portal.radius_call(ctx, payload);
return;
} }
if (portal.config.uam.final_redirect_url == 'uam') let reply = portal.radius_call(ctx, payload);
include('redir.uc', { redir_location: portal.uam_url(ctx, 'reject') }); if (reply['access-accept']) {
else portal.allow_client(ctx);
include('error.uc', ctx); return;
} }
include('error.uc', ctx);
// disconnect client
function deauth_client(ctx) {
portal.logoff(ctx, true);
} }
global.handle_request = function(env) { global.handle_request = function(env) {
let ctx = portal.handle_request(env, true); let ctx = portal.handle_request(env);
switch (split(ctx.env.REQUEST_URI, '?')[0] || '') { if (ctx)
case '/logon':
auth_client(ctx); auth_client(ctx);
break;
case '/logout':
case '/logoff':
deauth_client(ctx);
break;
default:
include('error.uc', ctx);
break;
}
}; };
%} %}

View File

@@ -7,7 +7,6 @@ let portal = require('common');
// delegate an initial connection to the correct handler // delegate an initial connection to the correct handler
function request_start(ctx) { function request_start(ctx) {
portal.debug(ctx, 'start ' + (portal.config?.config?.auth_mode || '') + ' flow');
switch (portal.config?.config?.auth_mode) { switch (portal.config?.config?.auth_mode) {
case 'click-to-continue': case 'click-to-continue':
include('click.uc', ctx); include('click.uc', ctx);
@@ -19,7 +18,16 @@ function request_start(ctx) {
include('radius.uc', ctx); include('radius.uc', ctx);
return; return;
case 'uam': case 'uam':
ctx.redir_location = portal.uam_url(ctx, 'notyet'); ctx.redir_location = portal.config.uam.uam_server +
'?res=notyet' +
'&uamip=' + ctx.env.SERVER_ADDR +
'&uamport=' + portal.config.uam.uam_port +
'&challenge=' + portal.uam.md5(portal.config.uam.challenge, ctx.mac) +
'&mac=' + replace(ctx.mac, ':', '-') +
'&ip=' + ctx.env.REMOTE_ADDR +
'&called=' + portal.config.uam.nasmac +
'&nasid=' + portal.config.uam.nasid;
ctx.redir_location += '&md=' + portal.uam.md5(ctx.uam_location, portal.config.uam.uam_secret);
include('redir.uc', ctx); include('redir.uc', ctx);
return; return;
default: default:
@@ -38,7 +46,6 @@ function request_click(ctx) {
// check if a username and password was provided // check if a username and password was provided
if (ctx.form_data.accept_terms != 'clicked') { if (ctx.form_data.accept_terms != 'clicked') {
portal.debug(ctx, 'user did not accept conditions');
request_start({ ...ctx, error: 1 }); request_start({ ...ctx, error: 1 });
return; return;
} }
@@ -55,7 +62,6 @@ function request_credentials(ctx) {
// check if a username and password was provided // check if a username and password was provided
if (!ctx.form_data.username || !ctx.form_data.password) { if (!ctx.form_data.username || !ctx.form_data.password) {
portal.debug(ctx, 'missing credentials\n');
request_start({ ...ctx, error: 1 }); request_start({ ...ctx, error: 1 });
return; return;
} }
@@ -70,12 +76,11 @@ function request_credentials(ctx) {
ctx.form_data.password != cred.password) ctx.form_data.password != cred.password)
continue; continue;
portal.allow_client(ctx, { username: ctx.form_data.username }); portal.allow_client(ctx);
return; return;
} }
// auth failed // auth failed
portal.debug(ctx, 'invalid credentials\n');
request_start({ ...ctx, error: 1 }); request_start({ ...ctx, error: 1 });
} }
@@ -89,25 +94,23 @@ function request_radius(ctx) {
// check if a username and password was provided // check if a username and password was provided
if (!ctx.form_data.username || !ctx.form_data.password) { if (!ctx.form_data.username || !ctx.form_data.password) {
portal.debug(ctx, 'missing credentials\n');
request_start({ ...ctx, error: 1 }); request_start({ ...ctx, error: 1 });
return; return;
} }
// trigger the radius auth // trigger the radius auth
let payload = portal.radius_init(ctx); let payload = radius_init(ctx);
payload.type = 'auth'; payload.type = 'auth';
payload.username = ctx.form_data.username; payload.username = ctx.form_data.username;
payload.password = ctx.form_data.password; payload.password = ctx.form_data.password;
let radius = portal.radius_call(ctx, payload); let reply = portal.radius_call(ctx, payload);
if (radius['access-accept']) { if (reply['access-accept']) {
portal.allow_client(ctx, { username: ctx.form_data.username, radius: { reply: radius.reply, request: payload } } ); portal.allow_client(ctx);
return; return;
} }
// auth failed // auth failed
portal.debug(ctx, 'invalid credentials\n');
request_start({ ...ctx, error: 1 }); request_start({ ...ctx, error: 1 });
} }

View File

@@ -1,4 +0,0 @@
Status: 200 OK
Content-Type: text/html
<h1> You are now logged-off </h1>

View File

@@ -9,10 +9,8 @@
#include <libubox/blobmsg_json.h> #include <libubox/blobmsg_json.h>
enum { enum {
RADIUS_ACCT, RADIUS_TYPE,
RADIUS_SERVER, RADIUS_SERVER,
RADIUS_ACCT_SERVER,
RADIUS_ACCT_TYPE,
RADIUS_USERNAME, RADIUS_USERNAME,
RADIUS_PASSWORD, RADIUS_PASSWORD,
RADIUS_CHAP_PASSWORD, RADIUS_CHAP_PASSWORD,
@@ -23,24 +21,12 @@ enum {
RADIUS_CALLING_STATION, RADIUS_CALLING_STATION,
RADIUS_NAS_IP, RADIUS_NAS_IP,
RADIUS_NAS_ID, RADIUS_NAS_ID,
RADIUS_TERMINATE_CAUSE,
RADIUS_SESSION_TIME,
RADIUS_INPUT_OCTETS,
RADIUS_OUTPUT_OCTETS,
RADIUS_INPUT_GIGAWORDS,
RADIUS_OUTPUT_GIGAWORDS,
RADIUS_INPUT_PACKETS,
RADIUS_OUTPUT_PACKETS,
RADIUS_LOGOFF_URL,
RADIUS_CLASS,
__RADIUS_MAX, __RADIUS_MAX,
}; };
static const struct blobmsg_policy radius_policy[__RADIUS_MAX] = { static const struct blobmsg_policy radius_policy[__RADIUS_MAX] = {
[RADIUS_ACCT] = { .name = "acct", .type = BLOBMSG_TYPE_BOOL }, [RADIUS_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING },
[RADIUS_SERVER] = { .name = "server", .type = BLOBMSG_TYPE_STRING }, [RADIUS_SERVER] = { .name = "server", .type = BLOBMSG_TYPE_STRING },
[RADIUS_ACCT_SERVER] = { .name = "acct_server", .type = BLOBMSG_TYPE_STRING },
[RADIUS_ACCT_TYPE] = { .name = "acct_type", .type = BLOBMSG_TYPE_INT32 },
[RADIUS_USERNAME] = { .name = "username", .type = BLOBMSG_TYPE_STRING }, [RADIUS_USERNAME] = { .name = "username", .type = BLOBMSG_TYPE_STRING },
[RADIUS_PASSWORD] = { .name = "password", .type = BLOBMSG_TYPE_STRING }, [RADIUS_PASSWORD] = { .name = "password", .type = BLOBMSG_TYPE_STRING },
[RADIUS_CHAP_PASSWORD] = { .name = "chap_password", .type = BLOBMSG_TYPE_STRING }, [RADIUS_CHAP_PASSWORD] = { .name = "chap_password", .type = BLOBMSG_TYPE_STRING },
@@ -51,18 +37,23 @@ static const struct blobmsg_policy radius_policy[__RADIUS_MAX] = {
[RADIUS_CALLING_STATION] = { .name = "calling_station", .type = BLOBMSG_TYPE_STRING }, [RADIUS_CALLING_STATION] = { .name = "calling_station", .type = BLOBMSG_TYPE_STRING },
[RADIUS_NAS_IP] = { .name = "nas_ip", .type = BLOBMSG_TYPE_STRING }, [RADIUS_NAS_IP] = { .name = "nas_ip", .type = BLOBMSG_TYPE_STRING },
[RADIUS_NAS_ID] = { .name = "nas_id", .type = BLOBMSG_TYPE_STRING }, [RADIUS_NAS_ID] = { .name = "nas_id", .type = BLOBMSG_TYPE_STRING },
[RADIUS_TERMINATE_CAUSE] = { .name = "terminate_cause", .type = BLOBMSG_TYPE_INT32 },
[RADIUS_SESSION_TIME] = { .name = "session_time", .type = BLOBMSG_TYPE_INT32 },
[RADIUS_INPUT_OCTETS] = { .name = "input_octets", .type = BLOBMSG_TYPE_INT32 },
[RADIUS_OUTPUT_OCTETS] = { .name = "output_octets", .type = BLOBMSG_TYPE_INT32 },
[RADIUS_INPUT_GIGAWORDS] = { .name = "input_gigawords", .type = BLOBMSG_TYPE_INT32 },
[RADIUS_OUTPUT_GIGAWORDS] = { .name = "output_gigawords", .type = BLOBMSG_TYPE_INT32 },
[RADIUS_INPUT_PACKETS] = { .name = "input_packets", .type = BLOBMSG_TYPE_INT32 },
[RADIUS_OUTPUT_PACKETS] = { .name = "output_packets", .type = BLOBMSG_TYPE_INT32 },
[RADIUS_LOGOFF_URL] = { .name = "logoff_url", .type = BLOBMSG_TYPE_STRING },
[RADIUS_CLASS] = { .name = "class", .type = BLOBMSG_TYPE_STRING },
}; };
static struct config {
char *type;
char *server;
char *username;
char *password;
char chap_password[17];
char chap_challenge[16];
char *acct_session;
struct sockaddr_in client_ip;
char *called_station;
char *calling_station;
struct sockaddr_in nas_ip;
char *nas_id;
} config;
static struct blob_buf b = {}; static struct blob_buf b = {};
static struct blob_attr *tb[__RADIUS_MAX] = {}; static struct blob_attr *tb[__RADIUS_MAX] = {};
@@ -113,162 +104,266 @@ result(rc_handle const *rh, int accept, VALUE_PAIR *pair)
return accept; return accept;
} }
static int static void
radius(void) config_load(void)
{ {
VALUE_PAIR *send = NULL, *received; if (tb[RADIUS_TYPE])
struct sockaddr_in client_ip = {}; config.type = blobmsg_get_string(tb[RADIUS_TYPE]);
struct sockaddr_in nas_ip = {};
char chap_challenge[16] = {};
char chap_password[17] = {};
rc_handle *rh = rc_new();
uint32_t val;
if (tb[RADIUS_SERVER])
config.server = blobmsg_get_string(tb[RADIUS_SERVER]);
if (tb[RADIUS_USERNAME])
config.username = blobmsg_get_string(tb[RADIUS_USERNAME]);
if (tb[RADIUS_PASSWORD])
config.password = blobmsg_get_string(tb[RADIUS_PASSWORD]);
if (tb[RADIUS_CHAP_PASSWORD]) {
*config.chap_password = '\0';
str_to_hex(blobmsg_get_string(tb[RADIUS_CHAP_PASSWORD]), &config.chap_password[1], 16);
}
if (tb[RADIUS_CHAP_CHALLENGE])
str_to_hex(blobmsg_get_string(tb[RADIUS_CHAP_CHALLENGE]), config.chap_challenge, 16);
if (tb[RADIUS_ACCT_SESSION])
config.acct_session = blobmsg_get_string(tb[RADIUS_ACCT_SESSION]);
if (tb[RADIUS_CLIENT_IP]) {
inet_pton(AF_INET, blobmsg_get_string(tb[RADIUS_CLIENT_IP]), &(config.client_ip.sin_addr));
config.client_ip.sin_addr.s_addr = ntohl(config.client_ip.sin_addr.s_addr);
}
if (tb[RADIUS_CALLED_STATION])
config.called_station = blobmsg_get_string(tb[RADIUS_CALLED_STATION]);
if (tb[RADIUS_CALLING_STATION])
config.calling_station = blobmsg_get_string(tb[RADIUS_CALLING_STATION]);
if (tb[RADIUS_NAS_IP]) {
inet_pton(AF_INET, blobmsg_get_string(tb[RADIUS_NAS_IP]), &(config.nas_ip.sin_addr));
config.nas_ip.sin_addr.s_addr = ntohl(config.nas_ip.sin_addr.s_addr);
}
if (tb[RADIUS_NAS_ID])
config.nas_id = blobmsg_get_string(tb[RADIUS_NAS_ID]);
}
static rc_handle *
radius_init(void)
{
rc_handle *rh = rc_new();
if (rh == NULL) if (rh == NULL)
return result(rh, 0, NULL);; return NULL;
rh = rc_config_init(rh); rh = rc_config_init(rh);
if (rh == NULL) if (rh == NULL)
return result(rh, 0, NULL);; return NULL;
if (tb[RADIUS_SERVER]) rc_add_config(rh, "authserver", config.server, "code", __LINE__);
rc_add_config(rh, "authserver", blobmsg_get_string(tb[RADIUS_SERVER]), "code", __LINE__);
if (tb[RADIUS_ACCT_SERVER])
rc_add_config(rh, "acctserver", blobmsg_get_string(tb[RADIUS_ACCT_SERVER]), "code", __LINE__);
rc_add_config(rh, "servers", "/tmp/radius.servers", "code", __LINE__); rc_add_config(rh, "servers", "/tmp/radius.servers", "code", __LINE__);
rc_add_config(rh, "dictionary", "/etc/radcli/dictionary", "code", __LINE__); rc_add_config(rh, "dictionary", "/etc/radcli/dictionary", "code", __LINE__);
rc_add_config(rh, "radius_timeout", "2", "code", __LINE__); rc_add_config(rh, "radius_timeout", "5", "code", __LINE__);
rc_add_config(rh, "radius_retries", "1", "code", __LINE__); rc_add_config(rh, "radius_retries", "1", "code", __LINE__);
rc_add_config(rh, "bindaddr", "*", "code", __LINE__); rc_add_config(rh, "bindaddr", "*", "code", __LINE__);
if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0)
return NULL;
return rh;
}
static int
auth(void)
{
VALUE_PAIR *send = NULL, *received;
rc_handle *rh = NULL;
if (!config.server || !config.username || !config.password)
return result(NULL, 0, NULL);
rh = radius_init();
if (!rh)
return result(NULL, 0, NULL);
if (rc_avpair_add(rh, &send, PW_USER_NAME, config.username, -1, 0) == NULL)
return result(rh, 0, NULL); return result(rh, 0, NULL);
if (tb[RADIUS_ACCT_TYPE]) { if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, config.password, -1, 0) == NULL)
val = blobmsg_get_u32(tb[RADIUS_ACCT_TYPE]);
if (rc_avpair_add(rh, &send, PW_ACCT_STATUS_TYPE, &val, 4, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_USERNAME])
if (rc_avpair_add(rh, &send, PW_USER_NAME, blobmsg_get_string(tb[RADIUS_USERNAME]), -1, 0) == NULL)
return result(rh, 0, NULL);
if (tb[RADIUS_PASSWORD])
if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, blobmsg_get_string(tb[RADIUS_PASSWORD]), -1, 0) == NULL)
return result(rh, 0, NULL);
if (tb[RADIUS_CHAP_PASSWORD]) {
str_to_hex(blobmsg_get_string(tb[RADIUS_CHAP_PASSWORD]), &chap_password[1], 16);
if (rc_avpair_add(rh, &send, PW_CHAP_PASSWORD, chap_password, 17, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_CHAP_CHALLENGE]) {
str_to_hex(blobmsg_get_string(tb[RADIUS_CHAP_CHALLENGE]), chap_challenge, 16);
if (rc_avpair_add(rh, &send, PW_CHAP_CHALLENGE, chap_challenge, 16, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_ACCT_SESSION])
if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_ID, blobmsg_get_string(tb[RADIUS_ACCT_SESSION]), -1, 0) == NULL)
return result(rh, 0, NULL);
if (tb[RADIUS_CLIENT_IP]) {
inet_pton(AF_INET, blobmsg_get_string(tb[RADIUS_CLIENT_IP]), &(client_ip.sin_addr));
client_ip.sin_addr.s_addr = ntohl(client_ip.sin_addr.s_addr);
if (rc_avpair_add(rh, &send, PW_FRAMED_IP_ADDRESS, &client_ip.sin_addr, 4, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_CALLED_STATION])
if (rc_avpair_add(rh, &send, PW_CALLED_STATION_ID, blobmsg_get_string(tb[RADIUS_CALLED_STATION]), -1, 0) == NULL)
return result(rh, 0, NULL);
if (tb[RADIUS_LOGOFF_URL])
if (rc_avpair_add(rh, &send, 3, blobmsg_get_string(tb[RADIUS_LOGOFF_URL]), -1, 14122) == NULL)
return result(rh, 0, NULL);
if (tb[RADIUS_CALLING_STATION])
if (rc_avpair_add(rh, &send, PW_CALLING_STATION_ID, blobmsg_get_string(tb[RADIUS_CALLING_STATION]), -1, 0) == NULL)
return result(rh, 0, NULL);
if (tb[RADIUS_NAS_IP]) {
inet_pton(AF_INET, blobmsg_get_string(tb[RADIUS_NAS_IP]), &(nas_ip.sin_addr));
nas_ip.sin_addr.s_addr = ntohl(nas_ip.sin_addr.s_addr);
if (rc_avpair_add(rh, &send, PW_NAS_IP_ADDRESS, &nas_ip.sin_addr, 4, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_NAS_ID])
if (rc_avpair_add(rh, &send, PW_NAS_IDENTIFIER, blobmsg_get_string(tb[RADIUS_NAS_ID]), -1, 0) == NULL)
return result(rh, 0, NULL);
if (tb[RADIUS_TERMINATE_CAUSE]) {
val = blobmsg_get_u32(tb[RADIUS_TERMINATE_CAUSE]);
if (rc_avpair_add(rh, &send, PW_ACCT_TERMINATE_CAUSE, &val, 4, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_SESSION_TIME]) {
val = blobmsg_get_u32(tb[RADIUS_SESSION_TIME]);
if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_TIME, &val, 4, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_INPUT_OCTETS]) {
val = blobmsg_get_u32(tb[RADIUS_INPUT_OCTETS]);
if (rc_avpair_add(rh, &send, PW_ACCT_INPUT_OCTETS, &val, 4, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_OUTPUT_OCTETS]) {
val = blobmsg_get_u32(tb[RADIUS_OUTPUT_OCTETS]);
if (rc_avpair_add(rh, &send, PW_ACCT_OUTPUT_OCTETS, &val, 4, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_INPUT_GIGAWORDS]) {
val = blobmsg_get_u32(tb[RADIUS_INPUT_GIGAWORDS]);
if (rc_avpair_add(rh, &send, PW_ACCT_INPUT_GIGAWORDS, &val, 4, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_OUTPUT_GIGAWORDS]) {
val = blobmsg_get_u32(tb[RADIUS_OUTPUT_GIGAWORDS]);
if (rc_avpair_add(rh, &send, PW_ACCT_OUTPUT_GIGAWORDS, &val, 4, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_INPUT_PACKETS]) {
val = blobmsg_get_u32(tb[RADIUS_INPUT_PACKETS]);
if (rc_avpair_add(rh, &send, PW_ACCT_INPUT_PACKETS, &val, 4, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_OUTPUT_PACKETS]) {
val = blobmsg_get_u32(tb[RADIUS_OUTPUT_PACKETS]);
if (rc_avpair_add(rh, &send, PW_ACCT_OUTPUT_PACKETS, &val, 4, 0) == NULL)
return result(rh, 0, NULL);
}
if (tb[RADIUS_CLASS])
if (rc_avpair_add(rh, &send, PW_CLASS, blobmsg_get_string(tb[RADIUS_CLASS]), -1, 0) == NULL)
return result(rh, 0, NULL);
val = 19;
if (rc_avpair_add(rh, &send, PW_NAS_PORT_TYPE, &val, 4, 0) == NULL)
return result(rh, 0, NULL); return result(rh, 0, NULL);
rc_apply_config(rh); rc_apply_config(rh);
if (tb[RADIUS_ACCT] && blobmsg_get_bool(tb[RADIUS_ACCT])) { if (rc_auth(rh, 0, send, &received, NULL) == OK_RC)
if (rc_acct(rh, 0, send) == OK_RC) return result(rh, 1, received);
return result(rh, 1, NULL);
} else { return result(rh, 0, NULL);
if (rc_auth(rh, 0, send, &received, NULL) == OK_RC) }
return result(rh, 1, received);
} static int
uam_auth(void)
{
VALUE_PAIR *send = NULL, *received;
rc_handle *rh = NULL;
if (!config.server || !config.username || !config.password ||
!config.acct_session || !config.called_station ||
!config.calling_station || !config.nas_id)
return result(NULL, 0, NULL);
rh = radius_init();
if (!rh)
return result(NULL, 0, NULL);
if (rc_avpair_add(rh, &send, PW_USER_NAME, config.username, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, config.password, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_ID, config.acct_session, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_FRAMED_IP_ADDRESS, &config.client_ip.sin_addr, 4, 0) == NULL)
return result(rh, 0, NULL);
//if (rc_avpair_add(rh, &send, PW_NAS_PORT_TYPE, , -1, 0) == NULL)
// return result(rh, 0, NULL);
//if (rc_avpair_add(rh, &send, PW_NAS_PORT, , -1, 0) == NULL)
// return result(rh, 0, NULL);
// if (rc_avpair_add(rh, &send, PW_NAS_PORT_ID_STRING, , -1, 0) == NULL)
// return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_CALLED_STATION_ID, config.called_station, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_CALLING_STATION_ID, config.calling_station, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_NAS_IP_ADDRESS, &config.nas_ip.sin_addr, 4, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_NAS_IDENTIFIER, config.nas_id, -1, 0) == NULL)
return result(rh, 0, NULL);
rc_apply_config(rh);
if (rc_auth(rh, 0, send, &received, NULL) == OK_RC)
return result(rh, 1, received);
return result(rh, 0, NULL);
}
static int
uam_chap_auth(void)
{
VALUE_PAIR *send = NULL, *received;
rc_handle *rh = NULL;
if (!config.server || !config.username ||
!config.acct_session || !config.called_station ||
!config.calling_station || !config.nas_id)
return result(NULL, 0, NULL);
rh = radius_init();
if (!rh)
return result(NULL, 0, NULL);
if (rc_avpair_add(rh, &send, PW_USER_NAME, config.username, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_CHAP_PASSWORD, config.chap_password, 17, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_CHAP_CHALLENGE, config.chap_challenge, 16, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_ID, config.acct_session, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_FRAMED_IP_ADDRESS, &config.client_ip.sin_addr, 4, 0) == NULL)
return result(rh, 0, NULL);
//if (rc_avpair_add(rh, &send, PW_NAS_PORT_TYPE, , -1, 0) == NULL)
// return result(rh, 0, NULL);
//if (rc_avpair_add(rh, &send, PW_NAS_PORT, , -1, 0) == NULL)
// return result(rh, 0, NULL);
// if (rc_avpair_add(rh, &send, PW_NAS_PORT_ID_STRING, , -1, 0) == NULL)
// return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_CALLED_STATION_ID, config.called_station, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_CALLING_STATION_ID, config.calling_station, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_NAS_IP_ADDRESS, &config.nas_ip.sin_addr, 4, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_NAS_IDENTIFIER, config.nas_id, -1, 0) == NULL)
return result(rh, 0, NULL);
rc_apply_config(rh);
if (rc_auth(rh, 0, send, &received, NULL) == OK_RC)
return result(rh, 1, received);
return result(rh, 0, NULL);
}
static int
uam_acct(void)
{
VALUE_PAIR *send = NULL, *received;
rc_handle *rh = NULL;
if (!config.server || !config.username || !config.password ||
!config.acct_session || !config.called_station ||
!config.calling_station || !config.nas_id)
return result(NULL, 0, NULL);
rh = radius_init();
if (!rh)
return result(NULL, 0, NULL);
if (rc_avpair_add(rh, &send, PW_USER_NAME, config.username, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, config.password, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_ID, config.acct_session, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_FRAMED_IP_ADDRESS, &config.client_ip.sin_addr, 4, 0) == NULL)
return result(rh, 0, NULL);
//if (rc_avpair_add(rh, &send, PW_NAS_PORT_TYPE, , -1, 0) == NULL)
// return result(rh, 0, NULL);
//if (rc_avpair_add(rh, &send, PW_NAS_PORT, , -1, 0) == NULL)
// return result(rh, 0, NULL);
// if (rc_avpair_add(rh, &send, PW_NAS_PORT_ID_STRING, , -1, 0) == NULL)
// return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_CALLED_STATION_ID, config.called_station, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_CALLING_STATION_ID, config.calling_station, -1, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_NAS_IP_ADDRESS, &config.nas_ip.sin_addr, 4, 0) == NULL)
return result(rh, 0, NULL);
if (rc_avpair_add(rh, &send, PW_NAS_IDENTIFIER, config.nas_id, -1, 0) == NULL)
return result(rh, 0, NULL);
rc_apply_config(rh);
if (rc_auth(rh, 0, send, &received, NULL) == OK_RC)
return result(rh, 1, received);
return result(rh, 0, NULL); return result(rh, 0, NULL);
} }
@@ -285,5 +380,21 @@ main(int argc, char **argv)
blobmsg_parse(radius_policy, __RADIUS_MAX, tb, blob_data(b.head), blob_len(b.head)); blobmsg_parse(radius_policy, __RADIUS_MAX, tb, blob_data(b.head), blob_len(b.head));
return radius(); config_load();
if (!config.type)
return result(NULL, 0, NULL);
if (!strcmp(config.type, "auth"))
return auth();
if (!strcmp(config.type, "uam-auth"))
return uam_auth();
if (!strcmp(config.type, "uam-chap-auth"))
return uam_chap_auth();
if (!strcmp(config.type, "uam-acct"))
return uam_acct();
return result(NULL, 0, NULL);
} }

View File

@@ -1,27 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=usteer2
PKG_RELEASE:=1
PKG_LICENSE:=ISC
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
include $(INCLUDE_DIR)/package.mk
define Package/usteer2
SECTION:=utils
CATEGORY:=Utilities
DEPENDS:=+ucrun
TITLE:=wifi client steering
endef
define Build/Compile/Default
endef
Build/Compile = $(Build/Compile/Default)
define Package/usteer2/install
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,usteer2))

View File

@@ -1,9 +0,0 @@
config base
option station_update 1000
option station_expiry 120
config policy
option name snr
option min_snr_kick_delay 5
option kick_reason 5
option interval 1000

View File

@@ -1,13 +0,0 @@
#!/bin/sh /etc/rc.common
START=99
STOP=01
USE_PROCD=1
start_service() {
procd_open_instance
procd_set_param command /usr/bin/usteer.uc
procd_set_param respawn 3600 5 0
procd_close_instance
}

View File

@@ -1,75 +0,0 @@
#!/usr/bin/ucrun
push(REQUIRE_SEARCH_PATH, '/usr/share/usteer/*.uc');
global.ulog = {
identity: 'usteer',
channels: [ 'stdio', 'syslog' ],
};
global.ubus = {
object: 'usteer2',
connect: function() {
printf('connected to ubus\n');
},
methods: {
interfaces: {
cb: function(msg) {
return global.local.status();
}
},
stations: {
cb: function(msg) {
return global.station.list(msg);
}
},
status: {
cb: function(msg) {
return global.station.status();
}
},
command: {
cb: function(msg) {
return global.command.handle(msg);
}
},
get_beacon_request: {
cb: function(msg) {
let val = global.station.list(msg);
return val?.beacon_report || {};
}
},
policy: {
cb: function(msg) {
return global.policy.status(msg);
},
},
},
};
global.start = function() {
try {
global.uci = require('uci').cursor();
global.ubus.conn = require('ubus').connect();
for (let module in [ 'config', 'local', 'station', 'command', 'policy' ]) {
printf('loading ' + module + '\n');
global[module] = require(module);
if (exists(global[module], 'init'))
global[module].init();
}
} catch(e) {
printf('exception %s\n', e);
}
};
global.stop = function() {
ulog_info('stopping\n');
};

View File

@@ -1,35 +0,0 @@
function result(error, text, data) {
return {
error: error,
text: text || 'unknown',
...(data ? { data } : {}),
};
}
const actions = {
// ubus call usteer2 command '{"action": "kick", "mac": "1c:57:dc:37:3c:b1", "params": {"reason": 5, "ban_time": 30}}'
kick: function(msg) {
if (global.station.kick(msg.mac, msg.params?.reason, msg.params?.ban_time))
return result(1, 'station ' + msg.mac + ' is unknown');
return result(0, 'station ' + msg.mac + ' was kicked');
},
// ubus call usteer2 command '{"action": "beacon_request", "mac": "1c:57:dc:37:3c:b1", "params": {"channel": 36}}'
// ubus call usteer2 get_beacon_request '{"mac": "1c:57:dc:37:3c:b1"}'
beacon_request: function(msg) {
if (!global.station.beacon_request(msg.mac, msg.params?.channel, msg.params?.op_class, msg.param?.duration))
return result(1, 'station ' + msg.mac + ' is unknown');
return result(0, 'station ' + msg.mac + ' beacon-request sent');
},
};
return {
handle: function(msg) {
if (!actions[msg.action])
return result(1, 'unknown action ' + msg.action);
return actions[msg.action](msg);
},
};

View File

@@ -1,10 +0,0 @@
return {
station_update: 1000,
station_expiry: 120,
init: function() {
let options = uci.get_all('usteer2', '@base[-1]');
for (let key in options)
this[key] = options[key];
},
};

View File

@@ -1,142 +0,0 @@
let nl80211 = require("nl80211");
let def = nl80211.const;
let subscriber;
let state = {};
let hapd = {};
let handlers = {};
function channel_survey(dev) {
/* trigger the nl80211 call that gathers channel survey data */
let res = nl80211.request(def.NL80211_CMD_GET_SURVEY, def.NLM_F_DUMP, { dev });
if (!res) {
ulog_err(sprintf('failed to update survey for %s', dev));
return;
}
/* iterate over the result and filter out the correct channel */
for (let survey in res) {
if (survey?.survey_info?.frequency != hapd[dev].freq)
continue;
if (survey.survey_info.noise)
hapd[dev].noise = survey.survey_info.noise;
if (survey.survey_info.time && survey.survey_info.busy) {
let time = survey.survey_info.time - (state[dev].time || 0);
let busy = survey.survey_info.busy - (state[dev].busy || 0);
state[dev].time = survey.survey_info.time;
state[dev].busy = survey.survey_info.busy;
let load = (100 * busy) / time;
if (hapd[dev].load)
hapd[dev].load = 0.85 * hapd[dev].load + 0.15 * load;
else
hapd[dev].load = load;
}
}
}
function hapd_update() {
/* todo: prefilter frequency */
for (let key in state)
channel_survey(key);
return 5000;
}
function hapd_subunsub(path, sub) {
/* check if this is a hostapd instance */
let name = split(path, '.');
if (length(name) != 2 || name[0] != 'hostapd')
return;
name = name[1];
ulog_info(sprintf('%s %s\n', sub ? 'add' : 'remove', path));
/* the hostapd instance disappeared */
if (!sub) {
delete hapd[name];
delete state[name];
return;
}
/* gather initial data from hostapd */
let status = global.ubus.conn.call(path, 'get_status');
if (!status)
return;
let cfg = uci.get_all('usteer2', status.uci_section);
if (!cfg)
return;
/* subscibe to hostapd */
subscriber.subscribe(path);
/* tell hostapd to wait for a reply before answering probe requests */
//global.ubus.conn.call(path, 'notify_response', { 'notify_response': 1 });
/* tell hostapd to enable rrm/roaming */
global.ubus.conn.call(path, 'bss_mgmt_enable', { 'neighbor_report': 1, 'beacon_report': 1, 'bss_transition': 1 });
/* instantiate state */
hapd[name] = { };
state[name] = { };
for (let prop in [ 'ssid', 'bssid', 'freq', 'channel', 'op_class', 'uci_section' ])
if (status[prop])
hapd[name][prop] = status[prop];
hapd[name].config = cfg;
/* ask hostapd for the local neighbourhood report data */
let rrm = global.ubus.conn.call(path, 'rrm_nr_get_own');
if (rrm && rrm.value)
hapd[name].rrm_nr = rrm.value;
/* trigger an initial channel survey */
channel_survey(name);
}
function hapd_listener(event, msg) {
hapd_subunsub(msg.path, event == 'ubus.object.add');
}
function hapd_handle_event(req) {
/* iterate over all handlers for this event type, if 1 or more handlers replied with false, do not reply to the notification */
let reply = true;
for (let handler in handlers[req.type])
if (!handler(req.type, req.data))
reply = false;
if (!reply)
return;
req.reply();
}
return {
status: function() {
return hapd;
},
init: function() {
subscriber = global.ubus.conn.subscriber(
hapd_handle_event,
function(msg) {
// printf('2 %.J\n', msg);
});
/* register a callback that will monitor hostapd instances spawning and disappearing */
global.ubus.conn.listener('ubus.object.add', hapd_listener);
global.ubus.conn.listener('ubus.object.remove', hapd_listener);
/* iterade over all existing hostapd instances and subscribe to them */
for (let path in global.ubus.conn.list())
hapd_subunsub(path, true);
uloop_timeout(hapd_update, 5000);
},
register_handler: function(event, handler) {
/* a policy requested to be notified of action frames, register the callback */
handlers[event] ??= [];
push(handlers[event], handler);
},
};

View File

@@ -1,36 +0,0 @@
let policies = {};
return {
init: function() {
let config = global.uci.get_all('usteer2');
for (let section in config) {
if (config[section]['.type'] != 'policy' || !config[section].name)
continue;
let policy = require(`policy_${config[section].name}`);
if (type(policy) != 'object' || type(policy.init) != 'function') {
ulog_info('failed to load policy "%s"\n', config[section].name);
continue;
}
try {
policy.init(config[section]);
} catch(e) {
ulog_info('failed to initialze policy "%s"\n', config[section].name);
continue;
}
ulog_info('loaded policy "%s"\n', config[section].name);
policies[config[section].name] = policy;
}
},
status: function(msg) {
/* if no specific policies state was requested, dump the list of loaded policies */
if (msg?.name === null)
return { policies: keys(policies) };
/* check if the requested policy exists and dump its state */
if (policies[msg.name])
return policies[msg.name].status(msg);
/* return an empty dictionary */
return {};
},
};

View File

@@ -1,91 +0,0 @@
let config = {
/* how many seconds must a client be below the thershold before we kick it */
min_snr_kick_delay: 5,
/* the reson code sent when triggering the deauth (IEEE Std 802.11-2016, 9.4.1.7, Table 9-45) */
kick_reason: 5,
/* the periodicity for checking client kick conditions */
interval: 1000,
};
/* counter of how often a station was kicked */
let kick_count = 0;
let foo = 0;
function snr_update() {
try {
let iface = global.local.status();
let stations = global.station.list();
let now = time();
/* iterate over all stations and kick anything that had a signal worse than the threshold for too long */
for (let addr in stations) {
let station = stations[addr];
if (!station.signal || !station.device)
continue;
let device = iface[station.device].config;
if (!device?.client_kick_rssi)
continue;
if (0) {
foo++;
if (foo > 10)
station.signal = -80;
printf(`snr check ${addr} ${station.seen} ${station.signal} ${device.client_kick_rssi}\n`);
}
printf(`${addr} ${station.signal} ${device.client_kick_rssi}\n`);
/* ignore old stations and ones that have a good signal */
if (now - station.seen > 2 || station.signal >= device.client_kick_rssi) {
station.snr_kick_timer = 0;
continue;
}
/* find out how long the station had a bad signal for */
if (!station.snr_kick_timer)
station.snr_kick_timer = now;
if (now - station.snr_kick_timer < config.min_snr_kick_delay)
continue;
printf(`${now - station.seen}\n`);
if ((now - station.seen) > 2)
return;
/* kick the station and ban it for the configured timeout */
ulog_info(`kick ${addr} as signal (${station.signal}) is too low\n`);
global.station.kick(addr, config.kick_reason, device.client_kick_ban_time);
kick_count++;
}
} catch(e) {
printf(`snr exception ${e}\n`);
}
return config.interval;
}
function probe_handler(type, data) {
/* only send a probe request if the signal is good enough */
return (data.signal > config.min_connect_snr)
}
return {
init: function(data) {
/* load config and override defaults if they were set in UCI */
for (let key in config)
if (data[key])
config[key] = +data[key];
/* register a callback that will inspect probe-requests and prevent a reply if SNR is too low */
//global.local.register_handler('probe', probe_handler);
/* register the timer that periodically checks if a client should be kicked */
uloop_timeout(snr_update, config.interval);
},
status: function(data) {
/* dump the status of this policy */
return { config, kick_count };
},
};

View File

@@ -1,201 +0,0 @@
let stations = {};
function station_add(device, addr, data, seen) {
/* only honour stations that are authenticated */
if (!data.auth || !data.assoc)
return;
/* if the station is new, add the initial entry */
if (!stations[addr]) {
ulog_info(`add station ${ addr }\n`);
/* extract the rrm bits and give them meaningful names */
let rrm = {
link_measure: !!(data.rrm[0] & 0x1),
beacon_passive_measure: !!(data.rrm[0] & 0x10),
beacon_active_measure: !!(data.rrm[0] & 0x20),
beacon_table_measure: !!(data.rrm[0] & 0x40),
statistics_measure: !!(data.rrm[1] & 0x8),
};
/* add the new station */
stations[addr] = {
rrm,
beacon_report: {},
};
}
/* update device, seen and signal data */
stations[addr].device = device;
stations[addr].seen = seen;
if (data.signal)
stations[addr].signal = data.signal;
}
function station_del(addr) {
ulog_info(`deleting ${ addr }\n`);
delete stations[addr];
}
function stations_update() {
try {
/* lets not call time() multiple times */
let seen = time();
/* iterate over all ssids and ask hapd for the list of associations */
for (let device in global.local.status()) {
let clients = global.ubus.conn.call(`hostapd.${ device}`, 'get_clients');
for (let client in clients.clients)
if (clients.clients[client].auth)
station_add(device, client, clients.clients[client], seen);
else
station_del(client);
}
/* purge all stations that have not been seen in a while */
for (let station in stations) {
if (seen - stations[station].seen <= +global.config.station_expiry)
continue;
station_del(station);
}
} catch (e) {
printf('%.J', e);
}
/* restart the timer */
return +global.config.station_update;
}
function beacon_report(type, report) {
/* make sure that the station exists */
if (!stations[report.address]) {
ulog_err(`beacon report on unknown station ${report.address}\n`);
return false;
}
/* store the report */
stations[report.address].beacon_report[report.bssid] = {
seen: time(),
channel: report.channel,
rcpi: report.rcpi,
rsni: report.rsni,
};
}
function probe_handler(type, data) {
/* track non-associated stations SNR */
stations[data.address] = {
signal: data.signal,
connected: false,
seen: time(),
};
return true;
}
function disassoc_handler(type, data) {
station_del(data.address);
return true;
}
return {
init: function() {
/* register the mgmt frame handlers */
global.local.register_handler('beacon-report', beacon_report);
//global.local.register_handler('probe', probe_handler);
global.local.register_handler('disassoc', disassoc_handler);
/* initial probe of associated stations */
uloop_timeout(stations_update, 100);
},
status: function() {
let ret = { };
let now = time();
/* get the list of our local APs */
let local = global.local.status();
/* iterate over all APs and aggregate their associations */
for (let device in local) {
/* iterate over all known stations */
for (let addr, station in stations) {
/* match for the current AP */
if (station.device != device)
continue;
/* add the station info to the return data */
ret[addr] = {
[device]: {
signal: station.signal,
rrm: station.rrm,
last_seen: now - station.seen,
},
};
if (length(station.beacon_report))
ret[addr][device].beacon_report = station.beacon_report;
}
}
return ret;
},
beacon_request: function(addr, channel, mode, op_class, duration) {
let station = stations[addr];
/* make sure that the station exists */
if (!station) {
ulog_err(`beacon request on unknown station ${addr}`);
return false;
}
/* make sure that the station supports active beacon requests */
if (!station.rrm?.beacon_active_measure) {
ulog_err(`${addr} does not support beacon requests`);
return false;
}
station.beacon_report = {};
let payload = {
addr,
channel,
mode: mode || 1,
op_class: op_class || 128,
duration: duration || 100,
};
global.ubus.conn.call(`hostapd.${station.device}`, 'rrm_beacon_req', payload);
return true;
},
kick: function(addr, reason, ban_time) {
if (!exists(stations, addr))
return -1;
let payload = {
addr,
reason: reason || 5,
deauth: 1
};
if (ban_time)
payload.ban_time = ban_time * 1000;
/* tell hostapd to kick a station via ubus */
global.ubus.conn.call(`hostapd.${stations[addr].device}`, 'del_client', payload);
return 0;
},
list: function(msg) {
if (msg?.mac)
return stations[msg.mac] || {};
return stations;
},
steer: function(addr, imminent, neighbors) {
},
};

View File

@@ -115,11 +115,6 @@ define Package/ath11k-firmware-qcn9000/install
$(1)/lib/firmware/ath11k/QCN9074/hw1.0/ $(1)/lib/firmware/ath11k/QCN9074/hw1.0/
endef endef
define Package/ath11k-wifi-yuncore-ax840/install
$(INSTALL_DIR) $(1)/lib/firmware/ath11k/IPQ6018/hw1.0/
$(INSTALL_DATA) ./board-2.bin.IPQ6018 $(1)/lib/firmware/ath11k/IPQ6018/hw1.0/board-2.bin
endef
$(eval $(call BuildPackage,ath11k-firmware-ipq50xx)) $(eval $(call BuildPackage,ath11k-firmware-ipq50xx))
$(eval $(call BuildPackage,ath11k-firmware-ipq50xx-spruce)) $(eval $(call BuildPackage,ath11k-firmware-ipq50xx-spruce))
$(eval $(call BuildPackage,ath11k-firmware-ipq60xx)) $(eval $(call BuildPackage,ath11k-firmware-ipq60xx))

View File

@@ -36,18 +36,15 @@ ALLWIFIBOARDS:= \
sercomm-wallaby \ sercomm-wallaby \
edgecore-eap102 \ edgecore-eap102 \
edgecore-eap104 \ edgecore-eap104 \
liteon-wpx8324 \
indio-um-310ax-v1 \ indio-um-310ax-v1 \
indio-um-510axp-v1 \ indio-um-510axp-v1 \
indio-um-510axm-v1 \ indio-um-510axm-v1 \
muxi-ap3220l \
plasmacloud-pax1800 \ plasmacloud-pax1800 \
wallys-dr6018 \ wallys-dr6018 \
wallys-dr6018-v4 \ wallys-dr6018-v4 \
tplink-ex227 \ tplink-ex227 \
tplink-ex447 \ tplink-ex447 \
yuncore-ax840 \ yuncore-ax840 \
yuncore-fap650 \
meshpp-s618 meshpp-s618
ALLWIFIPACKAGES:=$(foreach BOARD,$(ALLWIFIBOARDS),ath11k-wifi-$(BOARD)) ALLWIFIPACKAGES:=$(foreach BOARD,$(ALLWIFIBOARDS),ath11k-wifi-$(BOARD))
@@ -246,7 +243,6 @@ $(eval $(call generate-ath11k-wifi-package,wallys-dr6018-v4,Wallys DR6018 V4))
$(eval $(call generate-ath11k-wifi-package,edgecore-eap101,EdgeCore EAP101)) $(eval $(call generate-ath11k-wifi-package,edgecore-eap101,EdgeCore EAP101))
$(eval $(call generate-ath11k-wifi-package,edgecore-eap102,Edgecore EAP102)) $(eval $(call generate-ath11k-wifi-package,edgecore-eap102,Edgecore EAP102))
$(eval $(call generate-ath11k-wifi-package,edgecore-eap104,Edgecore EAP104)) $(eval $(call generate-ath11k-wifi-package,edgecore-eap104,Edgecore EAP104))
$(eval $(call generate-ath11k-wifi-package,liteon-wpx8324,Liteon WPX8324))
$(eval $(call generate-ath11k-wifi-package,indio-um-310ax-v1,Indio UM-310AX V1)) $(eval $(call generate-ath11k-wifi-package,indio-um-310ax-v1,Indio UM-310AX V1))
$(eval $(call generate-ath11k-wifi-package,indio-um-510axp-v1,Indio UM-510AXP V1)) $(eval $(call generate-ath11k-wifi-package,indio-um-510axp-v1,Indio UM-510AXP V1))
$(eval $(call generate-ath11k-wifi-package,indio-um-510axm-v1,Indio UM-510AXM V1)) $(eval $(call generate-ath11k-wifi-package,indio-um-510axm-v1,Indio UM-510AXM V1))
@@ -254,8 +250,6 @@ $(eval $(call generate-ath11k-wifi-package,tplink-ex227,TP-Link EX227))
$(eval $(call generate-ath11k-wifi-package,tplink-ex447,TP-Link EX447)) $(eval $(call generate-ath11k-wifi-package,tplink-ex447,TP-Link EX447))
$(eval $(call generate-ath11k-wifi-package,yuncore-ax840,YunCore AX840)) $(eval $(call generate-ath11k-wifi-package,yuncore-ax840,YunCore AX840))
$(eval $(call generate-ath11k-wifi-package,meshpp-s618,Mesh++ S618)) $(eval $(call generate-ath11k-wifi-package,meshpp-s618,Mesh++ S618))
$(eval $(call generate-ath11k-wifi-package,muxi-ap3220l,MUXI AP3220L))
$(eval $(call generate-ath11k-wifi-package,yuncore-fap650,YunCore FAP650))
$(foreach PACKAGE,$(ALLWIFIPACKAGES),$(eval $(call BuildPackage,$(PACKAGE)))) $(foreach PACKAGE,$(ALLWIFIPACKAGES),$(eval $(call BuildPackage,$(PACKAGE))))
$(eval $(call BuildPackage,ath11k-wifi-qcom-ipq5018)) $(eval $(call BuildPackage,ath11k-wifi-qcom-ipq5018))

View File

@@ -117,7 +117,6 @@ hostapd_common_add_device_config() {
config_add_int rssi_reject_assoc_rssi config_add_int rssi_reject_assoc_rssi
config_add_int rssi_ignore_probe_request config_add_int rssi_ignore_probe_request
config_add_int maxassoc config_add_int maxassoc
config_add_boolean maxassoc_ignore_probe
config_add_string acs_chan_bias config_add_string acs_chan_bias
config_add_boolean acs_exclude_dfs config_add_boolean acs_exclude_dfs
@@ -139,8 +138,7 @@ hostapd_prepare_device_config() {
json_get_vars country country3 country_ie beacon_int:100 dtim_period:2 doth require_mode legacy_rates \ json_get_vars country country3 country_ie beacon_int:100 dtim_period:2 doth require_mode legacy_rates \
acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \ acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \
rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc \ rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc \
multiple_bssid he_co_locate rnr_beacon ema acs_exclude_dfs \ multiple_bssid he_co_locate rnr_beacon ema acs_exclude_dfs
maxassoc_ignore_probe
hostapd_set_log_options base_cfg hostapd_set_log_options base_cfg
@@ -247,7 +245,6 @@ hostapd_prepare_device_config() {
append base_cfg "dtim_period=$dtim_period" "$N" append base_cfg "dtim_period=$dtim_period" "$N"
[ "$airtime_mode" -gt 0 ] && append base_cfg "airtime_mode=$airtime_mode" "$N" [ "$airtime_mode" -gt 0 ] && append base_cfg "airtime_mode=$airtime_mode" "$N"
[ -n "$maxassoc" ] && append base_cfg "iface_max_num_sta=$maxassoc" "$N" [ -n "$maxassoc" ] && append base_cfg "iface_max_num_sta=$maxassoc" "$N"
[ "$maxassoc_ignore_probe" -gt 0 ] && append base_cfg "no_probe_resp_if_max_sta=1" "$N"
[ "$rnr_beacon" -gt 0 ] && append base_cfg "rnr_beacon=$rnr_beacon" "$N" [ "$rnr_beacon" -gt 0 ] && append base_cfg "rnr_beacon=$rnr_beacon" "$N"
[ "$he_co_locate" -gt 0 ] && append base_cfg "he_co_locate=$he_co_locate" "$N" [ "$he_co_locate" -gt 0 ] && append base_cfg "he_co_locate=$he_co_locate" "$N"
[ "$multiple_bssid" -gt 0 ] && append base_cfg "multiple_bssid=$multiple_bssid" "$N" [ "$multiple_bssid" -gt 0 ] && append base_cfg "multiple_bssid=$multiple_bssid" "$N"
@@ -395,10 +392,6 @@ hostapd_common_add_bss_config() {
config_add_string fils_dhcp config_add_string fils_dhcp
config_add_boolean ratelimit config_add_boolean ratelimit
config_add_string uci_section
config_add_boolean dynamic_probe_resp
} }
hostapd_set_vlan_file() { hostapd_set_vlan_file() {
@@ -552,13 +545,11 @@ append_radius_server() {
json_get_vars \ json_get_vars \
auth_server auth_secret auth_port \ auth_server auth_secret auth_port \
dae_client dae_secret dae_port \ dae_client dae_secret dae_port \
dynamic_ownip ownip radius_client_addr \ ownip radius_client_addr \
eap_reauth_period request_cui \ eap_reauth_period request_cui \
erp_domain mobility_domain \ erp_domain mobility_domain \
fils_realm fils_dhcp fils_realm fils_dhcp
set_default dynamic_ownip 1
# legacy compatibility # legacy compatibility
[ -n "$auth_server" ] || json_get_var auth_server server [ -n "$auth_server" ] || json_get_var auth_server server
[ -n "$auth_port" ] || json_get_var auth_port port [ -n "$auth_port" ] || json_get_var auth_port port
@@ -607,12 +598,7 @@ append_radius_server() {
} }
json_for_each_item append_radius_auth_req_attr radius_auth_req_attr json_for_each_item append_radius_auth_req_attr radius_auth_req_attr
if [ -n "$ownip" ]; then [ -n "$ownip" ] && append bss_conf "own_ip_addr=$ownip" "$N"
append bss_conf "own_ip_addr=$ownip" "$N"
elif [ "$dynamic_ownip" -gt 0 ]; then
append bss_conf "dynamic_own_ip_addr=$dynamic_ownip" "$N"
fi
[ -n "$radius_client_addr" ] && append bss_conf "radius_client_addr=$radius_client_addr" "$N" [ -n "$radius_client_addr" ] && append bss_conf "radius_client_addr=$radius_client_addr" "$N"
[ "$macfilter" = radius ] && append bss_conf "macaddr_acl=2" "$N" [ "$macfilter" = radius ] && append bss_conf "macaddr_acl=2" "$N"
} }
@@ -641,7 +627,7 @@ hostapd_set_bss_options() {
airtime_bss_weight airtime_bss_limit airtime_sta_weight \ airtime_bss_weight airtime_bss_limit airtime_sta_weight \
multicast_to_unicast_all proxy_arp per_sta_vif \ multicast_to_unicast_all proxy_arp per_sta_vif \
eap_server eap_user_file ca_cert server_cert private_key private_key_passwd server_id \ eap_server eap_user_file ca_cert server_cert private_key private_key_passwd server_id \
vendor_elements fils uci_section dynamic_probe_resp vendor_elements fils
set_default fils 0 set_default fils 0
set_default isolate 0 set_default isolate 0
@@ -664,7 +650,6 @@ hostapd_set_bss_options() {
set_default airtime_bss_weight 0 set_default airtime_bss_weight 0
set_default airtime_bss_limit 0 set_default airtime_bss_limit 0
set_default eap_server 0 set_default eap_server 0
set_default dynamic_probe_resp 0
/usr/sbin/hostapd -vfils || fils=0 /usr/sbin/hostapd -vfils || fils=0
@@ -690,7 +675,6 @@ hostapd_set_bss_options() {
append bss_conf "preamble=$short_preamble" "$N" append bss_conf "preamble=$short_preamble" "$N"
append bss_conf "wmm_enabled=$wmm" "$N" append bss_conf "wmm_enabled=$wmm" "$N"
append bss_conf "ignore_broadcast_ssid=$hidden" "$N" append bss_conf "ignore_broadcast_ssid=$hidden" "$N"
append bss_conf "dynamic_probe_resp=$dynamic_probe_resp" "$N"
append bss_conf "uapsd_advertisement_enabled=$uapsd" "$N" append bss_conf "uapsd_advertisement_enabled=$uapsd" "$N"
append bss_conf "utf8_ssid=$utf8_ssid" "$N" append bss_conf "utf8_ssid=$utf8_ssid" "$N"
append bss_conf "multi_ap=$multi_ap" "$N" append bss_conf "multi_ap=$multi_ap" "$N"
@@ -705,9 +689,7 @@ hostapd_set_bss_options() {
[ -n "$wpa_strict_rekey" ] && append bss_conf "wpa_strict_rekey=$wpa_strict_rekey" "$N" [ -n "$wpa_strict_rekey" ] && append bss_conf "wpa_strict_rekey=$wpa_strict_rekey" "$N"
} }
set_default nasid "${macaddr//\:}" [ -n "$nasid" ] && append bss_conf "nas_identifier=$nasid" "$N"
append bss_conf "nas_identifier=$nasid" "$N"
[ -n "$acct_server" ] && { [ -n "$acct_server" ] && {
append bss_conf "acct_server_addr=$acct_server" "$N" append bss_conf "acct_server_addr=$acct_server" "$N"
append bss_conf "acct_server_port=$acct_port" "$N" append bss_conf "acct_server_port=$acct_port" "$N"
@@ -925,6 +907,7 @@ hostapd_set_bss_options() {
append bss_conf "ft_psk_generate_local=$ft_psk_generate_local" "$N" append bss_conf "ft_psk_generate_local=$ft_psk_generate_local" "$N"
append bss_conf "ft_over_ds=$ft_over_ds" "$N" append bss_conf "ft_over_ds=$ft_over_ds" "$N"
append bss_conf "reassociation_deadline=$reassociation_deadline" "$N" append bss_conf "reassociation_deadline=$reassociation_deadline" "$N"
[ -n "$nasid" ] || append bss_conf "nas_identifier=${macaddr//\:}" "$N"
if [ "$skip_kh_setup" -eq "0" ]; then if [ "$skip_kh_setup" -eq "0" ]; then
json_get_vars r0_key_lifetime r1_key_holder pmk_r1_push json_get_vars r0_key_lifetime r1_key_holder pmk_r1_push
@@ -1169,8 +1152,6 @@ hostapd_set_bss_options() {
append bss_conf "per_sta_vif=$per_sta_vif" "$N" append bss_conf "per_sta_vif=$per_sta_vif" "$N"
fi fi
[ -n "$uci_section" ] && append bss_conf "uci_section=$uci_section" "$N"
json_get_values opts hostapd_bss_options json_get_values opts hostapd_bss_options
for val in $opts; do for val in $opts; do
append bss_conf "$val" "$N" append bss_conf "$val" "$N"

View File

@@ -120,7 +120,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c
else else
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
- os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr)); - os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr));
+ os_snprintf(buf, sizeof(buf), MACSTR " %d %d", MAC2STR(sta->addr), sta->bandwidth[0] / 1000000, sta->bandwidth[1] / 1000000); + os_snprintf(buf, sizeof(buf), MACSTR " %d %d", MAC2STR(sta->addr), sta->bandwidth[0] / 1000, sta->bandwidth[1] / 1000);
if (hapd->sta_authorized_cb) if (hapd->sta_authorized_cb)
hapd->sta_authorized_cb(hapd->sta_authorized_cb_ctx, hapd->sta_authorized_cb(hapd->sta_authorized_cb_ctx,

View File

@@ -1,109 +0,0 @@
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -311,6 +311,7 @@ struct hostapd_bss_config {
unsigned int eap_sim_db_timeout;
int eap_server_erp; /* Whether ERP is enabled on internal EAP server */
struct hostapd_ip_addr own_ip_addr;
+ int dynamic_own_ip_addr;
char *nas_identifier;
struct hostapd_radius_servers *radius;
int acct_interim_interval;
--- a/src/radius/radius_client.c
+++ b/src/radius/radius_client.c
@@ -163,6 +163,8 @@ struct radius_client_data {
*/
void *ctx;
+ struct hostapd_ip_addr local_ip;
+
/**
* conf - RADIUS client configuration (list of RADIUS servers to use)
*/
@@ -720,6 +722,30 @@ static void radius_client_list_add(struc
/**
+ * radius_client_send - Get local address for the RADIUS auth socket
+ * @radius: RADIUS client context from radius_client_init()
+ * @addr: pointer to store the address
+ *
+ * This function returns the local address for the connection to the RADIUS
+ * auth server. It also opens the socket if it's not available yet.
+ */
+int radius_client_get_local_addr(struct radius_client_data *radius,
+ struct hostapd_ip_addr *addr)
+{
+ struct hostapd_radius_servers *conf = radius->conf;
+
+ if (conf->auth_server && radius->auth_sock < 0)
+ radius_client_init_auth(radius);
+
+ if (radius->auth_sock < 0)
+ return -1;
+
+ memcpy(addr, &radius->local_ip, sizeof(*addr));
+
+ return 0;
+}
+
+/**
* radius_client_send - Send a RADIUS request
* @radius: RADIUS client context from radius_client_init()
* @msg: RADIUS message to be sent
@@ -1238,6 +1264,10 @@ radius_change_server(struct radius_clien
wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u",
inet_ntoa(claddr.sin_addr),
ntohs(claddr.sin_port));
+ if (auth) {
+ radius->local_ip.af = AF_INET;
+ radius->local_ip.u.v4 = claddr.sin_addr;
+ }
}
break;
#ifdef CONFIG_IPV6
@@ -1249,6 +1279,10 @@ radius_change_server(struct radius_clien
inet_ntop(AF_INET6, &claddr6.sin6_addr,
abuf, sizeof(abuf)),
ntohs(claddr6.sin6_port));
+ if (auth) {
+ radius->local_ip.af = AF_INET6;
+ radius->local_ip.u.v6 = claddr6.sin6_addr;
+ }
}
break;
}
--- a/src/radius/radius_client.h
+++ b/src/radius/radius_client.h
@@ -249,6 +249,8 @@ int radius_client_register(struct radius
void radius_client_set_interim_error_cb(struct radius_client_data *radius,
void (*cb)(const u8 *addr, void *ctx),
void *ctx);
+int radius_client_get_local_addr(struct radius_client_data *radius,
+ struct hostapd_ip_addr * addr);
int radius_client_send(struct radius_client_data *radius,
struct radius_msg *msg,
RadiusType msg_type, const u8 *addr);
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -535,6 +535,10 @@ int add_common_radius_attr(struct hostap
struct hostapd_radius_attr *attr;
int len;
+ if (hapd->conf->dynamic_own_ip_addr)
+ radius_client_get_local_addr(hapd->radius,
+ &hapd->conf->own_ip_addr);
+
if (!hostapd_config_get_radius_attr(req_attr,
RADIUS_ATTR_NAS_IP_ADDRESS) &&
hapd->conf->own_ip_addr.af == AF_INET &&
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2681,6 +2681,8 @@ static int hostapd_config_fill(struct ho
} else if (os_strcmp(buf, "iapp_interface") == 0) {
wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used");
#endif /* CONFIG_IAPP */
+ } else if (os_strcmp(buf, "dynamic_own_ip_addr") == 0) {
+ bss->dynamic_own_ip_addr = atoi(pos);
} else if (os_strcmp(buf, "own_ip_addr") == 0) {
if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) {
wpa_printf(MSG_ERROR,

View File

@@ -1,298 +1,76 @@
--- a/src/radius/radius_das.h Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
+++ b/src/radius/radius_das.h ===================================================================
@@ -44,6 +44,7 @@ struct radius_das_attrs { --- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c
struct radius_das_conf { +++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
int port; @@ -862,7 +862,6 @@ static int hostapd_das_nas_mismatch(stru
const u8 *shared_secret; return 0;
+ const u8 *nas_identifier; }
size_t shared_secret_len;
const struct hostapd_ip_addr *client_addr;
unsigned int time_window;
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -1367,6 +1367,7 @@ static int hostapd_setup_bss(struct host
struct radius_das_conf das_conf;
os_memset(&das_conf, 0, sizeof(das_conf));
das_conf.port = conf->radius_das_port;
+ das_conf.nas_identifier = conf->nas_identifier;
das_conf.shared_secret = conf->radius_das_shared_secret;
das_conf.shared_secret_len =
conf->radius_das_shared_secret_len;
--- a/src/radius/radius_das.c
+++ b/src/radius/radius_das.c
@@ -12,13 +12,26 @@
#include "utils/common.h"
#include "utils/eloop.h"
#include "utils/ip_addr.h"
+#include "utils/list.h"
#include "radius.h"
#include "radius_das.h"
-
-struct radius_das_data { static struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd,
+static struct dl_list das_ports = DL_LIST_HEAD_INIT(das_ports); struct radius_das_attrs *attr,
+ int *multi)
+struct radius_das_port { @@ -1050,6 +1049,24 @@ static int hostapd_das_disconnect_pmksa(
+ struct dl_list list;
+ struct dl_list das_data;
+
+ int port;
int sock;
+};
+
+struct radius_das_data {
+ struct dl_list list;
+ struct radius_das_port *port;
u8 *shared_secret;
+ u8 *nas_identifier;
size_t shared_secret_len;
struct hostapd_ip_addr client_addr;
unsigned int time_window;
@@ -378,56 +391,17 @@ fail:
} }
-static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) +static struct hostapd_data * ap_get_hapd(struct hostapd_data *hapd, struct radius_das_attrs *attr)
+static void
+radius_das_receive_msg(struct radius_das_data *das, struct radius_msg *msg,
+ struct sockaddr *from, socklen_t fromlen,
+ char *abuf, int from_port)
{
- struct radius_das_data *das = eloop_ctx;
- u8 buf[1500];
- union {
- struct sockaddr_storage ss;
- struct sockaddr_in sin;
-#ifdef CONFIG_IPV6
- struct sockaddr_in6 sin6;
-#endif /* CONFIG_IPV6 */
- } from;
- char abuf[50];
- int from_port = 0;
- socklen_t fromlen;
- int len;
- struct radius_msg *msg, *reply = NULL;
+ struct radius_msg *reply = NULL;
struct radius_hdr *hdr;
struct wpabuf *rbuf;
+ struct os_time now;
u32 val;
int res;
- struct os_time now;
-
- fromlen = sizeof(from);
- len = recvfrom(sock, buf, sizeof(buf), 0,
- (struct sockaddr *) &from.ss, &fromlen);
- if (len < 0) {
- wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno));
- return;
- }
-
- os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
- from_port = ntohs(from.sin.sin_port);
-
- wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d",
- len, abuf, from_port);
- if (das->client_addr.u.v4.s_addr &&
- das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr) {
- wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client");
- return;
- }
-
- msg = radius_msg_parse(buf, len);
- if (msg == NULL) {
- wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet "
- "from %s:%d failed", abuf, from_port);
- return;
- }
-
- if (wpa_debug_level <= MSG_MSGDUMP)
- radius_msg_dump(msg);
if (radius_msg_verify_das_req(msg, das->shared_secret,
das->shared_secret_len,
@@ -494,9 +468,8 @@ static void radius_das_receive(int sock,
radius_msg_dump(reply);
rbuf = radius_msg_get_buf(reply);
- res = sendto(das->sock, wpabuf_head(rbuf),
- wpabuf_len(rbuf), 0,
- (struct sockaddr *) &from.ss, fromlen);
+ res = sendto(das->port->sock, wpabuf_head(rbuf),
+ wpabuf_len(rbuf), 0, from, fromlen);
if (res < 0) {
wpa_printf(MSG_ERROR, "DAS: sendto(to %s:%d): %s",
abuf, from_port, strerror(errno));
@@ -508,6 +481,72 @@ fail:
radius_msg_free(reply);
}
+static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx)
+{ +{
+ struct radius_das_port *p = eloop_ctx; + size_t i;
+ struct radius_das_data *das; + int multi;
+ u8 buf[1500];
+ union {
+ struct sockaddr_storage ss;
+ struct sockaddr_in sin;
+#ifdef CONFIG_IPV6
+ struct sockaddr_in6 sin6;
+#endif /* CONFIG_IPV6 */
+ } from;
+ struct radius_msg *msg;
+ size_t nasid_len = 0;
+ u8 *nasid_buf = NULL;
+ char abuf[50];
+ int from_port = 0;
+ socklen_t fromlen;
+ int found = 0;
+ int len;
+ +
+ fromlen = sizeof(from); + for (i = 0; i < hapd->iface->num_bss; i++) {
+ len = recvfrom(sock, buf, sizeof(buf), 0, + if (!hapd->iface->bss[i]->iface->bss[i]->radius_das)
+ (struct sockaddr *) &from.ss, &fromlen);
+ if (len < 0) {
+ wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno));
+ return;
+ }
+
+ os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
+ from_port = ntohs(from.sin.sin_port);
+
+ msg = radius_msg_parse(buf, len);
+ if (msg == NULL) {
+ wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet "
+ "from %s:%d failed", abuf, from_port);
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d",
+ len, abuf, from_port);
+
+ if (wpa_debug_level <= MSG_MSGDUMP)
+ radius_msg_dump(msg);
+
+ radius_msg_get_attr_ptr(msg, RADIUS_ATTR_NAS_IDENTIFIER,
+ &nasid_buf, &nasid_len, NULL);
+ dl_list_for_each(das, &p->das_data, struct radius_das_data, list) {
+ if (das->client_addr.u.v4.s_addr &&
+ das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr)
+ continue; + continue;
+ + if (hapd->conf->radius_das_port !=hapd->iface->bss[i]->iface->bss[i]->conf->radius_das_port)
+ if (das->nas_identifier && nasid_buf &&
+ (nasid_len != os_strlen(das->nas_identifier) ||
+ os_memcmp(das->nas_identifier, nasid_buf, nasid_len) != 0))
+ continue; + continue;
+ + if (hostapd_das_find_sta(hapd, attr, &multi))
+ found = 1; + return hapd->iface->bss[i];
+ radius_das_receive_msg(das, msg, (struct sockaddr *)&from.ss,
+ fromlen, abuf, from_port);
+ } + }
+ + return hapd;
+ if (!found)
+ wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client");
+} +}
+ +
+
static int radius_das_open_socket(int port) +
static enum radius_das_res
hostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr)
{ {
@@ -533,6 +572,49 @@ static int radius_das_open_socket(int po @@ -1057,6 +1074,10 @@ hostapd_das_disconnect(void *ctx, struct
} struct sta_info *sta;
int multi;
+ hapd = ap_get_hapd(hapd, attr);
+ if (!hapd)
+ return RADIUS_DAS_SESSION_NOT_FOUND;
+
if (hostapd_das_nas_mismatch(hapd, attr))
return RADIUS_DAS_NAS_MISMATCH;
+static struct radius_das_port * @@ -1096,6 +1117,10 @@ hostapd_das_coa(void *ctx, struct radius
+radius_das_open_port(int port) struct sta_info *sta;
+{ int multi;
+ struct radius_das_port *p;
+
+ dl_list_for_each(p, &das_ports, struct radius_das_port, list) {
+ if (p->port == port)
+ return p;
+ }
+
+ p = os_zalloc(sizeof(*p));
+ if (p == NULL)
+ return NULL;
+
+ dl_list_init(&p->das_data);
+ p->port = port;
+ p->sock = radius_das_open_socket(port);
+ if (p->sock < 0)
+ goto free_port;
+
+ if (eloop_register_read_sock(p->sock, radius_das_receive, p, NULL))
+ goto close_port;
+
+ dl_list_add(&das_ports, &p->list);
+
+ return p;
+
+close_port:
+ close(p->sock);
+free_port:
+ os_free(p);
+
+ return NULL;
+}
+
+static void radius_das_close_port(struct radius_das_port *p)
+{
+ dl_list_del(&p->list);
+ eloop_unregister_read_sock(p->sock);
+ close(p->sock);
+ free(p);
+}
+
struct radius_das_data *
radius_das_init(struct radius_das_conf *conf)
{
@@ -553,6 +635,8 @@ radius_das_init(struct radius_das_conf *
das->ctx = conf->ctx;
das->disconnect = conf->disconnect;
das->coa = conf->coa;
+ if (conf->nas_identifier)
+ das->nas_identifier = os_strdup(conf->nas_identifier);
os_memcpy(&das->client_addr, conf->client_addr, + hapd = ap_get_hapd(hapd, attr);
sizeof(das->client_addr)); + if (!hapd)
@@ -565,19 +649,15 @@ radius_das_init(struct radius_das_conf * + return RADIUS_DAS_SESSION_NOT_FOUND;
} +
das->shared_secret_len = conf->shared_secret_len; if (hostapd_das_nas_mismatch(hapd, attr))
return RADIUS_DAS_NAS_MISMATCH;
- das->sock = radius_das_open_socket(conf->port); Index: hostapd-2021-02-20-59e9794c/src/radius/radius_das.c
- if (das->sock < 0) { ===================================================================
+ das->port = radius_das_open_port(conf->port); --- hostapd-2021-02-20-59e9794c.orig/src/radius/radius_das.c
+ if (!das->port) { +++ hostapd-2021-02-20-59e9794c/src/radius/radius_das.c
wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS " @@ -568,10 +568,9 @@ radius_das_init(struct radius_das_conf *
das->sock = radius_das_open_socket(conf->port);
if (das->sock < 0) {
- wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS "
+ wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS - reusing existing port "
"DAS"); "DAS");
radius_das_deinit(das);
return NULL;
}
- if (eloop_register_read_sock(das->sock, radius_das_receive, das, NULL))
- {
- radius_das_deinit(das); - radius_das_deinit(das);
- return NULL; - return NULL;
- } + return das;
+ dl_list_add(&das->port->das_data, &das->list);
return das;
}
@@ -588,11 +668,14 @@ void radius_das_deinit(struct radius_das
if (das == NULL)
return;
- if (das->sock >= 0) {
- eloop_unregister_read_sock(das->sock);
- close(das->sock);
+ if (das->port) {
+ dl_list_del(&das->list);
+
+ if (dl_list_empty(&das->port->das_data))
+ radius_das_close_port(das->port);
} }
+ os_free(das->nas_identifier); if (eloop_register_read_sock(das->sock, radius_das_receive, das, NULL))
os_free(das->shared_secret);
os_free(das);
}

View File

@@ -1,51 +0,0 @@
Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c
+++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c
@@ -2366,6 +2366,8 @@ static int hostapd_config_fill(struct ho
return 1;
}
conf->driver = driver;
+ } else if (os_strcmp(buf, "uci_section") == 0) {
+ bss->uci_section = os_strdup(pos);
} else if (os_strcmp(buf, "driver_params") == 0) {
os_free(conf->driver_params);
conf->driver_params = os_strdup(pos);
Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.h
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/ap_config.h
+++ hostapd-2021-02-20-59e9794c/src/ap/ap_config.h
@@ -279,6 +279,7 @@ struct hostapd_bss_config {
char snoop_iface[IFNAMSIZ + 1];
char vlan_bridge[IFNAMSIZ + 1];
char wds_bridge[IFNAMSIZ + 1];
+ char *uci_section;
char *config_id;
Index: hostapd-2021-02-20-59e9794c/src/ap/ubus.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/ubus.c
+++ hostapd-2021-02-20-59e9794c/src/ap/ubus.c
@@ -467,6 +467,9 @@ hostapd_bss_get_status(struct ubus_conte
hapd->iface->cac_started ? hapd->iface->dfs_cac_ms / 1000 - now.sec : 0);
blobmsg_close_table(&b, dfs_table);
+ if (hapd->conf->uci_section)
+ blobmsg_add_string(&b, "uci_section", hapd->conf->uci_section);
+
ubus_send_reply(ctx, req, b.head);
return 0;
Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/ap_config.c
+++ hostapd-2021-02-20-59e9794c/src/ap/ap_config.c
@@ -785,6 +785,7 @@ void hostapd_config_free_bss(struct host
os_free(conf->radius_req_attr_sqlite);
os_free(conf->rsn_preauth_interfaces);
os_free(conf->ctrl_interface);
+ os_free(conf->uci_section);
os_free(conf->config_id);
os_free(conf->ca_cert);
os_free(conf->server_cert);

View File

@@ -1,49 +0,0 @@
Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c
+++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c
@@ -3339,6 +3339,8 @@ static int hostapd_config_fill(struct ho
bss->ignore_broadcast_ssid = atoi(pos);
} else if (os_strcmp(buf, "no_probe_resp_if_max_sta") == 0) {
bss->no_probe_resp_if_max_sta = atoi(pos);
+ } else if (os_strcmp(buf, "dynamic_probe_resp") == 0) {
+ bss->dynamic_probe_resp = atoi(pos);
#ifdef CONFIG_WEP
} else if (os_strcmp(buf, "wep_default_key") == 0) {
bss->ssid.wep.idx = atoi(pos);
Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.h
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/ap_config.h
+++ hostapd-2021-02-20-59e9794c/src/ap/ap_config.h
@@ -460,6 +460,7 @@ struct hostapd_bss_config {
int ap_max_inactivity;
int ignore_broadcast_ssid;
int no_probe_resp_if_max_sta;
+ int dynamic_probe_resp;
int wmm_enabled;
int wmm_uapsd;
Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/beacon.c
+++ hostapd-2021-02-20-59e9794c/src/ap/beacon.c
@@ -920,7 +920,8 @@ void handle_probe_req(struct hostapd_dat
}
#endif /* CONFIG_P2P */
- if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 &&
+ if (!hapd->conf->dynamic_probe_resp &&
+ hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 &&
elems.ssid_list_len == 0 && elems.short_ssid_list_len == 0) {
wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
"broadcast SSID ignored", MAC2STR(mgmt->sa));
@@ -967,7 +968,8 @@ void handle_probe_req(struct hostapd_dat
return;
}
- if (hapd->conf->ignore_broadcast_ssid && res == WILDCARD_SSID_MATCH) {
+ if (!hapd->conf->dynamic_probe_resp &&
+ hapd->conf->ignore_broadcast_ssid && res == WILDCARD_SSID_MATCH) {
wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
"broadcast SSID ignored", MAC2STR(mgmt->sa));
return;

View File

@@ -533,7 +533,7 @@ mac80211_generate_mac() {
local ref="$(cat /sys/class/ieee80211/${phy}/macaddress)" local ref="$(cat /sys/class/ieee80211/${phy}/macaddress)"
local mask="$(cat /sys/class/ieee80211/${phy}/address_mask)" local mask="$(cat /sys/class/ieee80211/${phy}/address_mask)"
[ "$mask" = "00:00:00:00:00:00" -a "$multiple_bssid" != 1 ] && { [ "$mask" = "00:00:00:00:00:00" -a "$multiple_bssid" -neq 1 ] && {
mask="ff:ff:ff:ff:ff:ff"; mask="ff:ff:ff:ff:ff:ff";
[ "$(wc -l < /sys/class/ieee80211/${phy}/addresses)" -gt $id ] && { [ "$(wc -l < /sys/class/ieee80211/${phy}/addresses)" -gt $id ] && {

View File

@@ -2,22 +2,11 @@ Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/q
=================================================================== ===================================================================
--- backports-20210222_001-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/qmi.c --- backports-20210222_001-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/qmi.c
+++ backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/qmi.c +++ backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/qmi.c
@@ -3161,6 +3161,23 @@ out_req: @@ -3161,6 +3161,12 @@ out_req:
return ret; return ret;
} }
+static const struct firmware *fw_macs; +static const struct firmware *fw_macs;
+static int fw_macs_num = 0;
+
+int ath11k_get_custom_macs_num(int num)
+{
+ int ret = fw_macs_num;
+
+ fw_macs_num += num;
+
+ return ret;
+}
+
+const struct firmware* ath11k_get_custom_macs(void) +const struct firmware* ath11k_get_custom_macs(void)
+{ +{
+ return fw_macs; + return fw_macs;
@@ -26,7 +15,7 @@ Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/q
static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab) static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
{ {
char filename[ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE]; char filename[ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE];
@@ -3188,6 +3205,8 @@ static int ath11k_qmi_load_bdf_qmi(struc @@ -3188,6 +3194,8 @@ static int ath11k_qmi_load_bdf_qmi(struc
goto out; goto out;
} }
@@ -47,12 +36,11 @@ Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/w
struct wmi_tlv_policy { struct wmi_tlv_policy {
size_t min_len; size_t min_len;
@@ -7268,11 +7269,15 @@ mem_free: @@ -7278,11 +7279,14 @@ mem_free:
return ret; return ret;
} }
+const struct firmware* ath11k_get_custom_macs(void); +const struct firmware* ath11k_get_custom_macs(void);
+int ath11k_get_custom_macs_num(int num);
+ +
static int ath11k_wmi_tlv_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len, static int ath11k_wmi_tlv_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len,
const void *ptr, void *data) const void *ptr, void *data)
@@ -63,18 +51,17 @@ Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/w
struct wmi_mac_addr *addr_list; struct wmi_mac_addr *addr_list;
struct ath11k_pdev *pdev; struct ath11k_pdev *pdev;
u32 num_mac_addr; u32 num_mac_addr;
@@ -7297,6 +7302,20 @@ static int ath11k_wmi_tlv_rdy_parse(stru @@ -7307,6 +7311,19 @@ static int ath11k_wmi_tlv_rdy_parse(stru
addr_list = (struct wmi_mac_addr *)ptr; addr_list = (struct wmi_mac_addr *)ptr;
num_mac_addr = rdy_parse->num_extra_mac_addr; num_mac_addr = rdy_parse->num_extra_mac_addr;
+ fw_entry = ath11k_get_custom_macs(); + fw_entry = ath11k_get_custom_macs();
+ if (fw_entry) { + if (fw_entry) {
+ int num = ath11k_get_custom_macs_num(ab->num_radios);
+ printk("applying ath11k-macs\n"); + printk("applying ath11k-macs\n");
+ if (fw_entry->size >= ((num + ab->num_radios) * 6)) { + if (fw_entry->size >= (ab->num_radios * 6)) {
+ for (i = 0; i < ab->num_radios; i++) { + for (i = 0; i < ab->num_radios; i++) {
+ pdev = &ab->pdevs[i]; + pdev = &ab->pdevs[i];
+ ether_addr_copy(pdev->mac_addr, &fw_entry->data[(num + i) * 6]); + ether_addr_copy(pdev->mac_addr, &fw_entry->data[i * 6]);
+ } + }
+ } + }
+ ab->pdevs_macaddr_valid = true; + ab->pdevs_macaddr_valid = true;

View File

@@ -1,12 +0,0 @@
Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/mac.c
===================================================================
--- backports-20210222_001-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/mac.c
+++ backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/mac.c
@@ -9356,6 +9356,7 @@ static int __ath11k_mac_register(struct
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_BSS_COLOR);
+ wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
if (test_bit(WMI_TLV_SERVICE_SCAN_PHYMODE_SUPPORT,
ar->ab->wmi_ab.svc_map))

View File

@@ -17,7 +17,7 @@ index 3f75411a43..7cf16e68e0 100644
mount_root mount_root
boot_run_hook preinit_mount_root boot_run_hook preinit_mount_root
- [ -f /sysupgrade.tgz ] && { - [ -f /sysupgrade.tgz ] && {
+ (tar tzf /sysupgrade.tgz | grep -q ucentral) 2> /dev/null + (tar tf /sysupgrade.tgz | grep ucentral) 2> /dev/null
+ [ $? -eq 0 ] && { + [ $? -eq 0 ] && {
echo "- config restore -" echo "- config restore -"
cp /etc/passwd /etc/group /etc/shadow /tmp cp /etc/passwd /etc/group /etc/shadow /tmp

Some files were not shown because too many files have changed in this diff Show More