madwifi.sh 10 KB

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