mac80211.sh 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. #!/bin/sh
  2. append DRIVERS "mac80211"
  3. mac80211_hostapd_setup_base() {
  4. local phy="$1"
  5. local ifname="$2"
  6. cfgfile="/var/run/hostapd-$phy.conf"
  7. config_get device "$vif" device
  8. config_get country "$device" country
  9. config_get hwmode "$device" hwmode
  10. config_get channel "$device" channel
  11. config_get beacon_int "$device" beacon_int
  12. config_get basic_rate_list "$device" basic_rate
  13. config_get_bool noscan "$device" noscan
  14. hostapd_set_log_options base_cfg "$device"
  15. [ -n "$channel" -a -z "$hwmode" ] && wifi_fixup_hwmode "$device"
  16. [ "$channel" = auto ] && {
  17. channel=$(iw phy "$phy" info | \
  18. sed -ne '/MHz/ { /disabled\|passive\|radar/d; s/.*\[//; s/\].*//; p; q }')
  19. config_set "$device" channel "$channel"
  20. }
  21. [ -n "$hwmode" ] && {
  22. config_get hwmode_11n "$device" hwmode_11n
  23. [ -n "$hwmode_11n" ] && {
  24. hwmode="$hwmode_11n"
  25. append base_cfg "ieee80211n=1" "$N"
  26. config_get htmode "$device" htmode
  27. config_get ht_capab_list "$device" ht_capab
  28. case "$htmode" in
  29. HT20|HT40+|HT40-) ht_capab="[$htmode]";;
  30. *)ht_capab=;;
  31. esac
  32. for cap in $ht_capab_list; do
  33. ht_capab="$ht_capab[$cap]"
  34. done
  35. [ -n "$ht_capab" ] && append base_cfg "ht_capab=$ht_capab" "$N"
  36. }
  37. }
  38. local country_ie=0
  39. [ -n "$country" ] && country_ie=1
  40. config_get_bool country_ie "$device" country_ie "$country_ie"
  41. [ "$country_ie" -gt 0 ] && append base_cfg "ieee80211d=1" "$N"
  42. local br brval brstr
  43. [ -n "$basic_rate_list" ] && {
  44. for br in $basic_rate_list; do
  45. brval="$(($br / 100))"
  46. [ -n "$brstr" ] && brstr="$brstr "
  47. brstr="$brstr$brval"
  48. done
  49. }
  50. cat >> "$cfgfile" <<EOF
  51. ctrl_interface=/var/run/hostapd-$phy
  52. driver=nl80211
  53. wmm_ac_bk_cwmin=4
  54. wmm_ac_bk_cwmax=10
  55. wmm_ac_bk_aifs=7
  56. wmm_ac_bk_txop_limit=0
  57. wmm_ac_bk_acm=0
  58. wmm_ac_be_aifs=3
  59. wmm_ac_be_cwmin=4
  60. wmm_ac_be_cwmax=10
  61. wmm_ac_be_txop_limit=0
  62. wmm_ac_be_acm=0
  63. wmm_ac_vi_aifs=2
  64. wmm_ac_vi_cwmin=3
  65. wmm_ac_vi_cwmax=4
  66. wmm_ac_vi_txop_limit=94
  67. wmm_ac_vi_acm=0
  68. wmm_ac_vo_aifs=2
  69. wmm_ac_vo_cwmin=2
  70. wmm_ac_vo_cwmax=3
  71. wmm_ac_vo_txop_limit=47
  72. wmm_ac_vo_acm=0
  73. tx_queue_data3_aifs=7
  74. tx_queue_data3_cwmin=15
  75. tx_queue_data3_cwmax=1023
  76. tx_queue_data3_burst=0
  77. tx_queue_data2_aifs=3
  78. tx_queue_data2_cwmin=15
  79. tx_queue_data2_cwmax=63
  80. tx_queue_data2_burst=0
  81. tx_queue_data1_aifs=1
  82. tx_queue_data1_cwmin=7
  83. tx_queue_data1_cwmax=15
  84. tx_queue_data1_burst=3.0
  85. tx_queue_data0_aifs=1
  86. tx_queue_data0_cwmin=3
  87. tx_queue_data0_cwmax=7
  88. tx_queue_data0_burst=1.5
  89. ${hwmode:+hw_mode=$hwmode}
  90. ${channel:+channel=$channel}
  91. ${beacon_int:+beacon_int=$beacon_int}
  92. ${country:+country_code=$country}
  93. ${noscan:+noscan=$noscan}
  94. ${brstr:+basic_rates=$brstr}
  95. $base_cfg
  96. EOF
  97. }
  98. mac80211_hostapd_setup_bss() {
  99. local phy="$1"
  100. local vif="$2"
  101. hostapd_cfg=
  102. cfgfile="/var/run/hostapd-$phy.conf"
  103. config_get ifname "$vif" ifname
  104. if [ -f "$cfgfile" ]; then
  105. append hostapd_cfg "bss=$ifname" "$N"
  106. else
  107. mac80211_hostapd_setup_base "$phy" "$ifname"
  108. append hostapd_cfg "interface=$ifname" "$N"
  109. fi
  110. local net_cfg bridge
  111. net_cfg="$(find_net_config "$vif")"
  112. [ -z "$net_cfg" ] || bridge="$(bridge_interface "$net_cfg")"
  113. config_set "$vif" bridge "$bridge"
  114. hostapd_set_bss_options hostapd_cfg "$vif"
  115. config_get_bool wds "$vif" wds 0
  116. [ "$wds" -gt 0 ] && append hostapd_cfg "wds_sta=1" "$N"
  117. local macaddr hidden maxassoc wmm
  118. config_get macaddr "$vif" macaddr
  119. config_get maxassoc "$vif" maxassoc
  120. config_get dtim_period "$vif" dtim_period
  121. config_get max_listen_int "$vif" max_listen_int
  122. config_get_bool hidden "$vif" hidden 0
  123. config_get_bool wmm "$vif" wmm 1
  124. cat >> /var/run/hostapd-$phy.conf <<EOF
  125. $hostapd_cfg
  126. wmm_enabled=$wmm
  127. bssid=$macaddr
  128. ignore_broadcast_ssid=$hidden
  129. ${dtim_period:+dtim_period=$dtim_period}
  130. ${max_listen_int:+max_listen_interval=$max_listen_int}
  131. ${maxassoc:+max_num_sta=$maxassoc}
  132. EOF
  133. }
  134. mac80211_start_vif() {
  135. local vif="$1"
  136. local ifname="$2"
  137. local net_cfg
  138. net_cfg="$(find_net_config "$vif")"
  139. [ -z "$net_cfg" ] || start_net "$ifname" "$net_cfg"
  140. set_wifi_up "$vif" "$ifname"
  141. }
  142. lookup_phy() {
  143. [ -n "$phy" ] && {
  144. [ -d /sys/class/ieee80211/$phy ] && return
  145. }
  146. local devpath
  147. config_get devpath "$device" path
  148. [ -n "$devpath" -a -d "/sys/devices/$devpath/ieee80211" ] && {
  149. phy="$(ls /sys/devices/$devpath/ieee80211 | grep -m 1 phy)"
  150. [ -n "$phy" ] && return
  151. }
  152. local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
  153. [ -n "$macaddr" ] && {
  154. for _phy in $(ls /sys/class/ieee80211 2>/dev/null); do
  155. [ "$macaddr" = "$(cat /sys/class/ieee80211/${_phy}/macaddress)" ] || continue
  156. phy="$_phy"
  157. return
  158. done
  159. }
  160. phy=
  161. return
  162. }
  163. find_mac80211_phy() {
  164. local device="$1"
  165. config_get phy "$device" phy
  166. lookup_phy
  167. [ -n "$phy" -a -d "/sys/class/ieee80211/$phy" ] || {
  168. echo "PHY for wifi device $1 not found"
  169. return 1
  170. }
  171. config_set "$device" phy "$phy"
  172. config_get macaddr "$device" macaddr
  173. [ -z "$macaddr" ] && {
  174. config_set "$device" macaddr "$(cat /sys/class/ieee80211/${phy}/macaddress)"
  175. }
  176. return 0
  177. }
  178. scan_mac80211() {
  179. local device="$1"
  180. local adhoc sta ap monitor mesh disabled
  181. config_get vifs "$device" vifs
  182. for vif in $vifs; do
  183. config_get_bool disabled "$vif" disabled 0
  184. [ $disabled = 0 ] || continue
  185. config_get mode "$vif" mode
  186. case "$mode" in
  187. adhoc|sta|ap|monitor|mesh)
  188. append $mode "$vif"
  189. ;;
  190. *) echo "$device($vif): Invalid mode, ignored."; continue;;
  191. esac
  192. done
  193. config_set "$device" vifs "${ap:+$ap }${adhoc:+$adhoc }${sta:+$sta }${monitor:+$monitor }${mesh:+$mesh}"
  194. }
  195. list_phy_interfaces() {
  196. local phy="$1"
  197. if [ -d "/sys/class/ieee80211/${phy}/device/net" ]; then
  198. ls "/sys/class/ieee80211/${phy}/device/net" 2>/dev/null;
  199. else
  200. ls "/sys/class/ieee80211/${phy}/device" 2>/dev/null | grep net: | sed -e 's,net:,,g'
  201. fi
  202. }
  203. disable_mac80211() (
  204. local device="$1"
  205. find_mac80211_phy "$device" || return 0
  206. config_get phy "$device" phy
  207. set_wifi_down "$device"
  208. # kill all running hostapd and wpa_supplicant processes that
  209. # are running on atheros/mac80211 vifs
  210. for pid in `pidof hostapd`; do
  211. grep -E "$phy" /proc/$pid/cmdline >/dev/null && \
  212. kill $pid
  213. done
  214. include /lib/network
  215. for wdev in $(list_phy_interfaces "$phy"); do
  216. [ -f "/var/run/$wdev.pid" ] && kill $(cat /var/run/$wdev.pid) >&/dev/null 2>&1
  217. for pid in `pidof wpa_supplicant meshd-nl80211`; do
  218. grep "$wdev" /proc/$pid/cmdline >/dev/null && \
  219. kill $pid
  220. done
  221. ifconfig "$wdev" down 2>/dev/null
  222. unbridge "$dev"
  223. iw dev "$wdev" del
  224. done
  225. return 0
  226. )
  227. get_freq() {
  228. local phy="$1"
  229. local chan="$2"
  230. iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep MHz | awk '{print $2}'
  231. }
  232. mac80211_generate_mac() {
  233. local id="$1"
  234. local ref="$2"
  235. local mask="$3"
  236. [ "$mask" = "00:00:00:00:00:00" ] && mask="ff:ff:ff:ff:ff:ff";
  237. local oIFS="$IFS"; IFS=":"; set -- $mask; IFS="$oIFS"
  238. local mask1=$1
  239. local mask6=$6
  240. local oIFS="$IFS"; IFS=":"; set -- $ref; IFS="$oIFS"
  241. [ "$((0x$mask1))" -gt 0 ] && {
  242. b1="0x$1"
  243. [ "$id" -gt 0 ] && \
  244. b1=$(($b1 ^ ((($id - 1) << 2) | 0x2)))
  245. printf "%02x:%s:%s:%s:%s:%s" $b1 $2 $3 $4 $5 $6
  246. return
  247. }
  248. [ "$((0x$mask6))" -lt 255 ] && {
  249. printf "%s:%s:%s:%s:%s:%02x" $1 $2 $3 $4 $5 $(( 0x$6 ^ $id ))
  250. return
  251. }
  252. off2=$(( (0x$6 + $id) / 0x100 ))
  253. printf "%s:%s:%s:%s:%02x:%02x" \
  254. $1 $2 $3 $4 \
  255. $(( (0x$5 + $off2) % 0x100 )) \
  256. $(( (0x$6 + $id) % 0x100 ))
  257. }
  258. enable_mac80211() {
  259. local device="$1"
  260. config_get channel "$device" channel
  261. config_get vifs "$device" vifs
  262. config_get txpower "$device" txpower
  263. config_get country "$device" country
  264. config_get distance "$device" distance
  265. config_get txantenna "$device" txantenna all
  266. config_get rxantenna "$device" rxantenna all
  267. config_get antenna_gain "$device" antenna_gain 0
  268. config_get frag "$device" frag
  269. config_get rts "$device" rts
  270. find_mac80211_phy "$device" || return 0
  271. config_get phy "$device" phy
  272. local i=0
  273. local macidx=0
  274. local apidx=0
  275. fixed=""
  276. local hostapd_ctrl=""
  277. [ -n "$country" ] && {
  278. iw reg get | grep -q "^country $country:" || {
  279. iw reg set "$country"
  280. sleep 1
  281. }
  282. }
  283. config_get chanbw "$device" chanbw
  284. [ -n "$chanbw" -a -d /sys/kernel/debug/ieee80211/$phy/ath9k ] && echo "$chanbw" > /sys/kernel/debug/ieee80211/$phy/ath9k/chanbw
  285. [ -n "$chanbw" -a -d /sys/kernel/debug/ieee80211/$phy/ath5k ] && echo "$chanbw" > /sys/kernel/debug/ieee80211/$phy/ath5k/bwmode
  286. [ "$channel" = "auto" -o "$channel" = "0" ] || {
  287. fixed=1
  288. }
  289. iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1
  290. iw phy "$phy" set antenna_gain $antenna_gain
  291. [ -n "$distance" ] && iw phy "$phy" set distance "$distance"
  292. [ -n "$frag" ] && iw phy "$phy" set frag "${frag%%.*}"
  293. [ -n "$rts" ] && iw phy "$phy" set rts "${rts%%.*}"
  294. export channel fixed
  295. # convert channel to frequency
  296. local freq="$(get_freq "$phy" "${fixed:+$channel}")"
  297. wifi_fixup_hwmode "$device" "g"
  298. for vif in $vifs; do
  299. config_get ifname "$vif" ifname
  300. [ -n "$ifname" ] || {
  301. [ $i -gt 0 ] && ifname="wlan${phy#phy}-$i" || ifname="wlan${phy#phy}"
  302. }
  303. config_set "$vif" ifname "$ifname"
  304. config_get mode "$vif" mode
  305. config_get ssid "$vif" ssid
  306. # It is far easier to delete and create the desired interface
  307. case "$mode" in
  308. adhoc)
  309. iw phy "$phy" interface add "$ifname" type adhoc
  310. ;;
  311. ap)
  312. # Hostapd will handle recreating the interface and
  313. # it's accompanying monitor
  314. apidx="$(($apidx + 1))"
  315. [ "$apidx" -gt 1 ] || iw phy "$phy" interface add "$ifname" type managed
  316. ;;
  317. mesh)
  318. config_get key "$vif" key ""
  319. if [ -n "$key" ]; then
  320. iw phy "$phy" interface add "$ifname" type mp
  321. else
  322. config_get mesh_id "$vif" mesh_id
  323. iw phy "$phy" interface add "$ifname" type mp mesh_id "$mesh_id"
  324. fi
  325. ;;
  326. monitor)
  327. iw phy "$phy" interface add "$ifname" type monitor
  328. ;;
  329. sta)
  330. local wdsflag
  331. config_get_bool wds "$vif" wds 0
  332. [ "$wds" -gt 0 ] && wdsflag="4addr on"
  333. iw phy "$phy" interface add "$ifname" type managed $wdsflag
  334. config_get_bool powersave "$vif" powersave 0
  335. [ "$powersave" -gt 0 ] && powersave="on" || powersave="off"
  336. iw "$ifname" set power_save "$powersave"
  337. ;;
  338. esac
  339. # All interfaces must have unique mac addresses
  340. # which can either be explicitly set in the device
  341. # section, or automatically generated
  342. config_get macaddr "$device" macaddr
  343. config_get vif_mac "$vif" macaddr
  344. [ -n "$vif_mac" ] || {
  345. vif_mac="$(mac80211_generate_mac $macidx $macaddr $(cat /sys/class/ieee80211/${phy}/address_mask))"
  346. macidx="$(($macidx + 1))"
  347. }
  348. [ "$mode" = "ap" ] || ifconfig "$ifname" hw ether "$vif_mac"
  349. config_set "$vif" macaddr "$vif_mac"
  350. # !! ap !!
  351. #
  352. # ALL ap functionality will be passed to hostapd
  353. #
  354. # !! station !!
  355. #
  356. # ALL station functionality will be passed to wpa_supplicant
  357. #
  358. if [ ! "$mode" = "ap" ]; then
  359. # We attempt to set the channel for all interfaces, although
  360. # mac80211 may not support it or the driver might not yet
  361. # for ap mode this is handled by hostapd
  362. config_get htmode "$device" htmode
  363. case "$htmode" in
  364. HT20|HT40+|HT40-) ;;
  365. *) htmode= ;;
  366. esac
  367. [ -n "$fixed" -a -n "$channel" ] && iw dev "$ifname" set channel "$channel" $htmode
  368. fi
  369. i=$(($i + 1))
  370. done
  371. local start_hostapd=
  372. rm -f /var/run/hostapd-$phy.conf
  373. for vif in $vifs; do
  374. config_get mode "$vif" mode
  375. case "$mode" in
  376. ap)
  377. mac80211_hostapd_setup_bss "$phy" "$vif"
  378. start_hostapd=1
  379. ;;
  380. mesh)
  381. config_get key "$vif" key ""
  382. [ -n "$key" ] && authsae_start_interface "$device" "$vif"
  383. ;;
  384. esac
  385. done
  386. [ -n "$start_hostapd" ] && {
  387. hostapd -P /var/run/wifi-$phy.pid -B /var/run/hostapd-$phy.conf || {
  388. echo "Failed to start hostapd for $phy"
  389. return
  390. }
  391. sleep 2
  392. for vif in $vifs; do
  393. config_get mode "$vif" mode
  394. config_get ifname "$vif" ifname
  395. [ "$mode" = "ap" ] || continue
  396. hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd-$phy/$ifname}"
  397. mac80211_start_vif "$vif" "$ifname"
  398. done
  399. }
  400. for vif in $vifs; do
  401. config_get mode "$vif" mode
  402. config_get ifname "$vif" ifname
  403. [ "$mode" = "ap" ] || ifconfig "$ifname" up
  404. config_get vif_txpower "$vif" txpower
  405. # use vif_txpower (from wifi-iface) to override txpower (from
  406. # wifi-device) if the latter doesn't exist
  407. txpower="${txpower:-$vif_txpower}"
  408. [ -z "$txpower" ] || iw dev "$ifname" set txpower fixed "${txpower%%.*}00"
  409. case "$mode" in
  410. adhoc)
  411. config_get bssid "$vif" bssid
  412. config_get ssid "$vif" ssid
  413. config_get beacon_int "$device" beacon_int
  414. config_get basic_rate_list "$device" basic_rate
  415. config_get encryption "$vif" encryption
  416. config_get key "$vif" key 1
  417. config_get mcast_rate "$vif" mcast_rate
  418. config_get htmode "$device" htmode
  419. case "$htmode" in
  420. HT20|HT40+|HT40-) ;;
  421. *) htmode= ;;
  422. esac
  423. local keyspec=""
  424. [ "$encryption" == "psk" -o "$encryption" == "psk2" ] && {
  425. if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
  426. wpa_supplicant_setup_vif "$vif" nl80211 "${hostapd_ctrl:+-H $hostapd_ctrl}" $freq $htmode || {
  427. echo "enable_mac80211($device): Failed to set up wpa_supplicant for interface $ifname" >&2
  428. # make sure this wifi interface won't accidentally stay open without encryption
  429. ifconfig "$ifname" down
  430. }
  431. mac80211_start_vif "$vif" "$ifname"
  432. continue
  433. fi
  434. }
  435. [ "$encryption" == "wep" ] && {
  436. case "$key" in
  437. [1234])
  438. local idx
  439. for idx in 1 2 3 4; do
  440. local ikey
  441. config_get ikey "$vif" "key$idx"
  442. [ -n "$ikey" ] && {
  443. ikey="$(($idx - 1)):$(prepare_key_wep "$ikey")"
  444. [ $idx -eq $key ] && ikey="d:$ikey"
  445. append keyspec "$ikey"
  446. }
  447. done
  448. ;;
  449. *) append keyspec "d:0:$(prepare_key_wep "$key")" ;;
  450. esac
  451. }
  452. local br brval brsub brstr
  453. [ -n "$basic_rate_list" ] && {
  454. for br in $basic_rate_list; do
  455. brval="$(($br / 1000))"
  456. brsub="$((($br / 100) % 10))"
  457. [ "$brsub" -gt 0 ] && brval="$brval.$brsub"
  458. [ -n "$brstr" ] && brstr="$brstr,"
  459. brstr="$brstr$brval"
  460. done
  461. }
  462. local mcval=""
  463. [ -n "$mcast_rate" ] && {
  464. mcval="$(($mcast_rate / 1000))"
  465. mcsub="$(( ($mcast_rate / 100) % 10 ))"
  466. [ "$mcsub" -gt 0 ] && mcval="$mcval.$mcsub"
  467. }
  468. iw dev "$ifname" ibss join "$ssid" $freq $htmode \
  469. ${fixed:+fixed-freq} $bssid \
  470. ${beacon_int:+beacon-interval $beacon_int} \
  471. ${brstr:+basic-rates $brstr} \
  472. ${mcval:+mcast-rate $mcval} \
  473. ${keyspec:+keys $keyspec}
  474. ;;
  475. mesh)
  476. mp_list="mesh_retry_timeout mesh_confirm_timeout mesh_holding_timeout mesh_max_peer_links
  477. mesh_max_retries mesh_ttl mesh_element_ttl mesh_auto_open_plinks mesh_hwmp_max_preq_retries
  478. mesh_path_refresh_time mesh_min_discovery_timeout mesh_hwmp_active_path_timeout
  479. mesh_hwmp_preq_min_interval mesh_hwmp_net_diameter_traversal_time mesh_hwmp_rootmode
  480. mesh_hwmp_rann_interval mesh_gate_announcements mesh_fwding mesh_sync_offset_max_neighor
  481. mesh_rssi_threshold mesh_hwmp_active_path_to_root_timeout mesh_hwmp_root_interval
  482. mesh_hwmp_confirmation_interval mesh_power_mode mesh_awake_window"
  483. for mp in $mp_list
  484. do
  485. config_get mp_val "$vif" "$mp" ""
  486. [ -n "$mp_val" ] && iw dev "$ifname" set mesh_param "$mp" "$mp_val"
  487. done
  488. ;;
  489. sta)
  490. if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
  491. wpa_supplicant_setup_vif "$vif" nl80211 "${hostapd_ctrl:+-H $hostapd_ctrl}" || {
  492. echo "enable_mac80211($device): Failed to set up wpa_supplicant for interface $ifname" >&2
  493. # make sure this wifi interface won't accidentally stay open without encryption
  494. ifconfig "$ifname" down
  495. continue
  496. }
  497. fi
  498. ;;
  499. esac
  500. [ "$mode" = "ap" ] || mac80211_start_vif "$vif" "$ifname"
  501. done
  502. }
  503. check_mac80211_device() {
  504. config_get phy "$1" phy
  505. [ -z "$phy" ] && {
  506. find_mac80211_phy "$1" >/dev/null || return 0
  507. config_get phy "$1" phy
  508. }
  509. [ "$phy" = "$dev" ] && found=1
  510. }
  511. detect_mac80211() {
  512. devidx=0
  513. config_load wireless
  514. while :; do
  515. config_get type "radio$devidx" type
  516. [ -n "$type" ] || break
  517. devidx=$(($devidx + 1))
  518. done
  519. for dev in $(ls /sys/class/ieee80211); do
  520. found=0
  521. config_foreach check_mac80211_device wifi-device
  522. [ "$found" -gt 0 ] && continue
  523. mode_11n=""
  524. mode_band="g"
  525. channel="11"
  526. ht_cap=0
  527. for cap in $(iw phy "$dev" info | grep 'Capabilities:' | cut -d: -f2); do
  528. ht_cap="$(($ht_cap | $cap))"
  529. done
  530. ht_capab="";
  531. [ "$ht_cap" -gt 0 ] && {
  532. mode_11n="n"
  533. append ht_capab " option htmode HT20" "$N"
  534. list=" list ht_capab"
  535. [ "$(($ht_cap & 1))" -eq 1 ] && append ht_capab "$list LDPC" "$N"
  536. [ "$(($ht_cap & 16))" -eq 16 ] && append ht_capab "$list GF" "$N"
  537. [ "$(($ht_cap & 32))" -eq 32 ] && append ht_capab "$list SHORT-GI-20" "$N"
  538. [ "$(($ht_cap & 64))" -eq 64 ] && append ht_capab "$list SHORT-GI-40" "$N"
  539. [ "$(($ht_cap & 128))" -eq 128 ] && append ht_capab "$list TX-STBC" "$N"
  540. [ "$(($ht_cap & 768))" -eq 256 ] && append ht_capab "$list RX-STBC1" "$N"
  541. [ "$(($ht_cap & 768))" -eq 512 ] && append ht_capab "$list RX-STBC12" "$N"
  542. [ "$(($ht_cap & 768))" -eq 768 ] && append ht_capab "$list RX-STBC123" "$N"
  543. [ "$(($ht_cap & 4096))" -eq 4096 ] && append ht_capab "$list DSSS_CCK-40" "$N"
  544. }
  545. iw phy "$dev" info | grep -q '2412 MHz' || { mode_band="a"; channel="36"; }
  546. if [ -x /usr/bin/readlink ]; then
  547. path="$(readlink -f /sys/class/ieee80211/${dev}/device)"
  548. path="${path##/sys/devices/}"
  549. dev_id=" option path '$path'"
  550. else
  551. dev_id=" option macaddr $(cat /sys/class/ieee80211/${dev}/macaddress)"
  552. fi
  553. cat <<EOF
  554. config wifi-device radio$devidx
  555. option type mac80211
  556. option channel ${channel}
  557. option hwmode 11${mode_11n}${mode_band}
  558. $dev_id
  559. $ht_capab
  560. # REMOVE THIS LINE TO ENABLE WIFI:
  561. option disabled 1
  562. config wifi-iface
  563. option device radio$devidx
  564. option network lan
  565. option mode ap
  566. option ssid OpenWrt
  567. option encryption none
  568. EOF
  569. devidx=$(($devidx + 1))
  570. done
  571. }