329 lines
7.3 KiB
Bash
329 lines
7.3 KiB
Bash
#!/bin/sh
|
|
. /lib/netifd/netifd-wireless.sh
|
|
. /lib/netifd/quantenna.sh
|
|
|
|
init_wireless_driver "$@"
|
|
|
|
# primarily to allow RPC API call debugging
|
|
quantenna_call() {
|
|
logger "Calling qcsapi_sockrpc" $*
|
|
qcsapi_sockrpc $*
|
|
}
|
|
|
|
quantenna_rfenable() {
|
|
local enable=$1
|
|
|
|
# compat: fw v36 req "wifi0" arg, v37 (and later?) does not
|
|
case "$(quantenna_api_ver)" in
|
|
v36)
|
|
quantenna_call rfenable $(quantenna_primaryif) $enable
|
|
;;
|
|
*)
|
|
quantenna_call rfenable $enable
|
|
;;
|
|
esac
|
|
}
|
|
|
|
quantenna_rfstatus() {
|
|
# compat: fw v36 req "wifi0" arg, v37 (and later?) does not
|
|
case "$(quantenna_api_ver)" in
|
|
v36)
|
|
quantenna_call rfstatus $(quantenna_primaryif)
|
|
;;
|
|
*)
|
|
quantenna_call rfstatus
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# mostly harmless if already done
|
|
quantenna_ready() {
|
|
[ -n "$(quantenna_ifprefix)" ] || return 1
|
|
[ "$(quantenna_call startprod)" = "complete" ] || return 1
|
|
[ "$(quantenna_call is_startprod_done)" = "1" ] || return 1
|
|
[ "$(quantenna_rfstatus)" = "On" ] || [ "$(quantenna_rfenable 1)" = "complete" ] || return 1
|
|
return 0
|
|
}
|
|
|
|
quantenna_set_security_mode() {
|
|
local ifname=$1
|
|
[ "$(quantenna_call apply_security_config $ifname)" = "complete" ] || return 1
|
|
return 0
|
|
}
|
|
|
|
quantenna_set_ssid_hidden() {
|
|
local ifname=$1
|
|
local hidden=${2:-0}
|
|
local enable=1
|
|
[ $hidden -gt 0 ] && enable=0
|
|
[ "$(quantenna_call set_option $ifname SSID_broadcast $enable)" = "complete" ] || return 1
|
|
return 0
|
|
}
|
|
|
|
quantenna_interface_enable() {
|
|
local ifname=$1
|
|
local enable=${2:-0}
|
|
local updown=down
|
|
[ $enable -gt 0 ] && updown=up
|
|
|
|
ip link set $ifname $updown
|
|
[ "$(quantenna_call enable_interface $ifname $enable)" = "complete" ] || return 1
|
|
return 0
|
|
}
|
|
|
|
_ifname2vid() {
|
|
echo "$((${1#$(quantenna_ifprefix)}+10))"
|
|
}
|
|
|
|
quantenna_interface_add() {
|
|
local ifname="$1"
|
|
local type="$2"
|
|
local phy="$3"
|
|
local vid=$(_ifname2vid $ifname)
|
|
|
|
# maximum number of devs is 8
|
|
[ $vid -lt 18 ] || return
|
|
|
|
case "$type" in
|
|
ap)
|
|
[ "$ifname" = "$(quantenna_primaryif)" ] || [ "$(quantenna_call wifi_create_bss $ifname)" = "complete" ] || echo "failed to create $ifname"
|
|
quantenna_set_security_mode $ifname || return 1
|
|
[ "$(quantenna_call set_pmf $ifname 0)" = "complete" ] || return 1
|
|
;;
|
|
*)
|
|
echo "$ifname: unsupported interface type '$type'"
|
|
return
|
|
;;
|
|
esac
|
|
|
|
# host local vlan dev
|
|
ip link add link $phy name $ifname type vlan id $vid
|
|
|
|
# bind quantenna vif to vlan
|
|
[ "$(quantenna_call vlan_config $ifname enable $vid)" = "complete" ] || return 1
|
|
[ "$(quantenna_call vlan_config $ifname bind $vid)" = "complete" ] || return 1
|
|
|
|
# disable interface until configured
|
|
quantenna_interface_enable $ifname 0
|
|
}
|
|
|
|
quantenna_interface_del() {
|
|
local ifname="$1"
|
|
local type="$2"
|
|
local vid=$(_ifname2vid $ifname)
|
|
|
|
quantenna_call vlan_config $ifname unbind $vid
|
|
quantenna_call vlan_config $ifname disable $vid
|
|
quantenna_interface_enable $ifname 0
|
|
|
|
case "$type" in
|
|
ap)
|
|
[ "$ifname" = "$(quantenna_primaryif)" ] || quantenna_call wifi_remove_bss $ifname
|
|
;;
|
|
*)
|
|
echo "$ifname: unsupported interface type '$type'"
|
|
return
|
|
;;
|
|
esac
|
|
|
|
ip link del $ifname
|
|
}
|
|
|
|
quantenna_set_ssid() {
|
|
local ifname=$1
|
|
local ssid=$2
|
|
|
|
quantenna_call set_SSID $ifname $ssid
|
|
}
|
|
|
|
quantenna_set_macaddr() {
|
|
local ifname=$1
|
|
local mac=$2
|
|
|
|
quantenna_call set_macaddr $ifname "$mac"
|
|
}
|
|
|
|
quantenna_set_encr() {
|
|
local ifname=$1
|
|
local encr=$2
|
|
|
|
quantenna_call set_WPA_encryption_modes $ifname "$encr"
|
|
}
|
|
|
|
quantenna_set_auth() {
|
|
local ifname=$1
|
|
local auth=$2
|
|
|
|
quantenna_call set_WPA_authentication_mode $ifname "$auth"
|
|
}
|
|
|
|
quantenna_set_key() {
|
|
local ifname=$1
|
|
local key=$2
|
|
|
|
quantenna_call set_passphrase $ifname 0 "$key"
|
|
}
|
|
|
|
quantenna_set_beacon() {
|
|
local ifname=$1
|
|
local type=$2
|
|
|
|
quantenna_call set_beacon $ifname "$type"
|
|
}
|
|
|
|
# This will not work with hairpin_mode enabled
|
|
quantenna_fixup_vif() {
|
|
echo "quantenna_fixup_vif: $(json_dump)"
|
|
json_select data
|
|
json_get_vars ifname
|
|
json_select ..
|
|
[ -r "/sys/class/net/$ifname/brport/hairpin_mode" ] && echo 0 > "/sys/class/net/$ifname/brport/hairpin_mode"
|
|
}
|
|
|
|
quantenna_setup_vif() {
|
|
local name="$1"
|
|
echo "quantenna_setup_vif: $(json_dump)"
|
|
|
|
json_select config
|
|
json_get_vars mode ssid macaddr enable key hidden
|
|
json_select ..
|
|
|
|
# FIXME - mac addresses for VAPs will be auto-generated by Quantenna firmware - we need only managed the first one...
|
|
# [ -n "$macaddr" ] || {
|
|
# macaddr="$(mac80211_generate_mac $phy)"
|
|
# macidx="$(($macidx + 1))"
|
|
# }
|
|
|
|
if_idx=$((${if_idx:--1} + 1))
|
|
local ifname="$(quantenna_ifprefix)${if_idx}"
|
|
set_default enable 1
|
|
|
|
json_add_object data
|
|
json_add_string ifname "$ifname"
|
|
json_close_object
|
|
|
|
json_select config
|
|
wireless_vif_parse_encryption
|
|
json_select ..
|
|
|
|
quantenna_interface_add "$ifname" "$mode" "$phy" || return
|
|
quantenna_set_ssid_hidden $ifname "$hidden"
|
|
|
|
case "$auth_type" in
|
|
none)
|
|
quantenna_set_beacon $ifname Basic
|
|
;;
|
|
psk)
|
|
quantenna_set_auth $ifname PSKAuthentication
|
|
;;
|
|
*)
|
|
echo "unsupported auth_type: $auth_type"
|
|
;;
|
|
esac
|
|
|
|
case "$wpa_cipher" in
|
|
"TKIP")
|
|
quantenna_set_beacon $ifname WPA
|
|
quantenna_set_encr $ifname TKIPEncryption
|
|
;;
|
|
"CCMP")
|
|
quantenna_set_beacon $ifname 11i
|
|
quantenna_set_encr $ifname AESEncryption
|
|
;;
|
|
"CCMP TKIP")
|
|
quantenna_set_beacon $ifname WPAand11i
|
|
quantenna_set_encr $ifname TKIPandAESEncryption
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
|
|
[ -n "$key" ] && quantenna_set_key $ifname "$key"
|
|
quantenna_set_ssid $ifname "$ssid"
|
|
[ -n "$macaddr" ] && quantenna_set_macaddr $ifname "$macaddr"
|
|
quantenna_interface_enable $ifname $enable
|
|
|
|
wireless_add_vif "$name" "$ifname"
|
|
}
|
|
|
|
quantenna_cleanup_vif() {
|
|
local name="$1"
|
|
|
|
echo "quantenna_cleanup_vif ($name): $(json_dump)"
|
|
json_select config
|
|
json_get_vars mode
|
|
json_select ..
|
|
|
|
json_select data
|
|
json_get_vars ifname
|
|
json_select ..
|
|
|
|
quantenna_interface_del $ifname $mode
|
|
}
|
|
|
|
# will be evaled after _wdev_common_device_config(), which adds
|
|
# config_add_string channel hwmode htmode noscan
|
|
drv_quantenna_init_device_config() {
|
|
config_add_string phy
|
|
config_add_int beacon_int
|
|
echo "drv_quantenna_init_device_config"
|
|
}
|
|
|
|
# will be evaled after _wdev_common_iface_config(), which adds
|
|
# config_add_string mode ssid encryption 'key:wpakey'
|
|
drv_quantenna_init_iface_config() {
|
|
config_add_boolean enable hidden
|
|
echo "drv_quantenna_init_iface_config"
|
|
}
|
|
|
|
drv_quantenna_setup() {
|
|
json_select config
|
|
echo "drv_quantenna_setup: $(json_dump)"
|
|
json_get_vars phy channel htmode beacon_int
|
|
json_select ..
|
|
|
|
[ "$(quantenna_device)" = "$phy" ] || {
|
|
echo "Could not find PHY for device '$1'"
|
|
wireless_set_retry 0
|
|
return 1
|
|
}
|
|
|
|
quantenna_ready || {
|
|
echo "Failed to connect to Quantenna module"
|
|
wireless_set_retry 1
|
|
return 1
|
|
}
|
|
|
|
quantenna_call set_channel $(quantenna_primaryif) $channel
|
|
|
|
case "$htmode" in
|
|
VHT20|HT20)
|
|
quantenna_call set_bw $(quantenna_primaryif) 20
|
|
;;
|
|
HT40*|VHT40)
|
|
quantenna_call set_bw $(quantenna_primaryif) 40
|
|
;;
|
|
VHT80)
|
|
quantenna_call set_bw $(quantenna_primaryif) 80
|
|
;;
|
|
*)
|
|
quantenna_call set_bw $(quantenna_primaryif) 40
|
|
;;
|
|
esac
|
|
|
|
[ -n "beacon_int" ] && quantenna_call set_beacon_interval $(quantenna_primaryif) $beacon_int
|
|
|
|
# FIMXE: support all modes: ap, sta, adhoc, wds, monitor, mesh
|
|
for_each_interface "ap" quantenna_setup_vif
|
|
wireless_set_up
|
|
for_each_interface "ap" quantenna_fixup_vif
|
|
}
|
|
|
|
drv_quantenna_teardown() {
|
|
echo "$drv_quantenna_teardown: $(json_dump)"
|
|
for_each_interface "ap" quantenna_cleanup_vif
|
|
quantenna_rfenable 0
|
|
}
|
|
|
|
add_driver quantenna
|