#!/bin/sh append DRIVERS "atheros" scan_atheros() { local device="$1" local wds local adhoc sta ap config_get vifs "$device" vifs for vif in $vifs; do config_get ifname "$vif" ifname config_set "$vif" ifname "${ifname:-ath}" config_get mode "$vif" mode case "$mode" in adhoc|ahdemo|sta|ap|monitor) append $mode "$vif" ;; wds) config_get ssid "$vif" ssid [ -z "$ssid" ] && continue config_set "$vif" wds 1 config_set "$vif" mode sta mode="sta" addr="$ssid" ${addr:+append $mode "$vif"} ;; *) echo "$device($vif): Invalid mode, ignored."; continue;; esac done case "${adhoc:+1}:${sta:+1}:${ap:+1}" in # valid mode combinations 1::) wds="";; 1::1);; :1:1)config_set "$device" nosbeacon 1;; # AP+STA, can't use beacon timers for STA :1:);; ::1);; ::);; *) echo "$device: Invalid mode combination in config"; return 1;; esac config_set "$device" vifs "${sta:+$sta }${ap:+$ap }${adhoc:+$adhoc }${ahdemo:+$ahdemo }${wds:+$wds }${monitor:+$monitor}" } disable_atheros() ( local device="$1" set_wifi_down "$device" include /lib/network cd /proc/sys/net for dev in *; do grep "$device" "$dev/%parent" >/dev/null 2>/dev/null && { [ -f "/var/run/wifi-${dev}.pid" ] && kill "$(cat "/var/run/wifi-${dev}.pid")" ifconfig "$dev" down unbridge "$dev" wlanconfig "$dev" destroy } done return 0 ) enable_atheros() { local device="$1" # Can only set the country code to one setting for the entire system. The last country code is the one that will be applied. config_get country "$device" country [ -z "$country" ] && country="0" local cc="0" [ -e /proc/sys/dev/$device/countrycode ] && cc="$(cat /proc/sys/dev/$device/countrycode)" if [ ! "$cc" = "$country" ] ; then rmmod ath_pci insmod ath_pci countrycode=$country fi config_get channel "$device" channel config_get vifs "$device" vifs config_get txpower "$device" txpower [ auto = "$channel" ] && channel=0 local first=1 for vif in $vifs; do local start_hostapd vif_txpower nosbeacon= config_get ifname "$vif" ifname config_get enc "$vif" encryption config_get eap_type "$vif" eap_type config_get mode "$vif" mode case "$mode" in sta) config_get nosbeacon "$device" nosbeacon;; adhoc) config_get nosbeacon "$vif" sw_merge;; esac config_get ifname "$vif" ifname ifname=$(wlanconfig "$ifname" create wlandev "$device" wlanmode "$mode" ${nosbeacon:+nosbeacon}) [ $? -ne 0 ] && { echo "enable_atheros($device): Failed to set up $mode vif $ifname" >&2 continue } config_set "$vif" ifname "$ifname" # only need to change freq band and channel on the first vif config_get hwmode "$device" hwmode [ -z "$hwmode" ] && config_get hwmode "$device" mode pureg=0 case "$hwmode" in *b) hwmode=11b;; *bg) hwmode=11g;; *g) hwmode=11g; pureg=1;; *gdt) hwmode=11gdt;; *a) hwmode=11a;; *adt) hwmode=11adt;; *ast) hwmode=11ast;; *fh) hwmode=fh;; *) hwmode=auto;; esac iwpriv "$ifname" mode "$hwmode" iwpriv "$ifname" pureg "$pureg" [ "$first" = 1 ] && { iwconfig "$ifname" channel "$channel" >/dev/null 2>/dev/null } config_get_bool hidden "$vif" hidden 0 iwpriv "$ifname" hide_ssid "$hidden" config_get ff "$vif" ff if [ -n "$ff" ]; then iwpriv "$ifname" ff "$ff" fi config_get wds "$vif" wds case "$wds" in 1|on|enabled) wds=1;; *) wds=0;; esac iwpriv "$ifname" wds "$wds" [ "$mode" = ap -a "$wds" = 1 ] && { config_get_bool wdssep "$vif" wdssep 1 [ -n "$wdssep" ] && iwpriv "$ifname" wdssep "$wdssep" } case "$enc" in WEP|wep) for idx in 1 2 3 4; do config_get key "$vif" "key${idx}" iwconfig "$ifname" enc "[$idx]" "${key:-off}" done config_get key "$vif" key key="${key:-1}" case "$key" in [1234]) iwconfig "$ifname" enc "[$key]";; *) iwconfig "$ifname" enc "$key";; esac ;; psk*|wpa*) start_hostapd=1 config_get key "$vif" key ;; esac case "$mode" in adhoc|ahdemo) config_get addr "$vif" bssid [ -z "$addr" ] || { iwconfig "$ifname" ap "$addr" } ;; esac config_get ssid "$vif" ssid config_get_bool bgscan "$vif" bgscan [ -n "$bgscan" ] && iwpriv "$ifname" bgscan "$bgscan" config_get_bool antdiv "$device" diversity config_get antrx "$device" rxantenna config_get anttx "$device" txantenna config_get_bool softled "$device" softled 1 devname="$(cat /proc/sys/dev/$device/dev_name)" antgpio= case "$devname" in NanoStation2) antgpio=7;; NanoStation5) antgpio=1;; esac if [ -n "$antgpio" ]; then softled=0 config_get antenna "$device" antenna case "$antenna" in external) antdiv=0; antrx=1; anttx=1 ;; horizontal) antdiv=0; antrx=1; anttx=1 ;; vertical) antdiv=0; antrx=2; anttx=2 ;; auto) antdiv=1; antrx=0; anttx=0 ;; esac [ -x "$(which gpioctl 2>/dev/null)" ] || antenna= case "$antenna" in horizontal|vertical|auto) gpioctl "dirout" "$antgpio" >/dev/null 2>&1 gpioctl "set" "$antgpio" >/dev/null 2>&1 ;; external) gpioctl "dirout" "$antgpio" >/dev/null 2>&1 gpioctl "clear" "$antgpio" >/dev/null 2>&1 ;; esac fi [ -n "$antdiv" ] && sysctl -w dev."$device".diversity="$antdiv" >&- [ -n "$antrx" ] && sysctl -w dev."$device".rxantenna="$antrx" >&- [ -n "$anttx" ] && sysctl -w dev."$device".txantenna="$anttx" >&- [ -n "$softled" ] && sysctl -w dev."$device".softled="$softled" >&- config_get distance "$device" distance [ -n "$distance" ] && athctrl -i "$device" -d "$distance" >&- config_get rate "$vif" rate [ -n "$rate" ] && iwconfig "$ifname" rate "${rate%%.*}" config_get mcast_rate "$vif" mcast_rate [ -n "$mcast_rate" ] && iwpriv "$ifname" mcast_rate "${mcast_rate%%.*}" config_get frag "$vif" frag [ -n "$frag" ] && iwconfig "$ifname" frag "${frag%%.*}" config_get rts "$vif" rts [ -n "$rts" ] && iwconfig "$ifname" rts "${rts%%.*}" config_get_bool comp "$vif" compression [ -n "$comp" ] && iwpriv "$ifname" compression "$comp" config_get_bool minrate "$vif" minrate [ -n "$minrate" ] && iwpriv "$ifname" minrate "$minrate" config_get_bool maxrate "$vif" maxrate [ -n "$maxrate" ] && iwpriv "$ifname" maxrate "$maxrate" config_get_bool burst "$vif" bursting [ -n "$burst" ] && iwpriv "$ifname" burst "$burst" config_get_bool wmm "$vif" wmm [ -n "$wmm" ] && iwpriv "$ifname" wmm "$wmm" config_get_bool xr "$vif" xr [ -n "$xr" ] && iwpriv "$ifname" xr "$xr" config_get_bool ar "$vif" ar [ -n "$ar" ] && iwpriv "$ifname" ar "$ar" config_get_bool turbo "$vif" turbo [ -n "$turbo" ] && iwpriv "$ifname" turbo "$turbo" config_get_bool doth "$vif" doth 0 [ -n "$doth" ] && iwpriv "$ifname" doth "$doth" config_get_bool probereq "$vif" probereq [ -n "$probereq" ] && iwpriv "$ifname" probereq "$probereq" config_get maclist "$vif" maclist [ -n "$maclist" ] && { # flush MAC list iwpriv "$ifname" maccmd 3 for mac in $maclist; do iwpriv "$ifname" addmac "$mac" done } config_get macpolicy "$vif" macpolicy case "$macpolicy" in allow) iwpriv "$ifname" maccmd 1 ;; deny) iwpriv "$ifname" maccmd 2 ;; *) # default deny policy if mac list exists [ -n "$maclist" ] && iwpriv "$ifname" maccmd 2 ;; esac ifconfig "$ifname" up local net_cfg bridge net_cfg="$(find_net_config "$vif")" [ -z "$net_cfg" ] || { bridge="$(bridge_interface "$net_cfg")" config_set "$vif" bridge "$bridge" start_net "$ifname" "$net_cfg" } [ -n "$ssid" ] && iwconfig "$ifname" essid on iwconfig "$ifname" essid "$ssid" set_wifi_up "$vif" "$ifname" # TXPower settings only work if device is up already # while atheros hardware theoretically is capable of per-vif (even per-packet) txpower # adjustment it does not work with the current atheros hal/madwifi driver config_get vif_txpower "$vif" txpower # use vif_txpower (from wifi-iface) instead of txpower (from wifi-device) if # the latter doesn't exist txpower="${txpower:-$vif_txpower}" [ -z "$txpower" ] || iwconfig "$ifname" txpower "${txpower%%.*}" case "$mode" in ap) config_get_bool isolate "$vif" isolate 0 iwpriv "$ifname" ap_bridge "$((isolate^1))" if [ -n "$start_hostapd" ] && eval "type hostapd_setup_vif" 2>/dev/null >/dev/null; then hostapd_setup_vif "$vif" madwifi || { echo "enable_atheros($device): Failed to set up hostapd for interface $ifname" >&2 # make sure this wifi interface won't accidentally stay open without encryption ifconfig "$ifname" down wlanconfig "$ifname" destroy continue } fi ;; wds|sta) if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then wpa_supplicant_setup_vif "$vif" madwifi || { echo "enable_atheros($device): Failed to set up wpa_supplicant for interface $ifname" >&2 ifconfig "$ifname" down wlanconfig "$ifname" destroy continue } fi ;; esac first=0 done } detect_atheros() { cd /proc/sys/dev [ -d ath ] || return for dev in $(ls -d wifi* 2>&-); do config_get type "$dev" type devname="$(cat /proc/sys/dev/$dev/dev_name)" case "$devname" in NanoStation*) EXTRA_DEV=" # Ubiquiti NanoStation features option antenna auto # (auto|horizontal|vertical|external) " ;; esac [ "$type" = atheros ] && return cat <174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260