Root/package/madwifi/files/lib/wifi/madwifi.sh

1#!/bin/sh
2append DRIVERS "atheros"
3
4find_atheros_phy() {
5    local device="$1"
6
7    local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
8    config_get phy "$device" phy
9    [ -z "$phy" -a -n "$macaddr" ] && {
10        cd /proc/sys/dev
11        for phy in $(ls -d wifi* 2>&-); do
12            [ "$macaddr" = "$(cat /sys/class/net/${phy}/address)" ] || continue
13            config_set "$device" phy "$phy"
14            break
15        done
16        config_get phy "$device" phy
17    }
18    [ -n "$phy" -a -d "/proc/sys/dev/$phy" ] || {
19        echo "phy for wifi device $1 not found"
20        return 1
21    }
22    [ -z "$macaddr" ] && {
23        config_set "$device" macaddr "$(cat /sys/class/net/${phy}/address)"
24    }
25    return 0
26}
27
28scan_atheros() {
29    local device="$1"
30    local wds
31    local adhoc ahdemo sta ap monitor
32
33    [ ${device%[0-9]} = "wifi" ] && config_set "$device" phy "$device"
34    
35    config_get vifs "$device" vifs
36    for vif in $vifs; do
37    
38        config_get ifname "$vif" ifname
39        config_set "$vif" ifname "${ifname:-ath}"
40        
41        config_get mode "$vif" mode
42        case "$mode" in
43            adhoc|ahdemo|sta|ap|monitor)
44                append $mode "$vif"
45            ;;
46            wds)
47                config_get ssid "$vif" ssid
48                [ -z "$ssid" ] && continue
49
50                config_set "$vif" wds 1
51                config_set "$vif" mode sta
52                mode="sta"
53                addr="$ssid"
54                ${addr:+append $mode "$vif"}
55            ;;
56            *) echo "$device($vif): Invalid mode, ignored."; continue;;
57        esac
58    done
59
60    case "${adhoc:+1}:${sta:+1}:${ap:+1}" in
61        # valid mode combinations
62        1::) wds="";;
63        1::1);;
64        :1:1)config_set "$device" nosbeacon 1;; # AP+STA, can't use beacon timers for STA
65        :1:);;
66        ::1);;
67        ::);;
68        *) echo "$device: Invalid mode combination in config"; return 1;;
69    esac
70
71    config_set "$device" vifs "${sta:+$sta }${ap:+$ap }${adhoc:+$adhoc }${ahdemo:+$ahdemo }${wds:+$wds }${monitor:+$monitor}"
72}
73
74
75disable_atheros() (
76    local device="$1"
77
78    find_atheros_phy "$device" || return 0
79    config_get phy "$device" phy
80
81    set_wifi_down "$device"
82
83    include /lib/network
84    cd /proc/sys/net
85    for dev in *; do
86        grep "$phy" "$dev/%parent" >/dev/null 2>/dev/null && {
87            [ -f "/var/run/wifi-${dev}.pid" ] &&
88                kill "$(cat "/var/run/wifi-${dev}.pid")"
89            ifconfig "$dev" down
90            unbridge "$dev"
91            wlanconfig "$dev" destroy
92        }
93    done
94    return 0
95)
96
97enable_atheros() {
98    local device="$1"
99
100    find_atheros_phy "$device" || return 0
101    config_get phy "$device" phy
102
103    config_get regdomain "$device" regdomain
104    [ -n "$regdomain" ] && echo "$regdomain" > /proc/sys/dev/$phy/regdomain
105
106    config_get country "$device" country
107    case "$country" in
108        [A-Za-z]*) country=`grep -i "$country" /lib/wifi/madwifi_countrycodes.txt |cut -d " " -f 2`;;
109        [0-9]*) ;;
110        *) country="" ;;
111    esac
112    [ -n "$country" ] && echo "$country" > /proc/sys/dev/$phy/countrycode
113
114    config_get_bool outdoor "$device" outdoor "0"
115    echo "$outdoor" > /proc/sys/dev/$phy/outdoor
116
117    config_get channel "$device" channel
118    config_get vifs "$device" vifs
119    config_get txpower "$device" txpower
120
121    [ auto = "$channel" ] && channel=0
122
123    config_get_bool antdiv "$device" diversity
124    config_get antrx "$device" rxantenna
125    config_get anttx "$device" txantenna
126    config_get_bool softled "$device" softled
127    config_get antenna "$device" antenna
128
129    devname="$(cat /proc/sys/dev/$phy/dev_name)"
130    local antgpio=
131    local invert=
132    case "$devname" in
133        NanoStation2) antgpio=7; invert=1;;
134        NanoStation5) antgpio=1; invert=1;;
135        "NanoStation Loco2") antgpio=2;;
136        "NanoStation Loco5")
137            case "$antenna" in
138                horizontal) antdiv=0; anttx=1; antrx=1;;
139                vertical) antdiv=0; anttx=2; antrx=2;;
140                *) antdiv=1; anttx=0; antrx=0;;
141            esac
142        ;;
143    esac
144    if [ -n "$invert" ]; then
145        _set="clear"
146        _clear="set"
147    else
148        _set="set"
149        _clear="clear"
150    fi
151    if [ -n "$antgpio" ]; then
152        softled=0
153        case "$devname" in
154            "NanoStation Loco2")
155                antdiv=0
156                antrx=1
157                anttx=1
158                case "$antenna" in
159                    horizontal) gpioval=0;;
160                    *) gpioval=1;;
161                esac
162            ;;
163            *)
164                case "$antenna" in
165                    external) antdiv=0; antrx=1; anttx=1; gpioval=1;;
166                    horizontal) antdiv=0; antrx=1; anttx=1; gpioval=0;;
167                    vertical) antdiv=0; antrx=2; anttx=2; gpioval=0;;
168                    auto) antdiv=1; antrx=0; anttx=0; gpioval=0;;
169                esac
170            ;;
171        esac
172
173        [ -x "$(which gpioctl 2>/dev/null)" ] || antenna=
174        gpioctl "dirout" "$antgpio" >/dev/null 2>&1
175        case "$gpioval" in
176            0)
177                gpioctl "$_clear" "$antgpio" >/dev/null 2>&1
178            ;;
179            1)
180                gpioctl "$_set" "$antgpio" >/dev/null 2>&1
181            ;;
182        esac
183    fi
184
185    [ -n "$antdiv" ] && sysctl -w dev."$phy".diversity="$antdiv" >&-
186    [ -n "$antrx" ] && sysctl -w dev."$phy".rxantenna="$antrx" >&-
187    [ -n "$anttx" ] && sysctl -w dev."$phy".txantenna="$anttx" >&-
188    [ -n "$softled" ] && sysctl -w dev."$phy".softled="$softled" >&-
189
190    config_get distance "$device" distance
191    [ -n "$distance" ] && sysctl -w dev."$phy".distance="$distance" >&-
192
193    for vif in $vifs; do
194        local start_hostapd= vif_txpower= nosbeacon=
195        config_get ifname "$vif" ifname
196        config_get enc "$vif" encryption
197        config_get eap_type "$vif" eap_type
198        config_get mode "$vif" mode
199
200        case "$mode" in
201            sta) config_get_bool nosbeacon "$device" nosbeacon;;
202            adhoc) config_get_bool nosbeacon "$vif" sw_merge 1;;
203        esac
204
205        [ "$nosbeacon" = 1 ] || nosbeacon=""
206        ifname=$(wlanconfig "$ifname" create wlandev "$phy" wlanmode "$mode" ${nosbeacon:+nosbeacon})
207        [ $? -ne 0 ] && {
208            echo "enable_atheros($device): Failed to set up $mode vif $ifname" >&2
209            continue
210        }
211        config_set "$vif" ifname "$ifname"
212
213        config_get hwmode "$device" hwmode
214        [ -z "$hwmode" ] && config_get hwmode "$device" mode
215
216        pureg=0
217        case "$hwmode" in
218            *b) hwmode=11b;;
219            *bg) hwmode=11g;;
220            *g) hwmode=11g; pureg=1;;
221            *gdt) hwmode=11gdt;;
222            *a) hwmode=11a;;
223            *adt) hwmode=11adt;;
224            *ast) hwmode=11ast;;
225            *fh) hwmode=fh;;
226            *) hwmode=auto;;
227        esac
228        iwpriv "$ifname" mode "$hwmode"
229        iwpriv "$ifname" pureg "$pureg"
230
231        iwconfig "$ifname" channel "$channel" >/dev/null 2>/dev/null
232
233        config_get_bool hidden "$vif" hidden 0
234        iwpriv "$ifname" hide_ssid "$hidden"
235
236        config_get ff "$vif" ff
237        if [ -n "$ff" ]; then
238            iwpriv "$ifname" ff "$ff"
239        fi
240
241        config_get wds "$vif" wds
242        case "$wds" in
243            1|on|enabled) wds=1;;
244            *) wds=0;;
245        esac
246        iwpriv "$ifname" wds "$wds" >/dev/null 2>&1
247
248        [ "$mode" = ap -a "$wds" = 1 ] && {
249            config_get_bool wdssep "$vif" wdssep 1
250            [ -n "$wdssep" ] && iwpriv "$ifname" wdssep "$wdssep"
251        }
252
253        case "$enc" in
254            wep*)
255                case "$enc" in
256                    *shared*) iwpriv "$ifname" authmode 2;;
257                    *) iwpriv "$ifname" authmode 1;;
258                esac
259                for idx in 1 2 3 4; do
260                    config_get key "$vif" "key${idx}"
261                    iwconfig "$ifname" enc "[$idx]" "${key:-off}"
262                done
263                config_get key "$vif" key
264                key="${key:-1}"
265                case "$key" in
266                    [1234]) iwconfig "$ifname" enc "[$key]";;
267                    *) iwconfig "$ifname" enc "$key";;
268                esac
269            ;;
270            psk*|wpa*)
271                start_hostapd=1
272                config_get key "$vif" key
273            ;;
274        esac
275
276        case "$mode" in
277            sta|adhoc|ahdemo)
278                config_get addr "$vif" bssid
279                [ -z "$addr" ] || {
280                    iwconfig "$ifname" ap "$addr"
281                }
282            ;;
283        esac
284
285        config_get_bool uapsd "$vif" uapsd 0
286        iwpriv "$ifname" uapsd "$uapsd"
287
288        config_get_bool bgscan "$vif" bgscan
289        [ -n "$bgscan" ] && iwpriv "$ifname" bgscan "$bgscan"
290
291        config_get rate "$vif" rate
292        [ -n "$rate" ] && iwconfig "$ifname" rate "${rate%%.*}"
293
294        config_get mcast_rate "$vif" mcast_rate
295        [ -n "$mcast_rate" ] && iwpriv "$ifname" mcast_rate "${mcast_rate%%.*}"
296
297        config_get frag "$vif" frag
298        [ -n "$frag" ] && iwconfig "$ifname" frag "${frag%%.*}"
299
300        config_get rts "$vif" rts
301        [ -n "$rts" ] && iwconfig "$ifname" rts "${rts%%.*}"
302
303        config_get_bool comp "$vif" compression 0
304        iwpriv "$ifname" compression "$comp" >/dev/null 2>&1
305
306        config_get minrate "$vif" minrate
307        [ -n "$minrate" ] && iwpriv "$ifname" minrate "$minrate"
308
309        config_get maxrate "$vif" maxrate
310        [ -n "$maxrate" ] && iwpriv "$ifname" maxrate "$maxrate"
311
312        config_get_bool burst "$vif" bursting
313        [ -n "$burst" ] && iwpriv "$ifname" burst "$burst"
314
315        config_get_bool wmm "$vif" wmm
316        [ -n "$wmm" ] && iwpriv "$ifname" wmm "$wmm"
317
318        config_get_bool xr "$vif" xr
319        [ -n "$xr" ] && iwpriv "$ifname" xr "$xr"
320
321        config_get_bool ar "$vif" ar
322        [ -n "$ar" ] && iwpriv "$ifname" ar "$ar"
323
324        config_get_bool beacon_power "$vif" beacon_power
325        [ -n "$beacon_power" ] && iwpriv "$ifname" beacon_pwr "$beacon_power"
326
327        config_get_bool doth "$vif" doth 0
328        [ -n "$doth" ] && iwpriv "$ifname" doth "$doth"
329
330        config_get_bool probereq "$vif" probereq
331        [ -n "$probereq" ] && iwpriv "$ifname" probereq "$probereq"
332
333        config_get maclist "$vif" maclist
334        [ -n "$maclist" ] && {
335            # flush MAC list
336            iwpriv "$ifname" maccmd 3
337            for mac in $maclist; do
338                iwpriv "$ifname" addmac "$mac"
339            done
340        }
341
342        config_get macpolicy "$vif" macpolicy
343        case "$macpolicy" in
344            allow)
345                iwpriv "$ifname" maccmd 1
346            ;;
347            deny)
348                iwpriv "$ifname" maccmd 2
349            ;;
350            *)
351                # default deny policy if mac list exists
352                [ -n "$maclist" ] && iwpriv "$ifname" maccmd 2
353            ;;
354        esac
355
356        ifconfig "$ifname" up
357
358        local net_cfg bridge
359        net_cfg="$(find_net_config "$vif")"
360        [ -z "$net_cfg" ] || {
361            bridge="$(bridge_interface "$net_cfg")"
362            config_set "$vif" bridge "$bridge"
363            start_net "$ifname" "$net_cfg"
364        }
365
366        config_get ssid "$vif" ssid
367        [ -n "$ssid" ] && {
368            iwconfig "$ifname" essid on
369            iwconfig "$ifname" essid ${ssid:+-- }"$ssid"
370        }
371
372        set_wifi_up "$vif" "$ifname"
373
374        # TXPower settings only work if device is up already
375        # while atheros hardware theoretically is capable of per-vif (even per-packet) txpower
376        # adjustment it does not work with the current atheros hal/madwifi driver
377
378        config_get vif_txpower "$vif" txpower
379        # use vif_txpower (from wifi-iface) instead of txpower (from wifi-device) if
380        # the latter doesn't exist
381        txpower="${txpower:-$vif_txpower}"
382        [ -z "$txpower" ] || iwconfig "$ifname" txpower "${txpower%%.*}"
383
384        case "$mode" in
385            ap)
386                config_get_bool isolate "$vif" isolate 0
387                iwpriv "$ifname" ap_bridge "$((isolate^1))"
388
389                if [ -n "$start_hostapd" ] && eval "type hostapd_setup_vif" 2>/dev/null >/dev/null; then
390                    hostapd_setup_vif "$vif" madwifi || {
391                        echo "enable_atheros($device): Failed to set up hostapd for interface $ifname" >&2
392                        # make sure this wifi interface won't accidentally stay open without encryption
393                        ifconfig "$ifname" down
394                        wlanconfig "$ifname" destroy
395                        continue
396                    }
397                fi
398            ;;
399            wds|sta)
400                if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
401                    wpa_supplicant_setup_vif "$vif" madwifi || {
402                        echo "enable_atheros($device): Failed to set up wpa_supplicant for interface $ifname" >&2
403                        ifconfig "$ifname" down
404                        wlanconfig "$ifname" destroy
405                        continue
406                    }
407                fi
408            ;;
409        esac
410    done
411}
412
413check_atheros_device() {
414    [ ${1%[0-9]} = "wifi" ] && config_set "$1" phy "$1"
415    config_get phy "$1" phy
416    [ -z "$phy" ] && {
417        find_atheros_phy "$1" >/dev/null || return 0
418        config_get phy "$1" phy
419    }
420    [ "$phy" = "$dev" ] && found=1
421}
422
423
424detect_atheros() {
425    devidx=0
426    config_load wireless
427    while :; do
428        config_get type "radio$devidx" type
429        [ -n "$type" ] || break
430        devidx=$(($devidx + 1))
431    done
432    cd /proc/sys/dev
433    [ -d ath ] || return
434    for dev in $(ls -d wifi* 2>&-); do
435        found=0
436        config_foreach check_atheros_device wifi-device
437        [ "$found" -gt 0 ] && continue
438
439        devname="$(cat /proc/sys/dev/$dev/dev_name)"
440        case "$devname" in
441            "NanoStation Loco2")
442                EXTRA_DEV="
443# Ubiquiti NanoStation Loco2 features
444    option antenna vertical # (horizontal|vertical)
445"
446            ;;
447            "NanoStation Loco5")
448                EXTRA_DEV="
449# Ubiquiti NanoStation Loco5 features
450    option antenna auto # (auto|horizontal|vertical)
451"
452            ;;
453            NanoStation*)
454                EXTRA_DEV="
455# Ubiquiti NanoStation features
456    option antenna auto # (auto|horizontal|vertical|external)
457"
458            ;;
459        esac
460
461        cat <<EOF
462config wifi-device radio$devidx
463    option type atheros
464    option channel auto
465    option macaddr $(cat /sys/class/net/${dev}/address)
466$EXTRA_DEV
467    # REMOVE THIS LINE TO ENABLE WIFI:
468    option disabled 1
469
470config wifi-iface
471    option device radio$devidx
472    option network lan
473    option mode ap
474    option ssid OpenWrt
475    option encryption none
476
477EOF
478    devidx=$(($devidx + 1))
479    done
480}
481

Archive Download this file



interactive