From 53a371041c064c3ae416b3149f62f6cefcd33868 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Wed, 18 Jul 2018 20:11:35 -0400 Subject: [PATCH] Remove the FreeBSD 9 compatibility layer. Long live the FreeBSD 11 compatibility layer! --- src/libs/compat/freebsd_network/Condvar.cpp | 81 - src/libs/compat/freebsd_network/Condvar.h | 26 - src/libs/compat/freebsd_network/Jamfile | 65 - src/libs/compat/freebsd_network/Unit.cpp | 59 - src/libs/compat/freebsd_network/bus.cpp | 940 ----- src/libs/compat/freebsd_network/callout.cpp | 238 -- src/libs/compat/freebsd_network/clock.c | 44 - src/libs/compat/freebsd_network/compat.c | 659 ---- .../freebsd_network/compat/altq/if_altq.h | 43 - .../freebsd_network/compat/dev/mii/mii.h | 202 - .../compat/dev/mii/mii_bitbang.h | 54 - .../freebsd_network/compat/dev/mii/miidevs | 325 -- .../freebsd_network/compat/dev/mii/miivar.h | 315 -- .../freebsd_network/compat/dev/ofw/openfirm.h | 0 .../freebsd_network/compat/dev/pci/pcireg.h | 988 ----- .../freebsd_network/compat/dev/pci/pcivar.h | 69 - .../freebsd_network/compat/machine/_bus.h | 32 - .../freebsd_network/compat/machine/atomic.h | 31 - .../freebsd_network/compat/machine/bus.h | 349 -- .../freebsd_network/compat/machine/bus_dma.h | 11 - .../freebsd_network/compat/machine/clock.h | 9 - .../freebsd_network/compat/machine/cpufunc.h | 43 - .../freebsd_network/compat/machine/endian.h | 12 - .../freebsd_network/compat/machine/in_cksum.h | 32 - .../freebsd_network/compat/machine/md_var.h | 0 .../compat/machine/ofw_machdep.h | 0 .../freebsd_network/compat/machine/resource.h | 14 - .../freebsd_network/compat/machine/stdarg.h | 12 - .../compat/freebsd_network/compat/miibus_if.h | 0 .../compat/freebsd_network/compat/net/bpf.h | 32 - .../freebsd_network/compat/net/ethernet.h | 405 -- .../compat/freebsd_network/compat/net/if.h | 110 - .../freebsd_network/compat/net/if_arp.h | 115 - .../freebsd_network/compat/net/if_llc.h | 161 - .../freebsd_network/compat/net/if_media.h | 672 ---- .../freebsd_network/compat/net/if_types.h | 14 - .../freebsd_network/compat/net/if_var.h | 696 ---- .../freebsd_network/compat/net/if_vlan_var.h | 135 - .../compat/freebsd_network/compat/net/route.h | 24 - .../freebsd_network/compat/netinet/if_ether.h | 13 - .../freebsd_network/compat/netinet/in_systm.h | 0 .../freebsd_network/compat/netinet/in_var.h | 11 - .../compat/security/mac/mac_framework.h | 9 - .../freebsd_network/compat/sys/_bus_dma.h | 62 - .../freebsd_network/compat/sys/_mutex.h | 26 - .../compat/freebsd_network/compat/sys/_task.h | 24 - .../freebsd_network/compat/sys/_timeval.h | 11 - .../freebsd_network/compat/sys/_types.h | 20 - .../compat/freebsd_network/compat/sys/bus.h | 158 - .../freebsd_network/compat/sys/bus_dma.h | 271 -- .../freebsd_network/compat/sys/callout.h | 45 - .../compat/freebsd_network/compat/sys/cdefs.h | 310 -- .../freebsd_network/compat/sys/condvar.h | 31 - .../compat/freebsd_network/compat/sys/ctype.h | 11 - .../freebsd_network/compat/sys/endian.h | 197 - .../compat/freebsd_network/compat/sys/errno.h | 16 - .../compat/freebsd_network/compat/sys/event.h | 13 - .../freebsd_network/compat/sys/eventhandler.h | 176 - .../freebsd_network/compat/sys/firmware.h | 23 - .../freebsd_network/compat/sys/haiku-module.h | 264 -- .../freebsd_network/compat/sys/ioccom.h | 12 - .../freebsd_network/compat/sys/kernel.h | 51 - .../freebsd_network/compat/sys/kthread.h | 0 .../compat/freebsd_network/compat/sys/ktr.h | 196 - .../freebsd_network/compat/sys/libkern.h | 20 - .../freebsd_network/compat/sys/limits.h | 9 - .../freebsd_network/compat/sys/linker.h | 9 - .../freebsd_network/compat/sys/linker_set.h | 64 - .../compat/freebsd_network/compat/sys/lock.h | 0 .../freebsd_network/compat/sys/malloc.h | 67 - .../freebsd_network/compat/sys/mbuf-fbsd.h | 117 - .../compat/freebsd_network/compat/sys/mbuf.h | 227 -- .../freebsd_network/compat/sys/module.h | 23 - .../compat/freebsd_network/compat/sys/mount.h | 9 - .../compat/freebsd_network/compat/sys/mutex.h | 92 - .../compat/freebsd_network/compat/sys/namei.h | 9 - .../compat/freebsd_network/compat/sys/param.h | 75 - .../compat/freebsd_network/compat/sys/pcpu.h | 22 - .../freebsd_network/compat/sys/priority.h | 12 - .../compat/freebsd_network/compat/sys/priv.h | 38 - .../compat/freebsd_network/compat/sys/proc.h | 9 - .../freebsd_network/compat/sys/protosw.h | 0 .../compat/freebsd_network/compat/sys/queue.h | 552 --- .../freebsd_network/compat/sys/random.h | 0 .../compat/freebsd_network/compat/sys/rman.h | 89 - .../freebsd_network/compat/sys/socket.h | 18 - .../freebsd_network/compat/sys/sockio.h | 16 - .../freebsd_network/compat/sys/sysctl.h | 165 - .../freebsd_network/compat/sys/syslog.h | 11 - .../compat/freebsd_network/compat/sys/systm.h | 103 - .../freebsd_network/compat/sys/taskqueue.h | 43 - .../compat/freebsd_network/compat/sys/time.h | 20 - .../compat/freebsd_network/compat/sys/types.h | 22 - .../compat/freebsd_network/compat/vm/pmap.h | 0 .../compat/freebsd_network/compat/vm/uma.h | 12 - .../compat/freebsd_network/compat/vm/vm.h | 36 - .../compat/freebsd_network/compat_cpp.cpp | 46 - src/libs/compat/freebsd_network/compat_cpp.h | 27 - src/libs/compat/freebsd_network/condvar.c | 42 - src/libs/compat/freebsd_network/device.c | 305 -- src/libs/compat/freebsd_network/device.h | 96 - src/libs/compat/freebsd_network/driver.c | 295 -- .../compat/freebsd_network/eventhandler.c | 42 - .../compat/freebsd_network/fbsd_busdma_x86.c | 1194 ------ src/libs/compat/freebsd_network/fbsd_ether.c | 118 - .../compat/freebsd_network/fbsd_if_media.c | 554 --- src/libs/compat/freebsd_network/fbsd_mbuf.c | 1018 ----- src/libs/compat/freebsd_network/fbsd_mbuf2.c | 452 --- src/libs/compat/freebsd_network/fbsd_mii.c | 578 --- .../compat/freebsd_network/fbsd_mii_bitbang.c | 180 - .../compat/freebsd_network/fbsd_mii_physubr.c | 664 ---- src/libs/compat/freebsd_network/fbsd_time.c | 53 - src/libs/compat/freebsd_network/firmware.c | 146 - src/libs/compat/freebsd_network/if.c | 763 ---- src/libs/compat/freebsd_network/libkern.c | 15 - src/libs/compat/freebsd_network/mbuf.c | 295 -- src/libs/compat/freebsd_network/mii.c | 59 - src/libs/compat/freebsd_network/miidevs2h.awk | 149 - src/libs/compat/freebsd_network/mutex.c | 63 - src/libs/compat/freebsd_network/priv.cpp | 27 - src/libs/compat/freebsd_network/shared.h | 56 - src/libs/compat/freebsd_network/synch.c | 47 - src/libs/compat/freebsd_network/systm.c | 20 - src/libs/compat/freebsd_network/taskqueue.c | 387 -- src/libs/compat/freebsd_network/unit.c | 99 - src/libs/compat/freebsd_network/unit.h | 33 - src/libs/compat/freebsd_wlan/Jamfile | 4 - .../crypto/rijndael/rijndael-alg-fst.c | 1223 ------ .../crypto/rijndael/rijndael-api.c | 59 - .../freebsd_wlan/crypto/rijndael/rijndael.h | 55 - .../crypto/rijndael/rijndael_local.h | 7 - src/libs/compat/freebsd_wlan/net80211/Jamfile | 65 - .../compat/freebsd_wlan/net80211/_ieee80211.h | 403 -- .../compat/freebsd_wlan/net80211/ieee80211.c | 1722 --------- .../compat/freebsd_wlan/net80211/ieee80211.h | 1088 ------ .../freebsd_wlan/net80211/ieee80211_acl.c | 340 -- .../freebsd_wlan/net80211/ieee80211_action.c | 279 -- .../freebsd_wlan/net80211/ieee80211_action.h | 52 - .../freebsd_wlan/net80211/ieee80211_adhoc.c | 919 ----- .../freebsd_wlan/net80211/ieee80211_adhoc.h | 35 - .../freebsd_wlan/net80211/ieee80211_ageq.c | 237 -- .../freebsd_wlan/net80211/ieee80211_ageq.h | 54 - .../freebsd_wlan/net80211/ieee80211_alq.c | 155 - .../freebsd_wlan/net80211/ieee80211_alq.h | 51 - .../freebsd_wlan/net80211/ieee80211_amrr.c | 317 -- .../freebsd_wlan/net80211/ieee80211_amrr.h | 61 - .../freebsd_wlan/net80211/ieee80211_crypto.c | 669 ---- .../freebsd_wlan/net80211/ieee80211_crypto.h | 254 -- .../net80211/ieee80211_crypto_ccmp.c | 635 --- .../net80211/ieee80211_crypto_none.c | 144 - .../net80211/ieee80211_crypto_tkip.c | 999 ----- .../net80211/ieee80211_crypto_wep.c | 480 --- .../freebsd_wlan/net80211/ieee80211_ddb.c | 879 ----- .../freebsd_wlan/net80211/ieee80211_dfs.c | 377 -- .../freebsd_wlan/net80211/ieee80211_dfs.h | 57 - .../freebsd_wlan/net80211/ieee80211_haiku.cpp | 753 ---- .../freebsd_wlan/net80211/ieee80211_haiku.h | 395 -- .../freebsd_wlan/net80211/ieee80211_hostap.c | 2321 ----------- .../freebsd_wlan/net80211/ieee80211_hostap.h | 35 - .../freebsd_wlan/net80211/ieee80211_ht.c | 2781 -------------- .../freebsd_wlan/net80211/ieee80211_ht.h | 205 - .../freebsd_wlan/net80211/ieee80211_hwmp.c | 1438 ------- .../freebsd_wlan/net80211/ieee80211_input.c | 894 ----- .../freebsd_wlan/net80211/ieee80211_input.h | 258 -- .../freebsd_wlan/net80211/ieee80211_ioctl.c | 3420 ----------------- .../freebsd_wlan/net80211/ieee80211_ioctl.h | 873 ----- .../freebsd_wlan/net80211/ieee80211_mesh.c | 2765 ------------- .../freebsd_wlan/net80211/ieee80211_mesh.h | 503 --- .../freebsd_wlan/net80211/ieee80211_monitor.c | 138 - .../freebsd_wlan/net80211/ieee80211_monitor.h | 35 - .../freebsd_wlan/net80211/ieee80211_node.c | 2652 ------------- .../freebsd_wlan/net80211/ieee80211_node.h | 461 --- .../freebsd_wlan/net80211/ieee80211_output.c | 3065 --------------- .../freebsd_wlan/net80211/ieee80211_phy.c | 465 --- .../freebsd_wlan/net80211/ieee80211_phy.h | 157 - .../freebsd_wlan/net80211/ieee80211_power.c | 525 --- .../freebsd_wlan/net80211/ieee80211_power.h | 79 - .../freebsd_wlan/net80211/ieee80211_proto.c | 1930 ---------- .../freebsd_wlan/net80211/ieee80211_proto.h | 416 -- .../net80211/ieee80211_radiotap.c | 355 -- .../net80211/ieee80211_radiotap.h | 234 -- .../freebsd_wlan/net80211/ieee80211_ratectl.c | 117 - .../freebsd_wlan/net80211/ieee80211_ratectl.h | 128 - .../net80211/ieee80211_ratectl_none.c | 114 - .../net80211/ieee80211_regdomain.c | 448 --- .../net80211/ieee80211_regdomain.h | 282 -- .../net80211/ieee80211_rssadapt.c | 349 -- .../net80211/ieee80211_rssadapt.h | 71 - .../freebsd_wlan/net80211/ieee80211_scan.c | 1258 ------ .../freebsd_wlan/net80211/ieee80211_scan.h | 300 -- .../net80211/ieee80211_scan_sta.c | 1961 ---------- .../freebsd_wlan/net80211/ieee80211_sta.c | 1761 --------- .../freebsd_wlan/net80211/ieee80211_sta.h | 36 - .../freebsd_wlan/net80211/ieee80211_superg.c | 900 ----- .../freebsd_wlan/net80211/ieee80211_superg.h | 129 - .../freebsd_wlan/net80211/ieee80211_tdma.c | 820 ---- .../freebsd_wlan/net80211/ieee80211_tdma.h | 102 - .../freebsd_wlan/net80211/ieee80211_var.h | 928 ----- .../freebsd_wlan/net80211/ieee80211_wds.c | 800 ---- .../freebsd_wlan/net80211/ieee80211_wds.h | 39 - .../freebsd_wlan/net80211/ieee80211_xauth.c | 76 - .../compat/freebsd_wlan/net80211/opt_inet.h | 6 - .../compat/freebsd_wlan/net80211/opt_inet6.h | 6 - .../compat/freebsd_wlan/net80211/opt_ipx.h | 6 - .../compat/freebsd_wlan/net80211/opt_wlan.h | 8 - 205 files changed, 68097 deletions(-) delete mode 100644 src/libs/compat/freebsd_network/Condvar.cpp delete mode 100644 src/libs/compat/freebsd_network/Condvar.h delete mode 100644 src/libs/compat/freebsd_network/Jamfile delete mode 100644 src/libs/compat/freebsd_network/Unit.cpp delete mode 100644 src/libs/compat/freebsd_network/bus.cpp delete mode 100644 src/libs/compat/freebsd_network/callout.cpp delete mode 100644 src/libs/compat/freebsd_network/clock.c delete mode 100644 src/libs/compat/freebsd_network/compat.c delete mode 100644 src/libs/compat/freebsd_network/compat/altq/if_altq.h delete mode 100644 src/libs/compat/freebsd_network/compat/dev/mii/mii.h delete mode 100644 src/libs/compat/freebsd_network/compat/dev/mii/mii_bitbang.h delete mode 100644 src/libs/compat/freebsd_network/compat/dev/mii/miidevs delete mode 100644 src/libs/compat/freebsd_network/compat/dev/mii/miivar.h delete mode 100644 src/libs/compat/freebsd_network/compat/dev/ofw/openfirm.h delete mode 100644 src/libs/compat/freebsd_network/compat/dev/pci/pcireg.h delete mode 100644 src/libs/compat/freebsd_network/compat/dev/pci/pcivar.h delete mode 100644 src/libs/compat/freebsd_network/compat/machine/_bus.h delete mode 100644 src/libs/compat/freebsd_network/compat/machine/atomic.h delete mode 100644 src/libs/compat/freebsd_network/compat/machine/bus.h delete mode 100644 src/libs/compat/freebsd_network/compat/machine/bus_dma.h delete mode 100644 src/libs/compat/freebsd_network/compat/machine/clock.h delete mode 100644 src/libs/compat/freebsd_network/compat/machine/cpufunc.h delete mode 100644 src/libs/compat/freebsd_network/compat/machine/endian.h delete mode 100644 src/libs/compat/freebsd_network/compat/machine/in_cksum.h delete mode 100644 src/libs/compat/freebsd_network/compat/machine/md_var.h delete mode 100644 src/libs/compat/freebsd_network/compat/machine/ofw_machdep.h delete mode 100644 src/libs/compat/freebsd_network/compat/machine/resource.h delete mode 100644 src/libs/compat/freebsd_network/compat/machine/stdarg.h delete mode 100644 src/libs/compat/freebsd_network/compat/miibus_if.h delete mode 100644 src/libs/compat/freebsd_network/compat/net/bpf.h delete mode 100644 src/libs/compat/freebsd_network/compat/net/ethernet.h delete mode 100644 src/libs/compat/freebsd_network/compat/net/if.h delete mode 100644 src/libs/compat/freebsd_network/compat/net/if_arp.h delete mode 100644 src/libs/compat/freebsd_network/compat/net/if_llc.h delete mode 100644 src/libs/compat/freebsd_network/compat/net/if_media.h delete mode 100644 src/libs/compat/freebsd_network/compat/net/if_types.h delete mode 100644 src/libs/compat/freebsd_network/compat/net/if_var.h delete mode 100644 src/libs/compat/freebsd_network/compat/net/if_vlan_var.h delete mode 100644 src/libs/compat/freebsd_network/compat/net/route.h delete mode 100644 src/libs/compat/freebsd_network/compat/netinet/if_ether.h delete mode 100644 src/libs/compat/freebsd_network/compat/netinet/in_systm.h delete mode 100644 src/libs/compat/freebsd_network/compat/netinet/in_var.h delete mode 100644 src/libs/compat/freebsd_network/compat/security/mac/mac_framework.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/_bus_dma.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/_mutex.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/_task.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/_timeval.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/_types.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/bus.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/bus_dma.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/callout.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/cdefs.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/condvar.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/ctype.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/endian.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/errno.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/event.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/eventhandler.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/firmware.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/haiku-module.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/ioccom.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/kernel.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/kthread.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/ktr.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/libkern.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/limits.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/linker.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/linker_set.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/lock.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/malloc.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/mbuf-fbsd.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/mbuf.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/module.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/mount.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/mutex.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/namei.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/param.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/pcpu.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/priority.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/priv.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/proc.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/protosw.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/queue.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/random.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/rman.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/socket.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/sockio.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/sysctl.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/syslog.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/systm.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/taskqueue.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/time.h delete mode 100644 src/libs/compat/freebsd_network/compat/sys/types.h delete mode 100644 src/libs/compat/freebsd_network/compat/vm/pmap.h delete mode 100644 src/libs/compat/freebsd_network/compat/vm/uma.h delete mode 100644 src/libs/compat/freebsd_network/compat/vm/vm.h delete mode 100644 src/libs/compat/freebsd_network/compat_cpp.cpp delete mode 100644 src/libs/compat/freebsd_network/compat_cpp.h delete mode 100644 src/libs/compat/freebsd_network/condvar.c delete mode 100644 src/libs/compat/freebsd_network/device.c delete mode 100644 src/libs/compat/freebsd_network/device.h delete mode 100644 src/libs/compat/freebsd_network/driver.c delete mode 100644 src/libs/compat/freebsd_network/eventhandler.c delete mode 100644 src/libs/compat/freebsd_network/fbsd_busdma_x86.c delete mode 100644 src/libs/compat/freebsd_network/fbsd_ether.c delete mode 100644 src/libs/compat/freebsd_network/fbsd_if_media.c delete mode 100644 src/libs/compat/freebsd_network/fbsd_mbuf.c delete mode 100644 src/libs/compat/freebsd_network/fbsd_mbuf2.c delete mode 100644 src/libs/compat/freebsd_network/fbsd_mii.c delete mode 100644 src/libs/compat/freebsd_network/fbsd_mii_bitbang.c delete mode 100644 src/libs/compat/freebsd_network/fbsd_mii_physubr.c delete mode 100644 src/libs/compat/freebsd_network/fbsd_time.c delete mode 100644 src/libs/compat/freebsd_network/firmware.c delete mode 100644 src/libs/compat/freebsd_network/if.c delete mode 100644 src/libs/compat/freebsd_network/libkern.c delete mode 100644 src/libs/compat/freebsd_network/mbuf.c delete mode 100644 src/libs/compat/freebsd_network/mii.c delete mode 100644 src/libs/compat/freebsd_network/miidevs2h.awk delete mode 100644 src/libs/compat/freebsd_network/mutex.c delete mode 100644 src/libs/compat/freebsd_network/priv.cpp delete mode 100644 src/libs/compat/freebsd_network/shared.h delete mode 100644 src/libs/compat/freebsd_network/synch.c delete mode 100644 src/libs/compat/freebsd_network/systm.c delete mode 100644 src/libs/compat/freebsd_network/taskqueue.c delete mode 100644 src/libs/compat/freebsd_network/unit.c delete mode 100644 src/libs/compat/freebsd_network/unit.h delete mode 100644 src/libs/compat/freebsd_wlan/Jamfile delete mode 100644 src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael-alg-fst.c delete mode 100644 src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael-api.c delete mode 100644 src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael.h delete mode 100644 src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael_local.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/Jamfile delete mode 100644 src/libs/compat/freebsd_wlan/net80211/_ieee80211.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_acl.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_action.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_action.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_adhoc.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_adhoc.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_ageq.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_ageq.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_alq.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_alq.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_amrr.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_amrr.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_ccmp.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_none.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_tkip.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_wep.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_ddb.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_dfs.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_dfs.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.cpp delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_hostap.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_hostap.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_ht.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_ht.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_hwmp.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_input.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_input.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_mesh.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_mesh.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_monitor.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_monitor.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_node.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_node.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_output.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_phy.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_phy.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_power.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_power.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_proto.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_proto.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_radiotap.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_radiotap.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_ratectl.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_ratectl.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_ratectl_none.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_regdomain.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_regdomain.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_rssadapt.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_rssadapt.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_scan.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_scan.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_scan_sta.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_sta.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_sta.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_superg.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_superg.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_tdma.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_tdma.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_var.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_wds.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_wds.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/ieee80211_xauth.c delete mode 100644 src/libs/compat/freebsd_wlan/net80211/opt_inet.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/opt_inet6.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/opt_ipx.h delete mode 100644 src/libs/compat/freebsd_wlan/net80211/opt_wlan.h diff --git a/src/libs/compat/freebsd_network/Condvar.cpp b/src/libs/compat/freebsd_network/Condvar.cpp deleted file mode 100644 index 9cb5be1dcd..0000000000 --- a/src/libs/compat/freebsd_network/Condvar.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2009 Colin Günther, coling@gmx.de - * All Rights Reserved. Distributed under the terms of the MIT License. - */ - - -extern "C" { -#include -#include -} - -#include "Condvar.h" - - -void -conditionInit(struct cv* variable, const char* description) -{ - variable->condition.Init(variable, description); -} - - -void -conditionPublish(struct cv* variable, const void* waitChannel, - const char* description) -{ - variable->condition.Publish(waitChannel, description); -} - - -void -conditionUnpublish(struct cv* variable) -{ - variable->condition.Unpublish(); -} - - -int -conditionTimedWait(struct cv* variable, const int timeout) -{ - status_t status = variable->condition.Wait(B_RELATIVE_TIMEOUT, - ticks_to_usecs(timeout)); - - if (status != B_OK) - status = EWOULDBLOCK; - return status; -} - - -void -conditionWait(struct cv* variable) -{ - variable->condition.Wait(); -} - - -void -conditionNotifyOne(struct cv* variable) -{ - variable->condition.NotifyOne(); -} - - -int -publishedConditionTimedWait(const void* waitChannel, const int timeout) -{ - ConditionVariableEntry variableEntry; - - status_t status = variableEntry.Wait(waitChannel, B_RELATIVE_TIMEOUT, - ticks_to_usecs(timeout)); - - if (status != B_OK) - status = EWOULDBLOCK; - return status; -} - - -void -publishedConditionNotifyAll(const void* waitChannel) -{ - ConditionVariable::NotifyAll(waitChannel, B_OK); -} diff --git a/src/libs/compat/freebsd_network/Condvar.h b/src/libs/compat/freebsd_network/Condvar.h deleted file mode 100644 index bff1b0d7bb..0000000000 --- a/src/libs/compat/freebsd_network/Condvar.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2009 Colin Günther, coling@gmx.de - * All Rights Reserved. Distributed under the terms of the MIT License. - */ -#ifndef CONDVAR_H_ -#define CONDVAR_H_ - - -#ifdef __cplusplus -extern "C" { -#endif - -void conditionInit(struct cv*, const char*); -void conditionPublish(struct cv*, const void*, const char*); -void conditionUnpublish(struct cv*); -int conditionTimedWait(struct cv*, const int); -void conditionWait(struct cv*); -void conditionNotifyOne(struct cv*); -int publishedConditionTimedWait(const void*, const int); -void publishedConditionNotifyAll(const void*); - -#ifdef __cplusplus -} -#endif - -#endif /* CONDVAR_H_ */ diff --git a/src/libs/compat/freebsd_network/Jamfile b/src/libs/compat/freebsd_network/Jamfile deleted file mode 100644 index 3d7b496a88..0000000000 --- a/src/libs/compat/freebsd_network/Jamfile +++ /dev/null @@ -1,65 +0,0 @@ -SubDir HAIKU_TOP src libs compat freebsd_network ; - -UseHeaders [ FDirName $(SUBDIR) ] : true ; -UseHeaders [ FDirName $(SUBDIR) compat ] : true ; -UsePrivateHeaders net ; -UsePrivateKernelHeaders ; -UseHeaders $(HAIKU_PRIVATE_KERNEL_HEADERS) : true ; - -# Enabling C++ structures in C only code -Includes [ FGristFiles kernel_c++_structs.h ] - : kernel_c++_struct_sizes.h ; - -SubDirCcFlags [ FDefines _KERNEL=1 _XOPEN_SOURCE ] ; - -KernelStaticLibrary libfreebsd_network.a : - bus.cpp - callout.cpp - clock.c - compat.c - compat_cpp.cpp - condvar.c - Condvar.cpp - device.c - driver.c - eventhandler.c - fbsd_busdma_x86.c - fbsd_ether.c - fbsd_if_media.c - fbsd_mbuf.c - fbsd_mbuf2.c - fbsd_mii.c - fbsd_mii_bitbang.c - fbsd_mii_physubr.c - fbsd_time.c - firmware.c - if.c - libkern.c - mbuf.c - mii.c - mutex.c - priv.cpp - synch.c - systm.c - taskqueue.c - unit.c - Unit.cpp - ; - -rule MIIHeaderGen -{ - SEARCH on $(2) = [ FDirName $(SUBDIR) compat dev mii ] ; - SEARCH on $(3) = $(SEARCH_SOURCE) ; - - Depends $(1) : $(2) $(3) ; - MakeLocateArch $(<) ; - MIIHeaderGen1 $(1) : $(2) $(3) ; - LocalClean clean : $(<) ; -} - -actions MIIHeaderGen1 -{ - gawk -v HEADERFILE=$(1) -f $(2[2]) $(2[1]) -} - -MIIHeaderGen [ FGristFiles miidevs.h ] : miidevs : miidevs2h.awk ; diff --git a/src/libs/compat/freebsd_network/Unit.cpp b/src/libs/compat/freebsd_network/Unit.cpp deleted file mode 100644 index 390878ef14..0000000000 --- a/src/libs/compat/freebsd_network/Unit.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2009 Colin Günther, coling@gmx.de - * All Rights Reserved. Distributed under the terms of the MIT License. - * - */ - - -/*! Wrapper functions for accessing the number buffer.*/ - - -#include "unit.h" - -#include - - -#define ID_STORE_FULL -1 - - -status_t -_new_unrhdr_buffer(struct unrhdr* idStore, uint32 maxIdCount) -{ - status_t status = B_OK; - - idStore->idBuffer = radix_bitmap_create(maxIdCount); - if (idStore->idBuffer == NULL) - status = B_NO_MEMORY; - - return status; -} - - -void -_delete_unrhdr_buffer_locked(struct unrhdr* idStore) -{ - radix_bitmap_destroy(idStore->idBuffer); -} - - -int -_alloc_unr_locked(struct unrhdr* idStore) -{ - radix_slot_t slotIndex; - int id = ID_STORE_FULL; - - slotIndex = radix_bitmap_alloc(idStore->idBuffer, 1); - if (slotIndex != RADIX_SLOT_NONE) - id = slotIndex + idStore->idBias; - - return id; -} - - -void -_free_unr_locked(struct unrhdr* idStore, u_int identity) -{ - uint32 slotIndex = (int32)identity - idStore->idBias; - - radix_bitmap_dealloc(idStore->idBuffer, slotIndex, 1); -} diff --git a/src/libs/compat/freebsd_network/bus.cpp b/src/libs/compat/freebsd_network/bus.cpp deleted file mode 100644 index 4a77a0af1c..0000000000 --- a/src/libs/compat/freebsd_network/bus.cpp +++ /dev/null @@ -1,940 +0,0 @@ -/* - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Copyright 2004, Marcus Overhagen. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ - - -extern "C" { -#include "device.h" -} - -#include - -#include - -#include - -extern "C" { -#include -#include -#include -#include -#include -#include -#include -} - -// private kernel header to get B_NO_HANDLED_INFO -#include - -#include - - -//#define DEBUG_BUS_SPACE_RW -#ifdef DEBUG_BUS_SPACE_RW -# define TRACE_BUS_SPACE_RW(x) driver_printf x -#else -# define TRACE_BUS_SPACE_RW(x) -#endif - -//#define DEBUG_PCI -#ifdef DEBUG_PCI -# define TRACE_PCI(dev, format, args...) device_printf(dev, format , ##args) -#else -# define TRACE_PCI(dev, format, args...) do { } while (0) -#endif - - -#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1)) - - -struct internal_intr { - device_t dev; - driver_filter_t filter; - driver_intr_t *handler; - void *arg; - int irq; - uint32 flags; - - thread_id thread; - sem_id sem; - int32 handling; -}; - -static int32 intr_wrapper(void *data); - - -static int -fls(int mask) -{ - int bit; - if (mask == 0) - return (0); - for (bit = 1; mask != 1; bit++) - mask = (unsigned int)mask >> 1; - return (bit); -} - - -static area_id -map_mem(void **virtualAddr, phys_addr_t _phy, size_t size, uint32 protection, - const char *name) -{ - uint32 offset = _phy & (B_PAGE_SIZE - 1); - phys_addr_t physicalAddr = _phy - offset; - area_id area; - - size = ROUNDUP(size + offset, B_PAGE_SIZE); - area = map_physical_memory(name, physicalAddr, size, B_ANY_KERNEL_ADDRESS, - protection, virtualAddr); - if (area < B_OK) - return area; - - *virtualAddr = (uint8 *)(*virtualAddr) + offset; - - return area; -} - - -static int -bus_alloc_irq_resource(device_t dev, struct resource *res) -{ - uint8 irq = pci_read_config(dev, PCI_interrupt_line, 1); - if (irq == 0 || irq == 0xff) - return -1; - - /* TODO: IRQ resources! */ - res->r_bustag = 0; - res->r_bushandle = irq; - - return 0; -} - - -static int -bus_alloc_mem_resource(device_t dev, struct resource *res, int regid) -{ - uint32 addr = pci_read_config(dev, regid, 4) & PCI_address_memory_32_mask; - uint32 size = 128 * 1024; /* XXX */ - void *virtualAddr; - - res->r_mapped_area = map_mem(&virtualAddr, addr, size, 0, - "bus_alloc_resource(MEMORY)"); - if (res->r_mapped_area < B_OK) - return -1; - - res->r_bustag = I386_BUS_SPACE_MEM; - res->r_bushandle = (bus_space_handle_t)virtualAddr; - return 0; -} - - -static int -bus_alloc_ioport_resource(device_t dev, struct resource *res, int regid) -{ - res->r_bustag = I386_BUS_SPACE_IO; - res->r_bushandle = pci_read_config(dev, regid, 4) & PCI_address_io_mask; - return 0; -} - - -struct resource * -bus_alloc_resource(device_t dev, int type, int *rid, unsigned long start, - unsigned long end, unsigned long count, uint32 flags) -{ - struct resource *res; - int result = -1; - - if (type != SYS_RES_IRQ && type != SYS_RES_MEMORY - && type != SYS_RES_IOPORT) - return NULL; - - device_printf(dev, "bus_alloc_resource(%i, [%i], 0x%lx, 0x%lx, 0x%lx," - "0x%" B_PRIx32 ")\n", type, *rid, start, end, count, flags); - - // maybe a local array of resources is enough - res = (struct resource *)malloc(sizeof(struct resource)); - if (res == NULL) - return NULL; - - if (type == SYS_RES_IRQ) { - if (*rid == 0) { - // pinned interrupt - result = bus_alloc_irq_resource(dev, res); - } else { - // msi or msi-x interrupt at index *rid - 1 - pci_info *info; - info = &((struct root_device_softc *)dev->root->softc)->pci_info; - res->r_bustag = 1; - res->r_bushandle = info->u.h0.interrupt_line + *rid - 1; - result = 0; - } - } else if (type == SYS_RES_MEMORY) - result = bus_alloc_mem_resource(dev, res, *rid); - else if (type == SYS_RES_IOPORT) - result = bus_alloc_ioport_resource(dev, res, *rid); - - if (result < 0) { - free(res); - return NULL; - } - - res->r_type = type; - return res; -} - - -int -bus_release_resource(device_t dev, int type, int rid, struct resource *res) -{ - if (res->r_type != type) - panic("bus_release_resource: mismatch"); - - if (type == SYS_RES_MEMORY) - delete_area(res->r_mapped_area); - - free(res); - return 0; -} - - -int -bus_alloc_resources(device_t dev, struct resource_spec *resourceSpec, - struct resource **resources) -{ - int i; - - for (i = 0; resourceSpec[i].type != -1; i++) { - resources[i] = bus_alloc_resource_any(dev, - resourceSpec[i].type, &resourceSpec[i].rid, resourceSpec[i].flags); - if (resources[i] == NULL - && (resourceSpec[i].flags & RF_OPTIONAL) == 0) { - for (++i; resourceSpec[i].type != -1; i++) { - resources[i] = NULL; - } - - bus_release_resources(dev, resourceSpec, resources); - return ENXIO; - } - } - return 0; -} - - -void -bus_release_resources(device_t dev, const struct resource_spec *resourceSpec, - struct resource **resources) -{ - int i; - - for (i = 0; resourceSpec[i].type != -1; i++) { - if (resources[i] == NULL) - continue; - - bus_release_resource(dev, resourceSpec[i].type, resourceSpec[i].rid, - resources[i]); - resources[i] = NULL; - } -} - - -bus_space_handle_t -rman_get_bushandle(struct resource *res) -{ - return res->r_bushandle; -} - - -bus_space_tag_t -rman_get_bustag(struct resource *res) -{ - return res->r_bustag; -} - - -int -rman_get_rid(struct resource *res) -{ - return 0; -} - - -// #pragma mark - Interrupt handling - - -static int32 -intr_wrapper(void *data) -{ - struct internal_intr *intr = (struct internal_intr *)data; - - //device_printf(intr->dev, "in interrupt handler.\n"); - - if (!HAIKU_CHECK_DISABLE_INTERRUPTS(intr->dev)) - return B_UNHANDLED_INTERRUPT; - - release_sem_etc(intr->sem, 1, B_DO_NOT_RESCHEDULE); - return intr->handling ? B_HANDLED_INTERRUPT : B_INVOKE_SCHEDULER; -} - - -static int32 -intr_fast_wrapper(void *data) -{ - struct internal_intr *intr = (struct internal_intr *)data; - - intr->handler(intr->arg); - - // We don't know if the interrupt has been handled. - return B_UNHANDLED_INTERRUPT; -} - - -static int32 -intr_handler(void *data) -{ - struct internal_intr *intr = (struct internal_intr *)data; - status_t status; - - while (1) { - status = acquire_sem(intr->sem); - if (status < B_OK) - break; - - //device_printf(intr->dev, "in soft interrupt handler.\n"); - - atomic_or(&intr->handling, 1); - intr->handler(intr->arg); - atomic_and(&intr->handling, 0); - HAIKU_REENABLE_INTERRUPTS(intr->dev); - } - - return 0; -} - - -static void -free_internal_intr(struct internal_intr *intr) -{ - if (intr->sem >= B_OK) { - status_t status; - delete_sem(intr->sem); - wait_for_thread(intr->thread, &status); - } - - free(intr); -} - - -int -bus_setup_intr(device_t dev, struct resource *res, int flags, - driver_filter_t filter, driver_intr_t handler, void *arg, void **_cookie) -{ - /* TODO check MPSAFE etc */ - - struct internal_intr *intr = (struct internal_intr *)malloc( - sizeof(struct internal_intr)); - char semName[64]; - status_t status; - - if (intr == NULL) - return B_NO_MEMORY; - - intr->dev = dev; - intr->filter = filter; - intr->handler = handler; - intr->arg = arg; - intr->irq = res->r_bushandle; - intr->flags = flags; - intr->sem = -1; - intr->thread = -1; - - if (filter != NULL) { - status = install_io_interrupt_handler(intr->irq, - (interrupt_handler)intr->filter, intr->arg, 0); - } else if ((flags & INTR_FAST) != 0) { - status = install_io_interrupt_handler(intr->irq, - intr_fast_wrapper, intr, B_NO_HANDLED_INFO); - } else { - snprintf(semName, sizeof(semName), "%s intr", dev->device_name); - - intr->sem = create_sem(0, semName); - if (intr->sem < B_OK) { - free(intr); - return B_NO_MEMORY; - } - - snprintf(semName, sizeof(semName), "%s intr handler", dev->device_name); - - intr->thread = spawn_kernel_thread(intr_handler, semName, - B_REAL_TIME_DISPLAY_PRIORITY, intr); - if (intr->thread < B_OK) { - delete_sem(intr->sem); - free(intr); - return B_NO_MEMORY; - } - - status = install_io_interrupt_handler(intr->irq, - intr_wrapper, intr, B_NO_HANDLED_INFO); - } - - if (status == B_OK && res->r_bustag == 1 && gPCIx86 != NULL) { - // this is an msi, enable it - pci_info *info - = &((struct root_device_softc *)dev->root->softc)->pci_info; - if (((struct root_device_softc *)dev->root->softc)->is_msi) { - if (gPCIx86->enable_msi(info->bus, info->device, - info->function) != B_OK) { - device_printf(dev, "enabling msi failed\n"); - bus_teardown_intr(dev, res, intr); - return ENODEV; - } - } else if (((struct root_device_softc *)dev->root->softc)->is_msix) { - if (gPCIx86->enable_msix(info->bus, info->device, - info->function) != B_OK) { - device_printf(dev, "enabling msix failed\n"); - bus_teardown_intr(dev, res, intr); - return ENODEV; - } - } - } - - if (status < B_OK) { - free_internal_intr(intr); - return status; - } - - resume_thread(intr->thread); - - *_cookie = intr; - return 0; -} - - -int -bus_teardown_intr(device_t dev, struct resource *res, void *arg) -{ - struct internal_intr *intr = (struct internal_intr *)arg; - struct root_device_softc *root = (struct root_device_softc *)dev->root->softc; - - if ((root->is_msi || root->is_msix) && gPCIx86 != NULL) { - // disable msi generation - pci_info *info = &root->pci_info; - gPCIx86->disable_msi(info->bus, info->device, info->function); - } - - if (intr->filter != NULL) { - remove_io_interrupt_handler(intr->irq, (interrupt_handler)intr->filter, - intr->arg); - } else if (intr->flags & INTR_FAST) { - remove_io_interrupt_handler(intr->irq, intr_fast_wrapper, intr); - } else { - remove_io_interrupt_handler(intr->irq, intr_wrapper, intr); - } - - free_internal_intr(intr); - return 0; -} - - -// #pragma mark - bus functions - - -bus_dma_tag_t -bus_get_dma_tag(device_t dev) -{ - return NULL; -} - - -int -bus_generic_suspend(device_t dev) -{ - UNIMPLEMENTED(); - return B_ERROR; -} - - -int -bus_generic_resume(device_t dev) -{ - UNIMPLEMENTED(); - return B_ERROR; -} - - -void -bus_generic_shutdown(device_t dev) -{ - UNIMPLEMENTED(); -} - - -int -bus_print_child_header(device_t dev, device_t child) -{ - UNIMPLEMENTED(); - return B_ERROR; -} - - -int -bus_print_child_footer(device_t dev, device_t child) -{ - UNIMPLEMENTED(); - return B_ERROR; -} - - -int -bus_generic_print_child(device_t dev, device_t child) -{ - UNIMPLEMENTED(); - return B_ERROR; -} - - -void -bus_generic_driver_added(device_t dev, driver_t *driver) -{ - UNIMPLEMENTED(); -} - - -int -bus_child_present(device_t child) -{ - device_t parent = device_get_parent(child); - if (parent == NULL) - return 0; - - return bus_child_present(parent); -} - - -// #pragma mark - PCI functions - - -uint32_t -pci_read_config(device_t dev, int offset, int size) -{ - pci_info *info = &((struct root_device_softc *)dev->root->softc)->pci_info; - - uint32_t value = gPci->read_pci_config(info->bus, info->device, - info->function, offset, size); - TRACE_PCI(dev, "pci_read_config(%i, %i) = 0x%x\n", offset, size, value); - return value; -} - - -void -pci_write_config(device_t dev, int offset, uint32_t value, int size) -{ - pci_info *info = &((struct root_device_softc *)dev->root->softc)->pci_info; - - TRACE_PCI(dev, "pci_write_config(%i, 0x%x, %i)\n", offset, value, size); - - gPci->write_pci_config(info->bus, info->device, info->function, offset, - size, value); -} - - -uint16_t -pci_get_vendor(device_t dev) -{ - return pci_read_config(dev, PCI_vendor_id, 2); -} - - -uint16_t -pci_get_device(device_t dev) -{ - return pci_read_config(dev, PCI_device_id, 2); -} - - -uint16_t -pci_get_subvendor(device_t dev) -{ - return pci_read_config(dev, PCI_subsystem_vendor_id, 2); -} - - -uint16_t -pci_get_subdevice(device_t dev) -{ - return pci_read_config(dev, PCI_subsystem_id, 2); -} - - -uint8_t -pci_get_revid(device_t dev) -{ - return pci_read_config(dev, PCI_revision, 1); -} - - -uint32_t -pci_get_domain(device_t dev) -{ - return 0; -} - -uint32_t -pci_get_devid(device_t dev) -{ - return pci_read_config(dev, PCI_device_id, 2) << 16 | - pci_read_config(dev, PCI_vendor_id, 2); -} - -uint8_t -pci_get_cachelnsz(device_t dev) -{ - return pci_read_config(dev, PCI_line_size, 1); -} - -uint8_t * -pci_get_ether(device_t dev) -{ - /* used in if_dc to get the MAC from CardBus CIS for Xircom card */ - return NULL; /* NULL is handled in the caller correctly */ -} - -uint8_t -pci_get_bus(device_t dev) -{ - pci_info *info - = &((struct root_device_softc *)dev->root->softc)->pci_info; - return info->bus; -} - - -uint8_t -pci_get_slot(device_t dev) -{ - pci_info *info - = &((struct root_device_softc *)dev->root->softc)->pci_info; - return info->device; -} - - -uint8_t -pci_get_function(device_t dev) -{ - pci_info *info - = &((struct root_device_softc *)dev->root->softc)->pci_info; - return info->function; -} - - -device_t -pci_find_dbsf(uint32_t domain, uint8_t bus, uint8_t slot, uint8_t func) -{ - // We don't support that yet - if we want to support the multi port - // feature of the Broadcom BCM 570x driver, we would have to change - // that. - return NULL; -} - - -static void -pci_set_command_bit(device_t dev, uint16_t bit) -{ - uint16_t command = pci_read_config(dev, PCI_command, 2); - pci_write_config(dev, PCI_command, command | bit, 2); -} - - -int -pci_enable_busmaster(device_t dev) -{ - pci_set_command_bit(dev, PCI_command_master); - return 0; -} - - -int -pci_enable_io(device_t dev, int space) -{ - /* adapted from FreeBSD's pci_enable_io_method */ - int bit = 0; - - switch (space) { - case SYS_RES_IOPORT: - bit = PCI_command_io; - break; - case SYS_RES_MEMORY: - bit = PCI_command_memory; - break; - default: - return EINVAL; - } - - pci_set_command_bit(dev, bit); - if (pci_read_config(dev, PCI_command, 2) & bit) - return 0; - - device_printf(dev, "pci_enable_io(%d) failed.\n", space); - - return ENXIO; -} - - -int -pci_find_cap(device_t dev, int capability, int *capreg) -{ - return pci_find_extcap(dev, capability, capreg); -} - - -int -pci_find_extcap(device_t child, int capability, int *_capabilityRegister) -{ - uint8 capabilityPointer; - uint8 headerType; - uint16 status; - - status = pci_read_config(child, PCIR_STATUS, 2); - if ((status & PCIM_STATUS_CAPPRESENT) == 0) - return ENXIO; - - headerType = pci_read_config(child, PCI_header_type, 1); - switch (headerType & PCIM_HDRTYPE) { - case 0: - case 1: - capabilityPointer = PCIR_CAP_PTR; - break; - case 2: - capabilityPointer = PCIR_CAP_PTR_2; - break; - default: - return ENXIO; - } - capabilityPointer = pci_read_config(child, capabilityPointer, 1); - - while (capabilityPointer != 0) { - if (pci_read_config(child, capabilityPointer + PCICAP_ID, 1) - == capability) { - if (_capabilityRegister != NULL) - *_capabilityRegister = capabilityPointer; - return 0; - } - capabilityPointer = pci_read_config(child, - capabilityPointer + PCICAP_NEXTPTR, 1); - } - - return ENOENT; -} - - -int -pci_msi_count(device_t dev) -{ - pci_info *info; - if (gPCIx86 == NULL) - return 0; - - info = &((struct root_device_softc *)dev->root->softc)->pci_info; - return gPCIx86->get_msi_count(info->bus, info->device, info->function); -} - - -int -pci_alloc_msi(device_t dev, int *count) -{ - pci_info *info; - uint8 startVector = 0; - if (gPCIx86 == NULL) - return ENODEV; - - info = &((struct root_device_softc *)dev->root->softc)->pci_info; - - if (gPCIx86->configure_msi(info->bus, info->device, info->function, *count, - &startVector) != B_OK) { - return ENODEV; - } - - ((struct root_device_softc *)dev->root->softc)->is_msi = true; - info->u.h0.interrupt_line = startVector; - return EOK; -} - - -int -pci_release_msi(device_t dev) -{ - pci_info *info; - if (gPCIx86 == NULL) - return ENODEV; - - info = &((struct root_device_softc *)dev->root->softc)->pci_info; - gPCIx86->unconfigure_msi(info->bus, info->device, info->function); - ((struct root_device_softc *)dev->root->softc)->is_msi = false; - ((struct root_device_softc *)dev->root->softc)->is_msix = false; - return EOK; -} - - -int -pci_msix_count(device_t dev) -{ - pci_info *info; - if (gPCIx86 == NULL) - return 0; - - info = &((struct root_device_softc *)dev->root->softc)->pci_info; - return gPCIx86->get_msix_count(info->bus, info->device, info->function); -} - - -int -pci_alloc_msix(device_t dev, int *count) -{ - pci_info *info; - uint8 startVector = 0; - if (gPCIx86 == NULL) - return ENODEV; - - info = &((struct root_device_softc *)dev->root->softc)->pci_info; - - if (gPCIx86->configure_msix(info->bus, info->device, info->function, *count, - &startVector) != B_OK) { - return ENODEV; - } - - ((struct root_device_softc *)dev->root->softc)->is_msix = true; - info->u.h0.interrupt_line = startVector; - return EOK; -} - - -int -pci_get_max_read_req(device_t dev) -{ - int cap; - uint16_t val; - - if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) != 0) - return (0); - val = pci_read_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, 2); - val &= PCIM_EXP_CTL_MAX_READ_REQUEST; - val >>= 12; - return (1 << (val + 7)); -} - - -int -pci_set_max_read_req(device_t dev, int size) -{ - int cap; - uint16_t val; - - if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) != 0) - return (0); - if (size < 128) - size = 128; - if (size > 4096) - size = 4096; - size = (1 << (fls(size) - 1)); - val = pci_read_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, 2); - val &= ~PCIM_EXP_CTL_MAX_READ_REQUEST; - val |= (fls(size) - 8) << 12; - pci_write_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, val, 2); - return (size); -} - - -int -pci_get_powerstate(device_t dev) -{ - int capabilityRegister; - uint16 status; - int powerState = PCI_POWERSTATE_D0; - - if (pci_find_extcap(dev, PCIY_PMG, &capabilityRegister) != EOK) - return powerState; - - status = pci_read_config(dev, capabilityRegister + PCIR_POWER_STATUS, 2); - switch (status & PCI_pm_mask) { - case PCI_pm_state_d0: - break; - case PCI_pm_state_d1: - powerState = PCI_POWERSTATE_D1; - break; - case PCI_pm_state_d2: - powerState = PCI_POWERSTATE_D2; - break; - case PCI_pm_state_d3: - powerState = PCI_POWERSTATE_D3; - break; - default: - powerState = PCI_POWERSTATE_UNKNOWN; - break; - } - - TRACE_PCI(dev, "%s: D%i\n", __func__, powerState); - return powerState; -} - - -int -pci_set_powerstate(device_t dev, int newPowerState) -{ - int capabilityRegister; - int oldPowerState; - uint8 currentPowerManagementStatus; - uint8 newPowerManagementStatus; - uint16 powerManagementCapabilities; - bigtime_t stateTransitionDelayInUs = 0; - - if (pci_find_extcap(dev, PCIY_PMG, &capabilityRegister) != EOK) - return EOPNOTSUPP; - - oldPowerState = pci_get_powerstate(dev); - if (oldPowerState == newPowerState) - return EOK; - - switch (std::max(oldPowerState, newPowerState)) { - case PCI_POWERSTATE_D2: - stateTransitionDelayInUs = 200; - break; - case PCI_POWERSTATE_D3: - stateTransitionDelayInUs = 10000; - break; - } - - currentPowerManagementStatus = pci_read_config(dev, capabilityRegister - + PCIR_POWER_STATUS, 2); - newPowerManagementStatus = currentPowerManagementStatus & ~PCI_pm_mask; - powerManagementCapabilities = pci_read_config(dev, capabilityRegister - + PCIR_POWER_CAP, 2); - - switch (newPowerState) { - case PCI_POWERSTATE_D0: - newPowerManagementStatus |= PCIM_PSTAT_D0; - break; - case PCI_POWERSTATE_D1: - if ((powerManagementCapabilities & PCI_pm_d1supp) == 0) - return EOPNOTSUPP; - newPowerManagementStatus |= PCIM_PSTAT_D1; - break; - case PCI_POWERSTATE_D2: - if ((powerManagementCapabilities & PCI_pm_d2supp) == 0) - return EOPNOTSUPP; - newPowerManagementStatus |= PCIM_PSTAT_D2; - break; - case PCI_POWERSTATE_D3: - newPowerManagementStatus |= PCIM_PSTAT_D3; - break; - default: - return EINVAL; - } - - TRACE_PCI(dev, "%s: D%i -> D%i\n", __func__, oldPowerState, newPowerState); - pci_write_config(dev, capabilityRegister + PCIR_POWER_STATUS, newPowerState, - 2); - if (stateTransitionDelayInUs != 0) - snooze(stateTransitionDelayInUs); - - return EOK; -} diff --git a/src/libs/compat/freebsd_network/callout.cpp b/src/libs/compat/freebsd_network/callout.cpp deleted file mode 100644 index c80938b63e..0000000000 --- a/src/libs/compat/freebsd_network/callout.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2010, Axel Dörfler, axeld@pinc-software.de. - * Distributed under the terms of the MIT License. - */ - - -#include "device.h" - -#include -#include - -extern "C" { -# include -# include -} - -#include - - -//#define TRACE_CALLOUT -#ifdef TRACE_CALLOUT -# define TRACE(x...) dprintf(x) -#else -# define TRACE(x...) ; -#endif - - -static struct list sTimers; -static mutex sLock; -static sem_id sWaitSem; -static callout* sCurrentCallout; -static thread_id sThread; -static bigtime_t sTimeout; - - -static status_t -callout_thread(void* /*data*/) -{ - status_t status = B_OK; - - do { - bigtime_t timeout = B_INFINITE_TIMEOUT; - - if (status == B_TIMED_OUT || status == B_OK) { - // scan timers for new timeout and/or execute a timer - mutex_lock(&sLock); - - struct callout* c = NULL; - while (true) { - c = (callout*)list_get_next_item(&sTimers, c); - if (c == NULL) - break; - - if (c->due < system_time()) { - struct mtx *mutex = c->c_mtx; - - // execute timer - list_remove_item(&sTimers, c); - c->due = -1; - sCurrentCallout = c; - - mutex_unlock(&sLock); - - if (mutex != NULL) - mtx_lock(mutex); - - c->c_func(c->c_arg); - - if (mutex != NULL) - mtx_unlock(mutex); - - mutex_lock(&sLock); - - sCurrentCallout = NULL; - c = NULL; - // restart scanning as we unlocked the list - } else { - // calculate new timeout - if (c->due < timeout) - timeout = c->due; - } - } - - sTimeout = timeout; - mutex_unlock(&sLock); - } - - status = acquire_sem_etc(sWaitSem, 1, B_ABSOLUTE_TIMEOUT, timeout); - // the wait sem normally can't be acquired, so we - // have to look at the status value the call returns: - // - // B_OK - a new timer has been added or canceled - // B_TIMED_OUT - look for timers to be executed - // B_BAD_SEM_ID - we are asked to quit - } while (status != B_BAD_SEM_ID); - - return B_OK; -} - - -// #pragma mark - private API - - -status_t -init_callout(void) -{ - list_init(&sTimers); - sTimeout = B_INFINITE_TIMEOUT; - - status_t status = B_OK; - mutex_init(&sLock, "fbsd callout"); - - sWaitSem = create_sem(0, "fbsd callout wait"); - if (sWaitSem < 0) { - status = sWaitSem; - goto err1; - } - - sThread = spawn_kernel_thread(callout_thread, "fbsd callout", - B_DISPLAY_PRIORITY, NULL); - if (sThread < 0) { - status = sThread; - goto err2; - } - - return resume_thread(sThread); - -err1: - mutex_destroy(&sLock); -err2: - delete_sem(sWaitSem); - return status; -} - - -void -uninit_callout(void) -{ - delete_sem(sWaitSem); - mutex_lock(&sLock); - - mutex_destroy(&sLock); - - status_t status; - wait_for_thread(sThread, &status); -} - - -// #pragma mark - public API - - -void -callout_init(struct callout *callout, int mpsafe) -{ - if (mpsafe) - callout_init_mtx(callout, NULL, 0); - else - callout_init_mtx(callout, &Giant, 0); -} - - -void -callout_init_mtx(struct callout *c, struct mtx *mtx, int flags) -{ - c->due = 0; - c->flags = 0; - - c->c_arg = NULL; - c->c_func = NULL; - c->c_mtx = mtx; - c->c_flags = flags; -} - - -int -callout_reset(struct callout *c, int ticks, void (*func)(void *), void *arg) -{ - int canceled = callout_stop(c); - - MutexLocker locker(sLock); - - c->c_func = func; - c->c_arg = arg; - - TRACE("callout_reset %p, func %p, arg %p\n", c, c->c_func, c->c_arg); - - if (ticks >= 0) { - // reschedule or add this timer - if (c->due <= 0) - list_add_item(&sTimers, c); - - c->due = system_time() + ticks_to_usecs(ticks); - - // notify timer about the change if necessary - if (sTimeout > c->due) - release_sem(sWaitSem); - } - - return canceled; -} - - -int -callout_schedule(struct callout *callout, int ticks) -{ - return callout_reset(callout, ticks, callout->c_func, callout->c_arg); -} - - -int -_callout_stop_safe(struct callout *c, int safe) -{ - MutexLocker locker(sLock); - - TRACE("_callout_stop_safe %p, func %p, arg %p\n", c, c->c_func, c->c_arg); - - if (c->due <= 0) - return 0; - - // this timer is scheduled, cancel it - list_remove_item(&sTimers, c); - c->due = 0; - return 1; -} - - -int -callout_pending(struct callout *c) -{ - return c->due > 0; -} - - -int -callout_active(struct callout *c) -{ - return c == sCurrentCallout; -} diff --git a/src/libs/compat/freebsd_network/clock.c b/src/libs/compat/freebsd_network/clock.c deleted file mode 100644 index 3ce5fbbe83..0000000000 --- a/src/libs/compat/freebsd_network/clock.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de - * All rights reserved. Distributed under the terms of the MIT License. - */ - - -#include "device.h" - -#include - - -int ticks; -static timer sHardClockTimer; - - -/*! - * Implementation of FreeBSD's hardclock timer. - */ -static int32 -hardClock(timer* hardClockTimer) -{ - atomic_add((vint32*)&ticks, 1); - return B_HANDLED_INTERRUPT; -} - - -/*! - * Initialization of the hardclock timer which ticks according to hz defined in - * compat/sys/kernel.h. - */ -status_t -init_hard_clock() -{ - ticks = 0; - return add_timer(&sHardClockTimer, hardClock, ticks_to_usecs(1), - B_PERIODIC_TIMER); -} - - -void -uninit_hard_clock() -{ - cancel_timer(&sHardClockTimer); -} diff --git a/src/libs/compat/freebsd_network/compat.c b/src/libs/compat/freebsd_network/compat.c deleted file mode 100644 index 3b40c9f2da..0000000000 --- a/src/libs/compat/freebsd_network/compat.c +++ /dev/null @@ -1,659 +0,0 @@ -/* - * Copyright 2007, Hugo Santos, hugosantos@gmail.com. All Rights Reserved. - * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved. - * Copyright 2004, Marcus Overhagen. All Rights Reserved. - * - * Distributed under the terms of the MIT License. - */ - - -#include "device.h" - -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include - -#include "compat_cpp.h" - - -spinlock __haiku_intr_spinlock; - -struct net_stack_module_info *gStack; -pci_module_info *gPci; -struct pci_x86_module_info *gPCIx86; - -static struct list sRootDevices; -static int sNextUnit; - -// #pragma mark - private functions - - -static device_t -init_device(device_t device, driver_t *driver) -{ - list_init_etc(&device->children, offsetof(struct device, link)); - device->unit = sNextUnit++; - - if (driver != NULL && device_set_driver(device, driver) < 0) - return NULL; - - return device; -} - - -static device_t -new_device(driver_t *driver) -{ - device_t dev = malloc(sizeof(struct device)); - if (dev == NULL) - return NULL; - - memset(dev, 0, sizeof(struct device)); - - if (init_device(dev, driver) == NULL) { - free(dev); - return NULL; - } - - return dev; -} - - -static image_id -find_own_image() -{ - int32 cookie = 0; - image_info info; - while (get_next_image_info(B_SYSTEM_TEAM, &cookie, &info) == B_OK) { - if (((addr_t)info.text <= (addr_t)find_own_image - && (addr_t)info.text + (addr_t)info.text_size - > (addr_t)find_own_image)) { - // found our own image - return info.id; - } - } - - return B_ENTRY_NOT_FOUND; -} - - -static device_method_signature_t -resolve_method(driver_t *driver, const char *name) -{ - device_method_signature_t method = NULL; - int i; - - for (i = 0; method == NULL && driver->methods[i].name != NULL; i++) { - if (strcmp(driver->methods[i].name, name) == 0) - method = driver->methods[i].method; - } - - return method; -} - - -// #pragma mark - Device - - -void -driver_printf(const char *format, ...) -{ - va_list vl; - va_start(vl, format); - driver_vprintf(format, vl); - va_end(vl); -} - - -static void -driver_vprintf_etc(const char *extra, const char *format, va_list vl) -{ - char buf[256]; - vsnprintf(buf, sizeof(buf), format, vl); - - if (extra) - dprintf("[%s] (%s) %s", gDriverName, extra, buf); - else - dprintf("[%s] %s", gDriverName, buf); -} - - -void -driver_vprintf(const char *format, va_list vl) -{ - driver_vprintf_etc(NULL, format, vl); -} - - -int -device_printf(device_t dev, const char *format, ...) -{ - va_list vl; - - va_start(vl, format); - driver_vprintf_etc(dev->device_name, format, vl); - va_end(vl); - return 0; -} - - -void -device_set_desc(device_t dev, const char *desc) -{ - dev->description = desc; -} - - -void -device_set_desc_copy(device_t dev, const char *desc) -{ - dev->description = strdup(desc); - dev->flags |= DEVICE_DESC_ALLOCED; -} - - -const char * -device_get_desc(device_t dev) -{ - return dev->description; -} - - -device_t -device_get_parent(device_t dev) -{ - return dev->parent; -} - - -devclass_t -device_get_devclass(device_t dev) -{ - // TODO find out what to do - return 0; -} - - -int -device_get_children(device_t dev, device_t **devlistp, int *devcountp) -{ - int count; - device_t child = NULL; - device_t *list; - - count = 0; - while ((child = list_get_next_item(&dev->children, child)) != NULL) { - count++; - } - - list = malloc(count * sizeof(device_t)); - if (!list) - return (ENOMEM); - - count = 0; - while ((child = list_get_next_item(&dev->children, child)) != NULL) { - list[count] = child; - count++; - } - - *devlistp = list; - *devcountp = count; - - return (0); -} - - -void -device_set_ivars(device_t dev, void *ivars) -{ - dev->ivars = ivars; -} - - -void * -device_get_ivars(device_t dev) -{ - return dev->ivars; -} - - -const char * -device_get_name(device_t dev) -{ - if (dev == NULL) - return NULL; - - return dev->device_name; -} - - -int -device_get_unit(device_t dev) -{ - return dev->unit; -} - - -const char * -device_get_nameunit(device_t dev) -{ - return dev->nameunit; -} - - -void * -device_get_softc(device_t dev) -{ - return dev->softc; -} - - -u_int32_t -device_get_flags(device_t dev) -{ - return dev->flags; -} - - -int -device_set_driver(device_t dev, driver_t *driver) -{ - device_method_signature_t method = NULL; - int i; - - dev->softc = malloc(driver->softc_size); - if (dev->softc == NULL) - return -1; - - memset(dev->softc, 0, driver->softc_size); - dev->driver = driver; - - for (i = 0; method == NULL && driver->methods[i].name != NULL; i++) { - device_method_t *mth = &driver->methods[i]; - - if (strcmp(mth->name, "device_probe") == 0) - dev->methods.probe = (void *)mth->method; - else if (strcmp(mth->name, "device_attach") == 0) - dev->methods.attach = (void *)mth->method; - else if (strcmp(mth->name, "device_detach") == 0) - dev->methods.detach = (void *)mth->method; - else if (strcmp(mth->name, "device_suspend") == 0) - dev->methods.suspend = (void *)mth->method; - else if (strcmp(mth->name, "device_resume") == 0) - dev->methods.resume = (void *)mth->method; - else if (strcmp(mth->name, "device_shutdown") == 0) - dev->methods.shutdown = (void *)mth->method; - else if (strcmp(mth->name, "miibus_readreg") == 0) - dev->methods.miibus_readreg = (void *)mth->method; - else if (strcmp(mth->name, "miibus_writereg") == 0) - dev->methods.miibus_writereg = (void *)mth->method; - else if (strcmp(mth->name, "miibus_statchg") == 0) - dev->methods.miibus_statchg = (void *)mth->method; - else if (!strcmp(mth->name, "miibus_linkchg")) - dev->methods.miibus_linkchg = (void *)mth->method; - else if (!strcmp(mth->name, "miibus_mediainit")) - dev->methods.miibus_mediainit = (void *)mth->method; - } - - return 0; -} - - -int -device_is_alive(device_t device) -{ - return (device->flags & DEVICE_ATTACHED) != 0; -} - - -device_t -device_add_child(device_t parent, const char *name, int unit) -{ - device_t child = NULL; - - if (name != NULL) { - if (strcmp(name, "miibus") == 0) - child = new_device(&miibus_driver); - else { - // find matching driver structure - driver_t **driver; - char symbol[128]; - - snprintf(symbol, sizeof(symbol), "__fbsd_%s_%s", name, - parent->driver->name); - if (get_image_symbol(find_own_image(), symbol, B_SYMBOL_TYPE_DATA, - (void **)&driver) == B_OK) { - child = new_device(*driver); - } else - device_printf(parent, "couldn't find symbol %s\n", symbol); - } - } else - child = new_device(NULL); - - if (child == NULL) - return NULL; - - if (name != NULL) - strlcpy(child->device_name, name, sizeof(child->device_name)); - - child->parent = parent; - - if (parent != NULL) { - list_add_item(&parent->children, child); - child->root = parent->root; - } else { - if (sRootDevices.link.next == NULL) - list_init_etc(&sRootDevices, offsetof(struct device, link)); - list_add_item(&sRootDevices, child); - } - - return child; -} - - -/*! Delete the child and all of its children. Detach as necessary. -*/ -int -device_delete_child(device_t parent, device_t child) -{ - int status; - - if (child == NULL) - return 0; - - if (parent != NULL) - list_remove_item(&parent->children, child); - else - list_remove_item(&sRootDevices, child); - - // We differentiate from the FreeBSD logic here - it will first delete - // the children, and will then detach the device. - // This has the problem that you cannot safely call device_delete_child() - // as you don't know if one of the children deletes its own children this - // way when it is detached. - // Therefore, we'll detach first, and then delete whatever is left. - - parent = child; - child = NULL; - - // detach children - while ((child = list_get_next_item(&parent->children, child)) != NULL) { - device_detach(child); - } - - // detach device - status = device_detach(parent); - if (status != 0) - return status; - - // delete children - while ((child = list_get_first_item(&parent->children)) != NULL) { - device_delete_child(parent, child); - } - - // delete device - if (parent->flags & DEVICE_DESC_ALLOCED) - free((char *)parent->description); - - free(parent->softc); - free(parent); - return 0; -} - - -int -device_is_attached(device_t device) -{ - return (device->flags & DEVICE_ATTACHED) != 0; -} - - -int -device_attach(device_t device) -{ - int result; - - if (device->driver == NULL - || device->methods.attach == NULL) - return B_ERROR; - - result = device->methods.attach(device); - - if (result == 0) - atomic_or(&device->flags, DEVICE_ATTACHED); - - if (result == 0) - result = start_wlan(device); - - return result; -} - - -int -device_detach(device_t device) -{ - if (device->driver == NULL) - return B_ERROR; - - if ((atomic_and(&device->flags, ~DEVICE_ATTACHED) & DEVICE_ATTACHED) != 0 - && device->methods.detach != NULL) { - int result = B_OK; - - result = stop_wlan(device); - if (result != 0) { - atomic_or(&device->flags, DEVICE_ATTACHED); - return result; - } - - result = device->methods.detach(device); - if (result != 0) { - atomic_or(&device->flags, DEVICE_ATTACHED); - return result; - } - } - - return 0; -} - - -int -bus_generic_attach(device_t dev) -{ - device_t child = NULL; - - while ((child = list_get_next_item(&dev->children, child)) != NULL) { - if (child->driver == NULL) { - driver_t *driver = __haiku_select_miibus_driver(child); - if (driver == NULL) { - struct mii_attach_args *ma = device_get_ivars(child); - - device_printf(dev, "No PHY module found (%x/%x)!\n", - MII_OUI(ma->mii_id1, ma->mii_id2), MII_MODEL(ma->mii_id2)); - } else - device_set_driver(child, driver); - } else - child->methods.probe(child); - - if (child->driver != NULL) { - int result = device_attach(child); - if (result != 0) - return result; - } - } - - return 0; -} - - -int -bus_generic_detach(device_t device) -{ - device_t child = NULL; - - if ((device->flags & DEVICE_ATTACHED) == 0) - return B_ERROR; - - while (true) { - child = list_get_next_item(&device->children, child); - if (child == NULL) - break; - - device_detach(child); - } - - return 0; -} - - -// #pragma mark - Misc, Malloc - - -device_t -find_root_device(int unit) -{ - device_t device = NULL; - - while ((device = list_get_next_item(&sRootDevices, device)) != NULL) { - if (device->unit <= unit) - return device; - } - - return NULL; -} - - -driver_t * -__haiku_probe_miibus(device_t dev, driver_t *drivers[]) -{ - driver_t *selected = NULL; - int i, selectedResult = 0; - - if (drivers == NULL) - return NULL; - - for (i = 0; drivers[i]; i++) { - device_probe_t *probe = (device_probe_t *) - resolve_method(drivers[i], "device_probe"); - if (probe) { - int result = probe(dev); - if (result >= 0) { - if (selected == NULL || result < selectedResult) { - selected = drivers[i]; - selectedResult = result; - device_printf(dev, "Found MII: %s\n", selected->name); - } - } - } - } - - return selected; -} - - -int -printf(const char *format, ...) -{ - char buf[256]; - va_list vl; - va_start(vl, format); - vsnprintf(buf, sizeof(buf), format, vl); - va_end(vl); - dprintf(buf); - - return 0; -} - - -int -ffs(int value) -{ - int i = 1; - - if (value == 0) - return 0; - - for (; !(value & 1); i++) - value >>= 1; - - return i; -} - - -int -resource_int_value(const char *name, int unit, const char *resname, - int *result) -{ - /* no support for hints */ - return -1; -} - - -void * -_kernel_malloc(size_t size, int flags) -{ - // our kernel malloc() is insufficient, must handle M_WAIT - - // According to the FreeBSD kernel malloc man page the allocator is expected - // to return power of two aligned addresses for allocations up to one page - // size. While it also states that this shouldn't be relied upon, at least - // bus_dmamem_alloc expects it and drivers may depend on it as well. - void *ptr - = memalign(size >= PAGESIZE ? PAGESIZE : next_power_of_2(size), size); - if (ptr == NULL) - return NULL; - - if (flags & M_ZERO) - memset(ptr, 0, size); - - return ptr; -} - - -void -_kernel_free(void *ptr) -{ - free(ptr); -} - - -void * -_kernel_contigmalloc(const char *file, int line, size_t size, int flags, - vm_paddr_t low, vm_paddr_t high, unsigned long alignment, - unsigned long boundary) -{ - return _kernel_contigmalloc_cpp(file, line, size, low, high, - alignment, boundary, (flags & M_ZERO) != 0, (flags & M_NOWAIT) != 0); -} - - -void -_kernel_contigfree(void *addr, size_t size) -{ - delete_area(area_for(addr)); -} - - -vm_paddr_t -pmap_kextract(vm_offset_t virtualAddress) -{ - physical_entry entry; - status_t status = get_memory_map((void *)virtualAddress, 1, &entry, 1); - if (status < B_OK) { - panic("fbsd compat: get_memory_map failed for %p, error %08" B_PRIx32 - "\n", (void *)virtualAddress, status); - } - - return (vm_paddr_t)entry.address; -} - diff --git a/src/libs/compat/freebsd_network/compat/altq/if_altq.h b/src/libs/compat/freebsd_network/compat/altq/if_altq.h deleted file mode 100644 index 5b0a815011..0000000000 --- a/src/libs/compat/freebsd_network/compat/altq/if_altq.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2007 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_ALTQ_IF_ALTQ_H_ -#define _FBSD_COMPAT_ALTQ_IF_ALTQ_H_ - - -#include -#include - - -struct ifaltq { - struct mbuf* ifq_head; - struct mbuf* ifq_tail; - - int ifq_len; - int ifq_maxlen; - int ifq_drops; - struct mtx ifq_mtx; - - struct mbuf* ifq_drv_head; - struct mbuf* ifq_drv_tail; - int ifq_drv_len; - int ifq_drv_maxlen; - - int altq_flags; -}; - - -#define ALTQF_READY 0x1 - -#define ALTDQ_REMOVE 1 - -#define ALTQ_IS_ENABLED(ifq) 0 -#define ALTQ_ENQUEUE(ifr, m, foo, error) \ - do { m_freem(m); error = -1; } while (0) -#define ALTQ_DEQUEUE(ifr, m) (m) = NULL - -#define TBR_IS_ENABLED(ifq) 0 -#define tbr_dequeue_ptr(ifq, v) NULL - -#endif diff --git a/src/libs/compat/freebsd_network/compat/dev/mii/mii.h b/src/libs/compat/freebsd_network/compat/dev/mii/mii.h deleted file mode 100644 index 668fb8fb87..0000000000 --- a/src/libs/compat/freebsd_network/compat/dev/mii/mii.h +++ /dev/null @@ -1,202 +0,0 @@ -/* $NetBSD: mii.h,v 1.9 2001/05/31 03:07:14 thorpej Exp $ */ - -/*- - * Copyright (c) 1997 Manuel Bouyer. All rights reserved. - * - * Modification to match BSD/OS 3.0 MII interface by Jason R. Thorpe, - * Numerical Aerospace Simulation Facility, NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _DEV_MII_MII_H_ -#define _DEV_MII_MII_H_ - -/* - * Registers common to all PHYs. - */ - -#define MII_NPHY 32 /* max # of PHYs per MII */ - -/* - * MII commands, used if a device must drive the MII lines - * manually. - */ -#define MII_COMMAND_START 0x01 -#define MII_COMMAND_READ 0x02 -#define MII_COMMAND_WRITE 0x01 -#define MII_COMMAND_ACK 0x02 - -#define MII_BMCR 0x00 /* Basic mode control register (rw) */ -#define BMCR_RESET 0x8000 /* reset */ -#define BMCR_LOOP 0x4000 /* loopback */ -#define BMCR_SPEED0 0x2000 /* speed selection (LSB) */ -#define BMCR_AUTOEN 0x1000 /* autonegotiation enable */ -#define BMCR_PDOWN 0x0800 /* power down */ -#define BMCR_ISO 0x0400 /* isolate */ -#define BMCR_STARTNEG 0x0200 /* restart autonegotiation */ -#define BMCR_FDX 0x0100 /* Set duplex mode */ -#define BMCR_CTEST 0x0080 /* collision test */ -#define BMCR_SPEED1 0x0040 /* speed selection (MSB) */ - -#define BMCR_S10 0x0000 /* 10 Mb/s */ -#define BMCR_S100 BMCR_SPEED0 /* 100 Mb/s */ -#define BMCR_S1000 BMCR_SPEED1 /* 1000 Mb/s */ - -#define BMCR_SPEED(x) ((x) & (BMCR_SPEED0|BMCR_SPEED1)) - -#define MII_BMSR 0x01 /* Basic mode status register (ro) */ -#define BMSR_100T4 0x8000 /* 100 base T4 capable */ -#define BMSR_100TXFDX 0x4000 /* 100 base Tx full duplex capable */ -#define BMSR_100TXHDX 0x2000 /* 100 base Tx half duplex capable */ -#define BMSR_10TFDX 0x1000 /* 10 base T full duplex capable */ -#define BMSR_10THDX 0x0800 /* 10 base T half duplex capable */ -#define BMSR_100T2FDX 0x0400 /* 100 base T2 full duplex capable */ -#define BMSR_100T2HDX 0x0200 /* 100 base T2 half duplex capable */ -#define BMSR_EXTSTAT 0x0100 /* Extended status in register 15 */ -#define BMSR_MFPS 0x0040 /* MII Frame Preamble Suppression */ -#define BMSR_ACOMP 0x0020 /* Autonegotiation complete */ -#define BMSR_RFAULT 0x0010 /* Link partner fault */ -#define BMSR_ANEG 0x0008 /* Autonegotiation capable */ -#define BMSR_LINK 0x0004 /* Link status */ -#define BMSR_JABBER 0x0002 /* Jabber detected */ -#define BMSR_EXTCAP 0x0001 /* Extended capability */ - -#define BMSR_DEFCAPMASK 0xffffffff - -/* - * Note that the EXTSTAT bit indicates that there is extended status - * info available in register 15, but 802.3 section 22.2.4.3 also - * states that that all 1000 Mb/s capable PHYs will set this bit to 1. - */ - -#define BMSR_MEDIAMASK (BMSR_100T4|BMSR_100TXFDX|BMSR_100TXHDX| \ - BMSR_10TFDX|BMSR_10THDX|BMSR_100T2FDX|BMSR_100T2HDX) - -/* - * Convert BMSR media capabilities to ANAR bits for autonegotiation. - * Note the shift chopps off the BMSR_ANEG bit. - */ -#define BMSR_MEDIA_TO_ANAR(x) (((x) & BMSR_MEDIAMASK) >> 6) - -#define MII_PHYIDR1 0x02 /* ID register 1 (ro) */ - -#define MII_PHYIDR2 0x03 /* ID register 2 (ro) */ -#define IDR2_OUILSB 0xfc00 /* OUI LSB */ -#define IDR2_MODEL 0x03f0 /* vendor model */ -#define IDR2_REV 0x000f /* vendor revision */ - -#define MII_ANAR 0x04 /* Autonegotiation advertisement (rw) */ - /* section 28.2.4.1 and 37.2.6.1 */ -#define ANAR_NP 0x8000 /* Next page (ro) */ -#define ANAR_ACK 0x4000 /* link partner abilities acknowledged (ro) */ -#define ANAR_RF 0x2000 /* remote fault (ro) */ -#define ANAR_FC 0x0400 /* local device supports PAUSE */ -#define ANAR_T4 0x0200 /* local device supports 100bT4 */ -#define ANAR_TX_FD 0x0100 /* local device supports 100bTx FD */ -#define ANAR_TX 0x0080 /* local device supports 100bTx */ -#define ANAR_10_FD 0x0040 /* local device supports 10bT FD */ -#define ANAR_10 0x0020 /* local device supports 10bT */ -#define ANAR_CSMA 0x0001 /* protocol selector CSMA/CD */ -#define ANAR_PAUSE_NONE (0 << 10) -#define ANAR_PAUSE_SYM (1 << 10) -#define ANAR_PAUSE_ASYM (2 << 10) -#define ANAR_PAUSE_TOWARDS (3 << 10) - -#define ANAR_X_FD 0x0020 /* local device supports 1000BASE-X FD */ -#define ANAR_X_HD 0x0040 /* local device supports 1000BASE-X HD */ -#define ANAR_X_PAUSE_NONE (0 << 7) -#define ANAR_X_PAUSE_SYM (1 << 7) -#define ANAR_X_PAUSE_ASYM (2 << 7) -#define ANAR_X_PAUSE_TOWARDS (3 << 7) - -#define MII_ANLPAR 0x05 /* Autonegotiation lnk partner abilities (rw) */ - /* section 28.2.4.1 and 37.2.6.1 */ -#define ANLPAR_NP 0x8000 /* Next page (ro) */ -#define ANLPAR_ACK 0x4000 /* link partner accepted ACK (ro) */ -#define ANLPAR_RF 0x2000 /* remote fault (ro) */ -#define ANLPAR_FC 0x0400 /* link partner supports PAUSE */ -#define ANLPAR_T4 0x0200 /* link partner supports 100bT4 */ -#define ANLPAR_TX_FD 0x0100 /* link partner supports 100bTx FD */ -#define ANLPAR_TX 0x0080 /* link partner supports 100bTx */ -#define ANLPAR_10_FD 0x0040 /* link partner supports 10bT FD */ -#define ANLPAR_10 0x0020 /* link partner supports 10bT */ -#define ANLPAR_CSMA 0x0001 /* protocol selector CSMA/CD */ -#define ANLPAR_PAUSE_MASK (3 << 10) -#define ANLPAR_PAUSE_NONE (0 << 10) -#define ANLPAR_PAUSE_SYM (1 << 10) -#define ANLPAR_PAUSE_ASYM (2 << 10) -#define ANLPAR_PAUSE_TOWARDS (3 << 10) - -#define ANLPAR_X_FD 0x0020 /* local device supports 1000BASE-X FD */ -#define ANLPAR_X_HD 0x0040 /* local device supports 1000BASE-X HD */ -#define ANLPAR_X_PAUSE_MASK (3 << 7) -#define ANLPAR_X_PAUSE_NONE (0 << 7) -#define ANLPAR_X_PAUSE_SYM (1 << 7) -#define ANLPAR_X_PAUSE_ASYM (2 << 7) -#define ANLPAR_X_PAUSE_TOWARDS (3 << 7) - -#define MII_ANER 0x06 /* Autonegotiation expansion (ro) */ - /* section 28.2.4.1 and 37.2.6.1 */ -#define ANER_MLF 0x0010 /* multiple link detection fault */ -#define ANER_LPNP 0x0008 /* link parter next page-able */ -#define ANER_NP 0x0004 /* next page-able */ -#define ANER_PAGE_RX 0x0002 /* Page received */ -#define ANER_LPAN 0x0001 /* link parter autoneg-able */ - -#define MII_ANNP 0x07 /* Autonegotiation next page */ - /* section 28.2.4.1 and 37.2.6.1 */ - -#define MII_ANLPRNP 0x08 /* Autonegotiation link partner rx next page */ - /* section 32.5.1 and 37.2.6.1 */ - - /* This is also the 1000baseT control register */ -#define MII_100T2CR 0x09 /* 100base-T2 control register */ -#define GTCR_TEST_MASK 0xe000 /* see 802.3ab ss. 40.6.1.1.2 */ -#define GTCR_MAN_MS 0x1000 /* enable manual master/slave control */ -#define GTCR_ADV_MS 0x0800 /* 1 = adv. master, 0 = adv. slave */ -#define GTCR_PORT_TYPE 0x0400 /* 1 = DCE, 0 = DTE (NIC) */ -#define GTCR_ADV_1000TFDX 0x0200 /* adv. 1000baseT FDX */ -#define GTCR_ADV_1000THDX 0x0100 /* adv. 1000baseT HDX */ - - /* This is also the 1000baseT status register */ -#define MII_100T2SR 0x0a /* 100base-T2 status register */ -#define GTSR_MAN_MS_FLT 0x8000 /* master/slave config fault */ -#define GTSR_MS_RES 0x4000 /* result: 1 = master, 0 = slave */ -#define GTSR_LRS 0x2000 /* local rx status, 1 = ok */ -#define GTSR_RRS 0x1000 /* remove rx status, 1 = ok */ -#define GTSR_LP_1000TFDX 0x0800 /* link partner 1000baseT FDX capable */ -#define GTSR_LP_1000THDX 0x0400 /* link partner 1000baseT HDX capable */ -#define GTSR_LP_ASM_DIR 0x0200 /* link partner asym. pause dir. capable */ -#define GTSR_IDLE_ERR 0x00ff /* IDLE error count */ - -#define MII_EXTSR 0x0f /* Extended status register */ -#define EXTSR_1000XFDX 0x8000 /* 1000X full-duplex capable */ -#define EXTSR_1000XHDX 0x4000 /* 1000X half-duplex capable */ -#define EXTSR_1000TFDX 0x2000 /* 1000T full-duplex capable */ -#define EXTSR_1000THDX 0x1000 /* 1000T half-duplex capable */ - -#define EXTSR_MEDIAMASK (EXTSR_1000XFDX|EXTSR_1000XHDX| \ - EXTSR_1000TFDX|EXTSR_1000THDX) - -#endif /* _DEV_MII_MII_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/dev/mii/mii_bitbang.h b/src/libs/compat/freebsd_network/compat/dev/mii/mii_bitbang.h deleted file mode 100644 index 2bc7427625..0000000000 --- a/src/libs/compat/freebsd_network/compat/dev/mii/mii_bitbang.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $NetBSD: mii_bitbang.h,v 1.6 2009/05/12 14:31:27 cegger Exp $ */ - -/*- - * Copyright (c) 1999 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#define MII_BIT_MDO 0 /* data out (host->PHY) */ -#define MII_BIT_MDI 1 /* data in (PHY->host) */ -#define MII_BIT_MDC 2 /* clock */ -#define MII_BIT_DIR_HOST_PHY 3 /* set direction: host->PHY */ -#define MII_BIT_DIR_PHY_HOST 4 /* set direction: PHY->host */ -#define MII_NBITS 5 - -struct mii_bitbang_ops { - uint32_t (*mbo_read)(device_t); - void (*mbo_write)(device_t, uint32_t); - uint32_t mbo_bits[MII_NBITS]; -}; - -typedef const struct mii_bitbang_ops *mii_bitbang_ops_t; - -int mii_bitbang_readreg(device_t dev, mii_bitbang_ops_t ops, - int phy, int reg); -void mii_bitbang_sync(device_t dev, mii_bitbang_ops_t ops); -void mii_bitbang_writereg(device_t dev, mii_bitbang_ops_t ops, - int phy, int reg, int val); diff --git a/src/libs/compat/freebsd_network/compat/dev/mii/miidevs b/src/libs/compat/freebsd_network/compat/dev/mii/miidevs deleted file mode 100644 index 5d69fa1f9f..0000000000 --- a/src/libs/compat/freebsd_network/compat/dev/mii/miidevs +++ /dev/null @@ -1,325 +0,0 @@ -$FreeBSD$ -/*$NetBSD: miidevs,v 1.105 2011/11/25 23:28:14 jakllsch Exp $*/ - -/*- - * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * List of known MII OUIs. - * For a complete list see http://standards.ieee.org/regauth/oui/ - * - * XXX Vendors do obviously not agree how OUIs (24 bit) are mapped - * to the 22 bits available in the id registers. - * IEEE 802.3u-1995, subclause 22.2.4.3.1, figure 22-12, depicts the right - * mapping; the bit positions are defined in IEEE 802-1990, figure 5.2. - * (There is a formal 802.3 interpretation, number 1-07/98 of July 09 1998, - * about this.) - * The MII_OUI() macro in "mii.h" reflects this. - * If a vendor uses a different mapping, an "xx" prefixed OUI is defined here - * which is mangled accordingly to compensate. - */ - -oui AGERE 0x00053d Agere Systems -oui ALTIMA 0x0010a9 Altima Communications -oui AMD 0x00001a Advanced Micro Devices -oui BROADCOM 0x001018 Broadcom Corporation -oui BROADCOM2 0x000af7 Broadcom Corporation -oui BROADCOM3 0x001be9 Broadcom Corporation -oui BROADCOM4 0x18c086 Broadcom Corporation -oui CICADA 0x0003F1 Cicada Semiconductor -oui DAVICOM 0x00606e Davicom Semiconductor -oui ENABLESEMI 0x0010dd Enable Semiconductor -oui ICPLUS 0x0090c3 IC Plus Corp. -oui ICS 0x00a0be Integrated Circuit Systems -oui INTEL 0x00aa00 Intel Corporation -oui JMICRON 0x00d831 JMicron Technologies -oui LEVEL1 0x00207b Level 1 -oui MARVELL 0x005043 Marvell Semiconductor -oui MYSON 0x00c0b4 Myson Technology -oui NATSEMI 0x080017 National Semiconductor -oui PMCSIERRA 0x00e004 PMC-Sierra -oui QUALSEMI 0x006051 Quality Semiconductor -oui RDC 0x00d02d RDC Semiconductor -oui REALTEK 0x00e04c RealTek Semicondctor -oui SEEQ 0x00a07d Seeq Technology -oui SIS 0x00e006 Silicon Integrated Systems -oui TI 0x080028 Texas Instruments -oui TSC 0x00c039 TDK Semiconductor -oui XAQTI 0x00e0ae XaQti Corp. - -/* Some Intel 82553's use an alternative OUI. */ -oui xxINTEL 0x001f00 Intel Corporation - -/* Some VIA 6122's use an alternative OUI. */ -oui xxCICADA 0x00c08f Cicada Semiconductor - -/* bad bitorder (bits "g" and "h" (= MSBs byte 1) lost) */ -oui yyAMD 0x000058 Advanced Micro Devices -oui xxATHEROS 0x00c82e Atheros Communications -oui xxBROADCOM 0x000818 Broadcom Corporation -oui xxBROADCOM_ALT1 0x0050ef Broadcom Corporation -oui xxDAVICOM 0x000676 Davicom Semiconductor -oui yyINTEL 0x005500 Intel Corporation -oui xxJATO 0x0007c1 Jato Technologies -oui xxMARVELL 0x000ac2 Marvell Semiconductor -oui xxMYSON 0x00032d Myson Technology -oui xxNATSEMI 0x1000e8 National Semiconductor -oui xxQUALSEMI 0x00068a Quality Semiconductor -oui xxTSC 0x00039c TDK Semiconductor -oui xxVITESSE 0x008083 Vitesse Semiconductor - -/* bad byteorder (bits "q" and "r" (= LSBs byte 3) lost) */ -oui xxLEVEL1 0x782000 Level 1 -oui xxXAQTI 0xace000 XaQti Corp. - -/* Don't know what's going on here. */ -oui xxASIX 0x000674 Asix Semiconductor -oui yyDAVICOM 0x000602 Davicom Semiconductor -oui xxICPLUS 0x0009c3 IC Plus Corp. -oui xxPMCSIERRA 0x0009c0 PMC-Sierra -oui xxPMCSIERRA2 0x009057 PMC-Sierra -oui xxREALTEK 0x000732 RealTek Semicondctor -oui yyREALTEK 0x000004 RealTek Semicondctor - -/* - * List of known models. Grouped by oui. - */ - -/* Agere Systems PHYs */ -model AGERE ET1011 0x0001 ET1011 10/100/1000baseT PHY -model AGERE ET1011C 0x0004 ET1011C 10/100/1000baseT PHY - -/* Altima Communications PHYs */ -model ALTIMA ACXXX 0x0001 ACXXX 10/100 media interface -model ALTIMA AC101L 0x0012 AC101L 10/100 media interface -model ALTIMA AC101 0x0021 AC101 10/100 media interface -/* AMD Am79C87[45] have ALTIMA OUI */ -model ALTIMA Am79C875 0x0014 Am79C875 10/100 media interface -model ALTIMA Am79C874 0x0021 Am79C874 10/100 media interface - -/* Advanced Micro Devices PHYs */ -/* see Davicom DM9101 for Am79C873 */ -model yyAMD 79C972_10T 0x0001 Am79C972 internal 10BASE-T interface -model yyAMD 79c973phy 0x0036 Am79C973 internal 10/100 media interface -model yyAMD 79c901 0x0037 Am79C901 10BASE-T interface -model yyAMD 79c901home 0x0039 Am79C901 HomePNA 1.0 interface - -/* Atheros Communications/Attansic PHYs */ -model xxATHEROS F1 0x0001 Atheros F1 10/100/1000 PHY -model xxATHEROS F2 0x0002 Atheros F2 10/100 PHY -model xxATHEROS F1_7 0x0007 Atheros F1 10/100/1000 PHY - -/* Asix semiconductor PHYs */ -model xxASIX AX88X9X 0x0031 Ax88x9x internal PHY - -/* Broadcom Corp. PHYs */ -model xxBROADCOM 3C905B 0x0012 Broadcom 3c905B internal PHY -model xxBROADCOM 3C905C 0x0017 Broadcom 3c905C internal PHY -model xxBROADCOM BCM5201 0x0021 BCM5201 10/100 media interface -model xxBROADCOM BCM5214 0x0028 BCM5214 Quad 10/100 media interface -model xxBROADCOM BCM5221 0x001e BCM5221 10/100 media interface -model xxBROADCOM BCM5222 0x0032 BCM5222 Dual 10/100 media interface -model xxBROADCOM BCM4401 0x0036 BCM4401 10/100 media interface -model xxBROADCOM BCM5365 0x0037 BCM5365 10/100 5-port PHY switch -model BROADCOM BCM5400 0x0004 BCM5400 1000BASE-T media interface -model BROADCOM BCM5401 0x0005 BCM5401 1000BASE-T media interface -model BROADCOM BCM5411 0x0007 BCM5411 1000BASE-T media interface -model BROADCOM BCM5464 0x000b BCM5464 1000BASE-T media interface -model BROADCOM BCM5461 0x000c BCM5461 1000BASE-T media interface -model BROADCOM BCM5462 0x000d BCM5462 1000BASE-T media interface -model BROADCOM BCM5421 0x000e BCM5421 1000BASE-T media interface -model BROADCOM BCM5752 0x0010 BCM5752 1000BASE-T media interface -model BROADCOM BCM5701 0x0011 BCM5701 1000BASE-T media interface -model BROADCOM BCM5706 0x0015 BCM5706 1000BASE-T/SX media interface -model BROADCOM BCM5703 0x0016 BCM5703 1000BASE-T media interface -model BROADCOM BCM5750 0x0018 BCM5750 1000BASE-T media interface -model BROADCOM BCM5704 0x0019 BCM5704 1000BASE-T media interface -model BROADCOM BCM5705 0x001a BCM5705 1000BASE-T media interface -model BROADCOM BCM54K2 0x002e BCM54K2 1000BASE-T media interface -model BROADCOM BCM5714 0x0034 BCM5714 1000BASE-T media interface -model BROADCOM BCM5780 0x0035 BCM5780 1000BASE-T media interface -model BROADCOM BCM5708C 0x0036 BCM5708C 1000BASE-T media interface -model BROADCOM2 BCM5325 0x0003 BCM5325 10/100 5-port PHY switch -model BROADCOM2 BCM5906 0x0004 BCM5906 10/100baseTX media interface -model BROADCOM2 BCM5481 0x000a BCM5481 1000BASE-T media interface -model BROADCOM2 BCM5482 0x000b BCM5482 1000BASE-T media interface -model BROADCOM2 BCM5755 0x000c BCM5755 1000BASE-T media interface -model BROADCOM2 BCM5754 0x000e BCM5754/5787 1000BASE-T media interface -model BROADCOM2 BCM5708S 0x0015 BCM5708S 1000/2500baseSX PHY -model BROADCOM2 BCM5785 0x0016 BCM5785 1000BASE-T media interface -model BROADCOM2 BCM5709CAX 0x002c BCM5709CAX 10/100/1000baseT PHY -model BROADCOM2 BCM5722 0x002d BCM5722 1000BASE-T media interface -model BROADCOM2 BCM5784 0x003a BCM5784 10/100/1000baseT PHY -model BROADCOM2 BCM5709C 0x003c BCM5709 10/100/1000baseT PHY -model BROADCOM2 BCM5761 0x003d BCM5761 10/100/1000baseT PHY -model BROADCOM2 BCM5709S 0x003f BCM5709S/5720S 1000/2500baseSX PHY -model BROADCOM3 BCM57780 0x0019 BCM57780 1000BASE-T media interface -model BROADCOM3 BCM5717C 0x0020 BCM5717C 1000BASE-T media interface -model BROADCOM3 BCM5719C 0x0022 BCM5719C 1000BASE-T media interface -model BROADCOM3 BCM57765 0x0024 BCM57765 1000BASE-T media interface -model BROADCOM3 BCM5720C 0x0036 BCM5720C 1000BASE-T media interface -model BROADCOM4 BCM5725C 0x0038 BCM5725C 1000BASE-T media interface -model xxBROADCOM_ALT1 BCM5906 0x0004 BCM5906 10/100baseTX media interface - -/* Cicada Semiconductor PHYs (now owned by Vitesse?) */ -model xxCICADA CS8201 0x0001 Cicada CS8201 10/100/1000TX PHY -model xxCICADA CS8204 0x0004 Cicada CS8204 10/100/1000TX PHY -model xxCICADA VSC8211 0x000b Cicada VSC8211 10/100/1000TX PHY -model xxCICADA CS8201A 0x0020 Cicada CS8201 10/100/1000TX PHY -model xxCICADA CS8201B 0x0021 Cicada CS8201 10/100/1000TX PHY -model xxCICADA CS8244 0x002c Cicada CS8244 10/100/1000TX PHY -model xxVITESSE VSC8601 0x0002 Vitesse VSC8601 10/100/1000TX PHY - -/* Davicom Semiconductor PHYs */ -/* AMD Am79C873 seems to be a relabeled DM9101 */ -model xxDAVICOM DM9101 0x0000 DM9101 (AMD Am79C873) 10/100 media interface -model xxDAVICOM DM9102 0x0004 DM9102 10/100 media interface -model yyDAVICOM DM9101 0x0000 DM9101 10/100 media interface - -/* IC Plus Corp. PHYs */ -model xxICPLUS IP101 0x0005 IP101 10/100 PHY -model xxICPLUS IP1000A 0x0008 IP100A 10/100/1000 media interface -model xxICPLUS IP1001 0x0019 IP1001 10/100/1000 media interface - -/* Integrated Circuit Systems PHYs */ -model ICS 1889 0x0001 ICS1889 10/100 media interface -model ICS 1890 0x0002 ICS1890 10/100 media interface -model ICS 1892 0x0003 ICS1892 10/100 media interface -model ICS 1893 0x0004 ICS1893 10/100 media interface - -/* Intel Corporation PHYs */ -model xxINTEL I82553 0x0000 i82553 10/100 media interface -model yyINTEL I82555 0x0015 i82555 10/100 media interface -model yyINTEL I82562EH 0x0017 i82562EH HomePNA interface -model yyINTEL I82562G 0x0031 i82562G 10/100 media interface -model yyINTEL I82562EM 0x0032 i82562EM 10/100 media interface -model yyINTEL I82562ET 0x0033 i82562ET 10/100 media interface -model yyINTEL I82553 0x0035 i82553 10/100 media interface -model yyINTEL I82566 0x0039 i82566 10/100/1000 media interface -model INTEL I82577 0x0005 i82577 10/100/1000 media interface -model INTEL I82579 0x0009 i82579 10/100/1000 media interface -model xxMARVELL I82563 0x000a i82563 10/100/1000 media interface - -model yyINTEL IGP01E1000 0x0038 Intel IGP01E1000 Gigabit PHY - -/* Jato Technologies PHYs */ -model xxJATO BASEX 0x0000 Jato 1000baseX media interface - -/* JMicron Technologies PHYs */ -model JMICRON JMP211 0x0021 JMP211 10/100/1000 media interface -model JMICRON JMP202 0x0022 JMP202 10/100 media interface - -/* Level 1 PHYs */ -model xxLEVEL1 LXT970 0x0000 LXT970 10/100 media interface -model LEVEL1 LXT971 0x000e LXT971/2 10/100 media interface -model LEVEL1 LXT973 0x0021 LXT973 10/100 Dual PHY -model LEVEL1 LXT974 0x0004 LXT974 10/100 Quad PHY -model LEVEL1 LXT975 0x0005 LXT975 10/100 Quad PHY -model LEVEL1 LXT1000_OLD 0x0003 LXT1000 1000BASE-T media interface -model LEVEL1 LXT1000 0x000c LXT1000 1000BASE-T media interface - -/* Marvell Semiconductor PHYs */ -model xxMARVELL E1000 0x0000 Marvell 88E1000 Gigabit PHY -model xxMARVELL E1011 0x0002 Marvell 88E1011 Gigabit PHY -model xxMARVELL E1000_3 0x0003 Marvell 88E1000 Gigabit PHY -model xxMARVELL E1000S 0x0004 Marvell 88E1000S Gigabit PHY -model xxMARVELL E1000_5 0x0005 Marvell 88E1000 Gigabit PHY -model xxMARVELL E1101 0x0006 Marvell 88E1101 Gigabit PHY -model xxMARVELL E3082 0x0008 Marvell 88E3082 10/100 Fast Ethernet PHY -model xxMARVELL E1112 0x0009 Marvell 88E1112 Gigabit PHY -model xxMARVELL E1149 0x000b Marvell 88E1149 Gigabit PHY -model xxMARVELL E1111 0x000c Marvell 88E1111 Gigabit PHY -model xxMARVELL E1145 0x000d Marvell 88E1145 Quad Gigabit PHY -model xxMARVELL E1116 0x0021 Marvell 88E1116 Gigabit PHY -model xxMARVELL E1116R 0x0024 Marvell 88E1116R Gigabit PHY -model xxMARVELL E1118 0x0022 Marvell 88E1118 Gigabit PHY -model xxMARVELL E1149R 0x0025 Marvell 88E1149R Quad Gigabit PHY -model xxMARVELL E3016 0x0026 Marvell 88E3016 10/100 Fast Ethernet PHY -model xxMARVELL PHYG65G 0x0027 Marvell PHYG65G Gigabit PHY -model xxMARVELL E1116R_29 0x0029 Marvell 88E1116R Gigabit PHY -model MARVELL E1000 0x0005 Marvell 88E1000 Gigabit PHY -model MARVELL E1011 0x0002 Marvell 88E1011 Gigabit PHY -model MARVELL E1000_3 0x0003 Marvell 88E1000 Gigabit PHY -model MARVELL E1000_5 0x0005 Marvell 88E1000 Gigabit PHY -model MARVELL E1111 0x000c Marvell 88E1111 Gigabit PHY - -/* Myson Technology PHYs */ -model xxMYSON MTD972 0x0000 MTD972 10/100 media interface -model MYSON MTD803 0x0000 MTD803 3-in-1 media interface - -/* National Semiconductor PHYs */ -model xxNATSEMI DP83840 0x0000 DP83840 10/100 media interface -model xxNATSEMI DP83843 0x0001 DP83843 10/100 media interface -model xxNATSEMI DP83815 0x0002 DP83815 10/100 media interface -model xxNATSEMI DP83847 0x0003 DP83847 10/100 media interface -model xxNATSEMI DP83891 0x0005 DP83891 1000BASE-T media interface -model xxNATSEMI DP83861 0x0006 DP83861 1000BASE-T media interface -model xxNATSEMI DP83865 0x0007 DP83865 1000BASE-T media interface -model xxNATSEMI DP83849 0x000a DP83849 10/100 media interface - -/* PMC Sierra PHYs */ -model xxPMCSIERRA PM8351 0x0000 PM8351 OctalPHY Gigabit interface -model xxPMCSIERRA2 PM8352 0x0002 PM8352 OctalPHY Gigabit interface -model xxPMCSIERRA2 PM8353 0x0003 PM8353 QuadPHY Gigabit interface -model PMCSIERRA PM8354 0x0004 PM8354 QuadPHY Gigabit interface - -/* Quality Semiconductor PHYs */ -model xxQUALSEMI QS6612 0x0000 QS6612 10/100 media interface - -/* RDC Semiconductor PHYs */ -model RDC R6040 0x0003 R6040 10/100 media interface - -/* RealTek Semicondctor PHYs */ -model yyREALTEK RTL8201L 0x0020 RTL8201L 10/100 media interface -model xxREALTEK RTL8169S 0x0011 RTL8169S/8110S/8211 1000BASE-T media interface -model REALTEK RTL8305SC 0x0005 RTL8305SC 10/100 802.1q switch -model REALTEK RTL8201E 0x0008 RTL8201E 10/100 media interface -model REALTEK RTL8251 0x0000 RTL8251 1000BASE-T media interface -model REALTEK RTL8169S 0x0011 RTL8169S/8110S/8211 1000BASE-T media interface - -/* Seeq Seeq PHYs */ -model SEEQ 80220 0x0003 Seeq 80220 10/100 media interface -model SEEQ 84220 0x0004 Seeq 84220 10/100 media interface -model SEEQ 80225 0x0008 Seeq 80225 10/100 media interface - -/* Silicon Integrated Systems PHYs */ -model SIS 900 0x0000 SiS 900 10/100 media interface - -/* Texas Instruments PHYs */ -model TI TLAN10T 0x0001 ThunderLAN 10BASE-T media interface -model TI 100VGPMI 0x0002 ThunderLAN 100VG-AnyLan media interface -model TI TNETE2101 0x0003 TNETE2101 media interface - -/* TDK Semiconductor PHYs */ -model xxTSC 78Q2120 0x0014 78Q2120 10/100 media interface -model xxTSC 78Q2121 0x0015 78Q2121 100BASE-TX media interface - -/* XaQti Corp. PHYs */ -model xxXAQTI XMACII 0x0000 XaQti Corp. XMAC II gigabit interface diff --git a/src/libs/compat/freebsd_network/compat/dev/mii/miivar.h b/src/libs/compat/freebsd_network/compat/dev/mii/miivar.h deleted file mode 100644 index 47fcdb2155..0000000000 --- a/src/libs/compat/freebsd_network/compat/dev/mii/miivar.h +++ /dev/null @@ -1,315 +0,0 @@ -/* $NetBSD: miivar.h,v 1.8 1999/04/23 04:24:32 thorpej Exp $ */ - -/*- - * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _DEV_MII_MIIVAR_H_ -#define _DEV_MII_MIIVAR_H_ - -#include - -/* - * Media Independent Interface data structure defintions - */ - -struct mii_softc; - -/* - * Callbacks from MII layer into network interface device driver. - */ -typedef int (*mii_readreg_t)(struct device *, int, int); -typedef void (*mii_writereg_t)(struct device *, int, int, int); -typedef void (*mii_statchg_t)(struct device *); - -/* - * A network interface driver has one of these structures in its softc. - * It is the interface from the network interface driver to the MII - * layer. - */ -struct mii_data { - struct ifmedia mii_media; /* media information */ - struct ifnet *mii_ifp; /* pointer back to network interface */ - - /* - * For network interfaces with multiple PHYs, a list of all - * PHYs is required so they can all be notified when a media - * request is made. - */ - LIST_HEAD(mii_listhead, mii_softc) mii_phys; - u_int mii_instance; - - /* - * PHY driver fills this in with active media status. - */ - u_int mii_media_status; - u_int mii_media_active; - - /* - * Calls from MII layer into network interface driver. - */ - mii_readreg_t mii_readreg; - mii_writereg_t mii_writereg; - mii_statchg_t mii_statchg; -}; -typedef struct mii_data mii_data_t; - -/* - * Functions provided by the PHY to perform various functions. - */ -struct mii_phy_funcs { - int (*pf_service)(struct mii_softc *, struct mii_data *, int); - void (*pf_status)(struct mii_softc *); - void (*pf_reset)(struct mii_softc *); -}; - -/* - * Requests that can be made to the downcall. - */ -#define MII_TICK 1 /* once-per-second tick */ -#define MII_MEDIACHG 2 /* user changed media; perform the switch */ -#define MII_POLLSTAT 3 /* user requested media status; fill it in */ - -/* - * Each PHY driver's softc has one of these as the first member. - * XXX This would be better named "phy_softc", but this is the name - * XXX BSDI used, and we would like to have the same interface. - */ -struct mii_softc { - device_t mii_dev; /* generic device glue */ - - LIST_ENTRY(mii_softc) mii_list; /* entry on parent's PHY list */ - - uint32_t mii_mpd_oui; /* the PHY's OUI (MII_OUI())*/ - uint32_t mii_mpd_model; /* the PHY's model (MII_MODEL())*/ - uint32_t mii_mpd_rev; /* the PHY's revision (MII_REV())*/ - u_int mii_capmask; /* capability mask for BMSR */ - u_int mii_phy; /* our MII address */ - u_int mii_offset; /* first PHY, second PHY, etc. */ - u_int mii_inst; /* instance for ifmedia */ - - /* Our PHY functions. */ - const struct mii_phy_funcs *mii_funcs; - - struct mii_data *mii_pdata; /* pointer to parent's mii_data */ - - u_int mii_flags; /* misc. flags; see below */ - u_int mii_capabilities; /* capabilities from BMSR */ - u_int mii_extcapabilities; /* extended capabilities */ - u_int mii_ticks; /* MII_TICK counter */ - u_int mii_anegticks; /* ticks before retrying aneg */ - u_int mii_media_active; /* last active media */ - u_int mii_media_status; /* last active status */ -}; -typedef struct mii_softc mii_softc_t; - -/* mii_flags */ -#define MIIF_INITDONE 0x00000001 /* has been initialized (mii_data) */ -#define MIIF_NOISOLATE 0x00000002 /* do not isolate the PHY */ -#if 0 -#define MIIF_NOLOOP 0x00000004 /* no loopback capability */ -#endif -#define MIIF_DOINGAUTO 0x00000008 /* doing autonegotiation (mii_softc) */ -#define MIIF_AUTOTSLEEP 0x00000010 /* use tsleep(), not callout() */ -#define MIIF_HAVEFIBER 0x00000020 /* from parent: has fiber interface */ -#define MIIF_HAVE_GTCR 0x00000040 /* has 100base-T2/1000base-T CR */ -#define MIIF_IS_1000X 0x00000080 /* is a 1000BASE-X device */ -#define MIIF_DOPAUSE 0x00000100 /* advertise PAUSE capability */ -#define MIIF_IS_HPNA 0x00000200 /* is a HomePNA device */ -#define MIIF_FORCEANEG 0x00000400 /* force auto-negotiation */ -#define MIIF_NOMANPAUSE 0x00100000 /* no manual PAUSE selection */ -#define MIIF_FORCEPAUSE 0x00200000 /* force PAUSE advertisement */ -#define MIIF_MACPRIV0 0x01000000 /* private to the MAC driver */ -#define MIIF_MACPRIV1 0x02000000 /* private to the MAC driver */ -#define MIIF_MACPRIV2 0x04000000 /* private to the MAC driver */ -#define MIIF_PHYPRIV0 0x10000000 /* private to the PHY driver */ -#define MIIF_PHYPRIV1 0x20000000 /* private to the PHY driver */ -#define MIIF_PHYPRIV2 0x40000000 /* private to the PHY driver */ - -/* Default mii_anegticks values */ -#define MII_ANEGTICKS 5 -#define MII_ANEGTICKS_GIGE 17 - -#define MIIF_INHERIT_MASK (MIIF_NOISOLATE|MIIF_NOLOOP|MIIF_AUTOTSLEEP) - -/* - * Special `locators' passed to mii_attach(). If one of these is not - * an `any' value, we look for *that* PHY and configure it. If both - * are not `any', that is an error, and mii_attach() will fail. - */ -#define MII_OFFSET_ANY -1 -#define MII_PHY_ANY -1 - -/* - * Used to attach a PHY to a parent. - */ -struct mii_attach_args { - struct mii_data *mii_data; /* pointer to parent data */ - u_int mii_phyno; /* MII address */ - u_int mii_offset; /* first PHY, second PHY, etc. */ - uint32_t mii_id1; /* PHY ID register 1 */ - uint32_t mii_id2; /* PHY ID register 2 */ - u_int mii_capmask; /* capability mask for BMSR */ -}; -typedef struct mii_attach_args mii_attach_args_t; - -/* - * Used to match a PHY. - */ -struct mii_phydesc { - uint32_t mpd_oui; /* the PHY's OUI */ - uint32_t mpd_model; /* the PHY's model */ - const char *mpd_name; /* the PHY's name */ -}; -#define MII_PHY_DESC(a, b) { MII_OUI_ ## a, MII_MODEL_ ## a ## _ ## b, \ - MII_STR_ ## a ## _ ## b } -#define MII_PHY_END { 0, 0, NULL } - -/* - * An array of these structures map MII media types to BMCR/ANAR settings. - */ -struct mii_media { - u_int mm_bmcr; /* BMCR settings for this media */ - u_int mm_anar; /* ANAR settings for this media */ - u_int mm_gtcr; /* 100base-T2 or 1000base-T CR */ -}; - -#define MII_MEDIA_NONE 0 -#define MII_MEDIA_10_T 1 -#define MII_MEDIA_10_T_FDX 2 -#define MII_MEDIA_100_T4 3 -#define MII_MEDIA_100_TX 4 -#define MII_MEDIA_100_TX_FDX 5 -#define MII_MEDIA_1000_X 6 -#define MII_MEDIA_1000_X_FDX 7 -#define MII_MEDIA_1000_T 8 -#define MII_MEDIA_1000_T_FDX 9 -#define MII_NMEDIA 10 - -#ifdef _KERNEL - -#ifdef __HAIKU__ -int __haiku_miibus_readreg(device_t dev, int phy, int reg); -int __haiku_miibus_writereg(device_t dev, int phy, int reg, int data); -void __haiku_miibus_statchg(device_t dev); -void __haiku_miibus_linkchg(device_t dev); -void __haiku_miibus_mediainit(device_t dev); - -#define MIIBUS_READREG(dev, phy, reg) \ - __haiku_miibus_readreg((dev), (phy), (reg)) - -#define MIIBUS_WRITEREG(dev, phy, reg, value) \ - __haiku_miibus_writereg((dev), (phy), (reg), (value)) - -#define MIIBUS_STATCHG(dev) \ - __haiku_miibus_statchg(dev) - -#define MIIBUS_LINKCHG(dev) \ - __haiku_miibus_linkchg(dev) - -#define MIIBUS_MEDIAINIT(dev) \ - __haiku_miibus_mediainit(dev) - -#endif - -#define PHY_READ(p, r) \ - MIIBUS_READREG((p)->mii_dev, (p)->mii_phy, (r)) - -#define PHY_WRITE(p, r, v) \ - MIIBUS_WRITEREG((p)->mii_dev, (p)->mii_phy, (r), (v)) - -#define PHY_SERVICE(p, d, o) \ - (*(p)->mii_funcs->pf_service)((p), (d), (o)) - -#define PHY_STATUS(p) \ - (*(p)->mii_funcs->pf_status)(p) - -#define PHY_RESET(p) \ - (*(p)->mii_funcs->pf_reset)(p) - -enum miibus_device_ivars { - MIIBUS_IVAR_FLAGS -}; - -/* - * Simplified accessors for miibus - */ -#define MIIBUS_ACCESSOR(var, ivar, type) \ - __BUS_ACCESSOR(miibus, var, MIIBUS, ivar, type) - -MIIBUS_ACCESSOR(flags, FLAGS, u_int) - -extern devclass_t miibus_devclass; -extern driver_t miibus_driver; - -int miibus_probe(device_t); -int miibus_attach(device_t); -int miibus_detach(device_t); - -int mii_attach(device_t, device_t *, struct ifnet *, ifm_change_cb_t, - ifm_stat_cb_t, int, int, int, int); -void mii_down(struct mii_data *); -int mii_mediachg(struct mii_data *); -void mii_tick(struct mii_data *); -void mii_pollstat(struct mii_data *); -void mii_phy_add_media(struct mii_softc *); - -#ifdef __HAIKU__ -int mii_media_from_bmcr(int); -#endif - -int mii_phy_auto(struct mii_softc *); -int mii_phy_detach(device_t dev); -void mii_phy_down(struct mii_softc *); -u_int mii_phy_flowstatus(struct mii_softc *); -void mii_phy_reset(struct mii_softc *); -void mii_phy_setmedia(struct mii_softc *sc); -void mii_phy_update(struct mii_softc *, int); -int mii_phy_tick(struct mii_softc *); - -const struct mii_phydesc * mii_phy_match(const struct mii_attach_args *ma, - const struct mii_phydesc *mpd); -const struct mii_phydesc * mii_phy_match_gen(const struct mii_attach_args *ma, - const struct mii_phydesc *mpd, size_t endlen); -int mii_phy_dev_probe(device_t dev, const struct mii_phydesc *mpd, int mrv); -void mii_phy_dev_attach(device_t dev, u_int flags, - const struct mii_phy_funcs *mpf, int add_media); - -void ukphy_status(struct mii_softc *); - -u_int mii_oui(u_int, u_int); -#define MII_OUI(id1, id2) mii_oui(id1, id2) -#define MII_MODEL(id2) (((id2) & IDR2_MODEL) >> 4) -#define MII_REV(id2) ((id2) & IDR2_REV) - -#endif /* _KERNEL */ - -#endif /* _DEV_MII_MIIVAR_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/dev/ofw/openfirm.h b/src/libs/compat/freebsd_network/compat/dev/ofw/openfirm.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/libs/compat/freebsd_network/compat/dev/pci/pcireg.h b/src/libs/compat/freebsd_network/compat/dev/pci/pcireg.h deleted file mode 100644 index ef3513560f..0000000000 --- a/src/libs/compat/freebsd_network/compat/dev/pci/pcireg.h +++ /dev/null @@ -1,988 +0,0 @@ -/*- - * Copyright (c) 1997, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice unmodified, this list of conditions, and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - * - */ - -/* - * PCIM_xxx: mask to locate subfield in register - * PCIR_xxx: config register offset - * PCIC_xxx: device class - * PCIS_xxx: device subclass - * PCIP_xxx: device programming interface - * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices) - * PCID_xxx: device ID - * PCIY_xxx: capability identification number - * PCIZ_xxx: extended capability identification number - */ - -/* some PCI bus constants */ -#define PCI_DOMAINMAX 65535 /* highest supported domain number */ -#define PCI_BUSMAX 255 /* highest supported bus number */ -#define PCI_SLOTMAX 31 /* highest supported slot number */ -#define PCI_FUNCMAX 7 /* highest supported function number */ -#define PCI_REGMAX 255 /* highest supported config register addr. */ -#define PCIE_REGMAX 4095 /* highest supported config register addr. */ -#define PCI_MAXHDRTYPE 2 - -/* PCI config header registers for all devices */ - -#define PCIR_DEVVENDOR 0x00 -#define PCIR_VENDOR 0x00 -#define PCIR_DEVICE 0x02 -#define PCIR_COMMAND 0x04 -#define PCIM_CMD_PORTEN 0x0001 -#define PCIM_CMD_MEMEN 0x0002 -#define PCIM_CMD_BUSMASTEREN 0x0004 -#define PCIM_CMD_SPECIALEN 0x0008 -#define PCIM_CMD_MWRICEN 0x0010 -#define PCIM_CMD_PERRESPEN 0x0040 -#define PCIM_CMD_SERRESPEN 0x0100 -#define PCIM_CMD_BACKTOBACK 0x0200 -#define PCIM_CMD_INTxDIS 0x0400 -#define PCIR_STATUS 0x06 -#define PCIM_STATUS_INTxSTATE 0x0008 -#define PCIM_STATUS_CAPPRESENT 0x0010 -#define PCIM_STATUS_66CAPABLE 0x0020 -#define PCIM_STATUS_BACKTOBACK 0x0080 -#define PCIM_STATUS_MDPERR 0x0100 -#define PCIM_STATUS_SEL_FAST 0x0000 -#define PCIM_STATUS_SEL_MEDIMUM 0x0200 -#define PCIM_STATUS_SEL_SLOW 0x0400 -#define PCIM_STATUS_SEL_MASK 0x0600 -#define PCIM_STATUS_STABORT 0x0800 -#define PCIM_STATUS_RTABORT 0x1000 -#define PCIM_STATUS_RMABORT 0x2000 -#define PCIM_STATUS_SERR 0x4000 -#define PCIM_STATUS_PERR 0x8000 -#define PCIR_REVID 0x08 -#define PCIR_PROGIF 0x09 -#define PCIR_SUBCLASS 0x0a -#define PCIR_CLASS 0x0b -#define PCIR_CACHELNSZ 0x0c -#define PCIR_LATTIMER 0x0d -#define PCIR_HDRTYPE 0x0e -#define PCIM_HDRTYPE 0x7f -#define PCIM_HDRTYPE_NORMAL 0x00 -#define PCIM_HDRTYPE_BRIDGE 0x01 -#define PCIM_HDRTYPE_CARDBUS 0x02 -#define PCIM_MFDEV 0x80 -#define PCIR_BIST 0x0f - -/* Capability Register Offsets */ - -#define PCICAP_ID 0x0 -#define PCICAP_NEXTPTR 0x1 - -/* Capability Identification Numbers */ - -#define PCIY_PMG 0x01 /* PCI Power Management */ -#define PCIY_AGP 0x02 /* AGP */ -#define PCIY_VPD 0x03 /* Vital Product Data */ -#define PCIY_SLOTID 0x04 /* Slot Identification */ -#define PCIY_MSI 0x05 /* Message Signaled Interrupts */ -#define PCIY_CHSWP 0x06 /* CompactPCI Hot Swap */ -#define PCIY_PCIX 0x07 /* PCI-X */ -#define PCIY_HT 0x08 /* HyperTransport */ -#define PCIY_VENDOR 0x09 /* Vendor Unique */ -#define PCIY_DEBUG 0x0a /* Debug port */ -#define PCIY_CRES 0x0b /* CompactPCI central resource control */ -#define PCIY_HOTPLUG 0x0c /* PCI Hot-Plug */ -#define PCIY_SUBVENDOR 0x0d /* PCI-PCI bridge subvendor ID */ -#define PCIY_AGP8X 0x0e /* AGP 8x */ -#define PCIY_SECDEV 0x0f /* Secure Device */ -#define PCIY_EXPRESS 0x10 /* PCI Express */ -#define PCIY_MSIX 0x11 /* MSI-X */ -#define PCIY_SATA 0x12 /* SATA */ -#define PCIY_PCIAF 0x13 /* PCI Advanced Features */ - -/* Extended Capability Register Fields */ - -#define PCIR_EXTCAP 0x100 -#define PCIM_EXTCAP_ID 0x0000ffff -#define PCIM_EXTCAP_VER 0x000f0000 -#define PCIM_EXTCAP_NEXTPTR 0xfff00000 -#define PCI_EXTCAP_ID(ecap) ((ecap) & PCIM_EXTCAP_ID) -#define PCI_EXTCAP_VER(ecap) (((ecap) & PCIM_EXTCAP_VER) >> 16) -#define PCI_EXTCAP_NEXTPTR(ecap) (((ecap) & PCIM_EXTCAP_NEXTPTR) >> 20) - -/* Extended Capability Identification Numbers */ - -#define PCIZ_AER 0x0001 /* Advanced Error Reporting */ -#define PCIZ_VC 0x0002 /* Virtual Channel */ -#define PCIZ_SERNUM 0x0003 /* Device Serial Number */ -#define PCIZ_PWRBDGT 0x0004 /* Power Budgeting */ -#define PCIZ_RCLINK_DCL 0x0005 /* Root Complex Link Declaration */ -#define PCIZ_RCLINK_CTL 0x0006 /* Root Complex Internal Link Control */ -#define PCIZ_RCEC_ASSOC 0x0007 /* Root Complex Event Collector Association */ -#define PCIZ_MFVC 0x0008 /* Multi-Function Virtual Channel */ -#define PCIZ_RCRB 0x000a /* RCRB Header */ -#define PCIZ_VENDOR 0x000b /* Vendor Unique */ -#define PCIZ_ACS 0x000d /* Access Control Services */ -#define PCIZ_ARI 0x000e /* Alternative Routing-ID Interpretation */ -#define PCIZ_ATS 0x000f /* Address Translation Services */ -#define PCIZ_SRIOV 0x0010 /* Single Root IO Virtualization */ -#define PCIZ_MULTICAST 0x0012 /* Multicast */ -#define PCIZ_RESIZE_BAR 0x0015 /* Resizable BAR */ -#define PCIZ_DPA 0x0016 /* Dynamic Power Allocation */ -#define PCIZ_TPH_REQ 0x0017 /* TPH Requester */ -#define PCIZ_LTR 0x0018 /* Latency Tolerance Reporting */ -#define PCIZ_SEC_PCIE 0x0019 /* Secondary PCI Express */ - -/* config registers for header type 0 devices */ - -#define PCIR_BARS 0x10 -#define PCIR_BAR(x) (PCIR_BARS + (x) * 4) -#define PCIR_MAX_BAR_0 5 -#define PCI_RID2BAR(rid) (((rid) - PCIR_BARS) / 4) -#define PCI_BAR_IO(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_IO_SPACE) -#define PCI_BAR_MEM(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_MEM_SPACE) -#define PCIM_BAR_SPACE 0x00000001 -#define PCIM_BAR_MEM_SPACE 0 -#define PCIM_BAR_IO_SPACE 1 -#define PCIM_BAR_MEM_TYPE 0x00000006 -#define PCIM_BAR_MEM_32 0 -#define PCIM_BAR_MEM_1MB 2 /* Locate below 1MB in PCI <= 2.1 */ -#define PCIM_BAR_MEM_64 4 -#define PCIM_BAR_MEM_PREFETCH 0x00000008 -#define PCIM_BAR_MEM_BASE 0xfffffffffffffff0ULL -#define PCIM_BAR_IO_RESERVED 0x00000002 -#define PCIM_BAR_IO_BASE 0xfffffffc -#define PCIR_CIS 0x28 -#define PCIM_CIS_ASI_MASK 0x00000007 -#define PCIM_CIS_ASI_CONFIG 0 -#define PCIM_CIS_ASI_BAR0 1 -#define PCIM_CIS_ASI_BAR1 2 -#define PCIM_CIS_ASI_BAR2 3 -#define PCIM_CIS_ASI_BAR3 4 -#define PCIM_CIS_ASI_BAR4 5 -#define PCIM_CIS_ASI_BAR5 6 -#define PCIM_CIS_ASI_ROM 7 -#define PCIM_CIS_ADDR_MASK 0x0ffffff8 -#define PCIM_CIS_ROM_MASK 0xf0000000 -#define PCIM_CIS_CONFIG_MASK 0xff -#define PCIR_SUBVEND_0 0x2c -#define PCIR_SUBDEV_0 0x2e -#define PCIR_BIOS 0x30 -#define PCIM_BIOS_ENABLE 0x01 -#define PCIM_BIOS_ADDR_MASK 0xfffff800 -#define PCIR_CAP_PTR 0x34 -#define PCIR_INTLINE 0x3c -#define PCIR_INTPIN 0x3d -#define PCIR_MINGNT 0x3e -#define PCIR_MAXLAT 0x3f - -/* config registers for header type 1 (PCI-to-PCI bridge) devices */ - -#define PCIR_MAX_BAR_1 1 -#define PCIR_SECSTAT_1 0x1e - -#define PCIR_PRIBUS_1 0x18 -#define PCIR_SECBUS_1 0x19 -#define PCIR_SUBBUS_1 0x1a -#define PCIR_SECLAT_1 0x1b - -#define PCIR_IOBASEL_1 0x1c -#define PCIR_IOLIMITL_1 0x1d -#define PCIR_IOBASEH_1 0x30 -#define PCIR_IOLIMITH_1 0x32 -#define PCIM_BRIO_16 0x0 -#define PCIM_BRIO_32 0x1 -#define PCIM_BRIO_MASK 0xf - -#define PCIR_MEMBASE_1 0x20 -#define PCIR_MEMLIMIT_1 0x22 - -#define PCIR_PMBASEL_1 0x24 -#define PCIR_PMLIMITL_1 0x26 -#define PCIR_PMBASEH_1 0x28 -#define PCIR_PMLIMITH_1 0x2c -#define PCIM_BRPM_32 0x0 -#define PCIM_BRPM_64 0x1 -#define PCIM_BRPM_MASK 0xf - -#define PCIR_BIOS_1 0x38 -#define PCIR_BRIDGECTL_1 0x3e - -/* config registers for header type 2 (CardBus) devices */ - -#define PCIR_MAX_BAR_2 0 -#define PCIR_CAP_PTR_2 0x14 -#define PCIR_SECSTAT_2 0x16 - -#define PCIR_PRIBUS_2 0x18 -#define PCIR_SECBUS_2 0x19 -#define PCIR_SUBBUS_2 0x1a -#define PCIR_SECLAT_2 0x1b - -#define PCIR_MEMBASE0_2 0x1c -#define PCIR_MEMLIMIT0_2 0x20 -#define PCIR_MEMBASE1_2 0x24 -#define PCIR_MEMLIMIT1_2 0x28 -#define PCIR_IOBASE0_2 0x2c -#define PCIR_IOLIMIT0_2 0x30 -#define PCIR_IOBASE1_2 0x34 -#define PCIR_IOLIMIT1_2 0x38 - -#define PCIR_BRIDGECTL_2 0x3e - -#define PCIR_SUBVEND_2 0x40 -#define PCIR_SUBDEV_2 0x42 - -#define PCIR_PCCARDIF_2 0x44 - -/* PCI device class, subclass and programming interface definitions */ - -#define PCIC_OLD 0x00 -#define PCIS_OLD_NONVGA 0x00 -#define PCIS_OLD_VGA 0x01 - -#define PCIC_STORAGE 0x01 -#define PCIS_STORAGE_SCSI 0x00 -#define PCIS_STORAGE_IDE 0x01 -#define PCIP_STORAGE_IDE_MODEPRIM 0x01 -#define PCIP_STORAGE_IDE_PROGINDPRIM 0x02 -#define PCIP_STORAGE_IDE_MODESEC 0x04 -#define PCIP_STORAGE_IDE_PROGINDSEC 0x08 -#define PCIP_STORAGE_IDE_MASTERDEV 0x80 -#define PCIS_STORAGE_FLOPPY 0x02 -#define PCIS_STORAGE_IPI 0x03 -#define PCIS_STORAGE_RAID 0x04 -#define PCIS_STORAGE_ATA_ADMA 0x05 -#define PCIS_STORAGE_SATA 0x06 -#define PCIP_STORAGE_SATA_AHCI_1_0 0x01 -#define PCIS_STORAGE_SAS 0x07 -#define PCIS_STORAGE_NVM 0x08 -#define PCIP_STORAGE_NVM_NVMHCI_1_0 0x01 -#define PCIP_STORAGE_NVM_ENTERPRISE_NVMHCI_1_0 0x02 -#define PCIS_STORAGE_OTHER 0x80 - -#define PCIC_NETWORK 0x02 -#define PCIS_NETWORK_ETHERNET 0x00 -#define PCIS_NETWORK_TOKENRING 0x01 -#define PCIS_NETWORK_FDDI 0x02 -#define PCIS_NETWORK_ATM 0x03 -#define PCIS_NETWORK_ISDN 0x04 -#define PCIS_NETWORK_WORLDFIP 0x05 -#define PCIS_NETWORK_PICMG 0x06 -#define PCIS_NETWORK_OTHER 0x80 - -#define PCIC_DISPLAY 0x03 -#define PCIS_DISPLAY_VGA 0x00 -#define PCIS_DISPLAY_XGA 0x01 -#define PCIS_DISPLAY_3D 0x02 -#define PCIS_DISPLAY_OTHER 0x80 - -#define PCIC_MULTIMEDIA 0x04 -#define PCIS_MULTIMEDIA_VIDEO 0x00 -#define PCIS_MULTIMEDIA_AUDIO 0x01 -#define PCIS_MULTIMEDIA_TELE 0x02 -#define PCIS_MULTIMEDIA_HDA 0x03 -#define PCIS_MULTIMEDIA_OTHER 0x80 - -#define PCIC_MEMORY 0x05 -#define PCIS_MEMORY_RAM 0x00 -#define PCIS_MEMORY_FLASH 0x01 -#define PCIS_MEMORY_OTHER 0x80 - -#define PCIC_BRIDGE 0x06 -#define PCIS_BRIDGE_HOST 0x00 -#define PCIS_BRIDGE_ISA 0x01 -#define PCIS_BRIDGE_EISA 0x02 -#define PCIS_BRIDGE_MCA 0x03 -#define PCIS_BRIDGE_PCI 0x04 -#define PCIP_BRIDGE_PCI_SUBTRACTIVE 0x01 -#define PCIS_BRIDGE_PCMCIA 0x05 -#define PCIS_BRIDGE_NUBUS 0x06 -#define PCIS_BRIDGE_CARDBUS 0x07 -#define PCIS_BRIDGE_RACEWAY 0x08 -#define PCIS_BRIDGE_PCI_TRANSPARENT 0x09 -#define PCIS_BRIDGE_INFINIBAND 0x0a -#define PCIS_BRIDGE_OTHER 0x80 - -#define PCIC_SIMPLECOMM 0x07 -#define PCIS_SIMPLECOMM_UART 0x00 -#define PCIP_SIMPLECOMM_UART_8250 0x00 -#define PCIP_SIMPLECOMM_UART_16450A 0x01 -#define PCIP_SIMPLECOMM_UART_16550A 0x02 -#define PCIP_SIMPLECOMM_UART_16650A 0x03 -#define PCIP_SIMPLECOMM_UART_16750A 0x04 -#define PCIP_SIMPLECOMM_UART_16850A 0x05 -#define PCIP_SIMPLECOMM_UART_16950A 0x06 -#define PCIS_SIMPLECOMM_PAR 0x01 -#define PCIS_SIMPLECOMM_MULSER 0x02 -#define PCIS_SIMPLECOMM_MODEM 0x03 -#define PCIS_SIMPLECOMM_GPIB 0x04 -#define PCIS_SIMPLECOMM_SMART_CARD 0x05 -#define PCIS_SIMPLECOMM_OTHER 0x80 - -#define PCIC_BASEPERIPH 0x08 -#define PCIS_BASEPERIPH_PIC 0x00 -#define PCIP_BASEPERIPH_PIC_8259A 0x00 -#define PCIP_BASEPERIPH_PIC_ISA 0x01 -#define PCIP_BASEPERIPH_PIC_EISA 0x02 -#define PCIP_BASEPERIPH_PIC_IO_APIC 0x10 -#define PCIP_BASEPERIPH_PIC_IOX_APIC 0x20 -#define PCIS_BASEPERIPH_DMA 0x01 -#define PCIS_BASEPERIPH_TIMER 0x02 -#define PCIS_BASEPERIPH_RTC 0x03 -#define PCIS_BASEPERIPH_PCIHOT 0x04 -#define PCIS_BASEPERIPH_SDHC 0x05 -#define PCIS_BASEPERIPH_OTHER 0x80 - -#define PCIC_INPUTDEV 0x09 -#define PCIS_INPUTDEV_KEYBOARD 0x00 -#define PCIS_INPUTDEV_DIGITIZER 0x01 -#define PCIS_INPUTDEV_MOUSE 0x02 -#define PCIS_INPUTDEV_SCANNER 0x03 -#define PCIS_INPUTDEV_GAMEPORT 0x04 -#define PCIS_INPUTDEV_OTHER 0x80 - -#define PCIC_DOCKING 0x0a -#define PCIS_DOCKING_GENERIC 0x00 -#define PCIS_DOCKING_OTHER 0x80 - -#define PCIC_PROCESSOR 0x0b -#define PCIS_PROCESSOR_386 0x00 -#define PCIS_PROCESSOR_486 0x01 -#define PCIS_PROCESSOR_PENTIUM 0x02 -#define PCIS_PROCESSOR_ALPHA 0x10 -#define PCIS_PROCESSOR_POWERPC 0x20 -#define PCIS_PROCESSOR_MIPS 0x30 -#define PCIS_PROCESSOR_COPROC 0x40 - -#define PCIC_SERIALBUS 0x0c -#define PCIS_SERIALBUS_FW 0x00 -#define PCIS_SERIALBUS_ACCESS 0x01 -#define PCIS_SERIALBUS_SSA 0x02 -#define PCIS_SERIALBUS_USB 0x03 -#define PCIP_SERIALBUS_USB_UHCI 0x00 -#define PCIP_SERIALBUS_USB_OHCI 0x10 -#define PCIP_SERIALBUS_USB_EHCI 0x20 -#define PCIP_SERIALBUS_USB_XHCI 0x30 -#define PCIP_SERIALBUS_USB_DEVICE 0xfe -#define PCIS_SERIALBUS_FC 0x04 -#define PCIS_SERIALBUS_SMBUS 0x05 -#define PCIS_SERIALBUS_INFINIBAND 0x06 -#define PCIS_SERIALBUS_IPMI 0x07 -#define PCIP_SERIALBUS_IPMI_SMIC 0x00 -#define PCIP_SERIALBUS_IPMI_KCS 0x01 -#define PCIP_SERIALBUS_IPMI_BT 0x02 -#define PCIS_SERIALBUS_SERCOS 0x08 -#define PCIS_SERIALBUS_CANBUS 0x09 - -#define PCIC_WIRELESS 0x0d -#define PCIS_WIRELESS_IRDA 0x00 -#define PCIS_WIRELESS_IR 0x01 -#define PCIS_WIRELESS_RF 0x10 -#define PCIS_WIRELESS_BLUETOOTH 0x11 -#define PCIS_WIRELESS_BROADBAND 0x12 -#define PCIS_WIRELESS_80211A 0x20 -#define PCIS_WIRELESS_80211B 0x21 -#define PCIS_WIRELESS_OTHER 0x80 - -#define PCIC_INTELLIIO 0x0e -#define PCIS_INTELLIIO_I2O 0x00 - -#define PCIC_SATCOM 0x0f -#define PCIS_SATCOM_TV 0x01 -#define PCIS_SATCOM_AUDIO 0x02 -#define PCIS_SATCOM_VOICE 0x03 -#define PCIS_SATCOM_DATA 0x04 - -#define PCIC_CRYPTO 0x10 -#define PCIS_CRYPTO_NETCOMP 0x00 -#define PCIS_CRYPTO_ENTERTAIN 0x10 -#define PCIS_CRYPTO_OTHER 0x80 - -#define PCIC_DASP 0x11 -#define PCIS_DASP_DPIO 0x00 -#define PCIS_DASP_PERFCNTRS 0x01 -#define PCIS_DASP_COMM_SYNC 0x10 -#define PCIS_DASP_MGMT_CARD 0x20 -#define PCIS_DASP_OTHER 0x80 - -#define PCIC_OTHER 0xff - -/* Bridge Control Values. */ -#define PCIB_BCR_PERR_ENABLE 0x0001 -#define PCIB_BCR_SERR_ENABLE 0x0002 -#define PCIB_BCR_ISA_ENABLE 0x0004 -#define PCIB_BCR_VGA_ENABLE 0x0008 -#define PCIB_BCR_MASTER_ABORT_MODE 0x0020 -#define PCIB_BCR_SECBUS_RESET 0x0040 -#define PCIB_BCR_SECBUS_BACKTOBACK 0x0080 -#define PCIB_BCR_PRI_DISCARD_TIMEOUT 0x0100 -#define PCIB_BCR_SEC_DISCARD_TIMEOUT 0x0200 -#define PCIB_BCR_DISCARD_TIMER_STATUS 0x0400 -#define PCIB_BCR_DISCARD_TIMER_SERREN 0x0800 - -/* PCI power manangement */ -#define PCIR_POWER_CAP 0x2 -#define PCIM_PCAP_SPEC 0x0007 -#define PCIM_PCAP_PMEREQCLK 0x0008 -#define PCIM_PCAP_DEVSPECINIT 0x0020 -#define PCIM_PCAP_AUXPWR_0 0x0000 -#define PCIM_PCAP_AUXPWR_55 0x0040 -#define PCIM_PCAP_AUXPWR_100 0x0080 -#define PCIM_PCAP_AUXPWR_160 0x00c0 -#define PCIM_PCAP_AUXPWR_220 0x0100 -#define PCIM_PCAP_AUXPWR_270 0x0140 -#define PCIM_PCAP_AUXPWR_320 0x0180 -#define PCIM_PCAP_AUXPWR_375 0x01c0 -#define PCIM_PCAP_AUXPWRMASK 0x01c0 -#define PCIM_PCAP_D1SUPP 0x0200 -#define PCIM_PCAP_D2SUPP 0x0400 -#define PCIM_PCAP_D0PME 0x0800 -#define PCIM_PCAP_D1PME 0x1000 -#define PCIM_PCAP_D2PME 0x2000 -#define PCIM_PCAP_D3PME_HOT 0x4000 -#define PCIM_PCAP_D3PME_COLD 0x8000 - -#define PCIR_POWER_STATUS 0x4 -#define PCIM_PSTAT_D0 0x0000 -#define PCIM_PSTAT_D1 0x0001 -#define PCIM_PSTAT_D2 0x0002 -#define PCIM_PSTAT_D3 0x0003 -#define PCIM_PSTAT_DMASK 0x0003 -#define PCIM_PSTAT_NOSOFTRESET 0x0008 -#define PCIM_PSTAT_PMEENABLE 0x0100 -#define PCIM_PSTAT_D0POWER 0x0000 -#define PCIM_PSTAT_D1POWER 0x0200 -#define PCIM_PSTAT_D2POWER 0x0400 -#define PCIM_PSTAT_D3POWER 0x0600 -#define PCIM_PSTAT_D0HEAT 0x0800 -#define PCIM_PSTAT_D1HEAT 0x0a00 -#define PCIM_PSTAT_D2HEAT 0x0c00 -#define PCIM_PSTAT_D3HEAT 0x0e00 -#define PCIM_PSTAT_DATASELMASK 0x1e00 -#define PCIM_PSTAT_DATAUNKN 0x0000 -#define PCIM_PSTAT_DATADIV10 0x2000 -#define PCIM_PSTAT_DATADIV100 0x4000 -#define PCIM_PSTAT_DATADIV1000 0x6000 -#define PCIM_PSTAT_DATADIVMASK 0x6000 -#define PCIM_PSTAT_PME 0x8000 - -#define PCIR_POWER_BSE 0x6 -#define PCIM_PMCSR_BSE_D3B3 0x00 -#define PCIM_PMCSR_BSE_D3B2 0x40 -#define PCIM_PMCSR_BSE_BPCCE 0x80 - -#define PCIR_POWER_DATA 0x7 - -/* VPD capability registers */ -#define PCIR_VPD_ADDR 0x2 -#define PCIR_VPD_DATA 0x4 - -/* PCI Message Signalled Interrupts (MSI) */ -#define PCIR_MSI_CTRL 0x2 -#define PCIM_MSICTRL_VECTOR 0x0100 -#define PCIM_MSICTRL_64BIT 0x0080 -#define PCIM_MSICTRL_MME_MASK 0x0070 -#define PCIM_MSICTRL_MME_1 0x0000 -#define PCIM_MSICTRL_MME_2 0x0010 -#define PCIM_MSICTRL_MME_4 0x0020 -#define PCIM_MSICTRL_MME_8 0x0030 -#define PCIM_MSICTRL_MME_16 0x0040 -#define PCIM_MSICTRL_MME_32 0x0050 -#define PCIM_MSICTRL_MMC_MASK 0x000E -#define PCIM_MSICTRL_MMC_1 0x0000 -#define PCIM_MSICTRL_MMC_2 0x0002 -#define PCIM_MSICTRL_MMC_4 0x0004 -#define PCIM_MSICTRL_MMC_8 0x0006 -#define PCIM_MSICTRL_MMC_16 0x0008 -#define PCIM_MSICTRL_MMC_32 0x000A -#define PCIM_MSICTRL_MSI_ENABLE 0x0001 -#define PCIR_MSI_ADDR 0x4 -#define PCIR_MSI_ADDR_HIGH 0x8 -#define PCIR_MSI_DATA 0x8 -#define PCIR_MSI_DATA_64BIT 0xc -#define PCIR_MSI_MASK 0x10 -#define PCIR_MSI_PENDING 0x14 - -/* PCI-X definitions */ - -/* For header type 0 devices */ -#define PCIXR_COMMAND 0x2 -#define PCIXM_COMMAND_DPERR_E 0x0001 /* Data Parity Error Recovery */ -#define PCIXM_COMMAND_ERO 0x0002 /* Enable Relaxed Ordering */ -#define PCIXM_COMMAND_MAX_READ 0x000c /* Maximum Burst Read Count */ -#define PCIXM_COMMAND_MAX_READ_512 0x0000 -#define PCIXM_COMMAND_MAX_READ_1024 0x0004 -#define PCIXM_COMMAND_MAX_READ_2048 0x0008 -#define PCIXM_COMMAND_MAX_READ_4096 0x000c -#define PCIXM_COMMAND_MAX_SPLITS 0x0070 /* Maximum Split Transactions */ -#define PCIXM_COMMAND_MAX_SPLITS_1 0x0000 -#define PCIXM_COMMAND_MAX_SPLITS_2 0x0010 -#define PCIXM_COMMAND_MAX_SPLITS_3 0x0020 -#define PCIXM_COMMAND_MAX_SPLITS_4 0x0030 -#define PCIXM_COMMAND_MAX_SPLITS_8 0x0040 -#define PCIXM_COMMAND_MAX_SPLITS_12 0x0050 -#define PCIXM_COMMAND_MAX_SPLITS_16 0x0060 -#define PCIXM_COMMAND_MAX_SPLITS_32 0x0070 -#define PCIXM_COMMAND_VERSION 0x3000 -#define PCIXR_STATUS 0x4 -#define PCIXM_STATUS_DEVFN 0x000000FF -#define PCIXM_STATUS_BUS 0x0000FF00 -#define PCIXM_STATUS_64BIT 0x00010000 -#define PCIXM_STATUS_133CAP 0x00020000 -#define PCIXM_STATUS_SC_DISCARDED 0x00040000 -#define PCIXM_STATUS_UNEXP_SC 0x00080000 -#define PCIXM_STATUS_COMPLEX_DEV 0x00100000 -#define PCIXM_STATUS_MAX_READ 0x00600000 -#define PCIXM_STATUS_MAX_READ_512 0x00000000 -#define PCIXM_STATUS_MAX_READ_1024 0x00200000 -#define PCIXM_STATUS_MAX_READ_2048 0x00400000 -#define PCIXM_STATUS_MAX_READ_4096 0x00600000 -#define PCIXM_STATUS_MAX_SPLITS 0x03800000 -#define PCIXM_STATUS_MAX_SPLITS_1 0x00000000 -#define PCIXM_STATUS_MAX_SPLITS_2 0x00800000 -#define PCIXM_STATUS_MAX_SPLITS_3 0x01000000 -#define PCIXM_STATUS_MAX_SPLITS_4 0x01800000 -#define PCIXM_STATUS_MAX_SPLITS_8 0x02000000 -#define PCIXM_STATUS_MAX_SPLITS_12 0x02800000 -#define PCIXM_STATUS_MAX_SPLITS_16 0x03000000 -#define PCIXM_STATUS_MAX_SPLITS_32 0x03800000 -#define PCIXM_STATUS_MAX_CUM_READ 0x1C000000 -#define PCIXM_STATUS_RCVD_SC_ERR 0x20000000 -#define PCIXM_STATUS_266CAP 0x40000000 -#define PCIXM_STATUS_533CAP 0x80000000 - -/* For header type 1 devices (PCI-X bridges) */ -#define PCIXR_SEC_STATUS 0x2 -#define PCIXM_SEC_STATUS_64BIT 0x0001 -#define PCIXM_SEC_STATUS_133CAP 0x0002 -#define PCIXM_SEC_STATUS_SC_DISC 0x0004 -#define PCIXM_SEC_STATUS_UNEXP_SC 0x0008 -#define PCIXM_SEC_STATUS_SC_OVERRUN 0x0010 -#define PCIXM_SEC_STATUS_SR_DELAYED 0x0020 -#define PCIXM_SEC_STATUS_BUS_MODE 0x03c0 -#define PCIXM_SEC_STATUS_VERSION 0x3000 -#define PCIXM_SEC_STATUS_266CAP 0x4000 -#define PCIXM_SEC_STATUS_533CAP 0x8000 -#define PCIXR_BRIDGE_STATUS 0x4 -#define PCIXM_BRIDGE_STATUS_DEVFN 0x000000FF -#define PCIXM_BRIDGE_STATUS_BUS 0x0000FF00 -#define PCIXM_BRIDGE_STATUS_64BIT 0x00010000 -#define PCIXM_BRIDGE_STATUS_133CAP 0x00020000 -#define PCIXM_BRIDGE_STATUS_SC_DISCARDED 0x00040000 -#define PCIXM_BRIDGE_STATUS_UNEXP_SC 0x00080000 -#define PCIXM_BRIDGE_STATUS_SC_OVERRUN 0x00100000 -#define PCIXM_BRIDGE_STATUS_SR_DELAYED 0x00200000 -#define PCIXM_BRIDGE_STATUS_DEVID_MSGCAP 0x20000000 -#define PCIXM_BRIDGE_STATUS_266CAP 0x40000000 -#define PCIXM_BRIDGE_STATUS_533CAP 0x80000000 - -/* HT (HyperTransport) Capability definitions */ -#define PCIR_HT_COMMAND 0x2 -#define PCIM_HTCMD_CAP_MASK 0xf800 /* Capability type. */ -#define PCIM_HTCAP_SLAVE 0x0000 /* 000xx */ -#define PCIM_HTCAP_HOST 0x2000 /* 001xx */ -#define PCIM_HTCAP_SWITCH 0x4000 /* 01000 */ -#define PCIM_HTCAP_INTERRUPT 0x8000 /* 10000 */ -#define PCIM_HTCAP_REVISION_ID 0x8800 /* 10001 */ -#define PCIM_HTCAP_UNITID_CLUMPING 0x9000 /* 10010 */ -#define PCIM_HTCAP_EXT_CONFIG_SPACE 0x9800 /* 10011 */ -#define PCIM_HTCAP_ADDRESS_MAPPING 0xa000 /* 10100 */ -#define PCIM_HTCAP_MSI_MAPPING 0xa800 /* 10101 */ -#define PCIM_HTCAP_DIRECT_ROUTE 0xb000 /* 10110 */ -#define PCIM_HTCAP_VCSET 0xb800 /* 10111 */ -#define PCIM_HTCAP_RETRY_MODE 0xc000 /* 11000 */ -#define PCIM_HTCAP_X86_ENCODING 0xc800 /* 11001 */ -#define PCIM_HTCAP_GEN3 0xd000 /* 11010 */ -#define PCIM_HTCAP_FLE 0xd800 /* 11011 */ -#define PCIM_HTCAP_PM 0xe000 /* 11100 */ -#define PCIM_HTCAP_HIGH_NODE_COUNT 0xe800 /* 11101 */ - -/* HT MSI Mapping Capability definitions. */ -#define PCIM_HTCMD_MSI_ENABLE 0x0001 -#define PCIM_HTCMD_MSI_FIXED 0x0002 -#define PCIR_HTMSI_ADDRESS_LO 0x4 -#define PCIR_HTMSI_ADDRESS_HI 0x8 - -/* PCI Vendor capability definitions */ -#define PCIR_VENDOR_LENGTH 0x2 -#define PCIR_VENDOR_DATA 0x3 - -/* PCI EHCI Debug Port definitions */ -#define PCIR_DEBUG_PORT 0x2 -#define PCIM_DEBUG_PORT_OFFSET 0x1FFF -#define PCIM_DEBUG_PORT_BAR 0xe000 - -/* PCI-PCI Bridge Subvendor definitions */ -#define PCIR_SUBVENDCAP_ID 0x4 - -/* PCI Express definitions */ -#define PCIER_FLAGS 0x2 -#define PCIEM_FLAGS_VERSION 0x000F -#define PCIEM_FLAGS_TYPE 0x00F0 -#define PCIEM_TYPE_ENDPOINT 0x0000 -#define PCIEM_TYPE_LEGACY_ENDPOINT 0x0010 -#define PCIEM_TYPE_ROOT_PORT 0x0040 -#define PCIEM_TYPE_UPSTREAM_PORT 0x0050 -#define PCIEM_TYPE_DOWNSTREAM_PORT 0x0060 -#define PCIEM_TYPE_PCI_BRIDGE 0x0070 -#define PCIEM_TYPE_PCIE_BRIDGE 0x0080 -#define PCIEM_TYPE_ROOT_INT_EP 0x0090 -#define PCIEM_TYPE_ROOT_EC 0x00a0 -#define PCIEM_FLAGS_SLOT 0x0100 -#define PCIEM_FLAGS_IRQ 0x3e00 -#define PCIER_DEVICE_CAP 0x4 -#define PCIEM_CAP_MAX_PAYLOAD 0x00000007 -#define PCIEM_CAP_PHANTHOM_FUNCS 0x00000018 -#define PCIEM_CAP_EXT_TAG_FIELD 0x00000020 -#define PCIEM_CAP_L0S_LATENCY 0x000001c0 -#define PCIEM_CAP_L1_LATENCY 0x00000e00 -#define PCIEM_CAP_ROLE_ERR_RPT 0x00008000 -#define PCIEM_CAP_SLOT_PWR_LIM_VAL 0x03fc0000 -#define PCIEM_CAP_SLOT_PWR_LIM_SCALE 0x0c000000 -#define PCIEM_CAP_FLR 0x10000000 -#define PCIER_DEVICE_CTL 0x8 -#define PCIEM_CTL_COR_ENABLE 0x0001 -#define PCIEM_CTL_NFER_ENABLE 0x0002 -#define PCIEM_CTL_FER_ENABLE 0x0004 -#define PCIEM_CTL_URR_ENABLE 0x0008 -#define PCIEM_CTL_RELAXED_ORD_ENABLE 0x0010 -#define PCIEM_CTL_MAX_PAYLOAD 0x00e0 -#define PCIEM_CTL_EXT_TAG_FIELD 0x0100 -#define PCIEM_CTL_PHANTHOM_FUNCS 0x0200 -#define PCIEM_CTL_AUX_POWER_PM 0x0400 -#define PCIEM_CTL_NOSNOOP_ENABLE 0x0800 -#define PCIEM_CTL_MAX_READ_REQUEST 0x7000 -#define PCIEM_CTL_BRDG_CFG_RETRY 0x8000 /* PCI-E - PCI/PCI-X bridges */ -#define PCIEM_CTL_INITIATE_FLR 0x8000 /* FLR capable endpoints */ -#define PCIER_DEVICE_STA 0xa -#define PCIEM_STA_CORRECTABLE_ERROR 0x0001 -#define PCIEM_STA_NON_FATAL_ERROR 0x0002 -#define PCIEM_STA_FATAL_ERROR 0x0004 -#define PCIEM_STA_UNSUPPORTED_REQ 0x0008 -#define PCIEM_STA_AUX_POWER 0x0010 -#define PCIEM_STA_TRANSACTION_PND 0x0020 -#define PCIER_LINK_CAP 0xc -#define PCIEM_LINK_CAP_MAX_SPEED 0x0000000f -#define PCIEM_LINK_CAP_MAX_WIDTH 0x000003f0 -#define PCIEM_LINK_CAP_ASPM 0x00000c00 -#define PCIEM_LINK_CAP_L0S_EXIT 0x00007000 -#define PCIEM_LINK_CAP_L1_EXIT 0x00038000 -#define PCIEM_LINK_CAP_CLOCK_PM 0x00040000 -#define PCIEM_LINK_CAP_SURPRISE_DOWN 0x00080000 -#define PCIEM_LINK_CAP_DL_ACTIVE 0x00100000 -#define PCIEM_LINK_CAP_LINK_BW_NOTIFY 0x00200000 -#define PCIEM_LINK_CAP_ASPM_COMPLIANCE 0x00400000 -#define PCIEM_LINK_CAP_PORT 0xff000000 -#define PCIER_LINK_CTL 0x10 -#define PCIEM_LINK_CTL_ASPMC_DIS 0x0000 -#define PCIEM_LINK_CTL_ASPMC_L0S 0x0001 -#define PCIEM_LINK_CTL_ASPMC_L1 0x0002 -#define PCIEM_LINK_CTL_ASPMC 0x0003 -#define PCIEM_LINK_CTL_RCB 0x0008 -#define PCIEM_LINK_CTL_LINK_DIS 0x0010 -#define PCIEM_LINK_CTL_RETRAIN_LINK 0x0020 -#define PCIEM_LINK_CTL_COMMON_CLOCK 0x0040 -#define PCIEM_LINK_CTL_EXTENDED_SYNC 0x0080 -#define PCIEM_LINK_CTL_ECPM 0x0100 -#define PCIEM_LINK_CTL_HAWD 0x0200 -#define PCIEM_LINK_CTL_LBMIE 0x0400 -#define PCIEM_LINK_CTL_LABIE 0x0800 -#define PCIER_LINK_STA 0x12 -#define PCIEM_LINK_STA_SPEED 0x000f -#define PCIEM_LINK_STA_WIDTH 0x03f0 -#define PCIEM_LINK_STA_TRAINING_ERROR 0x0400 -#define PCIEM_LINK_STA_TRAINING 0x0800 -#define PCIEM_LINK_STA_SLOT_CLOCK 0x1000 -#define PCIEM_LINK_STA_DL_ACTIVE 0x2000 -#define PCIEM_LINK_STA_LINK_BW_MGMT 0x4000 -#define PCIEM_LINK_STA_LINK_AUTO_BW 0x8000 -#define PCIER_SLOT_CAP 0x14 -#define PCIEM_SLOT_CAP_APB 0x00000001 -#define PCIEM_SLOT_CAP_PCP 0x00000002 -#define PCIEM_SLOT_CAP_MRLSP 0x00000004 -#define PCIEM_SLOT_CAP_AIP 0x00000008 -#define PCIEM_SLOT_CAP_PIP 0x00000010 -#define PCIEM_SLOT_CAP_HPS 0x00000020 -#define PCIEM_SLOT_CAP_HPC 0x00000040 -#define PCIEM_SLOT_CAP_SPLV 0x00007f80 -#define PCIEM_SLOT_CAP_SPLS 0x00018000 -#define PCIEM_SLOT_CAP_EIP 0x00020000 -#define PCIEM_SLOT_CAP_NCCS 0x00040000 -#define PCIEM_SLOT_CAP_PSN 0xfff80000 -#define PCIER_SLOT_CTL 0x18 -#define PCIEM_SLOT_CTL_ABPE 0x0001 -#define PCIEM_SLOT_CTL_PFDE 0x0002 -#define PCIEM_SLOT_CTL_MRLSCE 0x0004 -#define PCIEM_SLOT_CTL_PDCE 0x0008 -#define PCIEM_SLOT_CTL_CCIE 0x0010 -#define PCIEM_SLOT_CTL_HPIE 0x0020 -#define PCIEM_SLOT_CTL_AIC 0x00c0 -#define PCIEM_SLOT_CTL_PIC 0x0300 -#define PCIEM_SLOT_CTL_PCC 0x0400 -#define PCIEM_SLOT_CTL_EIC 0x0800 -#define PCIEM_SLOT_CTL_DLLSCE 0x1000 -#define PCIER_SLOT_STA 0x1a -#define PCIEM_SLOT_STA_ABP 0x0001 -#define PCIEM_SLOT_STA_PFD 0x0002 -#define PCIEM_SLOT_STA_MRLSC 0x0004 -#define PCIEM_SLOT_STA_PDC 0x0008 -#define PCIEM_SLOT_STA_CC 0x0010 -#define PCIEM_SLOT_STA_MRLSS 0x0020 -#define PCIEM_SLOT_STA_PDS 0x0040 -#define PCIEM_SLOT_STA_EIS 0x0080 -#define PCIEM_SLOT_STA_DLLSC 0x0100 -#define PCIER_ROOT_CTL 0x1c -#define PCIER_ROOT_CAP 0x1e -#define PCIER_ROOT_STA 0x20 -#define PCIER_DEVICE_CAP2 0x24 -#define PCIER_DEVICE_CTL2 0x28 -#define PCIEM_CTL2_COMP_TIMEOUT_VAL 0x000f -#define PCIEM_CTL2_COMP_TIMEOUT_DIS 0x0010 -#define PCIEM_CTL2_ARI 0x0020 -#define PCIEM_CTL2_ATOMIC_REQ_ENABLE 0x0040 -#define PCIEM_CTL2_ATOMIC_EGR_BLOCK 0x0080 -#define PCIEM_CTL2_ID_ORDERED_REQ_EN 0x0100 -#define PCIEM_CTL2_ID_ORDERED_CMP_EN 0x0200 -#define PCIEM_CTL2_LTR_ENABLE 0x0400 -#define PCIEM_CTL2_OBFF 0x6000 -#define PCIEM_OBFF_DISABLE 0x0000 -#define PCIEM_OBFF_MSGA_ENABLE 0x2000 -#define PCIEM_OBFF_MSGB_ENABLE 0x4000 -#define PCIEM_OBFF_WAKE_ENABLE 0x6000 -#define PCIEM_CTL2_END2END_TLP 0x8000 -#define PCIER_DEVICE_STA2 0x2a -#define PCIER_LINK_CAP2 0x2c -#define PCIER_LINK_CTL2 0x30 -#define PCIER_LINK_STA2 0x32 -#define PCIER_SLOT_CAP2 0x34 -#define PCIER_SLOT_CTL2 0x38 -#define PCIER_SLOT_STA2 0x3a - -/* Old compatibility definitions for PCI Express registers */ -#define PCIR_EXPRESS_FLAGS PCIER_FLAGS -#define PCIM_EXP_FLAGS_VERSION PCIEM_FLAGS_VERSION -#define PCIM_EXP_FLAGS_TYPE PCIEM_FLAGS_TYPE -#define PCIM_EXP_TYPE_ENDPOINT PCIEM_TYPE_ENDPOINT -#define PCIM_EXP_TYPE_LEGACY_ENDPOINT PCIEM_TYPE_LEGACY_ENDPOINT -#define PCIM_EXP_TYPE_ROOT_PORT PCIEM_TYPE_ROOT_PORT -#define PCIM_EXP_TYPE_UPSTREAM_PORT PCIEM_TYPE_UPSTREAM_PORT -#define PCIM_EXP_TYPE_DOWNSTREAM_PORT PCIEM_TYPE_DOWNSTREAM_PORT -#define PCIM_EXP_TYPE_PCI_BRIDGE PCIEM_TYPE_PCI_BRIDGE -#define PCIM_EXP_TYPE_PCIE_BRIDGE PCIEM_TYPE_PCIE_BRIDGE -#define PCIM_EXP_TYPE_ROOT_INT_EP PCIEM_TYPE_ROOT_INT_EP -#define PCIM_EXP_TYPE_ROOT_EC PCIEM_TYPE_ROOT_EC -#define PCIM_EXP_FLAGS_SLOT PCIEM_FLAGS_SLOT -#define PCIM_EXP_FLAGS_IRQ PCIEM_FLAGS_IRQ -#define PCIR_EXPRESS_DEVICE_CAP PCIER_DEVICE_CAP -#define PCIM_EXP_CAP_MAX_PAYLOAD PCIEM_CAP_MAX_PAYLOAD -#define PCIM_EXP_CAP_PHANTHOM_FUNCS PCIEM_CAP_PHANTHOM_FUNCS -#define PCIM_EXP_CAP_EXT_TAG_FIELD PCIEM_CAP_EXT_TAG_FIELD -#define PCIM_EXP_CAP_L0S_LATENCY PCIEM_CAP_L0S_LATENCY -#define PCIM_EXP_CAP_L1_LATENCY PCIEM_CAP_L1_LATENCY -#define PCIM_EXP_CAP_ROLE_ERR_RPT PCIEM_CAP_ROLE_ERR_RPT -#define PCIM_EXP_CAP_SLOT_PWR_LIM_VAL PCIEM_CAP_SLOT_PWR_LIM_VAL -#define PCIM_EXP_CAP_SLOT_PWR_LIM_SCALE PCIEM_CAP_SLOT_PWR_LIM_SCALE -#define PCIM_EXP_CAP_FLR PCIEM_CAP_FLR -#define PCIR_EXPRESS_DEVICE_CTL PCIER_DEVICE_CTL -#define PCIM_EXP_CTL_COR_ENABLE PCIEM_CTL_COR_ENABLE -#define PCIM_EXP_CTL_NFER_ENABLE PCIEM_CTL_NFER_ENABLE -#define PCIM_EXP_CTL_FER_ENABLE PCIEM_CTL_FER_ENABLE -#define PCIM_EXP_CTL_URR_ENABLE PCIEM_CTL_URR_ENABLE -#define PCIM_EXP_CTL_RELAXED_ORD_ENABLE PCIEM_CTL_RELAXED_ORD_ENABLE -#define PCIM_EXP_CTL_MAX_PAYLOAD PCIEM_CTL_MAX_PAYLOAD -#define PCIM_EXP_CTL_EXT_TAG_FIELD PCIEM_CTL_EXT_TAG_FIELD -#define PCIM_EXP_CTL_PHANTHOM_FUNCS PCIEM_CTL_PHANTHOM_FUNCS -#define PCIM_EXP_CTL_AUX_POWER_PM PCIEM_CTL_AUX_POWER_PM -#define PCIM_EXP_CTL_NOSNOOP_ENABLE PCIEM_CTL_NOSNOOP_ENABLE -#define PCIM_EXP_CTL_MAX_READ_REQUEST PCIEM_CTL_MAX_READ_REQUEST -#define PCIM_EXP_CTL_BRDG_CFG_RETRY PCIEM_CTL_BRDG_CFG_RETRY -#define PCIM_EXP_CTL_INITIATE_FLR PCIEM_CTL_INITIATE_FLR -#define PCIR_EXPRESS_DEVICE_STA PCIER_DEVICE_STA -#define PCIM_EXP_STA_CORRECTABLE_ERROR PCIEM_STA_CORRECTABLE_ERROR -#define PCIM_EXP_STA_NON_FATAL_ERROR PCIEM_STA_NON_FATAL_ERROR -#define PCIM_EXP_STA_FATAL_ERROR PCIEM_STA_FATAL_ERROR -#define PCIM_EXP_STA_UNSUPPORTED_REQ PCIEM_STA_UNSUPPORTED_REQ -#define PCIM_EXP_STA_AUX_POWER PCIEM_STA_AUX_POWER -#define PCIM_EXP_STA_TRANSACTION_PND PCIEM_STA_TRANSACTION_PND -#define PCIR_EXPRESS_LINK_CAP PCIER_LINK_CAP -#define PCIM_LINK_CAP_MAX_SPEED PCIEM_LINK_CAP_MAX_SPEED -#define PCIM_LINK_CAP_MAX_WIDTH PCIEM_LINK_CAP_MAX_WIDTH -#define PCIM_LINK_CAP_ASPM PCIEM_LINK_CAP_ASPM -#define PCIM_LINK_CAP_L0S_EXIT PCIEM_LINK_CAP_L0S_EXIT -#define PCIM_LINK_CAP_L1_EXIT PCIEM_LINK_CAP_L1_EXIT -#define PCIM_LINK_CAP_CLOCK_PM PCIEM_LINK_CAP_CLOCK_PM -#define PCIM_LINK_CAP_SURPRISE_DOWN PCIEM_LINK_CAP_SURPRISE_DOWN -#define PCIM_LINK_CAP_DL_ACTIVE PCIEM_LINK_CAP_DL_ACTIVE -#define PCIM_LINK_CAP_LINK_BW_NOTIFY PCIEM_LINK_CAP_LINK_BW_NOTIFY -#define PCIM_LINK_CAP_ASPM_COMPLIANCE PCIEM_LINK_CAP_ASPM_COMPLIANCE -#define PCIM_LINK_CAP_PORT PCIEM_LINK_CAP_PORT -#define PCIR_EXPRESS_LINK_CTL PCIER_LINK_CTL -#define PCIM_EXP_LINK_CTL_ASPMC_DIS PCIEM_LINK_CTL_ASPMC_DIS -#define PCIM_EXP_LINK_CTL_ASPMC_L0S PCIEM_LINK_CTL_ASPMC_L0S -#define PCIM_EXP_LINK_CTL_ASPMC_L1 PCIEM_LINK_CTL_ASPMC_L1 -#define PCIM_EXP_LINK_CTL_ASPMC PCIEM_LINK_CTL_ASPMC -#define PCIM_EXP_LINK_CTL_RCB PCIEM_LINK_CTL_RCB -#define PCIM_EXP_LINK_CTL_LINK_DIS PCIEM_LINK_CTL_LINK_DIS -#define PCIM_EXP_LINK_CTL_RETRAIN_LINK PCIEM_LINK_CTL_RETRAIN_LINK -#define PCIM_EXP_LINK_CTL_COMMON_CLOCK PCIEM_LINK_CTL_COMMON_CLOCK -#define PCIM_EXP_LINK_CTL_EXTENDED_SYNC PCIEM_LINK_CTL_EXTENDED_SYNC -#define PCIM_EXP_LINK_CTL_ECPM PCIEM_LINK_CTL_ECPM -#define PCIM_EXP_LINK_CTL_HAWD PCIEM_LINK_CTL_HAWD -#define PCIM_EXP_LINK_CTL_LBMIE PCIEM_LINK_CTL_LBMIE -#define PCIM_EXP_LINK_CTL_LABIE PCIEM_LINK_CTL_LABIE -#define PCIR_EXPRESS_LINK_STA PCIER_LINK_STA -#define PCIM_LINK_STA_SPEED PCIEM_LINK_STA_SPEED -#define PCIM_LINK_STA_WIDTH PCIEM_LINK_STA_WIDTH -#define PCIM_LINK_STA_TRAINING_ERROR PCIEM_LINK_STA_TRAINING_ERROR -#define PCIM_LINK_STA_TRAINING PCIEM_LINK_STA_TRAINING -#define PCIM_LINK_STA_SLOT_CLOCK PCIEM_LINK_STA_SLOT_CLOCK -#define PCIM_LINK_STA_DL_ACTIVE PCIEM_LINK_STA_DL_ACTIVE -#define PCIM_LINK_STA_LINK_BW_MGMT PCIEM_LINK_STA_LINK_BW_MGMT -#define PCIM_LINK_STA_LINK_AUTO_BW PCIEM_LINK_STA_LINK_AUTO_BW -#define PCIR_EXPRESS_SLOT_CAP PCIER_SLOT_CAP -#define PCIR_EXPRESS_SLOT_CTL PCIER_SLOT_CTL -#define PCIR_EXPRESS_SLOT_STA PCIER_SLOT_STA -#define PCIR_EXPRESS_ROOT_CTL PCIER_ROOT_CTL -#define PCIR_EXPRESS_ROOT_CAP PCIER_ROOT_CAP -#define PCIR_EXPRESS_ROOT_STA PCIER_ROOT_STA -#define PCIR_EXPRESS_DEVICE_CAP2 PCIER_DEVICE_CAP2 -#define PCIR_EXPRESS_DEVICE_CTL2 PCIER_DEVICE_CTL2 -#define PCIM_EXP_CTL2_COMP_TIMEOUT_VAL PCIEM_CTL2_COMP_TIMEOUT_VAL -#define PCIM_EXP_CTL2_COMP_TIMEOUT_DIS PCIEM_CTL2_COMP_TIMEOUT_DIS -#define PCIM_EXP_CTL2_ARI PCIEM_CTL2_ARI -#define PCIM_EXP_CTL2_ATOMIC_REQ_ENABLE PCIEM_CTL2_ATOMIC_REQ_ENABLE -#define PCIM_EXP_CTL2_ATOMIC_EGR_BLOCK PCIEM_CTL2_ATOMIC_EGR_BLOCK -#define PCIM_EXP_CTL2_ID_ORDERED_REQ_EN PCIEM_CTL2_ID_ORDERED_REQ_EN -#define PCIM_EXP_CTL2_ID_ORDERED_CMP_EN PCIEM_CTL2_ID_ORDERED_CMP_EN -#define PCIM_EXP_CTL2_LTR_ENABLE PCIEM_CTL2_LTR_ENABLE -#define PCIM_EXP_CTL2_OBFF PCIEM_CTL2_OBFF -#define PCIM_EXP_OBFF_DISABLE PCIEM_OBFF_DISABLE -#define PCIM_EXP_OBFF_MSGA_ENABLE PCIEM_OBFF_MSGA_ENABLE -#define PCIM_EXP_OBFF_MSGB_ENABLE PCIEM_OBFF_MSGB_ENABLE -#define PCIM_EXP_OBFF_WAKE_ENABLE PCIEM_OBFF_WAKE_ENABLE -#define PCIM_EXP_CTL2_END2END_TLP PCIEM_CTL2_END2END_TLP -#define PCIR_EXPRESS_DEVICE_STA2 PCIER_DEVICE_STA2 -#define PCIR_EXPRESS_LINK_CAP2 PCIER_LINK_CAP2 -#define PCIR_EXPRESS_LINK_CTL2 PCIER_LINK_CTL2 -#define PCIR_EXPRESS_LINK_STA2 PCIER_LINK_STA2 -#define PCIR_EXPRESS_SLOT_CAP2 PCIER_SLOT_CAP2 -#define PCIR_EXPRESS_SLOT_CTL2 PCIER_SLOT_CTL2 -#define PCIR_EXPRESS_SLOT_STA2 PCIER_SLOT_STA2 - -/* MSI-X definitions */ -#define PCIR_MSIX_CTRL 0x2 -#define PCIM_MSIXCTRL_MSIX_ENABLE 0x8000 -#define PCIM_MSIXCTRL_FUNCTION_MASK 0x4000 -#define PCIM_MSIXCTRL_TABLE_SIZE 0x07FF -#define PCIR_MSIX_TABLE 0x4 -#define PCIR_MSIX_PBA 0x8 -#define PCIM_MSIX_BIR_MASK 0x7 -#define PCIM_MSIX_BIR_BAR_10 0 -#define PCIM_MSIX_BIR_BAR_14 1 -#define PCIM_MSIX_BIR_BAR_18 2 -#define PCIM_MSIX_BIR_BAR_1C 3 -#define PCIM_MSIX_BIR_BAR_20 4 -#define PCIM_MSIX_BIR_BAR_24 5 -#define PCIM_MSIX_VCTRL_MASK 0x1 - -/* PCI Advanced Features definitions */ -#define PCIR_PCIAF_CAP 0x3 -#define PCIM_PCIAFCAP_TP 0x01 -#define PCIM_PCIAFCAP_FLR 0x02 -#define PCIR_PCIAF_CTRL 0x4 -#define PCIR_PCIAFCTRL_FLR 0x01 -#define PCIR_PCIAF_STATUS 0x5 -#define PCIR_PCIAFSTATUS_TP 0x01 - -/* Advanced Error Reporting */ -#define PCIR_AER_UC_STATUS 0x04 -#define PCIM_AER_UC_TRAINING_ERROR 0x00000001 -#define PCIM_AER_UC_DL_PROTOCOL_ERROR 0x00000010 -#define PCIM_AER_UC_SURPRISE_LINK_DOWN 0x00000020 -#define PCIM_AER_UC_POISONED_TLP 0x00001000 -#define PCIM_AER_UC_FC_PROTOCOL_ERROR 0x00002000 -#define PCIM_AER_UC_COMPLETION_TIMEOUT 0x00004000 -#define PCIM_AER_UC_COMPLETER_ABORT 0x00008000 -#define PCIM_AER_UC_UNEXPECTED_COMPLETION 0x00010000 -#define PCIM_AER_UC_RECEIVER_OVERFLOW 0x00020000 -#define PCIM_AER_UC_MALFORMED_TLP 0x00040000 -#define PCIM_AER_UC_ECRC_ERROR 0x00080000 -#define PCIM_AER_UC_UNSUPPORTED_REQUEST 0x00100000 -#define PCIM_AER_UC_ACS_VIOLATION 0x00200000 -#define PCIM_AER_UC_INTERNAL_ERROR 0x00400000 -#define PCIM_AER_UC_MC_BLOCKED_TLP 0x00800000 -#define PCIM_AER_UC_ATOMIC_EGRESS_BLK 0x01000000 -#define PCIM_AER_UC_TLP_PREFIX_BLOCKED 0x02000000 -#define PCIR_AER_UC_MASK 0x08 /* Shares bits with UC_STATUS */ -#define PCIR_AER_UC_SEVERITY 0x0c /* Shares bits with UC_STATUS */ -#define PCIR_AER_COR_STATUS 0x10 -#define PCIM_AER_COR_RECEIVER_ERROR 0x00000001 -#define PCIM_AER_COR_BAD_TLP 0x00000040 -#define PCIM_AER_COR_BAD_DLLP 0x00000080 -#define PCIM_AER_COR_REPLAY_ROLLOVER 0x00000100 -#define PCIM_AER_COR_REPLAY_TIMEOUT 0x00001000 -#define PCIM_AER_COR_ADVISORY_NF_ERROR 0x00002000 -#define PCIM_AER_COR_INTERNAL_ERROR 0x00004000 -#define PCIM_AER_COR_HEADER_LOG_OVFLOW 0x00008000 -#define PCIR_AER_COR_MASK 0x14 /* Shares bits with COR_STATUS */ -#define PCIR_AER_CAP_CONTROL 0x18 -#define PCIM_AER_FIRST_ERROR_PTR 0x0000001f -#define PCIM_AER_ECRC_GEN_CAPABLE 0x00000020 -#define PCIM_AER_ECRC_GEN_ENABLE 0x00000040 -#define PCIM_AER_ECRC_CHECK_CAPABLE 0x00000080 -#define PCIM_AER_ECRC_CHECK_ENABLE 0x00000100 -#define PCIM_AER_MULT_HDR_CAPABLE 0x00000200 -#define PCIM_AER_MULT_HDR_ENABLE 0x00000400 -#define PCIM_AER_TLP_PREFIX_LOG_PRESENT 0x00000800 -#define PCIR_AER_HEADER_LOG 0x1c -#define PCIR_AER_ROOTERR_CMD 0x2c /* Only for root complex ports */ -#define PCIM_AER_ROOTERR_COR_ENABLE 0x00000001 -#define PCIM_AER_ROOTERR_NF_ENABLE 0x00000002 -#define PCIM_AER_ROOTERR_F_ENABLE 0x00000004 -#define PCIR_AER_ROOTERR_STATUS 0x30 /* Only for root complex ports */ -#define PCIM_AER_ROOTERR_COR_ERR 0x00000001 -#define PCIM_AER_ROOTERR_MULTI_COR_ERR 0x00000002 -#define PCIM_AER_ROOTERR_UC_ERR 0x00000004 -#define PCIM_AER_ROOTERR_MULTI_UC_ERR 0x00000008 -#define PCIM_AER_ROOTERR_FIRST_UC_FATAL 0x00000010 -#define PCIM_AER_ROOTERR_NF_ERR 0x00000020 -#define PCIM_AER_ROOTERR_F_ERR 0x00000040 -#define PCIM_AER_ROOTERR_INT_MESSAGE 0xf8000000 -#define PCIR_AER_COR_SOURCE_ID 0x34 /* Only for root complex ports */ -#define PCIR_AER_ERR_SOURCE_ID 0x36 /* Only for root complex ports */ -#define PCIR_AER_TLP_PREFIX_LOG 0x38 /* Only for TLP prefix functions */ - -/* Virtual Channel definitions */ -#define PCIR_VC_CAP1 0x04 -#define PCIM_VC_CAP1_EXT_COUNT 0x00000007 -#define PCIM_VC_CAP1_LOWPRI_EXT_COUNT 0x00000070 -#define PCIR_VC_CAP2 0x08 -#define PCIR_VC_CONTROL 0x0C -#define PCIR_VC_STATUS 0x0E -#define PCIR_VC_RESOURCE_CAP(n) (0x10 + (n) * 0x0C) -#define PCIR_VC_RESOURCE_CTL(n) (0x14 + (n) * 0x0C) -#define PCIR_VC_RESOURCE_STA(n) (0x18 + (n) * 0x0C) - -/* Serial Number definitions */ -#define PCIR_SERIAL_LOW 0x04 -#define PCIR_SERIAL_HIGH 0x08 diff --git a/src/libs/compat/freebsd_network/compat/dev/pci/pcivar.h b/src/libs/compat/freebsd_network/compat/dev/pci/pcivar.h deleted file mode 100644 index 12f302e6fb..0000000000 --- a/src/libs/compat/freebsd_network/compat/dev/pci/pcivar.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_DEV_PCI_PCIVAR_H_ -#define _FBSD_COMPAT_DEV_PCI_PCIVAR_H_ - - -#include - - -#define PCI_RF_DENSE 0x10000 - // ignored on x86 - -#define PCI_POWERSTATE_D0 0 -#define PCI_POWERSTATE_D1 1 -#define PCI_POWERSTATE_D2 2 -#define PCI_POWERSTATE_D3 3 -#define PCI_POWERSTATE_UNKNOWN -1 - - -int pci_enable_busmaster(device_t dev); -int pci_enable_io(device_t dev, int reg); - -uint32_t pci_get_devid(device_t dev); -void pci_set_intpin(device_t dev, uint8_t pin); -uint8_t pci_get_intpin(device_t dev); - -uint16_t pci_get_vendor(device_t dev); -uint16_t pci_get_device(device_t dev); -uint16_t pci_get_subvendor(device_t dev); -uint16_t pci_get_subdevice(device_t dev); -uint8_t pci_get_revid(device_t dev); -uint8_t pci_get_cachelnsz(device_t dev); -uint8_t *pci_get_ether(device_t dev); - -uint32_t pci_read_config(device_t dev, int reg, int width); -void pci_write_config(device_t dev, int reg, uint32_t val, int width); - -uint32_t pci_get_domain(device_t dev); -uint8_t pci_get_bus(device_t dev); -uint8_t pci_get_slot(device_t dev); -uint8_t pci_get_function(device_t dev); -device_t pci_find_dbsf(uint32_t domain, uint8_t bus, uint8_t slot, - uint8_t func); - -int pci_find_cap(device_t dev, int capability, int *capreg); -int pci_find_extcap(device_t dev, int capability, int *capreg); - -int pci_msi_count(device_t dev); -int pci_alloc_msi(device_t dev, int *count); -int pci_release_msi(device_t dev); -int pci_msix_count(device_t dev); -int pci_alloc_msix(device_t dev, int *count); - -int pci_get_max_read_req(device_t dev); -int pci_set_max_read_req(device_t dev, int size); - -int pci_get_powerstate(device_t dev); -int pci_set_powerstate(device_t dev, int newPowerState); - -static inline int -pci_get_vpd_ident(device_t dev, const char **identptr) -{ - return -1; -} - -#endif /* _FBSD_COMPAT_DEV_PCI_PCIVAR_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/machine/_bus.h b/src/libs/compat/freebsd_network/compat/machine/_bus.h deleted file mode 100644 index a4b9025408..0000000000 --- a/src/libs/compat/freebsd_network/compat/machine/_bus.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2009, Colin Günther. All Rights Reserved. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_MACHINE__BUS_H_ -#define _FBSD_COMPAT_MACHINE__BUS_H_ - - -#ifdef B_HAIKU_64_BIT - - -typedef uint64_t bus_addr_t; -typedef uint64_t bus_size_t; - -typedef uint64_t bus_space_tag_t; -typedef uint64_t bus_space_handle_t; - - -#else - - -typedef uint32_t bus_addr_t; -typedef uint32_t bus_size_t; - -typedef int bus_space_tag_t; -typedef unsigned int bus_space_handle_t; - - -#endif - -#endif /* _FBSD_COMPAT_MACHINE__BUS_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/machine/atomic.h b/src/libs/compat/freebsd_network/compat/machine/atomic.h deleted file mode 100644 index 89b3f02d8f..0000000000 --- a/src/libs/compat/freebsd_network/compat/machine/atomic.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_MACHINE_ATOMIC_H_ -#define _FBSD_COMPAT_MACHINE_ATOMIC_H_ - - -#include - - -#define atomic_add_int(ptr, value) \ - atomic_add((int32 *)(ptr), value) - -#define atomic_subtract_int(ptr, value) \ - atomic_add((int32 *)(ptr), -value) - -#define atomic_set_acq_32(ptr, value) \ - atomic_set_int(ptr, value) - -#define atomic_set_int(ptr, value) \ - atomic_or((int32 *)(ptr), value) - -#define atomic_readandclear_int(ptr) \ - atomic_set((int32 *)(ptr), 0) - -#define atomic_cmpset_int(ptr, old, new) \ - (atomic_test_and_set((int32 *)(ptr), new, old) == old) - - -#endif /* _FBSD_COMPAT_MACHINE_ATOMIC_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/machine/bus.h b/src/libs/compat/freebsd_network/compat/machine/bus.h deleted file mode 100644 index 660b3390c0..0000000000 --- a/src/libs/compat/freebsd_network/compat/machine/bus.h +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright 2009, Colin Günther. All Rights Reserved. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ - - -/*- - * Copyright (c) KATO Takenori, 1999. - * - * All rights reserved. Unpublished rights reserved under the copyright - * laws of Japan. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer as - * the first lines of this file unmodified. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ - -/*- - * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/*- - * Copyright (c) 1996 Charles M. Hannum. All rights reserved. - * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christopher G. Demetriou - * for the NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef _FBSD_COMPAT_MACHINE_BUS_H_ -#define _FBSD_COMPAT_MACHINE_BUS_H_ - -#include -#include - - -struct resource; - - -// TODO: x86 specific! -#define I386_BUS_SPACE_IO 0 -#define I386_BUS_SPACE_MEM 1 - -#define BUS_SPACE_MAXADDR_32BIT 0xffffffff -#ifdef __x86_64__ -# define BUS_SPACE_MAXADDR 0xffffffffffffffffull -#else -# define BUS_SPACE_MAXADDR 0xffffffff -#endif - -#define BUS_SPACE_MAXSIZE_32BIT 0xffffffff -#define BUS_SPACE_MAXSIZE 0xffffffff - -#define BUS_SPACE_UNRESTRICTED (~0) - -#define BUS_SPACE_BARRIER_READ 1 -#define BUS_SPACE_BARRIER_WRITE 2 - - -// Copied from arch/x86/arch_cpu.h -// Can't use the header as it indirectly includes arch/x86/arch_thread_types.h -// Which has a namespace, so can't be used in FreeBSD's C-code atm. -#define out8(value,port) \ - __asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port)) - -#define out16(value,port) \ - __asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port)) - -#define out32(value,port) \ - __asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port)) - -#define in8(port) ({ \ - uint8 _v; \ - __asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \ - _v; \ -}) - -#define in16(port) ({ \ - uint16 _v; \ - __asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \ - _v; \ -}) - -#define in32(port) ({ \ - uint32 _v; \ - __asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \ - _v; \ -}) - - -static inline uint8_t -bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - return tag == I386_BUS_SPACE_MEM - ? (*(volatile u_int8_t *)(handle + offset)) - : in8(handle + offset); -} - - -static inline uint16_t -bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - return tag == I386_BUS_SPACE_MEM - ? (*(volatile u_int16_t *)(handle + offset)) - : in16(handle + offset); -} - - -static inline uint32_t -bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - return tag == I386_BUS_SPACE_MEM - ? (*(volatile u_int32_t *)(handle + offset)) - : in32(handle + offset); -} - - -static inline void -bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset, uint8_t value) -{ - if (tag == I386_BUS_SPACE_MEM) - *(volatile uint8_t *)(handle + offset) = value; - else - out8(value, handle + offset); -} - - -static inline void -bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset, uint16_t value) -{ - if (tag == I386_BUS_SPACE_MEM) - *(volatile uint16_t *)(handle + offset) = value; - else - out16(value, handle + offset); -} - - -static inline void -bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset, uint32_t value) -{ - if (tag == I386_BUS_SPACE_MEM) - *(volatile uint32_t *)(handle + offset) = value; - else - out32(value, handle + offset); -} - - -static inline void -bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, size_t count) -{ - if (tag == I386_BUS_SPACE_IO) { - int _port_ = bsh + offset; - __asm __volatile(" \n\ - cld \n\ - 1: inb %w2,%%al \n\ - stosb \n\ - incl %2 \n\ - loop 1b" : - "=D" (addr), "=c" (count), "=d" (_port_): - "0" (addr), "1" (count), "2" (_port_) : - "%eax", "memory", "cc"); - } else { - void* _port_ = (void*) (bsh + offset); - memcpy(addr, _port_, count); - } -} - - -static inline void -bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, size_t count) -{ - if (tag == I386_BUS_SPACE_IO) { - int _port_ = bsh + offset; - __asm __volatile(" \n\ - cld \n\ - 1: inl %w2,%%eax \n\ - stosl \n\ - addl $4,%2 \n\ - loop 1b" : - "=D" (addr), "=c" (count), "=d" (_port_): - "0" (addr), "1" (count), "2" (_port_) : - "%eax", "memory", "cc"); - } else { - void* _port_ = (void*) (bsh + offset); - memcpy(addr, _port_, count); - } -} - - -static inline void -bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int8_t *addr, size_t count) -{ - if (tag == I386_BUS_SPACE_IO) { - int _port_ = bsh + offset; - __asm __volatile(" \n\ - cld \n\ - 1: lodsb \n\ - outb %%al,%w0 \n\ - incl %0 \n\ - loop 1b" : - "=d" (_port_), "=S" (addr), "=c" (count): - "0" (_port_), "1" (addr), "2" (count) : - "%eax", "memory", "cc"); - } else { - void* _port_ = (void*) (bsh + offset); - memcpy(_port_, addr, count); - } -} - - -static inline void -bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, size_t count) -{ - /* TODO implement */ -} - - -static inline void -bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset, bus_size_t len, int flags) -{ - if (flags & BUS_SPACE_BARRIER_READ) -#ifdef __x86_64__ - __asm__ __volatile__ ("lock; addl $0,0(%%rsp)" : : : "memory"); -#else - __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory"); -#endif - else - __asm__ __volatile__ ("" : : : "memory"); -} - - -static inline void -bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int8_t *addr, size_t count) -{ - - if (tag == I386_BUS_SPACE_IO) - outsb(bsh + offset, addr, count); - else { - __asm __volatile(" \n\ - cld \n\ - 1: lodsb \n\ - movb %%al,(%2) \n\ - loop 1b" : - "=S" (addr), "=c" (count) : - "r" (bsh + offset), "0" (addr), "1" (count) : - "%eax", "memory", "cc"); - } -} - - -#include - - -#define bus_space_write_stream_4(t, h, o, v) \ - bus_space_write_4((t), (h), (o), (v)) - -#endif /* _FBSD_COMPAT_MACHINE_BUS_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/machine/bus_dma.h b/src/libs/compat/freebsd_network/compat/machine/bus_dma.h deleted file mode 100644 index 8520e43496..0000000000 --- a/src/libs/compat/freebsd_network/compat/machine/bus_dma.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de - * All Rights Reserved. Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_MACHINE_BUS_DMA_H_ -#define _FBSD_COMPAT_MACHINE_BUS_DMA_H_ - - -#include - -#endif /* _FBSD_COMPAT_MACHINE_BUS_DMA_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/machine/clock.h b/src/libs/compat/freebsd_network/compat/machine/clock.h deleted file mode 100644 index e458d01a13..0000000000 --- a/src/libs/compat/freebsd_network/compat/machine/clock.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_CLOCK_H_ -#define _FBSD_COMPAT_SYS_CLOCK_H_ - - -#endif /* _FBSD_COMPAT_SYS_CLOCK_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/machine/cpufunc.h b/src/libs/compat/freebsd_network/compat/machine/cpufunc.h deleted file mode 100644 index 8e1575b1dd..0000000000 --- a/src/libs/compat/freebsd_network/compat/machine/cpufunc.h +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 1993 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_MACHINE_CPUFUNC_H_ -#define _FBSD_COMPAT_MACHINE_CPUFUNC_H_ - - -static __inline void -outsb(u_int port, const void *addr, size_t cnt) -{ - __asm __volatile("cld; rep; outsb" - : "+S" (addr), "+c" (cnt) - : "d" (port)); -} - -#endif /* _FBSD_COMPAT_MACHINE_CPUFUNC_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/machine/endian.h b/src/libs/compat/freebsd_network/compat/machine/endian.h deleted file mode 100644 index 52861ac4bd..0000000000 --- a/src/libs/compat/freebsd_network/compat/machine/endian.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 2007 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_MACHINE_ENDIAN_H_ -#define _FBSD_COMPAT_MACHINE_ENDIAN_H_ - - -#include -#include - -#endif diff --git a/src/libs/compat/freebsd_network/compat/machine/in_cksum.h b/src/libs/compat/freebsd_network/compat/machine/in_cksum.h deleted file mode 100644 index f174d3021e..0000000000 --- a/src/libs/compat/freebsd_network/compat/machine/in_cksum.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_MACHINE_IN_CKSUM_H_ -#define _FBSD_COMPAT_MACHINE_IN_CKSUM_H_ - - -#include - - -#define in_cksum(m, len) in_cksum_skip(m, len, 0) - - -static inline u_short -in_pseudo(u_int sum, u_int b, u_int c) -{ - // should never be called - panic("in_pseudo() called"); - return 0; -} - - -static inline u_short -in_cksum_skip(struct mbuf* m, int len, int skip) -{ - // should never be called - panic("in_cksum_skip() called"); - return 0; -} - -#endif /* _FBSD_COMPAT_MACHINE_IN_CKSUM_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/machine/md_var.h b/src/libs/compat/freebsd_network/compat/machine/md_var.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/libs/compat/freebsd_network/compat/machine/ofw_machdep.h b/src/libs/compat/freebsd_network/compat/machine/ofw_machdep.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/libs/compat/freebsd_network/compat/machine/resource.h b/src/libs/compat/freebsd_network/compat/machine/resource.h deleted file mode 100644 index f9d9d43b4e..0000000000 --- a/src/libs/compat/freebsd_network/compat/machine/resource.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2007 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_MACHINE_RESOURCE_H_ -#define _FBSD_COMPAT_MACHINE_RESOURCE_H_ - - -#define SYS_RES_IRQ 0x1 -#define SYS_RES_DRQ 0x2 -#define SYS_RES_MEMORY 0x3 -#define SYS_RES_IOPORT 0x4 - -#endif diff --git a/src/libs/compat/freebsd_network/compat/machine/stdarg.h b/src/libs/compat/freebsd_network/compat/machine/stdarg.h deleted file mode 100644 index 75961678b4..0000000000 --- a/src/libs/compat/freebsd_network/compat/machine/stdarg.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_MACHINE_STDARG_H_ -#define _FBSD_COMPAT_MACHINE_STDARG_H_ - - -#include -#include - -#endif /* _FBSD_COMPAT_MACHINE_STDARG_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/miibus_if.h b/src/libs/compat/freebsd_network/compat/miibus_if.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/libs/compat/freebsd_network/compat/net/bpf.h b/src/libs/compat/freebsd_network/compat/net/bpf.h deleted file mode 100644 index c822dc0664..0000000000 --- a/src/libs/compat/freebsd_network/compat/net/bpf.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_NET_BPF_H_ -#define _FBSD_COMPAT_NET_BPF_H_ - - -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ - - -struct bpf_if; - - -#define bpf_mtap(bpf_if, mbuf) do { } while (0) -#define BPF_MTAP(ifp, m) do { } while (0) -#define BPF_TAP(ifp, pkt, pktlen) do { } while (0) -#define bpf_mtap2(bpf_if, data, dlen, mbuf) do { } while (0) -#define bpfattach(ifnet, dlt, hdrlen) do { } while (0); -#define bpfattach2(ifnet, dlt, hdrlen, bpf_if) do { } while (0) -#define bpfdetach(ifnet) do { } while (0); - - -static inline int -bpf_peers_present(struct bpf_if *bpf) -{ - return 0; -} - -#endif /* _FBSD_COMPAT_NET_BPF_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/net/ethernet.h b/src/libs/compat/freebsd_network/compat/net/ethernet.h deleted file mode 100644 index e112c1ebd9..0000000000 --- a/src/libs/compat/freebsd_network/compat/net/ethernet.h +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Fundamental constants relating to ethernet. - * - * $FreeBSD: src/sys/net/ethernet.h,v 1.32 2007/05/29 12:40:45 yar Exp $ - * - */ -#ifndef _FBSD_COMPAT_NET_ETHERNET_H_ -#define _FBSD_COMPAT_NET_ETHERNET_H_ - - -/* - * Somce basic Ethernet constants. - */ -#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ -#define ETHER_TYPE_LEN 2 /* length of the Ethernet type field */ -#define ETHER_CRC_LEN 4 /* length of the Ethernet CRC */ -#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN) -#define ETHER_MIN_LEN 64 /* minimum frame len, including CRC */ -#define ETHER_MAX_LEN 1518 /* maximum frame len, including CRC */ -#define ETHER_MAX_LEN_JUMBO 9018 /* max jumbo frame len, including CRC */ - -#define ETHER_VLAN_ENCAP_LEN 4 /* len of 802.1Q VLAN encapsulation */ -/* - * Mbuf adjust factor to force 32-bit alignment of IP header. - * Drivers should do m_adj(m, ETHER_ALIGN) when setting up a - * receive so the upper layers get the IP header properly aligned - * past the 14-byte Ethernet header. - */ -#define ETHER_ALIGN 2 /* driver adjust for IP hdr alignment */ - -/* - * Compute the maximum frame size based on ethertype (i.e. possible - * encapsulation) and whether or not an FCS is present. - */ -#define ETHER_MAX_FRAME(ifp, etype, hasfcs) \ - ((ifp)->if_mtu + ETHER_HDR_LEN + \ - ((hasfcs) ? ETHER_CRC_LEN : 0) + \ - (((etype) == ETHERTYPE_VLAN) ? ETHER_VLAN_ENCAP_LEN : 0)) - -/* - * Ethernet-specific mbuf flags. - */ -#define M_HASFCS M_PROTO5 /* FCS included at end of frame */ - -/* - * Ethernet CRC32 polynomials (big- and little-endian verions). - */ -#define ETHER_CRC_POLY_LE 0xedb88320 -#define ETHER_CRC_POLY_BE 0x04c11db6 - -/* - * A macro to validate a length with - */ -#define ETHER_IS_VALID_LEN(foo) \ - ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) - -static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - -/* - * Structure of a 10Mb/s Ethernet header. - */ -struct ether_header { - u_char ether_dhost[ETHER_ADDR_LEN]; - u_char ether_shost[ETHER_ADDR_LEN]; - u_short ether_type; -} __packed; - -/* - * Structure of a 48-bit Ethernet address. - */ -struct ether_addr { - u_char octet[ETHER_ADDR_LEN]; -} __packed; - -#ifdef CTASSERT -CTASSERT(sizeof (struct ether_header) == ETHER_ADDR_LEN * 2 + 2); -CTASSERT(sizeof (struct ether_addr) == ETHER_ADDR_LEN); -#endif - -#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */ - -/* - * NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields. - * However, there are some conflicts. - */ - -#define ETHERTYPE_8023 0x0004 /* IEEE 802.3 packet */ - /* 0x0101 .. 0x1FF Experimental */ -#define ETHERTYPE_PUP 0x0200 /* Xerox PUP protocol - see 0A00 */ -#define ETHERTYPE_PUPAT 0x0200 /* PUP Address Translation - see 0A01 */ -#define ETHERTYPE_SPRITE 0x0500 /* ??? */ - /* 0x0400 Nixdorf */ -#define ETHERTYPE_NS 0x0600 /* XNS */ -#define ETHERTYPE_NSAT 0x0601 /* XNS Address Translation (3Mb only) */ -#define ETHERTYPE_DLOG1 0x0660 /* DLOG (?) */ -#define ETHERTYPE_DLOG2 0x0661 /* DLOG (?) */ -#define ETHERTYPE_IP 0x0800 /* IP protocol */ -#define ETHERTYPE_X75 0x0801 /* X.75 Internet */ -#define ETHERTYPE_NBS 0x0802 /* NBS Internet */ -#define ETHERTYPE_ECMA 0x0803 /* ECMA Internet */ -#define ETHERTYPE_CHAOS 0x0804 /* CHAOSnet */ -#define ETHERTYPE_X25 0x0805 /* X.25 Level 3 */ -#define ETHERTYPE_ARP 0x0806 /* Address resolution protocol */ -#define ETHERTYPE_NSCOMPAT 0x0807 /* XNS Compatibility */ -#define ETHERTYPE_FRARP 0x0808 /* Frame Relay ARP (RFC1701) */ - /* 0x081C Symbolics Private */ - /* 0x0888 - 0x088A Xyplex */ -#define ETHERTYPE_UBDEBUG 0x0900 /* Ungermann-Bass network debugger */ -#define ETHERTYPE_IEEEPUP 0x0A00 /* Xerox IEEE802.3 PUP */ -#define ETHERTYPE_IEEEPUPAT 0x0A01 /* Xerox IEEE802.3 PUP Address Translation */ -#define ETHERTYPE_VINES 0x0BAD /* Banyan VINES */ -#define ETHERTYPE_VINESLOOP 0x0BAE /* Banyan VINES Loopback */ -#define ETHERTYPE_VINESECHO 0x0BAF /* Banyan VINES Echo */ - -/* 0x1000 - 0x100F Berkeley Trailer */ -/* - * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have - * (type-ETHERTYPE_TRAIL)*512 bytes of data followed - * by an ETHER type (as given above) and then the (variable-length) header. - */ -#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */ -#define ETHERTYPE_NTRAILER 16 - -#define ETHERTYPE_DCA 0x1234 /* DCA - Multicast */ -#define ETHERTYPE_VALID 0x1600 /* VALID system protocol */ -#define ETHERTYPE_DOGFIGHT 0x1989 /* Artificial Horizons ("Aviator" dogfight simulator [on Sun]) */ -#define ETHERTYPE_RCL 0x1995 /* Datapoint Corporation (RCL lan protocol) */ - - /* The following 3C0x types - are unregistered: */ -#define ETHERTYPE_NBPVCD 0x3C00 /* 3Com NBP virtual circuit datagram (like XNS SPP) not registered */ -#define ETHERTYPE_NBPSCD 0x3C01 /* 3Com NBP System control datagram not registered */ -#define ETHERTYPE_NBPCREQ 0x3C02 /* 3Com NBP Connect request (virtual cct) not registered */ -#define ETHERTYPE_NBPCRSP 0x3C03 /* 3Com NBP Connect repsonse not registered */ -#define ETHERTYPE_NBPCC 0x3C04 /* 3Com NBP Connect complete not registered */ -#define ETHERTYPE_NBPCLREQ 0x3C05 /* 3Com NBP Close request (virtual cct) not registered */ -#define ETHERTYPE_NBPCLRSP 0x3C06 /* 3Com NBP Close response not registered */ -#define ETHERTYPE_NBPDG 0x3C07 /* 3Com NBP Datagram (like XNS IDP) not registered */ -#define ETHERTYPE_NBPDGB 0x3C08 /* 3Com NBP Datagram broadcast not registered */ -#define ETHERTYPE_NBPCLAIM 0x3C09 /* 3Com NBP Claim NetBIOS name not registered */ -#define ETHERTYPE_NBPDLTE 0x3C0A /* 3Com NBP Delete Netbios name not registered */ -#define ETHERTYPE_NBPRAS 0x3C0B /* 3Com NBP Remote adaptor status request not registered */ -#define ETHERTYPE_NBPRAR 0x3C0C /* 3Com NBP Remote adaptor response not registered */ -#define ETHERTYPE_NBPRST 0x3C0D /* 3Com NBP Reset not registered */ - -#define ETHERTYPE_PCS 0x4242 /* PCS Basic Block Protocol */ -#define ETHERTYPE_IMLBLDIAG 0x424C /* Information Modes Little Big LAN diagnostic */ -#define ETHERTYPE_DIDDLE 0x4321 /* THD - Diddle */ -#define ETHERTYPE_IMLBL 0x4C42 /* Information Modes Little Big LAN */ -#define ETHERTYPE_SIMNET 0x5208 /* BBN Simnet Private */ -#define ETHERTYPE_DECEXPER 0x6000 /* DEC Unassigned, experimental */ -#define ETHERTYPE_MOPDL 0x6001 /* DEC MOP dump/load */ -#define ETHERTYPE_MOPRC 0x6002 /* DEC MOP remote console */ -#define ETHERTYPE_DECnet 0x6003 /* DEC DECNET Phase IV route */ -#define ETHERTYPE_DN ETHERTYPE_DECnet /* libpcap, tcpdump */ -#define ETHERTYPE_LAT 0x6004 /* DEC LAT */ -#define ETHERTYPE_DECDIAG 0x6005 /* DEC diagnostic protocol (at interface initialization?) */ -#define ETHERTYPE_DECCUST 0x6006 /* DEC customer protocol */ -#define ETHERTYPE_SCA 0x6007 /* DEC LAVC, SCA */ -#define ETHERTYPE_AMBER 0x6008 /* DEC AMBER */ -#define ETHERTYPE_DECMUMPS 0x6009 /* DEC MUMPS */ - /* 0x6010 - 0x6014 3Com Corporation */ -#define ETHERTYPE_TRANSETHER 0x6558 /* Trans Ether Bridging (RFC1701)*/ -#define ETHERTYPE_RAWFR 0x6559 /* Raw Frame Relay (RFC1701) */ -#define ETHERTYPE_UBDL 0x7000 /* Ungermann-Bass download */ -#define ETHERTYPE_UBNIU 0x7001 /* Ungermann-Bass NIUs */ -#define ETHERTYPE_UBDIAGLOOP 0x7002 /* Ungermann-Bass diagnostic/loopback */ -#define ETHERTYPE_UBNMC 0x7003 /* Ungermann-Bass ??? (NMC to/from UB Bridge) */ -#define ETHERTYPE_UBBST 0x7005 /* Ungermann-Bass Bridge Spanning Tree */ -#define ETHERTYPE_OS9 0x7007 /* OS/9 Microware */ -#define ETHERTYPE_OS9NET 0x7009 /* OS/9 Net? */ - /* 0x7020 - 0x7029 LRT (England) (now Sintrom) */ -#define ETHERTYPE_RACAL 0x7030 /* Racal-Interlan */ -#define ETHERTYPE_PRIMENTS 0x7031 /* Prime NTS (Network Terminal Service) */ -#define ETHERTYPE_CABLETRON 0x7034 /* Cabletron */ -#define ETHERTYPE_CRONUSVLN 0x8003 /* Cronus VLN */ -#define ETHERTYPE_CRONUS 0x8004 /* Cronus Direct */ -#define ETHERTYPE_HP 0x8005 /* HP Probe */ -#define ETHERTYPE_NESTAR 0x8006 /* Nestar */ -#define ETHERTYPE_ATTSTANFORD 0x8008 /* AT&T/Stanford (local use) */ -#define ETHERTYPE_EXCELAN 0x8010 /* Excelan */ -#define ETHERTYPE_SG_DIAG 0x8013 /* SGI diagnostic type */ -#define ETHERTYPE_SG_NETGAMES 0x8014 /* SGI network games */ -#define ETHERTYPE_SG_RESV 0x8015 /* SGI reserved type */ -#define ETHERTYPE_SG_BOUNCE 0x8016 /* SGI bounce server */ -#define ETHERTYPE_APOLLODOMAIN 0x8019 /* Apollo DOMAIN */ -#define ETHERTYPE_TYMSHARE 0x802E /* Tymeshare */ -#define ETHERTYPE_TIGAN 0x802F /* Tigan, Inc. */ -#define ETHERTYPE_REVARP 0x8035 /* Reverse addr resolution protocol */ -#define ETHERTYPE_AEONIC 0x8036 /* Aeonic Systems */ -#define ETHERTYPE_IPXNEW 0x8037 /* IPX (Novell Netware?) */ -#define ETHERTYPE_LANBRIDGE 0x8038 /* DEC LANBridge */ -#define ETHERTYPE_DSMD 0x8039 /* DEC DSM/DDP */ -#define ETHERTYPE_ARGONAUT 0x803A /* DEC Argonaut Console */ -#define ETHERTYPE_VAXELN 0x803B /* DEC VAXELN */ -#define ETHERTYPE_DECDNS 0x803C /* DEC DNS Naming Service */ -#define ETHERTYPE_ENCRYPT 0x803D /* DEC Ethernet Encryption */ -#define ETHERTYPE_DECDTS 0x803E /* DEC Distributed Time Service */ -#define ETHERTYPE_DECLTM 0x803F /* DEC LAN Traffic Monitor */ -#define ETHERTYPE_DECNETBIOS 0x8040 /* DEC PATHWORKS DECnet NETBIOS Emulation */ -#define ETHERTYPE_DECLAST 0x8041 /* DEC Local Area System Transport */ - /* 0x8042 DEC Unassigned */ -#define ETHERTYPE_PLANNING 0x8044 /* Planning Research Corp. */ - /* 0x8046 - 0x8047 AT&T */ -#define ETHERTYPE_DECAM 0x8048 /* DEC Availability Manager for Distributed Systems DECamds (but someone at DEC says not) */ -#define ETHERTYPE_EXPERDATA 0x8049 /* ExperData */ -#define ETHERTYPE_VEXP 0x805B /* Stanford V Kernel exp. */ -#define ETHERTYPE_VPROD 0x805C /* Stanford V Kernel prod. */ -#define ETHERTYPE_ES 0x805D /* Evans & Sutherland */ -#define ETHERTYPE_LITTLE 0x8060 /* Little Machines */ -#define ETHERTYPE_COUNTERPOINT 0x8062 /* Counterpoint Computers */ - /* 0x8065 - 0x8066 Univ. of Mass @ Amherst */ -#define ETHERTYPE_VEECO 0x8067 /* Veeco Integrated Auto. */ -#define ETHERTYPE_GENDYN 0x8068 /* General Dynamics */ -#define ETHERTYPE_ATT 0x8069 /* AT&T */ -#define ETHERTYPE_AUTOPHON 0x806A /* Autophon */ -#define ETHERTYPE_COMDESIGN 0x806C /* ComDesign */ -#define ETHERTYPE_COMPUGRAPHIC 0x806D /* Compugraphic Corporation */ - /* 0x806E - 0x8077 Landmark Graphics Corp. */ -#define ETHERTYPE_MATRA 0x807A /* Matra */ -#define ETHERTYPE_DDE 0x807B /* Dansk Data Elektronik */ -#define ETHERTYPE_MERIT 0x807C /* Merit Internodal (or Univ of Michigan?) */ - /* 0x807D - 0x807F Vitalink Communications */ -#define ETHERTYPE_VLTLMAN 0x8080 /* Vitalink TransLAN III Management */ - /* 0x8081 - 0x8083 Counterpoint Computers */ - /* 0x8088 - 0x808A Xyplex */ -#define ETHERTYPE_ATALK 0x809B /* AppleTalk */ -#define ETHERTYPE_AT ETHERTYPE_ATALK /* old NetBSD */ -#define ETHERTYPE_APPLETALK ETHERTYPE_ATALK /* HP-UX */ - /* 0x809C - 0x809E Datability */ -#define ETHERTYPE_SPIDER 0x809F /* Spider Systems Ltd. */ - /* 0x80A3 Nixdorf */ - /* 0x80A4 - 0x80B3 Siemens Gammasonics Inc. */ - /* 0x80C0 - 0x80C3 DCA (Digital Comm. Assoc.) Data Exchange Cluster */ - /* 0x80C4 - 0x80C5 Banyan Systems */ -#define ETHERTYPE_PACER 0x80C6 /* Pacer Software */ -#define ETHERTYPE_APPLITEK 0x80C7 /* Applitek Corporation */ - /* 0x80C8 - 0x80CC Intergraph Corporation */ - /* 0x80CD - 0x80CE Harris Corporation */ - /* 0x80CF - 0x80D2 Taylor Instrument */ - /* 0x80D3 - 0x80D4 Rosemount Corporation */ -#define ETHERTYPE_SNA 0x80D5 /* IBM SNA Services over Ethernet */ -#define ETHERTYPE_VARIAN 0x80DD /* Varian Associates */ - /* 0x80DE - 0x80DF TRFS (Integrated Solutions Transparent Remote File System) */ - /* 0x80E0 - 0x80E3 Allen-Bradley */ - /* 0x80E4 - 0x80F0 Datability */ -#define ETHERTYPE_RETIX 0x80F2 /* Retix */ -#define ETHERTYPE_AARP 0x80F3 /* AppleTalk AARP */ - /* 0x80F4 - 0x80F5 Kinetics */ -#define ETHERTYPE_APOLLO 0x80F7 /* Apollo Computer */ -#define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tagging (XXX conflicts) */ - /* 0x80FF - 0x8101 Wellfleet Communications (XXX conflicts) */ -#define ETHERTYPE_BOFL 0x8102 /* Wellfleet; BOFL (Breath OF Life) pkts [every 5-10 secs.] */ -#define ETHERTYPE_WELLFLEET 0x8103 /* Wellfleet Communications */ - /* 0x8107 - 0x8109 Symbolics Private */ -#define ETHERTYPE_TALARIS 0x812B /* Talaris */ -#define ETHERTYPE_WATERLOO 0x8130 /* Waterloo Microsystems Inc. (XXX which?) */ -#define ETHERTYPE_HAYES 0x8130 /* Hayes Microcomputers (XXX which?) */ -#define ETHERTYPE_VGLAB 0x8131 /* VG Laboratory Systems */ - /* 0x8132 - 0x8137 Bridge Communications */ -#define ETHERTYPE_IPX 0x8137 /* Novell (old) NetWare IPX (ECONFIG E option) */ -#define ETHERTYPE_NOVELL 0x8138 /* Novell, Inc. */ - /* 0x8139 - 0x813D KTI */ -#define ETHERTYPE_MUMPS 0x813F /* M/MUMPS data sharing */ -#define ETHERTYPE_AMOEBA 0x8145 /* Vrije Universiteit (NL) Amoeba 4 RPC (obsolete) */ -#define ETHERTYPE_FLIP 0x8146 /* Vrije Universiteit (NL) FLIP (Fast Local Internet Protocol) */ -#define ETHERTYPE_VURESERVED 0x8147 /* Vrije Universiteit (NL) [reserved] */ -#define ETHERTYPE_LOGICRAFT 0x8148 /* Logicraft */ -#define ETHERTYPE_NCD 0x8149 /* Network Computing Devices */ -#define ETHERTYPE_ALPHA 0x814A /* Alpha Micro */ -#define ETHERTYPE_SNMP 0x814C /* SNMP over Ethernet (see RFC1089) */ - /* 0x814D - 0x814E BIIN */ -#define ETHERTYPE_TEC 0x814F /* Technically Elite Concepts */ -#define ETHERTYPE_RATIONAL 0x8150 /* Rational Corp */ - /* 0x8151 - 0x8153 Qualcomm */ - /* 0x815C - 0x815E Computer Protocol Pty Ltd */ - /* 0x8164 - 0x8166 Charles River Data Systems */ -#define ETHERTYPE_XTP 0x817D /* Protocol Engines XTP */ -#define ETHERTYPE_SGITW 0x817E /* SGI/Time Warner prop. */ -#define ETHERTYPE_HIPPI_FP 0x8180 /* HIPPI-FP encapsulation */ -#define ETHERTYPE_STP 0x8181 /* Scheduled Transfer STP, HIPPI-ST */ - /* 0x8182 - 0x8183 Reserved for HIPPI-6400 */ - /* 0x8184 - 0x818C SGI prop. */ -#define ETHERTYPE_MOTOROLA 0x818D /* Motorola */ -#define ETHERTYPE_NETBEUI 0x8191 /* PowerLAN NetBIOS/NetBEUI (PC) */ - /* 0x819A - 0x81A3 RAD Network Devices */ - /* 0x81B7 - 0x81B9 Xyplex */ - /* 0x81CC - 0x81D5 Apricot Computers */ - /* 0x81D6 - 0x81DD Artisoft Lantastic */ - /* 0x81E6 - 0x81EF Polygon */ - /* 0x81F0 - 0x81F2 Comsat Labs */ - /* 0x81F3 - 0x81F5 SAIC */ - /* 0x81F6 - 0x81F8 VG Analytical */ - /* 0x8203 - 0x8205 QNX Software Systems Ltd. */ - /* 0x8221 - 0x8222 Ascom Banking Systems */ - /* 0x823E - 0x8240 Advanced Encryption Systems */ - /* 0x8263 - 0x826A Charles River Data Systems */ - /* 0x827F - 0x8282 Athena Programming */ - /* 0x829A - 0x829B Inst Ind Info Tech */ - /* 0x829C - 0x82AB Taurus Controls */ - /* 0x82AC - 0x8693 Walker Richer & Quinn */ -#define ETHERTYPE_ACCTON 0x8390 /* Accton Technologies (unregistered) */ -#define ETHERTYPE_TALARISMC 0x852B /* Talaris multicast */ -#define ETHERTYPE_KALPANA 0x8582 /* Kalpana */ - /* 0x8694 - 0x869D Idea Courier */ - /* 0x869E - 0x86A1 Computer Network Tech */ - /* 0x86A3 - 0x86AC Gateway Communications */ -#define ETHERTYPE_SECTRA 0x86DB /* SECTRA */ -#define ETHERTYPE_IPV6 0x86DD /* IP protocol version 6 */ -#define ETHERTYPE_DELTACON 0x86DE /* Delta Controls */ -#define ETHERTYPE_ATOMIC 0x86DF /* ATOMIC */ - /* 0x86E0 - 0x86EF Landis & Gyr Powers */ - /* 0x8700 - 0x8710 Motorola */ -#define ETHERTYPE_RDP 0x8739 /* Control Technology Inc. RDP Without IP */ -#define ETHERTYPE_MICP 0x873A /* Control Technology Inc. Mcast Industrial Ctrl Proto. */ - /* 0x873B - 0x873C Control Technology Inc. Proprietary */ -#define ETHERTYPE_TCPCOMP 0x876B /* TCP/IP Compression (RFC1701) */ -#define ETHERTYPE_IPAS 0x876C /* IP Autonomous Systems (RFC1701) */ -#define ETHERTYPE_SECUREDATA 0x876D /* Secure Data (RFC1701) */ -#define ETHERTYPE_FLOWCONTROL 0x8808 /* 802.3x flow control packet */ -#define ETHERTYPE_SLOW 0x8809 /* 802.3ad link aggregation (LACP) */ -#define ETHERTYPE_PPP 0x880B /* PPP (obsolete by PPPOE) */ -#define ETHERTYPE_HITACHI 0x8820 /* Hitachi Cable (Optoelectronic Systems Laboratory) */ -#define ETHERTYPE_MPLS 0x8847 /* MPLS Unicast */ -#define ETHERTYPE_MPLS_MCAST 0x8848 /* MPLS Multicast */ -#define ETHERTYPE_AXIS 0x8856 /* Axis Communications AB proprietary bootstrap/config */ -#define ETHERTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */ -#define ETHERTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */ -#define ETHERTYPE_LANPROBE 0x8888 /* HP LanProbe test? */ -#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ -#define ETHERTYPE_LOOPBACK 0x9000 /* Loopback: used to test interfaces */ -#define ETHERTYPE_LBACK ETHERTYPE_LOOPBACK /* DEC MOP loopback */ -#define ETHERTYPE_XNSSM 0x9001 /* 3Com (Formerly Bridge Communications), XNS Systems Management */ -#define ETHERTYPE_TCPSM 0x9002 /* 3Com (Formerly Bridge Communications), TCP/IP Systems Management */ -#define ETHERTYPE_BCLOOP 0x9003 /* 3Com (Formerly Bridge Communications), loopback detection */ -#define ETHERTYPE_DEBNI 0xAAAA /* DECNET? Used by VAX 6220 DEBNI */ -#define ETHERTYPE_SONIX 0xFAF5 /* Sonix Arpeggio */ -#define ETHERTYPE_VITAL 0xFF00 /* BBN VITAL-LanBridge cache wakeups */ - /* 0xFF00 - 0xFFOF ISC Bunker Ramo */ - -#define ETHERTYPE_MAX 0xFFFF /* Maximum valid ethernet type, reserved */ - -/* - * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have - * (type-ETHERTYPE_TRAIL)*512 bytes of data followed - * by an ETHER type (as given above) and then the (variable-length) header. - */ -#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */ -#define ETHERTYPE_NTRAILER 16 - -#define ETHERMTU (ETHER_MAX_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN) -#define ETHERMIN (ETHER_MIN_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN) -#define ETHERMTU_JUMBO (ETHER_MAX_LEN_JUMBO - ETHER_HDR_LEN - ETHER_CRC_LEN) -/* - * The ETHER_BPF_MTAP macro should be used by drivers which support hardware - * offload for VLAN tag processing. It will check the mbuf to see if it has - * M_VLANTAG set, and if it does, will pass the packet along to - * ether_vlan_mtap. This function will re-insert VLAN tags for the duration - * of the tap, so they show up properly for network analyzers. - */ -#define ETHER_BPF_MTAP(_ifp, _m) do { \ - } while (0) - -#ifdef _KERNEL - -struct ifnet; -struct mbuf; -struct route; -struct sockaddr; -struct bpf_if; - -extern uint32_t ether_crc32_le(const uint8_t *, size_t); -extern uint32_t ether_crc32_be(const uint8_t *, size_t); -extern void ether_demux(struct ifnet *, struct mbuf *); -extern void ether_ifattach(struct ifnet *, const u_int8_t *); -extern void ether_ifdetach(struct ifnet *); -extern int ether_ioctl(struct ifnet *, u_long, caddr_t); -extern int ether_output(struct ifnet *, - struct mbuf *, struct sockaddr *, struct route *); -extern int ether_output_frame(struct ifnet *, struct mbuf *); -extern char *ether_sprintf(const u_int8_t *); -void ether_vlan_mtap(struct bpf_if *, struct mbuf *, - void *, u_int); - -#else /* _KERNEL */ - -#include - -/* - * Ethernet address conversion/parsing routines. - */ -__BEGIN_DECLS -struct ether_addr *ether_aton(const char *); -struct ether_addr *ether_aton_r(const char *, struct ether_addr *); -int ether_hostton(const char *, struct ether_addr *); -int ether_line(const char *, struct ether_addr *, char *); -char *ether_ntoa(const struct ether_addr *); -char *ether_ntoa_r(const struct ether_addr *, char *); -int ether_ntohost(char *, const struct ether_addr *); -__END_DECLS - -#endif /* !_KERNEL */ - -#endif /* !_FBSD_COMPAT_NET_ETHERNET_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/net/if.h b/src/libs/compat/freebsd_network/compat/net/if.h deleted file mode 100644 index e56059cd50..0000000000 --- a/src/libs/compat/freebsd_network/compat/net/if.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_NET_IF_H_ -#define _FBSD_COMPAT_NET_IF_H_ - - -#include - -#include -#include -#include - - -#define IF_Kbps(x) ((x) * 1000) -#define IF_Mbps(x) (IF_Kbps((x) * 1000)) -#define IF_Gbps(x) (IF_Mbps((x) * 1000)) - -/* Capabilities that interfaces can advertise. */ -#define IFCAP_RXCSUM 0x00001 /* can offload checksum on RX */ -#define IFCAP_TXCSUM 0x00002 /* can offload checksum on TX */ -#define IFCAP_NETCONS 0x00004 /* can be a network console */ -#define IFCAP_VLAN_MTU 0x00008 /* VLAN-compatible MTU */ -#define IFCAP_VLAN_HWTAGGING 0x00010 /* hardware VLAN tag support */ -#define IFCAP_JUMBO_MTU 0x00020 /* 9000 byte MTU supported */ -#define IFCAP_POLLING 0x00040 /* driver supports polling */ -#define IFCAP_VLAN_HWCSUM 0x00080 -#define IFCAP_TSO4 0x00100 /* supports TCP segmentation offload */ -#define IFCAP_TSO6 0x00200 /* can do TCP6 Segmentation Offload */ -#define IFCAP_WOL_UCAST 0x00800 /* wake on any unicast frame */ -#define IFCAP_WOL_MCAST 0x01000 /* wake on any multicast frame */ -#define IFCAP_WOL_MAGIC 0x02000 /* wake on any Magic Packet */ -#define IFCAP_VLAN_HWFILTER 0x10000 /* interface hw can filter vlan tag */ -#define IFCAP_POLLING_NOCOUNT 0x20000 -#define IFCAP_VLAN_HWTSO 0x40000 -#define IFCAP_LINKSTATE 0x80000 - -#define IFCAP_HWCSUM (IFCAP_RXCSUM | IFCAP_TXCSUM) -#define IFCAP_TSO (IFCAP_TSO4 | IFCAP_TSO6) -#define IFCAP_WOL (IFCAP_WOL_UCAST | IFCAP_WOL_MCAST | IFCAP_WOL_MAGIC) - - -#define IFF_DRV_RUNNING 0x00010000 -#define IFF_DRV_OACTIVE 0x00020000 -#define IFF_LINK0 0x00040000 /* per link layer defined bit */ -#define IFF_LINK1 0x00080000 /* per link layer defined bit */ -#define IFF_LINK2 0x00100000 /* per link layer defined bit */ -#define IFF_DEBUG 0x00200000 -#define IFF_MONITOR 0x00400000 /* (n) user-requested monitor mode */ - -#define LINK_STATE_UNKNOWN 0 -#define LINK_STATE_DOWN 1 -#define LINK_STATE_UP 2 - -#define IFQ_MAXLEN 50 - - -/* - * Structure describing information about an interface - * which may be of interest to management entities. - */ -struct if_data { - /* generic interface information */ - u_char ifi_type; /* ethernet, tokenring, etc */ - u_char ifi_physical; /* e.g., AUI, Thinnet, 10base-T, etc */ - u_char ifi_addrlen; /* media address length */ - u_char ifi_hdrlen; /* media header length */ - u_char ifi_link_state; /* current link state */ - u_char ifi_recvquota; /* polling quota for receive intrs */ - u_char ifi_xmitquota; /* polling quota for xmit intrs */ - u_char ifi_datalen; /* length of this data struct */ - u_long ifi_mtu; /* maximum transmission unit */ - u_long ifi_metric; /* routing metric (external only) */ - u_long ifi_baudrate; /* linespeed */ - /* volatile statistics */ - u_long ifi_ipackets; /* packets received on interface */ - u_long ifi_ierrors; /* input errors on interface */ - u_long ifi_opackets; /* packets sent on interface */ - u_long ifi_oerrors; /* output errors on interface */ - u_long ifi_collisions; /* collisions on csma interfaces */ - u_long ifi_ibytes; /* total number of octets received */ - u_long ifi_obytes; /* total number of octets sent */ - u_long ifi_imcasts; /* packets received via multicast */ - u_long ifi_omcasts; /* packets sent via multicast */ - u_long ifi_iqdrops; /* dropped on input, this interface */ - u_long ifi_oqdrops; /* dropped on output, this interface */ - u_long ifi_noproto; /* destined for unsupported protocol */ - u_long ifi_hwassist; /* HW offload capabilities */ - time_t ifi_epoch; /* uptime at attach or stat reset */ -#ifdef __alpha__ - u_int ifi_timepad; /* time_t is int, not long on alpha */ -#endif - struct timeval ifi_lastchange; /* time of last administrative change */ -}; - -struct ifdrv { - char ifd_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - unsigned long ifd_cmd; - size_t ifd_len; - void* ifd_data; -}; - -#ifdef _KERNEL -/* TODO: this should go away soon. */ -# include -#endif - - -#endif /* _FBSD_COMPAT_NET_IF_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/net/if_arp.h b/src/libs/compat/freebsd_network/compat/net/if_arp.h deleted file mode 100644 index 2be137aebb..0000000000 --- a/src/libs/compat/freebsd_network/compat/net/if_arp.h +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * Copyright (c) 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)if_arp.h 8.1 (Berkeley) 6/10/93 - * $FreeBSD: src/sys/net/if_arp.h,v 1.22 2005/06/10 16:49:18 brooks Exp $ - */ - -#ifndef _FBSD_COMPAT_NET_IF_ARP_H_ -#define _FBSD_COMPAT_NET_IF_ARP_H_ - -/* - * Address Resolution Protocol. - * - * See RFC 826 for protocol description. ARP packets are variable - * in size; the arphdr structure defines the fixed-length portion. - * Protocol type values are the same as those for 10 Mb/s Ethernet. - * It is followed by the variable-sized fields ar_sha, arp_spa, - * arp_tha and arp_tpa in that order, according to the lengths - * specified. Field names used correspond to RFC 826. - */ -struct arphdr { - u_short ar_hrd; /* format of hardware address */ -#define ARPHRD_ETHER 1 /* ethernet hardware format */ -#define ARPHRD_IEEE802 6 /* token-ring hardware format */ -#define ARPHRD_ARCNET 7 /* arcnet hardware format */ -#define ARPHRD_FRELAY 15 /* frame relay hardware format */ -#define ARPHRD_IEEE1394 24 /* firewire hardware format */ - u_short ar_pro; /* format of protocol address */ - u_char ar_hln; /* length of hardware address */ - u_char ar_pln; /* length of protocol address */ - u_short ar_op; /* one of: */ -#define ARPOP_REQUEST 1 /* request to resolve address */ -#define ARPOP_REPLY 2 /* response to previous request */ -#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */ -#define ARPOP_REVREPLY 4 /* response giving protocol address */ -#define ARPOP_INVREQUEST 8 /* request to identify peer */ -#define ARPOP_INVREPLY 9 /* response identifying peer */ -/* - * The remaining fields are variable in size, - * according to the sizes above. - */ -#ifdef COMMENT_ONLY - u_char ar_sha[]; /* sender hardware address */ - u_char ar_spa[]; /* sender protocol address */ - u_char ar_tha[]; /* target hardware address */ - u_char ar_tpa[]; /* target protocol address */ -#endif -}; - -#define ar_sha(ap) (((caddr_t)((ap)+1)) + 0) -#define ar_spa(ap) (((caddr_t)((ap)+1)) + (ap)->ar_hln) -#define ar_tha(ap) (((caddr_t)((ap)+1)) + (ap)->ar_hln + (ap)->ar_pln) -#define ar_tpa(ap) (((caddr_t)((ap)+1)) + 2*(ap)->ar_hln + (ap)->ar_pln) - -#define arphdr_len2(ar_hln, ar_pln) \ - (sizeof(struct arphdr) + 2*(ar_hln) + 2*(ar_pln)) -#define arphdr_len(ap) (arphdr_len2((ap)->ar_hln, (ap)->ar_pln)) - -/* - * ARP ioctl request - */ -struct arpreq { - struct sockaddr arp_pa; /* protocol address */ - struct sockaddr arp_ha; /* hardware address */ - int arp_flags; /* flags */ -}; -/* arp_flags and at_flags field values */ -#define ATF_INUSE 0x01 /* entry in use */ -#define ATF_COM 0x02 /* completed entry (enaddr valid) */ -#define ATF_PERM 0x04 /* permanent entry */ -#define ATF_PUBL 0x08 /* publish entry (respond for other host) */ -#define ATF_USETRAILERS 0x10 /* has requested trailers */ - -#ifdef _KERNEL -/* - * Structure shared between the ethernet driver modules and - * the address resolution code. - */ -struct arpcom { - struct ifnet *ac_ifp; /* network-visible interface */ - u_char _ac_enaddr[6]; /* ethernet hardware address */ - void *ac_netgraph; /* ng_ether(4) netgraph node info */ -}; -#define IFP2AC(ifp) ((struct arpcom *)(ifp->if_l2com)) -#define IFP2ENADDR(ifp) (IFP2AC(ifp)->_ac_enaddr) -#define AC2IFP(ac) ((ac)->ac_ifp) - -#endif - -#endif /* _FBSD_COMPAT_NET_IF_ARP_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/net/if_llc.h b/src/libs/compat/freebsd_network/compat/net/if_llc.h deleted file mode 100644 index ec4427fb47..0000000000 --- a/src/libs/compat/freebsd_network/compat/net/if_llc.h +++ /dev/null @@ -1,161 +0,0 @@ -/* $NetBSD: if_llc.h,v 1.12 1999/11/19 20:41:19 thorpej Exp $ */ - -/*- - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)if_llc.h 8.1 (Berkeley) 6/10/93 - * $FreeBSD: src/sys/net/if_llc.h,v 1.13 2006/12/01 17:50:11 imp Exp $ - */ - -#ifndef _NET_IF_LLC_H_ -#define _NET_IF_LLC_H_ - -/* - * IEEE 802.2 Link Level Control headers, for use in conjunction with - * 802.{3,4,5} media access control methods. - * - * Headers here do not use bit fields due to shortcommings in many - * compilers. - */ - -struct llc { - u_int8_t llc_dsap; - u_int8_t llc_ssap; - union { - struct { - u_int8_t control; - u_int8_t format_id; - u_int8_t class; - u_int8_t window_x2; - } __packed type_u; - struct { - u_int8_t num_snd_x2; - u_int8_t num_rcv_x2; - } __packed type_i; - struct { - u_int8_t control; - u_int8_t num_rcv_x2; - } __packed type_s; - struct { - u_int8_t control; - /* - * We cannot put the following fields in a structure because - * the structure rounding might cause padding. - */ - u_int8_t frmr_rej_pdu0; - u_int8_t frmr_rej_pdu1; - u_int8_t frmr_control; - u_int8_t frmr_control_ext; - u_int8_t frmr_cause; - } __packed type_frmr; - struct { - u_int8_t control; - u_int8_t org_code[3]; - u_int16_t ether_type; - } __packed type_snap; - struct { - u_int8_t control; - u_int8_t control_ext; - } __packed type_raw; - } __packed llc_un; -} __packed; - -struct frmrinfo { - u_int8_t frmr_rej_pdu0; - u_int8_t frmr_rej_pdu1; - u_int8_t frmr_control; - u_int8_t frmr_control_ext; - u_int8_t frmr_cause; -} __packed; - -#define llc_control llc_un.type_u.control -#define llc_control_ext llc_un.type_raw.control_ext -#define llc_fid llc_un.type_u.format_id -#define llc_class llc_un.type_u.class -#define llc_window llc_un.type_u.window_x2 -#define llc_frmrinfo llc_un.type_frmr.frmr_rej_pdu0 -#define llc_frmr_pdu0 llc_un.type_frmr.frmr_rej_pdu0 -#define llc_frmr_pdu1 llc_un.type_frmr.frmr_rej_pdu1 -#define llc_frmr_control llc_un.type_frmr.frmr_control -#define llc_frmr_control_ext llc_un.type_frmr.frmr_control_ext -#define llc_frmr_cause llc_un.type_frmr.frmr_cause -#define llc_snap llc_un.type_snap - -/* - * Don't use sizeof(struct llc_un) for LLC header sizes - */ -#define LLC_ISFRAMELEN 4 -#define LLC_UFRAMELEN 3 -#define LLC_FRMRLEN 7 -#define LLC_SNAPFRAMELEN 8 - -#ifdef CTASSERT -CTASSERT(sizeof (struct llc) == LLC_SNAPFRAMELEN); -#endif - -/* - * Unnumbered LLC format commands - */ -#define LLC_UI 0x3 -#define LLC_UI_P 0x13 -#define LLC_DISC 0x43 -#define LLC_DISC_P 0x53 -#define LLC_UA 0x63 -#define LLC_UA_P 0x73 -#define LLC_TEST 0xe3 -#define LLC_TEST_P 0xf3 -#define LLC_FRMR 0x87 -#define LLC_FRMR_P 0x97 -#define LLC_DM 0x0f -#define LLC_DM_P 0x1f -#define LLC_XID 0xaf -#define LLC_XID_P 0xbf -#define LLC_SABME 0x6f -#define LLC_SABME_P 0x7f - -/* - * Supervisory LLC commands - */ -#define LLC_RR 0x01 -#define LLC_RNR 0x05 -#define LLC_REJ 0x09 - -/* - * Info format - dummy only - */ -#define LLC_INFO 0x00 - -/* - * ISO PDTR 10178 contains among others - */ -#define LLC_8021D_LSAP 0x42 -#define LLC_X25_LSAP 0x7e -#define LLC_SNAP_LSAP 0xaa -#define LLC_ISO_LSAP 0xfe - -#endif /* _NET_IF_LLC_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/net/if_media.h b/src/libs/compat/freebsd_network/compat/net/if_media.h deleted file mode 100644 index a6ce67a709..0000000000 --- a/src/libs/compat/freebsd_network/compat/net/if_media.h +++ /dev/null @@ -1,672 +0,0 @@ -/* $NetBSD: if_media.h,v 1.3 1997/03/26 01:19:27 thorpej Exp $ */ -/* $FreeBSD: src/sys/net/if_media.h,v 1.43 2008/08/01 22:13:39 antoine Exp $ */ - -/*- - * Copyright (c) 1997 - * Jonathan Stone and Jason R. Thorpe. All rights reserved. - * - * This software is derived from information provided by Matt Thomas. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jonathan Stone - * and Jason R. Thorpe for the NetBSD Project. - * 4. The names of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _FBSD_COMPAT_NET_IF_MEDIA_H_ -#define _FBSD_COMPAT_NET_IF_MEDIA_H_ - -/* - * Prototypes and definitions for BSD/OS-compatible network interface - * media selection. - * - * Where it is safe to do so, this code strays slightly from the BSD/OS - * design. Software which uses the API (device drivers, basically) - * shouldn't notice any difference. - * - * Many thanks to Matt Thomas for providing the information necessary - * to implement this interface. - */ - -#ifdef _KERNEL - -#include - -/* - * Driver callbacks for media status and change requests. - */ -typedef int (*ifm_change_cb_t)(struct ifnet *ifp); -typedef void (*ifm_stat_cb_t)(struct ifnet *ifp, struct ifmediareq *req); - -/* - * In-kernel representation of a single supported media type. - */ -struct ifmedia_entry { - LIST_ENTRY(ifmedia_entry) ifm_list; - int ifm_media; /* description of this media attachment */ - int ifm_data; /* for driver-specific use */ - void *ifm_aux; /* for driver-specific use */ -}; - -/* - * One of these goes into a network interface's softc structure. - * It is used to keep general media state. - */ -struct ifmedia { - int ifm_mask; /* mask of changes we don't care about */ - int ifm_media; /* current user-set media word */ - struct ifmedia_entry *ifm_cur; /* currently selected media */ - LIST_HEAD(, ifmedia_entry) ifm_list; /* list of all supported media */ - ifm_change_cb_t ifm_change; /* media change driver callback */ - ifm_stat_cb_t ifm_status; /* media status driver callback */ -}; - -/* Initialize an interface's struct if_media field. */ -void ifmedia_init(struct ifmedia *ifm, int dontcare_mask, - ifm_change_cb_t change_callback, ifm_stat_cb_t status_callback); - -/* Remove all mediums from a struct ifmedia. */ -void ifmedia_removeall( struct ifmedia *ifm); - -/* Add one supported medium to a struct ifmedia. */ -void ifmedia_add(struct ifmedia *ifm, int mword, int data, void *aux); - -/* Add an array (of ifmedia_entry) media to a struct ifmedia. */ -void ifmedia_list_add(struct ifmedia *mp, struct ifmedia_entry *lp, - int count); - -/* Set default media type on initialization. */ -void ifmedia_set(struct ifmedia *ifm, int mword); - -/* Common ioctl function for getting/setting media, called by driver. */ -int ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, - struct ifmedia *ifm, u_long cmd); - -/* Compute baudrate for a given media. */ -uint64_t ifmedia_baudrate(int); - -#endif /*_KERNEL */ - -/* - * if_media Options word: - * Bits Use - * ---- ------- - * 0-4 Media variant - * 5-7 Media type - * 8-15 Type specific options - * 16-18 Mode (for multi-mode devices) - * 19 RFU - * 20-27 Shared (global) options - * 28-31 Instance - */ - -/* - * Ethernet - */ -#define IFM_ETHER 0x00000020 -#define IFM_10_T 3 /* 10BaseT - RJ45 */ -#define IFM_10_2 4 /* 10Base2 - Thinnet */ -#define IFM_10_5 5 /* 10Base5 - AUI */ -#define IFM_100_TX 6 /* 100BaseTX - RJ45 */ -#define IFM_100_FX 7 /* 100BaseFX - Fiber */ -#define IFM_100_T4 8 /* 100BaseT4 - 4 pair cat 3 */ -#define IFM_100_VG 9 /* 100VG-AnyLAN */ -#define IFM_100_T2 10 /* 100BaseT2 */ -#define IFM_1000_SX 11 /* 1000BaseSX - multi-mode fiber */ -#define IFM_10_STP 12 /* 10BaseT over shielded TP */ -#define IFM_10_FL 13 /* 10BaseFL - Fiber */ -#define IFM_1000_LX 14 /* 1000baseLX - single-mode fiber */ -#define IFM_1000_CX 15 /* 1000baseCX - 150ohm STP */ -#define IFM_1000_T 16 /* 1000baseT - 4 pair cat 5 */ -#define IFM_HPNA_1 17 /* HomePNA 1.0 (1Mb/s) */ -#define IFM_10G_LR 18 /* 10GBase-LR 1310nm Single-mode */ -#define IFM_10G_SR 19 /* 10GBase-SR 850nm Multi-mode */ -#define IFM_10G_CX4 20 /* 10GBase CX4 copper */ -#define IFM_2500_SX 21 /* 2500BaseSX - multi-mode fiber */ -#define IFM_UNKNOWN 25 /* media types not defined yet */ - - -/* note 31 is the max! */ - -#define IFM_ETH_MASTER 0x00000100 /* master mode (1000baseT) */ -#define IFM_ETH_RXPAUSE 0x00000200 /* receive PAUSE frames */ -#define IFM_ETH_TXPAUSE 0x00000400 /* transmit PAUSE frames */ - -/* - * Token ring - */ -#define IFM_TOKEN 0x00000040 -#define IFM_TOK_STP4 3 /* Shielded twisted pair 4m - DB9 */ -#define IFM_TOK_STP16 4 /* Shielded twisted pair 16m - DB9 */ -#define IFM_TOK_UTP4 5 /* Unshielded twisted pair 4m - RJ45 */ -#define IFM_TOK_UTP16 6 /* Unshielded twisted pair 16m - RJ45 */ -#define IFM_TOK_STP100 7 /* Shielded twisted pair 100m - DB9 */ -#define IFM_TOK_UTP100 8 /* Unshielded twisted pair 100m - RJ45 */ -#define IFM_TOK_ETR 0x00000200 /* Early token release */ -#define IFM_TOK_SRCRT 0x00000400 /* Enable source routing features */ -#define IFM_TOK_ALLR 0x00000800 /* All routes / Single route bcast */ -#define IFM_TOK_DTR 0x00002000 /* Dedicated token ring */ -#define IFM_TOK_CLASSIC 0x00004000 /* Classic token ring */ -#define IFM_TOK_AUTO 0x00008000 /* Automatic Dedicate/Classic token ring */ - -/* - * FDDI - */ -#define IFM_FDDI 0x00000060 -#define IFM_FDDI_SMF 3 /* Single-mode fiber */ -#define IFM_FDDI_MMF 4 /* Multi-mode fiber */ -#define IFM_FDDI_UTP 5 /* CDDI / UTP */ -#define IFM_FDDI_DA 0x00000100 /* Dual attach / single attach */ - -/* - * IEEE 802.11 Wireless - */ -#define IFM_IEEE80211 0x00000080 -/* NB: 0,1,2 are auto, manual, none defined below */ -#define IFM_IEEE80211_FH1 3 /* Frequency Hopping 1Mbps */ -#define IFM_IEEE80211_FH2 4 /* Frequency Hopping 2Mbps */ -#define IFM_IEEE80211_DS1 5 /* Direct Sequence 1Mbps */ -#define IFM_IEEE80211_DS2 6 /* Direct Sequence 2Mbps */ -#define IFM_IEEE80211_DS5 7 /* Direct Sequence 5.5Mbps */ -#define IFM_IEEE80211_DS11 8 /* Direct Sequence 11Mbps */ -#define IFM_IEEE80211_DS22 9 /* Direct Sequence 22Mbps */ -#define IFM_IEEE80211_OFDM6 10 /* OFDM 6Mbps */ -#define IFM_IEEE80211_OFDM9 11 /* OFDM 9Mbps */ -#define IFM_IEEE80211_OFDM12 12 /* OFDM 12Mbps */ -#define IFM_IEEE80211_OFDM18 13 /* OFDM 18Mbps */ -#define IFM_IEEE80211_OFDM24 14 /* OFDM 24Mbps */ -#define IFM_IEEE80211_OFDM36 15 /* OFDM 36Mbps */ -#define IFM_IEEE80211_OFDM48 16 /* OFDM 48Mbps */ -#define IFM_IEEE80211_OFDM54 17 /* OFDM 54Mbps */ -#define IFM_IEEE80211_OFDM72 18 /* OFDM 72Mbps */ -#define IFM_IEEE80211_DS354k 19 /* Direct Sequence 354Kbps */ -#define IFM_IEEE80211_DS512k 20 /* Direct Sequence 512Kbps */ -#define IFM_IEEE80211_OFDM3 21 /* OFDM 3Mbps */ -#define IFM_IEEE80211_OFDM4 22 /* OFDM 4.5Mbps */ -#define IFM_IEEE80211_OFDM27 23 /* OFDM 27Mbps */ -/* NB: not enough bits to express MCS fully */ -#define IFM_IEEE80211_MCS 24 /* HT MCS rate */ - -#define IFM_IEEE80211_ADHOC 0x00000100 /* Operate in Adhoc mode */ -#define IFM_IEEE80211_HOSTAP 0x00000200 /* Operate in Host AP mode */ -#define IFM_IEEE80211_IBSS 0x00000400 /* Operate in IBSS mode */ -#define IFM_IEEE80211_WDS 0x00000800 /* Operate in WDS mode */ -#define IFM_IEEE80211_TURBO 0x00001000 /* Operate in turbo mode */ -#define IFM_IEEE80211_MONITOR 0x00002000 /* Operate in monitor mode */ -#define IFM_IEEE80211_MBSS 0x00004000 /* Operate in MBSS mode */ - -/* operating mode for multi-mode devices */ -#define IFM_IEEE80211_11A 0x00010000 /* 5Ghz, OFDM mode */ -#define IFM_IEEE80211_11B 0x00020000 /* Direct Sequence mode */ -#define IFM_IEEE80211_11G 0x00030000 /* 2Ghz, CCK mode */ -#define IFM_IEEE80211_FH 0x00040000 /* 2Ghz, GFSK mode */ -#define IFM_IEEE80211_11NA 0x00050000 /* 5Ghz, HT mode */ -#define IFM_IEEE80211_11NG 0x00060000 /* 2Ghz, HT mode */ - -/* - * ATM - */ -#define IFM_ATM 0x000000a0 -#define IFM_ATM_UNKNOWN 3 -#define IFM_ATM_UTP_25 4 -#define IFM_ATM_TAXI_100 5 -#define IFM_ATM_TAXI_140 6 -#define IFM_ATM_MM_155 7 -#define IFM_ATM_SM_155 8 -#define IFM_ATM_UTP_155 9 -#define IFM_ATM_MM_622 10 -#define IFM_ATM_SM_622 11 -#define IFM_ATM_VIRTUAL 12 -#define IFM_ATM_SDH 0x00000100 /* SDH instead of SONET */ -#define IFM_ATM_NOSCRAMB 0x00000200 /* no scrambling */ -#define IFM_ATM_UNASSIGNED 0x00000400 /* unassigned cells */ - -/* - * CARP Common Address Redundancy Protocol - */ -#define IFM_CARP 0x000000c0 - -/* - * Shared media sub-types - */ -#define IFM_AUTO 0 /* Autoselect best media */ -#define IFM_MANUAL 1 /* Jumper/dipswitch selects media */ -#define IFM_NONE 2 /* Deselect all media */ - -/* - * Shared options - */ -#define IFM_FDX 0x00100000 /* Force full duplex */ -#define IFM_HDX 0x00200000 /* Force half duplex */ -#define IFM_FLOW 0x00400000 /* Enable hardware flow control */ -#define IFM_FLAG0 0x01000000 /* Driver defined flag */ -#define IFM_FLAG1 0x02000000 /* Driver defined flag */ -#define IFM_FLAG2 0x04000000 /* Driver defined flag */ -#define IFM_LOOP 0x08000000 /* Put hardware in loopback */ - -/* - * Masks - */ -#define IFM_NMASK 0x000000e0 /* Network type */ -#define IFM_TMASK 0x0000001f /* Media sub-type */ -#define IFM_IMASK 0xf0000000 /* Instance */ -#define IFM_ISHIFT 28 /* Instance shift */ -#define IFM_OMASK 0x0000ff00 /* Type specific options */ -#define IFM_MMASK 0x00070000 /* Mode */ -#define IFM_MSHIFT 16 /* Mode shift */ -#define IFM_GMASK 0x0ff00000 /* Global options */ - -/* - * Status bits - */ -#define IFM_AVALID 0x10000000 /* Active bit valid */ -#define IFM_ACTIVE 0x00800000 /* same as Haiku's */ - -/* Mask of "status valid" bits, for ifconfig(8). */ -#define IFM_STATUS_VALID IFM_AVALID - -/* List of "status valid" bits, for ifconfig(8). */ -#define IFM_STATUS_VALID_LIST { \ - IFM_AVALID, \ - 0 \ -} - -/* - * Macros to extract various bits of information from the media word. - */ -#define IFM_TYPE(x) ((x) & IFM_NMASK) -#define IFM_SUBTYPE(x) ((x) & IFM_TMASK) -#define IFM_TYPE_OPTIONS(x) ((x) & IFM_OMASK) -#define IFM_INST(x) (((x) & IFM_IMASK) >> IFM_ISHIFT) -#define IFM_OPTIONS(x) ((x) & (IFM_OMASK|IFM_GMASK)) -#define IFM_MODE(x) ((x) & IFM_MMASK) - -#define IFM_INST_MAX IFM_INST(IFM_IMASK) - -/* - * Macro to create a media word. - */ -#define IFM_MAKEWORD(type, subtype, options, instance) \ - ((type) | (subtype) | (options) | ((instance) << IFM_ISHIFT)) -#define IFM_MAKEMODE(mode) \ - (((mode) << IFM_MSHIFT) & IFM_MMASK) - -/* - * NetBSD extension not defined in the BSDI API. This is used in various - * places to get the canonical description for a given type/subtype. - * - * NOTE: all but the top-level type descriptions must contain NO whitespace! - * Otherwise, parsing these in ifconfig(8) would be a nightmare. - */ -struct ifmedia_description { - int ifmt_word; /* word value; may be masked */ - const char *ifmt_string; /* description */ -}; - -#define IFM_TYPE_DESCRIPTIONS { \ - { IFM_ETHER, "Ethernet" }, \ - { IFM_TOKEN, "Token ring" }, \ - { IFM_FDDI, "FDDI" }, \ - { IFM_IEEE80211, "IEEE 802.11 Wireless Ethernet" }, \ - { IFM_ATM, "ATM" }, \ - { IFM_CARP, "Common Address Redundancy Protocol" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_ETHERNET_DESCRIPTIONS { \ - { IFM_10_T, "10baseT/UTP" }, \ - { IFM_10_2, "10base2/BNC" }, \ - { IFM_10_5, "10base5/AUI" }, \ - { IFM_100_TX, "100baseTX" }, \ - { IFM_100_FX, "100baseFX" }, \ - { IFM_100_T4, "100baseT4" }, \ - { IFM_100_VG, "100baseVG" }, \ - { IFM_100_T2, "100baseT2" }, \ - { IFM_10_STP, "10baseSTP" }, \ - { IFM_10_FL, "10baseFL" }, \ - { IFM_1000_SX, "1000baseSX" }, \ - { IFM_1000_LX, "1000baseLX" }, \ - { IFM_1000_CX, "1000baseCX" }, \ - { IFM_1000_T, "1000baseT" }, \ - { IFM_HPNA_1, "homePNA" }, \ - { IFM_10G_LR, "10Gbase-LR" }, \ - { IFM_10G_SR, "10Gbase-SR" }, \ - { IFM_10G_CX4, "10Gbase-CX4" }, \ - { IFM_UNKNOWN, "Unknown" }, \ - { IFM_2500_SX, "2500BaseSX" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_ETHERNET_ALIASES { \ - { IFM_10_T, "UTP" }, \ - { IFM_10_T, "10UTP" }, \ - { IFM_10_2, "BNC" }, \ - { IFM_10_2, "10BNC" }, \ - { IFM_10_5, "AUI" }, \ - { IFM_10_5, "10AUI" }, \ - { IFM_100_TX, "100TX" }, \ - { IFM_100_T4, "100T4" }, \ - { IFM_100_VG, "100VG" }, \ - { IFM_100_T2, "100T2" }, \ - { IFM_10_STP, "10STP" }, \ - { IFM_10_FL, "10FL" }, \ - { IFM_1000_SX, "1000SX" }, \ - { IFM_1000_LX, "1000LX" }, \ - { IFM_1000_CX, "1000CX" }, \ - { IFM_1000_T, "1000baseTX" }, \ - { IFM_1000_T, "1000TX" }, \ - { IFM_1000_T, "1000T" }, \ - { IFM_2500_SX, "2500SX" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS { \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_TOKENRING_DESCRIPTIONS { \ - { IFM_TOK_STP4, "DB9/4Mbit" }, \ - { IFM_TOK_STP16, "DB9/16Mbit" }, \ - { IFM_TOK_UTP4, "UTP/4Mbit" }, \ - { IFM_TOK_UTP16, "UTP/16Mbit" }, \ - { IFM_TOK_STP100, "STP/100Mbit" }, \ - { IFM_TOK_UTP100, "UTP/100Mbit" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_TOKENRING_ALIASES { \ - { IFM_TOK_STP4, "4STP" }, \ - { IFM_TOK_STP16, "16STP" }, \ - { IFM_TOK_UTP4, "4UTP" }, \ - { IFM_TOK_UTP16, "16UTP" }, \ - { IFM_TOK_STP100, "100STP" }, \ - { IFM_TOK_UTP100, "100UTP" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS { \ - { IFM_TOK_ETR, "EarlyTokenRelease" }, \ - { IFM_TOK_SRCRT, "SourceRouting" }, \ - { IFM_TOK_ALLR, "AllRoutes" }, \ - { IFM_TOK_DTR, "Dedicated" }, \ - { IFM_TOK_CLASSIC,"Classic" }, \ - { IFM_TOK_AUTO, " " }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_FDDI_DESCRIPTIONS { \ - { IFM_FDDI_SMF, "Single-mode" }, \ - { IFM_FDDI_MMF, "Multi-mode" }, \ - { IFM_FDDI_UTP, "UTP" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_FDDI_ALIASES { \ - { IFM_FDDI_SMF, "SMF" }, \ - { IFM_FDDI_MMF, "MMF" }, \ - { IFM_FDDI_UTP, "CDDI" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS { \ - { IFM_FDDI_DA, "Dual-attach" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_IEEE80211_DESCRIPTIONS { \ - { IFM_IEEE80211_FH1, "FH/1Mbps" }, \ - { IFM_IEEE80211_FH2, "FH/2Mbps" }, \ - { IFM_IEEE80211_DS1, "DS/1Mbps" }, \ - { IFM_IEEE80211_DS2, "DS/2Mbps" }, \ - { IFM_IEEE80211_DS5, "DS/5.5Mbps" }, \ - { IFM_IEEE80211_DS11, "DS/11Mbps" }, \ - { IFM_IEEE80211_DS22, "DS/22Mbps" }, \ - { IFM_IEEE80211_OFDM6, "OFDM/6Mbps" }, \ - { IFM_IEEE80211_OFDM9, "OFDM/9Mbps" }, \ - { IFM_IEEE80211_OFDM12, "OFDM/12Mbps" }, \ - { IFM_IEEE80211_OFDM18, "OFDM/18Mbps" }, \ - { IFM_IEEE80211_OFDM24, "OFDM/24Mbps" }, \ - { IFM_IEEE80211_OFDM36, "OFDM/36Mbps" }, \ - { IFM_IEEE80211_OFDM48, "OFDM/48Mbps" }, \ - { IFM_IEEE80211_OFDM54, "OFDM/54Mbps" }, \ - { IFM_IEEE80211_OFDM72, "OFDM/72Mbps" }, \ - { IFM_IEEE80211_DS354k, "DS/354Kbps" }, \ - { IFM_IEEE80211_DS512k, "DS/512Kbps" }, \ - { IFM_IEEE80211_OFDM3, "OFDM/3Mbps" }, \ - { IFM_IEEE80211_OFDM4, "OFDM/4.5Mbps" }, \ - { IFM_IEEE80211_OFDM27, "OFDM/27Mbps" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_IEEE80211_ALIASES { \ - { IFM_IEEE80211_FH1, "FH1" }, \ - { IFM_IEEE80211_FH2, "FH2" }, \ - { IFM_IEEE80211_FH1, "FrequencyHopping/1Mbps" }, \ - { IFM_IEEE80211_FH2, "FrequencyHopping/2Mbps" }, \ - { IFM_IEEE80211_DS1, "DS1" }, \ - { IFM_IEEE80211_DS2, "DS2" }, \ - { IFM_IEEE80211_DS5, "DS5.5" }, \ - { IFM_IEEE80211_DS11, "DS11" }, \ - { IFM_IEEE80211_DS22, "DS22" }, \ - { IFM_IEEE80211_DS1, "DirectSequence/1Mbps" }, \ - { IFM_IEEE80211_DS2, "DirectSequence/2Mbps" }, \ - { IFM_IEEE80211_DS5, "DirectSequence/5.5Mbps" }, \ - { IFM_IEEE80211_DS11, "DirectSequence/11Mbps" }, \ - { IFM_IEEE80211_DS22, "DirectSequence/22Mbps" }, \ - { IFM_IEEE80211_OFDM6, "OFDM6" }, \ - { IFM_IEEE80211_OFDM9, "OFDM9" }, \ - { IFM_IEEE80211_OFDM12, "OFDM12" }, \ - { IFM_IEEE80211_OFDM18, "OFDM18" }, \ - { IFM_IEEE80211_OFDM24, "OFDM24" }, \ - { IFM_IEEE80211_OFDM36, "OFDM36" }, \ - { IFM_IEEE80211_OFDM48, "OFDM48" }, \ - { IFM_IEEE80211_OFDM54, "OFDM54" }, \ - { IFM_IEEE80211_OFDM72, "OFDM72" }, \ - { IFM_IEEE80211_DS1, "CCK1" }, \ - { IFM_IEEE80211_DS2, "CCK2" }, \ - { IFM_IEEE80211_DS5, "CCK5.5" }, \ - { IFM_IEEE80211_DS11, "CCK11" }, \ - { IFM_IEEE80211_DS354k, "DS354K" }, \ - { IFM_IEEE80211_DS354k, "DirectSequence/354Kbps" }, \ - { IFM_IEEE80211_DS512k, "DS512K" }, \ - { IFM_IEEE80211_DS512k, "DirectSequence/512Kbps" }, \ - { IFM_IEEE80211_OFDM3, "OFDM3" }, \ - { IFM_IEEE80211_OFDM4, "OFDM4.5" }, \ - { IFM_IEEE80211_OFDM27, "OFDM27" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS { \ - { IFM_IEEE80211_ADHOC, "adhoc" }, \ - { IFM_IEEE80211_HOSTAP, "hostap" }, \ - { IFM_IEEE80211_IBSS, "ibss" }, \ - { IFM_IEEE80211_WDS, "wds" }, \ - { IFM_IEEE80211_TURBO, "turbo" }, \ - { IFM_IEEE80211_MONITOR, "monitor" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS { \ - { IFM_AUTO, "autoselect" }, \ - { IFM_IEEE80211_11A, "11a" }, \ - { IFM_IEEE80211_11B, "11b" }, \ - { IFM_IEEE80211_11G, "11g" }, \ - { IFM_IEEE80211_FH, "fh" }, \ - { IFM_IEEE80211_11NA, "11na" }, \ - { IFM_IEEE80211_11NG, "11ng" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_IEEE80211_MODE_ALIASES { \ - { IFM_AUTO, "auto" }, \ - { 0, NULL }, \ -} - -# define IFM_SUBTYPE_ATM_DESCRIPTIONS { \ - { IFM_ATM_UNKNOWN, "Unknown" }, \ - { IFM_ATM_UTP_25, "UTP/25.6MBit" }, \ - { IFM_ATM_TAXI_100, "Taxi/100MBit" }, \ - { IFM_ATM_TAXI_140, "Taxi/140MBit" }, \ - { IFM_ATM_MM_155, "Multi-mode/155MBit" }, \ - { IFM_ATM_SM_155, "Single-mode/155MBit" }, \ - { IFM_ATM_UTP_155, "UTP/155MBit" }, \ - { IFM_ATM_MM_622, "Multi-mode/622MBit" }, \ - { IFM_ATM_SM_622, "Single-mode/622MBit" }, \ - { IFM_ATM_VIRTUAL, "Virtual" }, \ - { 0, NULL }, \ -} - -# define IFM_SUBTYPE_ATM_ALIASES { \ - { IFM_ATM_UNKNOWN, "UNKNOWN" }, \ - { IFM_ATM_UTP_25, "UTP-25" }, \ - { IFM_ATM_TAXI_100, "TAXI-100" }, \ - { IFM_ATM_TAXI_140, "TAXI-140" }, \ - { IFM_ATM_MM_155, "MM-155" }, \ - { IFM_ATM_SM_155, "SM-155" }, \ - { IFM_ATM_UTP_155, "UTP-155" }, \ - { IFM_ATM_MM_622, "MM-622" }, \ - { IFM_ATM_SM_622, "SM-622" }, \ - { IFM_ATM_VIRTUAL, "VIRTUAL" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS { \ - { IFM_ATM_SDH, "SDH" }, \ - { IFM_ATM_NOSCRAMB, "Noscramb" }, \ - { IFM_ATM_UNASSIGNED, "Unassigned" }, \ - { 0, NULL }, \ -} - - -#define IFM_SUBTYPE_SHARED_DESCRIPTIONS { \ - { IFM_AUTO, "autoselect" }, \ - { IFM_MANUAL, "manual" }, \ - { IFM_NONE, "none" }, \ - { 0, NULL }, \ -} - -#define IFM_SUBTYPE_SHARED_ALIASES { \ - { IFM_AUTO, "auto" }, \ - { 0, NULL }, \ -} - -#define IFM_SHARED_OPTION_DESCRIPTIONS { \ - { IFM_FDX, "full-duplex" }, \ - { IFM_HDX, "half-duplex" }, \ - { IFM_FLAG0, "flag0" }, \ - { IFM_FLAG1, "flag1" }, \ - { IFM_FLAG2, "flag2" }, \ - { IFM_LOOP, "hw-loopback" }, \ - { 0, NULL }, \ -} - -/* - * Baudrate descriptions for the various media types. - */ -struct ifmedia_baudrate { - int ifmb_word; /* media word */ - uint64_t ifmb_baudrate; /* corresponding baudrate */ -}; - -#define IFM_BAUDRATE_DESCRIPTIONS { \ - { IFM_ETHER | IFM_10_T, IF_Mbps(10) }, \ - { IFM_ETHER | IFM_10_2, IF_Mbps(10) }, \ - { IFM_ETHER | IFM_10_5, IF_Mbps(10) }, \ - { IFM_ETHER | IFM_100_TX, IF_Mbps(100) }, \ - { IFM_ETHER | IFM_100_FX, IF_Mbps(100) }, \ - { IFM_ETHER | IFM_100_T4, IF_Mbps(100) }, \ - { IFM_ETHER | IFM_100_VG, IF_Mbps(100) }, \ - { IFM_ETHER | IFM_100_T2, IF_Mbps(100) }, \ - { IFM_ETHER | IFM_1000_SX, IF_Mbps(1000) }, \ - { IFM_ETHER | IFM_10_STP, IF_Mbps(10) }, \ - { IFM_ETHER | IFM_10_FL, IF_Mbps(10) }, \ - { IFM_ETHER | IFM_1000_LX, IF_Mbps(1000) }, \ - { IFM_ETHER | IFM_1000_CX, IF_Mbps(1000) }, \ - { IFM_ETHER | IFM_1000_T, IF_Mbps(1000) }, \ - { IFM_ETHER | IFM_HPNA_1, IF_Mbps(1) }, \ - { IFM_ETHER | IFM_10G_LR, IF_Gbps(10ULL) }, \ - { IFM_ETHER | IFM_10G_SR, IF_Gbps(10ULL) }, \ - { IFM_ETHER | IFM_10G_CX4, IF_Gbps(10ULL) }, \ - { IFM_ETHER | IFM_2500_SX, IF_Mbps(2500ULL) }, \ - \ - { IFM_TOKEN | IFM_TOK_STP4, IF_Mbps(4) }, \ - { IFM_TOKEN | IFM_TOK_STP16, IF_Mbps(16) }, \ - { IFM_TOKEN | IFM_TOK_UTP4, IF_Mbps(4) }, \ - { IFM_TOKEN | IFM_TOK_UTP16, IF_Mbps(16) }, \ - \ - { IFM_FDDI | IFM_FDDI_SMF, IF_Mbps(100) }, \ - { IFM_FDDI | IFM_FDDI_MMF, IF_Mbps(100) }, \ - { IFM_FDDI | IFM_FDDI_UTP, IF_Mbps(100) }, \ - \ - { IFM_IEEE80211 | IFM_IEEE80211_FH1, IF_Mbps(1) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_FH2, IF_Mbps(2) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_DS2, IF_Mbps(2) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_DS5, IF_Kbps(5500) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_DS11, IF_Mbps(11) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_DS1, IF_Mbps(1) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_DS22, IF_Mbps(22) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_OFDM6, IF_Mbps(6) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_OFDM9, IF_Mbps(9) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_OFDM12, IF_Mbps(12) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_OFDM18, IF_Mbps(18) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_OFDM24, IF_Mbps(24) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_OFDM36, IF_Mbps(36) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_OFDM48, IF_Mbps(48) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_OFDM54, IF_Mbps(54) }, \ - { IFM_IEEE80211 | IFM_IEEE80211_OFDM72, IF_Mbps(72) }, \ - \ - { 0, 0 }, \ -} - -/* - * Status descriptions for the various media types. - */ -struct ifmedia_status_description { - int ifms_type; - int ifms_valid; - int ifms_bit; - const char *ifms_string[2]; -}; - -#define IFM_STATUS_DESC(ifms, bit) \ - (ifms)->ifms_string[((ifms)->ifms_bit & (bit)) ? 1 : 0] - -#define IFM_STATUS_DESCRIPTIONS { \ - { IFM_ETHER, IFM_AVALID, IFM_ACTIVE, \ - { "no carrier", "active" } }, \ - { IFM_FDDI, IFM_AVALID, IFM_ACTIVE, \ - { "no ring", "inserted" } }, \ - { IFM_TOKEN, IFM_AVALID, IFM_ACTIVE, \ - { "no ring", "inserted" } }, \ - { IFM_IEEE80211, IFM_AVALID, IFM_ACTIVE, \ - { "no network", "active" } }, \ - { IFM_ATM, IFM_AVALID, IFM_ACTIVE, \ - { "no network", "active" } }, \ - { IFM_CARP, IFM_AVALID, IFM_ACTIVE, \ - { "backup", "master" } }, \ - { 0, 0, 0, \ - { NULL, NULL } } \ -} -#endif /* _FBSD_COMPAT_NET_IF_MEDIA_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/net/if_types.h b/src/libs/compat/freebsd_network/compat/net/if_types.h deleted file mode 100644 index 25766e4b1a..0000000000 --- a/src/libs/compat/freebsd_network/compat/net/if_types.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_NET_IF_TYPES_H_ -#define _FBSD_COMPAT_NET_IF_TYPES_H_ - - -#include - - -#define IFT_IEEE80211 0x47 - -#endif /* _FBSD_COMPAT_NET_IF_TYPES_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/net/if_var.h b/src/libs/compat/freebsd_network/compat/net/if_var.h deleted file mode 100644 index 6a766f5bd0..0000000000 --- a/src/libs/compat/freebsd_network/compat/net/if_var.h +++ /dev/null @@ -1,696 +0,0 @@ -/*- - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * From: @(#)if.h 8.1 (Berkeley) 6/10/93 - * $FreeBSD: src/sys/net/if_var.h,v 1.98.2.6 2006/10/06 20:26:05 andre Exp $ - */ - -#ifndef _FBSD_COMPAT_NET_IF_VAR_H_ -#define _FBSD_COMPAT_NET_IF_VAR_H_ - -/* - * Structures defining a network interface, providing a packet - * transport mechanism (ala level 0 of the PUP protocols). - * - * Each interface accepts output datagrams of a specified maximum - * length, and provides higher level routines with input datagrams - * received from its medium. - * - * Output occurs when the routine if_output is called, with three parameters: - * (*ifp->if_output)(ifp, m, dst, rt) - * Here m is the mbuf chain to be sent and dst is the destination address. - * The output routine encapsulates the supplied datagram if necessary, - * and then transmits it on its medium. - * - * On input, each interface unwraps the data received by it, and either - * places it on the input queue of an internetwork datagram routine - * and posts the associated software interrupt, or passes the datagram to a raw - * packet input routine. - * - * Routines exist for locating interfaces by their addresses - * or for locating an interface on a certain network, as well as more general - * routing and gateway routines maintaining information used to locate - * interfaces. These routines live in the files if.c and route.c - */ - -#ifdef __STDC__ -/* - * Forward structure declarations for function prototypes [sic]. - */ -struct mbuf; -struct thread; -struct rtentry; -struct rt_addrinfo; -struct socket; -struct ether_header; -struct carp_if; -struct route; -#endif - -#include - -#include /* get TAILQ macros */ - -#ifdef _KERNEL -#include -#include -#endif /* _KERNEL */ -#include /* XXX */ -#include /* XXX */ -#include /* XXX */ -#include - -#define IF_DUNIT_NONE -1 - -#include - -typedef enum { - IFCOUNTER_IPACKETS = 0, - IFCOUNTER_IERRORS, - IFCOUNTER_OPACKETS, - IFCOUNTER_OERRORS, - IFCOUNTER_COLLISIONS, - IFCOUNTER_IBYTES, - IFCOUNTER_OBYTES, - IFCOUNTER_IMCASTS, - IFCOUNTER_OMCASTS, - IFCOUNTER_IQDROPS, - IFCOUNTER_OQDROPS, - IFCOUNTER_NOPROTO, - IFCOUNTERS /* Array size. */ -} ift_counter; - -TAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */ -TAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */ -TAILQ_HEAD(ifprefixhead, ifprefix); -TAILQ_HEAD(ifmultihead, ifmultiaddr); - -/* - * Structure defining a queue for a network interface. - */ -struct ifqueue { - struct mbuf *ifq_head; - struct mbuf *ifq_tail; - int ifq_len; - int ifq_maxlen; - int ifq_drops; - struct mtx ifq_mtx; -}; - -struct device; - -/* - * Structure defining a network interface. - * - * (Would like to call this struct ``if'', but C isn't PL/1.) - */ - -struct ifnet { - void *if_softc; /* pointer to driver state */ - void *if_l2com; /* pointer to protocol bits */ - TAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained */ - char if_xname[IFNAMSIZ]; /* external name (name + unit) */ - const char *if_dname; /* driver name */ - int if_dunit; /* unit or IF_DUNIT_NONE */ - struct ifaddrhead if_addrhead; /* linked list of addresses per if */ - /* - * if_addrhead is the list of all addresses associated to - * an interface. - * Some code in the kernel assumes that first element - * of the list has type AF_LINK, and contains sockaddr_dl - * addresses which store the link-level address and the name - * of the interface. - * However, access to the AF_LINK address through this - * field is deprecated. Use ifaddr_byindex() instead. - */ - struct knlist if_klist; /* events attached to this if */ - int if_pcount; /* number of promiscuous listeners */ - struct carp_if *if_carp; /* carp interface structure */ - struct bpf_if *if_bpf; /* packet filter structure */ - u_short if_index; /* numeric abbreviation for this if */ - short if_timer; /* time 'til if_watchdog called */ - struct ifvlantrunk *if_vlantrunk; /* pointer to 802.1q data */ - int if_flags; /* up/down, broadcast, etc. */ - int if_capabilities; /* interface capabilities */ - int if_capenable; /* enabled features */ - void *if_linkmib; /* link-type-specific MIB data */ - size_t if_linkmiblen; /* length of above data */ - struct if_data if_data; - struct ifmultihead if_multiaddrs; /* multicast addresses configured */ - int if_amcount; /* number of all-multicast requests */ -/* procedure handles */ - int (*if_output) /* output routine (enqueue) */ - (struct ifnet *, struct mbuf *, struct sockaddr *, - struct route *); - void (*if_input) /* input routine (from h/w driver) */ - (struct ifnet *, struct mbuf *); - void (*if_start) /* initiate output routine */ - (struct ifnet *); - int (*if_ioctl) /* ioctl routine */ - (struct ifnet *, u_long, caddr_t); - void (*if_watchdog) /* timer routine */ - (struct ifnet *); - void (*if_init) /* Init routine */ - (void *); - int (*if_resolvemulti) /* validate/resolve multicast */ - (struct ifnet *, struct sockaddr **, struct sockaddr *); - int (*if_transmit) /* initiate output routine */ - (struct ifnet *, struct mbuf *); - void *if_spare1; /* spare pointer 1 */ - void *if_spare2; /* spare pointer 2 */ - void *if_spare3; /* spare pointer 3 */ - int if_drv_flags; /* driver-managed status flags */ - u_int if_spare_flags2; /* spare flags 2 */ - struct ifaltq if_snd; /* output queue (includes altq) */ - const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */ - - void *if_bridge; /* bridge glue */ - - struct lltable *lltables; /* list of L3-L2 resolution tables */ - - struct label *if_label; /* interface MAC label */ - - /* these are only used by IPv6 */ - struct ifprefixhead if_prefixhead; /* list of prefixes per if */ - void *if_afdata[AF_MAX]; - int if_afdata_initialized; - struct mtx if_afdata_mtx; - struct task if_starttask; /* task for IFF_NEEDSGIANT */ - struct task if_linktask; /* task for link change events */ - struct mtx if_addr_mtx; /* mutex to protect address lists */ - - /* Haiku additions */ - struct sockaddr_dl if_lladdr; - char device_name[128]; - struct device *root_device; - struct ifqueue receive_queue; - sem_id receive_sem; - sem_id link_state_sem; - int32 open_count; - int32 flags; - - /* WLAN specific additions */ - sem_id scan_done_sem; -}; - -typedef void if_init_f_t(void *); - -/* - * XXX These aliases are terribly dangerous because they could apply - * to anything. - */ -#define if_mtu if_data.ifi_mtu -#define if_type if_data.ifi_type -#define if_physical if_data.ifi_physical -#define if_addrlen if_data.ifi_addrlen -#define if_hdrlen if_data.ifi_hdrlen -#define if_metric if_data.ifi_metric -#define if_link_state if_data.ifi_link_state -#define if_baudrate if_data.ifi_baudrate -#define if_hwassist if_data.ifi_hwassist -#define if_ipackets if_data.ifi_ipackets -#define if_ierrors if_data.ifi_ierrors -#define if_opackets if_data.ifi_opackets -#define if_oerrors if_data.ifi_oerrors -#define if_collisions if_data.ifi_collisions -#define if_ibytes if_data.ifi_ibytes -#define if_obytes if_data.ifi_obytes -#define if_imcasts if_data.ifi_imcasts -#define if_omcasts if_data.ifi_omcasts -#define if_iqdrops if_data.ifi_iqdrops -#define if_oqdrops if_data.ifi_oqdrops -#define if_noproto if_data.ifi_noproto -#define if_lastchange if_data.ifi_lastchange -#define if_recvquota if_data.ifi_recvquota -#define if_xmitquota if_data.ifi_xmitquota -#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct route *)NULL) - -/* for compatibility with other BSDs */ -#define if_addrlist if_addrhead -#define if_list if_link - -/* - * Locks for address lists on the network interface. - */ -#define IF_ADDR_LOCK_INIT(if) mtx_init(&(if)->if_addr_mtx, \ - "if_addr_mtx", NULL, MTX_DEF) -#define IF_ADDR_LOCK_DESTROY(if) mtx_destroy(&(if)->if_addr_mtx) -#define IF_ADDR_LOCK(if) mtx_lock(&(if)->if_addr_mtx) -#define IF_ADDR_UNLOCK(if) mtx_unlock(&(if)->if_addr_mtx) -#define IF_ADDR_LOCK_ASSERT(if) mtx_assert(&(if)->if_addr_mtx, MA_OWNED) - -void if_addr_rlock(struct ifnet *ifp); /* if_addrhead */ -void if_addr_runlock(struct ifnet *ifp); /* if_addrhead */ -void if_maddr_rlock(struct ifnet *ifp); /* if_multiaddrs */ -void if_maddr_runlock(struct ifnet *ifp); /* if_multiaddrs */ - -/* - * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq) - * are queues of messages stored on ifqueue structures - * (defined above). Entries are added to and deleted from these structures - * by these macros, which should be called with ipl raised to splimp(). - */ -#define IF_LOCK(ifq) mtx_lock(&(ifq)->ifq_mtx) -#define IF_UNLOCK(ifq) mtx_unlock(&(ifq)->ifq_mtx) -#define IF_LOCK_ASSERT(ifq) mtx_assert(&(ifq)->ifq_mtx, MA_OWNED) -#define _IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) -#define _IF_DROP(ifq) ((ifq)->ifq_drops++) -#define _IF_QLEN(ifq) ((ifq)->ifq_len) - -#define _IF_ENQUEUE(ifq, m) do { \ - (m)->m_nextpkt = NULL; \ - if ((ifq)->ifq_tail == NULL) \ - (ifq)->ifq_head = m; \ - else \ - (ifq)->ifq_tail->m_nextpkt = m; \ - (ifq)->ifq_tail = m; \ - (ifq)->ifq_len++; \ -} while (0) - -#define IF_ENQUEUE(ifq, m) do { \ - IF_LOCK(ifq); \ - _IF_ENQUEUE(ifq, m); \ - IF_UNLOCK(ifq); \ -} while (0) - -#define _IF_PREPEND(ifq, m) do { \ - (m)->m_nextpkt = (ifq)->ifq_head; \ - if ((ifq)->ifq_tail == NULL) \ - (ifq)->ifq_tail = (m); \ - (ifq)->ifq_head = (m); \ - (ifq)->ifq_len++; \ -} while (0) - -#define IF_PREPEND(ifq, m) do { \ - IF_LOCK(ifq); \ - _IF_PREPEND(ifq, m); \ - IF_UNLOCK(ifq); \ -} while (0) - -#define _IF_DEQUEUE(ifq, m) do { \ - (m) = (ifq)->ifq_head; \ - if (m) { \ - if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL) \ - (ifq)->ifq_tail = NULL; \ - (m)->m_nextpkt = NULL; \ - (ifq)->ifq_len--; \ - } \ -} while (0) - -#define IF_DEQUEUE(ifq, m) do { \ - IF_LOCK(ifq); \ - _IF_DEQUEUE(ifq, m); \ - IF_UNLOCK(ifq); \ -} while (0) - -#define _IF_POLL(ifq, m) ((m) = (ifq)->ifq_head) -#define IF_POLL(ifq, m) _IF_POLL(ifq, m) - -#define _IF_DRAIN(ifq) do { \ - struct mbuf *m; \ - for (;;) { \ - _IF_DEQUEUE(ifq, m); \ - if (m == NULL) \ - break; \ - m_freem(m); \ - } \ -} while (0) - -#define IF_DRAIN(ifq) do { \ - IF_LOCK(ifq); \ - _IF_DRAIN(ifq); \ - IF_UNLOCK(ifq); \ -} while(0) - -#ifdef _KERNEL -/* interface address change event */ -typedef void (*ifaddr_event_handler_t)(void *, struct ifnet *); -EVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t); -/* new interface arrival event */ -typedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *); -EVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t); -/* interface departure event */ -typedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *); -EVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t); - -#define IF_AFDATA_LOCK_INIT(ifp) \ - mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, MTX_DEF) -#define IF_AFDATA_LOCK(ifp) mtx_lock(&(ifp)->if_afdata_mtx) -#define IF_AFDATA_TRYLOCK(ifp) mtx_trylock(&(ifp)->if_afdata_mtx) -#define IF_AFDATA_UNLOCK(ifp) mtx_unlock(&(ifp)->if_afdata_mtx) -#define IF_AFDATA_DESTROY(ifp) mtx_destroy(&(ifp)->if_afdata_mtx) - -#define IFF_LOCKGIANT(ifp) do { \ - if ((ifp)->if_flags & IFF_NEEDSGIANT) \ - mtx_lock(&Giant); \ -} while (0) - -#define IFF_UNLOCKGIANT(ifp) do { \ - if ((ifp)->if_flags & IFF_NEEDSGIANT) \ - mtx_unlock(&Giant); \ -} while (0) - -int if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, - int adjust); -#define IF_HANDOFF(ifq, m, ifp) \ - if_handoff((struct ifqueue *)ifq, m, ifp, 0) -#define IF_HANDOFF_ADJ(ifq, m, ifp, adj) \ - if_handoff((struct ifqueue *)ifq, m, ifp, adj) - -void if_start(struct ifnet *); - -#define IFQ_ENQUEUE(ifq, m, err) \ -do { \ - IF_LOCK(ifq); \ - if (ALTQ_IS_ENABLED(ifq)) \ - ALTQ_ENQUEUE(ifq, m, NULL, err); \ - else { \ - if (_IF_QFULL(ifq)) { \ - m_freem(m); \ - (err) = ENOBUFS; \ - } else { \ - _IF_ENQUEUE(ifq, m); \ - (err) = 0; \ - } \ - } \ - if (err) \ - (ifq)->ifq_drops++; \ - IF_UNLOCK(ifq); \ -} while (0) - -#define IFQ_DEQUEUE_NOLOCK(ifq, m) \ -do { \ - if (TBR_IS_ENABLED(ifq)) \ - (m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE); \ - else if (ALTQ_IS_ENABLED(ifq)) \ - ALTQ_DEQUEUE(ifq, m); \ - else \ - _IF_DEQUEUE(ifq, m); \ -} while (0) - -#define IFQ_DEQUEUE(ifq, m) \ -do { \ - IF_LOCK(ifq); \ - IFQ_DEQUEUE_NOLOCK(ifq, m); \ - IF_UNLOCK(ifq); \ -} while (0) - -#define IFQ_POLL_NOLOCK(ifq, m) \ -do { \ - if (TBR_IS_ENABLED(ifq)) \ - (m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL); \ - else if (ALTQ_IS_ENABLED(ifq)) \ - ALTQ_POLL(ifq, m); \ - else \ - _IF_POLL(ifq, m); \ -} while (0) - -#define IFQ_POLL(ifq, m) \ -do { \ - IF_LOCK(ifq); \ - IFQ_POLL_NOLOCK(ifq, m); \ - IF_UNLOCK(ifq); \ -} while (0) - -#define IFQ_PURGE_NOLOCK(ifq) \ -do { \ - if (ALTQ_IS_ENABLED(ifq)) { \ - ALTQ_PURGE(ifq); \ - } else \ - _IF_DRAIN(ifq); \ -} while (0) - -#define IFQ_PURGE(ifq) \ -do { \ - IF_LOCK(ifq); \ - IFQ_PURGE_NOLOCK(ifq); \ - IF_UNLOCK(ifq); \ -} while (0) - -#define IFQ_SET_READY(ifq) \ - do { ((ifq)->altq_flags |= ALTQF_READY); } while (0) - -#define IFQ_LOCK(ifq) IF_LOCK(ifq) -#define IFQ_UNLOCK(ifq) IF_UNLOCK(ifq) -#define IFQ_LOCK_ASSERT(ifq) IF_LOCK_ASSERT(ifq) -#define IFQ_IS_EMPTY(ifq) ((ifq)->ifq_len == 0) -#define IFQ_INC_LEN(ifq) ((ifq)->ifq_len++) -#define IFQ_DEC_LEN(ifq) (--(ifq)->ifq_len) -#define IFQ_INC_DROPS(ifq) ((ifq)->ifq_drops++) -#define IFQ_SET_MAXLEN(ifq, len) ((ifq)->ifq_maxlen = (len)) - -/* - * The IFF_DRV_OACTIVE test should really occur in the device driver, not in - * the handoff logic, as that flag is locked by the device driver. - */ -#define IFQ_HANDOFF_ADJ(ifp, m, adj, err) \ -do { \ - int len; \ - short mflags; \ - \ - len = (m)->m_pkthdr.len; \ - mflags = (m)->m_flags; \ - IFQ_ENQUEUE(&(ifp)->if_snd, m, err); \ - if ((err) == 0) { \ - (ifp)->if_obytes += len + (adj); \ - if (mflags & M_MCAST) \ - (ifp)->if_omcasts++; \ - if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0) \ - if_start(ifp); \ - } \ -} while (0) - -#define IFQ_HANDOFF(ifp, m, err) \ - IFQ_HANDOFF_ADJ(ifp, m, 0, err) - -#define IFQ_DRV_DEQUEUE(ifq, m) \ -do { \ - (m) = (ifq)->ifq_drv_head; \ - if (m) { \ - if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL) \ - (ifq)->ifq_drv_tail = NULL; \ - (m)->m_nextpkt = NULL; \ - (ifq)->ifq_drv_len--; \ - } else { \ - IFQ_LOCK(ifq); \ - IFQ_DEQUEUE_NOLOCK(ifq, m); \ - while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) { \ - struct mbuf *m0; \ - IFQ_DEQUEUE_NOLOCK(ifq, m0); \ - if (m0 == NULL) \ - break; \ - m0->m_nextpkt = NULL; \ - if ((ifq)->ifq_drv_tail == NULL) \ - (ifq)->ifq_drv_head = m0; \ - else \ - (ifq)->ifq_drv_tail->m_nextpkt = m0; \ - (ifq)->ifq_drv_tail = m0; \ - (ifq)->ifq_drv_len++; \ - } \ - IFQ_UNLOCK(ifq); \ - } \ -} while (0) - -#define IFQ_DRV_PREPEND(ifq, m) \ -do { \ - (m)->m_nextpkt = (ifq)->ifq_drv_head; \ - if ((ifq)->ifq_drv_tail == NULL) \ - (ifq)->ifq_drv_tail = (m); \ - (ifq)->ifq_drv_head = (m); \ - (ifq)->ifq_drv_len++; \ -} while (0) - -#define IFQ_DRV_IS_EMPTY(ifq) \ - (((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0)) - -#define IFQ_DRV_PURGE(ifq) \ -do { \ - struct mbuf *m, *n = (ifq)->ifq_drv_head; \ - while((m = n) != NULL) { \ - n = m->m_nextpkt; \ - m_freem(m); \ - } \ - (ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL; \ - (ifq)->ifq_drv_len = 0; \ - IFQ_PURGE(ifq); \ -} while (0) - -/* - * 72 was chosen below because it is the size of a TCP/IP - * header (40) + the minimum mss (32). - */ -#define IF_MINMTU 72 -#define IF_MAXMTU 65535 - -#endif /* _KERNEL */ - -/* - * The ifaddr structure contains information about one address - * of an interface. They are maintained by the different address families, - * are allocated and attached when an address is set, and are linked - * together so all addresses for an interface can be located. - * - * NOTE: a 'struct ifaddr' is always at the beginning of a larger - * chunk of malloc'ed memory, where we store the three addresses - * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here. - */ -struct ifaddr { - struct sockaddr *ifa_addr; /* address of interface */ - struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ -#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ - struct sockaddr *ifa_netmask; /* used to determine subnet */ - struct if_data if_data; /* not all members are meaningful */ - struct ifnet *ifa_ifp; /* back-pointer to interface */ - TAILQ_ENTRY(ifaddr) ifa_link; /* queue macro glue */ - void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */ - (int, struct rtentry *, struct rt_addrinfo *); - u_short ifa_flags; /* mostly rt_flags for cloning */ - u_int ifa_refcnt; /* references to this structure */ - int ifa_metric; /* cost of going out this interface */ - int (*ifa_claim_addr) /* check if an addr goes to this if */ - (struct ifaddr *, struct sockaddr *); - struct mtx ifa_mtx; -}; -#define IFA_ROUTE RTF_UP /* route installed */ - -/* for compatibility with other BSDs */ -#define ifa_list ifa_link - -#define IFA_LOCK_INIT(ifa) \ - mtx_init(&(ifa)->ifa_mtx, "ifaddr", NULL, MTX_DEF) -#define IFA_LOCK(ifa) mtx_lock(&(ifa)->ifa_mtx) -#define IFA_UNLOCK(ifa) mtx_unlock(&(ifa)->ifa_mtx) -#define IFA_DESTROY(ifa) mtx_destroy(&(ifa)->ifa_mtx) - -/* - * The prefix structure contains information about one prefix - * of an interface. They are maintained by the different address families, - * are allocated and attached when a prefix or an address is set, - * and are linked together so all prefixes for an interface can be located. - */ -struct ifprefix { - struct sockaddr *ifpr_prefix; /* prefix of interface */ - struct ifnet *ifpr_ifp; /* back-pointer to interface */ - TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */ - u_char ifpr_plen; /* prefix length in bits */ - u_char ifpr_type; /* protocol dependent prefix type */ -}; - -/* - * Multicast address structure. This is analogous to the ifaddr - * structure except that it keeps track of multicast addresses. - * Also, the reference count here is a count of requests for this - * address, not a count of pointers to this structure. - */ -struct ifmultiaddr { - TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */ - struct sockaddr *ifma_addr; /* address this membership is for */ - struct sockaddr *ifma_lladdr; /* link-layer translation, if any */ - struct ifnet *ifma_ifp; /* back-pointer to interface */ - u_int ifma_refcount; /* reference count */ - void *ifma_protospec; /* protocol-specific state, if any */ - - /* haiku additions, save a allocation -hugo */ - struct sockaddr_dl ifma_addr_storage; -}; - -#ifdef _KERNEL -#define IFA_LOCK(ifa) mtx_lock(&(ifa)->ifa_mtx) -#define IFA_UNLOCK(ifa) mtx_unlock(&(ifa)->ifa_mtx) - -__unused static void ifa_free(struct ifaddr *ifa) {} -__unused static void ifa_init(struct ifaddr *ifa) {} -__unused static void ifa_ref(struct ifaddr *ifa) {} - -extern struct rw_lock ifnet_rwlock; -#define IFNET_LOCK_INIT() rw_lock_init(&ifnet_rwlock, "ifnet rwlock") -#define IFNET_WLOCK() rw_lock_write_lock(&ifnet_rwlock) -#define IFNET_WUNLOCK() rw_lock_write_unlock(&ifnet_rwlock) -#define IFNET_RLOCK() rw_lock_read_lock(&ifnet_rwlock) -#define IFNET_RLOCK_NOSLEEP() rw_lock_read_lock(&ifnet_rwlock) -#define IFNET_RUNLOCK() rw_lock_read_unlock(&ifnet_rwlock) -#define IFNET_RUNLOCK_NOSLEEP() rw_lock_read_unlock(&ifnet_rwlock) - -struct ifnet *ifnet_byindex(u_short idx); -struct ifnet *ifnet_byindex_locked(u_short idx); - -extern struct ifnethead ifnet; -extern int ifqmaxlen; -extern struct ifnet *loif; /* first loopback interface */ -extern int if_index; - -int if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **); -int if_allmulti(struct ifnet *, int); -struct ifnet* if_alloc(u_char); -void if_attach(struct ifnet *); -int if_delmulti(struct ifnet *, struct sockaddr *); -void if_detach(struct ifnet *); -void if_purgeaddrs(struct ifnet *); -void if_delallmulti(struct ifnet *); -void if_purgemaddrs(struct ifnet *); -void if_down(struct ifnet *); -void if_free(struct ifnet *); -void if_free_type(struct ifnet *, u_char); -void if_initname(struct ifnet *, const char *, int); -void if_link_state_change(struct ifnet *, int); -int if_printf(struct ifnet *, const char *, ...) __printflike(2, 3); -int if_setlladdr(struct ifnet *, const u_char *, int); -void if_up(struct ifnet *); -/*void ifinit(void);*/ /* declared in systm.h for main() */ -int ifioctl(struct socket *, u_long, caddr_t, struct thread *); -int ifpromisc(struct ifnet *, int); -struct ifnet *ifunit(const char *); - -struct ifaddr *ifa_ifwithaddr(struct sockaddr *); -struct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *); -struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *); -struct ifaddr *ifa_ifwithnet(struct sockaddr *); -struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *); -struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *); - -int if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen); - -typedef void *if_com_alloc_t(u_char type, struct ifnet *ifp); -typedef void if_com_free_t(void *com, u_char type); -void if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f); -void if_deregister_com_alloc(u_char type); -void if_inc_counter(struct ifnet *, ift_counter, int64_t); - -#define IF_LLADDR(ifp) LLADDR(&ifp->if_lladdr) - -#ifdef DEVICE_POLLING -enum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS }; - -typedef void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count); -int ether_poll_register(poll_handler_t *h, struct ifnet *ifp); -int ether_poll_deregister(struct ifnet *ifp); -#endif /* DEVICE_POLLING */ - -#endif /* _KERNEL */ - -#endif /* _FBSD_COMPAT_NET_IF_VAR_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/net/if_vlan_var.h b/src/libs/compat/freebsd_network/compat/net/if_vlan_var.h deleted file mode 100644 index fc3b44be7a..0000000000 --- a/src/libs/compat/freebsd_network/compat/net/if_vlan_var.h +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * Copyright 1998 Massachusetts Institute of Technology - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby - * granted, provided that both the above copyright notice and this - * permission notice appear in all copies, that both the above - * copyright notice and this permission notice appear in all - * supporting documentation, and that the name of M.I.T. not be used - * in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. M.I.T. makes - * no representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS - * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT - * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/net/if_vlan_var.h,v 1.26 2007/02/28 22:05:30 bms Exp $ - */ - -#ifndef _FBSD_COMPAT_NET_IF_VLAN_VAR_H_ -#define _FBSD_COMPAT_NET_IF_VLAN_VAR_H_ 1 - -struct ether_vlan_header { - u_char evl_dhost[ETHER_ADDR_LEN]; - u_char evl_shost[ETHER_ADDR_LEN]; - u_int16_t evl_encap_proto; - u_int16_t evl_tag; - u_int16_t evl_proto; -}; - -#define EVL_VLID_MASK 0x0FFF -#define EVL_PRI_MASK 0xE000 -#define EVL_VLANOFTAG(tag) ((tag) & EVL_VLID_MASK) -#define EVL_PRIOFTAG(tag) (((tag) >> 13) & 7) -#define EVL_CFIOFTAG(tag) (((tag) >> 12) & 1) -#define EVL_MAKETAG(vlid, pri, cfi) \ - ((((((pri) & 7) << 1) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK)) - -/* Set the VLAN ID in an mbuf packet header non-destructively. */ -#define EVL_APPLY_VLID(m, vlid) \ - do { \ - if ((m)->m_flags & M_VLANTAG) { \ - (m)->m_pkthdr.ether_vtag &= EVL_VLID_MASK; \ - (m)->m_pkthdr.ether_vtag |= (vlid); \ - } else { \ - (m)->m_pkthdr.ether_vtag = (vlid); \ - (m)->m_flags |= M_VLANTAG; \ - } \ - } while (0) - -/* Set the priority ID in an mbuf packet header non-destructively. */ -#define EVL_APPLY_PRI(m, pri) \ - do { \ - if ((m)->m_flags & M_VLANTAG) { \ - uint16_t __vlantag = (m)->m_pkthdr.ether_vtag; \ - (m)->m_pkthdr.ether_vtag |= EVL_MAKETAG( \ - EVL_VLANOFTAG(__vlantag), (pri), \ - EVL_CFIOFTAG(__vlantag)); \ - } else { \ - (m)->m_pkthdr.ether_vtag = \ - EVL_MAKETAG(0, (pri), 0); \ - (m)->m_flags |= M_VLANTAG; \ - } \ - } while (0) - -/* sysctl(3) tags, for compatibility purposes */ -#define VLANCTL_PROTO 1 -#define VLANCTL_MAX 2 - -/* - * Configuration structure for SIOCSETVLAN and SIOCGETVLAN ioctls. - */ -struct vlanreq { - char vlr_parent[IFNAMSIZ]; - u_short vlr_tag; -}; -#define SIOCSETVLAN SIOCSIFGENERIC -#define SIOCGETVLAN SIOCGIFGENERIC - -#ifdef _KERNEL -/* - * Drivers that are capable of adding and removing the VLAN header - * in hardware indicate they support this by marking IFCAP_VLAN_HWTAGGING - * in if_capabilities. Drivers for hardware that is capable - * of handling larger MTU's that may include a software-appended - * VLAN header w/o lowering the normal MTU should mark IFCAP_VLAN_MTU - * in if_capabilities; this notifies the VLAN code it can leave the - * MTU on the vlan interface at the normal setting. - */ - -/* - * VLAN tags are stored in host byte order. Byte swapping may be - * necessary. - * - * Drivers that support hardware VLAN tag stripping fill in the - * received VLAN tag (containing both vlan and priority information) - * into the ether_vtag mbuf packet header field: - * - * m->m_pkthdr.ether_vtag = vlan_id; // ntohs()? - * m->m_flags |= M_VLANTAG; - * - * to mark the packet m with the specified VLAN tag. - * - * On output the driver should check the mbuf for the M_VLANTAG - * flag to see if a VLAN tag is present and valid: - * - * if (m->m_flags & M_VLANTAG) { - * ... = m->m_pkthdr.ether_vtag; // htons()? - * ... pass tag to hardware ... - * } - * - * Note that a driver must indicate it supports hardware VLAN - * stripping/insertion by marking IFCAP_VLAN_HWTAGGING in - * if_capabilities. - */ - -#define VLAN_CAPABILITIES(_ifp) do { \ - } while (0) - -extern void (*vlan_trunk_cap_p)(struct ifnet *); -#endif /* _KERNEL */ - -#endif /* _FBSD_COMPAT_NET_IF_VLAN_VAR_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/net/route.h b/src/libs/compat/freebsd_network/compat/net/route.h deleted file mode 100644 index 4109ead3f3..0000000000 --- a/src/libs/compat/freebsd_network/compat/net/route.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_NET_ROUTE_H_ -#define _FBSD_COMPAT_NET_ROUTE_H_ - - -#include - - -/* - * A route consists of a destination address, a reference - * to a routing entry, and a reference to an llentry. - * These are often held by protocols in their control - * blocks, e.g. inpcb. - */ -struct route { - struct rtentry *ro_rt; - struct llentry *ro_lle; - struct sockaddr ro_dst; -}; - -#endif /* _FBSD_COMPAT_NET_ROUTE_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/netinet/if_ether.h b/src/libs/compat/freebsd_network/compat/netinet/if_ether.h deleted file mode 100644 index 06e32a198a..0000000000 --- a/src/libs/compat/freebsd_network/compat/netinet/if_ether.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2007 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_NETINET_IF_ETHER_H_ -#define _FBSD_COMPAT_NETINET_IF_ETHER_H_ - - -/* Haiku does it's own ARP management */ - -#define arp_ifinit(ifp, ifa) - -#endif diff --git a/src/libs/compat/freebsd_network/compat/netinet/in_systm.h b/src/libs/compat/freebsd_network/compat/netinet/in_systm.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/libs/compat/freebsd_network/compat/netinet/in_var.h b/src/libs/compat/freebsd_network/compat/netinet/in_var.h deleted file mode 100644 index bb732d6c5d..0000000000 --- a/src/libs/compat/freebsd_network/compat/netinet/in_var.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_NETINET_IN_VAR_H_ -#define _FBSD_COMPAT_NETINET_IN_VAR_H_ - - -#include - -#endif /* _FBSD_COMPAT_NETINET_IN_VAR_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/security/mac/mac_framework.h b/src/libs/compat/freebsd_network/compat/security/mac/mac_framework.h deleted file mode 100644 index 6172e82247..0000000000 --- a/src/libs/compat/freebsd_network/compat/security/mac/mac_framework.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef FBSD_COMPAT_SECURITY_MAC_MAC_FRAMEWORK_H_ -#define FBSD_COMPAT_SECURITY_MAC_MAC_FRAMEWORK_H_ - - -#endif /* FBSD_COMPAT_SECURITY_MAC_MAC_FRAMEWORK_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/_bus_dma.h b/src/libs/compat/freebsd_network/compat/sys/_bus_dma.h deleted file mode 100644 index 5aa4482f05..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/_bus_dma.h +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright 2006 John-Mark Gurney. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/_bus_dma.h,v 1.1 2006/09/03 00:26:17 jmg Exp $ - * - */ -#ifndef _SYS__BUS_DMA_H_ -#define _SYS__BUS_DMA_H_ - -typedef int bus_dmasync_op_t; - -/* - * bus_dma_tag_t - * - * A machine-dependent opaque type describing the characteristics - * of how to perform DMA mappings. This structure encapsultes - * information concerning address and alignment restrictions, number - * of S/G segments, amount of data per S/G segment, etc. - */ -typedef struct bus_dma_tag *bus_dma_tag_t; - -/* - * bus_dmamap_t - * - * DMA mapping instance information. - */ -typedef struct bus_dmamap *bus_dmamap_t; - -/* - * A function that performs driver-specific synchronization on behalf of - * busdma. - */ -typedef enum { - BUS_DMA_LOCK = 0x01, - BUS_DMA_UNLOCK = 0x02, -} bus_dma_lock_op_t; - -typedef void bus_dma_lock_t(void *, bus_dma_lock_op_t); - -#endif /* !_SYS__BUS_DMA_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/_mutex.h b/src/libs/compat/freebsd_network/compat/sys/_mutex.h deleted file mode 100644 index 7d8e757c53..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/_mutex.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS__MUTEX_H_ -#define _FBSD_COMPAT_SYS__MUTEX_H_ - - -#include - - -struct mtx { - int type; - union { - struct { - mutex lock; - thread_id owner; - } mutex; - int32 spinlock; - recursive_lock recursive; - } u; -}; - - -#endif /* _FBSD_COMPAT_SYS__MUTEX_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/_task.h b/src/libs/compat/freebsd_network/compat/sys/_task.h deleted file mode 100644 index a94e6b8ca9..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/_task.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2007 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS__TASK_H_ -#define _FBSD_COMPAT_SYS__TASK_H_ - - -/* Haiku's list management */ -#include - - -typedef void (*task_handler_t)(void *context, int pending); - -struct task { - int ta_priority; - task_handler_t ta_handler; - void *ta_argument; - int ta_pending; - - struct list_link ta_link; -}; - -#endif diff --git a/src/libs/compat/freebsd_network/compat/sys/_timeval.h b/src/libs/compat/freebsd_network/compat/sys/_timeval.h deleted file mode 100644 index 6ba7a53deb..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/_timeval.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS__TIMEVAL_H_ -#define _FBSD_COMPAT_SYS__TIMEVAL_H_ - - -#include - -#endif /* _FBSD_COMPAT_SYS__TIMEVAL_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/_types.h b/src/libs/compat/freebsd_network/compat/sys/_types.h deleted file mode 100644 index 790e013860..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/_types.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2007 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS__TYPES_H_ -#define _FBSD_COMPAT_SYS__TYPES_H_ - - -#ifdef __GNUCLIKE_BUILTIN_VARARGS -typedef __builtin_va_list __va_list; /* internally known to gcc */ -#else -typedef char * __va_list; -#endif /* __GNUCLIKE_BUILTIN_VARARGS */ -#if defined(__GNUC_VA_LIST_COMPATIBILITY) && !defined(__GNUC_VA_LIST) \ - && !defined(__NO_GNUC_VA_LIST) -#define __GNUC_VA_LIST -typedef __va_list __gnuc_va_list; /* compatibility w/GNU headers*/ -#endif - -#endif /* _FBSD_COMPAT_SYS__TYPES_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/bus.h b/src/libs/compat/freebsd_network/compat/sys/bus.h deleted file mode 100644 index 889cd9992a..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/bus.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2009, Colin Günther. All Rights Reserved. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_BUS_H_ -#define _FBSD_COMPAT_SYS_BUS_H_ - - -#include - -#include - -#include - - -// TODO per platform, these are 32-bit - -// oh you glorious world of macros -#define bus_read_1(r, o) \ - bus_space_read_1((r)->r_bustag, (r)->r_bushandle, (o)) -#define bus_read_2(r, o) \ - bus_space_read_2((r)->r_bustag, (r)->r_bushandle, (o)) -#define bus_read_4(r, o) \ - bus_space_read_4((r)->r_bustag, (r)->r_bushandle, (o)) -#define bus_write_1(r, o, v) \ - bus_space_write_1((r)->r_bustag, (r)->r_bushandle, (o), (v)) -#define bus_write_2(r, o, v) \ - bus_space_write_2((r)->r_bustag, (r)->r_bushandle, (o), (v)) -#define bus_write_4(r, o, v) \ - bus_space_write_4((r)->r_bustag, (r)->r_bushandle, (o), (v)) - -#define bus_barrier(r, o, l, f) \ - bus_space_barrier((r)->r_bustag, (r)->r_bushandle, (o), (l), (f)) - -#define bus_read_region_1(r, o, d, c) \ - bus_space_read_region_1((r)->r_bustag, (r)->r_bushandle, (o), (d), (c)) - -#define FILTER_STRAY B_UNHANDLED_INTERRUPT -#define FILTER_HANDLED B_HANDLED_INTERRUPT -#define FILTER_SCHEDULE_THREAD B_INVOKE_SCHEDULER - -/* Note that we reversed the original order, so whenever actual (negative) - numbers are used in a driver, we have to change it. */ -#define BUS_PROBE_SPECIFIC 0 -#define BUS_PROBE_LOW_PRIORITY 10 -#define BUS_PROBE_DEFAULT 20 -#define BUS_PROBE_GENERIC 100 - -#define __BUS_ACCESSOR(varp, var, ivarp, ivar, type) \ - \ -static __inline type varp ## _get_ ## var(device_t dev) \ -{ \ - return 0; \ -} \ - \ -static __inline void varp ## _set_ ## var(device_t dev, type t) \ -{ \ -} - - -struct resource; - -struct resource_spec { - int type; - int rid; - int flags; -}; - -enum intr_type { - INTR_TYPE_NET = 4, - INTR_FAST = 128, - INTR_MPSAFE = 512, -}; - - -int bus_generic_detach(device_t dev); -int bus_generic_suspend(device_t dev); -int bus_generic_resume(device_t dev); -void bus_generic_shutdown(device_t dev); - -typedef int (*driver_filter_t)(void *); -typedef void driver_intr_t(void *); - - -int resource_int_value(const char *name, int unit, const char *resname, - int *result); - -struct resource *bus_alloc_resource(device_t dev, int type, int *rid, - unsigned long start, unsigned long end, unsigned long count, uint32 flags); -int bus_release_resource(device_t dev, int type, int rid, struct resource *r); -int bus_alloc_resources(device_t dev, struct resource_spec *resourceSpec, - struct resource **resources); -void bus_release_resources(device_t dev, - const struct resource_spec *resourceSpec, struct resource **resources); - -int bus_child_present(device_t child); - -static inline struct resource * -bus_alloc_resource_any(device_t dev, int type, int *rid, uint32 flags) -{ - return bus_alloc_resource(dev, type, rid, 0, ~0, 1, flags); -} - -bus_dma_tag_t bus_get_dma_tag(device_t dev); - -int bus_setup_intr(device_t dev, struct resource *r, int flags, - driver_filter_t filter, driver_intr_t handler, void *arg, void **_cookie); -int bus_teardown_intr(device_t dev, struct resource *r, void *cookie); - -const char *device_get_name(device_t dev); -const char *device_get_nameunit(device_t dev); -int device_get_unit(device_t dev); -void *device_get_softc(device_t dev); -int device_printf(device_t dev, const char *, ...) __printflike(2, 3); -void device_set_desc(device_t dev, const char *desc); -void device_set_desc_copy(device_t dev, const char *desc); -const char *device_get_desc(device_t dev); -device_t device_get_parent(device_t dev); -u_int32_t device_get_flags(device_t dev); -devclass_t device_get_devclass(device_t dev); -int device_get_children(device_t dev, device_t **devlistp, int *devcountp); - -void device_set_ivars(device_t dev, void *); -void *device_get_ivars(device_t dev); - -device_t device_add_child(device_t dev, const char *name, int unit); -int device_delete_child(device_t dev, device_t child); -int device_is_attached(device_t dev); -int device_attach(device_t dev); -int device_detach(device_t dev); -int bus_print_child_header(device_t dev, device_t child); -int bus_print_child_footer(device_t dev, device_t child); -int bus_generic_print_child(device_t dev, device_t child); -void bus_generic_driver_added(device_t dev, driver_t *driver); -int bus_generic_attach(device_t dev); -int device_set_driver(device_t dev, driver_t *driver); -int device_is_alive(device_t dev); - - -static inline struct sysctl_ctx_list * -device_get_sysctl_ctx(device_t dev) -{ - return NULL; -} - - -static inline void * -device_get_sysctl_tree(device_t dev) -{ - return NULL; -} - -devclass_t devclass_find(const char *classname); -device_t devclass_get_device(devclass_t dc, int unit); -int devclass_get_maxunit(devclass_t dc); - -#endif /* _FBSD_COMPAT_SYS_BUS_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/bus_dma.h b/src/libs/compat/freebsd_network/compat/sys/bus_dma.h deleted file mode 100644 index 362019f783..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/bus_dma.h +++ /dev/null @@ -1,271 +0,0 @@ -/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ - -/*- - * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/*- - * Copyright (c) 1996 Charles M. Hannum. All rights reserved. - * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christopher G. Demetriou - * for the NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* $FreeBSD: src/sys/sys/bus_dma.h,v 1.30 2006/09/03 00:26:17 jmg Exp $ */ -#ifndef _BUS_DMA_H_ -#define _BUS_DMA_H_ - -#include - - -/* - * Machine independent interface for mapping physical addresses to peripheral - * bus 'physical' addresses, and assisting with DMA operations. - * - * XXX This file is always included from and should not - * (yet) be included directly. - */ - -/* - * Flags used in various bus DMA methods. - */ -#define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */ -#define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */ -#define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */ -#define BUS_DMA_COHERENT 0x04 /* hint: map memory in a coherent way */ -#define BUS_DMA_ZERO 0x08 /* allocate zero'ed memory */ -#define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */ -#define BUS_DMA_BUS2 0x20 -#define BUS_DMA_BUS3 0x40 -#define BUS_DMA_BUS4 0x80 - -/* - * The following two flags are non-standard or specific to only certain - * architectures - */ -#define BUS_DMA_NOWRITE 0x100 -#define BUS_DMA_NOCACHE 0x200 -#define BUS_DMA_ISA 0x400 /* map memory for AXP ISA dma */ - -/* Forwards needed by prototypes below. */ -struct mbuf; -struct uio; - -/* - * Operations performed by bus_dmamap_sync(). - */ -#define BUS_DMASYNC_PREREAD 1 -#define BUS_DMASYNC_POSTREAD 2 -#define BUS_DMASYNC_PREWRITE 4 -#define BUS_DMASYNC_POSTWRITE 8 - -/* - * bus_dma_segment_t - * - * Describes a single contiguous DMA transaction. Values - * are suitable for programming into DMA registers. - */ -typedef struct bus_dma_segment { - bus_addr_t ds_addr; /* DMA address */ - bus_size_t ds_len; /* length of transfer */ -} bus_dma_segment_t; - -/* - * A function that returns 1 if the address cannot be accessed by - * a device and 0 if it can be. - */ -typedef int bus_dma_filter_t(void *, bus_addr_t); - -/* - * Generic helper function for manipulating mutexes. - */ -void busdma_lock_mutex(void *arg, bus_dma_lock_op_t op); - -/* - * Allocate a device specific dma_tag encapsulating the constraints of - * the parent tag in addition to other restrictions specified: - * - * alignment: Alignment for segments. - * boundary: Boundary that segments cannot cross. - * lowaddr: Low restricted address that cannot appear in a mapping. - * highaddr: High restricted address that cannot appear in a mapping. - * filtfunc: An optional function to further test if an address - * within the range of lowaddr and highaddr cannot appear - * in a mapping. - * filtfuncarg: An argument that will be passed to filtfunc in addition - * to the address to test. - * maxsize: Maximum mapping size supported by this tag. - * nsegments: Number of discontinuities allowed in maps. - * maxsegsz: Maximum size of a segment in the map. - * flags: Bus DMA flags. - * lockfunc: An optional function to handle driver-defined lock - * operations. - * lockfuncarg: An argument that will be passed to lockfunc in addition - * to the lock operation. - * dmat: A pointer to set to a valid dma tag should the return - * value of this function indicate success. - */ -/* XXX Should probably allow specification of alignment */ -int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, - bus_size_t boundary, bus_addr_t lowaddr, - bus_addr_t highaddr, bus_dma_filter_t *filtfunc, - void *filtfuncarg, bus_size_t maxsize, int nsegments, - bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, - void *lockfuncarg, bus_dma_tag_t *dmat); - -int bus_dma_tag_destroy(bus_dma_tag_t dmat); - -/* - * A function that processes a successfully loaded dma map or an error - * from a delayed load map. - */ -typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); - -/* - * Like bus_dmamap_callback but includes map size in bytes. This is - * defined as a separate interface to maintain compatibility for users - * of bus_dmamap_callback_t--at some point these interfaces should be merged. - */ -typedef void bus_dmamap_callback2_t(void *, bus_dma_segment_t *, int, bus_size_t, int); - -/* - * XXX sparc64 uses the same interface, but a much different implementation. - * for the sparc64 arch contains the equivalent - * declarations. - */ -#if !defined(__sparc64__) - -/* - * Allocate a handle for mapping from kva/uva/physical - * address space into bus device space. - */ -int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp); - -/* - * Destroy a handle for mapping from kva/uva/physical - * address space into bus device space. - */ -int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map); - -/* - * Allocate a piece of memory that can be efficiently mapped into - * bus device space based on the constraints listed in the dma tag. - * A dmamap to for use with dmamap_load is also allocated. - */ -int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, - bus_dmamap_t *mapp); - -/* - * Free a piece of memory and its allocated dmamap, that was allocated - * via bus_dmamem_alloc. - */ -void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map); - -/* - * Map the buffer buf into bus space using the dmamap map. - */ -int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, - bus_size_t buflen, bus_dmamap_callback_t *callback, - void *callback_arg, int flags); - -/* - * Like bus_dmamap_load but for mbufs. Note the use of the - * bus_dmamap_callback2_t interface. - */ -int bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, - struct mbuf *mbuf, - bus_dmamap_callback2_t *callback, void *callback_arg, - int flags); - -int bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map, - struct mbuf *mbuf, bus_dma_segment_t *segs, - int *nsegs, int flags); - -/* - * Like bus_dmamap_load but for uios. Note the use of the - * bus_dmamap_callback2_t interface. - */ -int bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, - struct uio *ui, - bus_dmamap_callback2_t *callback, void *callback_arg, - int flags); - -/* - * Perform a synchronization operation on the given map. - */ -void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t); -#define bus_dmamap_sync(dmat, dmamap, op) \ - do { \ - if ((dmamap) != NULL) \ - _bus_dmamap_sync(dmat, dmamap, op); \ - } while (0) - -/* - * Release the mapping held by map. - */ -void _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map); -#define bus_dmamap_unload(dmat, dmamap) \ - do { \ - if ((dmamap) != NULL) \ - _bus_dmamap_unload(dmat, dmamap); \ - } while (0) - -#endif /* __sparc64__ */ - -#endif /* _BUS_DMA_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/callout.h b/src/libs/compat/freebsd_network/compat/sys/callout.h deleted file mode 100644 index 9d4da3b944..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/callout.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2010, Axel Dörfler, axeld@pinc-software.de. - * Copyright 2009, Colin Günther, coling@gmx.de. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_CALLOUT_H_ -#define _FBSD_COMPAT_SYS_CALLOUT_H_ - - -#include - -#include - - -struct callout { - struct list_link link; - bigtime_t due; - uint32 flags; - - void * c_arg; - void (*c_func)(void *); - struct mtx * c_mtx; - int c_flags; -}; - - -#define CALLOUT_MPSAFE 0x0001 - - -void callout_init(struct callout *c, int mpsafe); -void callout_init_mtx(struct callout *c, struct mtx *mutex, int flags); -/* Time values are in ticks, see compat/sys/kernel.h for its definition */ -int callout_schedule(struct callout *c, int ticks); -int callout_reset(struct callout *c, int ticks, void (*func)(void *), void *arg); -int callout_pending(struct callout *c); -int callout_active(struct callout *c); - -#define callout_drain(c) _callout_stop_safe(c, 1) -#define callout_stop(c) _callout_stop_safe(c, 0) -int _callout_stop_safe(struct callout *c, int safe); - - - -#endif /* _FBSD_COMPAT_SYS_CALLOUT_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/cdefs.h b/src/libs/compat/freebsd_network/compat/sys/cdefs.h deleted file mode 100644 index f971269f4c..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/cdefs.h +++ /dev/null @@ -1,310 +0,0 @@ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Berkeley Software Design, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)cdefs.h 8.8 (Berkeley) 1/9/95 - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_SYS_CDEFS_H_ -#define _FBSD_COMPAT_SYS_CDEFS_H_ - - -#include - - -#define __FBSDID(str) static const char __fbsdid[] = str - -/* - * This code has been put in place to help reduce the addition of - * compiler specific defines in FreeBSD code. It helps to aid in - * having a compiler-agnostic source tree. - */ - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) - -#if __GNUC__ >= 3 || defined(__INTEL_COMPILER) -#define __GNUCLIKE_ASM 3 -#define __GNUCLIKE_MATH_BUILTIN_CONSTANTS -#else -#define __GNUCLIKE_ASM 2 -#endif -#define __GNUCLIKE___TYPEOF 1 -#define __GNUCLIKE___OFFSETOF 1 -#define __GNUCLIKE___SECTION 1 - -#define __GNUCLIKE_ATTRIBUTE_MODE_DI 1 - -#ifndef __INTEL_COMPILER -# define __GNUCLIKE_CTOR_SECTION_HANDLING 1 -#endif - -#define __GNUCLIKE_BUILTIN_CONSTANT_P 1 -# if defined(__INTEL_COMPILER) && defined(__cplusplus) \ - && __INTEL_COMPILER < 800 -# undef __GNUCLIKE_BUILTIN_CONSTANT_P -# endif - -#if (__GNUC_MINOR__ > 95 || __GNUC__ >= 3) && !defined(__INTEL_COMPILER) -# define __GNUCLIKE_BUILTIN_VARARGS 1 -# define __GNUCLIKE_BUILTIN_STDARG 1 -# define __GNUCLIKE_BUILTIN_VAALIST 1 -#endif - -#if defined(__GNUC__) -# define __GNUC_VA_LIST_COMPATIBILITY 1 -#endif - -#ifndef __INTEL_COMPILER -# define __GNUCLIKE_BUILTIN_NEXT_ARG 1 -# define __GNUCLIKE_MATH_BUILTIN_RELOPS -#endif - -#define __GNUCLIKE_BUILTIN_MEMCPY 1 - -/* XXX: if __GNUC__ >= 2: not tested everywhere originally, where replaced */ -#define __CC_SUPPORTS_INLINE 1 -#define __CC_SUPPORTS___INLINE 1 -#define __CC_SUPPORTS___INLINE__ 1 - -#define __CC_SUPPORTS___FUNC__ 1 -#define __CC_SUPPORTS_WARNING 1 - -#define __CC_SUPPORTS_VARADIC_XXX 1 /* see varargs.h */ - -#define __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 1 - -#endif /* __GNUC__ || __INTEL_COMPILER */ - - -/* - * Macro to test if we're using a specific version of gcc or later. - */ -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) -#define __GNUC_PREREQ__(ma, mi) \ - (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)) -#else -#define __GNUC_PREREQ__(ma, mi) 0 -#endif - -/* - * GNU C version 2.96 adds explicit branch prediction so that - * the CPU back-end can hint the processor and also so that - * code blocks can be reordered such that the predicted path - * sees a more linear flow, thus improving cache behavior, etc. - * - * The following two macros provide us with a way to utilize this - * compiler feature. Use __predict_true() if you expect the expression - * to evaluate to true, and __predict_false() if you expect the - * expression to evaluate to false. - * - * A few notes about usage: - * - * * Generally, __predict_false() error condition checks (unless - * you have some _strong_ reason to do otherwise, in which case - * document it), and/or __predict_true() `no-error' condition - * checks, assuming you want to optimize for the no-error case. - * - * * Other than that, if you don't know the likelihood of a test - * succeeding from empirical or other `hard' evidence, don't - * make predictions. - * - * * These are meant to be used in places that are run `a lot'. - * It is wasteful to make predictions in code that is run - * seldomly (e.g. at subsystem initialization time) as the - * basic block reordering that this affects can often generate - * larger code. - */ -#if __GNUC_PREREQ__(2, 96) -#define __predict_true(exp) __builtin_expect((exp), 1) -#define __predict_false(exp) __builtin_expect((exp), 0) -#else -#define __predict_true(exp) (exp) -#define __predict_false(exp) (exp) -#endif - -/* - * We define this here since , , and - * require it. - */ -#if __GNUC_PREREQ__(4, 1) -#define __offsetof(type, field) __builtin_offsetof(type, field) -#else -#ifndef __cplusplus -#define __offsetof(type, field) ((size_t)(&((type *)0)->field)) -#else -#define __offsetof(type, field) \ - (__offsetof__ (reinterpret_cast \ - (&reinterpret_cast \ - (static_cast (0)->field)))) -#endif -#endif -#define __rangeof(type, start, end) \ - (__offsetof(type, end) - __offsetof(type, start)) - -/* - * Compiler-dependent macros to help declare dead (non-returning) and - * pure (no side effects) functions, and unused variables. They are - * null except for versions of gcc that are known to support the features - * properly (old versions of gcc-2 supported the dead and pure features - * in a different (wrong) way). If we do not provide an implementation - * for a given compiler, let the compile fail if it is told to use - * a feature that we cannot live without. - */ -#ifdef lint -#define __pure2 -#define __unused -#define __packed -#define __aligned(x) -#define __section(x) -#else -#if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER) -#define __pure2 -#define __unused -#endif -#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER) -#define __pure2 __attribute__((__const__)) -#define __unused -/* XXX Find out what to do for __packed, __aligned and __section */ -#endif -#if __GNUC_PREREQ__(2, 7) -#define __pure2 __attribute__((__const__)) -#define __unused __attribute__((__unused__)) -#define __packed __attribute__((__packed__)) -#define __aligned(x) __attribute__((__aligned__(x))) -#define __section(x) __attribute__((__section__(x))) -#endif - -#if __GNUC_PREREQ__(3, 1) -#define __used __attribute__((__used__)) -#else -#if __GNUC_PREREQ__(2, 7) -#define __used -#endif -#endif - -#if defined(__INTEL_COMPILER) -#define __pure2 __attribute__((__const__)) -#define __unused __attribute__((__unused__)) -#define __used __attribute__((__used__)) -#define __packed __attribute__((__packed__)) -#define __aligned(x) __attribute__((__aligned__(x))) -#define __section(x) __attribute__((__section__(x))) -#endif -#endif - -/* - * Compiler-dependent macros to declare that functions take printf-like - * or scanf-like arguments. They are null except for versions of gcc - * that are known to support the features properly (old versions of gcc-2 - * didn't permit keeping the keywords out of the application namespace). - */ -#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER) -#define __printflike(fmtarg, firstvararg) -#define __scanflike(fmtarg, firstvararg) -#define __format_arg(fmtarg) -#else -#define __printflike(fmtarg, firstvararg) \ - __attribute__((__format__ (__printf__, fmtarg, firstvararg))) -#define __scanflike(fmtarg, firstvararg) \ - __attribute__((__format__ (__scanf__, fmtarg, firstvararg))) -#define __format_arg(fmtarg) __attribute__((__format_arg__ (fmtarg))) -#endif - -#if __GNUC_PREREQ__(3, 1) -#define __noinline __attribute__ ((__noinline__)) -#else -#define __noinline -#endif - -#if __GNUC_PREREQ__(3, 3) -#define __nonnull(x) __attribute__((__nonnull__(x))) -#else -#define __nonnull(x) -#endif - -/* - * The __CONCAT macro is used to concatenate parts of symbol names, e.g. - * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo. - * The __CONCAT macro is a bit tricky to use if it must work in non-ANSI - * mode -- there must be no spaces between its arguments, and for nested - * __CONCAT's, all the __CONCAT's must be at the left. __CONCAT can also - * concatenate double-quoted strings produced by the __STRING macro, but - * this only works with ANSI C. - * - * __XSTRING is like __STRING, but it expands any macros in its argument - * first. It is only available with ANSI C. - */ -#if defined(__STDC__) || defined(__cplusplus) -#define __XSTRING(x) __STRING(x) /* expand x, then stringify */ - -#define __const const /* define reserved names to standard */ -#define __signed signed -#define __volatile volatile -#if defined(__cplusplus) -#define __inline inline /* convert to C++ keyword */ -#else -#if !(defined(__CC_SUPPORTS___INLINE)) -#define __inline /* delete GCC keyword */ -#endif /* ! __CC_SUPPORTS___INLINE */ -#endif /* !__cplusplus */ - -#else /* !(__STDC__ || __cplusplus) */ - -#if !defined(__CC_SUPPORTS___INLINE) -#define __const /* delete pseudo-ANSI C keywords */ -#define __inline -#define __signed -#define __volatile -/* - * In non-ANSI C environments, new programs will want ANSI-only C keywords - * deleted from the program and old programs will want them left alone. - * When using a compiler other than gcc, programs using the ANSI C keywords - * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS. - * When using "gcc -traditional", we assume that this is the intent; if - * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone. - */ -#ifndef NO_ANSI_KEYWORDS -#define const /* delete ANSI C keywords */ -#define inline -#define signed -#define volatile -#endif /* !NO_ANSI_KEYWORDS */ -#endif /* !__CC_SUPPORTS___INLINE */ -#endif /* !(__STDC__ || __cplusplus) */ - -#ifndef __DECONST -#define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) -#endif - -#ifndef __UNCONST -#define __UNCONST(var) ((void*)(uintptr_t)(const void *)(var)) -#endif - -#endif diff --git a/src/libs/compat/freebsd_network/compat/sys/condvar.h b/src/libs/compat/freebsd_network/compat/sys/condvar.h deleted file mode 100644 index 55b96a816b..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/condvar.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_CONDVAR_H_ -#define _FBSD_COMPAT_SYS_CONDVAR_H_ - - -#include - -#ifdef __cplusplus -} /* extern "C" */ -#include -extern "C" { -#else -#include -#endif - - -struct cv { - struct ConditionVariable condition; -}; - - -void cv_init(struct cv*, const char*); -void cv_destroy(struct cv*); -void cv_wait(struct cv*, struct mtx*); -int cv_timedwait(struct cv*, struct mtx*, int); -void cv_signal(struct cv*); - -#endif /* _FBSD_COMPAT_SYS_CONDVAR_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/ctype.h b/src/libs/compat/freebsd_network/compat/sys/ctype.h deleted file mode 100644 index 60cc664acf..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/ctype.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_CTYPE_H_ -#define _FBSD_COMPAT_SYS_CTYPE_H_ - - -#define isprint(c) ((c) >= ' ' && (c) <= '~') - -#endif /* _FBSD_COMPAT_SYS_CTYPE_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/endian.h b/src/libs/compat/freebsd_network/compat/sys/endian.h deleted file mode 100644 index 6261634319..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/endian.h +++ /dev/null @@ -1,197 +0,0 @@ -/*- - * Copyright (c) 2002 Thomas Moestl - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/endian.h,v 1.6 2003/10/15 20:05:57 obrien Exp $ - */ -#ifndef _FBSD_COMPAT_SYS_ENDIAN_H_ -#define _FBSD_COMPAT_SYS_ENDIAN_H_ - -#include -#include - -#include - -#include -#include -#include - -#define _BYTE_ORDER BYTE_ORDER -#define _LITTLE_ENDIAN LITTLE_ENDIAN -#define _BIG_ENDIAN BIG_ENDIAN - -#define __bswap16(x) __swap_int16(x) -#define __bswap32(x) __swap_int32(x) -#define __bswap64(x) __swap_int64(x) - -/* - * General byte order swapping functions. - */ -#define bswap16(x) __bswap16(x) -#define bswap32(x) __bswap32(x) -#define bswap64(x) __bswap64(x) - -/* - * Host to big endian, host to little endian, big endian to host, and little - * endian to host byte order functions as detailed in byteorder(9). - */ -#if _BYTE_ORDER == _LITTLE_ENDIAN -#define htobe16(x) bswap16((x)) -#define htobe32(x) bswap32((x)) -#define htobe64(x) bswap64((x)) -#define htole16(x) ((uint16_t)(x)) -#define htole32(x) ((uint32_t)(x)) -#define htole64(x) ((uint64_t)(x)) - -#define be16toh(x) bswap16((x)) -#define be32toh(x) bswap32((x)) -#define be64toh(x) bswap64((x)) -#define le16toh(x) ((uint16_t)(x)) -#define le32toh(x) ((uint32_t)(x)) -#define le64toh(x) ((uint64_t)(x)) -#else /* _BYTE_ORDER != _LITTLE_ENDIAN */ -#define htobe16(x) ((uint16_t)(x)) -#define htobe32(x) ((uint32_t)(x)) -#define htobe64(x) ((uint64_t)(x)) -#define htole16(x) bswap16((x)) -#define htole32(x) bswap32((x)) -#define htole64(x) bswap64((x)) - -#define be16toh(x) ((uint16_t)(x)) -#define be32toh(x) ((uint32_t)(x)) -#define be64toh(x) ((uint64_t)(x)) -#define le16toh(x) bswap16((x)) -#define le32toh(x) bswap32((x)) -#define le64toh(x) bswap64((x)) -#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */ - -/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */ - -static __inline uint16_t -be16dec(const void *pp) -{ - unsigned char const *p = (unsigned char const *)pp; - - return ((p[0] << 8) | p[1]); -} - -static __inline uint32_t -be32dec(const void *pp) -{ - unsigned char const *p = (unsigned char const *)pp; - - return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); -} - -static __inline uint64_t -be64dec(const void *pp) -{ - unsigned char const *p = (unsigned char const *)pp; - - return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4)); -} - -static __inline uint16_t -le16dec(const void *pp) -{ - unsigned char const *p = (unsigned char const *)pp; - - return ((p[1] << 8) | p[0]); -} - -static __inline uint32_t -le32dec(const void *pp) -{ - unsigned char const *p = (unsigned char const *)pp; - - return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); -} - -static __inline uint64_t -le64dec(const void *pp) -{ - unsigned char const *p = (unsigned char const *)pp; - - return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); -} - -static __inline void -be16enc(void *pp, uint16_t u) -{ - unsigned char *p = (unsigned char *)pp; - - p[0] = (u >> 8) & 0xff; - p[1] = u & 0xff; -} - -static __inline void -be32enc(void *pp, uint32_t u) -{ - unsigned char *p = (unsigned char *)pp; - - p[0] = (u >> 24) & 0xff; - p[1] = (u >> 16) & 0xff; - p[2] = (u >> 8) & 0xff; - p[3] = u & 0xff; -} - -static __inline void -be64enc(void *pp, uint64_t u) -{ - unsigned char *p = (unsigned char *)pp; - - be32enc(p, u >> 32); - be32enc(p + 4, u & 0xffffffff); -} - -static __inline void -le16enc(void *pp, uint16_t u) -{ - unsigned char *p = (unsigned char *)pp; - - p[0] = u & 0xff; - p[1] = (u >> 8) & 0xff; -} - -static __inline void -le32enc(void *pp, uint32_t u) -{ - unsigned char *p = (unsigned char *)pp; - - p[0] = u & 0xff; - p[1] = (u >> 8) & 0xff; - p[2] = (u >> 16) & 0xff; - p[3] = (u >> 24) & 0xff; -} - -static __inline void -le64enc(void *pp, uint64_t u) -{ - unsigned char *p = (unsigned char *)pp; - - le32enc(p, u & 0xffffffff); - le32enc(p + 4, u >> 32); -} - -#endif /* _SYS_ENDIAN_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/errno.h b/src/libs/compat/freebsd_network/compat/sys/errno.h deleted file mode 100644 index fd307ce311..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/errno.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2007 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_ERRNO_H_ -#define _FBSD_COMPAT_SYS_ERRNO_H_ - - -#include - - -/* pseudo-errors returned inside freebsd compat layer to modify return to process */ -#define ERESTART (B_ERRORS_END + 1) /* restart syscall */ -#define EJUSTRETURN (B_ERRORS_END + 2) /* don't modify regs, just return */ - -#endif diff --git a/src/libs/compat/freebsd_network/compat/sys/event.h b/src/libs/compat/freebsd_network/compat/sys/event.h deleted file mode 100644 index 642f49cd45..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/event.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2007 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_EVENT_H_ -#define _FBSD_COMPAT_SYS_EVENT_H_ - - -struct knlist { - int _dummy; -}; - -#endif diff --git a/src/libs/compat/freebsd_network/compat/sys/eventhandler.h b/src/libs/compat/freebsd_network/compat/sys/eventhandler.h deleted file mode 100644 index 9a53c98760..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/eventhandler.h +++ /dev/null @@ -1,176 +0,0 @@ -/*- - * Copyright (c) 1999 Michael Smith - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/eventhandler.h,v 1.33.2.1 2006/05/16 07:27:49 ps Exp $ - */ -#ifndef SYS_EVENTHANDLER_H -#define SYS_EVENTHANDLER_H - -#include -#include -#include -#include - -struct eventhandler_entry { - TAILQ_ENTRY(eventhandler_entry) ee_link; - int ee_priority; -#define EHE_DEAD_PRIORITY (-1) - void *ee_arg; -}; - -struct eventhandler_list { - char *el_name; - int el_flags; -#define EHL_INITTED (1<<0) - u_int el_runcount; - struct mtx el_lock; - TAILQ_ENTRY(eventhandler_list) el_link; - TAILQ_HEAD(,eventhandler_entry) el_entries; -}; - -typedef struct eventhandler_entry *eventhandler_tag; - -#define EHL_LOCK(p) mtx_lock(&(p)->el_lock) -#define EHL_UNLOCK(p) mtx_unlock(&(p)->el_lock) -#define EHL_LOCK_ASSERT(p, x) mtx_assert(&(p)->el_lock, x) - -/* - * Macro to invoke the handlers for a given event. - */ -#define _EVENTHANDLER_INVOKE(name, list, ...) do { \ - struct eventhandler_entry *_ep; \ - struct eventhandler_entry_ ## name *_t; \ - \ - KASSERT((list)->el_flags & EHL_INITTED, \ - ("eventhandler_invoke: running non-inited list")); \ - EHL_LOCK_ASSERT((list), MA_OWNED); \ - (list)->el_runcount++; \ - KASSERT((list)->el_runcount > 0, \ - ("eventhandler_invoke: runcount overflow")); \ - CTR0(KTR_EVH, "eventhandler_invoke(\"" __STRING(name) "\")"); \ - TAILQ_FOREACH(_ep, &((list)->el_entries), ee_link) { \ - if (_ep->ee_priority != EHE_DEAD_PRIORITY) { \ - EHL_UNLOCK((list)); \ - _t = (struct eventhandler_entry_ ## name *)_ep; \ - CTR1(KTR_EVH, "eventhandler_invoke: executing %p", \ - (void *)_t->eh_func); \ - _t->eh_func(_ep->ee_arg , ## __VA_ARGS__); \ - EHL_LOCK((list)); \ - } \ - } \ - KASSERT((list)->el_runcount > 0, \ - ("eventhandler_invoke: runcount underflow")); \ - (list)->el_runcount--; \ - if ((list)->el_runcount == 0) \ - eventhandler_prune_list(list); \ - EHL_UNLOCK((list)); \ -} while (0) - -/* - * Slow handlers are entirely dynamic; lists are created - * when entries are added to them, and thus have no concept of "owner", - * - * Slow handlers need to be declared, but do not need to be defined. The - * declaration must be in scope wherever the handler is to be invoked. - */ -#define EVENTHANDLER_DECLARE(name, type) \ -struct eventhandler_entry_ ## name \ -{ \ - struct eventhandler_entry ee; \ - type eh_func; \ -}; \ -struct __hack - -#define EVENTHANDLER_INVOKE(name, ...) \ -do { \ - struct eventhandler_list *_el; \ - \ - if ((_el = eventhandler_find_list(#name)) != NULL) \ - _EVENTHANDLER_INVOKE(name, _el , ## __VA_ARGS__); \ -} while (0) - -#define EVENTHANDLER_REGISTER(name, func, arg, priority) \ - eventhandler_register(NULL, #name, func, arg, priority) - -#define EVENTHANDLER_DEREGISTER(name, tag) \ -do { \ - struct eventhandler_list *_el; \ - \ - if ((_el = eventhandler_find_list(#name)) != NULL) \ - eventhandler_deregister(_el, tag); \ -} while(0) - - -eventhandler_tag eventhandler_register(struct eventhandler_list *list, - const char *name, void *func, void *arg, int priority); -void eventhandler_deregister(struct eventhandler_list *list, - eventhandler_tag tag); -struct eventhandler_list *eventhandler_find_list(const char *name); -void eventhandler_prune_list(struct eventhandler_list *list); - -/* - * Standard system event queues. - */ - -/* Generic priority levels */ -#define EVENTHANDLER_PRI_FIRST 0 -#define EVENTHANDLER_PRI_ANY 10000 -#define EVENTHANDLER_PRI_LAST 20000 - -/* Shutdown events */ -typedef void (*shutdown_fn)(void *, int); - -#define SHUTDOWN_PRI_FIRST EVENTHANDLER_PRI_FIRST -#define SHUTDOWN_PRI_DEFAULT EVENTHANDLER_PRI_ANY -#define SHUTDOWN_PRI_LAST EVENTHANDLER_PRI_LAST - -EVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn); /* before fs sync */ -EVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn); /* after fs sync */ -EVENTHANDLER_DECLARE(shutdown_final, shutdown_fn); - -/* Low memory event */ -typedef void (*vm_lowmem_handler_t)(void *, int); -#define LOWMEM_PRI_DEFAULT EVENTHANDLER_PRI_FIRST -EVENTHANDLER_DECLARE(vm_lowmem, vm_lowmem_handler_t); - -/* - * Process events - * process_fork and exit handlers are called without Giant. - * exec handlers are called with Giant, but that is by accident. - */ -struct proc; - -typedef void (*exitlist_fn)(void *, struct proc *); -typedef void (*forklist_fn)(void *, struct proc *, struct proc *, int); -typedef void (*execlist_fn)(void *, struct proc *); - -EVENTHANDLER_DECLARE(process_exit, exitlist_fn); -EVENTHANDLER_DECLARE(process_fork, forklist_fn); -EVENTHANDLER_DECLARE(process_exec, execlist_fn); - -typedef void (*uma_zone_chfn)(void *); -EVENTHANDLER_DECLARE(nmbclusters_change, uma_zone_chfn); -EVENTHANDLER_DECLARE(maxsockets_change, uma_zone_chfn); -#endif /* SYS_EVENTHANDLER_H */ diff --git a/src/libs/compat/freebsd_network/compat/sys/firmware.h b/src/libs/compat/freebsd_network/compat/sys/firmware.h deleted file mode 100644 index bfc52b26b1..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/firmware.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_FIRMWARE_H_ -#define _FBSD_COMPAT_SYS_FIRMWARE_H_ - - -#define FIRMWARE_UNLOAD 0x0001 - - -struct firmware { - const char* name; // system-wide name - const void* data; // location of image - size_t datasize; // size of image in bytes - unsigned int version; // version of the image -}; - - -const struct firmware* firmware_get(const char*); -void firmware_put(const struct firmware*, int); - -#endif /* _FBSD_COMPAT_SYS_FIRMWARE_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/haiku-module.h b/src/libs/compat/freebsd_network/compat/sys/haiku-module.h deleted file mode 100644 index 26e07bb3de..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/haiku-module.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2009, Colin Günther. All Rights Reserved. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_HAIKU_MODULE_H_ -#define _FBSD_COMPAT_SYS_HAIKU_MODULE_H_ - - -#include -#include - -#include -#include - - -#undef ASSERT - /* private/kernel/debug.h sets it */ - -typedef struct device *device_t; -typedef struct devclass *devclass_t; - -typedef int (*device_method_signature_t)(device_t dev); - -typedef int device_probe_t(device_t dev); -typedef int device_attach_t(device_t dev); -typedef int device_detach_t(device_t dev); -typedef int device_resume_t(device_t dev); -typedef int device_suspend_t(device_t dev); - -struct device_method { - const char *name; - device_method_signature_t method; -}; - -typedef struct device_method device_method_t; - -#define DEVMETHOD(name, func) { #name, (device_method_signature_t)&func } -#define DEVMETHOD_END { 0, 0 } - -typedef struct { - const char *name; - device_method_t *methods; - size_t softc_size; -} driver_t; - -#define DRIVER_MODULE_NAME(name, busname) \ - __fbsd_ ## name ## _ ## busname - -status_t _fbsd_init_hardware(driver_t *driver[]); -status_t _fbsd_init_drivers(driver_t *driver[]); -status_t _fbsd_uninit_drivers(driver_t *driver[]); - -extern const char *gDriverName; -driver_t *__haiku_select_miibus_driver(device_t dev); -driver_t *__haiku_probe_miibus(device_t dev, driver_t *drivers[]); -status_t __haiku_handle_fbsd_drivers_list(status_t (*handler)(driver_t *[])); - -status_t init_wlan_stack(void); -void uninit_wlan_stack(void); -status_t start_wlan(device_t); -status_t stop_wlan(device_t); -status_t wlan_control(void*, uint32, void*, size_t); -status_t wlan_close(void*); -status_t wlan_if_l2com_alloc(void*); - -/* we define the driver methods with HAIKU_FBSD_DRIVERS_GLUE to - * force the rest of the stuff to be linked back with the driver. - * While gcc 2.95 packs everything from the static library onto - * the final binary, gcc 4.x rightfuly doesn't. */ - -#define HAIKU_FBSD_DRIVERS_GLUE(publicname) \ - extern const char *gDeviceNameList[]; \ - extern device_hooks gDeviceHooks; \ - const char *gDriverName = #publicname; \ - int32 api_version = B_CUR_DRIVER_API_VERSION; \ - status_t init_hardware() \ - { \ - return __haiku_handle_fbsd_drivers_list(_fbsd_init_hardware); \ - } \ - status_t init_driver() \ - { \ - return __haiku_handle_fbsd_drivers_list(_fbsd_init_drivers); \ - } \ - void uninit_driver() \ - { \ - __haiku_handle_fbsd_drivers_list(_fbsd_uninit_drivers); \ - } \ - const char **publish_devices() \ - { return gDeviceNameList; } \ - device_hooks *find_device(const char *name) \ - { return &gDeviceHooks; } \ - status_t init_wlan_stack(void) \ - { return B_OK; } \ - void uninit_wlan_stack(void) {} \ - status_t start_wlan(device_t dev) \ - { return B_OK; } \ - status_t stop_wlan(device_t dev) \ - { return B_OK; } \ - status_t wlan_control(void *cookie, uint32 op, void *arg, \ - size_t length) \ - { return B_BAD_VALUE; } \ - status_t wlan_close(void* cookie) \ - { return B_OK; } \ - status_t wlan_if_l2com_alloc(void* ifp) \ - { return B_OK; } - -#define HAIKU_FBSD_DRIVER_GLUE(publicname, name, busname) \ - extern driver_t *DRIVER_MODULE_NAME(name, busname); \ - status_t __haiku_handle_fbsd_drivers_list(status_t (*proc)(driver_t *[])) {\ - driver_t *drivers[] = { \ - DRIVER_MODULE_NAME(name, busname), \ - NULL \ - }; \ - return (*proc)(drivers); \ - } \ - HAIKU_FBSD_DRIVERS_GLUE(publicname); - -#define HAIKU_FBSD_WLAN_DRIVERS_GLUE(publicname) \ - extern const char *gDeviceNameList[]; \ - extern device_hooks gDeviceHooks; \ - const char *gDriverName = #publicname; \ - int32 api_version = B_CUR_DRIVER_API_VERSION; \ - status_t init_hardware() \ - { \ - return __haiku_handle_fbsd_drivers_list(_fbsd_init_hardware); \ - } \ - status_t init_driver() \ - { \ - return __haiku_handle_fbsd_drivers_list(_fbsd_init_drivers); \ - } \ - void uninit_driver() \ - { \ - __haiku_handle_fbsd_drivers_list(_fbsd_uninit_drivers); \ - } \ - const char **publish_devices() \ - { return gDeviceNameList; } \ - device_hooks *find_device(const char *name) \ - { return &gDeviceHooks; } - -#define HAIKU_FBSD_WLAN_DRIVER_GLUE(publicname, name, busname) \ - extern driver_t *DRIVER_MODULE_NAME(name, busname); \ - status_t __haiku_handle_fbsd_drivers_list(status_t (*proc)(driver_t *[])) {\ - driver_t *drivers[] = { \ - DRIVER_MODULE_NAME(name, busname), \ - NULL \ - }; \ - return (*proc)(drivers); \ - } \ - HAIKU_FBSD_WLAN_DRIVERS_GLUE(publicname); - -#define HAIKU_FBSD_RETURN_MII_DRIVER(drivers) \ - driver_t *__haiku_select_miibus_driver(device_t dev) \ - { \ - return __haiku_probe_miibus(dev, drivers); \ - } - -#define HAIKU_FBSD_MII_DRIVER(name) \ - extern driver_t *DRIVER_MODULE_NAME(name, miibus); \ - driver_t *__haiku_select_miibus_driver(device_t dev) \ - { \ - driver_t *drivers[] = { \ - DRIVER_MODULE_NAME(name, miibus), \ - NULL \ - }; \ - return __haiku_probe_miibus(dev, drivers); \ - } - -#define NO_HAIKU_FBSD_MII_DRIVER() \ - HAIKU_FBSD_RETURN_MII_DRIVER(NULL) - -extern spinlock __haiku_intr_spinlock; -extern int __haiku_disable_interrupts(device_t dev); -extern void __haiku_reenable_interrupts(device_t dev); - -#define HAIKU_CHECK_DISABLE_INTERRUPTS __haiku_disable_interrupts -#define HAIKU_REENABLE_INTERRUPTS __haiku_reenable_interrupts - -#define NO_HAIKU_CHECK_DISABLE_INTERRUPTS() \ - int HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev) { \ - panic("should never be called."); \ - return -1; \ - } - -#define NO_HAIKU_REENABLE_INTERRUPTS() \ - void HAIKU_REENABLE_INTERRUPTS(device_t dev) {} - -extern int __haiku_driver_requirements; - -enum { - FBSD_TASKQUEUES = 1 << 0, - FBSD_FAST_TASKQUEUE = 1 << 1, - FBSD_SWI_TASKQUEUE = 1 << 2, - FBSD_WLAN = 1 << 3, -}; - -#define HAIKU_DRIVER_REQUIREMENTS(flags) \ - int __haiku_driver_requirements = (flags) - -#define HAIKU_DRIVER_REQUIRES(flag) (__haiku_driver_requirements & (flag)) - - -/* #pragma mark - firmware loading */ - - -/* - * Only needed to be specified in the glue code of drivers which actually need - * to load firmware. See iprowifi2100 for an example. - */ - -extern const uint __haiku_firmware_version; - -/* Use 0 if driver doesn't care about firmware version. */ -#define HAIKU_FIRMWARE_VERSION(version) \ - const uint __haiku_firmware_version = (version) - -extern const uint __haiku_firmware_parts_count; -extern const char* __haiku_firmware_name_map[][2]; - -#define HAIKU_FIRMWARE_NAME_MAP(firmwarePartsCount) \ - const uint __haiku_firmware_parts_count = firmwarePartsCount; \ - const char* __haiku_firmware_name_map[firmwarePartsCount][2] - -#define NO_HAIKU_FIRMWARE_NAME_MAP() \ - const uint __haiku_firmware_parts_count = 0; \ - const char* __haiku_firmware_name_map[0][2] = {} - - -/* #pragma mark - synchronization */ - - -#define HAIKU_INTR_REGISTER_STATE \ - cpu_status __haiku_cpu_state = 0 - -#define HAIKU_INTR_REGISTER_ENTER() do { \ - __haiku_cpu_state = disable_interrupts(); \ - acquire_spinlock(&__haiku_intr_spinlock); \ -} while (0) - -#define HAIKU_INTR_REGISTER_LEAVE() do { \ - release_spinlock(&__haiku_intr_spinlock); \ - restore_interrupts(__haiku_cpu_state); \ -} while (0) - -#define HAIKU_PROTECT_INTR_REGISTER(x) do { \ - HAIKU_INTR_REGISTER_STATE; \ - HAIKU_INTR_REGISTER_ENTER(); \ - x; \ - HAIKU_INTR_REGISTER_LEAVE(); \ -} while (0) - -#define DEFINE_CLASS_0(name, driver, methods, size) \ - driver_t driver = { #name, methods, size } - -#define DRIVER_MODULE(name, busname, driver, devclass, evh, arg) \ - driver_t *DRIVER_MODULE_NAME(name, busname) = &(driver); \ - devclass_t *__class_ ## name ## _ ## busname ## _ ## devclass = &(devclass) - -#define DRIVER_MODULE_ORDERED(name, busname, driver, devclass, evh, arg, order) \ - DRIVER_MODULE(name, busname, driver, devclass, evh, arg) - -#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) - -#endif /* _FBSD_COMPAT_SYS_HAIKU_MODULE_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/ioccom.h b/src/libs/compat/freebsd_network/compat/sys/ioccom.h deleted file mode 100644 index f6ba2deb2d..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/ioccom.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_IOCCOM_H_ -#define _FBSD_COMPAT_SYS_IOCCOM_H_ - - -#define _IOW(g,n,t) SIOCEND + n -#define _IOWR(g,n,t) SIOCEND + n - -#endif /* _FBSD_COMPAT_SYS_IOCCOM_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/kernel.h b/src/libs/compat/freebsd_network/compat/sys/kernel.h deleted file mode 100644 index 0124a6892b..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/kernel.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2007-2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_KERNEL_H_ -#define _FBSD_COMPAT_SYS_KERNEL_H_ - - -#include - -#include - -#include -#include - - -/* - * - * The rate at which FreeBSD can generate callouts (kind of timeout mechanism). - * For FreeBSD 8 this is typically 1000 times per second (100 for ARM). - * This value is defined in a file called subr_param.c - * - * WHile Haiku can have a much higher granularity, it is not a good idea to have - * this since FreeBSD tries to do certain tasks based on ticks, for instance - * autonegotiation and wlan scanning. - * Suffixing LL prevents integer overflows during calculations. - * as it defines a long long constant.*/ -#define hz 1000LL - -#define ticks_to_usecs(t) (1000000*((bigtime_t)t) / hz) - -typedef void (*system_init_func_t)(void *); - - -struct __system_init { - system_init_func_t func; -}; - -/* TODO implement SYSINIT/SYSUNINIT subsystem */ -#define SYSINIT(uniquifier, subsystem, order, func, ident) \ - struct __system_init __init_##uniquifier = { (system_init_func_t) func } - -#define SYSUNINIT(uniquifier, subsystem, order, func, ident) \ - struct __system_init __uninit_##uniquifier = { (system_init_func_t) func } - -#define TUNABLE_INT(path, var) -#define TUNABLE_INT_FETCH(path, var) - -extern int ticks; - -#endif diff --git a/src/libs/compat/freebsd_network/compat/sys/kthread.h b/src/libs/compat/freebsd_network/compat/sys/kthread.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/libs/compat/freebsd_network/compat/sys/ktr.h b/src/libs/compat/freebsd_network/compat/sys/ktr.h deleted file mode 100644 index 2e817a74c8..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/ktr.h +++ /dev/null @@ -1,196 +0,0 @@ -/*- - * Copyright (c) 1996 Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Berkeley Software Design Inc's name may not be used to endorse or - * promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from BSDI $Id: ktr.h,v 1.10.2.7 2000/03/16 21:44:42 cp Exp $ - * $FreeBSD: src/sys/sys/ktr.h,v 1.32.2.2 2006/01/23 14:56:33 marius Exp $ - */ - -/* - * Wraparound kernel trace buffer support. - */ -#ifndef _SYS_KTR_H_ -#define _SYS_KTR_H_ - -/* - * Trace classes - */ -#define KTR_GEN 0x00000001 /* General (TR) */ -#define KTR_NET 0x00000002 /* Network */ -#define KTR_DEV 0x00000004 /* Device driver */ -#define KTR_LOCK 0x00000008 /* MP locking */ -#define KTR_SMP 0x00000010 /* MP general */ -#define KTR_FS 0x00000020 /* Filesystem */ -#define KTR_PMAP 0x00000040 /* Pmap tracing */ -#define KTR_MALLOC 0x00000080 /* Malloc tracing */ -#define KTR_TRAP 0x00000100 /* Trap processing */ -#define KTR_INTR 0x00000200 /* Interrupt tracing */ -#define KTR_SIG 0x00000400 /* Signal processing */ -#define KTR_CLK 0x00000800 /* hardclock verbose */ -#define KTR_PROC 0x00001000 /* Process scheduling */ -#define KTR_SYSC 0x00002000 /* System call */ -#define KTR_INIT 0x00004000 /* System initialization */ -#define KTR_KGDB 0x00008000 /* Trace kgdb internals */ -#define KTR_IO 0x00010000 /* Upper I/O */ -#define KTR_EVH 0x00020000 /* Eventhandler */ -#define KTR_VFS 0x00040000 /* VFS events */ -#define KTR_VOP 0x00080000 /* Auto-generated vop events */ -#define KTR_VM 0x00100000 /* The virtual memory system */ -#define KTR_WITNESS 0x00200000 -#define KTR_RUNQ 0x00400000 /* Run queue */ -#define KTR_CONTENTION 0x00800000 /* Lock contention */ -#define KTR_UMA 0x01000000 /* UMA slab allocator */ -#define KTR_CALLOUT 0x02000000 /* Callouts and timeouts */ -#define KTR_GEOM 0x04000000 /* GEOM I/O events */ -#define KTR_BUSDMA 0x08000000 /* busdma(9) events */ -#define KTR_CRITICAL 0x10000000 /* Critical sections */ -#define KTR_SCHED 0x20000000 /* Machine parsed sched info. */ -#define KTR_BUF 0x40000000 /* Buffer cache */ -#define KTR_ALL 0x7fffffff - -/* - * Trace classes which can be assigned to particular use at compile time - * These must remain in high 22 as some assembly code counts on it - */ -#define KTR_CT1 0x01000000 -#define KTR_CT2 0x02000000 -#define KTR_CT3 0x04000000 -#define KTR_CT4 0x08000000 -#define KTR_CT5 0x10000000 -#define KTR_CT6 0x20000000 -#define KTR_CT7 0x40000000 -#define KTR_CT8 0x80000000 - -/* Trace classes to compile in */ -#ifdef KTR -#ifndef KTR_COMPILE -#define KTR_COMPILE (KTR_ALL) -#endif -#else /* !KTR */ -#undef KTR_COMPILE -#define KTR_COMPILE 0 -#endif /* KTR */ - -/* Trace classes that can not be used with KTR_ALQ */ -#define KTR_ALQ_MASK (KTR_WITNESS) - -/* - * Version number for ktr_entry struct. Increment this when you break binary - * compatibility. - */ -#define KTR_VERSION 2 - -#define KTR_PARMS 6 - -#ifndef LOCORE - -struct ktr_entry { - u_int64_t ktr_timestamp; - int ktr_cpu; - int ktr_line; - const char *ktr_file; - const char *ktr_desc; - struct thread *ktr_thread; - u_long ktr_parms[KTR_PARMS]; -}; - -extern int ktr_cpumask; -extern int ktr_mask; -extern int ktr_entries; -extern int ktr_verbose; - -extern volatile int ktr_idx; -extern struct ktr_entry ktr_buf[]; - -#ifdef KTR - -#if 0 -void ktr_tracepoint(u_int mask, const char *file, int line, - const char *format, u_long arg1, u_long arg2, u_long arg3, - u_long arg4, u_long arg5, u_long arg6); -#else -extern void driver_printf(const char *format, ...); -#define ktr_tracepoint(mask, file, line, format, arg1, arg2, arg3, arg4, arg5, arg6) \ - driver_printf("(%s:%i) " format "\n", file, line, arg1, arg2, arg3, arg4, arg5, arg6) -#endif - -#define CTR6(m, format, p1, p2, p3, p4, p5, p6) do { \ - if (KTR_COMPILE & (m)) \ - ktr_tracepoint((m), __FILE__, __LINE__, format, \ - (u_long)(p1), (u_long)(p2), (u_long)(p3), \ - (u_long)(p4), (u_long)(p5), (u_long)(p6)); \ - } while(0) -#define CTR0(m, format) CTR6(m, format, 0, 0, 0, 0, 0, 0) -#define CTR1(m, format, p1) CTR6(m, format, p1, 0, 0, 0, 0, 0) -#define CTR2(m, format, p1, p2) CTR6(m, format, p1, p2, 0, 0, 0, 0) -#define CTR3(m, format, p1, p2, p3) CTR6(m, format, p1, p2, p3, 0, 0, 0) -#define CTR4(m, format, p1, p2, p3, p4) CTR6(m, format, p1, p2, p3, p4, 0, 0) -#define CTR5(m, format, p1, p2, p3, p4, p5) CTR6(m, format, p1, p2, p3, p4, p5, 0) -#else /* KTR */ -#define CTR0(m, d) -#define CTR1(m, d, p1) -#define CTR2(m, d, p1, p2) -#define CTR3(m, d, p1, p2, p3) -#define CTR4(m, d, p1, p2, p3, p4) -#define CTR5(m, d, p1, p2, p3, p4, p5) -#define CTR6(m, d, p1, p2, p3, p4, p5, p6) -#endif /* KTR */ - -#define TR0(d) CTR0(KTR_GEN, d) -#define TR1(d, p1) CTR1(KTR_GEN, d, p1) -#define TR2(d, p1, p2) CTR2(KTR_GEN, d, p1, p2) -#define TR3(d, p1, p2, p3) CTR3(KTR_GEN, d, p1, p2, p3) -#define TR4(d, p1, p2, p3, p4) CTR4(KTR_GEN, d, p1, p2, p3, p4) -#define TR5(d, p1, p2, p3, p4, p5) CTR5(KTR_GEN, d, p1, p2, p3, p4, p5) -#define TR6(d, p1, p2, p3, p4, p5, p6) CTR6(KTR_GEN, d, p1, p2, p3, p4, p5, p6) - -/* - * Trace initialization events, similar to CTR with KTR_INIT, but - * completely ifdef'ed out if KTR_INIT isn't in KTR_COMPILE (to - * save string space, the compiler doesn't optimize out strings - * for the conditional ones above). - */ -#if (KTR_COMPILE & KTR_INIT) != 0 -#define ITR0(d) CTR0(KTR_INIT, d) -#define ITR1(d, p1) CTR1(KTR_INIT, d, p1) -#define ITR2(d, p1, p2) CTR2(KTR_INIT, d, p1, p2) -#define ITR3(d, p1, p2, p3) CTR3(KTR_INIT, d, p1, p2, p3) -#define ITR4(d, p1, p2, p3, p4) CTR4(KTR_INIT, d, p1, p2, p3, p4) -#define ITR5(d, p1, p2, p3, p4, p5) CTR5(KTR_INIT, d, p1, p2, p3, p4, p5) -#define ITR6(d, p1, p2, p3, p4, p5, p6) CTR6(KTR_INIT, d, p1, p2, p3, p4, p5, p6) -#else -#define ITR0(d) -#define ITR1(d, p1) -#define ITR2(d, p1, p2) -#define ITR3(d, p1, p2, p3) -#define ITR4(d, p1, p2, p3, p4) -#define ITR5(d, p1, p2, p3, p4, p5) -#define ITR6(d, p1, p2, p3, p4, p5, p6) -#endif - -#endif /* !LOCORE */ - -#endif /* !_SYS_KTR_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/libkern.h b/src/libs/compat/freebsd_network/compat/sys/libkern.h deleted file mode 100644 index 98b870a190..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/libkern.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_LIBKERN_H_ -#define _FBSD_COMPAT_SYS_LIBKERN_H_ - - -#include -#include - - -extern int random(void); -uint32_t arc4random(void); - -static __inline int imax(int a, int b) { return (a > b ? a : b); } - -extern int abs(int a); - -#endif /* _FBSD_COMPAT_SYS_LIBKERN_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/limits.h b/src/libs/compat/freebsd_network/compat/sys/limits.h deleted file mode 100644 index 492074debb..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/limits.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_LIMITS_H_ -#define _FBSD_COMPAT_SYS_LIMITS_H_ - - -#endif /* _FBSD_COMPAT_SYS_LIMITS_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/linker.h b/src/libs/compat/freebsd_network/compat/sys/linker.h deleted file mode 100644 index 52cd150ece..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/linker.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_LINKER_H_ -#define _FBSD_COMPAT_SYS_LINKER_H_ - - -#endif /* _FBSD_COMPAT_SYS_LINKER_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/linker_set.h b/src/libs/compat/freebsd_network/compat/sys/linker_set.h deleted file mode 100644 index 41c964df38..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/linker_set.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_LINKER_SET_H_ -#define _FBSD_COMPAT_SYS_LINKER_SET_H_ - - -#ifndef _FBSD_COMPAT_SYS_CDEFS_H_ -#error this file needs sys/cdefs.h as a prerequisite -#endif - -/* - * The following macros are used to declare global sets of objects, which - * are collected by the linker into a `linker_set' as defined below. - * For ELF, this is done by constructing a separate segment for each set. - */ - -/* - * Private macros, not to be used outside this header file. - */ -#ifdef __GNUCLIKE___SECTION -#define __MAKE_SET(set, sym) \ - static void const * const __set_##set##_sym_##sym \ - __section("set_" #set) __used = &sym -#else /* !__GNUCLIKE___SECTION */ -#ifndef lint -#error this file needs to be ported to your compiler -#endif /* lint */ -#define __MAKE_SET(set, sym) extern void const * const (__set_##set##_sym_##sym) -#endif /* __GNUCLIKE___SECTION */ - -/* - * Public macros. - */ -#define TEXT_SET(set, sym) __MAKE_SET(set, sym) -#define DATA_SET(set, sym) __MAKE_SET(set, sym) -#define BSS_SET(set, sym) __MAKE_SET(set, sym) -#define ABS_SET(set, sym) __MAKE_SET(set, sym) -#define SET_ENTRY(set, sym) __MAKE_SET(set, sym) - -/* - * Initialize before referring to a given linker set. - */ -#define SET_DECLARE(set, ptype) \ - extern ptype *__CONCAT(__start_set_,set); \ - extern ptype *__CONCAT(__stop_set_,set) - -#define SET_BEGIN(set) \ - (&__CONCAT(__start_set_,set)) -#define SET_LIMIT(set) \ - (&__CONCAT(__stop_set_,set)) - -/* - * Iterate over all the elements of a set. - * - * Sets always contain addresses of things, and "pvar" points to words - * containing those addresses. Thus is must be declared as "type **pvar", - * and the address of each set item is obtained inside the loop by "*pvar". - */ -#define SET_FOREACH(pvar, set) \ - for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++) - -#endif /* _FBSD_COMPAT_SYS_LINKER_SET_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/lock.h b/src/libs/compat/freebsd_network/compat/sys/lock.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/libs/compat/freebsd_network/compat/sys/malloc.h b/src/libs/compat/freebsd_network/compat/sys/malloc.h deleted file mode 100644 index 7dc4018101..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/malloc.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_MALLOC_H_ -#define _FBSD_COMPAT_SYS_MALLOC_H_ - - -#include - -#include - -#include -#include -#include - - -/* - * flags to malloc. - */ -#define M_NOWAIT 0x0001 -#define M_WAITOK 0x0002 -#define M_ZERO 0x0100 - -#define M_MAGIC 877983977 /* time when first defined :-) */ - -#define M_DEVBUF - - -void *_kernel_malloc(size_t size, int flags); -void _kernel_free(void *ptr); - -void *_kernel_contigmalloc(const char *file, int line, size_t size, int flags, - vm_paddr_t low, vm_paddr_t high, unsigned long alignment, - unsigned long boundary); -void _kernel_contigfree(void *addr, unsigned long size); - -#define kernel_malloc(size, base, flags) \ - _kernel_malloc(size, flags) - -#define kernel_free(ptr, base) \ - _kernel_free(ptr) - -#define kernel_contigmalloc(size, type, flags, low, high, alignment, boundary) \ - _kernel_contigmalloc(__FILE__, __LINE__, size, flags, low, high, \ - alignment, boundary) - -#define kernel_contigfree(addr, size, base) \ - _kernel_contigfree(addr, size) - -#ifdef FBSD_DRIVER -# define malloc(size, tag, flags) kernel_malloc(size, tag, flags) -# define free(pointer, tag) kernel_free(pointer, tag) -# define contigmalloc(size, type, flags, low, high, alignment, boundary) \ - _kernel_contigmalloc(__FILE__, __LINE__, size, flags, low, high, \ - alignment, boundary) -# define contigfree(addr, size, base) \ - _kernel_contigfree(addr, size) -#endif - -#define MALLOC_DEFINE(type, shortdesc, longdesc) int type[1] - -#define MALLOC_DECLARE(type) \ - extern int type[1] - -#endif /* _FBSD_COMPAT_SYS_MALLOC_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/mbuf-fbsd.h b/src/libs/compat/freebsd_network/compat/sys/mbuf-fbsd.h deleted file mode 100644 index 2983efd461..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/mbuf-fbsd.h +++ /dev/null @@ -1,117 +0,0 @@ -/*- - * Copyright (c) 1982, 1986, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)mbuf.h 8.5 (Berkeley) 2/19/95 - * $FreeBSD: src/sys/sys/mbuf.h,v 1.170.2.6 2006/03/23 23:24:32 sam Exp $ - */ -#ifndef _FBSD_COMPAT_SYS_MBUF_FBSD_H_ -#define _FBSD_COMPAT_SYS_MBUF_FBSD_H_ - -/* - * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place - * an object of the specified size at the end of the mbuf, longword aligned. - */ -#define M_ALIGN(m, len) do { \ - (m)->m_data += (MLEN - (len)) & ~(sizeof(long) - 1); \ -} while (0) - -/* - * As above, for mbufs allocated with m_gethdr/MGETHDR - * or initialized by M_COPY_PKTHDR. - */ -#define MH_ALIGN(m, len) do { \ - (m)->m_data += (MHLEN - (len)) & ~(sizeof(long) - 1); \ -} while (0) - -/* -#define MEXT_IS_REF(m) (((m)->m_ext.ref_cnt != NULL) \ - && (*((m)->m_ext.ref_cnt) > 1)) - */ -#define MEXT_IS_REF(m) 0 - -/* - * Evaluate TRUE if it's safe to write to the mbuf m's data region (this - * can be both the local data payload, or an external buffer area, - * depending on whether M_EXT is set). - */ - -/* -#define M_WRITABLE(m) (!((m)->m_flags & M_RDONLY) && (!((m)->m_flags \ - & M_EXT) || !MEXT_IS_REF(m))) - */ -#define M_WRITABLE(m) (!((m)->m_flags & M_EXT) || !MEXT_IS_REF(m)) - -/* - * Compute the amount of space available - * before the current start of data in an mbuf. - * - * The M_WRITABLE() is a temporary, conservative safety measure: the burden - * of checking writability of the mbuf data area rests solely with the caller. - */ -#define M_LEADINGSPACE(m) \ - ((m)->m_flags & M_EXT ? \ - (M_WRITABLE(m) ? (m)->m_data - (m)->m_ext.ext_buf : 0): \ - (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \ - (m)->m_data - (m)->m_dat) - -/* - * Compute the amount of space available after the end of data in an mbuf. - * - * The M_WRITABLE() is a temporary, conservative safety measure: the burden - * of checking writability of the mbuf data area rests solely with the caller. - */ -#define M_TRAILINGSPACE(m) \ - ((m)->m_flags & M_EXT ? \ - (M_WRITABLE(m) ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size \ - - ((m)->m_data + (m)->m_len) : 0) : \ - &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len)) - -/* - * Arrange to prepend space of size plen to mbuf m. - * If a new mbuf must be allocated, how specifies whether to wait. - * If the allocation fails, the original mbuf chain is freed and m is - * set to NULL. - */ -#define M_PREPEND(m, plen, how) do { \ - struct mbuf **_mmp = &(m); \ - struct mbuf *_mm = *_mmp; \ - int _mplen = (plen); \ - int __mhow = (how); \ - \ - MBUF_CHECKSLEEP(how); \ - if (M_LEADINGSPACE(_mm) >= _mplen) { \ - _mm->m_data -= _mplen; \ - _mm->m_len += _mplen; \ - } else \ - _mm = m_prepend(_mm, _mplen, __mhow); \ - if (_mm != NULL && _mm->m_flags & M_PKTHDR) \ - _mm->m_pkthdr.len += _mplen; \ - *_mmp = _mm; \ -} while (0) - -#endif diff --git a/src/libs/compat/freebsd_network/compat/sys/mbuf.h b/src/libs/compat/freebsd_network/compat/sys/mbuf.h deleted file mode 100644 index 8c6e6c5b03..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/mbuf.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_MBUF_H_ -#define _FBSD_COMPAT_SYS_MBUF_H_ - - -#include -#include -#include - - -#define MLEN ((int)(MSIZE - sizeof(struct m_hdr))) -#define MHLEN ((int)(MLEN - sizeof(struct pkthdr))) - -#define MINCLSIZE (MHLEN + 1) - -#define MBTOM(how) (how) -#define M_DONTWAIT M_NOWAIT -#define M_TRYWAIT M_WAITOK -#define M_WAIT M_WAITOK - -#define MT_DATA 1 - -#define M_EXT 0x00000001 -#define M_PKTHDR 0x00000002 -#define M_RDONLY 0x00000008 -#define M_PROTO1 0x00000010 -#define M_PROTO2 0x00000020 -#define M_PROTO3 0x00000040 -#define M_PROTO4 0x00000080 -#define M_PROTO5 0x00000100 -#define M_BCAST 0x00000200 -#define M_MCAST 0x00000400 -#define M_FRAG 0x00000800 -#define M_FIRSTFRAG 0x00001000 -#define M_LASTFRAG 0x00002000 -#define M_VLANTAG 0x00010000 -#define M_PROTO6 0x00080000 -#define M_PROTO7 0x00100000 -#define M_PROTO8 0x00200000 - -#define M_COPYFLAGS (M_PKTHDR | M_RDONLY | M_BCAST | M_MCAST | M_FRAG \ - | M_FIRSTFRAG | M_LASTFRAG | M_VLANTAG) - // Flags preserved when copying m_pkthdr - -#define M_MOVE_PKTHDR(to, from) m_move_pkthdr((to), (from)) -#define MGET(m, how, type) ((m) = m_get((how), (type))) -#define MGETHDR(m, how, type) ((m) = m_gethdr((how), (type))) -#define MCLGET(m, how) m_clget((m), (how)) - -#define mtod(m, type) ((type)((m)->m_data)) - -// Check if the supplied mbuf has a packet header, or else panic. -#define M_ASSERTPKTHDR(m) KASSERT(m != NULL && m->m_flags & M_PKTHDR, \ - ("%s: no mbuf packet header!", __func__)) - -#define MBUF_CHECKSLEEP(how) do { } while (0) - -#define MTAG_PERSISTENT 0x800 - -#define EXT_CLUSTER 1 // 2048 bytes -#define EXT_JUMBOP 4 // Page size -#define EXT_JUMBO9 5 // 9 * 1024 bytes -#define EXT_NET_DRV 100 // custom ext_buf provided by net driver - -#define CSUM_IP 0x0001 -#define CSUM_TCP 0x0002 -#define CSUM_UDP 0x0004 -#define CSUM_TSO 0x0020 -#define CSUM_IP_CHECKED 0x0100 -#define CSUM_IP_VALID 0x0200 -#define CSUM_DATA_VALID 0x0400 -#define CSUM_PSEUDO_HDR 0x0800 -#define CSUM_DELAY_DATA (CSUM_TCP | CSUM_UDP) - -#define MEXTADD(m, buf, size, free, arg1, arg2, flags, type) \ - m_extadd((m), (caddr_t)(buf), (size), (free),(arg1),(arg2),(flags), (type)) - - -extern int max_linkhdr; -extern int max_protohdr; -extern int max_hdr; -extern int max_datalen; // MHLEN - max_hdr - - -struct m_hdr { - struct mbuf* mh_next; - struct mbuf* mh_nextpkt; - caddr_t mh_data; - int mh_len; - int mh_flags; - short mh_type; -}; - -struct pkthdr { - struct ifnet* rcvif; - int len; - int csum_flags; - int csum_data; - uint16_t tso_segsz; - uint16_t ether_vtag; - SLIST_HEAD(packet_tags, m_tag) tags; -}; - -struct m_tag { - SLIST_ENTRY(m_tag) m_tag_link; // List of packet tags - u_int16_t m_tag_id; // Tag ID - u_int16_t m_tag_len; // Length of data - u_int32_t m_tag_cookie; // ABI/Module ID - void (*m_tag_free)(struct m_tag*); -}; - -struct m_ext { - caddr_t ext_buf; - unsigned int ext_size; - int ext_type; -}; - -struct mbuf { - struct m_hdr m_hdr; - union { - struct { - struct pkthdr MH_pkthdr; - union { - struct m_ext MH_ext; - char MH_databuf[MHLEN]; - } MH_dat; - } MH; - char M_databuf[MLEN]; - } M_dat; -}; - - -#define m_next m_hdr.mh_next -#define m_len m_hdr.mh_len -#define m_data m_hdr.mh_data -#define m_type m_hdr.mh_type -#define m_flags m_hdr.mh_flags -#define m_nextpkt m_hdr.mh_nextpkt -#define m_act m_nextpkt -#define m_pkthdr M_dat.MH.MH_pkthdr -#define m_ext M_dat.MH.MH_dat.MH_ext -#define m_pktdat M_dat.MH.MH_dat.MH_databuf -#define m_dat M_dat.M_databuf - - -void m_adj(struct mbuf*, int); -void m_align(struct mbuf*, int); -int m_append(struct mbuf*, int, c_caddr_t); -void m_cat(struct mbuf*, struct mbuf*); -void m_clget(struct mbuf*, int); -void* m_cljget(struct mbuf*, int, int); -struct mbuf* m_collapse(struct mbuf*, int, int); -void m_copyback(struct mbuf*, int, int, caddr_t); -void m_copydata(const struct mbuf*, int, int, caddr_t); -struct mbuf* m_copypacket(struct mbuf*, int); -struct mbuf* m_defrag(struct mbuf*, int); -struct mbuf* m_devget(char*, int, int, struct ifnet*, - void(*) (char*, caddr_t, u_int)); - -struct mbuf* m_dup(struct mbuf*, int); -int m_dup_pkthdr(struct mbuf*, struct mbuf*, int); - -void m_extadd(struct mbuf*, caddr_t, u_int, void(*) (void*, void*), - void*, void*, int, int); - -u_int m_fixhdr(struct mbuf*); -struct mbuf* m_free(struct mbuf*); -void m_freem(struct mbuf*); -struct mbuf* m_get(int, short); -struct mbuf* m_gethdr(int, short); -struct mbuf* m_getjcl(int, short, int, int); -u_int m_length(struct mbuf*, struct mbuf**); -struct mbuf* m_getcl(int, short, int); -void m_move_pkthdr(struct mbuf*, struct mbuf*); -struct mbuf* m_prepend(struct mbuf*, int, int); -struct mbuf* m_pulldown(struct mbuf*, int, int, int*); -struct mbuf* m_pullup(struct mbuf*, int); -struct mbuf* m_split(struct mbuf*, int, int); -struct mbuf* m_unshare(struct mbuf*, int); - -struct m_tag* m_tag_alloc(u_int32_t, int, int, int); -void m_tag_delete(struct mbuf*, struct m_tag*); -void m_tag_delete_chain(struct mbuf*, struct m_tag*); -void m_tag_free_default(struct m_tag*); -struct m_tag* m_tag_locate(struct mbuf*, u_int32_t, int, struct m_tag*); -struct m_tag* m_tag_copy(struct m_tag*, int); -int m_tag_copy_chain(struct mbuf*, struct mbuf*, int); -void m_tag_delete_nonpersistent(struct mbuf*); - - -static inline void -m_tag_setup(struct m_tag* tagPointer, u_int32_t cookie, int type, int length) -{ - tagPointer->m_tag_id = type; - tagPointer->m_tag_len = length; - tagPointer->m_tag_cookie = cookie; -} - - -static inline void -m_tag_free(struct m_tag* tag) -{ - (*tag->m_tag_free)(tag); -} - - -static inline void -m_tag_prepend(struct mbuf* memoryBuffer, struct m_tag* tag) -{ - SLIST_INSERT_HEAD(&memoryBuffer->m_pkthdr.tags, tag, m_tag_link); -} - - -static inline void -m_tag_unlink(struct mbuf* memoryBuffer, struct m_tag* tag) -{ - SLIST_REMOVE(&memoryBuffer->m_pkthdr.tags, tag, m_tag, m_tag_link); -} - - -#include - -#endif /* _FBSD_COMPAT_SYS_MBUF_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/module.h b/src/libs/compat/freebsd_network/compat/sys/module.h deleted file mode 100644 index 4315069b72..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/module.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _FBSD_COMPAT_SYS_MODULE_H_ -#define _FBSD_COMPAT_SYS_MODULE_H_ - - -#include - - -typedef struct module* module_t; - -typedef enum modeventtype { - MOD_LOAD, - MOD_UNLOAD, - MOD_SHUTDOWN, - MOD_QUIESCE -} modeventtype_t; - - -#define DECLARE_MODULE(name, data, sub, order) - -#define MODULE_VERSION(name, version) -#define MODULE_DEPEND(module, mdepend, vmin, vpref, vmax) - -#endif diff --git a/src/libs/compat/freebsd_network/compat/sys/mount.h b/src/libs/compat/freebsd_network/compat/sys/mount.h deleted file mode 100644 index 4d447271f5..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/mount.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_MOUNT_H_ -#define _FBSD_COMPAT_SYS_MOUNT_H_ - - -#endif /* _FBSD_COMPAT_SYS_MOUNT_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/mutex.h b/src/libs/compat/freebsd_network/compat/sys/mutex.h deleted file mode 100644 index 18b2838557..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/mutex.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_MUTEX_H_ -#define _FBSD_COMPAT_SYS_MUTEX_H_ - - -#include - -#include -#include -#include -#include -#include - - -#define MA_OWNED 0x1 -#define MA_NOTOWNED 0x2 -#define MA_RECURSED 0x4 -#define MA_NOTRECURSED 0x8 - -#define mtx_assert(mtx, what) - -#define MTX_DEF 0x0000 -#define MTX_RECURSE 0x0004 -#define MTX_QUIET 0x40000 -#define MTX_DUPOK 0x400000 - - -#define MTX_NETWORK_LOCK "network driver" - -#define NET_LOCK_GIANT() -#define NET_UNLOCK_GIANT() - - -extern struct mtx Giant; - - -void mtx_init(struct mtx*, const char*, const char*, int); -void mtx_destroy(struct mtx*); - - -static inline void -mtx_lock(struct mtx* mutex) -{ - if (mutex->type == MTX_DEF) { - mutex_lock(&mutex->u.mutex.lock); - mutex->u.mutex.owner = find_thread(NULL); - } else if (mutex->type == MTX_RECURSE) - recursive_lock_lock(&mutex->u.recursive); -} - - -static inline void -mtx_unlock(struct mtx* mutex) -{ - if (mutex->type == MTX_DEF) { - mutex->u.mutex.owner = -1; - mutex_unlock(&mutex->u.mutex.lock); - } else if (mutex->type == MTX_RECURSE) - recursive_lock_unlock(&mutex->u.recursive); -} - - -static inline int -mtx_initialized(struct mtx* mutex) -{ - /* TODO */ - return 1; -} - - -static inline int -mtx_owned(struct mtx* mutex) -{ - if (mutex->type == MTX_DEF) - return mutex->u.mutex.owner == find_thread(NULL); - if (mutex->type == MTX_RECURSE) { -#if KDEBUG - return mutex->u.recursive.lock.holder == find_thread(NULL); -#else - return mutex->u.recursive.holder == find_thread(NULL); -#endif - } - - return 0; -} - - -#endif /* _FBSD_COMPAT_SYS_MUTEX_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/namei.h b/src/libs/compat/freebsd_network/compat/sys/namei.h deleted file mode 100644 index 3da8a0a778..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/namei.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_NAMEI_H_ -#define _FBSD_COMPAT_SYS_NAMEI_H_ - - -#endif /* _FBSD_COMPAT_SYS_NAMEI_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/param.h b/src/libs/compat/freebsd_network/compat/sys/param.h deleted file mode 100644 index 51e09e4a6d..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/param.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_PARAM_H_ -#define _FBSD_COMPAT_SYS_PARAM_H_ - - -#include - -#include -#include -#include -#include -#include - - -/* The version this compatibility layer is based on */ -#define __FreeBSD_version 800107 - -#define MAXBSIZE 0x10000 - -#define PAGE_SHIFT 12 -#define PAGE_MASK (PAGE_SIZE - 1) - -#define trunc_page(x) ((x) & ~PAGE_MASK) - -#define ptoa(x) ((unsigned long)((x) << PAGE_SHIFT)) -#define atop(x) ((unsigned long)((x) >> PAGE_SHIFT)) - -/* MAJOR FIXME */ -#define Maxmem (32768) - -#ifndef MSIZE -#define MSIZE 256 -#endif - -#ifndef MCLSHIFT -#define MCLSHIFT 11 -#endif - -#define MCLBYTES (1 << MCLSHIFT) - -#define MJUMPAGESIZE PAGE_SIZE -#define MJUM9BYTES (9 * 1024) -#define MJUM16BYTES (16 * 1024) - -#define ALIGN_BYTES (sizeof(unsigned long) - 1) -#define ALIGN(x) ((((unsigned long)x) + ALIGN_BYTES) & ~ALIGN_BYTES) - -/* Macros for counting and rounding. */ -#ifndef howmany -#define howmany(x, y) (((x)+((y)-1))/(y)) -#endif -#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ -#define roundup2(x, y) (((x) + ((y) - 1)) & (~((y) - 1))) -#define rounddown(x, y) (((x) / (y)) * (y)) - -#define PRIMASK 0x0ff -#define PCATCH 0x100 -#define PDROP 0x200 -#define PBDRY 0x400 - -#define NBBY 8 /* number of bits in a byte */ - -/* Bit map related macros. */ -#define setbit(a,i) (((unsigned char *)(a))[(i)/NBBY] |= 1<<((i)%NBBY)) -#define clrbit(a,i) (((unsigned char *)(a))[(i)/NBBY] &= ~(1<<((i)%NBBY))) -#define isset(a,i) \ - (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) -#define isclr(a,i) \ - ((((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) == 0) - -#endif /* _FBSD_COMPAT_SYS_PARAM_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/pcpu.h b/src/libs/compat/freebsd_network/compat/sys/pcpu.h deleted file mode 100644 index 858d57b7f8..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/pcpu.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_PCPU_H_ -#define _FBSD_COMPAT_SYS_PCPU_H_ - - -#include - - -struct thread; - -#define curthread ((struct thread*)NULL) - /* NOTE: Dereferencing curthread will crash, which is intentional. There is - no FreeBSD compatible struct thread and Haiku's should not be used as it - is only valid for the current thread or with proper locking. Currently - only priv_check() expects a struct thread parameter and ignores it. Using - NULL will show us when other uses appear. */ - - -#endif /* _FBSD_COMPAT_SYS_PCPU_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/priority.h b/src/libs/compat/freebsd_network/compat/sys/priority.h deleted file mode 100644 index 61fd7f1b27..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/priority.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_PRIORITY_H_ -#define _FBSD_COMPAT_SYS_PRIORITY_H_ - - -#define PRI_MIN_KERN (64) -#define PZERO (PRI_MIN_KERN + 20) - -#endif /* _FBSD_COMPAT_SYS_PRIORITY_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/priv.h b/src/libs/compat/freebsd_network/compat/sys/priv.h deleted file mode 100644 index 4ba76e34c6..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/priv.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_PRIV_H_ -#define _FBSD_COMPAT_SYS_PRIV_H_ - - -#include - - -/* - * 802.11-related privileges. - */ -#define PRIV_NET80211_GETKEY 440 /* Query 802.11 keys. */ -#define PRIV_NET80211_MANAGE 441 /* Administer 802.11. */ - -#define PRIV_DRIVER 14 /* Low-level driver privilege. */ - - -/* - * Privilege check interfaces, modeled after historic suser() interfacs, but - * with the addition of a specific privilege name. No flags are currently - * defined for the API. Historically, flags specified using the real uid - * instead of the effective uid, and whether or not the check should be - * allowed in jail. - */ -struct thread; - - -__BEGIN_DECLS - -int priv_check(struct thread*, int); - -__END_DECLS - - -#endif /* _FBSD_COMPAT_SYS_PRIV_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/proc.h b/src/libs/compat/freebsd_network/compat/sys/proc.h deleted file mode 100644 index 1eb862a86a..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/proc.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_PROC_H_ -#define _FBSD_COMPAT_SYS_PROC_H_ - - -#endif /* _FBSD_COMPAT_SYS_PROC_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/protosw.h b/src/libs/compat/freebsd_network/compat/sys/protosw.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/libs/compat/freebsd_network/compat/sys/queue.h b/src/libs/compat/freebsd_network/compat/sys/queue.h deleted file mode 100644 index 7f2428779c..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/queue.h +++ /dev/null @@ -1,552 +0,0 @@ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - * $FreeBSD: src/sys/sys/queue.h,v 1.60.2.1 2005/08/16 22:41:39 phk Exp $ - */ -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -#include - -/* - * This file defines four types of data structures: singly-linked lists, - * singly-linked tail queues, lists and tail queues. - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A singly-linked tail queue is headed by a pair of pointers, one to the - * head of the list and the other to the tail of the list. The elements are - * singly linked for minimum space and pointer manipulation overhead at the - * expense of O(n) removal for arbitrary elements. New elements can be added - * to the list after an existing element, at the head of the list, or at the - * end of the list. Elements being removed from the head of the tail queue - * should use the explicit macro for this purpose for optimum efficiency. - * A singly-linked tail queue may only be traversed in the forward direction. - * Singly-linked tail queues are ideal for applications with large datasets - * and few or no removals or for implementing a FIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * For details on the use of these macros, see the queue(3) manual page. - * - * - * SLIST LIST STAILQ TAILQ - * _HEAD + + + + - * _HEAD_INITIALIZER + + + + - * _ENTRY + + + + - * _INIT + + + + - * _EMPTY + + + + - * _FIRST + + + + - * _NEXT + + + + - * _PREV - - - + - * _LAST - - + + - * _FOREACH + + + + - * _FOREACH_SAFE + + + + - * _FOREACH_REVERSE - - - + - * _FOREACH_REVERSE_SAFE - - - + - * _INSERT_HEAD + + + + - * _INSERT_BEFORE - + - + - * _INSERT_AFTER + + + + - * _INSERT_TAIL - - + + - * _CONCAT - - + + - * _REMOVE_HEAD + - + - - * _REMOVE + + + + - * - */ -#define QUEUE_MACRO_DEBUG 0 -#if QUEUE_MACRO_DEBUG -/* Store the last 2 places the queue element or head was altered */ -struct qm_trace { - char * lastfile; - int lastline; - char * prevfile; - int prevline; -}; - -#define TRACEBUF struct qm_trace trace; -#define TRASHIT(x) do {(x) = (void *)-1;} while (0) - -#define QMD_TRACE_HEAD(head) do { \ - (head)->trace.prevline = (head)->trace.lastline; \ - (head)->trace.prevfile = (head)->trace.lastfile; \ - (head)->trace.lastline = __LINE__; \ - (head)->trace.lastfile = __FILE__; \ -} while (0) - -#define QMD_TRACE_ELEM(elem) do { \ - (elem)->trace.prevline = (elem)->trace.lastline; \ - (elem)->trace.prevfile = (elem)->trace.lastfile; \ - (elem)->trace.lastline = __LINE__; \ - (elem)->trace.lastfile = __FILE__; \ -} while (0) - -#else -#define QMD_TRACE_ELEM(elem) -#define QMD_TRACE_HEAD(head) -#define TRACEBUF -#define TRASHIT(x) -#endif /* QUEUE_MACRO_DEBUG */ - -/* - * Singly-linked List declarations. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List functions. - */ -#define SLIST_EMPTY(head) ((head)->slh_first == NULL) - -#define SLIST_FIRST(head) ((head)->slh_first) - -#define SLIST_FOREACH(var, head, field) \ - for ((var) = SLIST_FIRST((head)); \ - (var); \ - (var) = SLIST_NEXT((var), field)) - -#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = SLIST_FIRST((head)); \ - (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ - for ((varp) = &SLIST_FIRST((head)); \ - ((var) = *(varp)) != NULL; \ - (varp) = &SLIST_NEXT((var), field)) - -#define SLIST_INIT(head) do { \ - SLIST_FIRST((head)) = NULL; \ -} while (0) - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ - SLIST_NEXT((slistelm), field) = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ - SLIST_FIRST((head)) = (elm); \ -} while (0) - -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if (SLIST_FIRST((head)) == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = SLIST_FIRST((head)); \ - while (SLIST_NEXT(curelm, field) != (elm)) \ - curelm = SLIST_NEXT(curelm, field); \ - SLIST_NEXT(curelm, field) = \ - SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ - } \ -} while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ -} while (0) - -/* - * Singly-linked Tail queue declarations. - */ -#define STAILQ_HEAD(name, type) \ -struct name { \ - struct type *stqh_first;/* first element */ \ - struct type **stqh_last;/* addr of last next element */ \ -} - -#define STAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).stqh_first } - -#define STAILQ_ENTRY(type) \ -struct { \ - struct type *stqe_next; /* next element */ \ -} - -/* - * Singly-linked Tail queue functions. - */ -#define STAILQ_CONCAT(head1, head2) do { \ - if (!STAILQ_EMPTY((head2))) { \ - *(head1)->stqh_last = (head2)->stqh_first; \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_INIT((head2)); \ - } \ -} while (0) - -#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) - -#define STAILQ_FIRST(head) ((head)->stqh_first) - -#define STAILQ_FOREACH(var, head, field) \ - for((var) = STAILQ_FIRST((head)); \ - (var); \ - (var) = STAILQ_NEXT((var), field)) - - -#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = STAILQ_FIRST((head)); \ - (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define STAILQ_INIT(head) do { \ - STAILQ_FIRST((head)) = NULL; \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_NEXT((tqelm), field) = (elm); \ -} while (0) - -#define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_FIRST((head)) = (elm); \ -} while (0) - -#define STAILQ_INSERT_TAIL(head, elm, field) do { \ - STAILQ_NEXT((elm), field) = NULL; \ - *(head)->stqh_last = (elm); \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ -} while (0) - -#define STAILQ_LAST(head, type, field) \ - (STAILQ_EMPTY((head)) ? \ - NULL : \ - ((struct type *) \ - ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) - -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) - -#define STAILQ_REMOVE(head, elm, type, field) do { \ - if (STAILQ_FIRST((head)) == (elm)) { \ - STAILQ_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = STAILQ_FIRST((head)); \ - while (STAILQ_NEXT(curelm, field) != (elm)) \ - curelm = STAILQ_NEXT(curelm, field); \ - if ((STAILQ_NEXT(curelm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ - } \ -} while (0) - -#define STAILQ_REMOVE_HEAD(head, field) do { \ - if ((STAILQ_FIRST((head)) = \ - STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ - if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -/* - * List declarations. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ - -#define LIST_EMPTY(head) ((head)->lh_first == NULL) - -#define LIST_FIRST(head) ((head)->lh_first) - -#define LIST_FOREACH(var, head, field) \ - for ((var) = LIST_FIRST((head)); \ - (var); \ - (var) = LIST_NEXT((var), field)) - -#define LIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = LIST_FIRST((head)); \ - (var) && ((tvar) = LIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define LIST_INIT(head) do { \ - LIST_FIRST((head)) = NULL; \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ - LIST_NEXT((listelm), field)->field.le_prev = \ - &LIST_NEXT((elm), field); \ - LIST_NEXT((listelm), field) = (elm); \ - (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - LIST_NEXT((elm), field) = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ - LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ - LIST_FIRST((head)) = (elm); \ - (elm)->field.le_prev = &LIST_FIRST((head)); \ -} while (0) - -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_REMOVE(elm, field) do { \ - if (LIST_NEXT((elm), field) != NULL) \ - LIST_NEXT((elm), field)->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = LIST_NEXT((elm), field); \ -} while (0) - -/* - * Tail queue declarations. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ - TRACEBUF \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ - TRACEBUF \ -} - -/* - * Tail queue functions. - */ -#define TAILQ_CONCAT(head1, head2, field) do { \ - if (!TAILQ_EMPTY(head2)) { \ - *(head1)->tqh_last = (head2)->tqh_first; \ - (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ - (head1)->tqh_last = (head2)->tqh_last; \ - TAILQ_INIT((head2)); \ - QMD_TRACE_HEAD(head1); \ - QMD_TRACE_HEAD(head2); \ - } \ -} while (0) - -#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) - -#define TAILQ_FIRST(head) ((head)->tqh_first) - -#define TAILQ_FOREACH(var, head, field) \ - for ((var) = TAILQ_FIRST((head)); \ - (var); \ - (var) = TAILQ_NEXT((var), field)) - -#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = TAILQ_FIRST((head)); \ - (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var); \ - (var) = TAILQ_PREV((var), headname, field)) - -#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ - (var) = (tvar)) - -#define TAILQ_INIT(head) do { \ - TAILQ_FIRST((head)) = NULL; \ - (head)->tqh_last = &TAILQ_FIRST((head)); \ - QMD_TRACE_HEAD(head); \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else { \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - QMD_TRACE_HEAD(head); \ - } \ - TAILQ_NEXT((listelm), field) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ - QMD_TRACE_ELEM(&(elm)->field); \ - QMD_TRACE_ELEM(&listelm->field); \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - TAILQ_NEXT((elm), field) = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ - QMD_TRACE_ELEM(&(elm)->field); \ - QMD_TRACE_ELEM(&listelm->field); \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ - TAILQ_FIRST((head))->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - TAILQ_FIRST((head)) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ - QMD_TRACE_HEAD(head); \ - QMD_TRACE_ELEM(&(elm)->field); \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - TAILQ_NEXT((elm), field) = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - QMD_TRACE_HEAD(head); \ - QMD_TRACE_ELEM(&(elm)->field); \ -} while (0) - -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) - -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) - -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field)) != NULL) \ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else { \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - QMD_TRACE_HEAD(head); \ - } \ - *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ - TRASHIT((elm)->field.tqe_next); \ - TRASHIT((elm)->field.tqe_prev); \ - QMD_TRACE_ELEM(&(elm)->field); \ -} while (0) - - -#ifdef _KERNEL - -/* - * XXX insque() and remque() are an old way of handling certain queues. - * They bogusly assumes that all queue heads look alike. - */ - -struct quehead { - struct quehead *qh_link; - struct quehead *qh_rlink; -}; - -#ifdef __CC_SUPPORTS___INLINE - -static __inline void -insque(void *a, void *b) -{ - struct quehead *element = (struct quehead *)a, - *head = (struct quehead *)b; - - element->qh_link = head->qh_link; - element->qh_rlink = head; - head->qh_link = element; - element->qh_link->qh_rlink = element; -} - -static __inline void -remque(void *a) -{ - struct quehead *element = (struct quehead *)a; - - element->qh_link->qh_rlink = element->qh_rlink; - element->qh_rlink->qh_link = element->qh_link; - element->qh_rlink = 0; -} - -#else /* !__CC_SUPPORTS___INLINE */ - -void insque(void *a, void *b); -void remque(void *a); - -#endif /* __CC_SUPPORTS___INLINE */ - -#endif /* _KERNEL */ - -#endif /* !_SYS_QUEUE_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/random.h b/src/libs/compat/freebsd_network/compat/sys/random.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/libs/compat/freebsd_network/compat/sys/rman.h b/src/libs/compat/freebsd_network/compat/sys/rman.h deleted file mode 100644 index c3911d974f..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/rman.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ - - -/*- - * Copyright 1998 Massachusetts Institute of Technology - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby - * granted, provided that both the above copyright notice and this - * permission notice appear in all copies, that both the above - * copyright notice and this permission notice appear in all - * supporting documentation, and that the name of M.I.T. not be used - * in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. M.I.T. makes - * no representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS - * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT - * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_SYS_RMAN_H_ -#define _FBSD_COMPAT_SYS_RMAN_H_ - - -#include -#include - - -#define RF_ACTIVE 0x0002 -#define RF_SHAREABLE 0x0004 -#define RF_OPTIONAL 0x0080 - -#define RF_ALIGNMENT_SHIFT 10 /* alignment size bit starts bit 10 */ -#define RF_ALIGNMENT_LOG2(x) ((x) << RF_ALIGNMENT_SHIFT) - -struct resource { - int r_type; - bus_space_tag_t r_bustag; /* bus_space tag */ - bus_space_handle_t r_bushandle; /* bus_space handle */ - area_id r_mapped_area; -}; - - -bus_space_handle_t rman_get_bushandle(struct resource *); -bus_space_tag_t rman_get_bustag(struct resource *); -int rman_get_rid(struct resource *); - - -static inline u_long -rman_get_start(struct resource *resourcePointer) -{ - return resourcePointer->r_bushandle; -} - - -static inline uint32_t -rman_make_alignment_flags(uint32_t size) -{ - int i; - - /* - * Find the hightest bit set, and add one if more than one bit - * set. We're effectively computing the ceil(log2(size)) here. - */ - for (i = 31; i > 0; i--) - if ((1 << i) & size) - break; - if (~(1 << i) & size) - i++; - - return RF_ALIGNMENT_LOG2(i); -} -#endif /* _FBSD_COMPAT_SYS_RMAN_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/socket.h b/src/libs/compat/freebsd_network/compat/sys/socket.h deleted file mode 100644 index dc83ed2edd..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/socket.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_SOCKET_H_ -#define _FBSD_COMPAT_SYS_SOCKET_H_ - - -#include - -#include -#include - - -// TODO Should be incorporated into Haikus socket.h with a number below AF_MAX -#define AF_IEEE80211 AF_MAX + 1 /* IEEE 802.11 protocol */ - -#endif /* _FBSD_COMPAT_SYS_SOCKET_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/sockio.h b/src/libs/compat/freebsd_network/compat/sys/sockio.h deleted file mode 100644 index 7d469d7e38..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/sockio.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2007-2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_SOCKIO_H_ -#define _FBSD_COMPAT_SYS_SOCKIO_H_ - - -#include - -#include - - -#define SIOCSIFCAP SIOCSPACKETCAP - -#endif diff --git a/src/libs/compat/freebsd_network/compat/sys/sysctl.h b/src/libs/compat/freebsd_network/compat/sys/sysctl.h deleted file mode 100644 index 0f324a296a..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/sysctl.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_SYSCTL_H_ -#define _FBSD_COMPAT_SYS_SYSCTL_H_ - - -#include - - -#ifdef _KERNEL - -struct sysctl_req { - void *newptr; -}; - -struct sysctl_ctx_list { -}; - -struct sysctl_oid_list { -}; - - -#define SYSCTL_HANDLER_ARGS void *oidp, void *arg1, int arg2, \ - struct sysctl_req *req - -#define OID_AUTO (-1) - -#define CTLTYPE 0xf /* Mask for the type */ -#define CTLTYPE_NODE 1 /* name is a node */ -#define CTLTYPE_INT 2 /* name describes an integer */ -#define CTLTYPE_STRING 3 /* name describes a string */ -#define CTLTYPE_QUAD 4 /* name describes a 64-bit number */ -#define CTLTYPE_OPAQUE 5 /* name describes a structure */ -#define CTLTYPE_STRUCT CTLTYPE_OPAQUE /* name describes a structure */ -#define CTLTYPE_UINT 6 /* name describes an unsigned integer */ -#define CTLTYPE_LONG 7 /* name describes a long */ -#define CTLTYPE_ULONG 8 /* name describes an unsigned long */ -#define CTLTYPE_U64 9 /* name describes an unsigned 64-bit number */ - -#define CTLFLAG_RD 0x80000000 /* Allow reads of variable */ -#define CTLFLAG_WR 0x40000000 /* Allow writes to the variable */ -#define CTLFLAG_RW (CTLFLAG_RD|CTLFLAG_WR) -#define CTLFLAG_NOLOCK 0x20000000 /* XXX Don't Lock */ -#define CTLFLAG_ANYBODY 0x10000000 /* All users can set this var */ -#define CTLFLAG_SECURE 0x08000000 /* Permit set only if securelevel<=0 */ -#define CTLFLAG_PRISON 0x04000000 /* Prisoned roots can fiddle */ -#define CTLFLAG_DYN 0x02000000 /* Dynamic oid - can be freed */ -#define CTLFLAG_SKIP 0x01000000 /* Skip this sysctl when listing */ -#define CTLMASK_SECURE 0x00F00000 /* Secure level */ -#define CTLFLAG_TUN 0x00080000 /* Tunable variable */ -#define CTLFLAG_MPSAFE 0x00040000 /* Handler is MP safe */ -#define CTLFLAG_RDTUN (CTLFLAG_RD|CTLFLAG_TUN) - - -static inline int -sysctl_ctx_init(struct sysctl_ctx_list *clist) -{ - return -1; -} - - -static inline int -sysctl_ctx_free(struct sysctl_ctx_list *clist) -{ - return -1; -} - - -static inline void * -sysctl_add_oid(struct sysctl_ctx_list *clist, void *parent, int nbr, - const char *name, int kind, void *arg1, int arg2, - int (*handler) (SYSCTL_HANDLER_ARGS), const char *fmt, const char *descr) -{ - return NULL; -} - - -static inline int sysctl_handle_long(SYSCTL_HANDLER_ARGS) { return -1; } -static inline int sysctl_handle_opaque(SYSCTL_HANDLER_ARGS) { return -1; } -static inline int sysctl_handle_quad(SYSCTL_HANDLER_ARGS) { return -1; } -static inline int sysctl_handle_int(SYSCTL_HANDLER_ARGS) { return -1; } -static inline int sysctl_handle_64(SYSCTL_HANDLER_ARGS) { return -1; } -static inline int sysctl_handle_string(SYSCTL_HANDLER_ARGS) { return -1; } - - -#define SYSCTL_OUT(r, p, l) -1 - -#define __DESCR(x) "" - -#define SYSCTL_ADD_OID(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, \ - __DESCR(descr)) - -#define SYSCTL_ADD_NODE(ctx, parent, nbr, name, access, handler, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_NODE|(access), \ - 0, 0, handler, "N", __DESCR(descr)) - -#define SYSCTL_ADD_STRING(ctx, parent, nbr, name, access, arg, len, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_STRING|(access), \ - arg, len, sysctl_handle_string, "A", __DESCR(descr)) - -#define SYSCTL_ADD_INT(ctx, parent, nbr, name, access, ptr, val, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_INT|(access), \ - ptr, val, sysctl_handle_int, "I", __DESCR(descr)) - -#define SYSCTL_ADD_UINT(ctx, parent, nbr, name, access, ptr, val, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_UINT|(access), \ - ptr, val, sysctl_handle_int, "IU", __DESCR(descr)) - -#define SYSCTL_ADD_XINT(ctx, parent, nbr, name, access, ptr, val, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_UINT|(access), \ - ptr, val, sysctl_handle_int, "IX", __DESCR(descr)) - -#define SYSCTL_ADD_LONG(ctx, parent, nbr, name, access, ptr, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_LONG|(access), \ - ptr, 0, sysctl_handle_long, "L", __DESCR(descr)) - -#define SYSCTL_ADD_ULONG(ctx, parent, nbr, name, access, ptr, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_ULONG|(access), \ - ptr, 0, sysctl_handle_long, "LU", __DESCR(descr)) - -#define SYSCTL_ADD_QUAD(ctx, parent, nbr, name, access, ptr, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_QUAD|(access), \ - ptr, 0, sysctl_handle_quad, "Q", __DESCR(descr)) - -#define SYSCTL_ADD_UQUAD(ctx, parent, nbr, name, access, ptr, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, \ - CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \ - ptr, 0, sysctl_handle_64, "QU", __DESCR(descr)) - -#define SYSCTL_ADD_OPAQUE(ctx, parent, nbr, name, access, ptr, len, fmt, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \ - ptr, len, sysctl_handle_opaque, fmt, __DESCR(descr)) - -#define SYSCTL_ADD_STRUCT(ctx, parent, nbr, name, access, ptr, type, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \ - ptr, sizeof(struct type), sysctl_handle_opaque, "S," #type, __DESCR(descr)) - -#define SYSCTL_ADD_PROC(ctx, parent, nbr, name, access, ptr, arg, handler, fmt, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, (access), ptr, arg, handler, fmt, \ - __DESCR(descr)) - - -static inline void * -SYSCTL_CHILDREN(void *ptr) -{ - return NULL; -} - - -#define SYSCTL_STATIC_CHILDREN(...) NULL - -#define SYSCTL_DECL(name) \ - extern struct sysctl_oid_list sysctl_##name##_children - -#define SYSCTL_NODE(...) -#define SYSCTL_INT(...) -#define SYSCTL_UINT(...) -#define SYSCTL_PROC(...) - -#endif - -#endif diff --git a/src/libs/compat/freebsd_network/compat/sys/syslog.h b/src/libs/compat/freebsd_network/compat/sys/syslog.h deleted file mode 100644 index f785d64b35..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/syslog.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_SYSLOG_H_ -#define _FBSD_COMPAT_SYS_SYSLOG_H_ - - -#define LOG_ERR 3 /* error conditions */ - -#endif /* _FBSD_COMPAT_SYS_SYSLOG_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/systm.h b/src/libs/compat/freebsd_network/compat/sys/systm.h deleted file mode 100644 index 42c2a795bb..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/systm.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_SYSTM_H_ -#define _FBSD_COMPAT_SYS_SYSTM_H_ - - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include - - -#define printf freebsd_printf -int printf(const char *format, ...) __printflike(1, 2); - - -#define ovbcopy(f, t, l) bcopy((f), (t), (l)) - -#define bootverbose 1 - -#ifdef INVARIANTS -#define KASSERT(cond,msg) do { \ - if (!(cond)) \ - panic msg; \ -} while (0) -#else -#define KASSERT(exp,msg) do { \ -} while (0) -#endif - -#define DELAY(n) \ - do { \ - if (n < 1000) \ - spin(n); \ - else \ - snooze(n); \ - } while (0) - -void wakeup(void *); - -#ifndef CTASSERT /* Allow lint to override */ -#define CTASSERT(x) _CTASSERT(x, __LINE__) -#define _CTASSERT(x, y) __CTASSERT(x, y) -#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] -#endif - - -static inline int -copyin(const void * __restrict udaddr, void * __restrict kaddr, - size_t len) -{ - return user_memcpy(kaddr, udaddr, len); -} - - -static inline int -copyout(const void * __restrict kaddr, void * __restrict udaddr, - size_t len) -{ - return user_memcpy(udaddr, kaddr, len); -} - - -static inline void log(int level, const char *fmt, ...) { } - - -int snprintf(char *, size_t, const char *, ...) __printflike(3, 4); -extern int sprintf(char *buf, const char *, ...); - -extern void driver_vprintf(const char *format, va_list vl); -#define vprintf(fmt, vl) driver_vprintf(fmt, vl) - -extern int vsnprintf(char *, size_t, const char *, __va_list) - __printflike(3, 0); - -int msleep(void *, struct mtx *, int, const char *, int); -int _pause(const char *, int); -#define pause(waitMessage, timeout) _pause((waitMessage), (timeout)) -#define tsleep(channel, priority, waitMessage, timeout) \ - msleep((channel), NULL, (priority), (waitMessage), (timeout)) - -struct unrhdr; -struct unrhdr *new_unrhdr(int low, int high, struct mtx *mutex); -void delete_unrhdr(struct unrhdr *); -int alloc_unr(struct unrhdr *); -void free_unr(struct unrhdr *, u_int); - -extern char *getenv(const char *name); -extern void freeenv(char *env); - -#endif /* _FBSD_COMPAT_SYS_SYSTM_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/taskqueue.h b/src/libs/compat/freebsd_network/compat/sys/taskqueue.h deleted file mode 100644 index 77fa6a0604..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/taskqueue.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2007 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_TASKQUEUE_H_ -#define _FBSD_COMPAT_SYS_TASKQUEUE_H_ - - -#include -#include - - -#define PI_NET (B_REAL_TIME_DISPLAY_PRIORITY - 1) - -#define TASK_INIT(taskp, prio, hand, arg) task_init(taskp, prio, hand, arg) - - -typedef void (*taskqueue_enqueue_fn)(void *context); - - -struct taskqueue; -struct taskqueue *taskqueue_create(const char *name, int mflags, - taskqueue_enqueue_fn enqueue, void *context); -int taskqueue_start_threads(struct taskqueue **tq, int count, int pri, - const char *name, ...) __printflike(4, 5); -void taskqueue_free(struct taskqueue *tq); -void taskqueue_drain(struct taskqueue *tq, struct task *task); -void taskqueue_block(struct taskqueue *queue); -void taskqueue_unblock(struct taskqueue *queue); -int taskqueue_enqueue(struct taskqueue *tq, struct task *task); - -void taskqueue_thread_enqueue(void *context); - -extern struct taskqueue *taskqueue_fast; -extern struct taskqueue *taskqueue_swi; - -int taskqueue_enqueue_fast(struct taskqueue *queue, struct task *task); -struct taskqueue *taskqueue_create_fast(const char *name, int mflags, - taskqueue_enqueue_fn enqueue, void *context); - -void task_init(struct task *, int prio, task_handler_t handler, void *arg); - -#endif diff --git a/src/libs/compat/freebsd_network/compat/sys/time.h b/src/libs/compat/freebsd_network/compat/sys/time.h deleted file mode 100644 index 4b061e3ad4..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/time.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_TIME_H_ -#define _FBSD_COMPAT_SYS_TIME_H_ - - -#include - -#include -#include - - -#define time_uptime (system_time() / 1000000) - - -int ppsratecheck(struct timeval*, int*, int); - -#endif /* _FBSD_COMPAT_SYS_TIME_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/types.h b/src/libs/compat/freebsd_network/compat/sys/types.h deleted file mode 100644 index babd91bc8c..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/types.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2007 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_TYPES_H_ -#define _FBSD_COMPAT_SYS_TYPES_H_ - - -#include -#include - -#include - -#include -#include - - -typedef int boolean_t; -typedef __const char* c_caddr_t; -typedef uint64_t u_quad_t; - -#endif diff --git a/src/libs/compat/freebsd_network/compat/vm/pmap.h b/src/libs/compat/freebsd_network/compat/vm/pmap.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/libs/compat/freebsd_network/compat/vm/uma.h b/src/libs/compat/freebsd_network/compat/vm/uma.h deleted file mode 100644 index 5f6b8e9915..0000000000 --- a/src/libs/compat/freebsd_network/compat/vm/uma.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 2009 Haiku Inc. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_VM_UMA_H_ -#define _FBSD_COMPAT_VM_UMA_H_ - - -#include -#include - -#endif /* _FBSD_COMPAT_VM_UMA_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/vm/vm.h b/src/libs/compat/freebsd_network/compat/vm/vm.h deleted file mode 100644 index 56eef91da4..0000000000 --- a/src/libs/compat/freebsd_network/compat/vm/vm.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_VM_VM_H_ -#define _FBSD_COMPAT_VM_VM_H_ - - -#include -#include - - -#ifdef B_HAIKU_64_BIT - -typedef uint64_t vm_offset_t; -typedef uint64_t vm_paddr_t; - -#else - -typedef uint32_t vm_offset_t; -typedef uint32_t vm_paddr_t; - -#endif - -typedef void *pmap_t; - - -#define vmspace_pmap(...) NULL -#define pmap_extract(...) NULL - - -vm_paddr_t pmap_kextract(vm_offset_t virtualAddress); - -#define vtophys(virtualAddress) pmap_kextract((vm_offset_t)(virtualAddress)) - -#endif /* _FBSD_COMPAT_VM_VM_H_ */ diff --git a/src/libs/compat/freebsd_network/compat_cpp.cpp b/src/libs/compat/freebsd_network/compat_cpp.cpp deleted file mode 100644 index a9ae740755..0000000000 --- a/src/libs/compat/freebsd_network/compat_cpp.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. - * Distributed under the terms of the MIT License. - */ - - -#include "compat_cpp.h" - -#include -#include - -#include - - -void* -_kernel_contigmalloc_cpp(const char* file, int line, size_t size, - phys_addr_t low, phys_addr_t high, phys_size_t alignment, - phys_size_t boundary, bool zero, bool dontWait) -{ - size = ROUNDUP(size, B_PAGE_SIZE); - - uint32 creationFlags = (zero ? 0 : CREATE_AREA_DONT_CLEAR) - | (dontWait ? CREATE_AREA_DONT_WAIT : 0); - - char name[B_OS_NAME_LENGTH]; - const char* baseName = strrchr(file, '/'); - baseName = baseName != NULL ? baseName + 1 : file; - snprintf(name, sizeof(name), "contig:%s:%d", baseName, line); - - virtual_address_restrictions virtualRestrictions = {}; - - physical_address_restrictions physicalRestrictions = {}; - physicalRestrictions.low_address = low; - physicalRestrictions.high_address = high; - physicalRestrictions.alignment = alignment; - physicalRestrictions.boundary = boundary; - - void* address; - area_id area = create_area_etc(B_SYSTEM_TEAM, name, size, B_CONTIGUOUS, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, creationFlags, 0, - &virtualRestrictions, &physicalRestrictions, &address); - if (area < 0) - return NULL; - - return address; -} diff --git a/src/libs/compat/freebsd_network/compat_cpp.h b/src/libs/compat/freebsd_network/compat_cpp.h deleted file mode 100644 index ee531b4f2e..0000000000 --- a/src/libs/compat/freebsd_network/compat_cpp.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. - * Distributed under the terms of the MIT License. - */ -#ifndef _FREE_BSD_NETWORK_COMPAT_CPP_H -#define _FREE_BSD_NETWORK_COMPAT_CPP_H - - -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -void* _kernel_contigmalloc_cpp(const char* file, int line, size_t size, - phys_addr_t low, phys_addr_t high, phys_size_t alignment, - phys_size_t boundary, bool zero, bool dontWait); - - -#ifdef __cplusplus -} -#endif - - -#endif /* _FREE_BSD_NETWORK_COMPAT_CPP_H */ diff --git a/src/libs/compat/freebsd_network/condvar.c b/src/libs/compat/freebsd_network/condvar.c deleted file mode 100644 index 79f1062d3a..0000000000 --- a/src/libs/compat/freebsd_network/condvar.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2009 Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ - - -#include -#include - -#include "Condvar.h" - - -void cv_init(struct cv* variable, const char* description) -{ - conditionInit(variable, description); -} - - -void cv_signal(struct cv* variable) -{ - conditionNotifyOne(variable); -} - - -int cv_timedwait(struct cv* variable, struct mtx* mutex, int timeout) -{ - int status; - - mtx_unlock(mutex); - status = conditionTimedWait(variable, timeout); - mtx_lock(mutex); - - return status; -} - - -void cv_wait(struct cv* variable, struct mtx* mutex) -{ - mtx_unlock(mutex); - conditionWait(variable); - mtx_lock(mutex); -} diff --git a/src/libs/compat/freebsd_network/device.c b/src/libs/compat/freebsd_network/device.c deleted file mode 100644 index 87cc7fcfa7..0000000000 --- a/src/libs/compat/freebsd_network/device.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright 2007-2009, Axel Dörfler, axeld@pinc-software.de. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Copyright 2004, Marcus Overhagen. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "device.h" - -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include - - -static status_t -compat_open(const char *name, uint32 flags, void **cookie) -{ - struct ifnet *ifp; - struct ifreq ifr; - int i; - status_t status; - - for (i = 0; i < MAX_DEVICES; i++) { - if (gDevices[i] != NULL && !strcmp(gDevices[i]->device_name, name)) - break; - } - - if (i == MAX_DEVICES) - return B_ERROR; - - if (get_module(NET_STACK_MODULE_NAME, (module_info **)&gStack) != B_OK) - return B_ERROR; - - ifp = gDevices[i]; - if_printf(ifp, "compat_open(0x%" B_PRIx32 ")\n", flags); - - if (atomic_or(&ifp->open_count, 1)) { - put_module(NET_STACK_MODULE_NAME); - return B_BUSY; - } - - ifp->if_init(ifp->if_softc); - - if (!HAIKU_DRIVER_REQUIRES(FBSD_WLAN)) { - ifp->if_flags &= ~IFF_UP; - ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL); - - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_media = IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, 0); - status = ifp->if_ioctl(ifp, SIOCSIFMEDIA, (caddr_t)&ifr); - if (status != B_OK) { - ifr.ifr_media = IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, 0); - status = ifp->if_ioctl(ifp, SIOCSIFMEDIA, (caddr_t)&ifr); - } - } - - ifp->if_flags |= IFF_UP; - ifp->flags &= ~DEVICE_CLOSED; - ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL); - - *cookie = ifp; - return B_OK; -} - - -static status_t -compat_close(void *cookie) -{ - struct ifnet *ifp = cookie; - - if_printf(ifp, "compat_close()\n"); - - atomic_or(&ifp->flags, DEVICE_CLOSED); - - wlan_close(cookie); - - release_sem_etc(ifp->receive_sem, 1, B_RELEASE_ALL); - - return B_OK; -} - - -static status_t -compat_free(void *cookie) -{ - struct ifnet *ifp = cookie; - - if_printf(ifp, "compat_free()\n"); - - // TODO: empty out the send queue - - atomic_and(&ifp->open_count, 0); - put_module(NET_STACK_MODULE_NAME); - return B_OK; -} - - -static status_t -compat_read(void *cookie, off_t position, void *buffer, size_t *numBytes) -{ - struct ifnet *ifp = cookie; - uint32 semFlags = B_CAN_INTERRUPT; - status_t status; - struct mbuf *mb; - size_t length; - - //if_printf(ifp, "compat_read(%lld, %p, [%lu])\n", position, - // buffer, *numBytes); - - if (ifp->flags & DEVICE_CLOSED) - return B_INTERRUPTED; - - if (ifp->flags & DEVICE_NON_BLOCK) - semFlags |= B_RELATIVE_TIMEOUT; - - do { - status = acquire_sem_etc(ifp->receive_sem, 1, semFlags, 0); - if (ifp->flags & DEVICE_CLOSED) - return B_INTERRUPTED; - - if (status == B_WOULD_BLOCK) { - *numBytes = 0; - return B_OK; - } else if (status < B_OK) - return status; - - IF_DEQUEUE(&ifp->receive_queue, mb); - } while (mb == NULL); - - length = min_c(max_c((size_t)mb->m_pkthdr.len, 0), *numBytes); - -#if 0 - mb = m_defrag(mb, 0); - if (mb == NULL) { - *numBytes = 0; - return B_NO_MEMORY; - } -#endif - - m_copydata(mb, 0, length, buffer); - *numBytes = length; - - m_freem(mb); - return B_OK; -} - - -static status_t -compat_write(void *cookie, off_t position, const void *buffer, - size_t *numBytes) -{ - struct ifnet *ifp = cookie; - struct mbuf *mb; - - //if_printf(ifp, "compat_write(%lld, %p, [%lu])\n", position, - // buffer, *numBytes); - - if (*numBytes > MHLEN) { - mb = m_getcl(0, MT_DATA, M_PKTHDR); - *numBytes = min_c(*numBytes, (size_t)MCLBYTES); - } else { - mb = m_gethdr(0, MT_DATA); - } - - if (mb == NULL) - return ENOBUFS; - - // if we waited, check after if the ifp is still valid - - mb->m_pkthdr.len = mb->m_len = *numBytes; - memcpy(mtod(mb, void *), buffer, mb->m_len); - - return ifp->if_output(ifp, mb, NULL, NULL); -} - - -static status_t -compat_control(void *cookie, uint32 op, void *arg, size_t length) -{ - struct ifnet *ifp = cookie; - - //if_printf(ifp, "compat_control(op %lu, %p, [%lu])\n", op, - // arg, length); - - switch (op) { - case ETHER_INIT: - return B_OK; - - case ETHER_GETADDR: - return user_memcpy(arg, IF_LLADDR(ifp), ETHER_ADDR_LEN); - - case ETHER_NONBLOCK: - { - int32 value; - if (length < 4) - return B_BAD_VALUE; - if (user_memcpy(&value, arg, sizeof(int32)) < B_OK) - return B_BAD_ADDRESS; - if (value) - ifp->flags |= DEVICE_NON_BLOCK; - else - ifp->flags &= ~DEVICE_NON_BLOCK; - return B_OK; - } - - case ETHER_SETPROMISC: - { - int32 value; - if (length < 4) - return B_BAD_VALUE; - if (user_memcpy(&value, arg, sizeof(int32)) < B_OK) - return B_BAD_ADDRESS; - if (value) - ifp->if_flags |= IFF_PROMISC; - else - ifp->if_flags &= ~IFF_PROMISC; - return ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL); - } - - case ETHER_GETFRAMESIZE: - { - uint32 frameSize; - if (length < 4) - return B_BAD_VALUE; - - frameSize = ifp->if_mtu + ETHER_HDR_LEN; - return user_memcpy(arg, &frameSize, 4); - } - - case ETHER_ADDMULTI: - case ETHER_REMMULTI: - { - struct sockaddr_dl address; - - if ((ifp->if_flags & IFF_MULTICAST) == 0) - return B_NOT_SUPPORTED; - - memset(&address, 0, sizeof(address)); - address.sdl_family = AF_LINK; - memcpy(LLADDR(&address), arg, ETHER_ADDR_LEN); - - if (op == ETHER_ADDMULTI) - return if_addmulti(ifp, (struct sockaddr *)&address, NULL); - - return if_delmulti(ifp, (struct sockaddr *)&address); - } - - case ETHER_GET_LINK_STATE: - { - struct ifmediareq mediareq; - ether_link_state_t state; - status_t status; - - if (length < sizeof(ether_link_state_t)) - return EINVAL; - - memset(&mediareq, 0, sizeof(mediareq)); - status = ifp->if_ioctl(ifp, SIOCGIFMEDIA, (caddr_t)&mediareq); - if (status < B_OK) - return status; - - state.media = mediareq.ifm_active; - if ((mediareq.ifm_status & IFM_ACTIVE) != 0) - state.media |= IFM_ACTIVE; - if ((mediareq.ifm_active & IFM_10_T) != 0) - state.speed = 10000000; - else if ((mediareq.ifm_active & IFM_100_TX) != 0) - state.speed = 100000000; - else - state.speed = 1000000000; - state.quality = 1000; - - return user_memcpy(arg, &state, sizeof(ether_link_state_t)); - } - - case ETHER_SET_LINK_STATE_SEM: - if (user_memcpy(&ifp->link_state_sem, arg, sizeof(sem_id)) < B_OK) { - ifp->link_state_sem = -1; - return B_BAD_ADDRESS; - } - return B_OK; - } - - return wlan_control(cookie, op, arg, length); -} - - -device_hooks gDeviceHooks = { - compat_open, - compat_close, - compat_free, - compat_control, - compat_read, - compat_write, -}; diff --git a/src/libs/compat/freebsd_network/device.h b/src/libs/compat/freebsd_network/device.h deleted file mode 100644 index 9a63201b32..0000000000 --- a/src/libs/compat/freebsd_network/device.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. All Rights Reserved. - * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Copyright 2004, Marcus Overhagen. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef DEVICE_H -#define DEVICE_H - - -#include -#include - -#include -#include - -#include - -#include - -#include -#include - -#include "shared.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct root_device_softc { - struct pci_info pci_info; - bool is_msi; - bool is_msix; -}; - -enum { - DEVICE_OPEN = 1 << 0, - DEVICE_CLOSED = 1 << 1, - DEVICE_NON_BLOCK = 1 << 2, - DEVICE_DESC_ALLOCED = 1 << 3, - DEVICE_ATTACHED = 1 << 4 -}; - - -extern struct net_stack_module_info *gStack; -extern pci_module_info *gPci; -extern struct pci_x86_module_info *gPCIx86; - - -static inline void -__unimplemented(const char *method) -{ - char msg[128]; - snprintf(msg, sizeof(msg), "fbsd compat, unimplemented: %s", method); - panic(msg); -} - -#define UNIMPLEMENTED() __unimplemented(__FUNCTION__) - -status_t init_mbufs(void); -void uninit_mbufs(void); - -status_t init_mutexes(void); -void uninit_mutexes(void); - -status_t init_taskqueues(void); -void uninit_taskqueues(void); - -status_t init_hard_clock(void); -void uninit_hard_clock(void); - -status_t init_callout(void); -void uninit_callout(void); - -device_t find_root_device(int); - -/* busdma_machdep.c */ -void init_bounce_pages(void); -void uninit_bounce_pages(void); - -void driver_printf(const char *format, ...) - __attribute__ ((format (__printf__, 1, 2))); -void driver_vprintf(const char *format, va_list vl); - -void device_sprintf_name(device_t dev, const char *format, ...) - __attribute__ ((format (__printf__, 2, 3))); - -void ifq_init(struct ifqueue *, const char *); -void ifq_uninit(struct ifqueue *); - -#ifdef __cplusplus -} -#endif - -#endif /* DEVICE_H */ diff --git a/src/libs/compat/freebsd_network/driver.c b/src/libs/compat/freebsd_network/driver.c deleted file mode 100644 index 48ad2fed2d..0000000000 --- a/src/libs/compat/freebsd_network/driver.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved. - * Copyright 2004, Marcus Overhagen. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ - - -/*! Driver functions that adapt the FreeBSD driver to Haiku's driver API. - The actual driver functions are exported by the HAIKU_FBSD_DRIVER_GLUE - macro, and just call the functions here. -*/ - - -#include "device.h" - -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include - - -//#define TRACE_DRIVER -#ifdef TRACE_DRIVER -# define TRACE(x) dprintf x -#else -# define TRACE(x) -#endif - - -const char *gDeviceNameList[MAX_DEVICES + 1]; -struct ifnet *gDevices[MAX_DEVICES]; -int32 gDeviceCount; - - -static status_t -init_root_device(device_t *_root) -{ - static driver_t sRootDriver = { - "pci", - NULL, - sizeof(struct root_device_softc) - }; - - device_t root = device_add_child(NULL, NULL, 0); - if (root == NULL) - return B_NO_MEMORY; - - root->softc = malloc(sizeof(struct root_device_softc)); - if (root->softc == NULL) { - device_delete_child(NULL, root); - return B_NO_MEMORY; - } - - bzero(root->softc, sizeof(struct root_device_softc)); - root->driver = &sRootDriver; - root->root = root; - - if (_root != NULL) - *_root = root; - - return B_OK; -} - - -static status_t -add_child_device(driver_t *driver, device_t root, device_t *_child) -{ - device_t child = device_add_child(root, driver->name, 0); - if (child == NULL) { - return B_ERROR; - } - - if (_child != NULL) - *_child = child; - - return B_OK; -} - - -static pci_info * -get_pci_info(struct device *device) -{ - return &((struct root_device_softc *)device->softc)->pci_info; -} - - -// #pragma mark - Haiku Driver API - - -status_t -_fbsd_init_hardware(driver_t *drivers[]) -{ - status_t status = B_ENTRY_NOT_FOUND; - device_t root; - pci_info *info; - driver_t *driver = NULL; - int i = 0; - - if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPci) < B_OK) - return B_ERROR; - - status = init_root_device(&root); - if (status != B_OK) - goto err; - - for (info = get_pci_info(root); gPci->get_nth_pci_info(i, info) == B_OK; - i++) { - int index; - driver = NULL; - - for (index = 0; drivers[index] && gDeviceCount < MAX_DEVICES - && driver == NULL; index++) { - int result; - device_t device; - status = add_child_device(drivers[index], root, &device); - if (status < B_OK) - break; - - result = device->methods.probe(device); - if (result >= 0) { - TRACE(("%s, found %s at %d\n", gDriverName, - device_get_desc(device), i)); - driver = drivers[index]; - } - device_delete_child(root, device); - } - - if (driver != NULL) - break; - } - - device_delete_child(NULL, root); - - if (driver == NULL) { - status = B_ERROR; - TRACE(("%s: no hardware found.\n", gDriverName)); - } -err: - put_module(B_PCI_MODULE_NAME); - TRACE(("%s: status 0x%lx\n", gDriverName, status)); - - return status; -} - - -status_t -_fbsd_init_drivers(driver_t *drivers[]) -{ - status_t status; - int i = 0; - int index = 0; - pci_info *info; - device_t root; - - status = get_module(B_PCI_MODULE_NAME, (module_info **)&gPci); - if (status < B_OK) - return status; - - // if it fails we just don't support x86 specific features (like MSIs) - if (get_module(B_PCI_X86_MODULE_NAME, (module_info **)&gPCIx86) != B_OK) - gPCIx86 = NULL; - - status = init_hard_clock(); - if (status < B_OK) - goto err1; - - status = init_mutexes(); - if (status < B_OK) - goto err2; - - status = init_mbufs(); - if (status < B_OK) - goto err3; - - status = init_callout(); - if (status < B_OK) - goto err4; - - init_bounce_pages(); - - if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES)) { - status = init_taskqueues(); - if (status < B_OK) - goto err5; - } - - status = init_wlan_stack(); - if (status < B_OK) - goto err6; - - status = init_root_device(&root); - if (status != B_OK) - goto err7; - - for (info = get_pci_info(root); gPci->get_nth_pci_info(i, info) == B_OK; - i++) { - int best = 0; - driver_t *driver = NULL; - - for (index = 0; drivers[index] && gDeviceCount < MAX_DEVICES; index++) { - int result; - device_t device; - status = add_child_device(drivers[index], root, &device); - if (status < B_OK) - break; - - result = device->methods.probe(device); - if (result >= 0 && (driver == NULL || result > best)) { - TRACE(("%s, found %s at %d (%d)\n", gDriverName, - device_get_desc(device), i, result)); - driver = drivers[index]; - best = result; - } - device_delete_child(root, device); - } - - if (driver != NULL) { - device_t device; - status = add_child_device(driver, root, &device); - if (status != B_OK) - break; - if (device_attach(device) == 0) { - dprintf("%s: init_driver(%p) at %d\n", gDriverName, driver, i); - } else - device_delete_child(root, device); - } - } - - if (gDeviceCount > 0) - return B_OK; - - device_delete_child(NULL, root); - - if (status == B_OK) - status = B_ERROR; - -err7: - uninit_wlan_stack(); - -err6: - if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES)) - uninit_taskqueues(); -err5: - uninit_mbufs(); -err4: - uninit_callout(); -err3: - uninit_mutexes(); -err2: - uninit_hard_clock(); -err1: - put_module(B_PCI_MODULE_NAME); - if (gPCIx86 != NULL) - put_module(B_PCI_X86_MODULE_NAME); - - return status; -} - - -status_t -_fbsd_uninit_drivers(driver_t *drivers[]) -{ - int i; - - for (i = 0; drivers[i]; i++) - TRACE(("%s: uninit_driver(%p)\n", gDriverName, drivers[i])); - - for (i = 0; i < gDeviceCount; i++) { - device_delete_child(NULL, gDevices[i]->root_device); - } - - uninit_wlan_stack(); - uninit_bounce_pages(); - uninit_mbufs(); - if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES)) - uninit_taskqueues(); - uninit_callout(); - uninit_mutexes(); - uninit_hard_clock(); - - put_module(B_PCI_MODULE_NAME); - if (gPCIx86 != NULL) - put_module(B_PCI_X86_MODULE_NAME); - - return B_OK; -} diff --git a/src/libs/compat/freebsd_network/eventhandler.c b/src/libs/compat/freebsd_network/eventhandler.c deleted file mode 100644 index 1d4ac8255c..0000000000 --- a/src/libs/compat/freebsd_network/eventhandler.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2009, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Michael Weirauch, dev@m-phasis.de - */ - - -#include - -#include - - -eventhandler_tag -eventhandler_register(struct eventhandler_list *list, - const char *name, void *func, void *arg, int priority) -{ - return NULL; -}; - - -void -eventhandler_deregister(struct eventhandler_list *list, - eventhandler_tag tag) -{ - // -}; - - -struct eventhandler_list * -eventhandler_find_list(const char *name) -{ - return NULL; -}; - - -void -eventhandler_prune_list(struct eventhandler_list *list) -{ - // -}; diff --git a/src/libs/compat/freebsd_network/fbsd_busdma_x86.c b/src/libs/compat/freebsd_network/fbsd_busdma_x86.c deleted file mode 100644 index 67f3a4981c..0000000000 --- a/src/libs/compat/freebsd_network/fbsd_busdma_x86.c +++ /dev/null @@ -1,1194 +0,0 @@ -/*- - * Copyright (c) 1997, 1998 Justin T. Gibbs. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#include -__FBSDID("$FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.74.2.4 2006/10/21 16:26:53 hrs Exp $"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#ifdef __x86_64__ -# define MAX_BPAGES 8192 -#else -# define MAX_BPAGES 512 -#endif - -/* -hugo */ -#define malloc(a, b, c) kernel_malloc(a, b, c) -#define free(a, b) kernel_free(a, b) -#define contigmalloc(a, b, c, d, e, f, g) kernel_contigmalloc(a, b, c, d, e, f, g) -#define contigfree(a, b, c) kernel_contigfree(a, b, c) -void busdma_swi(void); -void init_bounce_pages(void); -void uninit_bounce_pages(void); -/* */ - -struct bounce_zone; - -struct bus_dma_tag { - bus_dma_tag_t parent; - bus_size_t alignment; - bus_addr_t boundary; - bus_addr_t lowaddr; - bus_addr_t highaddr; - bus_dma_filter_t *filter; - void *filterarg; - bus_size_t maxsize; - u_int nsegments; - bus_size_t maxsegsz; - int flags; - int ref_count; - int map_count; - bus_dma_lock_t *lockfunc; - void *lockfuncarg; - bus_dma_segment_t *segments; - struct bounce_zone *bounce_zone; -}; - -struct bounce_page { - vm_offset_t vaddr; /* kva of bounce buffer */ - bus_addr_t busaddr; /* Physical address */ - vm_offset_t datavaddr; /* kva of client data */ - bus_size_t datacount; /* client data count */ - STAILQ_ENTRY(bounce_page) links; -}; - -int busdma_swi_pending; - -struct bounce_zone { - STAILQ_ENTRY(bounce_zone) links; - STAILQ_HEAD(bp_list, bounce_page) bounce_page_list; - int total_bpages; - int free_bpages; - int reserved_bpages; - int active_bpages; - int total_bounced; - int total_deferred; - bus_size_t alignment; - bus_addr_t boundary; - bus_addr_t lowaddr; - char zoneid[8]; - char lowaddrid[20]; - struct sysctl_ctx_list sysctl_tree; - struct sysctl_oid *sysctl_tree_top; -}; - -static struct mtx bounce_lock; -static int total_bpages; -static int busdma_zonecount; -static STAILQ_HEAD(, bounce_zone) bounce_zone_list; - -SYSCTL_NODE(_hw, OID_AUTO, busdma, CTLFLAG_RD, 0, "Busdma parameters"); -SYSCTL_INT(_hw_busdma, OID_AUTO, total_bpages, CTLFLAG_RD, &total_bpages, 0, - "Total bounce pages"); - -struct bus_dmamap { - struct bp_list bpages; - int pagesneeded; - int pagesreserved; - bus_dma_tag_t dmat; - void *buf; /* unmapped buffer pointer */ - bus_size_t buflen; /* unmapped buffer length */ - bus_dmamap_callback_t *callback; - void *callback_arg; - STAILQ_ENTRY(bus_dmamap) links; -}; - -static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist; -static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist; -static struct bus_dmamap nobounce_dmamap; - -static int alloc_bounce_zone(bus_dma_tag_t dmat); -static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages); -static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map, - int commit); -static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, - vm_offset_t vaddr, bus_size_t size); -static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage); -static __inline int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr); - -/* - * Return true if a match is made. - * - * To find a match walk the chain of bus_dma_tag_t's looking for 'paddr'. - * - * If paddr is within the bounds of the dma tag then call the filter callback - * to check for a match, if there is no filter callback then assume a match. - */ -static __inline -int -run_filter(bus_dma_tag_t dmat, bus_addr_t paddr) -{ - int retval; - - retval = 0; - - do { - if (((paddr > dmat->lowaddr && paddr <= dmat->highaddr) - || ((paddr & (dmat->alignment - 1)) != 0)) - && (dmat->filter == NULL - || (*dmat->filter)(dmat->filterarg, paddr) != 0)) - retval = 1; - - dmat = dmat->parent; - } while (retval == 0 && dmat != NULL); - return (retval); -} - -/* - * Convenience function for manipulating driver locks from busdma (during - * busdma_swi, for example). Drivers that don't provide their own locks - * should specify &Giant to dmat->lockfuncarg. Drivers that use their own - * non-mutex locking scheme don't have to use this at all. - */ -void -busdma_lock_mutex(void *arg, bus_dma_lock_op_t op) -{ - struct mtx *dmtx; - - dmtx = (struct mtx *)arg; - switch (op) { - case BUS_DMA_LOCK: - mtx_lock(dmtx); - break; - case BUS_DMA_UNLOCK: - mtx_unlock(dmtx); - break; - default: - panic("Unknown operation 0x%x for busdma_lock_mutex!", op); - } -} - -/* - * dflt_lock should never get called. It gets put into the dma tag when - * lockfunc == NULL, which is only valid if the maps that are associated - * with the tag are meant to never be defered. - * XXX Should have a way to identify which driver is responsible here. - */ -static -void -dflt_lock(void *arg, bus_dma_lock_op_t op) -{ - panic("driver error: busdma dflt_lock called"); -} - -#define BUS_DMA_COULD_BOUNCE BUS_DMA_BUS3 -#define BUS_DMA_MIN_ALLOC_COMP BUS_DMA_BUS4 - -/* - * Allocate a device specific dma_tag. - */ -int -bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, - bus_size_t boundary, bus_addr_t lowaddr, - bus_addr_t highaddr, bus_dma_filter_t *filter, - void *filterarg, bus_size_t maxsize, int nsegments, - bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, - void *lockfuncarg, bus_dma_tag_t *dmat) -{ - bus_dma_tag_t newtag; - int error = 0; - - /* Basic sanity checking */ - if (boundary != 0 && boundary < maxsegsz) - maxsegsz = boundary; - - /* Return a NULL tag on failure */ - *dmat = NULL; - - newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, - M_ZERO | M_NOWAIT); - if (newtag == NULL) { - CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d", - __func__, newtag, 0, error); - return (ENOMEM); - } - - newtag->parent = parent; - newtag->alignment = alignment; - newtag->boundary = boundary; - newtag->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1); - newtag->highaddr = trunc_page((vm_paddr_t)highaddr) + - (PAGE_SIZE - 1); - newtag->filter = filter; - newtag->filterarg = filterarg; - newtag->maxsize = maxsize; - newtag->nsegments = nsegments; - newtag->maxsegsz = maxsegsz; - newtag->flags = flags; - newtag->ref_count = 1; /* Count ourself */ - newtag->map_count = 0; - if (lockfunc != NULL) { - newtag->lockfunc = lockfunc; - newtag->lockfuncarg = lockfuncarg; - } else { - newtag->lockfunc = dflt_lock; - newtag->lockfuncarg = NULL; - } - newtag->segments = NULL; - - /* Take into account any restrictions imposed by our parent tag */ - if (parent != NULL) { - newtag->lowaddr = MIN(parent->lowaddr, newtag->lowaddr); - newtag->highaddr = MAX(parent->highaddr, newtag->highaddr); - if (newtag->boundary == 0) - newtag->boundary = parent->boundary; - else if (parent->boundary != 0) - newtag->boundary = MIN(parent->boundary, - newtag->boundary); - if (newtag->filter == NULL) { - /* - * Short circuit looking at our parent directly - * since we have encapsulated all of its information - */ - newtag->filter = parent->filter; - newtag->filterarg = parent->filterarg; - newtag->parent = parent->parent; - } - if (newtag->parent != NULL) - atomic_add_int(&parent->ref_count, 1); - } - - if (newtag->lowaddr < ptoa((vm_paddr_t)Maxmem) - || newtag->alignment > 1) - newtag->flags |= BUS_DMA_COULD_BOUNCE; - - if (((newtag->flags & BUS_DMA_COULD_BOUNCE) != 0) && - (flags & BUS_DMA_ALLOCNOW) != 0) { - struct bounce_zone *bz; - - /* Must bounce */ - - if ((error = alloc_bounce_zone(newtag)) != 0) { - free(newtag, M_DEVBUF); - return (error); - } - bz = newtag->bounce_zone; - - if (ptoa(bz->total_bpages) < maxsize) { - int pages; - - pages = atop(maxsize) - bz->total_bpages; - - /* Add pages to our bounce pool */ - if (alloc_bounce_pages(newtag, pages) < pages) - error = ENOMEM; - } - /* Performed initial allocation */ - newtag->flags |= BUS_DMA_MIN_ALLOC_COMP; - } - - if (error != 0) { - free(newtag, M_DEVBUF); - } else { - *dmat = newtag; - } - CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d", - __func__, newtag, (newtag != NULL ? newtag->flags : 0), error); - return (error); -} - -int -bus_dma_tag_destroy(bus_dma_tag_t dmat) -{ - bus_dma_tag_t dmat_copy; - int error; - - error = 0; - dmat_copy = dmat; - - if (dmat != NULL) { - - if (dmat->map_count != 0) { - error = EBUSY; - goto out; - } - - while (dmat != NULL) { - bus_dma_tag_t parent; - - parent = dmat->parent; - atomic_subtract_int(&dmat->ref_count, 1); - if (dmat->ref_count == 0) { - if (dmat->segments != NULL) - free(dmat->segments, M_DEVBUF); - free(dmat, M_DEVBUF); - /* - * Last reference count, so - * release our reference - * count on our parent. - */ - dmat = parent; - } else - dmat = NULL; - } - } -out: - CTR3(KTR_BUSDMA, "%s tag %p error %d", __func__, dmat_copy, error); - return (error); -} - -/* - * Allocate a handle for mapping from kva/uva/physical - * address space into bus device space. - */ -int -bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) -{ - int error; - - error = 0; - - if (dmat->segments == NULL) { - dmat->segments = (bus_dma_segment_t *)malloc( - sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF, - M_NOWAIT); - if (dmat->segments == NULL) { - CTR3(KTR_BUSDMA, "%s: tag %p error %d", - __func__, dmat, ENOMEM); - return (ENOMEM); - } - } - - /* - * Bouncing might be required if the driver asks for an active - * exclusion region, a data alignment that is stricter than 1, and/or - * an active address boundary. - */ - if (dmat->flags & BUS_DMA_COULD_BOUNCE) { - - /* Must bounce */ - struct bounce_zone *bz; - int maxpages; - - if (dmat->bounce_zone == NULL) { - if ((error = alloc_bounce_zone(dmat)) != 0) - return (error); - } - bz = dmat->bounce_zone; - - *mapp = (bus_dmamap_t)malloc(sizeof(**mapp), M_DEVBUF, - M_NOWAIT | M_ZERO); - if (*mapp == NULL) { - CTR3(KTR_BUSDMA, "%s: tag %p error %d", - __func__, dmat, ENOMEM); - return (ENOMEM); - } - - /* Initialize the new map */ - STAILQ_INIT(&((*mapp)->bpages)); - - /* - * Attempt to add pages to our pool on a per-instance - * basis up to a sane limit. - */ - if (dmat->alignment > 1) - maxpages = MAX_BPAGES; - else - maxpages = MIN(MAX_BPAGES, Maxmem -atop(dmat->lowaddr)); - if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0 - || (dmat->map_count > 0 && bz->total_bpages < maxpages)) { - int pages; - - pages = MAX(atop(dmat->maxsize), 1); - pages = MIN(maxpages - bz->total_bpages, pages); - pages = MAX(pages, 1); - if (alloc_bounce_pages(dmat, pages) < pages) - error = ENOMEM; - - if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0) { - if (error == 0) - dmat->flags |= BUS_DMA_MIN_ALLOC_COMP; - } else { - error = 0; - } - } - } else { - *mapp = NULL; - } - if (error == 0) - dmat->map_count++; - CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", - __func__, dmat, dmat->flags, error); - return (error); -} - -/* - * Destroy a handle for mapping from kva/uva/physical - * address space into bus device space. - */ -int -bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map) -{ - if (map != NULL && map != &nobounce_dmamap) { - if (STAILQ_FIRST(&map->bpages) != NULL) { - CTR3(KTR_BUSDMA, "%s: tag %p error %d", - __func__, dmat, EBUSY); - return (EBUSY); - } - free(map, M_DEVBUF); - } - dmat->map_count--; - CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat); - return (0); -} - -/* - * Allocate a piece of memory that can be efficiently mapped into - * bus device space based on the constraints lited in the dma tag. - * A dmamap to for use with dmamap_load is also allocated. - */ -int -bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, - bus_dmamap_t *mapp) -{ - int mflags; - - if (flags & BUS_DMA_NOWAIT) - mflags = M_NOWAIT; - else - mflags = M_WAITOK; - if (flags & BUS_DMA_ZERO) - mflags |= M_ZERO; - - /* If we succeed, no mapping/bouncing will be required */ - *mapp = NULL; - - if (dmat->segments == NULL) { - dmat->segments = (bus_dma_segment_t *)malloc( - sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF, - M_NOWAIT); - if (dmat->segments == NULL) { - CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", - __func__, dmat, dmat->flags, ENOMEM); - return (ENOMEM); - } - } - - /* - * XXX: - * (dmat->alignment < dmat->maxsize) is just a quick hack; the exact - * alignment guarantees of malloc need to be nailed down, and the - * code below should be rewritten to take that into account. - * - * In the meantime, we'll warn the user if malloc gets it wrong. - */ - if ((dmat->maxsize <= PAGE_SIZE) && - (dmat->alignment < dmat->maxsize) && - dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem)) { - *vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags); - } else { - /* - * XXX Use Contigmalloc until it is merged into this facility - * and handles multi-seg allocations. Nobody is doing - * multi-seg allocations yet though. - * XXX Certain AGP hardware does. - */ - *vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, mflags, - 0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul, - dmat->boundary); - } - if (*vaddr == NULL) { - CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", - __func__, dmat, dmat->flags, ENOMEM); - return (ENOMEM); - } else if ((uintptr_t)*vaddr & (dmat->alignment - 1)) { - printf("bus_dmamem_alloc failed to align memory properly.\n"); - } - CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", - __func__, dmat, dmat->flags, 0); - return (0); -} - -/* - * Free a piece of memory and it's allociated dmamap, that was allocated - * via bus_dmamem_alloc. Make the same choice for free/contigfree. - */ -void -bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) -{ - /* - * dmamem does not need to be bounced, so the map should be - * NULL - */ - if (map != NULL) - panic("bus_dmamem_free: Invalid map freed\n"); - if ((dmat->maxsize <= PAGE_SIZE) && - (dmat->alignment < dmat->maxsize) && - dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem)) - free(vaddr, M_DEVBUF); - else { - contigfree(vaddr, dmat->maxsize, M_DEVBUF); - } - CTR3(KTR_BUSDMA, "%s: tag %p flags 0x%x", __func__, dmat, dmat->flags); -} - -/* - * Utility function to load a linear buffer. lastaddrp holds state - * between invocations (for multiple-buffer loads). segp contains - * the starting segment on entrace, and the ending segment on exit. - * first indicates if this is the first invocation of this function. - */ -static __inline int -_bus_dmamap_load_buffer(bus_dma_tag_t dmat, - bus_dmamap_t map, - void *buf, bus_size_t buflen, - pmap_t pmap, - int flags, - bus_addr_t *lastaddrp, - bus_dma_segment_t *segs, - int *segp, - int first) -{ - bus_size_t sgsize; - bus_addr_t curaddr, lastaddr, baddr, bmask; - vm_offset_t vaddr; - bus_addr_t paddr; - int needbounce = 0; - int seg; - - if (map == NULL) - map = &nobounce_dmamap; - - if ((map != &nobounce_dmamap && map->pagesneeded == 0) - && ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0)) { - vm_offset_t vendaddr; - - CTR4(KTR_BUSDMA, "lowaddr= %d Maxmem= %d, boundary= %d, " - "alignment= %d", dmat->lowaddr, ptoa((vm_paddr_t)Maxmem), - dmat->boundary, dmat->alignment); - CTR3(KTR_BUSDMA, "map= %p, nobouncemap= %p, pagesneeded= %d", - map, &nobounce_dmamap, map->pagesneeded); - /* - * Count the number of bounce pages - * needed in order to complete this transfer - */ - vaddr = trunc_page((vm_offset_t)buf); - vendaddr = (vm_offset_t)buf + buflen; - - while (vaddr < vendaddr) { - paddr = pmap_kextract(vaddr); - if (run_filter(dmat, paddr) != 0) { - needbounce = 1; - map->pagesneeded++; - } - vaddr += PAGE_SIZE; - } - CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded); - } - - /* Reserve Necessary Bounce Pages */ - if (map->pagesneeded != 0) { - mtx_lock(&bounce_lock); - if (flags & BUS_DMA_NOWAIT) { - if (reserve_bounce_pages(dmat, map, 0) != 0) { - mtx_unlock(&bounce_lock); - return (ENOMEM); - } - } else { - if (reserve_bounce_pages(dmat, map, 1) != 0) { - /* Queue us for resources */ - map->dmat = dmat; - map->buf = buf; - map->buflen = buflen; - STAILQ_INSERT_TAIL(&bounce_map_waitinglist, - map, links); - mtx_unlock(&bounce_lock); - return (EINPROGRESS); - } - } - mtx_unlock(&bounce_lock); - } - - vaddr = (vm_offset_t)buf; - lastaddr = *lastaddrp; - bmask = ~(dmat->boundary - 1); - - for (seg = *segp; buflen > 0 ; ) { - /* - * Get the physical address for this segment. - */ - if (pmap) - curaddr = (bus_addr_t)pmap_extract(pmap, vaddr); - else - curaddr = pmap_kextract(vaddr); - - /* - * Compute the segment size, and adjust counts. - */ - sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK); - if (buflen < sgsize) - sgsize = buflen; - - /* - * Make sure we don't cross any boundaries. - */ - if (dmat->boundary > 0) { - baddr = (curaddr + dmat->boundary) & bmask; - if (sgsize > (baddr - curaddr)) - sgsize = (baddr - curaddr); - } - - if (map->pagesneeded != 0 && run_filter(dmat, curaddr)) - curaddr = add_bounce_page(dmat, map, vaddr, sgsize); - - /* - * Insert chunk into a segment, coalescing with - * previous segment if possible. - */ - if (first) { - segs[seg].ds_addr = curaddr; - segs[seg].ds_len = sgsize; - first = 0; - } else { - if (needbounce == 0 && curaddr == lastaddr && - (segs[seg].ds_len + sgsize) <= dmat->maxsegsz && - (dmat->boundary == 0 || - (segs[seg].ds_addr & bmask) == (curaddr & bmask))) - segs[seg].ds_len += sgsize; - else { - if (++seg >= dmat->nsegments) - break; - segs[seg].ds_addr = curaddr; - segs[seg].ds_len = sgsize; - } - } - - lastaddr = curaddr + sgsize; - vaddr += sgsize; - buflen -= sgsize; - } - - *segp = seg; - *lastaddrp = lastaddr; - - /* - * Did we fit? - */ - return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */ -} - -/* - * Map the buffer buf into bus space using the dmamap map. - */ -int -bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, - bus_size_t buflen, bus_dmamap_callback_t *callback, - void *callback_arg, int flags) -{ - bus_addr_t lastaddr = 0; - int error, nsegs = 0; - - if (map != NULL) { - flags |= BUS_DMA_WAITOK; - map->callback = callback; - map->callback_arg = callback_arg; - } - - error = _bus_dmamap_load_buffer(dmat, map, buf, buflen, NULL, flags, - &lastaddr, dmat->segments, &nsegs, 1); - - CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", - __func__, dmat, dmat->flags, error, nsegs + 1); - - if (error == EINPROGRESS) { - return (error); - } - - if (error) - (*callback)(callback_arg, dmat->segments, 0, error); - else - (*callback)(callback_arg, dmat->segments, nsegs + 1, 0); - - /* - * Return ENOMEM to the caller so that it can pass it up the stack. - * This error only happens when NOWAIT is set, so deferal is disabled. - */ - if (error == ENOMEM) - return (error); - - return (0); -} - -/* - * Like _bus_dmamap_load(), but for mbufs. - */ -int -bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, - struct mbuf *m0, - bus_dmamap_callback2_t *callback, void *callback_arg, - int flags) -{ - int nsegs, error; - - M_ASSERTPKTHDR(m0); - - flags |= BUS_DMA_NOWAIT; - nsegs = 0; - error = 0; - if (m0->m_pkthdr.len <= dmat->maxsize) { - int first = 1; - bus_addr_t lastaddr = 0; - struct mbuf *m; - - for (m = m0; m != NULL && error == 0; m = m->m_next) { - if (m->m_len > 0) { - error = _bus_dmamap_load_buffer(dmat, map, - m->m_data, m->m_len, - NULL, flags, &lastaddr, - dmat->segments, &nsegs, first); - first = 0; - } - } - } else { - error = EINVAL; - } - - if (error) { - /* force "no valid mappings" in callback */ - (*callback)(callback_arg, dmat->segments, 0, 0, error); - } else { - (*callback)(callback_arg, dmat->segments, - nsegs+1, m0->m_pkthdr.len, error); - } - CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", - __func__, dmat, dmat->flags, error, nsegs + 1); - return (error); -} - -int -bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map, - struct mbuf *m0, bus_dma_segment_t *segs, int *nsegs, - int flags) -{ - int error; - - M_ASSERTPKTHDR(m0); - - flags |= BUS_DMA_NOWAIT; - *nsegs = 0; - error = 0; - if (m0->m_pkthdr.len <= dmat->maxsize) { - int first = 1; - bus_addr_t lastaddr = 0; - struct mbuf *m; - - for (m = m0; m != NULL && error == 0; m = m->m_next) { - if (m->m_len > 0) { - error = _bus_dmamap_load_buffer(dmat, map, - m->m_data, m->m_len, - NULL, flags, &lastaddr, - segs, nsegs, first); - first = 0; - } - } - } else { - error = EINVAL; - } - - /* XXX FIXME: Having to increment nsegs is really annoying */ - ++*nsegs; - CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", - __func__, dmat, dmat->flags, error, *nsegs); - return (error); -} - -#if 0 -/* - * Like _bus_dmamap_load(), but for uios. - */ -int -bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, - struct uio *uio, - bus_dmamap_callback2_t *callback, void *callback_arg, - int flags) -{ - bus_addr_t lastaddr; - int nsegs, error, first, i; - bus_size_t resid; - struct iovec *iov; - pmap_t pmap; - - flags |= BUS_DMA_NOWAIT; - resid = uio->uio_resid; - iov = uio->uio_iov; - - if (uio->uio_segflg == UIO_USERSPACE) { - KASSERT(uio->uio_td != NULL, - ("bus_dmamap_load_uio: USERSPACE but no proc")); - pmap = vmspace_pmap(uio->uio_td->td_proc->p_vmspace); - } else - pmap = NULL; - - nsegs = 0; - error = 0; - first = 1; - for (i = 0; i < uio->uio_iovcnt && resid != 0 && !error; i++) { - /* - * Now at the first iovec to load. Load each iovec - * until we have exhausted the residual count. - */ - bus_size_t minlen = - resid < iov[i].iov_len ? resid : iov[i].iov_len; - caddr_t addr = (caddr_t) iov[i].iov_base; - - if (minlen > 0) { - error = _bus_dmamap_load_buffer(dmat, map, - addr, minlen, pmap, flags, &lastaddr, - dmat->segments, &nsegs, first); - first = 0; - - resid -= minlen; - } - } - - if (error) { - /* force "no valid mappings" in callback */ - (*callback)(callback_arg, dmat->segments, 0, 0, error); - } else { - (*callback)(callback_arg, dmat->segments, - nsegs+1, uio->uio_resid, error); - } - CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", - __func__, dmat, dmat->flags, error, nsegs + 1); - return (error); -} -#endif - -/* - * Release the mapping held by map. - */ -void -_bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map) -{ - struct bounce_page *bpage; - - while ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) { - STAILQ_REMOVE_HEAD(&map->bpages, links); - free_bounce_page(dmat, bpage); - } -} - -void -_bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) -{ - struct bounce_page *bpage; - - if ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) { - /* - * Handle data bouncing. We might also - * want to add support for invalidating - * the caches on broken hardware - */ - dmat->bounce_zone->total_bounced++; - CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x " - "performing bounce", __func__, op, dmat, dmat->flags); - - if (op & BUS_DMASYNC_PREWRITE) { - while (bpage != NULL) { - bcopy((void *)bpage->datavaddr, - (void *)bpage->vaddr, - bpage->datacount); - bpage = STAILQ_NEXT(bpage, links); - } - } - - if (op & BUS_DMASYNC_POSTREAD) { - while (bpage != NULL) { - bcopy((void *)bpage->vaddr, - (void *)bpage->datavaddr, - bpage->datacount); - bpage = STAILQ_NEXT(bpage, links); - } - } - } -} - -void -init_bounce_pages() -{ - - total_bpages = 0; - STAILQ_INIT(&bounce_zone_list); - STAILQ_INIT(&bounce_map_waitinglist); - STAILQ_INIT(&bounce_map_callbacklist); - mtx_init(&bounce_lock, "bounce pages lock", NULL, MTX_DEF); -} - -/* Haiku extension */ -void -uninit_bounce_pages() -{ - /* XXX deep free */ - - mtx_destroy(&bounce_lock); -} - -static struct sysctl_ctx_list * -busdma_sysctl_tree(struct bounce_zone *bz) -{ - return (&bz->sysctl_tree); -} - -static struct sysctl_oid * -busdma_sysctl_tree_top(struct bounce_zone *bz) -{ - return (bz->sysctl_tree_top); -} - -static int -alloc_bounce_zone(bus_dma_tag_t dmat) -{ - struct bounce_zone *bz; - - /* Check to see if we already have a suitable zone */ - STAILQ_FOREACH(bz, &bounce_zone_list, links) { - if ((dmat->alignment <= bz->alignment) - && (dmat->boundary <= bz->boundary) - && (dmat->lowaddr >= bz->lowaddr)) { - dmat->bounce_zone = bz; - return (0); - } - } - - if ((bz = (struct bounce_zone *)malloc(sizeof(*bz), M_DEVBUF, - M_NOWAIT | M_ZERO)) == NULL) - return (ENOMEM); - - STAILQ_INIT(&bz->bounce_page_list); - bz->free_bpages = 0; - bz->reserved_bpages = 0; - bz->active_bpages = 0; - bz->lowaddr = dmat->lowaddr; - bz->alignment = dmat->alignment; - bz->boundary = dmat->boundary; - snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount); - busdma_zonecount++; - snprintf(bz->lowaddrid, 18, "%llx", (uintmax_t)bz->lowaddr); - STAILQ_INSERT_TAIL(&bounce_zone_list, bz, links); - dmat->bounce_zone = bz; - - sysctl_ctx_init(&bz->sysctl_tree); - bz->sysctl_tree_top = SYSCTL_ADD_NODE(&bz->sysctl_tree, - SYSCTL_STATIC_CHILDREN(_hw_busdma), OID_AUTO, bz->zoneid, - CTLFLAG_RD, 0, ""); - if (bz->sysctl_tree_top == NULL) { - sysctl_ctx_free(&bz->sysctl_tree); - return (0); /* XXX error code? */ - } - - SYSCTL_ADD_INT(busdma_sysctl_tree(bz), - SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, - "total_bpages", CTLFLAG_RD, &bz->total_bpages, 0, - "Total bounce pages"); - SYSCTL_ADD_INT(busdma_sysctl_tree(bz), - SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, - "free_bpages", CTLFLAG_RD, &bz->free_bpages, 0, - "Free bounce pages"); - SYSCTL_ADD_INT(busdma_sysctl_tree(bz), - SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, - "reserved_bpages", CTLFLAG_RD, &bz->reserved_bpages, 0, - "Reserved bounce pages"); - SYSCTL_ADD_INT(busdma_sysctl_tree(bz), - SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, - "active_bpages", CTLFLAG_RD, &bz->active_bpages, 0, - "Active bounce pages"); - SYSCTL_ADD_INT(busdma_sysctl_tree(bz), - SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, - "total_bounced", CTLFLAG_RD, &bz->total_bounced, 0, - "Total bounce requests"); - SYSCTL_ADD_INT(busdma_sysctl_tree(bz), - SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, - "total_deferred", CTLFLAG_RD, &bz->total_deferred, 0, - "Total bounce requests that were deferred"); - SYSCTL_ADD_STRING(busdma_sysctl_tree(bz), - SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, - "lowaddr", CTLFLAG_RD, bz->lowaddrid, 0, ""); - SYSCTL_ADD_INT(busdma_sysctl_tree(bz), - SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, - "alignment", CTLFLAG_RD, &bz->alignment, 0, ""); - SYSCTL_ADD_INT(busdma_sysctl_tree(bz), - SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, - "boundary", CTLFLAG_RD, &bz->boundary, 0, ""); - - return (0); -} - -static int -alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages) -{ - struct bounce_zone *bz; - int count; - - bz = dmat->bounce_zone; - count = 0; - while (numpages > 0) { - struct bounce_page *bpage; - - bpage = (struct bounce_page *)malloc(sizeof(*bpage), M_DEVBUF, - M_NOWAIT | M_ZERO); - - if (bpage == NULL) - break; - bpage->vaddr = (vm_offset_t)contigmalloc(PAGE_SIZE, M_DEVBUF, - M_NOWAIT, 0ul, - bz->lowaddr, - PAGE_SIZE, - bz->boundary); - if (bpage->vaddr == 0) { - free(bpage, M_DEVBUF); - break; - } - bpage->busaddr = pmap_kextract(bpage->vaddr); - mtx_lock(&bounce_lock); - STAILQ_INSERT_TAIL(&bz->bounce_page_list, bpage, links); - total_bpages++; - bz->total_bpages++; - bz->free_bpages++; - mtx_unlock(&bounce_lock); - count++; - numpages--; - } - return (count); -} - -static int -reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map, int commit) -{ - struct bounce_zone *bz; - int pages; - - mtx_assert(&bounce_lock, MA_OWNED); - bz = dmat->bounce_zone; - pages = MIN(bz->free_bpages, map->pagesneeded - map->pagesreserved); - if (commit == 0 && map->pagesneeded > (map->pagesreserved + pages)) - return (map->pagesneeded - (map->pagesreserved + pages)); - bz->free_bpages -= pages; - bz->reserved_bpages += pages; - map->pagesreserved += pages; - pages = map->pagesneeded - map->pagesreserved; - - return (pages); -} - -static bus_addr_t -add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr, - bus_size_t size) -{ - struct bounce_zone *bz; - struct bounce_page *bpage; - - KASSERT(dmat->bounce_zone != NULL, ("no bounce zone in dma tag")); - KASSERT(map != NULL && map != &nobounce_dmamap, - ("add_bounce_page: bad map %p", map)); - - bz = dmat->bounce_zone; - if (map->pagesneeded == 0) - panic("add_bounce_page: map doesn't need any pages"); - map->pagesneeded--; - - if (map->pagesreserved == 0) - panic("add_bounce_page: map doesn't need any pages"); - map->pagesreserved--; - - mtx_lock(&bounce_lock); - bpage = STAILQ_FIRST(&bz->bounce_page_list); - if (bpage == NULL) - panic("add_bounce_page: free page list is empty"); - - STAILQ_REMOVE_HEAD(&bz->bounce_page_list, links); - bz->reserved_bpages--; - bz->active_bpages++; - mtx_unlock(&bounce_lock); - - bpage->datavaddr = vaddr; - bpage->datacount = size; - STAILQ_INSERT_TAIL(&(map->bpages), bpage, links); - return (bpage->busaddr); -} - -static void -free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage) -{ - struct bus_dmamap *map; - struct bounce_zone *bz; - - bz = dmat->bounce_zone; - bpage->datavaddr = 0; - bpage->datacount = 0; - - mtx_lock(&bounce_lock); - STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links); - bz->free_bpages++; - bz->active_bpages--; - if ((map = STAILQ_FIRST(&bounce_map_waitinglist)) != NULL) { - if (reserve_bounce_pages(map->dmat, map, 1) == 0) { - STAILQ_REMOVE_HEAD(&bounce_map_waitinglist, links); - STAILQ_INSERT_TAIL(&bounce_map_callbacklist, - map, links); - busdma_swi_pending = 1; - bz->total_deferred++; -#if 0 - swi_sched(vm_ih, 0); -#endif - busdma_swi(); - } - } - mtx_unlock(&bounce_lock); -} - -void -busdma_swi(void) -{ - bus_dma_tag_t dmat; - struct bus_dmamap *map; - - mtx_lock(&bounce_lock); - while ((map = STAILQ_FIRST(&bounce_map_callbacklist)) != NULL) { - STAILQ_REMOVE_HEAD(&bounce_map_callbacklist, links); - mtx_unlock(&bounce_lock); - dmat = map->dmat; - (dmat->lockfunc)(dmat->lockfuncarg, BUS_DMA_LOCK); - bus_dmamap_load(map->dmat, map, map->buf, map->buflen, - map->callback, map->callback_arg, /*flags*/0); - (dmat->lockfunc)(dmat->lockfuncarg, BUS_DMA_UNLOCK); - mtx_lock(&bounce_lock); - } - mtx_unlock(&bounce_lock); -} diff --git a/src/libs/compat/freebsd_network/fbsd_ether.c b/src/libs/compat/freebsd_network/fbsd_ether.c deleted file mode 100644 index e219cc6743..0000000000 --- a/src/libs/compat/freebsd_network/fbsd_ether.c +++ /dev/null @@ -1,118 +0,0 @@ -/*- - * Copyright (c) 1982, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93 - * $FreeBSD: src/sys/net/if_ethersubr.c,v 1.193.2.12 2006/08/28 02:54:14 thompsa Exp $ - */ -#include -#include -#include - -#if 0 -/* - * This is for reference. We have a table-driven version - * of the little-endian crc32 generator, which is faster - * than the double-loop. - */ -uint32_t -ether_crc32_le(const uint8_t *buf, size_t len) -{ - size_t i; - uint32_t crc; - int bit; - uint8_t data; - - crc = 0xffffffff; /* initial value */ - - for (i = 0; i < len; i++) { - for (data = *buf++, bit = 0; bit < 8; bit++, data >>= 1) - carry = (crc ^ data) & 1; - crc >>= 1; - if (carry) - crc = (crc ^ ETHER_CRC_POLY_LE); - } - - return (crc); -} -#else -uint32_t -ether_crc32_le(const uint8_t *buf, size_t len) -{ - static const uint32_t crctab[] = { - 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, - 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, - 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, - 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c - }; - size_t i; - uint32_t crc; - - crc = 0xffffffff; /* initial value */ - - for (i = 0; i < len; i++) { - crc ^= buf[i]; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - } - - return (crc); -} -#endif - -uint32_t -ether_crc32_be(const uint8_t *buf, size_t len) -{ - size_t i; - uint32_t crc, carry; - int bit; - uint8_t data; - - crc = 0xffffffff; /* initial value */ - - for (i = 0; i < len; i++) { - for (data = *buf++, bit = 0; bit < 8; bit++, data >>= 1) { - carry = ((crc & 0x80000000) ? 1 : 0) ^ (data & 0x01); - crc <<= 1; - if (carry) - crc = (crc ^ ETHER_CRC_POLY_BE) | carry; - } - } - - return (crc); -} - -char * -ether_sprintf(const u_char *ap) -{ - static char etherbuf[18]; - snprintf(etherbuf, sizeof (etherbuf), - "%02x:%02x:%02x:%02x:%02x:%02x", - (unsigned)ap[0], (unsigned)ap[1], (unsigned)ap[2], - (unsigned)ap[3], (unsigned)ap[4], (unsigned)ap[5]); - return (etherbuf); -} diff --git a/src/libs/compat/freebsd_network/fbsd_if_media.c b/src/libs/compat/freebsd_network/fbsd_if_media.c deleted file mode 100644 index a115c01102..0000000000 --- a/src/libs/compat/freebsd_network/fbsd_if_media.c +++ /dev/null @@ -1,554 +0,0 @@ -/* $NetBSD: if_media.c,v 1.1 1997/03/17 02:55:15 thorpej Exp $ */ -/* $FreeBSD: src/sys/net/if_media.c,v 1.21.2.1 2006/03/17 20:17:43 glebius Exp $ */ - -/*- - * Copyright (c) 1997 - * Jonathan Stone and Jason R. Thorpe. All rights reserved. - * - * This software is derived from information provided by Matt Thomas. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jonathan Stone - * and Jason R. Thorpe for the NetBSD Project. - * 4. The names of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * BSD/OS-compatible network interface media selection. - * - * Where it is safe to do so, this code strays slightly from the BSD/OS - * design. Software which uses the API (device drivers, basically) - * shouldn't notice any difference. - * - * Many thanks to Matt Thomas for providing the information necessary - * to implement this interface. - */ -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -/* - * Compile-time options: - * IFMEDIA_DEBUG: - * turn on implementation-level debug printfs. - * Useful for debugging newly-ported drivers. - */ - -#define IFMEDIA_DEBUG -#ifdef IFMEDIA_DEBUG -# define TRACE(x...) dprintf(x) -#else -# define TRACE(x...) ; -#endif - -static struct ifmedia_entry *ifmedia_match(struct ifmedia *ifm, - int flags, int mask); - -static void ifmedia_printword(int); - -/* - * Initialize if_media struct for a specific interface instance. - */ -void -ifmedia_init(ifm, dontcare_mask, change_callback, status_callback) - struct ifmedia *ifm; - int dontcare_mask; - ifm_change_cb_t change_callback; - ifm_stat_cb_t status_callback; -{ - - LIST_INIT(&ifm->ifm_list); - ifm->ifm_cur = NULL; - ifm->ifm_media = 0; - ifm->ifm_mask = dontcare_mask; /* IF don't-care bits */ - ifm->ifm_change = change_callback; - ifm->ifm_status = status_callback; -} - -void -ifmedia_removeall(ifm) - struct ifmedia *ifm; -{ - struct ifmedia_entry *entry; - - for (entry = LIST_FIRST(&ifm->ifm_list); entry; - entry = LIST_FIRST(&ifm->ifm_list)) { - LIST_REMOVE(entry, ifm_list); - kernel_free(entry, M_IFADDR); - } -} - -/* - * Add a media configuration to the list of supported media - * for a specific interface instance. - */ -void -ifmedia_add(ifm, mword, data, aux) - struct ifmedia *ifm; - int mword; - int data; - void *aux; -{ - register struct ifmedia_entry *entry; - -#ifdef IFMEDIA_DEBUG - if (ifm == NULL) { - TRACE("ifmedia_add: null ifm\n"); - return; - } - TRACE("ifmedia_add: Adding Entry...\n"); - ifmedia_printword(mword); -#endif - - entry = kernel_malloc(sizeof(*entry), M_IFADDR, M_NOWAIT); - if (entry == NULL) - panic("ifmedia_add: can't malloc entry"); - - entry->ifm_media = mword; - entry->ifm_data = data; - entry->ifm_aux = aux; - - LIST_INSERT_HEAD(&ifm->ifm_list, entry, ifm_list); -} - -/* - * Add an array of media configurations to the list of - * supported media for a specific interface instance. - */ -void -ifmedia_list_add(ifm, lp, count) - struct ifmedia *ifm; - struct ifmedia_entry *lp; - int count; -{ - int i; - - for (i = 0; i < count; i++) - ifmedia_add(ifm, lp[i].ifm_media, lp[i].ifm_data, - lp[i].ifm_aux); -} - -/* - * Set the default active media. - * - * Called by device-specific code which is assumed to have already - * selected the default media in hardware. We do _not_ call the - * media-change callback. - */ -void -ifmedia_set(ifm, target) - struct ifmedia *ifm; - int target; - -{ - struct ifmedia_entry *match; - - match = ifmedia_match(ifm, target, ifm->ifm_mask); - - if (match == NULL) { - TRACE("ifmedia_set: no match for 0x%x/0x%x\n", - target, ~ifm->ifm_mask); - panic("ifmedia_set"); - } - ifm->ifm_cur = match; - -#ifdef IFMEDIA_DEBUG - TRACE("ifmedia_set: target "); - ifmedia_printword(target); - TRACE("ifmedia_set: setting to "); - ifmedia_printword(ifm->ifm_cur->ifm_media); -#endif -} - -/* - * Device-independent media ioctl support function. - */ -int -ifmedia_ioctl(ifp, ifr, ifm, cmd) - struct ifnet *ifp; - struct ifreq *ifr; - struct ifmedia *ifm; - u_long cmd; -{ - struct ifmedia_entry *match; - struct ifmediareq *ifmr = (struct ifmediareq *) ifr; - int error = 0, sticky; - - if (ifp == NULL || ifr == NULL || ifm == NULL) - return(EINVAL); - - switch (cmd) { - - /* - * Set the current media. - */ - case SIOCSIFMEDIA: - { - struct ifmedia_entry *oldentry; - int oldmedia; - int newmedia = ifr->ifr_media; - - match = ifmedia_match(ifm, newmedia, ifm->ifm_mask); - if (match == NULL) { - TRACE("ifmedia_ioctl: no media found for 0x%x\n", - newmedia); - return (ENXIO); - } - - /* - * If no change, we're done. - * XXX Automedia may invole software intervention. - * Keep going in case the the connected media changed. - * Similarly, if best match changed (kernel debugger?). - */ - if ((IFM_SUBTYPE(newmedia) != IFM_AUTO) && - (newmedia == ifm->ifm_media) && - (match == ifm->ifm_cur)) - return 0; - - /* - * We found a match, now make the driver switch to it. - * Make sure to preserve our old media type in case the - * driver can't switch. - */ -#ifdef IFMEDIA_DEBUG - TRACE("ifmedia_ioctl: switching %s to ", - ifp->if_xname); - ifmedia_printword(match->ifm_media); -#endif - oldentry = ifm->ifm_cur; - oldmedia = ifm->ifm_media; - ifm->ifm_cur = match; - ifm->ifm_media = newmedia; - error = (*ifm->ifm_change)(ifp); - if (error) { - ifm->ifm_cur = oldentry; - ifm->ifm_media = oldmedia; - } - break; - } - - /* - * Get list of available media and current media on interface. - */ - case SIOCGIFMEDIA: - { - struct ifmedia_entry *ep; - int *kptr, count; - int usermax; /* user requested max */ - - kptr = NULL; /* XXX gcc */ - - ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ? - ifm->ifm_cur->ifm_media : IFM_NONE; - ifmr->ifm_mask = ifm->ifm_mask; - ifmr->ifm_status = 0; - (*ifm->ifm_status)(ifp, ifmr); - - count = 0; - usermax = 0; - - /* - * If there are more interfaces on the list, count - * them. This allows the caller to set ifmr->ifm_count - * to 0 on the first call to know how much space to - * allocate. - */ - LIST_FOREACH(ep, &ifm->ifm_list, ifm_list) - usermax++; - - /* - * Don't allow the user to ask for too many - * or a negative number. - */ - if (ifmr->ifm_count > usermax) - ifmr->ifm_count = usermax; - else if (ifmr->ifm_count < 0) - return (EINVAL); - - if (ifmr->ifm_count != 0) { - kptr = (int *)kernel_malloc(ifmr->ifm_count * sizeof(int), - M_TEMP, M_NOWAIT); - - if (kptr == NULL) - return (ENOMEM); - /* - * Get the media words from the interface's list. - */ - ep = LIST_FIRST(&ifm->ifm_list); - for (; ep != NULL && count < ifmr->ifm_count; - ep = LIST_NEXT(ep, ifm_list), count++) - kptr[count] = ep->ifm_media; - - if (ep != NULL) - error = E2BIG; /* oops! */ - } else { - count = usermax; - } - - /* - * We do the copyout on E2BIG, because that's - * just our way of telling userland that there - * are more. This is the behavior I've observed - * under BSD/OS 3.0 - */ - sticky = error; - if ((error == 0 || error == E2BIG) && ifmr->ifm_count != 0) { -#if 0 - error = copyout((caddr_t)kptr, - (caddr_t)ifmr->ifm_ulist, - ifmr->ifm_count * sizeof(int)); -#endif - /* this ioctl() is only called from within the kernel -hugo */ - memcpy(kptr, ifmr->ifm_ulist, ifmr->ifm_count * sizeof(int)); - } - - if (error == 0) - error = sticky; - - if (ifmr->ifm_count != 0) - kernel_free(kptr, M_TEMP); - - ifmr->ifm_count = count; - break; - } - - default: - return (EINVAL); - } - - return (error); -} - -/* - * Find media entry matching a given ifm word. - * - */ -static struct ifmedia_entry * -ifmedia_match(ifm, target, mask) - struct ifmedia *ifm; - int target; - int mask; -{ - struct ifmedia_entry *match, *next; - - match = NULL; - mask = ~mask; - - LIST_FOREACH(next, &ifm->ifm_list, ifm_list) { - if ((next->ifm_media & mask) == (target & mask)) { -#ifdef IFMEDIA_DEBUG - if (match) { - TRACE("ifmedia_match: multiple match for " - "0x%x/0x%x\n", target, mask); - } -#endif - match = next; - } - } - - return match; -} - -/* - * Compute the interface `baudrate' from the media, for the interface - * metrics (used by routing daemons). - */ -static const struct ifmedia_baudrate ifmedia_baudrate_descriptions[] = - IFM_BAUDRATE_DESCRIPTIONS; - -uint64_t -ifmedia_baudrate(int mword) -{ - int i; - - for (i = 0; ifmedia_baudrate_descriptions[i].ifmb_word != 0; i++) { - if ((mword & (IFM_NMASK|IFM_TMASK)) == - ifmedia_baudrate_descriptions[i].ifmb_word) - return (ifmedia_baudrate_descriptions[i].ifmb_baudrate); - } - - /* Not known. */ - return (0); -} - -#ifdef IFMEDIA_DEBUG -struct ifmedia_description ifm_type_descriptions[] = - IFM_TYPE_DESCRIPTIONS; - -struct ifmedia_description ifm_subtype_ethernet_descriptions[] = - IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; - -struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] = - IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS; - -struct ifmedia_description ifm_subtype_tokenring_descriptions[] = - IFM_SUBTYPE_TOKENRING_DESCRIPTIONS; - -struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] = - IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS; - -struct ifmedia_description ifm_subtype_fddi_descriptions[] = - IFM_SUBTYPE_FDDI_DESCRIPTIONS; - -struct ifmedia_description ifm_subtype_fddi_option_descriptions[] = - IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS; - -struct ifmedia_description ifm_subtype_ieee80211_descriptions[] = - IFM_SUBTYPE_IEEE80211_DESCRIPTIONS; - -struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] = - IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS; - -struct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] = - IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS; - -struct ifmedia_description ifm_subtype_atm_descriptions[] = - IFM_SUBTYPE_ATM_DESCRIPTIONS; - -struct ifmedia_description ifm_subtype_atm_option_descriptions[] = - IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS; - -struct ifmedia_description ifm_subtype_shared_descriptions[] = - IFM_SUBTYPE_SHARED_DESCRIPTIONS; - -struct ifmedia_description ifm_shared_option_descriptions[] = - IFM_SHARED_OPTION_DESCRIPTIONS; - -struct ifmedia_type_to_subtype { - struct ifmedia_description *subtypes; - struct ifmedia_description *options; - struct ifmedia_description *modes; -}; - -/* must be in the same order as IFM_TYPE_DESCRIPTIONS */ -struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { - { - &ifm_subtype_ethernet_descriptions[0], - &ifm_subtype_ethernet_option_descriptions[0], - NULL, - }, - { - &ifm_subtype_tokenring_descriptions[0], - &ifm_subtype_tokenring_option_descriptions[0], - NULL, - }, - { - &ifm_subtype_fddi_descriptions[0], - &ifm_subtype_fddi_option_descriptions[0], - NULL, - }, - { - &ifm_subtype_ieee80211_descriptions[0], - &ifm_subtype_ieee80211_option_descriptions[0], - &ifm_subtype_ieee80211_mode_descriptions[0] - }, - { - &ifm_subtype_atm_descriptions[0], - &ifm_subtype_atm_option_descriptions[0], - NULL, - }, -}; - -/* - * print a media word. - */ -static void -ifmedia_printword(ifmw) - int ifmw; -{ - struct ifmedia_description *desc; - struct ifmedia_type_to_subtype *ttos; - int seen_option = 0; - - /* Find the top-level interface type. */ - for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; - desc->ifmt_string != NULL; desc++, ttos++) - if (IFM_TYPE(ifmw) == desc->ifmt_word) - break; - if (desc->ifmt_string == NULL) { - TRACE(" Type: \n"); - return; - } - TRACE(" Type: %s\n", desc->ifmt_string); - - /* Any mode. */ - for (desc = ttos->modes; desc && desc->ifmt_string != NULL; desc++) - if (IFM_MODE(ifmw) == desc->ifmt_word) { - if (desc->ifmt_string != NULL) - TRACE(" Mode: %s\n", desc->ifmt_string); - break; - } - - /* - * Check for the shared subtype descriptions first, then the - * type-specific ones. - */ - for (desc = ifm_subtype_shared_descriptions; - desc->ifmt_string != NULL; desc++) - if (IFM_SUBTYPE(ifmw) == desc->ifmt_word) - goto got_subtype; - - for (desc = ttos->subtypes; desc->ifmt_string != NULL; desc++) - if (IFM_SUBTYPE(ifmw) == desc->ifmt_word) - break; - if (desc->ifmt_string == NULL) { - TRACE(" SubType: \n"); - return; - } - - got_subtype: - TRACE(" SubType: %s\n", desc->ifmt_string); - - /* - * Look for shared options. - */ - for (desc = ifm_shared_option_descriptions; - desc->ifmt_string != NULL; desc++) { - if (ifmw & desc->ifmt_word) { - TRACE(" Shared Option[%d]: %s\n", seen_option++, - desc->ifmt_string); - } - } - - /* - * Look for subtype-specific options. - */ - for (desc = ttos->options; desc->ifmt_string != NULL; desc++) { - if (ifmw & desc->ifmt_word) { - TRACE(" SubType Option[%d]: %s\n", seen_option++, - desc->ifmt_string); - } - } -} -#endif /* IFMEDIA_DEBUG */ diff --git a/src/libs/compat/freebsd_network/fbsd_mbuf.c b/src/libs/compat/freebsd_network/fbsd_mbuf.c deleted file mode 100644 index 7a0e6db63f..0000000000 --- a/src/libs/compat/freebsd_network/fbsd_mbuf.c +++ /dev/null @@ -1,1018 +0,0 @@ -/*- - * Copyright (c) 1982, 1986, 1988, 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - */ -#include -#include -#include - -/* - * Copy data from an mbuf chain starting "off" bytes from the beginning, - * continuing for "len" bytes, into the indicated buffer. - */ -void -m_copydata(const struct mbuf *m, int off, int len, caddr_t cp) -{ - u_int count; - - KASSERT(off >= 0, ("m_copydata, negative off %d", off)); - KASSERT(len >= 0, ("m_copydata, negative len %d", len)); - while (off > 0) { - KASSERT(m != NULL, ("m_copydata, offset > size of mbuf chain")); - if (off < m->m_len) - break; - off -= m->m_len; - m = m->m_next; - } - while (len > 0) { - KASSERT(m != NULL, ("m_copydata, length > size of mbuf chain")); - count = min(m->m_len - off, len); - bcopy(mtod(m, caddr_t) + off, cp, count); - len -= count; - cp += count; - off = 0; - m = m->m_next; - } -} - -/* - * Concatenate mbuf chain n to m. - * Both chains must be of the same type (e.g. MT_DATA). - * Any m_pkthdr is not updated. - */ -void -m_cat(struct mbuf *m, struct mbuf *n) -{ - while (m->m_next) - m = m->m_next; - while (n) { - if (m->m_flags & M_EXT || - m->m_data + m->m_len + n->m_len >= &m->m_dat[MLEN]) { - /* just join the two chains */ - m->m_next = n; - return; - } - /* splat the data from one into the other */ - bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, - (u_int)n->m_len); - m->m_len += n->m_len; - n = m_free(n); - } -} - -u_int -m_length(struct mbuf *m0, struct mbuf **last) -{ - struct mbuf *m; - u_int len; - - len = 0; - for (m = m0; m != NULL; m = m->m_next) { - len += m->m_len; - if (m->m_next == NULL) - break; - } - if (last != NULL) - *last = m; - return (len); -} - -u_int -m_fixhdr(struct mbuf *m0) -{ - u_int len; - - len = m_length(m0, NULL); - m0->m_pkthdr.len = len; - return (len); -} - -/* - * Duplicate "from"'s mbuf pkthdr in "to". - * "from" must have M_PKTHDR set, and "to" must be empty. - * In particular, this does a deep copy of the packet tags. - */ -int -m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how) -{ - MBUF_CHECKSLEEP(how); - to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT); - if ((to->m_flags & M_EXT) == 0) - to->m_data = to->m_pktdat; - to->m_pkthdr = from->m_pkthdr; - SLIST_INIT(&to->m_pkthdr.tags); - return (m_tag_copy_chain(to, from, MBTOM(how))); -} - -/* - * Defragment a mbuf chain, returning the shortest possible - * chain of mbufs and clusters. If allocation fails and - * this cannot be completed, NULL will be returned, but - * the passed in chain will be unchanged. Upon success, - * the original chain will be freed, and the new chain - * will be returned. - * - * If a non-packet header is passed in, the original - * mbuf (chain?) will be returned unharmed. - */ -struct mbuf * -m_defrag(struct mbuf *m0, int how) -{ - struct mbuf *m_new = NULL, *m_final = NULL; - int progress = 0, length; - - MBUF_CHECKSLEEP(how); - if (!(m0->m_flags & M_PKTHDR)) - return (m0); - - m_fixhdr(m0); /* Needed sanity check */ - - if (m0->m_pkthdr.len > MHLEN) - m_final = m_getcl(how, MT_DATA, M_PKTHDR); - else - m_final = m_gethdr(how, MT_DATA); - - if (m_final == NULL) - goto nospace; - - if (m_dup_pkthdr(m_final, m0, how) == 0) - goto nospace; - - m_new = m_final; - - while (progress < m0->m_pkthdr.len) { - length = m0->m_pkthdr.len - progress; - if (length > MCLBYTES) - length = MCLBYTES; - - if (m_new == NULL) { - if (length > MLEN) - m_new = m_getcl(how, MT_DATA, 0); - else - m_new = m_get(how, MT_DATA); - if (m_new == NULL) - goto nospace; - } - - m_copydata(m0, progress, length, mtod(m_new, caddr_t)); - progress += length; - m_new->m_len = length; - if (m_new != m_final) - m_cat(m_final, m_new); - m_new = NULL; - } - - m_freem(m0); - m0 = m_final; - return (m0); -nospace: - if (m_final) - m_freem(m_final); - return (NULL); -} - -void -m_adj(struct mbuf *mp, int req_len) -{ - int len = req_len; - struct mbuf *m; - int count; - - if ((m = mp) == NULL) - return; - if (len >= 0) { - /* - * Trim from head. - */ - while (m != NULL && len > 0) { - if (m->m_len <= len) { - len -= m->m_len; - m->m_len = 0; - m = m->m_next; - } else { - m->m_len -= len; - m->m_data += len; - len = 0; - } - } - m = mp; - if (mp->m_flags & M_PKTHDR) - m->m_pkthdr.len -= (req_len - len); - } else { - /* - * Trim from tail. Scan the mbuf chain, - * calculating its length and finding the last mbuf. - * If the adjustment only affects this mbuf, then just - * adjust and return. Otherwise, rescan and truncate - * after the remaining size. - */ - len = -len; - count = 0; - for (;;) { - count += m->m_len; - if (m->m_next == (struct mbuf *)0) - break; - m = m->m_next; - } - if (m->m_len >= len) { - m->m_len -= len; - if (mp->m_flags & M_PKTHDR) - mp->m_pkthdr.len -= len; - return; - } - count -= len; - if (count < 0) - count = 0; - /* - * Correct length for chain is "count". - * Find the mbuf with last data, adjust its length, - * and toss data from remaining mbufs on chain. - */ - m = mp; - if (m->m_flags & M_PKTHDR) - m->m_pkthdr.len = count; - for (; m; m = m->m_next) { - if (m->m_len >= count) { - m->m_len = count; - if (m->m_next != NULL) { - m_freem(m->m_next); - m->m_next = NULL; - } - break; - } - count -= m->m_len; - } - } -} - -/* - * Rearange an mbuf chain so that len bytes are contiguous - * and in the data area of an mbuf (so that mtod and dtom - * will work for a structure of size len). Returns the resulting - * mbuf chain on success, frees it and returns null on failure. - * If there is room, it will add up to max_protohdr-len extra bytes to the - * contiguous region in an attempt to avoid being called next time. - */ -struct mbuf * -m_pullup(struct mbuf *n, int len) -{ - struct mbuf *m; - int count; - int space; - - /* - * If first mbuf has no cluster, and has room for len bytes - * without shifting current data, pullup into it, - * otherwise allocate a new mbuf to prepend to the chain. - */ - if ((n->m_flags & M_EXT) == 0 && - n->m_data + len < &n->m_dat[MLEN] && n->m_next) { - if (n->m_len >= len) - return (n); - m = n; - n = n->m_next; - len -= m->m_len; - } else { - if (len > MHLEN) - goto bad; - MGET(m, M_DONTWAIT, n->m_type); - if (m == NULL) - goto bad; - m->m_len = 0; - if (n->m_flags & M_PKTHDR) - M_MOVE_PKTHDR(m, n); - } - space = &m->m_dat[MLEN] - (m->m_data + m->m_len); - do { - count = min(min(max(len, max_protohdr), space), n->m_len); - bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len, - (u_int)count); - len -= count; - m->m_len += count; - n->m_len -= count; - space -= count; - if (n->m_len) - n->m_data += count; - else - n = m_free(n); - } while (len > 0 && n); - if (len > 0) { - (void) m_free(m); - goto bad; - } - m->m_next = n; - return (m); -bad: - m_freem(n); - return (NULL); -} - -/* - * Lesser-used path for M_PREPEND: - * allocate new mbuf to prepend to chain, - * copy junk along. - */ -struct mbuf * -m_prepend(struct mbuf *m, int len, int how) -{ - struct mbuf *mn; - - if (m->m_flags & M_PKTHDR) - MGETHDR(mn, how, m->m_type); - else - MGET(mn, how, m->m_type); - if (mn == NULL) { - m_freem(m); - return (NULL); - } - if (m->m_flags & M_PKTHDR) - M_MOVE_PKTHDR(mn, m); - mn->m_next = m; - m = mn; - if (len < MHLEN) - MH_ALIGN(m, len); - m->m_len = len; - return (m); -} - -/* - * "Move" mbuf pkthdr from "from" to "to". - * "from" must have M_PKTHDR set, and "to" must be empty. - */ -void -m_move_pkthdr(struct mbuf *to, struct mbuf *from) -{ -#ifdef MAC - /* - * XXXMAC: It could be this should also occur for non-MAC? - */ - if (to->m_flags & M_PKTHDR) - m_tag_delete_chain(to, NULL); -#endif - to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT); - if ((to->m_flags & M_EXT) == 0) - to->m_data = to->m_pktdat; - to->m_pkthdr = from->m_pkthdr; /* especially tags */ - SLIST_INIT(&from->m_pkthdr.tags); /* purge tags from src */ - from->m_flags &= ~M_PKTHDR; -} - -/* - * Routine to copy from device local memory into mbufs. - * Note that `off' argument is offset into first mbuf of target chain from - * which to begin copying the data to. - */ -struct mbuf * -m_devget(char *buf, int totlen, int off, struct ifnet *ifp, - void (*copy)(char *from, caddr_t to, u_int len)) -{ - struct mbuf *m; - struct mbuf *top = NULL, **mp = ⊤ - int len; - - if (off < 0 || off > MHLEN) - return (NULL); - - while (totlen > 0) { - if (top == NULL) { /* First one, must be PKTHDR */ - if (totlen + off >= MINCLSIZE) { - m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - len = MCLBYTES; - } else { - m = m_gethdr(M_DONTWAIT, MT_DATA); - len = MHLEN; - - /* Place initial small packet/header at end of mbuf */ - if (m && totlen + off + max_linkhdr <= MLEN) { - m->m_data += max_linkhdr; - len -= max_linkhdr; - } - } - if (m == NULL) - return NULL; - m->m_pkthdr.rcvif = ifp; - m->m_pkthdr.len = totlen; - } else { - if (totlen + off >= MINCLSIZE) { - m = m_getcl(M_DONTWAIT, MT_DATA, 0); - len = MCLBYTES; - } else { - m = m_get(M_DONTWAIT, MT_DATA); - len = MLEN; - } - if (m == NULL) { - m_freem(top); - return NULL; - } - } - if (off) { - m->m_data += off; - len -= off; - off = 0; - } - m->m_len = len = min(totlen, len); - if (copy) - copy(buf, mtod(m, caddr_t), (u_int)len); - else - bcopy(buf, mtod(m, caddr_t), (u_int)len); - buf += len; - *mp = m; - mp = &m->m_next; - totlen -= len; - } - return (top); -} - -/* - * Copy data from a buffer back into the indicated mbuf chain, - * starting "off" bytes from the beginning, extending the mbuf - * chain if necessary. - */ -void -m_copyback(struct mbuf *m0, int off, int len, caddr_t cp) -{ - int mlen; - struct mbuf *m = m0, *n; - int totlen = 0; - - if (m0 == NULL) - return; - while (off > (mlen = m->m_len)) { - off -= mlen; - totlen += mlen; - if (m->m_next == NULL) { - n = m_get(M_DONTWAIT, m->m_type); - if (n == NULL) - goto out; - bzero(mtod(n, caddr_t), MLEN); - n->m_len = min(MLEN, len + off); - m->m_next = n; - } - m = m->m_next; - } - while (len > 0) { - mlen = min (m->m_len - off, len); - bcopy(cp, off + mtod(m, caddr_t), (u_int)mlen); - cp += mlen; - len -= mlen; - mlen += off; - off = 0; - totlen += mlen; - if (len == 0) - break; - if (m->m_next == NULL) { - n = m_get(M_DONTWAIT, m->m_type); - if (n == NULL) - break; - n->m_len = min(MLEN, len); - m->m_next = n; - } - m = m->m_next; - } -out: if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen)) - m->m_pkthdr.len = totlen; -} - -/* - * Append the specified data to the indicated mbuf chain, - * Extend the mbuf chain if the new data does not fit in - * existing space. - * - * Return 1 if able to complete the job; otherwise 0. - */ -int -m_append(struct mbuf *m0, int len, c_caddr_t cp) -{ - struct mbuf *m, *n; - int remainder, space; - - for (m = m0; m->m_next != NULL; m = m->m_next) - ; - remainder = len; - space = M_TRAILINGSPACE(m); - if (space > 0) { - /* - * Copy into available space. - */ - if (space > remainder) - space = remainder; - bcopy(cp, mtod(m, caddr_t) + m->m_len, space); - m->m_len += space; - cp += space, remainder -= space; - } - while (remainder > 0) { - /* - * Allocate a new mbuf; could check space - * and allocate a cluster instead. - */ - n = m_get(M_DONTWAIT, m->m_type); - if (n == NULL) - break; - n->m_len = min(MLEN, remainder); - bcopy(cp, mtod(n, caddr_t), n->m_len); - cp += n->m_len, remainder -= n->m_len; - m->m_next = n; - m = n; - } - if (m0->m_flags & M_PKTHDR) - m0->m_pkthdr.len += len - remainder; - return (remainder == 0); -} - -/* - * Defragment an mbuf chain, returning at most maxfrags separate - * mbufs+clusters. If this is not possible NULL is returned and - * the original mbuf chain is left in it's present (potentially - * modified) state. We use two techniques: collapsing consecutive - * mbufs and replacing consecutive mbufs by a cluster. - * - * NB: this should really be named m_defrag but that name is taken - */ -struct mbuf * -m_collapse(struct mbuf *m0, int how, int maxfrags) -{ - struct mbuf *m, *n, *n2, **prev; - u_int curfrags; - - /* - * Calculate the current number of frags. - */ - curfrags = 0; - for (m = m0; m != NULL; m = m->m_next) - curfrags++; - /* - * First, try to collapse mbufs. Note that we always collapse - * towards the front so we don't need to deal with moving the - * pkthdr. This may be suboptimal if the first mbuf has much - * less data than the following. - */ - m = m0; -again: - for (;;) { - n = m->m_next; - if (n == NULL) - break; - if ((m->m_flags & M_RDONLY) == 0 && - n->m_len < M_TRAILINGSPACE(m)) { - bcopy(mtod(n, void *), mtod(m, char *) + m->m_len, - n->m_len); - m->m_len += n->m_len; - m->m_next = n->m_next; - m_free(n); - if (--curfrags <= maxfrags) - return m0; - } else - m = n; - } - KASSERT(maxfrags > 1, - ("maxfrags %u, but normal collapse failed", maxfrags)); - /* - * Collapse consecutive mbufs to a cluster. - */ - prev = &m0->m_next; /* NB: not the first mbuf */ - while ((n = *prev) != NULL) { - if ((n2 = n->m_next) != NULL && - n->m_len + n2->m_len < MCLBYTES) { - m = m_getcl(how, MT_DATA, 0); - if (m == NULL) - goto bad; - bcopy(mtod(n, void *), mtod(m, void *), n->m_len); - bcopy(mtod(n2, void *), mtod(m, char *) + n->m_len, - n2->m_len); - m->m_len = n->m_len + n2->m_len; - m->m_next = n2->m_next; - *prev = m; - m_free(n); - m_free(n2); - if (--curfrags <= maxfrags) /* +1 cl -2 mbufs */ - return m0; - /* - * Still not there, try the normal collapse - * again before we allocate another cluster. - */ - goto again; - } - prev = &n->m_next; - } - /* - * No place where we can collapse to a cluster; punt. - * This can occur if, for example, you request 2 frags - * but the packet requires that both be clusters (we - * never reallocate the first mbuf to avoid moving the - * packet header). - */ -bad: - return NULL; -} - -/* - * Attach the the cluster from *m to *n, set up m_ext in *n - * and bump the refcount of the cluster. - */ -static void -mb_dupcl(struct mbuf *n, struct mbuf *m) -{ - KASSERT((m->m_flags & M_EXT) == M_EXT, ("%s: M_EXT not set", __func__)); - KASSERT((n->m_flags & M_EXT) == 0, ("%s: M_EXT set", __func__)); - - n->m_ext.ext_buf = m->m_ext.ext_buf; - n->m_ext.ext_size = m->m_ext.ext_size; - n->m_ext.ext_type = m->m_ext.ext_type; - n->m_flags |= M_EXT; -} - -/* - * Partition an mbuf chain in two pieces, returning the tail -- - * all but the first len0 bytes. In case of failure, it returns NULL and - * attempts to restore the chain to its original state. - * - * Note that the resulting mbufs might be read-only, because the new - * mbuf can end up sharing an mbuf cluster with the original mbuf if - * the "breaking point" happens to lie within a cluster mbuf. Use the - * M_WRITABLE() macro to check for this case. - */ -struct mbuf * -m_split(struct mbuf *m0, int len0, int wait) -{ - struct mbuf *m, *n; - u_int len = len0, remain; - - MBUF_CHECKSLEEP(wait); - for (m = m0; m && len > m->m_len; m = m->m_next) - len -= m->m_len; - if (m == NULL) - return (NULL); - remain = m->m_len - len; - if (m0->m_flags & M_PKTHDR) { - MGETHDR(n, wait, m0->m_type); - if (n == NULL) - return (NULL); - n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif; - n->m_pkthdr.len = m0->m_pkthdr.len - len0; - m0->m_pkthdr.len = len0; - if (m->m_flags & M_EXT) - goto extpacket; - if (remain > MHLEN) { - /* m can't be the lead packet */ - MH_ALIGN(n, 0); - n->m_next = m_split(m, len, wait); - if (n->m_next == NULL) { - (void) m_free(n); - return (NULL); - } else { - n->m_len = 0; - return (n); - } - } else - MH_ALIGN(n, remain); - } else if (remain == 0) { - n = m->m_next; - m->m_next = NULL; - return (n); - } else { - MGET(n, wait, m->m_type); - if (n == NULL) - return (NULL); - M_ALIGN(n, remain); - } -extpacket: - if (m->m_flags & M_EXT) { - n->m_data = m->m_data + len; - mb_dupcl(n, m); - } else { - bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain); - } - n->m_len = remain; - m->m_len = len; - n->m_next = m->m_next; - m->m_next = NULL; - return (n); -} - -/* - * Copy a packet header mbuf chain into a completely new chain, including - * copying any mbuf clusters. Use this instead of m_copypacket() when - * you need a writable copy of an mbuf chain. - */ -struct mbuf * -m_dup(struct mbuf *m, int how) -{ - struct mbuf **p, *top = NULL; - int remain, moff, nsize; - - MBUF_CHECKSLEEP(how); - /* Sanity check */ - if (m == NULL) - return (NULL); - M_ASSERTPKTHDR(m); - - /* While there's more data, get a new mbuf, tack it on, and fill it */ - remain = m->m_pkthdr.len; - moff = 0; - p = ⊤ - while (remain > 0 || top == NULL) { /* allow m->m_pkthdr.len == 0 */ - struct mbuf *n; - - /* Get the next new mbuf */ - if (remain >= MINCLSIZE) { - n = m_getcl(how, m->m_type, 0); - nsize = MCLBYTES; - } else { - n = m_get(how, m->m_type); - nsize = MLEN; - } - if (n == NULL) - goto nospace; - - if (top == NULL) { /* First one, must be PKTHDR */ - if (!m_dup_pkthdr(n, m, how)) { - m_free(n); - goto nospace; - } - if ((n->m_flags & M_EXT) == 0) - nsize = MHLEN; - } - n->m_len = 0; - - /* Link it into the new chain */ - *p = n; - p = &n->m_next; - - /* Copy data from original mbuf(s) into new mbuf */ - while (n->m_len < nsize && m != NULL) { - int chunk = min(nsize - n->m_len, m->m_len - moff); - - bcopy(m->m_data + moff, n->m_data + n->m_len, chunk); - moff += chunk; - n->m_len += chunk; - remain -= chunk; - if (moff == m->m_len) { - m = m->m_next; - moff = 0; - } - } - - /* Check correct total mbuf length */ - KASSERT((remain > 0 && m != NULL) || (remain == 0 && m == NULL), - ("%s: bogus m_pkthdr.len", __func__)); - } - return (top); - -nospace: - m_freem(top); - return (NULL); -} - -/* - * Create a writable copy of the mbuf chain. While doing this - * we compact the chain with a goal of producing a chain with - * at most two mbufs. The second mbuf in this chain is likely - * to be a cluster. The primary purpose of this work is to create - * a writable packet for encryption, compression, etc. The - * secondary goal is to linearize the data so the data can be - * passed to crypto hardware in the most efficient manner possible. - */ -struct mbuf * -m_unshare(struct mbuf *m0, int how) -{ - struct mbuf *m, *mprev; - struct mbuf *n, *mfirst, *mlast; - int len, off; - - mprev = NULL; - for (m = m0; m != NULL; m = mprev->m_next) { - /* - * Regular mbufs are ignored unless there's a cluster - * in front of it that we can use to coalesce. We do - * the latter mainly so later clusters can be coalesced - * also w/o having to handle them specially (i.e. convert - * mbuf+cluster -> cluster). This optimization is heavily - * influenced by the assumption that we're running over - * Ethernet where MCLBYTES is large enough that the max - * packet size will permit lots of coalescing into a - * single cluster. This in turn permits efficient - * crypto operations, especially when using hardware. - */ - if ((m->m_flags & M_EXT) == 0) { - if (mprev && (mprev->m_flags & M_EXT) && - m->m_len <= M_TRAILINGSPACE(mprev)) { - /* XXX: this ignores mbuf types */ - memcpy(mtod(mprev, caddr_t) + mprev->m_len, - mtod(m, caddr_t), m->m_len); - mprev->m_len += m->m_len; - mprev->m_next = m->m_next; /* unlink from chain */ - m_free(m); /* reclaim mbuf */ -#if 0 - newipsecstat.ips_mbcoalesced++; -#endif - } else { - mprev = m; - } - continue; - } - /* - * Writable mbufs are left alone (for now). - */ - if (M_WRITABLE(m)) { - mprev = m; - continue; - } - - /* - * Not writable, replace with a copy or coalesce with - * the previous mbuf if possible (since we have to copy - * it anyway, we try to reduce the number of mbufs and - * clusters so that future work is easier). - */ - KASSERT(m->m_flags & M_EXT, ("m_flags 0x%x", m->m_flags)); - /* NB: we only coalesce into a cluster or larger */ - if (mprev != NULL && (mprev->m_flags & M_EXT) && - m->m_len <= M_TRAILINGSPACE(mprev)) { - /* XXX: this ignores mbuf types */ - memcpy(mtod(mprev, caddr_t) + mprev->m_len, - mtod(m, caddr_t), m->m_len); - mprev->m_len += m->m_len; - mprev->m_next = m->m_next; /* unlink from chain */ - m_free(m); /* reclaim mbuf */ -#if 0 - newipsecstat.ips_clcoalesced++; -#endif - continue; - } - - /* - * Allocate new space to hold the copy... - */ - /* XXX why can M_PKTHDR be set past the first mbuf? */ - if (mprev == NULL && (m->m_flags & M_PKTHDR)) { - /* - * NB: if a packet header is present we must - * allocate the mbuf separately from any cluster - * because M_MOVE_PKTHDR will smash the data - * pointer and drop the M_EXT marker. - */ - MGETHDR(n, how, m->m_type); - if (n == NULL) { - m_freem(m0); - return (NULL); - } - M_MOVE_PKTHDR(n, m); - MCLGET(n, how); - if ((n->m_flags & M_EXT) == 0) { - m_free(n); - m_freem(m0); - return (NULL); - } - } else { - n = m_getcl(how, m->m_type, m->m_flags); - if (n == NULL) { - m_freem(m0); - return (NULL); - } - } - /* - * ... and copy the data. We deal with jumbo mbufs - * (i.e. m_len > MCLBYTES) by splitting them into - * clusters. We could just malloc a buffer and make - * it external but too many device drivers don't know - * how to break up the non-contiguous memory when - * doing DMA. - */ - len = m->m_len; - off = 0; - mfirst = n; - mlast = NULL; - for (;;) { - int cc = min(len, MCLBYTES); - memcpy(mtod(n, caddr_t), mtod(m, caddr_t) + off, cc); - n->m_len = cc; - if (mlast != NULL) - mlast->m_next = n; - mlast = n; -#if 0 - newipsecstat.ips_clcopied++; -#endif - - len -= cc; - if (len <= 0) - break; - off += cc; - - n = m_getcl(how, m->m_type, m->m_flags); - if (n == NULL) { - m_freem(mfirst); - m_freem(m0); - return (NULL); - } - } - n->m_next = m->m_next; - if (mprev == NULL) - m0 = mfirst; /* new head of chain */ - else - mprev->m_next = mfirst; /* replace old mbuf */ - m_free(m); /* release old mbuf */ - mprev = mfirst; - } - return (m0); -} - -/* - * Set the m_data pointer of a newly-allocated mbuf - * to place an object of the specified size at the - * end of the mbuf, longword aligned. - */ -void -m_align(struct mbuf *m, int len) -{ - int adjust; - - if (m->m_flags & M_EXT) - adjust = m->m_ext.ext_size - len; - else if (m->m_flags & M_PKTHDR) - adjust = MHLEN - len; - else - adjust = MLEN - len; - m->m_data += adjust &~ (sizeof(long)-1); -} - -/* - * Copy an entire packet, including header (which must be present). - * An optimization of the common case `m_copym(m, 0, M_COPYALL, how)'. - * Note that the copy is read-only, because clusters are not copied, - * only their reference counts are incremented. - * Preserve alignment of the first mbuf so if the creator has left - * some room at the beginning (e.g. for inserting protocol headers) - * the copies still have the room available. - */ -struct mbuf * -m_copypacket(struct mbuf *m, int how) -{ - struct mbuf *top, *n, *o; - - MBUF_CHECKSLEEP(how); - MGET(n, how, m->m_type); - top = n; - if (n == NULL) - goto nospace; - - if (!m_dup_pkthdr(n, m, how)) - goto nospace; - n->m_len = m->m_len; - if (m->m_flags & M_EXT) { - n->m_data = m->m_data; - mb_dupcl(n, m); - } else { - n->m_data = n->m_pktdat + (m->m_data - m->m_pktdat ); - bcopy(mtod(m, char *), mtod(n, char *), n->m_len); - } - - m = m->m_next; - while (m) { - MGET(o, how, m->m_type); - if (o == NULL) - goto nospace; - - n->m_next = o; - n = n->m_next; - - n->m_len = m->m_len; - if (m->m_flags & M_EXT) { - n->m_data = m->m_data; - mb_dupcl(n, m); - } else { - bcopy(mtod(m, char *), mtod(n, char *), n->m_len); - } - - m = m->m_next; - } - return top; -nospace: - m_freem(top); - return (NULL); -} diff --git a/src/libs/compat/freebsd_network/fbsd_mbuf2.c b/src/libs/compat/freebsd_network/fbsd_mbuf2.c deleted file mode 100644 index 3f7661c26c..0000000000 --- a/src/libs/compat/freebsd_network/fbsd_mbuf2.c +++ /dev/null @@ -1,452 +0,0 @@ -/* $KAME: uipc_mbuf2.c,v 1.31 2001/11/28 11:08:53 itojun Exp $ */ -/* $NetBSD: uipc_mbuf.c,v 1.40 1999/04/01 00:23:25 thorpej Exp $ */ - -/*- - * Copyright (C) 1999 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/*- - * Copyright (c) 1982, 1986, 1988, 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)uipc_mbuf.c 8.4 (Berkeley) 2/14/95 - */ -#include -__FBSDID("$FreeBSD$"); - -/*#define PULLDOWN_DEBUG*/ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define malloc(size, tag, flags) kernel_malloc(size, tag, flags) -#define free(pointer, tag) kernel_free(pointer, tag) - -/* can't call it m_dup(), as freebsd[34] uses m_dup() with different arg */ -static struct mbuf *m_dup1(struct mbuf *, int, int, int); - -/* - * ensure that [off, off + len) is contiguous on the mbuf chain "m". - * packet chain before "off" is kept untouched. - * if offp == NULL, the target will start at on resulting chain. - * if offp != NULL, the target will start at on resulting chain. - * - * on error return (NULL return value), original "m" will be freed. - * - * XXX: M_TRAILINGSPACE/M_LEADINGSPACE only permitted on writable ext_buf. - */ -struct mbuf * -m_pulldown(struct mbuf *m, int off, int len, int *offp) -{ - struct mbuf *n, *o; - int hlen, tlen, olen; - int writable; - - /* check invalid arguments. */ - if (m == NULL) - panic("m == NULL in m_pulldown()"); - if (len > MCLBYTES) { - m_freem(m); - return NULL; /* impossible */ - } - -#ifdef PULLDOWN_DEBUG - { - struct mbuf *t; - printf("before:"); - for (t = m; t; t = t->m_next) - printf(" %d", t->m_len); - printf("\n"); - } -#endif - n = m; - while (n != NULL && off > 0) { - if (n->m_len > off) - break; - off -= n->m_len; - n = n->m_next; - } - /* be sure to point non-empty mbuf */ - while (n != NULL && n->m_len == 0) - n = n->m_next; - if (!n) { - m_freem(m); - return NULL; /* mbuf chain too short */ - } - - /* - * XXX: This code is flawed because it considers a "writable" mbuf - * data region to require all of the following: - * (i) mbuf _has_ to have M_EXT set; if it is just a regular - * mbuf, it is still not considered "writable." - * (ii) since mbuf has M_EXT, the ext_type _has_ to be - * EXT_CLUSTER. Anything else makes it non-writable. - * (iii) M_WRITABLE() must evaluate true. - * Ideally, the requirement should only be (iii). - * - * If we're writable, we're sure we're writable, because the ref. count - * cannot increase from 1, as that would require posession of mbuf - * n by someone else (which is impossible). However, if we're _not_ - * writable, we may eventually become writable )if the ref. count drops - * to 1), but we'll fail to notice it unless we re-evaluate - * M_WRITABLE(). For now, we only evaluate once at the beginning and - * live with this. - */ - /* - * XXX: This is dumb. If we're just a regular mbuf with no M_EXT, - * then we're not "writable," according to this code. - */ - writable = 0; - if ((n->m_flags & M_EXT) == 0 || - (n->m_ext.ext_type == EXT_CLUSTER && M_WRITABLE(n))) - writable = 1; - - /* - * the target data is on . - * if we got enough data on the mbuf "n", we're done. - */ - if ((off == 0 || offp) && len <= n->m_len - off && writable) - goto ok; - - /* - * when len <= n->m_len - off and off != 0, it is a special case. - * len bytes from sits in single mbuf, but the caller does - * not like the starting position (off). - * chop the current mbuf into two pieces, set off to 0. - */ - if (len <= n->m_len - off) { - o = m_dup1(n, off, n->m_len - off, M_DONTWAIT); - if (o == NULL) { - m_freem(m); - return NULL; /* ENOBUFS */ - } - n->m_len = off; - o->m_next = n->m_next; - n->m_next = o; - n = n->m_next; - off = 0; - goto ok; - } - - /* - * we need to take hlen from and tlen from m_next, 0>, - * and construct contiguous mbuf with m_len == len. - * note that hlen + tlen == len, and tlen > 0. - */ - hlen = n->m_len - off; - tlen = len - hlen; - - /* - * ensure that we have enough trailing data on mbuf chain. - * if not, we can do nothing about the chain. - */ - olen = 0; - for (o = n->m_next; o != NULL; o = o->m_next) - olen += o->m_len; - if (hlen + olen < len) { - m_freem(m); - return NULL; /* mbuf chain too short */ - } - - /* - * easy cases first. - * we need to use m_copydata() to get data from m_next, 0>. - */ - if ((off == 0 || offp) && M_TRAILINGSPACE(n) >= tlen - && writable) { - m_copydata(n->m_next, 0, tlen, mtod(n, caddr_t) + n->m_len); - n->m_len += tlen; - m_adj(n->m_next, tlen); - goto ok; - } - if ((off == 0 || offp) && M_LEADINGSPACE(n->m_next) >= hlen - && writable) { - n->m_next->m_data -= hlen; - n->m_next->m_len += hlen; - bcopy(mtod(n, caddr_t) + off, mtod(n->m_next, caddr_t), hlen); - n->m_len -= hlen; - n = n->m_next; - off = 0; - goto ok; - } - - /* - * now, we need to do the hard way. don't m_copy as there's no room - * on both end. - */ - if (len > MLEN) - o = m_getcl(M_DONTWAIT, m->m_type, 0); - else - o = m_get(M_DONTWAIT, m->m_type); - if (!o) { - m_freem(m); - return NULL; /* ENOBUFS */ - } - /* get hlen from into */ - o->m_len = hlen; - bcopy(mtod(n, caddr_t) + off, mtod(o, caddr_t), hlen); - n->m_len -= hlen; - /* get tlen from m_next, 0> into */ - m_copydata(n->m_next, 0, tlen, mtod(o, caddr_t) + o->m_len); - o->m_len += tlen; - m_adj(n->m_next, tlen); - o->m_next = n->m_next; - n->m_next = o; - n = o; - off = 0; - -ok: -#ifdef PULLDOWN_DEBUG - { - struct mbuf *t; - printf("after:"); - for (t = m; t; t = t->m_next) - printf("%c%d", t == n ? '*' : ' ', t->m_len); - printf(" (off=%d)\n", off); - } -#endif - if (offp) - *offp = off; - return n; -} - -static struct mbuf * -m_dup1(struct mbuf *m, int off, int len, int wait) -{ - struct mbuf *n; - int copyhdr; - - if (len > MCLBYTES) - return NULL; - if (off == 0 && (m->m_flags & M_PKTHDR) != 0) - copyhdr = 1; - else - copyhdr = 0; - if (len >= MINCLSIZE) { - if (copyhdr == 1) - n = m_getcl(wait, m->m_type, M_PKTHDR); - else - n = m_getcl(wait, m->m_type, 0); - } else { - if (copyhdr == 1) - n = m_gethdr(wait, m->m_type); - else - n = m_get(wait, m->m_type); - } - if (!n) - return NULL; /* ENOBUFS */ - - if (copyhdr && !m_dup_pkthdr(n, m, wait)) { - m_free(n); - return NULL; - } - m_copydata(m, off, len, mtod(n, caddr_t)); - n->m_len = len; - return n; -} - -/* Free a packet tag. */ -void -m_tag_free_default(struct m_tag *t) -{ -#ifdef MAC - if (t->m_tag_id == PACKET_TAG_MACLABEL) - mac_mbuf_tag_destroy(t); -#endif - free(t, M_PACKET_TAGS); -} - -/* Get a packet tag structure along with specified data following. */ -struct m_tag * -m_tag_alloc(u_int32_t cookie, int type, int len, int wait) -{ - struct m_tag *t; - - MBUF_CHECKSLEEP(wait); - if (len < 0) - return NULL; - t = malloc(len + sizeof(struct m_tag), M_PACKET_TAGS, wait); - if (t == NULL) - return NULL; - m_tag_setup(t, cookie, type, len); - t->m_tag_free = m_tag_free_default; - return t; -} - -/* Unlink and free a packet tag. */ -void -m_tag_delete(struct mbuf *m, struct m_tag *t) -{ - - KASSERT(m && t, ("m_tag_delete: null argument, m %p t %p", m, t)); - m_tag_unlink(m, t); - m_tag_free(t); -} - -/* Unlink and free a packet tag chain, starting from given tag. */ -void -m_tag_delete_chain(struct mbuf *m, struct m_tag *t) -{ - struct m_tag *p, *q; - - KASSERT(m, ("m_tag_delete_chain: null mbuf")); - if (t != NULL) - p = t; - else - p = SLIST_FIRST(&m->m_pkthdr.tags); - if (p == NULL) - return; - while ((q = SLIST_NEXT(p, m_tag_link)) != NULL) - m_tag_delete(m, q); - m_tag_delete(m, p); -} - -/* - * Strip off all tags that would normally vanish when - * passing through a network interface. Only persistent - * tags will exist after this; these are expected to remain - * so long as the mbuf chain exists, regardless of the - * path the mbufs take. - */ -void -m_tag_delete_nonpersistent(struct mbuf *m) -{ - struct m_tag *p, *q; - - SLIST_FOREACH_SAFE(p, &m->m_pkthdr.tags, m_tag_link, q) - if ((p->m_tag_id & MTAG_PERSISTENT) == 0) - m_tag_delete(m, p); -} - -/* Find a tag, starting from a given position. */ -struct m_tag * -m_tag_locate(struct mbuf *m, u_int32_t cookie, int type, struct m_tag *t) -{ - struct m_tag *p; - - KASSERT(m, ("m_tag_locate: null mbuf")); - if (t == NULL) - p = SLIST_FIRST(&m->m_pkthdr.tags); - else - p = SLIST_NEXT(t, m_tag_link); - while (p != NULL) { - if (p->m_tag_cookie == cookie && p->m_tag_id == type) - return p; - p = SLIST_NEXT(p, m_tag_link); - } - return NULL; -} - -/* Copy a single tag. */ -struct m_tag * -m_tag_copy(struct m_tag *t, int how) -{ - struct m_tag *p; - - MBUF_CHECKSLEEP(how); - KASSERT(t, ("m_tag_copy: null tag")); - p = m_tag_alloc(t->m_tag_cookie, t->m_tag_id, t->m_tag_len, how); - if (p == NULL) - return (NULL); -#ifdef MAC - /* - * XXXMAC: we should probably pass off the initialization, and - * copying here? can we hide that PACKET_TAG_MACLABEL is - * special from the mbuf code? - */ - if (t->m_tag_id == PACKET_TAG_MACLABEL) { - if (mac_mbuf_tag_init(p, how) != 0) { - m_tag_free(p); - return (NULL); - } - mac_mbuf_tag_copy(t, p); - } else -#endif - bcopy(t + 1, p + 1, t->m_tag_len); /* Copy the data */ - return p; -} - -/* - * Copy two tag chains. The destination mbuf (to) loses any attached - * tags even if the operation fails. This should not be a problem, as - * m_tag_copy_chain() is typically called with a newly-allocated - * destination mbuf. - */ -int -m_tag_copy_chain(struct mbuf *to, struct mbuf *from, int how) -{ - struct m_tag *p, *t, *tprev = NULL; - - MBUF_CHECKSLEEP(how); - KASSERT(to && from, - ("m_tag_copy_chain: null argument, to %p from %p", to, from)); - m_tag_delete_chain(to, NULL); - SLIST_FOREACH(p, &from->m_pkthdr.tags, m_tag_link) { - t = m_tag_copy(p, how); - if (t == NULL) { - m_tag_delete_chain(to, NULL); - return 0; - } - if (tprev == NULL) - SLIST_INSERT_HEAD(&to->m_pkthdr.tags, t, m_tag_link); - else - SLIST_INSERT_AFTER(tprev, t, m_tag_link); - tprev = t; - } - return 1; -} diff --git a/src/libs/compat/freebsd_network/fbsd_mii.c b/src/libs/compat/freebsd_network/fbsd_mii.c deleted file mode 100644 index f9950af5cf..0000000000 --- a/src/libs/compat/freebsd_network/fbsd_mii.c +++ /dev/null @@ -1,578 +0,0 @@ -/* $NetBSD: mii.c,v 1.12 1999/08/03 19:41:49 drochner Exp $ */ - -/*- - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifdef __HAIKU__ -#include "device.h" - -#define malloc(size, tag, flags) kernel_malloc(size, tag, flags) -#define free(pointer, tag) kernel_free(pointer, tag) -#endif - -#include -__FBSDID("$FreeBSD$"); - -/* - * MII bus layer, glues MII-capable network interface drivers to sharable - * PHY drivers. This exports an interface compatible with BSD/OS 3.0's, - * plus some NetBSD extensions. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -MODULE_VERSION(miibus, 1); - -#include "miibus_if.h" - -static int miibus_print_child(device_t dev, device_t child); -static int miibus_read_ivar(device_t dev, device_t child, int which, - uintptr_t *result); -static int miibus_child_location_str(device_t bus, device_t child, char *buf, - size_t buflen); -static int miibus_child_pnpinfo_str(device_t bus, device_t child, char *buf, - size_t buflen); -static int miibus_readreg(device_t, int, int); -static int miibus_writereg(device_t, int, int, int); -static void miibus_statchg(device_t); -static void miibus_linkchg(device_t); -static void miibus_mediainit(device_t); -static unsigned char mii_bitreverse(unsigned char x); - -static device_method_t miibus_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, miibus_probe), - DEVMETHOD(device_attach, miibus_attach), - DEVMETHOD(device_detach, miibus_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - /* bus interface */ - DEVMETHOD(bus_print_child, miibus_print_child), - DEVMETHOD(bus_read_ivar, miibus_read_ivar), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - DEVMETHOD(bus_child_pnpinfo_str, miibus_child_pnpinfo_str), - DEVMETHOD(bus_child_location_str, miibus_child_location_str), - - /* MII interface */ - DEVMETHOD(miibus_readreg, miibus_readreg), - DEVMETHOD(miibus_writereg, miibus_writereg), - DEVMETHOD(miibus_statchg, miibus_statchg), - DEVMETHOD(miibus_linkchg, miibus_linkchg), - DEVMETHOD(miibus_mediainit, miibus_mediainit), - - { 0, 0 } -}; - -devclass_t miibus_devclass; - -driver_t miibus_driver = { - "miibus", - miibus_methods, - sizeof(struct mii_data) -}; - -struct miibus_ivars { - struct ifnet *ifp; - ifm_change_cb_t ifmedia_upd; - ifm_stat_cb_t ifmedia_sts; - int mii_flags; -}; - -int -miibus_probe(device_t dev) -{ - - device_set_desc(dev, "MII bus"); - - return (BUS_PROBE_SPECIFIC); -} - -int -miibus_attach(device_t dev) -{ - struct miibus_ivars *ivars; - struct mii_attach_args *ma; - struct mii_data *mii; - device_t *children; - int i, nchildren; - - mii = device_get_softc(dev); - nchildren = 0; - if (device_get_children(dev, &children, &nchildren) == 0) { - for (i = 0; i < nchildren; i++) { - ma = device_get_ivars(children[i]); - ma->mii_data = mii; - } - free(children, M_TEMP); - } - if (nchildren == 0) { - device_printf(dev, "cannot get children\n"); - return (ENXIO); - } - ivars = device_get_ivars(dev); - ifmedia_init(&mii->mii_media, IFM_IMASK, ivars->ifmedia_upd, - ivars->ifmedia_sts); - mii->mii_ifp = ivars->ifp; - mii->mii_ifp->if_capabilities |= IFCAP_LINKSTATE; - mii->mii_ifp->if_capenable |= IFCAP_LINKSTATE; - LIST_INIT(&mii->mii_phys); - - return (bus_generic_attach(dev)); -} - -int -miibus_detach(device_t dev) -{ - struct mii_data *mii; - - bus_generic_detach(dev); - mii = device_get_softc(dev); - ifmedia_removeall(&mii->mii_media); - mii->mii_ifp = NULL; - - return (0); -} - -static int -miibus_print_child(device_t dev, device_t child) -{ - struct mii_attach_args *ma; - int retval; - - ma = device_get_ivars(child); - retval = bus_print_child_header(dev, child); - retval += printf(" PHY %d", ma->mii_phyno); - retval += bus_print_child_footer(dev, child); - - return (retval); -} - -static int -miibus_read_ivar(device_t dev, device_t child __unused, int which, - uintptr_t *result) -{ - struct miibus_ivars *ivars; - - /* - * NB: this uses the instance variables of the miibus rather than - * its PHY children. - */ - ivars = device_get_ivars(dev); - switch (which) { - case MIIBUS_IVAR_FLAGS: - *result = ivars->mii_flags; - break; - default: - return (ENOENT); - } - return (0); -} - -static int -miibus_child_pnpinfo_str(device_t bus __unused, device_t child, char *buf, - size_t buflen) -{ - struct mii_attach_args *ma; - - ma = device_get_ivars(child); - snprintf(buf, buflen, "oui=0x%x model=0x%x rev=0x%x", - MII_OUI(ma->mii_id1, ma->mii_id2), - MII_MODEL(ma->mii_id2), MII_REV(ma->mii_id2)); - return (0); -} - -static int -miibus_child_location_str(device_t bus __unused, device_t child, char *buf, - size_t buflen) -{ - struct mii_attach_args *ma; - - ma = device_get_ivars(child); - snprintf(buf, buflen, "phyno=%d", ma->mii_phyno); - return (0); -} - -static int -miibus_readreg(device_t dev, int phy, int reg) -{ - device_t parent; - - parent = device_get_parent(dev); - return (MIIBUS_READREG(parent, phy, reg)); -} - -static int -miibus_writereg(device_t dev, int phy, int reg, int data) -{ - device_t parent; - - parent = device_get_parent(dev); - return (MIIBUS_WRITEREG(parent, phy, reg, data)); -} - -static void -miibus_statchg(device_t dev) -{ - device_t parent; - struct mii_data *mii; - - parent = device_get_parent(dev); - MIIBUS_STATCHG(parent); - - mii = device_get_softc(dev); - mii->mii_ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active); -} - -static void -miibus_linkchg(device_t dev) -{ - struct mii_data *mii; - device_t parent; - int link_state; - - parent = device_get_parent(dev); - MIIBUS_LINKCHG(parent); - - mii = device_get_softc(dev); - - if (mii->mii_media_status & IFM_AVALID) { - if (mii->mii_media_status & IFM_ACTIVE) - link_state = LINK_STATE_UP; - else - link_state = LINK_STATE_DOWN; - } else - link_state = LINK_STATE_UNKNOWN; - if_link_state_change(mii->mii_ifp, link_state); -} - -static void -miibus_mediainit(device_t dev) -{ - struct mii_data *mii; - struct ifmedia_entry *m; - int media = 0; - - /* Poke the parent in case it has any media of its own to add. */ - MIIBUS_MEDIAINIT(device_get_parent(dev)); - - mii = device_get_softc(dev); - LIST_FOREACH(m, &mii->mii_media.ifm_list, ifm_list) { - media = m->ifm_media; - if (media == (IFM_ETHER | IFM_AUTO)) - break; - } - - ifmedia_set(&mii->mii_media, media); -} - -/* - * Helper function used by network interface drivers, attaches the miibus and - * the PHYs to the network interface driver parent. - */ -int -mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp, - ifm_change_cb_t ifmedia_upd, ifm_stat_cb_t ifmedia_sts, int capmask, - int phyloc, int offloc, int flags) -{ - struct miibus_ivars *ivars; - struct mii_attach_args ma, *args; - device_t *children, phy; - int bmsr, first, i, nchildren, offset, phymax, phymin, rv; - - if (phyloc != MII_PHY_ANY && offloc != MII_OFFSET_ANY) { - printf("%s: phyloc and offloc specified\n", __func__); - return (EINVAL); - } - - if (offloc != MII_OFFSET_ANY && (offloc < 0 || offloc >= MII_NPHY)) { - printf("%s: ivalid offloc %d\n", __func__, offloc); - return (EINVAL); - } - - if (phyloc == MII_PHY_ANY) { - phymin = 0; - phymax = MII_NPHY - 1; - } else { - if (phyloc < 0 || phyloc >= MII_NPHY) { - printf("%s: ivalid phyloc %d\n", __func__, phyloc); - return (EINVAL); - } - phymin = phymax = phyloc; - } - - first = 0; - if (*miibus == NULL) { - first = 1; - ivars = malloc(sizeof(*ivars), M_DEVBUF, M_NOWAIT); - if (ivars == NULL) - return (ENOMEM); - ivars->ifp = ifp; - ivars->ifmedia_upd = ifmedia_upd; - ivars->ifmedia_sts = ifmedia_sts; - ivars->mii_flags = flags; - *miibus = device_add_child(dev, "miibus", -1); - if (*miibus == NULL) { - rv = ENXIO; - goto fail; - } - device_set_ivars(*miibus, ivars); - } else { - ivars = device_get_ivars(*miibus); - if (ivars->ifp != ifp || ivars->ifmedia_upd != ifmedia_upd || - ivars->ifmedia_sts != ifmedia_sts || - ivars->mii_flags != flags) { - printf("%s: non-matching invariant\n", __func__); - return (EINVAL); - } - /* - * Assignment of the attach arguments mii_data for the first - * pass is done in miibus_attach(), i.e. once the miibus softc - * has been allocated. - */ - ma.mii_data = device_get_softc(*miibus); - } - - ma.mii_capmask = capmask; - - phy = NULL; - offset = 0; - for (ma.mii_phyno = phymin; ma.mii_phyno <= phymax; ma.mii_phyno++) { - /* - * Make sure we haven't already configured a PHY at this - * address. This allows mii_attach() to be called - * multiple times. - */ - if (device_get_children(*miibus, &children, &nchildren) == 0) { - for (i = 0; i < nchildren; i++) { - args = device_get_ivars(children[i]); - if (args->mii_phyno == ma.mii_phyno) { - /* - * Yes, there is already something - * configured at this address. - */ - free(children, M_TEMP); - goto skip; - } - } - free(children, M_TEMP); - } - - /* - * Check to see if there is a PHY at this address. Note, - * many braindead PHYs report 0/0 in their ID registers, - * so we test for media in the BMSR. - */ - bmsr = MIIBUS_READREG(dev, ma.mii_phyno, MII_BMSR); - if (bmsr == 0 || bmsr == 0xffff || - (bmsr & (BMSR_EXTSTAT | BMSR_MEDIAMASK)) == 0) { - /* Assume no PHY at this address. */ - continue; - } - - /* - * There is a PHY at this address. If we were given an - * `offset' locator, skip this PHY if it doesn't match. - */ - if (offloc != MII_OFFSET_ANY && offloc != offset) - goto skip; - - /* - * Extract the IDs. Braindead PHYs will be handled by - * the `ukphy' driver, as we have no ID information to - * match on. - */ - ma.mii_id1 = MIIBUS_READREG(dev, ma.mii_phyno, MII_PHYIDR1); - ma.mii_id2 = MIIBUS_READREG(dev, ma.mii_phyno, MII_PHYIDR2); - - ma.mii_offset = offset; - args = malloc(sizeof(struct mii_attach_args), M_DEVBUF, - M_NOWAIT); - if (args == NULL) - goto skip; - bcopy((char *)&ma, (char *)args, sizeof(ma)); - phy = device_add_child(*miibus, NULL, -1); - if (phy == NULL) { - free(args, M_DEVBUF); - goto skip; - } - device_set_ivars(phy, args); - skip: - offset++; - } - - if (first != 0) { - if (phy == NULL) { - rv = ENXIO; - goto fail; - } - rv = bus_generic_attach(dev); - if (rv != 0) - goto fail; - - /* Attaching of the PHY drivers is done in miibus_attach(). */ - return (0); - } - rv = bus_generic_attach(*miibus); - if (rv != 0) - goto fail; - - return (0); - - fail: - if (*miibus != NULL) - device_delete_child(dev, *miibus); - free(ivars, M_DEVBUF); - if (first != 0) - *miibus = NULL; - return (rv); -} - -/* - * Media changed; notify all PHYs. - */ -int -mii_mediachg(struct mii_data *mii) -{ - struct mii_softc *child; - struct ifmedia_entry *ife = mii->mii_media.ifm_cur; - int rv; - - mii->mii_media_status = 0; - mii->mii_media_active = IFM_NONE; - - LIST_FOREACH(child, &mii->mii_phys, mii_list) { - /* - * If the media indicates a different PHY instance, - * isolate this one. - */ - if (IFM_INST(ife->ifm_media) != child->mii_inst) { - if ((child->mii_flags & MIIF_NOISOLATE) != 0) { - device_printf(child->mii_dev, "%s: " - "can't handle non-zero PHY instance %d\n", - __func__, child->mii_inst); - continue; - } - PHY_WRITE(child, MII_BMCR, PHY_READ(child, MII_BMCR) | - BMCR_ISO); - continue; - } - rv = PHY_SERVICE(child, mii, MII_MEDIACHG); - if (rv) - return (rv); - } - return (0); -} - -/* - * Call the PHY tick routines, used during autonegotiation. - */ -void -mii_tick(struct mii_data *mii) -{ - struct mii_softc *child; - struct ifmedia_entry *ife = mii->mii_media.ifm_cur; - - LIST_FOREACH(child, &mii->mii_phys, mii_list) { - /* - * If this PHY instance isn't currently selected, just skip - * it. - */ - if (IFM_INST(ife->ifm_media) != child->mii_inst) - continue; - (void)PHY_SERVICE(child, mii, MII_TICK); - } -} - -/* - * Get media status from PHYs. - */ -void -mii_pollstat(struct mii_data *mii) -{ - struct mii_softc *child; - struct ifmedia_entry *ife = mii->mii_media.ifm_cur; - - mii->mii_media_status = 0; - mii->mii_media_active = IFM_NONE; - - LIST_FOREACH(child, &mii->mii_phys, mii_list) { - /* - * If we're not polling this PHY instance, just skip it. - */ - if (IFM_INST(ife->ifm_media) != child->mii_inst) - continue; - (void)PHY_SERVICE(child, mii, MII_POLLSTAT); - } -} - -/* - * Inform the PHYs that the interface is down. - */ -void -mii_down(struct mii_data *mii) -{ - struct mii_softc *child; - - LIST_FOREACH(child, &mii->mii_phys, mii_list) - mii_phy_down(child); -} - -static unsigned char -mii_bitreverse(unsigned char x) -{ - unsigned const char const nibbletab[16] = { - 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 - }; - - return ((nibbletab[x & 15] << 4) | nibbletab[x >> 4]); -} - -u_int -mii_oui(u_int id1, u_int id2) -{ - u_int h; - - h = (id1 << 6) | (id2 >> 10); - - return ((mii_bitreverse(h >> 16) << 16) | - (mii_bitreverse((h >> 8) & 0xff) << 8) | - mii_bitreverse(h & 0xff)); -} diff --git a/src/libs/compat/freebsd_network/fbsd_mii_bitbang.c b/src/libs/compat/freebsd_network/fbsd_mii_bitbang.c deleted file mode 100644 index 6a5f5dc775..0000000000 --- a/src/libs/compat/freebsd_network/fbsd_mii_bitbang.c +++ /dev/null @@ -1,180 +0,0 @@ -/* $NetBSD: mii_bitbang.c,v 1.12 2008/05/04 17:06:09 xtraeme Exp $ */ - -/*- - * Copyright (c) 1999 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following didevlaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following didevlaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Common module for bit-bang'ing the MII. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include -#include - -MODULE_VERSION(mii_bitbang, 1); - -static void mii_bitbang_sendbits(device_t dev, mii_bitbang_ops_t ops, - uint32_t data, int nbits); - -#define MWRITE(x) \ -do { \ - ops->mbo_write(dev, (x)); \ - DELAY(1); \ -} while (/* CONSTCOND */ 0) - -#define MREAD ops->mbo_read(dev) - -#define MDO ops->mbo_bits[MII_BIT_MDO] -#define MDI ops->mbo_bits[MII_BIT_MDI] -#define MDC ops->mbo_bits[MII_BIT_MDC] -#define MDIRPHY ops->mbo_bits[MII_BIT_DIR_HOST_PHY] -#define MDIRHOST ops->mbo_bits[MII_BIT_DIR_PHY_HOST] - -/* - * mii_bitbang_sync: - * - * Synchronize the MII. - */ -void -mii_bitbang_sync(device_t dev, mii_bitbang_ops_t ops) -{ - int i; - uint32_t v; - - v = MDIRPHY | MDO; - - MWRITE(v); - for (i = 0; i < 32; i++) { - MWRITE(v | MDC); - MWRITE(v); - } -} - -/* - * mii_bitbang_sendbits: - * - * Send a series of bits to the MII. - */ -static void -mii_bitbang_sendbits(device_t dev, mii_bitbang_ops_t ops, uint32_t data, - int nbits) -{ - int i; - uint32_t v; - - v = MDIRPHY; - MWRITE(v); - - for (i = 1 << (nbits - 1); i != 0; i >>= 1) { - if (data & i) - v |= MDO; - else - v &= ~MDO; - MWRITE(v); - MWRITE(v | MDC); - MWRITE(v); - } -} - -/* - * mii_bitbang_readreg: - * - * Read a PHY register by bit-bang'ing the MII. - */ -int -mii_bitbang_readreg(device_t dev, mii_bitbang_ops_t ops, int phy, int reg) -{ - int i, error, val; - - mii_bitbang_sync(dev, ops); - - mii_bitbang_sendbits(dev, ops, MII_COMMAND_START, 2); - mii_bitbang_sendbits(dev, ops, MII_COMMAND_READ, 2); - mii_bitbang_sendbits(dev, ops, phy, 5); - mii_bitbang_sendbits(dev, ops, reg, 5); - - /* Switch direction to PHY->host, without a clock transition. */ - MWRITE(MDIRHOST); - - /* Turnaround clock. */ - MWRITE(MDIRHOST | MDC); - MWRITE(MDIRHOST); - - /* Check for error. */ - error = MREAD & MDI; - - /* Idle clock. */ - MWRITE(MDIRHOST | MDC); - MWRITE(MDIRHOST); - - val = 0; - for (i = 0; i < 16; i++) { - val <<= 1; - /* Read data prior to clock low-high transition. */ - if (error == 0 && (MREAD & MDI) != 0) - val |= 1; - - MWRITE(MDIRHOST | MDC); - MWRITE(MDIRHOST); - } - - /* Set direction to host->PHY, without a clock transition. */ - MWRITE(MDIRPHY); - - return (error != 0 ? 0 : val); -} - -/* - * mii_bitbang_writereg: - * - * Write a PHY register by bit-bang'ing the MII. - */ -void -mii_bitbang_writereg(device_t dev, mii_bitbang_ops_t ops, int phy, int reg, - int val) -{ - - mii_bitbang_sync(dev, ops); - - mii_bitbang_sendbits(dev, ops, MII_COMMAND_START, 2); - mii_bitbang_sendbits(dev, ops, MII_COMMAND_WRITE, 2); - mii_bitbang_sendbits(dev, ops, phy, 5); - mii_bitbang_sendbits(dev, ops, reg, 5); - mii_bitbang_sendbits(dev, ops, MII_COMMAND_ACK, 2); - mii_bitbang_sendbits(dev, ops, val, 16); - - MWRITE(MDIRPHY); -} diff --git a/src/libs/compat/freebsd_network/fbsd_mii_physubr.c b/src/libs/compat/freebsd_network/fbsd_mii_physubr.c deleted file mode 100644 index 45212482bc..0000000000 --- a/src/libs/compat/freebsd_network/fbsd_mii_physubr.c +++ /dev/null @@ -1,664 +0,0 @@ -/* $NetBSD: mii_physubr.c,v 1.5 1999/08/03 19:41:49 drochner Exp $ */ - -/*- - * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD: src/sys/dev/mii/mii_physubr.c,v 1.22.2.2 2006/07/29 08:30:12 oleg Exp $"); - -/* - * Subroutines common to all PHYs. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "miibus_if.h" - -/* - * Media to register setting conversion table. Order matters. - */ -static const struct mii_media mii_media_table[MII_NMEDIA] = { - /* None */ - { BMCR_ISO, ANAR_CSMA, - 0, }, - - /* 10baseT */ - { BMCR_S10, ANAR_CSMA|ANAR_10, - 0, }, - - /* 10baseT-FDX */ - { BMCR_S10|BMCR_FDX, ANAR_CSMA|ANAR_10_FD, - 0, }, - - /* 100baseT4 */ - { BMCR_S100, ANAR_CSMA|ANAR_T4, - 0, }, - - /* 100baseTX */ - { BMCR_S100, ANAR_CSMA|ANAR_TX, - 0, }, - - /* 100baseTX-FDX */ - { BMCR_S100|BMCR_FDX, ANAR_CSMA|ANAR_TX_FD, - 0, }, - - /* 1000baseX */ - { BMCR_S1000, ANAR_CSMA, - 0, }, - - /* 1000baseX-FDX */ - { BMCR_S1000|BMCR_FDX, ANAR_CSMA, - 0, }, - - /* 1000baseT */ - { BMCR_S1000, ANAR_CSMA, - GTCR_ADV_1000THDX }, - - /* 1000baseT-FDX */ - { BMCR_S1000, ANAR_CSMA, - GTCR_ADV_1000TFDX }, -}; - -void -mii_phy_setmedia(struct mii_softc *sc) -{ - struct mii_data *mii = sc->mii_pdata; - struct ifmedia_entry *ife = mii->mii_media.ifm_cur; - int bmcr, anar, gtcr; - - if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { - /* - * Force renegotiation if MIIF_DOPAUSE or MIIF_FORCEANEG. - * The former is necessary as we might switch from flow- - * control advertisement being off to on or vice versa. - */ - if ((PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN) == 0 || - (sc->mii_flags & (MIIF_DOPAUSE | MIIF_FORCEANEG)) != 0) - (void)mii_phy_auto(sc); - return; - } - - /* - * Table index is stored in the media entry. - */ - - KASSERT(ife->ifm_data >=0 && ife->ifm_data < MII_NMEDIA, - ("invalid ife->ifm_data (0x%x) in mii_phy_setmedia", - ife->ifm_data)); - - anar = mii_media_table[ife->ifm_data].mm_anar; - bmcr = mii_media_table[ife->ifm_data].mm_bmcr; - gtcr = mii_media_table[ife->ifm_data].mm_gtcr; - - if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { - gtcr |= GTCR_MAN_MS; - if ((ife->ifm_media & IFM_ETH_MASTER) != 0) - gtcr |= GTCR_ADV_MS; - } - - if ((ife->ifm_media & IFM_FDX) != 0 && - ((ife->ifm_media & IFM_FLOW) != 0 || - (sc->mii_flags & MIIF_FORCEPAUSE) != 0)) { - if ((sc->mii_flags & MIIF_IS_1000X) != 0) - anar |= ANAR_X_PAUSE_TOWARDS; - else { - anar |= ANAR_FC; - /* XXX Only 1000BASE-T has PAUSE_ASYM? */ - if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0 && - (sc->mii_extcapabilities & - (EXTSR_1000THDX | EXTSR_1000TFDX)) != 0) - anar |= ANAR_X_PAUSE_ASYM; - } - } - - PHY_WRITE(sc, MII_ANAR, anar); - PHY_WRITE(sc, MII_BMCR, bmcr); - if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) - PHY_WRITE(sc, MII_100T2CR, gtcr); -} - -int -mii_phy_auto(struct mii_softc *sc) -{ - struct ifmedia_entry *ife = sc->mii_pdata->mii_media.ifm_cur; - int anar, gtcr; - - /* - * Check for 1000BASE-X. Autonegotiation is a bit - * different on such devices. - */ - if ((sc->mii_flags & MIIF_IS_1000X) != 0) { - anar = 0; - if ((sc->mii_extcapabilities & EXTSR_1000XFDX) != 0) - anar |= ANAR_X_FD; - if ((sc->mii_extcapabilities & EXTSR_1000XHDX) != 0) - anar |= ANAR_X_HD; - - if ((ife->ifm_media & IFM_FLOW) != 0 || - (sc->mii_flags & MIIF_FORCEPAUSE) != 0) - anar |= ANAR_X_PAUSE_TOWARDS; - PHY_WRITE(sc, MII_ANAR, anar); - } else { - anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | - ANAR_CSMA; - if ((ife->ifm_media & IFM_FLOW) != 0 || - (sc->mii_flags & MIIF_FORCEPAUSE) != 0) { - if ((sc->mii_capabilities & - (BMSR_10TFDX | BMSR_100TXFDX)) != 0) - anar |= ANAR_FC; - /* XXX Only 1000BASE-T has PAUSE_ASYM? */ - if (((sc->mii_flags & MIIF_HAVE_GTCR) != 0) && - (sc->mii_extcapabilities & - (EXTSR_1000THDX | EXTSR_1000TFDX)) != 0) - anar |= ANAR_X_PAUSE_ASYM; - } - PHY_WRITE(sc, MII_ANAR, anar); - if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) { - gtcr = 0; - if ((sc->mii_extcapabilities & EXTSR_1000TFDX) != 0) - gtcr |= GTCR_ADV_1000TFDX; - if ((sc->mii_extcapabilities & EXTSR_1000THDX) != 0) - gtcr |= GTCR_ADV_1000THDX; - PHY_WRITE(sc, MII_100T2CR, gtcr); - } - } - PHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG); - return (EJUSTRETURN); -} - -int -mii_phy_tick(struct mii_softc *sc) -{ - struct ifmedia_entry *ife = sc->mii_pdata->mii_media.ifm_cur; - struct ifnet *ifp = sc->mii_pdata->mii_ifp; - int reg; - - /* Just bail now if the interface is down. */ - if ((ifp->if_flags & IFF_UP) == 0) - return (EJUSTRETURN); - - /* - * If we're not doing autonegotiation, we don't need to do - * any extra work here. However, we need to check the link - * status so we can generate an announcement if the status - * changes. - */ - if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { - sc->mii_ticks = 0; /* reset autonegotiation timer. */ - return (0); - } - - /* Read the status register twice; BMSR_LINK is latch-low. */ - reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); - if ((reg & BMSR_LINK) != 0) { - sc->mii_ticks = 0; /* reset autonegotiation timer. */ - /* See above. */ - return (0); - } - - /* Announce link loss right after it happens */ - if (sc->mii_ticks++ == 0) - return (0); - - /* XXX: use default value if phy driver did not set mii_anegticks */ - if (sc->mii_anegticks == 0) - sc->mii_anegticks = MII_ANEGTICKS_GIGE; - - /* Only retry autonegotiation every mii_anegticks ticks. */ - if (sc->mii_ticks <= sc->mii_anegticks) - return (EJUSTRETURN); - - sc->mii_ticks = 0; - PHY_RESET(sc); - mii_phy_auto(sc); - return (0); -} - -void -mii_phy_reset(struct mii_softc *sc) -{ - struct ifmedia_entry *ife = sc->mii_pdata->mii_media.ifm_cur; - int i, reg; - - if ((sc->mii_flags & MIIF_NOISOLATE) != 0) - reg = BMCR_RESET; - else - reg = BMCR_RESET | BMCR_ISO; - PHY_WRITE(sc, MII_BMCR, reg); - - /* Wait 100ms for it to complete. */ - for (i = 0; i < 100; i++) { - reg = PHY_READ(sc, MII_BMCR); - if ((reg & BMCR_RESET) == 0) - break; - DELAY(1000); - } - - /* NB: a PHY may default to being powered down and/or isolated. */ - reg &= ~(BMCR_PDOWN | BMCR_ISO); - if ((sc->mii_flags & MIIF_NOISOLATE) == 0 && - ((ife == NULL && sc->mii_inst != 0) || - (ife != NULL && IFM_INST(ife->ifm_media) != sc->mii_inst))) - reg |= BMCR_ISO; - if (PHY_READ(sc, MII_BMCR) != reg) - PHY_WRITE(sc, MII_BMCR, reg); -} - -void -mii_phy_down(struct mii_softc *sc) -{ - -} - -void -mii_phy_update(struct mii_softc *sc, int cmd) -{ - struct mii_data *mii = sc->mii_pdata; - - if (sc->mii_media_active != mii->mii_media_active || - cmd == MII_MEDIACHG) { - MIIBUS_STATCHG(sc->mii_dev); - sc->mii_media_active = mii->mii_media_active; - } - if (sc->mii_media_status != mii->mii_media_status) { - MIIBUS_LINKCHG(sc->mii_dev); - sc->mii_media_status = mii->mii_media_status; - } -} - -/* - * Given an ifmedia word, return the corresponding ANAR value. - */ -int -mii_anar(int media) -{ - int rv; - - switch (media & (IFM_TMASK|IFM_NMASK|IFM_FDX)) { - case IFM_ETHER|IFM_10_T: - rv = ANAR_10|ANAR_CSMA; - break; - case IFM_ETHER|IFM_10_T|IFM_FDX: - rv = ANAR_10_FD|ANAR_CSMA; - break; - case IFM_ETHER|IFM_100_TX: - rv = ANAR_TX|ANAR_CSMA; - break; - case IFM_ETHER|IFM_100_TX|IFM_FDX: - rv = ANAR_TX_FD|ANAR_CSMA; - break; - case IFM_ETHER|IFM_100_T4: - rv = ANAR_T4|ANAR_CSMA; - break; - default: - rv = 0; - break; - } - - return (rv); -} - -/* - * Given a BMCR value, return the corresponding ifmedia word. - */ -int -mii_media_from_bmcr(int bmcr) -{ - int rv = IFM_ETHER; - - if (bmcr & BMCR_S100) - rv |= IFM_100_TX; - else - rv |= IFM_10_T; - if (bmcr & BMCR_FDX) - rv |= IFM_FDX; - - return (rv); -} - -/* - * Initialize generic PHY media based on BMSR, called when a PHY is - * attached. We expect to be set up to print a comma-separated list - * of media names. Does not print a newline. - */ -void -mii_phy_add_media(struct mii_softc *sc) -{ - struct mii_data *mii = sc->mii_pdata; - const char *sep = ""; - int fdx = 0; - - /* - * Set the autonegotiation timer for 10/100 media. Gigabit media is - * handled below. - */ - sc->mii_anegticks = MII_ANEGTICKS; - -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) -#define PRINT(s) printf("%s%s", sep, s); sep = ", " - - if ((sc->mii_flags & MIIF_NOISOLATE) == 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), - MII_MEDIA_NONE); - PRINT("none"); - } - - /* - * There are different interpretations for the bits in - * HomePNA PHYs. And there is really only one media type - * that is supported. - */ - if ((sc->mii_flags & MIIF_IS_HPNA) != 0) { - if ((sc->mii_capabilities & BMSR_10THDX) != 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_HPNA_1, 0, - sc->mii_inst), MII_MEDIA_10_T); - PRINT("HomePNA1"); - } - return; - } - - if ((sc->mii_capabilities & BMSR_10THDX) != 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), - MII_MEDIA_10_T); - PRINT("10baseT"); - } - if ((sc->mii_capabilities & BMSR_10TFDX) != 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), - MII_MEDIA_10_T_FDX); - PRINT("10baseT-FDX"); - if ((sc->mii_flags & MIIF_DOPAUSE) != 0 && - (sc->mii_flags & MIIF_NOMANPAUSE) == 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, - IFM_FDX | IFM_FLOW, sc->mii_inst), - MII_MEDIA_10_T_FDX); - PRINT("10baseT-FDX-flow"); - } - fdx = 1; - } - if ((sc->mii_capabilities & BMSR_100TXHDX) != 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), - MII_MEDIA_100_TX); - PRINT("100baseTX"); - } - if ((sc->mii_capabilities & BMSR_100TXFDX) != 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), - MII_MEDIA_100_TX_FDX); - PRINT("100baseTX-FDX"); - if ((sc->mii_flags & MIIF_DOPAUSE) != 0 && - (sc->mii_flags & MIIF_NOMANPAUSE) == 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, - IFM_FDX | IFM_FLOW, sc->mii_inst), - MII_MEDIA_100_TX_FDX); - PRINT("100baseTX-FDX-flow"); - } - fdx = 1; - } - if ((sc->mii_capabilities & BMSR_100T4) != 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_T4, 0, sc->mii_inst), - MII_MEDIA_100_T4); - PRINT("100baseT4"); - } - - if ((sc->mii_extcapabilities & EXTSR_MEDIAMASK) != 0) { - /* - * XXX Right now only handle 1000SX and 1000TX. Need - * XXX to handle 1000LX and 1000CX somehow. - */ - if ((sc->mii_extcapabilities & EXTSR_1000XHDX) != 0) { - sc->mii_anegticks = MII_ANEGTICKS_GIGE; - sc->mii_flags |= MIIF_IS_1000X; - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, 0, - sc->mii_inst), MII_MEDIA_1000_X); - PRINT("1000baseSX"); - } - if ((sc->mii_extcapabilities & EXTSR_1000XFDX) != 0) { - sc->mii_anegticks = MII_ANEGTICKS_GIGE; - sc->mii_flags |= MIIF_IS_1000X; - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, - sc->mii_inst), MII_MEDIA_1000_X_FDX); - PRINT("1000baseSX-FDX"); - if ((sc->mii_flags & MIIF_DOPAUSE) != 0 && - (sc->mii_flags & MIIF_NOMANPAUSE) == 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, - IFM_FDX | IFM_FLOW, sc->mii_inst), - MII_MEDIA_1000_X_FDX); - PRINT("1000baseSX-FDX-flow"); - } - fdx = 1; - } - - /* - * 1000baseT media needs to be able to manipulate - * master/slave mode. - * - * All 1000baseT PHYs have a 1000baseT control register. - */ - if ((sc->mii_extcapabilities & EXTSR_1000THDX) != 0) { - sc->mii_anegticks = MII_ANEGTICKS_GIGE; - sc->mii_flags |= MIIF_HAVE_GTCR; - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, - sc->mii_inst), MII_MEDIA_1000_T); - PRINT("1000baseT"); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, - IFM_ETH_MASTER, sc->mii_inst), MII_MEDIA_1000_T); - PRINT("1000baseT-master"); - } - if ((sc->mii_extcapabilities & EXTSR_1000TFDX) != 0) { - sc->mii_anegticks = MII_ANEGTICKS_GIGE; - sc->mii_flags |= MIIF_HAVE_GTCR; - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, - sc->mii_inst), MII_MEDIA_1000_T_FDX); - PRINT("1000baseT-FDX"); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, - IFM_FDX | IFM_ETH_MASTER, sc->mii_inst), - MII_MEDIA_1000_T_FDX); - PRINT("1000baseT-FDX-master"); - if ((sc->mii_flags & MIIF_DOPAUSE) != 0 && - (sc->mii_flags & MIIF_NOMANPAUSE) == 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, - IFM_FDX | IFM_FLOW, sc->mii_inst), - MII_MEDIA_1000_T_FDX); - PRINT("1000baseT-FDX-flow"); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, - IFM_FDX | IFM_FLOW | IFM_ETH_MASTER, - sc->mii_inst), MII_MEDIA_1000_T_FDX); - PRINT("1000baseT-FDX-flow-master"); - } - fdx = 1; - } - } - - if ((sc->mii_capabilities & BMSR_ANEG) != 0) { - /* intentionally invalid index */ - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), - MII_NMEDIA); - PRINT("auto"); - if (fdx != 0 && (sc->mii_flags & MIIF_DOPAUSE) != 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, IFM_FLOW, - sc->mii_inst), MII_NMEDIA); - PRINT("auto-flow"); - } - } -#undef ADD -#undef PRINT -} - -int -mii_phy_detach(device_t dev) -{ - struct mii_softc *sc; - - sc = device_get_softc(dev); - mii_phy_down(sc); - sc->mii_dev = NULL; - LIST_REMOVE(sc, mii_list); - return (0); -} - -const struct mii_phydesc * -mii_phy_match_gen(const struct mii_attach_args *ma, - const struct mii_phydesc *mpd, size_t len) -{ - - for (; mpd->mpd_name != NULL; - mpd = (const struct mii_phydesc *)((const char *)mpd + len)) { - if (MII_OUI(ma->mii_id1, ma->mii_id2) == mpd->mpd_oui && - MII_MODEL(ma->mii_id2) == mpd->mpd_model) - return (mpd); - } - return (NULL); -} - -const struct mii_phydesc * -mii_phy_match(const struct mii_attach_args *ma, const struct mii_phydesc *mpd) -{ - - return (mii_phy_match_gen(ma, mpd, sizeof(struct mii_phydesc))); -} - -int -mii_phy_dev_probe(device_t dev, const struct mii_phydesc *mpd, int mrv) -{ - - mpd = mii_phy_match(device_get_ivars(dev), mpd); - if (mpd != NULL) { - device_set_desc(dev, mpd->mpd_name); - return (mrv); - } - return (ENXIO); -} - -void -mii_phy_dev_attach(device_t dev, u_int flags, const struct mii_phy_funcs *mpf, - int add_media) -{ - struct mii_softc *sc; - struct mii_attach_args *ma; - struct mii_data *mii; - - sc = device_get_softc(dev); - ma = device_get_ivars(dev); - sc->mii_dev = device_get_parent(dev); - mii = ma->mii_data; - LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); - - sc->mii_flags = flags | miibus_get_flags(dev); - sc->mii_mpd_oui = MII_OUI(ma->mii_id1, ma->mii_id2); - sc->mii_mpd_model = MII_MODEL(ma->mii_id2); - sc->mii_mpd_rev = MII_REV(ma->mii_id2); - sc->mii_capmask = ma->mii_capmask; - sc->mii_inst = mii->mii_instance++; - sc->mii_phy = ma->mii_phyno; - sc->mii_offset = ma->mii_offset; - sc->mii_funcs = mpf; - sc->mii_pdata = mii; - - if (bootverbose) - device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n", - sc->mii_mpd_oui, sc->mii_mpd_model, sc->mii_mpd_rev); - - if (add_media == 0) - return; - - PHY_RESET(sc); - - sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & sc->mii_capmask; - if (sc->mii_capabilities & BMSR_EXTSTAT) - sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); - device_printf(dev, " "); - mii_phy_add_media(sc); - printf("\n"); - - MIIBUS_MEDIAINIT(sc->mii_dev); -} - -/* - * Return the flow control status flag from MII_ANAR & MII_ANLPAR. - */ -u_int -mii_phy_flowstatus(struct mii_softc *sc) -{ - int anar, anlpar; - - if ((sc->mii_flags & MIIF_DOPAUSE) == 0) - return (0); - - anar = PHY_READ(sc, MII_ANAR); - anlpar = PHY_READ(sc, MII_ANLPAR); - - /* - * Check for 1000BASE-X. Autonegotiation is a bit - * different on such devices. - */ - if ((sc->mii_flags & MIIF_IS_1000X) != 0) { - anar <<= 3; - anlpar <<= 3; - } - - if ((anar & ANAR_PAUSE_SYM) != 0 && (anlpar & ANLPAR_PAUSE_SYM) != 0) - return (IFM_FLOW | IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE); - - if ((anar & ANAR_PAUSE_SYM) == 0) { - if ((anar & ANAR_PAUSE_ASYM) != 0 && - (anlpar & ANLPAR_PAUSE_TOWARDS) != 0) - return (IFM_FLOW | IFM_ETH_TXPAUSE); - else - return (0); - } - - if ((anar & ANAR_PAUSE_ASYM) == 0) { - if ((anlpar & ANLPAR_PAUSE_SYM) != 0) - return (IFM_FLOW | IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE); - else - return (0); - } - - switch ((anlpar & ANLPAR_PAUSE_TOWARDS)) { - case ANLPAR_PAUSE_NONE: - return (0); - case ANLPAR_PAUSE_ASYM: - return (IFM_FLOW | IFM_ETH_RXPAUSE); - default: - return (IFM_FLOW | IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE); - } - /* NOTREACHED */ -} diff --git a/src/libs/compat/freebsd_network/fbsd_time.c b/src/libs/compat/freebsd_network/fbsd_time.c deleted file mode 100644 index 7ab8fcae72..0000000000 --- a/src/libs/compat/freebsd_network/fbsd_time.c +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)kern_time.c 8.1 (Berkeley) 6/10/93 - */ -#include -#include - -int -ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps) -{ - int now; - - /* - * Reset the last time and counter if this is the first call - * or more than a second has passed since the last update of - * lasttime. - */ - now = ticks; - if (lasttime->tv_sec == 0 || (u_int)(now - lasttime->tv_sec) >= hz) { - lasttime->tv_sec = now; - *curpps = 1; - return (maxpps != 0); - } else { - (*curpps)++; /* NB: ignore potential overflow */ - return (maxpps < 0 || *curpps < maxpps); - } -} diff --git a/src/libs/compat/freebsd_network/firmware.c b/src/libs/compat/freebsd_network/firmware.c deleted file mode 100644 index aaa246e3f2..0000000000 --- a/src/libs/compat/freebsd_network/firmware.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2009-2010, Colin Günther, coling@gmx.de. - * All Rights Reserved. Distributed under the terms of the MIT License. - * - */ - - -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include - - -#define MAX_FBSD_FIRMWARE_NAME_CHARS 64 - // For strndup, beeing cautious in kernel code is a good thing. - // NB: This constant doesn't exist in FreeBSD. - - -static const char* -getHaikuFirmwareName(const char* fbsdFirmwareName, - const char* unknownFirmwareName) -{ - int i; - - if (__haiku_firmware_name_map == NULL) - return unknownFirmwareName; - - for (i = 0; i < __haiku_firmware_parts_count; i++) { - if (strcmp(__haiku_firmware_name_map[i][0], fbsdFirmwareName) == 0) - return __haiku_firmware_name_map[i][1]; - } - return unknownFirmwareName; -} - - -const struct firmware* -firmware_get(const char* fbsdFirmwareName) -{ - char* fbsdFirmwareNameCopy = NULL; - int fileDescriptor = -1; - struct firmware* firmware = NULL; - int32 firmwareFileSize; - char* firmwarePath = NULL; - const char* haikuFirmwareName = NULL; - ssize_t readCount = 0; - directory_which checkDirs[] = { B_SYSTEM_NONPACKAGED_DATA_DIRECTORY, - B_SYSTEM_DATA_DIRECTORY }; - size_t numCheckDirs - = sizeof(checkDirs) / sizeof(checkDirs[0]); - size_t i = 0; - - haikuFirmwareName = getHaikuFirmwareName(fbsdFirmwareName, - fbsdFirmwareName); - - firmwarePath = (char*)malloc(B_PATH_NAME_LENGTH); - if (firmwarePath == NULL) - goto cleanup; - - - for (; i < numCheckDirs; i++) { - if (find_directory(checkDirs[i], -1, false, firmwarePath, - B_PATH_NAME_LENGTH) != B_OK) { - continue; - } - - strlcat(firmwarePath, "/firmware/", B_PATH_NAME_LENGTH); - strlcat(firmwarePath, gDriverName, B_PATH_NAME_LENGTH); - strlcat(firmwarePath, "/", B_PATH_NAME_LENGTH); - strlcat(firmwarePath, haikuFirmwareName, B_PATH_NAME_LENGTH); - - fileDescriptor = open(firmwarePath, B_READ_ONLY); - if (fileDescriptor >= 0) - break; - } - - if (fileDescriptor < 0) - goto cleanup; - - firmwareFileSize = lseek(fileDescriptor, 0, SEEK_END); - if (firmwareFileSize == -1) - goto cleanup; - - lseek(fileDescriptor, 0, SEEK_SET); - - fbsdFirmwareNameCopy = strndup(fbsdFirmwareName, - MAX_FBSD_FIRMWARE_NAME_CHARS); - if (fbsdFirmwareNameCopy == NULL) - goto cleanup; - - firmware = (struct firmware*)malloc(sizeof(struct firmware)); - if (firmware == NULL) - goto cleanup; - - firmware->data = malloc(firmwareFileSize); - if (firmware->data == NULL) - goto cleanup; - - readCount = read(fileDescriptor, (void*)firmware->data, firmwareFileSize); - if (readCount == -1 || readCount < firmwareFileSize) { - free((void*)firmware->data); - goto cleanup; - } - - firmware->datasize = firmwareFileSize; - firmware->name = fbsdFirmwareNameCopy; - firmware->version = __haiku_firmware_version; - - close(fileDescriptor); - free(firmwarePath); - return firmware; - -cleanup: - if (firmware) - free(firmware); - if (fbsdFirmwareNameCopy) - free(fbsdFirmwareNameCopy); - if (firmwarePath) - free(firmwarePath); - if (fileDescriptor >= 0) - close(fileDescriptor); - return NULL; -} - - -void -firmware_put(const struct firmware* firmware, int flags) -{ - if (firmware == NULL) - return; - - if (firmware->data) - free((void*)firmware->data); - if (firmware->name) - free((void*)firmware->name); - free((void*)firmware); -} diff --git a/src/libs/compat/freebsd_network/if.c b/src/libs/compat/freebsd_network/if.c deleted file mode 100644 index dc67514295..0000000000 --- a/src/libs/compat/freebsd_network/if.c +++ /dev/null @@ -1,763 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * Copyright 2007-2009, Axel Dörfler, axeld@pinc-software.de. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Copyright 2004, Marcus Overhagen. All Rights Reserved. - * - * Distributed under the terms of the MIT License. - */ - - -#include "device.h" - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - - -int ifqmaxlen = IFQ_MAXLEN; - - -#define IFNET_HOLD (void *)(uintptr_t)(-1) - - -static void -insert_into_device_name_list(struct ifnet * ifp) -{ - int i; - for (i = 0; i < MAX_DEVICES; i++) { - if (gDeviceNameList[i] == NULL) { - gDeviceNameList[i] = ifp->device_name; - return; - } - } - - panic("too many devices"); -} - - -static void -remove_from_device_name_list(struct ifnet * ifp) -{ - int i; - for (i = 0; i < MAX_DEVICES; i++) { - if (ifp->device_name == gDeviceNameList[i]) { - int last; - for (last = i + 1; last < MAX_DEVICES; last++) { - if (gDeviceNameList[last] == NULL) - break; - } - last--; - - if (i == last) - gDeviceNameList[i] = NULL; - else { - // switch positions with the last entry - gDeviceNameList[i] = gDeviceNameList[last]; - gDeviceNameList[last] = NULL; - } - break; - } - } -} - - -struct ifnet * -ifnet_byindex(u_short idx) -{ - struct ifnet *ifp; - - IFNET_RLOCK_NOSLEEP(); - ifp = ifnet_byindex_locked(idx); - IFNET_RUNLOCK_NOSLEEP(); - - return (ifp); -} - - -struct ifnet * -ifnet_byindex_locked(u_short idx) -{ - struct ifnet *ifp; - - ifp = gDevices[idx]; - - return (ifp); -} - - -static void -ifnet_setbyindex_locked(u_short idx, struct ifnet *ifp) -{ - gDevices[idx] = ifp; -} - - -static void -ifnet_setbyindex(u_short idx, struct ifnet *ifp) -{ - IFNET_WLOCK(); - ifnet_setbyindex_locked(idx, ifp); - IFNET_WUNLOCK(); -} - - -static int -ifindex_alloc_locked(u_short *idxp) -{ - u_short index; - - for (index = 0; index < MAX_DEVICES; index++) { - if (gDevices[index] == NULL) { - break; - } - } - - if (index == MAX_DEVICES) - return ENOSPC; - - gDeviceCount++; - *idxp = index; - - return ENOERR; -} - - -static void -ifindex_free_locked(u_short idx) -{ - gDevices[idx] = NULL; - gDeviceCount--; -} - - -struct ifnet * -if_alloc(u_char type) -{ - char semName[64]; - u_short index; - - struct ifnet *ifp = _kernel_malloc(sizeof(struct ifnet), M_ZERO); - if (ifp == NULL) - return NULL; - - snprintf(semName, sizeof(semName), "%s receive", gDriverName); - - ifp->receive_sem = create_sem(0, semName); - if (ifp->receive_sem < B_OK) - goto err1; - - switch (type) { - case IFT_ETHER: - { - ifp->if_l2com = _kernel_malloc(sizeof(struct arpcom), M_ZERO); - if (ifp->if_l2com == NULL) - goto err2; - IFP2AC(ifp)->ac_ifp = ifp; - break; - } - case IFT_IEEE80211: - { - if (wlan_if_l2com_alloc(ifp) != B_OK) - goto err2; - break; - } - } - - ifp->link_state_sem = -1; - ifp->open_count = 0; - ifp->flags = 0; - ifp->if_type = type; - ifq_init(&ifp->receive_queue, semName); - - ifp->scan_done_sem = -1; - // WLAN specific, doesn't hurt when initilized for other devices - - // Search for the first free device slot, and use that one - IFNET_WLOCK(); - if (ifindex_alloc_locked(&index) != ENOERR) { - IFNET_WUNLOCK(); - panic("too many devices"); - goto err3; - } - ifnet_setbyindex_locked(index, IFNET_HOLD); - IFNET_WUNLOCK(); - - ifp->if_index = index; - ifnet_setbyindex(ifp->if_index, ifp); - - IF_ADDR_LOCK_INIT(ifp); - return ifp; - -err3: - switch (type) { - case IFT_ETHER: - case IFT_IEEE80211: - _kernel_free(ifp->if_l2com); - break; - } - -err2: - delete_sem(ifp->receive_sem); - -err1: - _kernel_free(ifp); - return NULL; -} - - -void -if_free(struct ifnet *ifp) -{ - // IEEE80211 devices won't be in this list, - // so don't try to remove them. - if (ifp->if_type == IFT_ETHER) - remove_from_device_name_list(ifp); - - IFNET_WLOCK(); - ifindex_free_locked(ifp->if_index); - IFNET_WUNLOCK(); - - IF_ADDR_LOCK_DESTROY(ifp); - switch (ifp->if_type) { - case IFT_ETHER: - case IFT_IEEE80211: - _kernel_free(ifp->if_l2com); - break; - } - - delete_sem(ifp->receive_sem); - ifq_uninit(&ifp->receive_queue); - - _kernel_free(ifp); -} - - -void -if_initname(struct ifnet *ifp, const char *name, int unit) -{ - dprintf("if_initname(%p, %s, %d)\n", ifp, name, unit); - - if (name == NULL || name[0] == '\0') - panic("interface goes unnamed"); - - ifp->if_dname = name; - ifp->if_dunit = unit; - - strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname)); - - snprintf(ifp->device_name, sizeof(ifp->device_name), "net/%s/%i", - gDriverName, ifp->if_index); - - driver_printf("%s: /dev/%s\n", gDriverName, ifp->device_name); - - // For wlan devices we only want to see the cloned wlan device - // in the list. - // Remember: For each wlan device, there is a base device of type - // IFT_IEEE80211. On top of that a clone device is created of - // type IFT_ETHER. - // Haiku shall only see the cloned device as it is the one - // FreeBSD 8 uses for wireless i/o, too. - if (ifp->if_type == IFT_ETHER) - insert_into_device_name_list(ifp); - - ifp->root_device = find_root_device(unit); -} - - -void -ifq_init(struct ifqueue *ifq, const char *name) -{ - ifq->ifq_head = NULL; - ifq->ifq_tail = NULL; - ifq->ifq_len = 0; - ifq->ifq_maxlen = IFQ_MAXLEN; - ifq->ifq_drops = 0; - - mtx_init(&ifq->ifq_mtx, name, NULL, MTX_DEF); -} - - -void -ifq_uninit(struct ifqueue *ifq) -{ - mtx_destroy(&ifq->ifq_mtx); -} - - -static int -if_transmit(struct ifnet *ifp, struct mbuf *m) -{ - int error; - - IFQ_HANDOFF(ifp, m, error); - return (error); -} - - -void -if_attach(struct ifnet *ifp) -{ - TAILQ_INIT(&ifp->if_addrhead); - TAILQ_INIT(&ifp->if_prefixhead); - TAILQ_INIT(&ifp->if_multiaddrs); - - IF_ADDR_LOCK_INIT(ifp); - - ifp->if_lladdr.sdl_family = AF_LINK; - - ifq_init((struct ifqueue *) &ifp->if_snd, ifp->if_xname); - - if (ifp->if_transmit == NULL) { - ifp->if_transmit = if_transmit; - } -} - - -void -if_detach(struct ifnet *ifp) -{ - if (HAIKU_DRIVER_REQUIRES(FBSD_SWI_TASKQUEUE)) - taskqueue_drain(taskqueue_swi, &ifp->if_linktask); - - IF_ADDR_LOCK_DESTROY(ifp); - ifq_uninit((struct ifqueue *) &ifp->if_snd); -} - - -void -if_start(struct ifnet *ifp) -{ -#ifdef IFF_NEEDSGIANT - if (ifp->if_flags & IFF_NEEDSGIANT) - panic("freebsd compat.: unsupported giant requirement"); -#endif - ifp->if_start(ifp); -} - - -int -if_printf(struct ifnet *ifp, const char *format, ...) -{ - char buf[256]; - va_list vl; - va_start(vl, format); - vsnprintf(buf, sizeof(buf), format, vl); - va_end(vl); - - dprintf("[%s] %s", ifp->device_name, buf); - return 0; -} - - -void -if_link_state_change(struct ifnet *ifp, int linkState) -{ - if (ifp->if_link_state == linkState) - return; - - ifp->if_link_state = linkState; - release_sem_etc(ifp->link_state_sem, 1, B_DO_NOT_RESCHEDULE); -} - - -static struct ifmultiaddr * -if_findmulti(struct ifnet *ifp, struct sockaddr *_address) -{ - struct sockaddr_dl *address = (struct sockaddr_dl *) _address; - struct ifmultiaddr *ifma; - - TAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link) { - if (memcmp(LLADDR(address), - LLADDR((struct sockaddr_dl *)ifma->ifma_addr), ETHER_ADDR_LEN) == 0) - return ifma; - } - - return NULL; -} - - -/* - * if_freemulti: free ifmultiaddr structure and possibly attached related - * addresses. The caller is responsible for implementing reference - * counting, notifying the driver, handling routing messages, and releasing - * any dependent link layer state. - */ -static void -if_freemulti(struct ifmultiaddr *ifma) -{ - - KASSERT(ifma->ifma_refcount == 0, ("if_freemulti: refcount %d", - ifma->ifma_refcount)); - KASSERT(ifma->ifma_protospec == NULL, - ("if_freemulti: protospec not NULL")); - - if (ifma->ifma_lladdr != NULL) - free(ifma->ifma_lladdr); - - // Haiku note: We use a field in the ifmultiaddr struct (ifma_addr_storage) - // to store the address and let ifma_addr point to that. We therefore do not - // free it here, as it will be freed as part of freeing the if_multiaddr. - //free(ifma->ifma_addr); - - free(ifma); -} - - -static struct ifmultiaddr * -_if_addmulti(struct ifnet *ifp, struct sockaddr *address) -{ - struct ifmultiaddr *addr = if_findmulti(ifp, address); - - if (addr != NULL) { - addr->ifma_refcount++; - return addr; - } - - addr = (struct ifmultiaddr *) malloc(sizeof(struct ifmultiaddr)); - if (addr == NULL) - return NULL; - - addr->ifma_lladdr = NULL; - addr->ifma_ifp = ifp; - addr->ifma_protospec = NULL; - - memcpy(&addr->ifma_addr_storage, address, sizeof(struct sockaddr_dl)); - addr->ifma_addr = (struct sockaddr *) &addr->ifma_addr_storage; - - addr->ifma_refcount = 1; - - TAILQ_INSERT_HEAD(&ifp->if_multiaddrs, addr, ifma_link); - - return addr; -} - - -int -if_addmulti(struct ifnet *ifp, struct sockaddr *address, - struct ifmultiaddr **out) -{ - struct ifmultiaddr *result; - int refcount = 0; - - IF_ADDR_LOCK(ifp); - result = _if_addmulti(ifp, address); - if (result) - refcount = result->ifma_refcount; - IF_ADDR_UNLOCK(ifp); - - if (result == NULL) - return ENOBUFS; - - if (refcount == 1 && ifp->if_ioctl != NULL) - ifp->if_ioctl(ifp, SIOCADDMULTI, NULL); - - if (out) - (*out) = result; - - return 0; -} - - -static int -if_delmulti_locked(struct ifnet *ifp, struct ifmultiaddr *ifma, int detaching) -{ - struct ifmultiaddr *ll_ifma; - - if (ifp != NULL && ifma->ifma_ifp != NULL) { - KASSERT(ifma->ifma_ifp == ifp, - ("%s: inconsistent ifp %p", __func__, ifp)); - IF_ADDR_LOCK_ASSERT(ifp); - } - - ifp = ifma->ifma_ifp; - - /* - * If the ifnet is detaching, null out references to ifnet, - * so that upper protocol layers will notice, and not attempt - * to obtain locks for an ifnet which no longer exists. The - * routing socket announcement must happen before the ifnet - * instance is detached from the system. - */ - if (detaching) { -#ifdef DIAGNOSTIC - printf("%s: detaching ifnet instance %p\n", __func__, ifp); -#endif - /* - * ifp may already be nulled out if we are being reentered - * to delete the ll_ifma. - */ - if (ifp != NULL) { -#ifndef __HAIKU__ - rt_newmaddrmsg(RTM_DELMADDR, ifma); -#endif - ifma->ifma_ifp = NULL; - } - } - - if (--ifma->ifma_refcount > 0) - return 0; - -#ifndef __HAIKU__ - /* - * If this ifma is a network-layer ifma, a link-layer ifma may - * have been associated with it. Release it first if so. - */ - ll_ifma = ifma->ifma_llifma; - if (ll_ifma != NULL) { - KASSERT(ifma->ifma_lladdr != NULL, - ("%s: llifma w/o lladdr", __func__)); - if (detaching) - ll_ifma->ifma_ifp = NULL; /* XXX */ - if (--ll_ifma->ifma_refcount == 0) { - if (ifp != NULL) { - TAILQ_REMOVE(&ifp->if_multiaddrs, ll_ifma, - ifma_link); - } - if_freemulti(ll_ifma); - } - } -#endif - - if (ifp != NULL) - TAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifma_link); - - if_freemulti(ifma); - - /* - * The last reference to this instance of struct ifmultiaddr - * was released; the hardware should be notified of this change. - */ - return 1; -} - - -/* - * Delete all multicast group membership for an interface. - * Should be used to quickly flush all multicast filters. - */ -void -if_delallmulti(struct ifnet *ifp) -{ - struct ifmultiaddr *ifma; - struct ifmultiaddr *next; - - IF_ADDR_LOCK(ifp); - TAILQ_FOREACH_SAFE(ifma, &ifp->if_multiaddrs, ifma_link, next) - if_delmulti_locked(ifp, ifma, 0); - IF_ADDR_UNLOCK(ifp); -} - - -static void -if_delete_multiaddr(struct ifnet *ifp, struct ifmultiaddr *ifma) -{ - TAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifma_link); - free(ifma); -} - - -int -if_delmulti(struct ifnet *ifp, struct sockaddr *sa) -{ - struct ifmultiaddr *ifma; - int lastref; -#ifdef INVARIANTS - struct ifnet *oifp; - - IFNET_RLOCK_NOSLEEP(); - TAILQ_FOREACH(oifp, &V_ifnet, if_link) - if (ifp == oifp) - break; - if (ifp != oifp) - ifp = NULL; - IFNET_RUNLOCK_NOSLEEP(); - - KASSERT(ifp != NULL, ("%s: ifnet went away", __func__)); -#endif - if (ifp == NULL) - return (ENOENT); - - IF_ADDR_LOCK(ifp); - lastref = 0; - ifma = if_findmulti(ifp, sa); - if (ifma != NULL) - lastref = if_delmulti_locked(ifp, ifma, 0); - IF_ADDR_UNLOCK(ifp); - - if (ifma == NULL) - return (ENOENT); - - if (lastref && ifp->if_ioctl != NULL) { - (void)(*ifp->if_ioctl)(ifp, SIOCDELMULTI, 0); - } - - return (0); -} - - -void -if_purgemaddrs(struct ifnet *ifp) -{ - struct ifmultiaddr *ifma; - struct ifmultiaddr *next; - - IF_ADDR_LOCK(ifp); - TAILQ_FOREACH_SAFE(ifma, &ifp->if_multiaddrs, ifma_link, next) - if_delmulti_locked(ifp, ifma, 1); - IF_ADDR_UNLOCK(ifp); -} - - -void -if_addr_rlock(struct ifnet *ifp) -{ - IF_ADDR_LOCK(ifp); -} - - -void -if_addr_runlock(struct ifnet *ifp) -{ - IF_ADDR_UNLOCK(ifp); -} - - -void -if_maddr_rlock(struct ifnet *ifp) -{ - IF_ADDR_LOCK(ifp); -} - - -void -if_maddr_runlock(struct ifnet *ifp) -{ - IF_ADDR_UNLOCK(ifp); -} - - -int -ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, - struct route *ro) -{ - int error = 0; - IFQ_HANDOFF(ifp, m, error); - return error; -} - - -static void ether_input(struct ifnet *ifp, struct mbuf *m) -{ - IF_ENQUEUE(&ifp->receive_queue, m); - release_sem_etc(ifp->receive_sem, 1, B_DO_NOT_RESCHEDULE); -} - - -void -ether_ifattach(struct ifnet *ifp, const uint8_t *macAddress) -{ - ifp->if_addrlen = ETHER_ADDR_LEN; - ifp->if_hdrlen = ETHER_HDR_LEN; - if_attach(ifp); - ifp->if_mtu = ETHERMTU; - ifp->if_output = ether_output; - ifp->if_input = ether_input; - ifp->if_resolvemulti = NULL; // done in the stack - ifp->if_broadcastaddr = etherbroadcastaddr; - - memcpy(IF_LLADDR(ifp), macAddress, ETHER_ADDR_LEN); - - // TODO: according to FreeBSD's if_ethersubr.c, this should be removed - // once all drivers are cleaned up. - if (macAddress != IFP2ENADDR(ifp)) - memcpy(IFP2ENADDR(ifp), macAddress, ETHER_ADDR_LEN); -} - - -void -ether_ifdetach(struct ifnet *ifp) -{ - if_detach(ifp); -} - - -int -ether_ioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct ifreq *ifr = (struct ifreq *) data; - - switch (command) { - case SIOCSIFMTU: - if (ifr->ifr_mtu > ETHERMTU) - return EINVAL; - else - ; - // need to fix our ifreq to work with C... - // ifp->ifr_mtu = ifr->ifr_mtu; - break; - - default: - return EINVAL; - } - - return 0; -} - - -void -if_inc_counter(struct ifnet *ifp, ift_counter cnt, int64_t inc) -{ - switch (cnt) { - case IFCOUNTER_IPACKETS: - atomic_add(&ifp->if_ipackets, inc); - break; - case IFCOUNTER_IERRORS: - atomic_add(&ifp->if_ierrors, inc); - break; - case IFCOUNTER_OPACKETS: - atomic_add(&ifp->if_opackets, inc); - break; - case IFCOUNTER_OERRORS: - atomic_add(&ifp->if_oerrors, inc); - break; - case IFCOUNTER_COLLISIONS: - atomic_add(&ifp->if_collisions, inc); - break; - case IFCOUNTER_IBYTES: - atomic_add(&ifp->if_ibytes, inc); - break; - case IFCOUNTER_OBYTES: - atomic_add(&ifp->if_obytes, inc); - break; - case IFCOUNTER_IMCASTS: - atomic_add(&ifp->if_imcasts, inc); - break; - case IFCOUNTER_OMCASTS: - atomic_add(&ifp->if_omcasts, inc); - break; - case IFCOUNTER_IQDROPS: - atomic_add(&ifp->if_iqdrops, inc); - break; - case IFCOUNTER_OQDROPS: - atomic_add(&ifp->if_oqdrops, inc); - break; - case IFCOUNTER_NOPROTO: - atomic_add(&ifp->if_noproto, inc); - break; - case IFCOUNTERS: - KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt)); - } -} diff --git a/src/libs/compat/freebsd_network/libkern.c b/src/libs/compat/freebsd_network/libkern.c deleted file mode 100644 index c3066f9193..0000000000 --- a/src/libs/compat/freebsd_network/libkern.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ - - -#include - - -uint32_t -arc4random(void) -{ - return random(); -} - diff --git a/src/libs/compat/freebsd_network/mbuf.c b/src/libs/compat/freebsd_network/mbuf.c deleted file mode 100644 index 22e30ef45e..0000000000 --- a/src/libs/compat/freebsd_network/mbuf.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Copyright 2004, Marcus Overhagen. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "device.h" - -#include -#include -#include - -#include -#include -#include - - -static object_cache *sMBufCache; -static object_cache *sChunkCache; -static object_cache *sJumbo9ChunkCache; -static object_cache *sJumboPageSizeCache; - - -int max_linkhdr = 16; -int max_protohdr = 40 + 20; /* ip6 + tcp */ - -/* max_linkhdr + max_protohdr, but that's not allowed by gcc. */ -int max_hdr = 16 + 40 + 20; - -/* MHLEN - max_hdr */ -int max_datalen = MHLEN - (16 + 40 + 20); - - -static int -m_to_oc_flags(int how) -{ - if (how & M_NOWAIT) - return CACHE_DONT_WAIT_FOR_MEMORY; - - return 0; -} - - -static int -construct_mbuf(struct mbuf *memoryBuffer, short type, int flags) -{ - memoryBuffer->m_next = NULL; - memoryBuffer->m_nextpkt = NULL; - memoryBuffer->m_len = 0; - memoryBuffer->m_flags = flags; - memoryBuffer->m_type = type; - - if (flags & M_PKTHDR) { - memoryBuffer->m_data = memoryBuffer->m_pktdat; - memset(&memoryBuffer->m_pkthdr, 0, sizeof(memoryBuffer->m_pkthdr)); - SLIST_INIT(&memoryBuffer->m_pkthdr.tags); - } else { - memoryBuffer->m_data = memoryBuffer->m_dat; - } - - return 0; -} - - -static int -construct_ext_sized_mbuf(struct mbuf *memoryBuffer, int how, int size) -{ - object_cache *cache; - int extType; - if (size != MCLBYTES && size != MJUM9BYTES && size != MJUMPAGESIZE) - panic("unsupported size"); - - if (size == MCLBYTES) { - cache = sChunkCache; - extType = EXT_CLUSTER; - } else if (size == MJUM9BYTES) { - cache = sJumbo9ChunkCache; - extType = EXT_JUMBO9; - } else { - cache = sJumboPageSizeCache; - extType = EXT_JUMBOP; - } - - memoryBuffer->m_ext.ext_buf = object_cache_alloc(cache, m_to_oc_flags(how)); - if (memoryBuffer->m_ext.ext_buf == NULL) - return B_NO_MEMORY; - - memoryBuffer->m_data = memoryBuffer->m_ext.ext_buf; - memoryBuffer->m_flags |= M_EXT; - /* mb->m_ext.ext_free = NULL; */ - /* mb->m_ext.ext_args = NULL; */ - memoryBuffer->m_ext.ext_size = size; - memoryBuffer->m_ext.ext_type = extType; - /* mb->m_ext.ref_cnt = NULL; */ - - return 0; -} - - -static inline int -construct_ext_mbuf(struct mbuf *memoryBuffer, int how) -{ - return construct_ext_sized_mbuf(memoryBuffer, how, MCLBYTES); -} - - -static int -construct_pkt_mbuf(int how, struct mbuf *memoryBuffer, short type, int flags) -{ - construct_mbuf(memoryBuffer, type, flags); - if (construct_ext_mbuf(memoryBuffer, how) < 0) - return -1; - memoryBuffer->m_ext.ext_type = EXT_CLUSTER; - return 0; -} - - -struct mbuf * -m_getcl(int how, short type, int flags) -{ - struct mbuf *memoryBuffer = - (struct mbuf *)object_cache_alloc(sMBufCache, m_to_oc_flags(how)); - if (memoryBuffer == NULL) - return NULL; - - if (construct_pkt_mbuf(how, memoryBuffer, type, flags) < 0) { - object_cache_free(sMBufCache, memoryBuffer, 0); - return NULL; - } - - return memoryBuffer; -} - - -static struct mbuf * -_m_get(int how, short type, int flags) -{ - struct mbuf *memoryBuffer = - (struct mbuf *)object_cache_alloc(sMBufCache, m_to_oc_flags(how)); - if (memoryBuffer == NULL) - return NULL; - - construct_mbuf(memoryBuffer, type, flags); - - return memoryBuffer; -} - - -struct mbuf * -m_get(int how, short type) -{ - return _m_get(how, type, 0); -} - - -struct mbuf * -m_gethdr(int how, short type) -{ - return _m_get(how, type, M_PKTHDR); -} - - -struct mbuf * -m_getjcl(int how, short type, int flags, int size) -{ - struct mbuf *memoryBuffer = - (struct mbuf *)object_cache_alloc(sMBufCache, m_to_oc_flags(how)); - if (memoryBuffer == NULL) - return NULL; - construct_mbuf(memoryBuffer, type, flags); - if (construct_ext_sized_mbuf(memoryBuffer, how, size) < 0) { - object_cache_free(sMBufCache, memoryBuffer, 0); - return NULL; - } - return memoryBuffer; -} - - -void -m_clget(struct mbuf *memoryBuffer, int how) -{ - memoryBuffer->m_ext.ext_buf = NULL; - /* called checks for errors by looking for M_EXT */ - construct_ext_mbuf(memoryBuffer, how); -} - - -void * -m_cljget(struct mbuf *memoryBuffer, int how, int size) -{ - if (memoryBuffer == NULL) - panic("m_cljget doesn't support allocate mbuf"); - memoryBuffer->m_ext.ext_buf = NULL; - construct_ext_sized_mbuf(memoryBuffer, how, size); - /* shouldn't be used */ - return NULL; -} - - -void -m_freem(struct mbuf *memoryBuffer) -{ - while (memoryBuffer) - memoryBuffer = m_free(memoryBuffer); -} - - -static void -mb_free_ext(struct mbuf *memoryBuffer) -{ - /* - if (m->m_ext.ref_count != NULL) - panic("unsupported"); - */ - - object_cache *cache = NULL; - - if (memoryBuffer->m_ext.ext_type == EXT_CLUSTER) - cache = sChunkCache; - else if (memoryBuffer->m_ext.ext_type == EXT_JUMBO9) - cache = sJumbo9ChunkCache; - else if (memoryBuffer->m_ext.ext_type == EXT_JUMBOP) - cache = sJumboPageSizeCache; - else - panic("unknown type"); - - object_cache_free(cache, memoryBuffer->m_ext.ext_buf, 0); - memoryBuffer->m_ext.ext_buf = NULL; - object_cache_free(sMBufCache, memoryBuffer, 0); -} - - -struct mbuf * -m_free(struct mbuf *memoryBuffer) -{ - struct mbuf *next = memoryBuffer->m_next; - - if (memoryBuffer->m_flags & M_EXT) - mb_free_ext(memoryBuffer); - else - object_cache_free(sMBufCache, memoryBuffer, 0); - - return next; -} - - -void -m_extadd(struct mbuf *memoryBuffer, caddr_t buffer, u_int size, - void (*freeHook)(void *, void *), void *arg1, void *arg2, int flags, int type) -{ - // TODO: implement? - panic("m_extadd() called."); -} - - -status_t -init_mbufs() -{ - sMBufCache = create_object_cache("mbufs", MSIZE, 8, NULL, NULL, NULL); - if (sMBufCache == NULL) - goto clean; - sChunkCache = create_object_cache("mbuf chunks", MCLBYTES, 0, NULL, NULL, - NULL); - if (sChunkCache == NULL) - goto clean; - sJumbo9ChunkCache = create_object_cache("mbuf jumbo9 chunks", MJUM9BYTES, 0, - NULL, NULL, NULL); - if (sJumbo9ChunkCache == NULL) - goto clean; - sJumboPageSizeCache = create_object_cache("mbuf jumbo page size chunks", - MJUMPAGESIZE, 0, NULL, NULL, NULL); - if (sJumboPageSizeCache == NULL) - goto clean; - return B_OK; - -clean: - if (sJumbo9ChunkCache != NULL) - delete_object_cache(sJumbo9ChunkCache); - if (sChunkCache != NULL) - delete_object_cache(sChunkCache); - if (sMBufCache != NULL) - delete_object_cache(sMBufCache); - return B_NO_MEMORY; -} - - -void -uninit_mbufs() -{ - delete_object_cache(sMBufCache); - delete_object_cache(sChunkCache); - delete_object_cache(sJumbo9ChunkCache); - delete_object_cache(sJumboPageSizeCache); -} diff --git a/src/libs/compat/freebsd_network/mii.c b/src/libs/compat/freebsd_network/mii.c deleted file mode 100644 index 4721938e24..0000000000 --- a/src/libs/compat/freebsd_network/mii.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Hugo Santos, hugosantos@gmail.com - */ - - -#include "device.h" - -#include - -#include -#include - - -int -__haiku_miibus_readreg(device_t device, int phy, int reg) -{ - if (device->methods.miibus_readreg == NULL) - panic("miibus_readreg, no support"); - - return device->methods.miibus_readreg(device, phy, reg); -} - - -int -__haiku_miibus_writereg(device_t device, int phy, int reg, int data) -{ - if (device->methods.miibus_writereg == NULL) - panic("miibus_writereg, no support"); - - return device->methods.miibus_writereg(device, phy, reg, data); -} - - -void -__haiku_miibus_statchg(device_t device) -{ - if (device->methods.miibus_statchg) - device->methods.miibus_statchg(device); -} - - -void -__haiku_miibus_linkchg(device_t device) -{ - if (device->methods.miibus_linkchg) - device->methods.miibus_linkchg(device); -} - - -void -__haiku_miibus_mediainit(device_t device) -{ - if (device->methods.miibus_mediainit) - device->methods.miibus_mediainit(device); -} diff --git a/src/libs/compat/freebsd_network/miidevs2h.awk b/src/libs/compat/freebsd_network/miidevs2h.awk deleted file mode 100644 index 2fbf8100f3..0000000000 --- a/src/libs/compat/freebsd_network/miidevs2h.awk +++ /dev/null @@ -1,149 +0,0 @@ -#! /usr/bin/awk -f -# $NetBSD: devlist2h.awk,v 1.2 1998/09/05 14:42:06 christos Exp $ - -#- -# Copyright (c) 1998 The NetBSD Foundation, Inc. -# All rights reserved. -# -# This code is derived from software contributed to The NetBSD Foundation -# by Christos Zoulas. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the NetBSD -# Foundation, Inc. and its contributors. -# 4. Neither the name of The NetBSD Foundation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS -# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS -# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# Copyright (c) 1995, 1996 Christopher G. Demetriou -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This model includes software developed by Christopher G. Demetriou. -# This model includes software developed by Christos Zoulas -# 4. The name of the author(s) may not be used to endorse or promote models -# derived from this software without specific prior written permission -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# $FreeBSD: src/sys/tools/miidevs2h.awk,v 1.6 2005/01/07 02:29:25 imp Exp $ -# -function collectline(f, line) { - oparen = 0 - line = "" - while (f <= NF) { - if ($f == "#") { - line = line "(" - oparen = 1 - f++ - continue - } - if (oparen) { - line = line $f - if (f < NF) - line = line " " - f++ - continue - } - line = line $f - if (f < NF) - line = line " " - f++ - } - if (oparen) - line = line ")" - return line -} -BEGIN { - nmodels = nouis = 0 - hfile=HEADERFILE - line = ""; -} -NR == 1 { - VERSION = $0 - gsub("\\$", "", VERSION) - - printf("/* $FreeBSD$ */\n\n") > hfile - printf("/*\n") > hfile - printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n") \ - > hfile - printf(" *\n") > hfile - printf(" * generated from:\n") > hfile - printf(" *\t%s\n", VERSION) > hfile - printf(" */\n") > hfile - - next -} -$1 == "oui" { - nuios++ - - ouiindex[$2] = nouis; # record index for this name, for later. - - ouis[nouis, 1] = $2; # name - ouis[nouis, 2] = $3; # id - printf("#define\tMII_OUI_%s\t%s\t", ouis[nouis, 1], - ouis[nouis, 2]) > hfile - ouis[nouis, 3] = collectline(4, line) - printf("/* %s */\n", ouis[nouis, 3]) > hfile - next -} -$1 == "model" { - nmodels++ - - models[nmodels, 1] = $2; # oui name - models[nmodels, 2] = $3; # model id - models[nmodels, 3] = $4; # id - - printf("#define\tMII_MODEL_%s_%s\t%s\n", models[nmodels, 1], - models[nmodels, 2], models[nmodels, 3]) > hfile - - models[nmodels, 4] = collectline(5, line) - - printf("#define\tMII_STR_%s_%s\t\"%s\"\n", - models[nmodels, 1], models[nmodels, 2], - models[nmodels, 4]) > hfile - - next -} -{ - print $0 > hfile -} diff --git a/src/libs/compat/freebsd_network/mutex.c b/src/libs/compat/freebsd_network/mutex.c deleted file mode 100644 index d7589a8cbe..0000000000 --- a/src/libs/compat/freebsd_network/mutex.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "device.h" - -#include - - -// these methods are bit unfriendly, a bit too much panic() around - -struct mtx Giant; -struct rw_lock ifnet_rwlock; -struct mtx gIdStoreLock; - - -void -mtx_init(struct mtx *mutex, const char *name, const char *type, - int options) -{ - if ((options & MTX_RECURSE) != 0) { - recursive_lock_init_etc(&mutex->u.recursive, name, - MUTEX_FLAG_CLONE_NAME); - } else { - mutex_init_etc(&mutex->u.mutex.lock, name, MUTEX_FLAG_CLONE_NAME); - mutex->u.mutex.owner = -1; - } - - mutex->type = options; -} - - -void -mtx_destroy(struct mtx *mutex) -{ - if ((mutex->type & MTX_RECURSE) != 0) - recursive_lock_destroy(&mutex->u.recursive); - else - mutex_destroy(&mutex->u.mutex.lock); -} - - -status_t -init_mutexes() -{ - mtx_init(&Giant, "Banana Giant", NULL, MTX_DEF); - rw_lock_init(&ifnet_rwlock, "gDevices"); - mtx_init(&gIdStoreLock, "Identity Store", NULL, MTX_DEF); - - return B_OK; -} - - -void -uninit_mutexes() -{ - mtx_destroy(&Giant); - rw_lock_destroy(&ifnet_rwlock); - mtx_destroy(&gIdStoreLock); -} diff --git a/src/libs/compat/freebsd_network/priv.cpp b/src/libs/compat/freebsd_network/priv.cpp deleted file mode 100644 index 61525ba7e7..0000000000 --- a/src/libs/compat/freebsd_network/priv.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ - - -#include - -#include -#include - - -/* - * FreeBSD has a more sophisticated privilege checking system. - * We only check for superuser rights. - */ -int -priv_check(struct thread *thread, int privilegeLevel) -{ - // Note: The thread parameter is ignored intentionally (cf. the comment in - // pcpu.h). Currently calling this function is only valid for the current - // thread. - if (thread_get_current_thread()->team->effective_uid == 0) - return ENOERR; - - return EPERM; -} diff --git a/src/libs/compat/freebsd_network/shared.h b/src/libs/compat/freebsd_network/shared.h deleted file mode 100644 index 51cbba8a1c..0000000000 --- a/src/libs/compat/freebsd_network/shared.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. All Rights Reserved. - * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved. - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Copyright 2004, Marcus Overhagen. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef SHARED_H_ -#define SHARED_H_ - - -#define MAX_DEVICES 8 - - -struct ifnet; - -struct device { - struct device *parent; - struct device *root; - - driver_t *driver; - struct list children; - - uint32 flags; - - char device_name[128]; - int unit; - char nameunit[64]; - const char *description; - void *softc; - void *ivars; - - struct { - int (*probe)(device_t dev); - int (*attach)(device_t dev); - int (*detach)(device_t dev); - int (*suspend)(device_t dev); - int (*resume)(device_t dev); - void (*shutdown)(device_t dev); - - int (*miibus_readreg)(device_t, int, int); - int (*miibus_writereg)(device_t, int, int, int); - void (*miibus_statchg)(device_t); - void (*miibus_linkchg)(device_t); - void (*miibus_mediainit)(device_t); - } methods; - - struct list_link link; -}; - - -extern const char *gDeviceNameList[]; -extern struct ifnet *gDevices[]; -extern int32 gDeviceCount; - -#endif /* SHARED_H_ */ diff --git a/src/libs/compat/freebsd_network/synch.c b/src/libs/compat/freebsd_network/synch.c deleted file mode 100644 index 8f872636ba..0000000000 --- a/src/libs/compat/freebsd_network/synch.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2009 Colin Günther, coling@gmx.de - * All rights reserved. Distributed under the terms of the MIT License. - */ - - -#include -#include -#include -#include - -#include "Condvar.h" - - -int -msleep(void* identifier, struct mtx* mutex, int priority, - const char* description, int timeout) -{ - int status; - struct cv sleep; - - conditionPublish(&sleep, identifier, description); - - mtx_unlock(mutex); - status = publishedConditionTimedWait(identifier, timeout); - mtx_lock(mutex); - - conditionUnpublish(&sleep); - - return status; -} - - -void -wakeup(void* identifier) -{ - publishedConditionNotifyAll(identifier); -} - - -int -_pause(const char* waitMessage, int timeout) -{ - int waitChannel; - KASSERT(timeout != 0, ("pause: timeout required")); - return tsleep(&waitChannel, 0, waitMessage, timeout); -} diff --git a/src/libs/compat/freebsd_network/systm.c b/src/libs/compat/freebsd_network/systm.c deleted file mode 100644 index 830f6df71b..0000000000 --- a/src/libs/compat/freebsd_network/systm.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012, Jérôme Duval, korli@users.berlios.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ - - -#include - - -void -freeenv(char *env) -{ -} - - -char * -getenv(const char *name) -{ - return NULL; -} diff --git a/src/libs/compat/freebsd_network/taskqueue.c b/src/libs/compat/freebsd_network/taskqueue.c deleted file mode 100644 index b4cf6d1c35..0000000000 --- a/src/libs/compat/freebsd_network/taskqueue.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de - * Copyright 2007, Hugo Santos. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Hugo Santos, hugosantos@gmail.com - */ - - -#include "device.h" - -#include - -#include -#include - - -#define TQ_FLAGS_ACTIVE (1 << 0) -#define TQ_FLAGS_BLOCKED (1 << 1) -#define TQ_FLAGS_PENDING (1 << 2) - - -struct taskqueue { - char tq_name[64]; - mutex tq_mutex; - struct list tq_list; - taskqueue_enqueue_fn tq_enqueue; - void *tq_arg; - int tq_fast; - spinlock tq_spinlock; - sem_id tq_sem; - thread_id *tq_threads; - thread_id tq_thread_storage; - int tq_threadcount; - int tq_flags; -}; - -struct taskqueue *taskqueue_fast = NULL; -struct taskqueue *taskqueue_swi = NULL; - - -static struct taskqueue * -_taskqueue_create(const char *name, int mflags, int fast, - taskqueue_enqueue_fn enqueueFunction, void *context) -{ - struct taskqueue *tq = malloc(sizeof(struct taskqueue)); - if (tq == NULL) - return NULL; - - tq->tq_fast = fast; - - if (fast) { - B_INITIALIZE_SPINLOCK(&tq->tq_spinlock); - } else { - mutex_init_etc(&tq->tq_mutex, name, MUTEX_FLAG_CLONE_NAME); - } - - strlcpy(tq->tq_name, name, sizeof(tq->tq_name)); - list_init_etc(&tq->tq_list, offsetof(struct task, ta_link)); - tq->tq_enqueue = enqueueFunction; - tq->tq_arg = context; - - tq->tq_sem = -1; - tq->tq_threads = NULL; - tq->tq_threadcount = 0; - tq->tq_flags = TQ_FLAGS_ACTIVE; - - return tq; -} - - -static void -tq_lock(struct taskqueue *taskQueue, cpu_status *status) -{ - if (taskQueue->tq_fast) { - *status = disable_interrupts(); - acquire_spinlock(&taskQueue->tq_spinlock); - } else { - mutex_lock(&taskQueue->tq_mutex); - } -} - - -static void -tq_unlock(struct taskqueue *taskQueue, cpu_status status) -{ - if (taskQueue->tq_fast) { - release_spinlock(&taskQueue->tq_spinlock); - restore_interrupts(status); - } else { - mutex_unlock(&taskQueue->tq_mutex); - } -} - - -struct taskqueue * -taskqueue_create(const char *name, int mflags, - taskqueue_enqueue_fn enqueueFunction, void *context) -{ - return _taskqueue_create(name, mflags, 0, enqueueFunction, context); -} - - -static int32 -tq_handle_thread(void *data) -{ - struct taskqueue *tq = data; - cpu_status cpu_state; - struct task *t; - int pending; - sem_id sem; - - /* just a synchronization point */ - tq_lock(tq, &cpu_state); - sem = tq->tq_sem; - tq_unlock(tq, cpu_state); - - while (acquire_sem(sem) == B_NO_ERROR) { - tq_lock(tq, &cpu_state); - t = list_remove_head_item(&tq->tq_list); - tq_unlock(tq, cpu_state); - if (t == NULL) - continue; - pending = t->ta_pending; - t->ta_pending = 0; - - t->ta_handler(t->ta_argument, pending); - } - - return 0; -} - - -static int -_taskqueue_start_threads(struct taskqueue **taskQueue, int count, int priority, - const char *name) -{ - struct taskqueue *tq = (*taskQueue); - int i, j; - - if (count == 0) - return -1; - - if (tq->tq_threads != NULL) - return -1; - - if (count == 1) { - tq->tq_threads = &tq->tq_thread_storage; - } else { - tq->tq_threads = malloc(sizeof(thread_id) * count); - if (tq->tq_threads == NULL) - return B_NO_MEMORY; - } - - tq->tq_sem = create_sem(0, tq->tq_name); - if (tq->tq_sem < B_OK) { - if (count > 1) - free(tq->tq_threads); - tq->tq_threads = NULL; - return tq->tq_sem; - } - - for (i = 0; i < count; i++) { - tq->tq_threads[i] = spawn_kernel_thread(tq_handle_thread, tq->tq_name, - priority, tq); - if (tq->tq_threads[i] < B_OK) { - status_t status = tq->tq_threads[i]; - for (j = 0; j < i; j++) - kill_thread(tq->tq_threads[j]); - if (count > 1) - free(tq->tq_threads); - tq->tq_threads = NULL; - delete_sem(tq->tq_sem); - return status; - } - } - - tq->tq_threadcount = count; - - for (i = 0; i < count; i++) - resume_thread(tq->tq_threads[i]); - - return 0; -} - - -int -taskqueue_start_threads(struct taskqueue **taskQueue, int count, int priority, - const char *format, ...) -{ - /* we assume that start_threads is called in a sane place, and thus - * don't need to be locked. This is mostly due to the fact that if - * the TQ is 'fast', locking the TQ disables interrupts... and then - * we can't create semaphores, threads and bananas. */ - - /* cpu_status state; */ - char name[64]; - int result; - va_list vl; - - va_start(vl, format); - vsnprintf(name, sizeof(name), format, vl); - va_end(vl); - - /*tq_lock(*tqp, &state);*/ - result = _taskqueue_start_threads(taskQueue, count, priority, name); - /*tq_unlock(*tqp, state);*/ - - return result; -} - - -void -taskqueue_free(struct taskqueue *taskQueue) -{ - /* lock and drain list? */ - taskQueue->tq_flags &= ~TQ_FLAGS_ACTIVE; - if (!taskQueue->tq_fast) - mutex_destroy(&taskQueue->tq_mutex); - if (taskQueue->tq_sem != -1) { - int i; - - delete_sem(taskQueue->tq_sem); - - for (i = 0; i < taskQueue->tq_threadcount; i++) { - status_t status; - wait_for_thread(taskQueue->tq_threads[i], &status); - } - - if (taskQueue->tq_threadcount > 1) - free(taskQueue->tq_threads); - } - - free(taskQueue); -} - - -void -taskqueue_drain(struct taskqueue *taskQueue, struct task *task) -{ - cpu_status status; - - tq_lock(taskQueue, &status); - while (task->ta_pending != 0) { - tq_unlock(taskQueue, status); - snooze(0); - tq_lock(taskQueue, &status); - } - tq_unlock(taskQueue, status); -} - - -int -taskqueue_enqueue(struct taskqueue *taskQueue, struct task *task) -{ - cpu_status status; - tq_lock(taskQueue, &status); - /* we don't really support priorities */ - if (task->ta_pending) { - task->ta_pending++; - } else { - list_add_item(&taskQueue->tq_list, task); - task->ta_pending = 1; - if ((taskQueue->tq_flags & TQ_FLAGS_BLOCKED) == 0) - taskQueue->tq_enqueue(taskQueue->tq_arg); - else - taskQueue->tq_flags |= TQ_FLAGS_PENDING; - } - tq_unlock(taskQueue, status); - return 0; -} - - -void -taskqueue_thread_enqueue(void *context) -{ - struct taskqueue **tqp = context; - release_sem_etc((*tqp)->tq_sem, 1, B_DO_NOT_RESCHEDULE); -} - - -int -taskqueue_enqueue_fast(struct taskqueue *taskQueue, struct task *task) -{ - return taskqueue_enqueue(taskQueue, task); -} - - -struct taskqueue * -taskqueue_create_fast(const char *name, int mflags, - taskqueue_enqueue_fn enqueueFunction, void *context) -{ - return _taskqueue_create(name, mflags, 1, enqueueFunction, context); -} - - -void -task_init(struct task *task, int prio, task_handler_t handler, void *context) -{ - task->ta_priority = prio; - task->ta_handler = handler; - task->ta_argument = context; - task->ta_pending = 0; -} - - -status_t -init_taskqueues() -{ - status_t status = B_NO_MEMORY; - - if (HAIKU_DRIVER_REQUIRES(FBSD_FAST_TASKQUEUE)) { - taskqueue_fast = taskqueue_create_fast("fast taskq", 0, - taskqueue_thread_enqueue, &taskqueue_fast); - if (taskqueue_fast == NULL) - return B_NO_MEMORY; - - status = taskqueue_start_threads(&taskqueue_fast, 1, - B_REAL_TIME_PRIORITY, "fast taskq thread"); - if (status < B_OK) - goto err_1; - } - - if (HAIKU_DRIVER_REQUIRES(FBSD_SWI_TASKQUEUE)) { - taskqueue_swi = taskqueue_create_fast("swi taskq", 0, - taskqueue_thread_enqueue, &taskqueue_swi); - if (taskqueue_swi == NULL) { - status = B_NO_MEMORY; - goto err_1; - } - - status = taskqueue_start_threads(&taskqueue_swi, 1, - B_REAL_TIME_PRIORITY, "swi taskq"); - if (status < B_OK) - goto err_2; - } - - return B_OK; - -err_2: - if (taskqueue_swi) - taskqueue_free(taskqueue_swi); - -err_1: - if (taskqueue_fast) - taskqueue_free(taskqueue_fast); - - return status; -} - - -void -uninit_taskqueues() -{ - if (HAIKU_DRIVER_REQUIRES(FBSD_SWI_TASKQUEUE)) - taskqueue_free(taskqueue_swi); - - if (HAIKU_DRIVER_REQUIRES(FBSD_FAST_TASKQUEUE)) - taskqueue_free(taskqueue_fast); -} - - -void -taskqueue_block(struct taskqueue *taskQueue) -{ - cpu_status status; - - tq_lock(taskQueue, &status); - taskQueue->tq_flags |= TQ_FLAGS_BLOCKED; - tq_unlock(taskQueue, status); -} - - -void -taskqueue_unblock(struct taskqueue *taskQueue) -{ - cpu_status status; - - tq_lock(taskQueue, &status); - taskQueue->tq_flags &= ~TQ_FLAGS_BLOCKED; - if (taskQueue->tq_flags & TQ_FLAGS_PENDING) { - taskQueue->tq_flags &= ~TQ_FLAGS_PENDING; - taskQueue->tq_enqueue(taskQueue->tq_arg); - } - tq_unlock(taskQueue, status); -} diff --git a/src/libs/compat/freebsd_network/unit.c b/src/libs/compat/freebsd_network/unit.c deleted file mode 100644 index 0053875eef..0000000000 --- a/src/libs/compat/freebsd_network/unit.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2009 Colin Günther, coling@gmx.de - * All Rights Reserved. Distributed under the terms of the MIT License. - * - */ - - -/*! Implementation of a number allocator.*/ - - -#include "unit.h" - -#include - -#include - - -extern struct mtx gIdStoreLock; - - -struct unrhdr* -new_unrhdr(int low, int high, struct mtx* mutex) -{ - struct unrhdr* idStore; - uint32 maxIdCount = high - low + 1; - - KASSERT(low <= high, - ("ID-Store: use error: %s(%u, %u)", __func__, low, high)); - - idStore = malloc(sizeof *idStore); - if (idStore == NULL) - return NULL; - - if (_new_unrhdr_buffer(idStore, maxIdCount) != B_OK) { - free(idStore); - return NULL; - } - - if (mutex) - idStore->storeMutex = mutex; - else - idStore->storeMutex = &gIdStoreLock; - - idStore->idBias = low; - - return idStore; -} - - -void -delete_unrhdr(struct unrhdr* idStore) -{ - KASSERT(uh != NULL, - ("ID-Store: %s: NULL pointer as argument.", __func__)); - - mtx_lock(idStore->storeMutex); - - KASSERT(uh->idBuffer->root_size == 0, - ("ID-Store: %s: some ids are still in use..", __func__)); - - _delete_unrhdr_buffer_locked(idStore); - mtx_unlock(idStore->storeMutex); - - free(idStore); - idStore = NULL; -} - - -int -alloc_unr(struct unrhdr* idStore) -{ - int id; - - KASSERT(uh != NULL, - ("ID-Store: %s: NULL pointer as argument.", __func__)); - - mtx_lock(idStore->storeMutex); - id = _alloc_unr_locked(idStore); - mtx_unlock(idStore->storeMutex); - - return id; -} - - -void -free_unr(struct unrhdr* idStore, u_int identity) -{ - KASSERT(uh != NULL, - ("ID-Store: %s: NULL pointer as argument.", __func__)); - - mtx_lock(idStore->storeMutex); - - KASSERT((int32)item - uh->idBias >= 0, ("ID-Store: %s(%p, %u): second " - + "parameter is not in interval.", __func__, uh, item)); - - _free_unr_locked(idStore, identity); - - mtx_unlock(idStore->storeMutex); -} diff --git a/src/libs/compat/freebsd_network/unit.h b/src/libs/compat/freebsd_network/unit.h deleted file mode 100644 index a975675112..0000000000 --- a/src/libs/compat/freebsd_network/unit.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2009 Colin Günther, coling@gmx.de - * All Rights Reserved. Distributed under the terms of the MIT License. - */ -#ifndef UNIT_H_ -#define UNIT_H_ - - -#include - - -struct radix_bitmap; -struct unrhdr { - struct radix_bitmap* idBuffer; - struct mtx* storeMutex; - int32 idBias; -}; - - -#ifdef __cplusplus -extern "C" { -#endif - -status_t _new_unrhdr_buffer(struct unrhdr*, uint32); -void _delete_unrhdr_buffer_locked(struct unrhdr*); -int _alloc_unr_locked(struct unrhdr*); -void _free_unr_locked(struct unrhdr*, u_int); - -#ifdef __cplusplus -} -#endif - -#endif /* UNIT_H_ */ diff --git a/src/libs/compat/freebsd_wlan/Jamfile b/src/libs/compat/freebsd_wlan/Jamfile deleted file mode 100644 index ec45e4b5f9..0000000000 --- a/src/libs/compat/freebsd_wlan/Jamfile +++ /dev/null @@ -1,4 +0,0 @@ -SubDir HAIKU_TOP src libs compat freebsd_wlan ; - -SubInclude HAIKU_TOP src libs compat freebsd_wlan net80211 ; - diff --git a/src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael-alg-fst.c b/src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael-alg-fst.c deleted file mode 100644 index 5197e226a2..0000000000 --- a/src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael-alg-fst.c +++ /dev/null @@ -1,1223 +0,0 @@ -/* $KAME: rijndael-alg-fst.c,v 1.10 2003/07/15 10:47:16 itojun Exp $ */ -/** - * rijndael-alg-fst.c - * - * @version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen - * @author Antoon Bosselaers - * @author Paulo Barreto - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#ifdef _KERNEL -#include -#else -#include -#include -#define KASSERT(exp, msg) assert(exp) -#endif - -#include -#include - -/* -Te0[x] = S [x].[02, 01, 01, 03]; -Te1[x] = S [x].[03, 02, 01, 01]; -Te2[x] = S [x].[01, 03, 02, 01]; -Te3[x] = S [x].[01, 01, 03, 02]; -Te4[x] = S [x].[01, 01, 01, 01]; - -Td0[x] = Si[x].[0e, 09, 0d, 0b]; -Td1[x] = Si[x].[0b, 0e, 09, 0d]; -Td2[x] = Si[x].[0d, 0b, 0e, 09]; -Td3[x] = Si[x].[09, 0d, 0b, 0e]; -Td4[x] = Si[x].[01, 01, 01, 01]; -*/ - -static const u32 Te0[256] = { - 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, - 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, - 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, - 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, - 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, - 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, - 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, - 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, - 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, - 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, - 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, - 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, - 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, - 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, - 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, - 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, - 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, - 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, - 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, - 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, - 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, - 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, - 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, - 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, - 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, - 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, - 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, - 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, - 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, - 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, - 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, - 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, - 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, - 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, - 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, - 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, - 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, - 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, - 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, - 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, - 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, - 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, - 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, - 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, - 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, - 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, - 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, - 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, - 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, - 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, - 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, - 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, - 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, - 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, - 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, - 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, - 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, - 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, - 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, - 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, - 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, - 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, - 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, - 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, -}; -static const u32 Te1[256] = { - 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, - 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, - 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, - 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, - 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, - 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, - 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, - 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, - 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, - 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, - 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, - 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, - 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, - 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, - 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, - 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, - 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, - 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, - 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, - 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, - 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, - 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, - 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, - 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, - 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, - 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, - 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, - 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, - 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, - 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, - 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, - 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, - 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, - 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, - 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, - 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, - 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, - 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, - 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, - 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, - 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, - 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, - 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, - 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, - 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, - 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, - 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, - 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, - 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, - 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, - 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, - 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, - 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, - 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, - 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, - 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, - 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, - 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, - 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, - 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, - 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, - 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, - 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, - 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, -}; -static const u32 Te2[256] = { - 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, - 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, - 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, - 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, - 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, - 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, - 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, - 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, - 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, - 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, - 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, - 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, - 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, - 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, - 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, - 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, - 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, - 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, - 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, - 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, - 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, - 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, - 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, - 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, - 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, - 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, - 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, - 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, - 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, - 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, - 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, - 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, - 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, - 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, - 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, - 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, - 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, - 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, - 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, - 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, - 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, - 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, - 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, - 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, - 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, - 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, - 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, - 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, - 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, - 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, - 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, - 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, - 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, - 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, - 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, - 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, - 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, - 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, - 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, - 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, - 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, - 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, - 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, - 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, -}; -static const u32 Te3[256] = { - - 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, - 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, - 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, - 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, - 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, - 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, - 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, - 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, - 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, - 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, - 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, - 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, - 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, - 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, - 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, - 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, - 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, - 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, - 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, - 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, - 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, - 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, - 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, - 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, - 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, - 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, - 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, - 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, - 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, - 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, - 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, - 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, - 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, - 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, - 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, - 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, - 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, - 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, - 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, - 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, - 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, - 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, - 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, - 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, - 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, - 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, - 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, - 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, - 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, - 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, - 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, - 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, - 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, - 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, - 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, - 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, - 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, - 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, - 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, - 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, - 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, - 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, - 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, - 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, -}; -static const u32 Te4[256] = { - 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, - 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, - 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, - 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, - 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, - 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, - 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, - 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, - 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, - 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, - 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, - 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, - 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, - 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, - 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, - 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, - 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, - 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, - 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, - 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, - 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, - 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, - 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, - 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, - 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, - 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, - 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, - 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, - 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, - 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, - 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, - 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, - 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, - 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, - 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, - 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, - 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, - 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, - 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, - 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, - 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, - 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, - 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, - 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, - 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, - 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, - 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, - 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, - 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, - 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, - 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, - 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, - 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, - 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, - 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, - 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, - 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, - 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, - 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, - 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, - 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, - 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, - 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, - 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, -}; -static const u32 Td0[256] = { - 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, - 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, - 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, - 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, - 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, - 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, - 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, - 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, - 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, - 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, - 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, - 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, - 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, - 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, - 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, - 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, - 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, - 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, - 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, - 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, - 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, - 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, - 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, - 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, - 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, - 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, - 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, - 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, - 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, - 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, - 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, - 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, - 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, - 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, - 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, - 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, - 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, - 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, - 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, - 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, - 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, - 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, - 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, - 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, - 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, - 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, - 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, - 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, - 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, - 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, - 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, - 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, - 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, - 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, - 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, - 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, - 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, - 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, - 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, - 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, - 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, - 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, - 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, - 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, -}; -static const u32 Td1[256] = { - 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, - 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, - 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, - 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, - 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, - 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, - 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, - 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, - 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, - 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, - 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, - 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, - 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, - 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, - 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, - 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, - 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, - 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, - 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, - 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, - 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, - 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, - 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, - 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, - 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, - 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, - 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, - 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, - 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, - 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, - 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, - 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, - 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, - 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, - 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, - 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, - 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, - 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, - 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, - 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, - 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, - 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, - 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, - 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, - 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, - 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, - 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, - 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, - 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, - 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, - 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, - 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, - 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, - 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, - 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, - 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, - 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, - 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, - 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, - 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, - 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, - 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, - 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, - 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, -}; -static const u32 Td2[256] = { - 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, - 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, - 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, - 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, - 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, - 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, - 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, - 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, - 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, - 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, - 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, - 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, - 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, - 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, - 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, - 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, - 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, - 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, - 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, - 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, - - 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, - 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, - 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, - 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, - 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, - 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, - 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, - 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, - 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, - 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, - 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, - 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, - 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, - 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, - 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, - 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, - 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, - 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, - 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, - 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, - 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, - 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, - 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, - 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, - 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, - 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, - 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, - 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, - 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, - 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, - 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, - 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, - 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, - 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, - 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, - 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, - 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, - 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, - 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, - 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, - 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, - 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, - 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, - 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, -}; -static const u32 Td3[256] = { - 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, - 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, - 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, - 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, - 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, - 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, - 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, - 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, - 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, - 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, - 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, - 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, - 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, - 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, - 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, - 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, - 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, - 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, - 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, - 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, - 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, - 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, - 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, - 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, - 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, - 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, - 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, - 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, - 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, - 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, - 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, - 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, - 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, - 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, - 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, - 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, - 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, - 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, - 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, - 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, - 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, - 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, - 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, - 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, - 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, - 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, - 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, - 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, - 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, - 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, - 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, - 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, - 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, - 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, - 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, - 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, - 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, - 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, - 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, - 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, - 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, - 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, - 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, - 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, -}; -static const u32 Td4[256] = { - 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, - 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, - 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, - 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, - 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, - 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, - 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, - 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, - 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, - 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, - 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, - 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, - 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, - 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, - 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, - 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, - 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, - 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, - 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, - 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, - 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, - 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, - 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, - 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, - 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, - 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, - 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, - 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, - 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, - 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, - 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, - 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, - 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, - 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, - 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, - 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, - 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, - 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, - 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, - 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, - 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, - 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, - 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, - 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, - 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, - 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, - 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, - 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, - 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, - 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, - 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, - 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, - 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, - 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, - 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, - 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, - 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, - 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, - 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, - 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, - 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, - 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, - 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, - 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, -}; -static const u32 rcon[] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ -}; - -#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) - -#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) -#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } - -/** - * Expand the cipher key into the encryption key schedule. - * - * @return the number of rounds for the given cipher key size. - */ -int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) { - int i = 0; - u32 temp; - - KASSERT(keyBits == 128 || keyBits == 192 || keyBits == 256, - ("Invalid key size (%d).", keyBits)); - rk[0] = GETU32(cipherKey ); - rk[1] = GETU32(cipherKey + 4); - rk[2] = GETU32(cipherKey + 8); - rk[3] = GETU32(cipherKey + 12); - if (keyBits == 128) { - for (;;) { - temp = rk[3]; - rk[4] = rk[0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - if (++i == 10) { - return 10; - } - rk += 4; - } - } - rk[4] = GETU32(cipherKey + 16); - rk[5] = GETU32(cipherKey + 20); - if (keyBits == 192) { - for (;;) { - temp = rk[ 5]; - rk[ 6] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 7] = rk[ 1] ^ rk[ 6]; - rk[ 8] = rk[ 2] ^ rk[ 7]; - rk[ 9] = rk[ 3] ^ rk[ 8]; - if (++i == 8) { - return 12; - } - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; - rk += 6; - } - } - rk[6] = GETU32(cipherKey + 24); - rk[7] = GETU32(cipherKey + 28); - if (keyBits == 256) { - for (;;) { - temp = rk[ 7]; - rk[ 8] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 9] = rk[ 1] ^ rk[ 8]; - rk[10] = rk[ 2] ^ rk[ 9]; - rk[11] = rk[ 3] ^ rk[10]; - if (++i == 7) { - return 14; - } - temp = rk[11]; - rk[12] = rk[ 4] ^ - (Te4[(temp >> 24) ] & 0xff000000) ^ - (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(temp ) & 0xff] & 0x000000ff); - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; - - rk += 8; - } - } - return 0; -} - -/** - * Expand the cipher key into the decryption key schedule. - * - * @return the number of rounds for the given cipher key size. - */ -int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) { - int Nr, i, j; - u32 temp; - - /* expand the cipher key: */ - Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); - /* invert the order of the round keys: */ - for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { - temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; - temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; - temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; - temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; - } - /* apply the inverse MixColumn transform to all round keys but the first and the last: */ - for (i = 1; i < Nr; i++) { - rk += 4; - rk[0] = - Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[0] ) & 0xff] & 0xff]; - rk[1] = - Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[1] ) & 0xff] & 0xff]; - rk[2] = - Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[2] ) & 0xff] & 0xff]; - rk[3] = - Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[3] ) & 0xff] & 0xff]; - } - return Nr; -} - -void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) { - u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(pt ) ^ rk[0]; - s1 = GETU32(pt + 4) ^ rk[1]; - s2 = GETU32(pt + 8) ^ rk[2]; - s3 = GETU32(pt + 12) ^ rk[3]; -#ifdef FULL_UNROLL - /* round 1: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; - /* round 2: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; - /* round 3: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; - /* round 4: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; - /* round 5: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; - /* round 6: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; - /* round 7: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; - /* round 8: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; - /* round 9: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; - if (Nr > 10) { - /* round 10: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; - /* round 11: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; - if (Nr > 12) { - /* round 12: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; - /* round 13: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; - } - } - rk += Nr << 2; -#else /* !FULL_UNROLL */ - /* - * Nr - 1 full rounds: - */ - r = Nr >> 1; - for (;;) { - t0 = - Te0[(s0 >> 24) ] ^ - Te1[(s1 >> 16) & 0xff] ^ - Te2[(s2 >> 8) & 0xff] ^ - Te3[(s3 ) & 0xff] ^ - rk[4]; - t1 = - Te0[(s1 >> 24) ] ^ - Te1[(s2 >> 16) & 0xff] ^ - Te2[(s3 >> 8) & 0xff] ^ - Te3[(s0 ) & 0xff] ^ - rk[5]; - t2 = - Te0[(s2 >> 24) ] ^ - Te1[(s3 >> 16) & 0xff] ^ - Te2[(s0 >> 8) & 0xff] ^ - Te3[(s1 ) & 0xff] ^ - rk[6]; - t3 = - Te0[(s3 >> 24) ] ^ - Te1[(s0 >> 16) & 0xff] ^ - Te2[(s1 >> 8) & 0xff] ^ - Te3[(s2 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - Te0[(t0 >> 24) ] ^ - Te1[(t1 >> 16) & 0xff] ^ - Te2[(t2 >> 8) & 0xff] ^ - Te3[(t3 ) & 0xff] ^ - rk[0]; - s1 = - Te0[(t1 >> 24) ] ^ - Te1[(t2 >> 16) & 0xff] ^ - Te2[(t3 >> 8) & 0xff] ^ - Te3[(t0 ) & 0xff] ^ - rk[1]; - s2 = - Te0[(t2 >> 24) ] ^ - Te1[(t3 >> 16) & 0xff] ^ - Te2[(t0 >> 8) & 0xff] ^ - Te3[(t1 ) & 0xff] ^ - rk[2]; - s3 = - Te0[(t3 >> 24) ] ^ - Te1[(t0 >> 16) & 0xff] ^ - Te2[(t1 >> 8) & 0xff] ^ - Te3[(t2 ) & 0xff] ^ - rk[3]; - } -#endif /* ?FULL_UNROLL */ - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Te4[(t0 >> 24) ] & 0xff000000) ^ - (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(ct , s0); - s1 = - (Te4[(t1 >> 24) ] & 0xff000000) ^ - (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(ct + 4, s1); - s2 = - (Te4[(t2 >> 24) ] & 0xff000000) ^ - (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(ct + 8, s2); - s3 = - (Te4[(t3 >> 24) ] & 0xff000000) ^ - (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(ct + 12, s3); -} - -void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]) { - u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(ct ) ^ rk[0]; - s1 = GETU32(ct + 4) ^ rk[1]; - s2 = GETU32(ct + 8) ^ rk[2]; - s3 = GETU32(ct + 12) ^ rk[3]; -#ifdef FULL_UNROLL - /* round 1: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; - /* round 2: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; - /* round 3: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; - /* round 4: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; - /* round 5: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; - /* round 6: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; - /* round 7: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; - /* round 8: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; - /* round 9: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; - if (Nr > 10) { - /* round 10: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; - /* round 11: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; - if (Nr > 12) { - /* round 12: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; - /* round 13: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; - } - } - rk += Nr << 2; -#else /* !FULL_UNROLL */ - /* - * Nr - 1 full rounds: - */ - r = Nr >> 1; - for (;;) { - t0 = - Td0[(s0 >> 24) ] ^ - Td1[(s3 >> 16) & 0xff] ^ - Td2[(s2 >> 8) & 0xff] ^ - Td3[(s1 ) & 0xff] ^ - rk[4]; - t1 = - Td0[(s1 >> 24) ] ^ - Td1[(s0 >> 16) & 0xff] ^ - Td2[(s3 >> 8) & 0xff] ^ - Td3[(s2 ) & 0xff] ^ - rk[5]; - t2 = - Td0[(s2 >> 24) ] ^ - Td1[(s1 >> 16) & 0xff] ^ - Td2[(s0 >> 8) & 0xff] ^ - Td3[(s3 ) & 0xff] ^ - rk[6]; - t3 = - Td0[(s3 >> 24) ] ^ - Td1[(s2 >> 16) & 0xff] ^ - Td2[(s1 >> 8) & 0xff] ^ - Td3[(s0 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - Td0[(t0 >> 24) ] ^ - Td1[(t3 >> 16) & 0xff] ^ - Td2[(t2 >> 8) & 0xff] ^ - Td3[(t1 ) & 0xff] ^ - rk[0]; - s1 = - Td0[(t1 >> 24) ] ^ - Td1[(t0 >> 16) & 0xff] ^ - Td2[(t3 >> 8) & 0xff] ^ - Td3[(t2 ) & 0xff] ^ - rk[1]; - s2 = - Td0[(t2 >> 24) ] ^ - Td1[(t1 >> 16) & 0xff] ^ - Td2[(t0 >> 8) & 0xff] ^ - Td3[(t3 ) & 0xff] ^ - rk[2]; - s3 = - Td0[(t3 >> 24) ] ^ - Td1[(t2 >> 16) & 0xff] ^ - Td2[(t1 >> 8) & 0xff] ^ - Td3[(t0 ) & 0xff] ^ - rk[3]; - } -#endif /* ?FULL_UNROLL */ - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Td4[(t0 >> 24) ] & 0xff000000) ^ - (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(pt , s0); - s1 = - (Td4[(t1 >> 24) ] & 0xff000000) ^ - (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(pt + 4, s1); - s2 = - (Td4[(t2 >> 24) ] & 0xff000000) ^ - (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(pt + 8, s2); - s3 = - (Td4[(t3 >> 24) ] & 0xff000000) ^ - (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(pt + 12, s3); -} diff --git a/src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael-api.c b/src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael-api.c deleted file mode 100644 index 47de142149..0000000000 --- a/src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael-api.c +++ /dev/null @@ -1,59 +0,0 @@ -/* $KAME: rijndael.c,v 1.3 2003/08/28 14:20:22 itojun Exp $ */ - -/* - * rijndael-alg-fst.c - * - * @version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen - * @author Antoon Bosselaers - * @author Paulo Barreto - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#ifdef _KERNEL -#include -#endif - -#include - -void -rijndael_set_key(rijndael_ctx *ctx, const u_char *key, int bits) -{ - - ctx->Nr = rijndaelKeySetupEnc(ctx->ek, key, bits); - rijndaelKeySetupDec(ctx->dk, key, bits); -} - -void -rijndael_decrypt(const rijndael_ctx *ctx, const u_char *src, u_char *dst) -{ - - rijndaelDecrypt(ctx->dk, ctx->Nr, src, dst); -} - -void -rijndael_encrypt(const rijndael_ctx *ctx, const u_char *src, u_char *dst) -{ - - rijndaelEncrypt(ctx->ek, ctx->Nr, src, dst); -} diff --git a/src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael.h b/src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael.h deleted file mode 100644 index da855284dc..0000000000 --- a/src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael.h +++ /dev/null @@ -1,55 +0,0 @@ -/* $KAME: rijndael.h,v 1.6 2003/08/28 08:36:32 itojun Exp $ */ -/* $FreeBSD$ */ - -/** - * rijndael-alg-fst.h - * - * @version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen - * @author Antoon Bosselaers - * @author Paulo Barreto - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __RIJNDAEL_H -#define __RIJNDAEL_H - -#define RIJNDAEL_MAXKC (256/32) -#define RIJNDAEL_MAXKB (256/8) -#define RIJNDAEL_MAXNR 14 - -typedef struct { - int decrypt; - int Nr; /* key-length-dependent number of rounds */ - uint32_t ek[4 * (RIJNDAEL_MAXNR + 1)]; /* encrypt key schedule */ - uint32_t dk[4 * (RIJNDAEL_MAXNR + 1)]; /* decrypt key schedule */ -} rijndael_ctx; - -void rijndael_set_key(rijndael_ctx *, const u_char *, int); -void rijndael_decrypt(const rijndael_ctx *, const u_char *, u_char *); -void rijndael_encrypt(const rijndael_ctx *, const u_char *, u_char *); - -int rijndaelKeySetupEnc(u_int32_t [/*4*(Nr+1)*/], const u_int8_t [], int); -int rijndaelKeySetupDec(u_int32_t [/*4*(Nr+1)*/], const u_int8_t [], int); -void rijndaelEncrypt(const u_int32_t [/*4*(Nr+1)*/], int, - const u_int8_t[16], u_int8_t [16]); -void rijndaelDecrypt(const u_int32_t [/*4*(Nr+1)*/], int, - const u_int8_t [16], u_int8_t [16]); - -#endif /* __RIJNDAEL_H */ diff --git a/src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael_local.h b/src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael_local.h deleted file mode 100644 index 7c765a2b11..0000000000 --- a/src/libs/compat/freebsd_wlan/crypto/rijndael/rijndael_local.h +++ /dev/null @@ -1,7 +0,0 @@ -/* $KAME: rijndael_local.h,v 1.5 2003/08/28 08:37:24 itojun Exp $ */ -/* $FreeBSD$ */ - -/* the file should not be used from outside */ -typedef u_int8_t u8; -typedef u_int16_t u16; -typedef u_int32_t u32; diff --git a/src/libs/compat/freebsd_wlan/net80211/Jamfile b/src/libs/compat/freebsd_wlan/net80211/Jamfile deleted file mode 100644 index bff3d75686..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/Jamfile +++ /dev/null @@ -1,65 +0,0 @@ -SubDir HAIKU_TOP src libs compat freebsd_wlan net80211 ; - -UseHeaders [ FDirName $(SUBDIR) .. .. freebsd_network ] : true ; -UseHeaders [ FDirName $(SUBDIR) .. .. freebsd_network compat ] : true ; -UseHeaders [ FDirName $(SUBDIR) .. ] : true ; -UseHeaders [ FDirName $(SUBDIR) ] : true ; -UsePrivateHeaders net system ; -UsePrivateKernelHeaders ; - -# Enabling C++ structures in C only code -Includes [ FGristFiles kernel_c++_structs.h ] - : kernel_c++_struct_sizes.h ; - -SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] - -Wno-format -Wno-unused -Wno-uninitialized ; -SubDirC++Flags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] - -Wno-format -Wno-unused -Wno-uninitialized ; - -SEARCH_SOURCE += [ FDirName $(SUBDIR) .. crypto rijndael ] ; - -KernelStaticLibrary libfreebsd_wlan.a : - ieee80211.c - ieee80211_action.c - ieee80211_adhoc.c - ieee80211_ageq.c - ieee80211_amrr.c - ieee80211_crypto.c - ieee80211_crypto_ccmp.c - ieee80211_crypto_none.c - ieee80211_crypto_tkip.c - ieee80211_crypto_wep.c - ieee80211_dfs.c - ieee80211_haiku.cpp - ieee80211_ht.c - ieee80211_input.c - ieee80211_ioctl.c - ieee80211_hostap.c - ieee80211_monitor.c - ieee80211_node.c - ieee80211_output.c - ieee80211_phy.c - ieee80211_power.c - ieee80211_proto.c - ieee80211_radiotap.c - ieee80211_ratectl.c - ieee80211_ratectl_none.c - ieee80211_regdomain.c - ieee80211_rssadapt.c - ieee80211_scan_sta.c - ieee80211_scan.c - ieee80211_sta.c - ieee80211_wds.c - - # Rijndael (aka AES) cryptographic support for crypto_ccmp - rijndael-alg-fst.c - rijndael-api.c - - # NOT SUPPORTED YET ieee80211_acl.c - # NOT SUPPORTED YET ieee80211_ddb.c - # NOT SUPPORTED YET ieee80211_hwmp.c - # NOT SUPPORTED YET ieee80211_mesh.c - # NOT SUPPORTED YET ieee80211_superg.c - # NOT SUPPORTED YET ieee80211_tdma.c - ieee80211_xauth.c -; diff --git a/src/libs/compat/freebsd_wlan/net80211/_ieee80211.h b/src/libs/compat/freebsd_wlan/net80211/_ieee80211.h deleted file mode 100644 index 7cbc684fef..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/_ieee80211.h +++ /dev/null @@ -1,403 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211__IEEE80211_H_ -#define _FBSD_COMPAT_NET80211__IEEE80211_H_ - -/* - * 802.11 implementation definitions. - * - * NB: this file is used by applications. - */ - -/* - * PHY type; mostly used to identify FH phys. - */ -enum ieee80211_phytype { - IEEE80211_T_DS, /* direct sequence spread spectrum */ - IEEE80211_T_FH, /* frequency hopping */ - IEEE80211_T_OFDM, /* frequency division multiplexing */ - IEEE80211_T_TURBO, /* high rate OFDM, aka turbo mode */ - IEEE80211_T_HT, /* high throughput */ - IEEE80211_T_OFDM_HALF, /* 1/2 rate OFDM */ - IEEE80211_T_OFDM_QUARTER, /* 1/4 rate OFDM */ -}; -#define IEEE80211_T_CCK IEEE80211_T_DS /* more common nomenclature */ - -/* - * PHY mode; this is not really a mode as multi-mode devices - * have multiple PHY's. Mode is mostly used as a shorthand - * for constraining which channels to consider in setting up - * operation. Modes used to be used more extensively when - * channels were identified as IEEE channel numbers. - */ -enum ieee80211_phymode { - IEEE80211_MODE_AUTO = 0, /* autoselect */ - IEEE80211_MODE_11A = 1, /* 5GHz, OFDM */ - IEEE80211_MODE_11B = 2, /* 2GHz, CCK */ - IEEE80211_MODE_11G = 3, /* 2GHz, OFDM */ - IEEE80211_MODE_FH = 4, /* 2GHz, GFSK */ - IEEE80211_MODE_TURBO_A = 5, /* 5GHz, OFDM, 2x clock */ - IEEE80211_MODE_TURBO_G = 6, /* 2GHz, OFDM, 2x clock */ - IEEE80211_MODE_STURBO_A = 7, /* 5GHz, OFDM, 2x clock, static */ - IEEE80211_MODE_11NA = 8, /* 5GHz, w/ HT */ - IEEE80211_MODE_11NG = 9, /* 2GHz, w/ HT */ - IEEE80211_MODE_HALF = 10, /* OFDM, 1/2x clock */ - IEEE80211_MODE_QUARTER = 11, /* OFDM, 1/4x clock */ -}; -#define IEEE80211_MODE_MAX (IEEE80211_MODE_QUARTER+1) - -/* - * Operating mode. Devices do not necessarily support - * all modes; they indicate which are supported in their - * capabilities. - */ -enum ieee80211_opmode { - IEEE80211_M_IBSS = 0, /* IBSS (adhoc) station */ - IEEE80211_M_STA = 1, /* infrastructure station */ - IEEE80211_M_WDS = 2, /* WDS link */ - IEEE80211_M_AHDEMO = 3, /* Old lucent compatible adhoc demo */ - IEEE80211_M_HOSTAP = 4, /* Software Access Point */ - IEEE80211_M_MONITOR = 5, /* Monitor mode */ - IEEE80211_M_MBSS = 6, /* MBSS (Mesh Point) link */ -}; -#define IEEE80211_OPMODE_MAX (IEEE80211_M_MBSS+1) - -/* - * 802.11g/802.11n protection mode. - */ -enum ieee80211_protmode { - IEEE80211_PROT_NONE = 0, /* no protection */ - IEEE80211_PROT_CTSONLY = 1, /* CTS to self */ - IEEE80211_PROT_RTSCTS = 2, /* RTS-CTS */ -}; - -/* - * Authentication mode. The open and shared key authentication - * modes are implemented within the 802.11 layer. 802.1x and - * WPA/802.11i are implemented in user mode by setting the - * 802.11 layer into IEEE80211_AUTH_8021X and deferring - * authentication to user space programs. - */ -enum ieee80211_authmode { - IEEE80211_AUTH_NONE = 0, - IEEE80211_AUTH_OPEN = 1, /* open */ - IEEE80211_AUTH_SHARED = 2, /* shared-key */ - IEEE80211_AUTH_8021X = 3, /* 802.1x */ - IEEE80211_AUTH_AUTO = 4, /* auto-select/accept */ - /* NB: these are used only for ioctls */ - IEEE80211_AUTH_WPA = 5, /* WPA/RSN w/ 802.1x/PSK */ -}; - -/* - * Roaming mode is effectively who controls the operation - * of the 802.11 state machine when operating as a station. - * State transitions are controlled either by the driver - * (typically when management frames are processed by the - * hardware/firmware), the host (auto/normal operation of - * the 802.11 layer), or explicitly through ioctl requests - * when applications like wpa_supplicant want control. - */ -enum ieee80211_roamingmode { - IEEE80211_ROAMING_DEVICE= 0, /* driver/hardware control */ - IEEE80211_ROAMING_AUTO = 1, /* 802.11 layer control */ - IEEE80211_ROAMING_MANUAL= 2, /* application control */ -}; - -/* - * Channels are specified by frequency and attributes. - */ -struct ieee80211_channel { - uint32_t ic_flags; /* see below */ - uint16_t ic_freq; /* setting in MHz */ - uint8_t ic_ieee; /* IEEE channel number */ - int8_t ic_maxregpower; /* maximum regulatory tx power in dBm */ - int8_t ic_maxpower; /* maximum tx power in .5 dBm */ - int8_t ic_minpower; /* minimum tx power in .5 dBm */ - uint8_t ic_state; /* dynamic state */ - uint8_t ic_extieee; /* HT40 extension channel number */ - int8_t ic_maxantgain; /* maximum antenna gain in .5 dBm */ - uint8_t ic_pad; - uint16_t ic_devdata; /* opaque device/driver data */ -}; - -#define IEEE80211_CHAN_MAX 256 -#define IEEE80211_CHAN_BYTES 32 /* howmany(IEEE80211_CHAN_MAX, NBBY) */ -#define IEEE80211_CHAN_ANY 0xffff /* token for ``any channel'' */ -#define IEEE80211_CHAN_ANYC \ - ((struct ieee80211_channel *) IEEE80211_CHAN_ANY) - -/* channel attributes */ -#define IEEE80211_CHAN_PRIV0 0x00000001 /* driver private bit 0 */ -#define IEEE80211_CHAN_PRIV1 0x00000002 /* driver private bit 1 */ -#define IEEE80211_CHAN_PRIV2 0x00000004 /* driver private bit 2 */ -#define IEEE80211_CHAN_PRIV3 0x00000008 /* driver private bit 3 */ -#define IEEE80211_CHAN_TURBO 0x00000010 /* Turbo channel */ -#define IEEE80211_CHAN_CCK 0x00000020 /* CCK channel */ -#define IEEE80211_CHAN_OFDM 0x00000040 /* OFDM channel */ -#define IEEE80211_CHAN_2GHZ 0x00000080 /* 2 GHz spectrum channel. */ -#define IEEE80211_CHAN_5GHZ 0x00000100 /* 5 GHz spectrum channel */ -#define IEEE80211_CHAN_PASSIVE 0x00000200 /* Only passive scan allowed */ -#define IEEE80211_CHAN_DYN 0x00000400 /* Dynamic CCK-OFDM channel */ -#define IEEE80211_CHAN_GFSK 0x00000800 /* GFSK channel (FHSS PHY) */ -#define IEEE80211_CHAN_GSM 0x00001000 /* 900 MHz spectrum channel */ -#define IEEE80211_CHAN_STURBO 0x00002000 /* 11a static turbo channel only */ -#define IEEE80211_CHAN_HALF 0x00004000 /* Half rate channel */ -#define IEEE80211_CHAN_QUARTER 0x00008000 /* Quarter rate channel */ -#define IEEE80211_CHAN_HT20 0x00010000 /* HT 20 channel */ -#define IEEE80211_CHAN_HT40U 0x00020000 /* HT 40 channel w/ ext above */ -#define IEEE80211_CHAN_HT40D 0x00040000 /* HT 40 channel w/ ext below */ -#define IEEE80211_CHAN_DFS 0x00080000 /* DFS required */ -#define IEEE80211_CHAN_4MSXMIT 0x00100000 /* 4ms limit on frame length */ -#define IEEE80211_CHAN_NOADHOC 0x00200000 /* adhoc mode not allowed */ -#define IEEE80211_CHAN_NOHOSTAP 0x00400000 /* hostap mode not allowed */ -#define IEEE80211_CHAN_11D 0x00800000 /* 802.11d required */ - -#define IEEE80211_CHAN_HT40 (IEEE80211_CHAN_HT40U | IEEE80211_CHAN_HT40D) -#define IEEE80211_CHAN_HT (IEEE80211_CHAN_HT20 | IEEE80211_CHAN_HT40) - -#define IEEE80211_CHAN_BITS \ - "\20\1PRIV0\2PRIV2\3PRIV3\4PRIV4\5TURBO\6CCK\7OFDM\0102GHZ\0115GHZ" \ - "\12PASSIVE\13DYN\14GFSK\15GSM\16STURBO\17HALF\20QUARTER\21HT20" \ - "\22HT40U\23HT40D\24DFS\0254MSXMIT\26NOADHOC\27NOHOSTAP\03011D" - -/* - * Useful combinations of channel characteristics. - */ -#define IEEE80211_CHAN_FHSS \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK) -#define IEEE80211_CHAN_A \ - (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) -#define IEEE80211_CHAN_B \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) -#define IEEE80211_CHAN_PUREG \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM) -#define IEEE80211_CHAN_G \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) -#define IEEE80211_CHAN_108A \ - (IEEE80211_CHAN_A | IEEE80211_CHAN_TURBO) -#define IEEE80211_CHAN_108G \ - (IEEE80211_CHAN_PUREG | IEEE80211_CHAN_TURBO) -#define IEEE80211_CHAN_ST \ - (IEEE80211_CHAN_108A | IEEE80211_CHAN_STURBO) - -#define IEEE80211_CHAN_ALL \ - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_GFSK | \ - IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN | \ - IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER | \ - IEEE80211_CHAN_HT) -#define IEEE80211_CHAN_ALLTURBO \ - (IEEE80211_CHAN_ALL | IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO) - -#define IEEE80211_IS_CHAN_FHSS(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS) -#define IEEE80211_IS_CHAN_A(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A) -#define IEEE80211_IS_CHAN_B(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B) -#define IEEE80211_IS_CHAN_PUREG(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG) -#define IEEE80211_IS_CHAN_G(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G) -#define IEEE80211_IS_CHAN_ANYG(_c) \ - (IEEE80211_IS_CHAN_PUREG(_c) || IEEE80211_IS_CHAN_G(_c)) -#define IEEE80211_IS_CHAN_ST(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_ST) == IEEE80211_CHAN_ST) -#define IEEE80211_IS_CHAN_108A(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_108A) == IEEE80211_CHAN_108A) -#define IEEE80211_IS_CHAN_108G(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_108G) == IEEE80211_CHAN_108G) - -#define IEEE80211_IS_CHAN_2GHZ(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_2GHZ) != 0) -#define IEEE80211_IS_CHAN_5GHZ(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_5GHZ) != 0) -#define IEEE80211_IS_CHAN_PASSIVE(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_PASSIVE) != 0) -#define IEEE80211_IS_CHAN_OFDM(_c) \ - (((_c)->ic_flags & (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN)) != 0) -#define IEEE80211_IS_CHAN_CCK(_c) \ - (((_c)->ic_flags & (IEEE80211_CHAN_CCK | IEEE80211_CHAN_DYN)) != 0) -#define IEEE80211_IS_CHAN_GFSK(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_GFSK) != 0) -#define IEEE80211_IS_CHAN_TURBO(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_TURBO) != 0) -#define IEEE80211_IS_CHAN_STURBO(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_STURBO) != 0) -#define IEEE80211_IS_CHAN_DTURBO(_c) \ - (((_c)->ic_flags & \ - (IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO)) == IEEE80211_CHAN_TURBO) -#define IEEE80211_IS_CHAN_HALF(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_HALF) != 0) -#define IEEE80211_IS_CHAN_QUARTER(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_QUARTER) != 0) -#define IEEE80211_IS_CHAN_FULL(_c) \ - (((_c)->ic_flags & (IEEE80211_CHAN_QUARTER | IEEE80211_CHAN_HALF)) == 0) -#define IEEE80211_IS_CHAN_GSM(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_GSM) != 0) -#define IEEE80211_IS_CHAN_HT(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_HT) != 0) -#define IEEE80211_IS_CHAN_HT20(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_HT20) != 0) -#define IEEE80211_IS_CHAN_HT40(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_HT40) != 0) -#define IEEE80211_IS_CHAN_HT40U(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_HT40U) != 0) -#define IEEE80211_IS_CHAN_HT40D(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_HT40D) != 0) -#define IEEE80211_IS_CHAN_HTA(_c) \ - (IEEE80211_IS_CHAN_5GHZ(_c) && \ - ((_c)->ic_flags & IEEE80211_CHAN_HT) != 0) -#define IEEE80211_IS_CHAN_HTG(_c) \ - (IEEE80211_IS_CHAN_2GHZ(_c) && \ - ((_c)->ic_flags & IEEE80211_CHAN_HT) != 0) -#define IEEE80211_IS_CHAN_DFS(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_DFS) != 0) -#define IEEE80211_IS_CHAN_NOADHOC(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_NOADHOC) != 0) -#define IEEE80211_IS_CHAN_NOHOSTAP(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_NOHOSTAP) != 0) -#define IEEE80211_IS_CHAN_11D(_c) \ - (((_c)->ic_flags & IEEE80211_CHAN_11D) != 0) - -#define IEEE80211_CHAN2IEEE(_c) (_c)->ic_ieee - -/* dynamic state */ -#define IEEE80211_CHANSTATE_RADAR 0x01 /* radar detected */ -#define IEEE80211_CHANSTATE_CACDONE 0x02 /* CAC completed */ -#define IEEE80211_CHANSTATE_CWINT 0x04 /* interference detected */ -#define IEEE80211_CHANSTATE_NORADAR 0x10 /* post notify on radar clear */ - -#define IEEE80211_IS_CHAN_RADAR(_c) \ - (((_c)->ic_state & IEEE80211_CHANSTATE_RADAR) != 0) -#define IEEE80211_IS_CHAN_CACDONE(_c) \ - (((_c)->ic_state & IEEE80211_CHANSTATE_CACDONE) != 0) -#define IEEE80211_IS_CHAN_CWINT(_c) \ - (((_c)->ic_state & IEEE80211_CHANSTATE_CWINT) != 0) - -/* ni_chan encoding for FH phy */ -#define IEEE80211_FH_CHANMOD 80 -#define IEEE80211_FH_CHAN(set,pat) (((set)-1)*IEEE80211_FH_CHANMOD+(pat)) -#define IEEE80211_FH_CHANSET(chan) ((chan)/IEEE80211_FH_CHANMOD+1) -#define IEEE80211_FH_CHANPAT(chan) ((chan)%IEEE80211_FH_CHANMOD) - -#define IEEE80211_TID_SIZE (WME_NUM_TID+1) /* WME TID's +1 for non-QoS */ -#define IEEE80211_NONQOS_TID WME_NUM_TID /* index for non-QoS sta */ - -/* - * The 802.11 spec says at most 2007 stations may be - * associated at once. For most AP's this is way more - * than is feasible so we use a default of 128. This - * number may be overridden by the driver and/or by - * user configuration but may not be less than IEEE80211_AID_MIN. - */ -#define IEEE80211_AID_DEF 128 -#define IEEE80211_AID_MIN 16 - -/* - * 802.11 rate set. - */ -#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */ -#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */ - -struct ieee80211_rateset { - uint8_t rs_nrates; - uint8_t rs_rates[IEEE80211_RATE_MAXSIZE]; -}; - -/* - * 802.11n variant of ieee80211_rateset. Instead of - * legacy rates the entries are MCS rates. We define - * the structure such that it can be used interchangeably - * with an ieee80211_rateset (modulo structure size). - */ -#define IEEE80211_HTRATE_MAXSIZE 77 - -struct ieee80211_htrateset { - uint8_t rs_nrates; - uint8_t rs_rates[IEEE80211_HTRATE_MAXSIZE]; -}; - -#define IEEE80211_RATE_MCS 0x80 - -/* - * Per-mode transmit parameters/controls visible to user space. - * These can be used to set fixed transmit rate for all operating - * modes or on a per-client basis according to the capabilities - * of the client (e.g. an 11b client associated to an 11g ap). - * - * MCS are distinguished from legacy rates by or'ing in 0x80. - */ -struct ieee80211_txparam { - uint8_t ucastrate; /* ucast data rate (legacy/MCS|0x80) */ - uint8_t mgmtrate; /* mgmt frame rate (legacy/MCS|0x80) */ - uint8_t mcastrate; /* multicast rate (legacy/MCS|0x80) */ - uint8_t maxretry; /* max unicast data retry count */ -}; - -/* - * Per-mode roaming state visible to user space. There are two - * thresholds that control whether roaming is considered; when - * either is exceeded the 802.11 layer will check the scan cache - * for another AP. If the cache is stale then a scan may be - * triggered. - */ -struct ieee80211_roamparam { - int8_t rssi; /* rssi thresh (.5 dBm) */ - uint8_t rate; /* tx rate thresh (.5 Mb/s or MCS) */ - uint16_t pad; /* reserve */ -}; - -/* - * Regulatory Information. - */ -struct ieee80211_regdomain { - uint16_t regdomain; /* SKU */ - uint16_t country; /* ISO country code */ - uint8_t location; /* I (indoor), O (outdoor), other */ - uint8_t ecm; /* Extended Channel Mode */ - char isocc[2]; /* country code string */ - short pad[2]; -}; - -/* - * MIMO antenna/radio state. - */ - -#define IEEE80211_MAX_CHAINS 3 -#define IEEE80211_MAX_EVM_PILOTS 6 - -/* - * XXX This doesn't yet export both ctl/ext chain details - */ -struct ieee80211_mimo_info { - int8_t rssi[IEEE80211_MAX_CHAINS]; /* per-antenna rssi */ - int8_t noise[IEEE80211_MAX_CHAINS]; /* per-antenna noise floor */ - uint8_t pad[2]; - uint32_t evm[3]; /* EVM data */ -}; -#endif /* _FBSD_COMPAT_NET80211__IEEE80211_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211.c deleted file mode 100644 index a03904176c..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211.c +++ /dev/null @@ -1,1722 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 generic handler - */ -#include "opt_wlan.h" - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include -#ifdef IEEE80211_SUPPORT_SUPERG -#include -#endif -#include - -#include - -const char *ieee80211_phymode_name[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = "auto", - [IEEE80211_MODE_11A] = "11a", - [IEEE80211_MODE_11B] = "11b", - [IEEE80211_MODE_11G] = "11g", - [IEEE80211_MODE_FH] = "FH", - [IEEE80211_MODE_TURBO_A] = "turboA", - [IEEE80211_MODE_TURBO_G] = "turboG", - [IEEE80211_MODE_STURBO_A] = "sturboA", - [IEEE80211_MODE_HALF] = "half", - [IEEE80211_MODE_QUARTER] = "quarter", - [IEEE80211_MODE_11NA] = "11na", - [IEEE80211_MODE_11NG] = "11ng", -}; -/* map ieee80211_opmode to the corresponding capability bit */ -const int ieee80211_opcap[IEEE80211_OPMODE_MAX] = { - [IEEE80211_M_IBSS] = IEEE80211_C_IBSS, - [IEEE80211_M_WDS] = IEEE80211_C_WDS, - [IEEE80211_M_STA] = IEEE80211_C_STA, - [IEEE80211_M_AHDEMO] = IEEE80211_C_AHDEMO, - [IEEE80211_M_HOSTAP] = IEEE80211_C_HOSTAP, - [IEEE80211_M_MONITOR] = IEEE80211_C_MONITOR, -#ifdef IEEE80211_SUPPORT_MESH - [IEEE80211_M_MBSS] = IEEE80211_C_MBSS, -#endif -}; - -static const uint8_t ieee80211broadcastaddr[IEEE80211_ADDR_LEN] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - -static void ieee80211_syncflag_locked(struct ieee80211com *ic, int flag); -static void ieee80211_syncflag_ht_locked(struct ieee80211com *ic, int flag); -static void ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag); -static int ieee80211_media_setup(struct ieee80211com *ic, - struct ifmedia *media, int caps, int addsta, - ifm_change_cb_t media_change, ifm_stat_cb_t media_stat); -static void ieee80211com_media_status(struct ifnet *, struct ifmediareq *); -static int ieee80211com_media_change(struct ifnet *); -static int media_status(enum ieee80211_opmode, - const struct ieee80211_channel *); - -/* - * Default supported rates for 802.11 operation (in IEEE .5Mb units). - */ -#define B(r) ((r) | IEEE80211_RATE_BASIC) -static const struct ieee80211_rateset ieee80211_rateset_11a = - { 8, { B(12), 18, B(24), 36, B(48), 72, 96, 108 } }; -static const struct ieee80211_rateset ieee80211_rateset_half = - { 8, { B(6), 9, B(12), 18, B(24), 36, 48, 54 } }; -static const struct ieee80211_rateset ieee80211_rateset_quarter = - { 8, { B(3), 4, B(6), 9, B(12), 18, 24, 27 } }; -static const struct ieee80211_rateset ieee80211_rateset_11b = - { 4, { B(2), B(4), B(11), B(22) } }; -/* NB: OFDM rates are handled specially based on mode */ -static const struct ieee80211_rateset ieee80211_rateset_11g = - { 12, { B(2), B(4), B(11), B(22), 12, 18, 24, 36, 48, 72, 96, 108 } }; -#undef B - -/* - * Fill in 802.11 available channel set, mark - * all available channels as active, and pick - * a default channel if not already specified. - */ -static void -ieee80211_chan_init(struct ieee80211com *ic) -{ -#define DEFAULTRATES(m, def) do { \ - if (ic->ic_sup_rates[m].rs_nrates == 0) \ - ic->ic_sup_rates[m] = def; \ -} while (0) - struct ieee80211_channel *c; - int i; - - KASSERT(0 < ic->ic_nchans && ic->ic_nchans <= IEEE80211_CHAN_MAX, - ("invalid number of channels specified: %u", ic->ic_nchans)); - memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail)); - memset(ic->ic_modecaps, 0, sizeof(ic->ic_modecaps)); - setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO); - for (i = 0; i < ic->ic_nchans; i++) { - c = &ic->ic_channels[i]; - KASSERT(c->ic_flags != 0, ("channel with no flags")); - /* - * Help drivers that work only with frequencies by filling - * in IEEE channel #'s if not already calculated. Note this - * mimics similar work done in ieee80211_setregdomain when - * changing regulatory state. - */ - if (c->ic_ieee == 0) - c->ic_ieee = ieee80211_mhz2ieee(c->ic_freq,c->ic_flags); - if (IEEE80211_IS_CHAN_HT40(c) && c->ic_extieee == 0) - c->ic_extieee = ieee80211_mhz2ieee(c->ic_freq + - (IEEE80211_IS_CHAN_HT40U(c) ? 20 : -20), - c->ic_flags); - /* default max tx power to max regulatory */ - if (c->ic_maxpower == 0) - c->ic_maxpower = 2*c->ic_maxregpower; - setbit(ic->ic_chan_avail, c->ic_ieee); - /* - * Identify mode capabilities. - */ - if (IEEE80211_IS_CHAN_A(c)) - setbit(ic->ic_modecaps, IEEE80211_MODE_11A); - if (IEEE80211_IS_CHAN_B(c)) - setbit(ic->ic_modecaps, IEEE80211_MODE_11B); - if (IEEE80211_IS_CHAN_ANYG(c)) - setbit(ic->ic_modecaps, IEEE80211_MODE_11G); - if (IEEE80211_IS_CHAN_FHSS(c)) - setbit(ic->ic_modecaps, IEEE80211_MODE_FH); - if (IEEE80211_IS_CHAN_108A(c)) - setbit(ic->ic_modecaps, IEEE80211_MODE_TURBO_A); - if (IEEE80211_IS_CHAN_108G(c)) - setbit(ic->ic_modecaps, IEEE80211_MODE_TURBO_G); - if (IEEE80211_IS_CHAN_ST(c)) - setbit(ic->ic_modecaps, IEEE80211_MODE_STURBO_A); - if (IEEE80211_IS_CHAN_HALF(c)) - setbit(ic->ic_modecaps, IEEE80211_MODE_HALF); - if (IEEE80211_IS_CHAN_QUARTER(c)) - setbit(ic->ic_modecaps, IEEE80211_MODE_QUARTER); - if (IEEE80211_IS_CHAN_HTA(c)) - setbit(ic->ic_modecaps, IEEE80211_MODE_11NA); - if (IEEE80211_IS_CHAN_HTG(c)) - setbit(ic->ic_modecaps, IEEE80211_MODE_11NG); - } - /* initialize candidate channels to all available */ - memcpy(ic->ic_chan_active, ic->ic_chan_avail, - sizeof(ic->ic_chan_avail)); - - /* sort channel table to allow lookup optimizations */ - ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans); - - /* invalidate any previous state */ - ic->ic_bsschan = IEEE80211_CHAN_ANYC; - ic->ic_prevchan = NULL; - ic->ic_csa_newchan = NULL; - /* arbitrarily pick the first channel */ - ic->ic_curchan = &ic->ic_channels[0]; - ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan); - - /* fillin well-known rate sets if driver has not specified */ - DEFAULTRATES(IEEE80211_MODE_11B, ieee80211_rateset_11b); - DEFAULTRATES(IEEE80211_MODE_11G, ieee80211_rateset_11g); - DEFAULTRATES(IEEE80211_MODE_11A, ieee80211_rateset_11a); - DEFAULTRATES(IEEE80211_MODE_TURBO_A, ieee80211_rateset_11a); - DEFAULTRATES(IEEE80211_MODE_TURBO_G, ieee80211_rateset_11g); - DEFAULTRATES(IEEE80211_MODE_STURBO_A, ieee80211_rateset_11a); - DEFAULTRATES(IEEE80211_MODE_HALF, ieee80211_rateset_half); - DEFAULTRATES(IEEE80211_MODE_QUARTER, ieee80211_rateset_quarter); - DEFAULTRATES(IEEE80211_MODE_11NA, ieee80211_rateset_11a); - DEFAULTRATES(IEEE80211_MODE_11NG, ieee80211_rateset_11g); - - /* - * Setup required information to fill the mcsset field, if driver did - * not. Assume a 2T2R setup for historic reasons. - */ - if (ic->ic_rxstream == 0) - ic->ic_rxstream = 2; - if (ic->ic_txstream == 0) - ic->ic_txstream = 2; - - /* - * Set auto mode to reset active channel state and any desired channel. - */ - (void) ieee80211_setmode(ic, IEEE80211_MODE_AUTO); -#undef DEFAULTRATES -} - -static void -null_update_mcast(struct ifnet *ifp) -{ - if_printf(ifp, "need multicast update callback\n"); -} - -static void -null_update_promisc(struct ifnet *ifp) -{ - if_printf(ifp, "need promiscuous mode update callback\n"); -} - -static int -null_transmit(struct ifnet *ifp, struct mbuf *m) -{ - m_freem(m); - ifp->if_oerrors++; - return EACCES; /* XXX EIO/EPERM? */ -} - -static int -null_output(struct ifnet *ifp, struct mbuf *m, - struct sockaddr *dst, struct route *ro) -{ - if_printf(ifp, "discard raw packet\n"); - return null_transmit(ifp, m); -} - -static void -null_input(struct ifnet *ifp, struct mbuf *m) -{ - if_printf(ifp, "if_input should not be called\n"); - m_freem(m); -} - -/* - * Attach/setup the common net80211 state. Called by - * the driver on attach to prior to creating any vap's. - */ -void -ieee80211_ifattach(struct ieee80211com *ic, - const uint8_t macaddr[IEEE80211_ADDR_LEN]) -{ - struct ifnet *ifp = ic->ic_ifp; - struct sockaddr_dl *sdl; - struct ifaddr *ifa; - - KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type)); - - IEEE80211_LOCK_INIT(ic, ifp->if_xname); - TAILQ_INIT(&ic->ic_vaps); - - /* Create a taskqueue for all state changes */ - ic->ic_tq = taskqueue_create("ic_taskq", M_WAITOK | M_ZERO, - taskqueue_thread_enqueue, &ic->ic_tq); - taskqueue_start_threads(&ic->ic_tq, 1, PI_NET, "%s taskq", - ifp->if_xname); - /* - * Fill in 802.11 available channel set, mark all - * available channels as active, and pick a default - * channel if not already specified. - */ - ieee80211_media_init(ic); - - ic->ic_update_mcast = null_update_mcast; - ic->ic_update_promisc = null_update_promisc; - - ic->ic_hash_key = arc4random(); - ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT; - ic->ic_lintval = ic->ic_bintval; - ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX; - - ieee80211_crypto_attach(ic); - ieee80211_node_attach(ic); - ieee80211_power_attach(ic); - ieee80211_proto_attach(ic); -#ifdef IEEE80211_SUPPORT_SUPERG - ieee80211_superg_attach(ic); -#endif - ieee80211_ht_attach(ic); - ieee80211_scan_attach(ic); - ieee80211_regdomain_attach(ic); - ieee80211_dfs_attach(ic); -#if defined(__HAIKU__) - ieee80211_ratectl_attach(ic); -#endif - - ieee80211_sysctl_attach(ic); - - ifp->if_addrlen = IEEE80211_ADDR_LEN; - ifp->if_hdrlen = 0; - if_attach(ifp); - ifp->if_mtu = IEEE80211_MTU_MAX; - ifp->if_broadcastaddr = ieee80211broadcastaddr; - ifp->if_output = null_output; - ifp->if_input = null_input; /* just in case */ - ifp->if_resolvemulti = NULL; /* NB: callers check */ - -#ifndef __HAIKU__ - ifa = ifaddr_byindex(ifp->if_index); - KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__)); - sdl = (struct sockaddr_dl *)ifa->ifa_addr;; -#else - sdl = &ifp->if_lladdr; -#endif - sdl->sdl_type = IFT_ETHER; /* XXX IFT_IEEE80211? */ - sdl->sdl_alen = IEEE80211_ADDR_LEN; - IEEE80211_ADDR_COPY(LLADDR(sdl), macaddr); - ifa_free(ifa); -} - -/* - * Detach net80211 state on device detach. Tear down - * all vap's and reclaim all common state prior to the - * device state going away. Note we may call back into - * driver; it must be prepared for this. - */ -void -ieee80211_ifdetach(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - struct ieee80211vap *vap; - - if_detach(ifp); - - while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL) - ieee80211_vap_destroy(vap); - ieee80211_waitfor_parent(ic); - - ieee80211_sysctl_detach(ic); -#if defined(__HAIKU__) - ieee80211_ratectl_detach(ic); -#endif - ieee80211_dfs_detach(ic); - ieee80211_regdomain_detach(ic); - ieee80211_scan_detach(ic); -#ifdef IEEE80211_SUPPORT_SUPERG - ieee80211_superg_detach(ic); -#endif - ieee80211_ht_detach(ic); - /* NB: must be called before ieee80211_node_detach */ - ieee80211_proto_detach(ic); - ieee80211_crypto_detach(ic); - ieee80211_power_detach(ic); - ieee80211_node_detach(ic); - - ifmedia_removeall(&ic->ic_media); - taskqueue_free(ic->ic_tq); - IEEE80211_LOCK_DESTROY(ic); -} - -/* - * Default reset method for use with the ioctl support. This - * method is invoked after any state change in the 802.11 - * layer that should be propagated to the hardware but not - * require re-initialization of the 802.11 state machine (e.g - * rescanning for an ap). We always return ENETRESET which - * should cause the driver to re-initialize the device. Drivers - * can override this method to implement more optimized support. - */ -static int -default_reset(struct ieee80211vap *vap, u_long cmd) -{ - return ENETRESET; -} - -/* - * Prepare a vap for use. Drivers use this call to - * setup net80211 state in new vap's prior attaching - * them with ieee80211_vap_attach (below). - */ -int -ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t macaddr[IEEE80211_ADDR_LEN]) -{ - struct ifnet *ifp; - - ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - if_printf(ic->ic_ifp, "%s: unable to allocate ifnet\n", - __func__); - return ENOMEM; - } - if_initname(ifp, name, unit); - ifp->if_softc = vap; /* back pointer */ - ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; - ifp->if_start = ieee80211_start; - ifp->if_ioctl = ieee80211_ioctl; - ifp->if_init = ieee80211_init; - /* NB: input+output filled in by ether_ifattach */ - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - vap->iv_ifp = ifp; - vap->iv_ic = ic; - vap->iv_flags = ic->ic_flags; /* propagate common flags */ - vap->iv_flags_ext = ic->ic_flags_ext; - vap->iv_flags_ven = ic->ic_flags_ven; - vap->iv_caps = ic->ic_caps &~ IEEE80211_C_OPMODE; - vap->iv_htcaps = ic->ic_htcaps; - vap->iv_htextcaps = ic->ic_htextcaps; - vap->iv_opmode = opmode; - vap->iv_caps |= ieee80211_opcap[opmode]; - switch (opmode) { - case IEEE80211_M_WDS: - /* - * WDS links must specify the bssid of the far end. - * For legacy operation this is a static relationship. - * For non-legacy operation the station must associate - * and be authorized to pass traffic. Plumbing the - * vap to the proper node happens when the vap - * transitions to RUN state. - */ - IEEE80211_ADDR_COPY(vap->iv_des_bssid, bssid); - vap->iv_flags |= IEEE80211_F_DESBSSID; - if (flags & IEEE80211_CLONE_WDSLEGACY) - vap->iv_flags_ext |= IEEE80211_FEXT_WDSLEGACY; - break; -#ifdef IEEE80211_SUPPORT_TDMA - case IEEE80211_M_AHDEMO: - if (flags & IEEE80211_CLONE_TDMA) { - /* NB: checked before clone operation allowed */ - KASSERT(ic->ic_caps & IEEE80211_C_TDMA, - ("not TDMA capable, ic_caps 0x%x", ic->ic_caps)); - /* - * Propagate TDMA capability to mark vap; this - * cannot be removed and is used to distinguish - * regular ahdemo operation from ahdemo+tdma. - */ - vap->iv_caps |= IEEE80211_C_TDMA; - } - break; -#endif - } - /* auto-enable s/w beacon miss support */ - if (flags & IEEE80211_CLONE_NOBEACONS) - vap->iv_flags_ext |= IEEE80211_FEXT_SWBMISS; - /* auto-generated or user supplied MAC address */ - if (flags & (IEEE80211_CLONE_BSSID|IEEE80211_CLONE_MACADDR)) - vap->iv_flags_ext |= IEEE80211_FEXT_UNIQMAC; - /* - * Enable various functionality by default if we're - * capable; the driver can override us if it knows better. - */ - if (vap->iv_caps & IEEE80211_C_WME) - vap->iv_flags |= IEEE80211_F_WME; - if (vap->iv_caps & IEEE80211_C_BURST) - vap->iv_flags |= IEEE80211_F_BURST; - /* NB: bg scanning only makes sense for station mode right now */ -#if 0 - if (vap->iv_opmode == IEEE80211_M_STA && - (vap->iv_caps & IEEE80211_C_BGSCAN)) - vap->iv_flags |= IEEE80211_F_BGSCAN; -#endif - vap->iv_flags |= IEEE80211_F_DOTH; /* XXX no cap, just ena */ - /* NB: DFS support only makes sense for ap mode right now */ - if (vap->iv_opmode == IEEE80211_M_HOSTAP && - (vap->iv_caps & IEEE80211_C_DFS)) - vap->iv_flags_ext |= IEEE80211_FEXT_DFS; - - vap->iv_des_chan = IEEE80211_CHAN_ANYC; /* any channel is ok */ - vap->iv_bmissthreshold = IEEE80211_HWBMISS_DEFAULT; - vap->iv_dtim_period = IEEE80211_DTIM_DEFAULT; - /* - * Install a default reset method for the ioctl support; - * the driver can override this. - */ - vap->iv_reset = default_reset; - - IEEE80211_ADDR_COPY(vap->iv_myaddr, macaddr); - - ieee80211_sysctl_vattach(vap); - ieee80211_crypto_vattach(vap); - ieee80211_node_vattach(vap); - ieee80211_power_vattach(vap); - ieee80211_proto_vattach(vap); -#ifdef IEEE80211_SUPPORT_SUPERG - ieee80211_superg_vattach(vap); -#endif - ieee80211_ht_vattach(vap); - ieee80211_scan_vattach(vap); - ieee80211_regdomain_vattach(vap); - ieee80211_radiotap_vattach(vap); - ieee80211_ratectl_set(vap, IEEE80211_RATECTL_NONE); - - return 0; -} - -/* - * Activate a vap. State should have been prepared with a - * call to ieee80211_vap_setup and by the driver. On return - * from this call the vap is ready for use. - */ -int -ieee80211_vap_attach(struct ieee80211vap *vap, - ifm_change_cb_t media_change, ifm_stat_cb_t media_stat) -{ - struct ifnet *ifp = vap->iv_ifp; - struct ieee80211com *ic = vap->iv_ic; - struct ifmediareq imr; - int maxrate; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, - "%s: %s parent %s flags 0x%x flags_ext 0x%x\n", - __func__, ieee80211_opmode_name[vap->iv_opmode], - ic->ic_ifp->if_xname, vap->iv_flags, vap->iv_flags_ext); - - /* - * Do late attach work that cannot happen until after - * the driver has had a chance to override defaults. - */ - ieee80211_node_latevattach(vap); - ieee80211_power_latevattach(vap); - - maxrate = ieee80211_media_setup(ic, &vap->iv_media, vap->iv_caps, - vap->iv_opmode == IEEE80211_M_STA, media_change, media_stat); - ieee80211_media_status(ifp, &imr); - /* NB: strip explicit mode; we're actually in autoselect */ - ifmedia_set(&vap->iv_media, - imr.ifm_active &~ (IFM_MMASK | IFM_IEEE80211_TURBO)); - if (maxrate) - ifp->if_baudrate = IF_Mbps(maxrate); - - ether_ifattach(ifp, vap->iv_myaddr); - if (vap->iv_opmode == IEEE80211_M_MONITOR) { - /* NB: disallow transmit */ - ifp->if_transmit = null_transmit; - ifp->if_output = null_output; - } else { - /* hook output method setup by ether_ifattach */ - vap->iv_output = ifp->if_output; - ifp->if_output = ieee80211_output; - } - /* NB: if_mtu set by ether_ifattach to ETHERMTU */ - - IEEE80211_LOCK(ic); - TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next); - ieee80211_syncflag_locked(ic, IEEE80211_F_WME); -#ifdef IEEE80211_SUPPORT_SUPERG - ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP); -#endif - ieee80211_syncflag_locked(ic, IEEE80211_F_PCF); - ieee80211_syncflag_locked(ic, IEEE80211_F_BURST); - ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT); - ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40); - ieee80211_syncifflag_locked(ic, IFF_PROMISC); - ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); - IEEE80211_UNLOCK(ic); - - return 1; -} - -/* - * Tear down vap state and reclaim the ifnet. - * The driver is assumed to have prepared for - * this; e.g. by turning off interrupts for the - * underlying device. - */ -void -ieee80211_vap_detach(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = vap->iv_ifp; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s parent %s\n", - __func__, ieee80211_opmode_name[vap->iv_opmode], - ic->ic_ifp->if_xname); - - /* NB: bpfdetach is called by ether_ifdetach and claims all taps */ - ether_ifdetach(ifp); - - ieee80211_stop(vap); - - /* - * Flush any deferred vap tasks. - */ - ieee80211_draintask(ic, &vap->iv_nstate_task); - ieee80211_draintask(ic, &vap->iv_swbmiss_task); - - IEEE80211_LOCK(ic); - KASSERT(vap->iv_state == IEEE80211_S_INIT , ("vap still running")); - TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next); - ieee80211_syncflag_locked(ic, IEEE80211_F_WME); -#ifdef IEEE80211_SUPPORT_SUPERG - ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP); -#endif - ieee80211_syncflag_locked(ic, IEEE80211_F_PCF); - ieee80211_syncflag_locked(ic, IEEE80211_F_BURST); - ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT); - ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40); - /* NB: this handles the bpfdetach done below */ - ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF); - ieee80211_syncifflag_locked(ic, IFF_PROMISC); - ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); - IEEE80211_UNLOCK(ic); - - ifmedia_removeall(&vap->iv_media); - - ieee80211_radiotap_vdetach(vap); - ieee80211_regdomain_vdetach(vap); - ieee80211_scan_vdetach(vap); -#ifdef IEEE80211_SUPPORT_SUPERG - ieee80211_superg_vdetach(vap); -#endif - ieee80211_ht_vdetach(vap); - /* NB: must be before ieee80211_node_vdetach */ - ieee80211_proto_vdetach(vap); - ieee80211_crypto_vdetach(vap); - ieee80211_power_vdetach(vap); - ieee80211_node_vdetach(vap); - ieee80211_sysctl_vdetach(vap); - - if_free(ifp); -} - -/* - * Synchronize flag bit state in the parent ifnet structure - * according to the state of all vap ifnet's. This is used, - * for example, to handle IFF_PROMISC and IFF_ALLMULTI. - */ -void -ieee80211_syncifflag_locked(struct ieee80211com *ic, int flag) -{ - struct ifnet *ifp = ic->ic_ifp; - struct ieee80211vap *vap; - int bit, oflags; - - IEEE80211_LOCK_ASSERT(ic); - - bit = 0; - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if (vap->iv_ifp->if_flags & flag) { - /* - * XXX the bridge sets PROMISC but we don't want to - * enable it on the device, discard here so all the - * drivers don't need to special-case it - */ - if (flag == IFF_PROMISC && - !(vap->iv_opmode == IEEE80211_M_MONITOR || - (vap->iv_opmode == IEEE80211_M_AHDEMO && - (vap->iv_caps & IEEE80211_C_TDMA) == 0))) - continue; - bit = 1; - break; - } - oflags = ifp->if_flags; - if (bit) - ifp->if_flags |= flag; - else - ifp->if_flags &= ~flag; - if ((ifp->if_flags ^ oflags) & flag) { - /* XXX should we return 1/0 and let caller do this? */ - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if (flag == IFF_PROMISC) - ieee80211_runtask(ic, &ic->ic_promisc_task); - else if (flag == IFF_ALLMULTI) - ieee80211_runtask(ic, &ic->ic_mcast_task); - } - } -} - -/* - * Synchronize flag bit state in the com structure - * according to the state of all vap's. This is used, - * for example, to handle state changes via ioctls. - */ -static void -ieee80211_syncflag_locked(struct ieee80211com *ic, int flag) -{ - struct ieee80211vap *vap; - int bit; - - IEEE80211_LOCK_ASSERT(ic); - - bit = 0; - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if (vap->iv_flags & flag) { - bit = 1; - break; - } - if (bit) - ic->ic_flags |= flag; - else - ic->ic_flags &= ~flag; -} - -void -ieee80211_syncflag(struct ieee80211vap *vap, int flag) -{ - struct ieee80211com *ic = vap->iv_ic; - - IEEE80211_LOCK(ic); - if (flag < 0) { - flag = -flag; - vap->iv_flags &= ~flag; - } else - vap->iv_flags |= flag; - ieee80211_syncflag_locked(ic, flag); - IEEE80211_UNLOCK(ic); -} - -/* - * Synchronize flags_ht bit state in the com structure - * according to the state of all vap's. This is used, - * for example, to handle state changes via ioctls. - */ -static void -ieee80211_syncflag_ht_locked(struct ieee80211com *ic, int flag) -{ - struct ieee80211vap *vap; - int bit; - - IEEE80211_LOCK_ASSERT(ic); - - bit = 0; - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if (vap->iv_flags_ht & flag) { - bit = 1; - break; - } - if (bit) - ic->ic_flags_ht |= flag; - else - ic->ic_flags_ht &= ~flag; -} - -void -ieee80211_syncflag_ht(struct ieee80211vap *vap, int flag) -{ - struct ieee80211com *ic = vap->iv_ic; - - IEEE80211_LOCK(ic); - if (flag < 0) { - flag = -flag; - vap->iv_flags_ht &= ~flag; - } else - vap->iv_flags_ht |= flag; - ieee80211_syncflag_ht_locked(ic, flag); - IEEE80211_UNLOCK(ic); -} - -/* - * Synchronize flags_ext bit state in the com structure - * according to the state of all vap's. This is used, - * for example, to handle state changes via ioctls. - */ -static void -ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag) -{ - struct ieee80211vap *vap; - int bit; - - IEEE80211_LOCK_ASSERT(ic); - - bit = 0; - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if (vap->iv_flags_ext & flag) { - bit = 1; - break; - } - if (bit) - ic->ic_flags_ext |= flag; - else - ic->ic_flags_ext &= ~flag; -} - -void -ieee80211_syncflag_ext(struct ieee80211vap *vap, int flag) -{ - struct ieee80211com *ic = vap->iv_ic; - - IEEE80211_LOCK(ic); - if (flag < 0) { - flag = -flag; - vap->iv_flags_ext &= ~flag; - } else - vap->iv_flags_ext |= flag; - ieee80211_syncflag_ext_locked(ic, flag); - IEEE80211_UNLOCK(ic); -} - -static __inline int -mapgsm(u_int freq, u_int flags) -{ - freq *= 10; - if (flags & IEEE80211_CHAN_QUARTER) - freq += 5; - else if (flags & IEEE80211_CHAN_HALF) - freq += 10; - else - freq += 20; - /* NB: there is no 907/20 wide but leave room */ - return (freq - 906*10) / 5; -} - -static __inline int -mappsb(u_int freq, u_int flags) -{ - return 37 + ((freq * 10) + ((freq % 5) == 2 ? 5 : 0) - 49400) / 5; -} - -/* - * Convert MHz frequency to IEEE channel number. - */ -int -ieee80211_mhz2ieee(u_int freq, u_int flags) -{ -#define IS_FREQ_IN_PSB(_freq) ((_freq) > 4940 && (_freq) < 4990) - if (flags & IEEE80211_CHAN_GSM) - return mapgsm(freq, flags); - if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */ - if (freq == 2484) - return 14; - if (freq < 2484) - return ((int) freq - 2407) / 5; - else - return 15 + ((freq - 2512) / 20); - } else if (flags & IEEE80211_CHAN_5GHZ) { /* 5Ghz band */ - if (freq <= 5000) { - /* XXX check regdomain? */ - if (IS_FREQ_IN_PSB(freq)) - return mappsb(freq, flags); - return (freq - 4000) / 5; - } else - return (freq - 5000) / 5; - } else { /* either, guess */ - if (freq == 2484) - return 14; - if (freq < 2484) { - if (907 <= freq && freq <= 922) - return mapgsm(freq, flags); - return ((int) freq - 2407) / 5; - } - if (freq < 5000) { - if (IS_FREQ_IN_PSB(freq)) - return mappsb(freq, flags); - else if (freq > 4900) - return (freq - 4000) / 5; - else - return 15 + ((freq - 2512) / 20); - } - return (freq - 5000) / 5; - } -#undef IS_FREQ_IN_PSB -} - -/* - * Convert channel to IEEE channel number. - */ -int -ieee80211_chan2ieee(struct ieee80211com *ic, const struct ieee80211_channel *c) -{ - if (c == NULL) { - if_printf(ic->ic_ifp, "invalid channel (NULL)\n"); - return 0; /* XXX */ - } - return (c == IEEE80211_CHAN_ANYC ? IEEE80211_CHAN_ANY : c->ic_ieee); -} - -/* - * Convert IEEE channel number to MHz frequency. - */ -u_int -ieee80211_ieee2mhz(u_int chan, u_int flags) -{ - if (flags & IEEE80211_CHAN_GSM) - return 907 + 5 * (chan / 10); - if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */ - if (chan == 14) - return 2484; - if (chan < 14) - return 2407 + chan*5; - else - return 2512 + ((chan-15)*20); - } else if (flags & IEEE80211_CHAN_5GHZ) {/* 5Ghz band */ - if (flags & (IEEE80211_CHAN_HALF|IEEE80211_CHAN_QUARTER)) { - chan -= 37; - return 4940 + chan*5 + (chan % 5 ? 2 : 0); - } - return 5000 + (chan*5); - } else { /* either, guess */ - /* XXX can't distinguish PSB+GSM channels */ - if (chan == 14) - return 2484; - if (chan < 14) /* 0-13 */ - return 2407 + chan*5; - if (chan < 27) /* 15-26 */ - return 2512 + ((chan-15)*20); - return 5000 + (chan*5); - } -} - -/* - * Locate a channel given a frequency+flags. We cache - * the previous lookup to optimize switching between two - * channels--as happens with dynamic turbo. - */ -struct ieee80211_channel * -ieee80211_find_channel(struct ieee80211com *ic, int freq, int flags) -{ - struct ieee80211_channel *c; - int i; - - flags &= IEEE80211_CHAN_ALLTURBO; - c = ic->ic_prevchan; - if (c != NULL && c->ic_freq == freq && - (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags) - return c; - /* brute force search */ - for (i = 0; i < ic->ic_nchans; i++) { - c = &ic->ic_channels[i]; - if (c->ic_freq == freq && - (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags) - return c; - } - return NULL; -} - -/* - * Locate a channel given a channel number+flags. We cache - * the previous lookup to optimize switching between two - * channels--as happens with dynamic turbo. - */ -struct ieee80211_channel * -ieee80211_find_channel_byieee(struct ieee80211com *ic, int ieee, int flags) -{ - struct ieee80211_channel *c; - int i; - - flags &= IEEE80211_CHAN_ALLTURBO; - c = ic->ic_prevchan; - if (c != NULL && c->ic_ieee == ieee && - (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags) - return c; - /* brute force search */ - for (i = 0; i < ic->ic_nchans; i++) { - c = &ic->ic_channels[i]; - if (c->ic_ieee == ieee && - (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags) - return c; - } - return NULL; -} - -static void -addmedia(struct ifmedia *media, int caps, int addsta, int mode, int mword) -{ -#define ADD(_ic, _s, _o) \ - ifmedia_add(media, \ - IFM_MAKEWORD(IFM_IEEE80211, (_s), (_o), 0), 0, NULL) - static const u_int mopts[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = IFM_AUTO, - [IEEE80211_MODE_11A] = IFM_IEEE80211_11A, - [IEEE80211_MODE_11B] = IFM_IEEE80211_11B, - [IEEE80211_MODE_11G] = IFM_IEEE80211_11G, - [IEEE80211_MODE_FH] = IFM_IEEE80211_FH, - [IEEE80211_MODE_TURBO_A] = IFM_IEEE80211_11A|IFM_IEEE80211_TURBO, - [IEEE80211_MODE_TURBO_G] = IFM_IEEE80211_11G|IFM_IEEE80211_TURBO, - [IEEE80211_MODE_STURBO_A] = IFM_IEEE80211_11A|IFM_IEEE80211_TURBO, - [IEEE80211_MODE_HALF] = IFM_IEEE80211_11A, /* XXX */ - [IEEE80211_MODE_QUARTER] = IFM_IEEE80211_11A, /* XXX */ - [IEEE80211_MODE_11NA] = IFM_IEEE80211_11NA, - [IEEE80211_MODE_11NG] = IFM_IEEE80211_11NG, - }; - u_int mopt; - - mopt = mopts[mode]; - if (addsta) - ADD(ic, mword, mopt); /* STA mode has no cap */ - if (caps & IEEE80211_C_IBSS) - ADD(media, mword, mopt | IFM_IEEE80211_ADHOC); - if (caps & IEEE80211_C_HOSTAP) - ADD(media, mword, mopt | IFM_IEEE80211_HOSTAP); - if (caps & IEEE80211_C_AHDEMO) - ADD(media, mword, mopt | IFM_IEEE80211_ADHOC | IFM_FLAG0); - if (caps & IEEE80211_C_MONITOR) - ADD(media, mword, mopt | IFM_IEEE80211_MONITOR); - if (caps & IEEE80211_C_WDS) - ADD(media, mword, mopt | IFM_IEEE80211_WDS); - if (caps & IEEE80211_C_MBSS) - ADD(media, mword, mopt | IFM_IEEE80211_MBSS); -#undef ADD -} - -/* - * Setup the media data structures according to the channel and - * rate tables. - */ -static int -ieee80211_media_setup(struct ieee80211com *ic, - struct ifmedia *media, int caps, int addsta, - ifm_change_cb_t media_change, ifm_stat_cb_t media_stat) -{ - int i, j, mode, rate, maxrate, mword, r; - const struct ieee80211_rateset *rs; - struct ieee80211_rateset allrates; - - /* - * Fill in media characteristics. - */ - ifmedia_init(media, 0, media_change, media_stat); - maxrate = 0; - /* - * Add media for legacy operating modes. - */ - memset(&allrates, 0, sizeof(allrates)); - for (mode = IEEE80211_MODE_AUTO; mode < IEEE80211_MODE_11NA; mode++) { - if (isclr(ic->ic_modecaps, mode)) - continue; - addmedia(media, caps, addsta, mode, IFM_AUTO); - if (mode == IEEE80211_MODE_AUTO) - continue; - rs = &ic->ic_sup_rates[mode]; - for (i = 0; i < rs->rs_nrates; i++) { - rate = rs->rs_rates[i]; - mword = ieee80211_rate2media(ic, rate, mode); - if (mword == 0) - continue; - addmedia(media, caps, addsta, mode, mword); - /* - * Add legacy rate to the collection of all rates. - */ - r = rate & IEEE80211_RATE_VAL; - for (j = 0; j < allrates.rs_nrates; j++) - if (allrates.rs_rates[j] == r) - break; - if (j == allrates.rs_nrates) { - /* unique, add to the set */ - allrates.rs_rates[j] = r; - allrates.rs_nrates++; - } - rate = (rate & IEEE80211_RATE_VAL) / 2; - if (rate > maxrate) - maxrate = rate; - } - } - for (i = 0; i < allrates.rs_nrates; i++) { - mword = ieee80211_rate2media(ic, allrates.rs_rates[i], - IEEE80211_MODE_AUTO); - if (mword == 0) - continue; - /* NB: remove media options from mword */ - addmedia(media, caps, addsta, - IEEE80211_MODE_AUTO, IFM_SUBTYPE(mword)); - } - /* - * Add HT/11n media. Note that we do not have enough - * bits in the media subtype to express the MCS so we - * use a "placeholder" media subtype and any fixed MCS - * must be specified with a different mechanism. - */ - for (; mode <= IEEE80211_MODE_11NG; mode++) { - if (isclr(ic->ic_modecaps, mode)) - continue; - addmedia(media, caps, addsta, mode, IFM_AUTO); - addmedia(media, caps, addsta, mode, IFM_IEEE80211_MCS); - } - if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA) || - isset(ic->ic_modecaps, IEEE80211_MODE_11NG)) { - addmedia(media, caps, addsta, - IEEE80211_MODE_AUTO, IFM_IEEE80211_MCS); - i = ic->ic_txstream * 8 - 1; - if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) && - (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40)) - rate = ieee80211_htrates[i].ht40_rate_400ns; - else if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40)) - rate = ieee80211_htrates[i].ht40_rate_800ns; - else if ((ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20)) - rate = ieee80211_htrates[i].ht20_rate_400ns; - else - rate = ieee80211_htrates[i].ht20_rate_800ns; - if (rate > maxrate) - maxrate = rate; - } - return maxrate; -} - -void -ieee80211_media_init(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - int maxrate; - - /* NB: this works because the structure is initialized to zero */ - if (!LIST_EMPTY(&ic->ic_media.ifm_list)) { - /* - * We are re-initializing the channel list; clear - * the existing media state as the media routines - * don't suppress duplicates. - */ - ifmedia_removeall(&ic->ic_media); - } - ieee80211_chan_init(ic); - - /* - * Recalculate media settings in case new channel list changes - * the set of available modes. - */ - maxrate = ieee80211_media_setup(ic, &ic->ic_media, ic->ic_caps, 1, - ieee80211com_media_change, ieee80211com_media_status); - /* NB: strip explicit mode; we're actually in autoselect */ - ifmedia_set(&ic->ic_media, - media_status(ic->ic_opmode, ic->ic_curchan) &~ - (IFM_MMASK | IFM_IEEE80211_TURBO)); - if (maxrate) - ifp->if_baudrate = IF_Mbps(maxrate); - - /* XXX need to propagate new media settings to vap's */ -} - -/* XXX inline or eliminate? */ -const struct ieee80211_rateset * -ieee80211_get_suprates(struct ieee80211com *ic, const struct ieee80211_channel *c) -{ - /* XXX does this work for 11ng basic rates? */ - return &ic->ic_sup_rates[ieee80211_chan2mode(c)]; -} - -void -ieee80211_announce(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - int i, mode, rate, mword; - const struct ieee80211_rateset *rs; - - /* NB: skip AUTO since it has no rates */ - for (mode = IEEE80211_MODE_AUTO+1; mode < IEEE80211_MODE_11NA; mode++) { - if (isclr(ic->ic_modecaps, mode)) - continue; - if_printf(ifp, "%s rates: ", ieee80211_phymode_name[mode]); - rs = &ic->ic_sup_rates[mode]; - for (i = 0; i < rs->rs_nrates; i++) { - mword = ieee80211_rate2media(ic, rs->rs_rates[i], mode); - if (mword == 0) - continue; - rate = ieee80211_media2rate(mword); - printf("%s%d%sMbps", (i != 0 ? " " : ""), - rate / 2, ((rate & 0x1) != 0 ? ".5" : "")); - } - printf("\n"); - } - ieee80211_ht_announce(ic); -} - -void -ieee80211_announce_channels(struct ieee80211com *ic) -{ - const struct ieee80211_channel *c; - char type; - int i, cw; - - printf("Chan Freq CW RegPwr MinPwr MaxPwr\n"); - for (i = 0; i < ic->ic_nchans; i++) { - c = &ic->ic_channels[i]; - if (IEEE80211_IS_CHAN_ST(c)) - type = 'S'; - else if (IEEE80211_IS_CHAN_108A(c)) - type = 'T'; - else if (IEEE80211_IS_CHAN_108G(c)) - type = 'G'; - else if (IEEE80211_IS_CHAN_HT(c)) - type = 'n'; - else if (IEEE80211_IS_CHAN_A(c)) - type = 'a'; - else if (IEEE80211_IS_CHAN_ANYG(c)) - type = 'g'; - else if (IEEE80211_IS_CHAN_B(c)) - type = 'b'; - else - type = 'f'; - if (IEEE80211_IS_CHAN_HT40(c) || IEEE80211_IS_CHAN_TURBO(c)) - cw = 40; - else if (IEEE80211_IS_CHAN_HALF(c)) - cw = 10; - else if (IEEE80211_IS_CHAN_QUARTER(c)) - cw = 5; - else - cw = 20; - printf("%4d %4d%c %2d%c %6d %4d.%d %4d.%d\n" - , c->ic_ieee, c->ic_freq, type - , cw - , IEEE80211_IS_CHAN_HT40U(c) ? '+' : - IEEE80211_IS_CHAN_HT40D(c) ? '-' : ' ' - , c->ic_maxregpower - , c->ic_minpower / 2, c->ic_minpower & 1 ? 5 : 0 - , c->ic_maxpower / 2, c->ic_maxpower & 1 ? 5 : 0 - ); - } -} - -static int -media2mode(const struct ifmedia_entry *ime, uint32_t flags, uint16_t *mode) -{ - switch (IFM_MODE(ime->ifm_media)) { - case IFM_IEEE80211_11A: - *mode = IEEE80211_MODE_11A; - break; - case IFM_IEEE80211_11B: - *mode = IEEE80211_MODE_11B; - break; - case IFM_IEEE80211_11G: - *mode = IEEE80211_MODE_11G; - break; - case IFM_IEEE80211_FH: - *mode = IEEE80211_MODE_FH; - break; - case IFM_IEEE80211_11NA: - *mode = IEEE80211_MODE_11NA; - break; - case IFM_IEEE80211_11NG: - *mode = IEEE80211_MODE_11NG; - break; - case IFM_AUTO: - *mode = IEEE80211_MODE_AUTO; - break; - default: - return 0; - } - /* - * Turbo mode is an ``option''. - * XXX does not apply to AUTO - */ - if (ime->ifm_media & IFM_IEEE80211_TURBO) { - if (*mode == IEEE80211_MODE_11A) { - if (flags & IEEE80211_F_TURBOP) - *mode = IEEE80211_MODE_TURBO_A; - else - *mode = IEEE80211_MODE_STURBO_A; - } else if (*mode == IEEE80211_MODE_11G) - *mode = IEEE80211_MODE_TURBO_G; - else - return 0; - } - /* XXX HT40 +/- */ - return 1; -} - -/* - * Handle a media change request on the underlying interface. - */ -int -ieee80211com_media_change(struct ifnet *ifp) -{ - return EINVAL; -} - -/* - * Handle a media change request on the vap interface. - */ -int -ieee80211_media_change(struct ifnet *ifp) -{ - struct ieee80211vap *vap = ifp->if_softc; - struct ifmedia_entry *ime = vap->iv_media.ifm_cur; - uint16_t newmode; - - if (!media2mode(ime, vap->iv_flags, &newmode)) - return EINVAL; - if (vap->iv_des_mode != newmode) { - vap->iv_des_mode = newmode; - /* XXX kick state machine if up+running */ - } - return 0; -} - -/* - * Common code to calculate the media status word - * from the operating mode and channel state. - */ -static int -media_status(enum ieee80211_opmode opmode, const struct ieee80211_channel *chan) -{ - int status; - - status = IFM_IEEE80211; - switch (opmode) { - case IEEE80211_M_STA: - break; - case IEEE80211_M_IBSS: - status |= IFM_IEEE80211_ADHOC; - break; - case IEEE80211_M_HOSTAP: - status |= IFM_IEEE80211_HOSTAP; - break; - case IEEE80211_M_MONITOR: - status |= IFM_IEEE80211_MONITOR; - break; - case IEEE80211_M_AHDEMO: - status |= IFM_IEEE80211_ADHOC | IFM_FLAG0; - break; - case IEEE80211_M_WDS: - status |= IFM_IEEE80211_WDS; - break; - case IEEE80211_M_MBSS: - status |= IFM_IEEE80211_MBSS; - break; - } - if (IEEE80211_IS_CHAN_HTA(chan)) { - status |= IFM_IEEE80211_11NA; - } else if (IEEE80211_IS_CHAN_HTG(chan)) { - status |= IFM_IEEE80211_11NG; - } else if (IEEE80211_IS_CHAN_A(chan)) { - status |= IFM_IEEE80211_11A; - } else if (IEEE80211_IS_CHAN_B(chan)) { - status |= IFM_IEEE80211_11B; - } else if (IEEE80211_IS_CHAN_ANYG(chan)) { - status |= IFM_IEEE80211_11G; - } else if (IEEE80211_IS_CHAN_FHSS(chan)) { - status |= IFM_IEEE80211_FH; - } - /* XXX else complain? */ - - if (IEEE80211_IS_CHAN_TURBO(chan)) - status |= IFM_IEEE80211_TURBO; -#if 0 - if (IEEE80211_IS_CHAN_HT20(chan)) - status |= IFM_IEEE80211_HT20; - if (IEEE80211_IS_CHAN_HT40(chan)) - status |= IFM_IEEE80211_HT40; -#endif - return status; -} - -static void -ieee80211com_media_status(struct ifnet *ifp, struct ifmediareq *imr) -{ - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap; - - imr->ifm_status = IFM_AVALID; - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if (vap->iv_ifp->if_flags & IFF_UP) { - imr->ifm_status |= IFM_ACTIVE; - break; - } - imr->ifm_active = media_status(ic->ic_opmode, ic->ic_curchan); - if (imr->ifm_status & IFM_ACTIVE) - imr->ifm_current = imr->ifm_active; -} - -void -ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr) -{ - struct ieee80211vap *vap = ifp->if_softc; - struct ieee80211com *ic = vap->iv_ic; - enum ieee80211_phymode mode; - - imr->ifm_status = IFM_AVALID; - /* - * NB: use the current channel's mode to lock down a xmit - * rate only when running; otherwise we may have a mismatch - * in which case the rate will not be convertible. - */ - if (vap->iv_state == IEEE80211_S_RUN) { - imr->ifm_status |= IFM_ACTIVE; - mode = ieee80211_chan2mode(ic->ic_curchan); - } else - mode = IEEE80211_MODE_AUTO; - imr->ifm_active = media_status(vap->iv_opmode, ic->ic_curchan); - /* - * Calculate a current rate if possible. - */ - if (vap->iv_txparms[mode].ucastrate != IEEE80211_FIXED_RATE_NONE) { - /* - * A fixed rate is set, report that. - */ - imr->ifm_active |= ieee80211_rate2media(ic, - vap->iv_txparms[mode].ucastrate, mode); - } else if (vap->iv_opmode == IEEE80211_M_STA) { - /* - * In station mode report the current transmit rate. - */ - imr->ifm_active |= ieee80211_rate2media(ic, - vap->iv_bss->ni_txrate, mode); - } else - imr->ifm_active |= IFM_AUTO; - if (imr->ifm_status & IFM_ACTIVE) - imr->ifm_current = imr->ifm_active; -} - -/* - * Set the current phy mode and recalculate the active channel - * set based on the available channels for this mode. Also - * select a new default/current channel if the current one is - * inappropriate for this mode. - */ -int -ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode) -{ - /* - * Adjust basic rates in 11b/11g supported rate set. - * Note that if operating on a hal/quarter rate channel - * this is a noop as those rates sets are different - * and used instead. - */ - if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11B) - ieee80211_setbasicrates(&ic->ic_sup_rates[mode], mode); - - ic->ic_curmode = mode; - ieee80211_reset_erp(ic); /* reset ERP state */ - - return 0; -} - -/* - * Return the phy mode for with the specified channel. - */ -enum ieee80211_phymode -ieee80211_chan2mode(const struct ieee80211_channel *chan) -{ - - if (IEEE80211_IS_CHAN_HTA(chan)) - return IEEE80211_MODE_11NA; - else if (IEEE80211_IS_CHAN_HTG(chan)) - return IEEE80211_MODE_11NG; - else if (IEEE80211_IS_CHAN_108G(chan)) - return IEEE80211_MODE_TURBO_G; - else if (IEEE80211_IS_CHAN_ST(chan)) - return IEEE80211_MODE_STURBO_A; - else if (IEEE80211_IS_CHAN_TURBO(chan)) - return IEEE80211_MODE_TURBO_A; - else if (IEEE80211_IS_CHAN_HALF(chan)) - return IEEE80211_MODE_HALF; - else if (IEEE80211_IS_CHAN_QUARTER(chan)) - return IEEE80211_MODE_QUARTER; - else if (IEEE80211_IS_CHAN_A(chan)) - return IEEE80211_MODE_11A; - else if (IEEE80211_IS_CHAN_ANYG(chan)) - return IEEE80211_MODE_11G; - else if (IEEE80211_IS_CHAN_B(chan)) - return IEEE80211_MODE_11B; - else if (IEEE80211_IS_CHAN_FHSS(chan)) - return IEEE80211_MODE_FH; - - /* NB: should not get here */ - printf("%s: cannot map channel to mode; freq %u flags 0x%x\n", - __func__, chan->ic_freq, chan->ic_flags); - return IEEE80211_MODE_11B; -} - -struct ratemedia { - u_int match; /* rate + mode */ - u_int media; /* if_media rate */ -}; - -static int -findmedia(const struct ratemedia rates[], int n, u_int match) -{ - int i; - - for (i = 0; i < n; i++) - if (rates[i].match == match) - return rates[i].media; - return IFM_AUTO; -} - -/* - * Convert IEEE80211 rate value to ifmedia subtype. - * Rate is either a legacy rate in units of 0.5Mbps - * or an MCS index. - */ -int -ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode mode) -{ -#define N(a) (sizeof(a) / sizeof(a[0])) - static const struct ratemedia rates[] = { - { 2 | IFM_IEEE80211_FH, IFM_IEEE80211_FH1 }, - { 4 | IFM_IEEE80211_FH, IFM_IEEE80211_FH2 }, - { 2 | IFM_IEEE80211_11B, IFM_IEEE80211_DS1 }, - { 4 | IFM_IEEE80211_11B, IFM_IEEE80211_DS2 }, - { 11 | IFM_IEEE80211_11B, IFM_IEEE80211_DS5 }, - { 22 | IFM_IEEE80211_11B, IFM_IEEE80211_DS11 }, - { 44 | IFM_IEEE80211_11B, IFM_IEEE80211_DS22 }, - { 12 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM6 }, - { 18 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM9 }, - { 24 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM12 }, - { 36 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM18 }, - { 48 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM24 }, - { 72 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM36 }, - { 96 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM48 }, - { 108 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM54 }, - { 2 | IFM_IEEE80211_11G, IFM_IEEE80211_DS1 }, - { 4 | IFM_IEEE80211_11G, IFM_IEEE80211_DS2 }, - { 11 | IFM_IEEE80211_11G, IFM_IEEE80211_DS5 }, - { 22 | IFM_IEEE80211_11G, IFM_IEEE80211_DS11 }, - { 12 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM6 }, - { 18 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM9 }, - { 24 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM12 }, - { 36 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM18 }, - { 48 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM24 }, - { 72 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM36 }, - { 96 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM48 }, - { 108 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM54 }, - { 6 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM3 }, - { 9 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM4 }, - { 54 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM27 }, - /* NB: OFDM72 doesn't realy exist so we don't handle it */ - }; - static const struct ratemedia htrates[] = { - { 0, IFM_IEEE80211_MCS }, - { 1, IFM_IEEE80211_MCS }, - { 2, IFM_IEEE80211_MCS }, - { 3, IFM_IEEE80211_MCS }, - { 4, IFM_IEEE80211_MCS }, - { 5, IFM_IEEE80211_MCS }, - { 6, IFM_IEEE80211_MCS }, - { 7, IFM_IEEE80211_MCS }, - { 8, IFM_IEEE80211_MCS }, - { 9, IFM_IEEE80211_MCS }, - { 10, IFM_IEEE80211_MCS }, - { 11, IFM_IEEE80211_MCS }, - { 12, IFM_IEEE80211_MCS }, - { 13, IFM_IEEE80211_MCS }, - { 14, IFM_IEEE80211_MCS }, - { 15, IFM_IEEE80211_MCS }, - { 16, IFM_IEEE80211_MCS }, - { 17, IFM_IEEE80211_MCS }, - { 18, IFM_IEEE80211_MCS }, - { 19, IFM_IEEE80211_MCS }, - { 20, IFM_IEEE80211_MCS }, - { 21, IFM_IEEE80211_MCS }, - { 22, IFM_IEEE80211_MCS }, - { 23, IFM_IEEE80211_MCS }, - { 24, IFM_IEEE80211_MCS }, - { 25, IFM_IEEE80211_MCS }, - { 26, IFM_IEEE80211_MCS }, - { 27, IFM_IEEE80211_MCS }, - { 28, IFM_IEEE80211_MCS }, - { 29, IFM_IEEE80211_MCS }, - { 30, IFM_IEEE80211_MCS }, - { 31, IFM_IEEE80211_MCS }, - { 32, IFM_IEEE80211_MCS }, - { 33, IFM_IEEE80211_MCS }, - { 34, IFM_IEEE80211_MCS }, - { 35, IFM_IEEE80211_MCS }, - { 36, IFM_IEEE80211_MCS }, - { 37, IFM_IEEE80211_MCS }, - { 38, IFM_IEEE80211_MCS }, - { 39, IFM_IEEE80211_MCS }, - { 40, IFM_IEEE80211_MCS }, - { 41, IFM_IEEE80211_MCS }, - { 42, IFM_IEEE80211_MCS }, - { 43, IFM_IEEE80211_MCS }, - { 44, IFM_IEEE80211_MCS }, - { 45, IFM_IEEE80211_MCS }, - { 46, IFM_IEEE80211_MCS }, - { 47, IFM_IEEE80211_MCS }, - { 48, IFM_IEEE80211_MCS }, - { 49, IFM_IEEE80211_MCS }, - { 50, IFM_IEEE80211_MCS }, - { 51, IFM_IEEE80211_MCS }, - { 52, IFM_IEEE80211_MCS }, - { 53, IFM_IEEE80211_MCS }, - { 54, IFM_IEEE80211_MCS }, - { 55, IFM_IEEE80211_MCS }, - { 56, IFM_IEEE80211_MCS }, - { 57, IFM_IEEE80211_MCS }, - { 58, IFM_IEEE80211_MCS }, - { 59, IFM_IEEE80211_MCS }, - { 60, IFM_IEEE80211_MCS }, - { 61, IFM_IEEE80211_MCS }, - { 62, IFM_IEEE80211_MCS }, - { 63, IFM_IEEE80211_MCS }, - { 64, IFM_IEEE80211_MCS }, - { 65, IFM_IEEE80211_MCS }, - { 66, IFM_IEEE80211_MCS }, - { 67, IFM_IEEE80211_MCS }, - { 68, IFM_IEEE80211_MCS }, - { 69, IFM_IEEE80211_MCS }, - { 70, IFM_IEEE80211_MCS }, - { 71, IFM_IEEE80211_MCS }, - { 72, IFM_IEEE80211_MCS }, - { 73, IFM_IEEE80211_MCS }, - { 74, IFM_IEEE80211_MCS }, - { 75, IFM_IEEE80211_MCS }, - { 76, IFM_IEEE80211_MCS }, - }; - int m; - - /* - * Check 11n rates first for match as an MCS. - */ - if (mode == IEEE80211_MODE_11NA) { - if (rate & IEEE80211_RATE_MCS) { - rate &= ~IEEE80211_RATE_MCS; - m = findmedia(htrates, N(htrates), rate); - if (m != IFM_AUTO) - return m | IFM_IEEE80211_11NA; - } - } else if (mode == IEEE80211_MODE_11NG) { - /* NB: 12 is ambiguous, it will be treated as an MCS */ - if (rate & IEEE80211_RATE_MCS) { - rate &= ~IEEE80211_RATE_MCS; - m = findmedia(htrates, N(htrates), rate); - if (m != IFM_AUTO) - return m | IFM_IEEE80211_11NG; - } - } - rate &= IEEE80211_RATE_VAL; - switch (mode) { - case IEEE80211_MODE_11A: - case IEEE80211_MODE_HALF: /* XXX good 'nuf */ - case IEEE80211_MODE_QUARTER: - case IEEE80211_MODE_11NA: - case IEEE80211_MODE_TURBO_A: - case IEEE80211_MODE_STURBO_A: - return findmedia(rates, N(rates), rate | IFM_IEEE80211_11A); - case IEEE80211_MODE_11B: - return findmedia(rates, N(rates), rate | IFM_IEEE80211_11B); - case IEEE80211_MODE_FH: - return findmedia(rates, N(rates), rate | IFM_IEEE80211_FH); - case IEEE80211_MODE_AUTO: - /* NB: ic may be NULL for some drivers */ - if (ic != NULL && ic->ic_phytype == IEEE80211_T_FH) - return findmedia(rates, N(rates), - rate | IFM_IEEE80211_FH); - /* NB: hack, 11g matches both 11b+11a rates */ - /* fall thru... */ - case IEEE80211_MODE_11G: - case IEEE80211_MODE_11NG: - case IEEE80211_MODE_TURBO_G: - return findmedia(rates, N(rates), rate | IFM_IEEE80211_11G); - } - return IFM_AUTO; -#undef N -} - -int -ieee80211_media2rate(int mword) -{ -#define N(a) (sizeof(a) / sizeof(a[0])) - static const int ieeerates[] = { - -1, /* IFM_AUTO */ - 0, /* IFM_MANUAL */ - 0, /* IFM_NONE */ - 2, /* IFM_IEEE80211_FH1 */ - 4, /* IFM_IEEE80211_FH2 */ - 2, /* IFM_IEEE80211_DS1 */ - 4, /* IFM_IEEE80211_DS2 */ - 11, /* IFM_IEEE80211_DS5 */ - 22, /* IFM_IEEE80211_DS11 */ - 44, /* IFM_IEEE80211_DS22 */ - 12, /* IFM_IEEE80211_OFDM6 */ - 18, /* IFM_IEEE80211_OFDM9 */ - 24, /* IFM_IEEE80211_OFDM12 */ - 36, /* IFM_IEEE80211_OFDM18 */ - 48, /* IFM_IEEE80211_OFDM24 */ - 72, /* IFM_IEEE80211_OFDM36 */ - 96, /* IFM_IEEE80211_OFDM48 */ - 108, /* IFM_IEEE80211_OFDM54 */ - 144, /* IFM_IEEE80211_OFDM72 */ - 0, /* IFM_IEEE80211_DS354k */ - 0, /* IFM_IEEE80211_DS512k */ - 6, /* IFM_IEEE80211_OFDM3 */ - 9, /* IFM_IEEE80211_OFDM4 */ - 54, /* IFM_IEEE80211_OFDM27 */ - -1, /* IFM_IEEE80211_MCS */ - }; - return IFM_SUBTYPE(mword) < N(ieeerates) ? - ieeerates[IFM_SUBTYPE(mword)] : 0; -#undef N -} - -/* - * The following hash function is adapted from "Hash Functions" by Bob Jenkins - * ("Algorithm Alley", Dr. Dobbs Journal, September 1997). - */ -#define mix(a, b, c) \ -do { \ - a -= b; a -= c; a ^= (c >> 13); \ - b -= c; b -= a; b ^= (a << 8); \ - c -= a; c -= b; c ^= (b >> 13); \ - a -= b; a -= c; a ^= (c >> 12); \ - b -= c; b -= a; b ^= (a << 16); \ - c -= a; c -= b; c ^= (b >> 5); \ - a -= b; a -= c; a ^= (c >> 3); \ - b -= c; b -= a; b ^= (a << 10); \ - c -= a; c -= b; c ^= (b >> 15); \ -} while (/*CONSTCOND*/0) - -uint32_t -ieee80211_mac_hash(const struct ieee80211com *ic, - const uint8_t addr[IEEE80211_ADDR_LEN]) -{ - uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = ic->ic_hash_key; - - b += addr[5] << 8; - b += addr[4]; - a += addr[3] << 24; - a += addr[2] << 16; - a += addr[1] << 8; - a += addr[0]; - - mix(a, b, c); - - return c; -} -#undef mix diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211.h deleted file mode 100644 index 49716b3d80..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211.h +++ /dev/null @@ -1,1088 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_H_ - -/* - * 802.11 protocol definitions. - */ - -#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ -/* is 802.11 address multicast/broadcast? */ -#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01) - -typedef uint16_t ieee80211_seq; - -/* IEEE 802.11 PLCP header */ -struct ieee80211_plcp_hdr { - uint16_t i_sfd; - uint8_t i_signal; - uint8_t i_service; - uint16_t i_length; - uint16_t i_crc; -} __packed; - -#define IEEE80211_PLCP_SFD 0xF3A0 -#define IEEE80211_PLCP_SERVICE 0x00 -#define IEEE80211_PLCP_SERVICE_LOCKED 0x04 -#define IEEE80211_PLCL_SERVICE_PBCC 0x08 -#define IEEE80211_PLCP_SERVICE_LENEXT5 0x20 -#define IEEE80211_PLCP_SERVICE_LENEXT6 0x40 -#define IEEE80211_PLCP_SERVICE_LENEXT7 0x80 - -/* - * generic definitions for IEEE 802.11 frames - */ -struct ieee80211_frame { - uint8_t i_fc[2]; - uint8_t i_dur[2]; - uint8_t i_addr1[IEEE80211_ADDR_LEN]; - uint8_t i_addr2[IEEE80211_ADDR_LEN]; - uint8_t i_addr3[IEEE80211_ADDR_LEN]; - uint8_t i_seq[2]; - /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ - /* see below */ -} __packed; - -struct ieee80211_qosframe { - uint8_t i_fc[2]; - uint8_t i_dur[2]; - uint8_t i_addr1[IEEE80211_ADDR_LEN]; - uint8_t i_addr2[IEEE80211_ADDR_LEN]; - uint8_t i_addr3[IEEE80211_ADDR_LEN]; - uint8_t i_seq[2]; - uint8_t i_qos[2]; - /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ - /* see below */ -} __packed; - -struct ieee80211_qoscntl { - uint8_t i_qos[2]; -}; - -struct ieee80211_frame_addr4 { - uint8_t i_fc[2]; - uint8_t i_dur[2]; - uint8_t i_addr1[IEEE80211_ADDR_LEN]; - uint8_t i_addr2[IEEE80211_ADDR_LEN]; - uint8_t i_addr3[IEEE80211_ADDR_LEN]; - uint8_t i_seq[2]; - uint8_t i_addr4[IEEE80211_ADDR_LEN]; -} __packed; - - -struct ieee80211_qosframe_addr4 { - uint8_t i_fc[2]; - uint8_t i_dur[2]; - uint8_t i_addr1[IEEE80211_ADDR_LEN]; - uint8_t i_addr2[IEEE80211_ADDR_LEN]; - uint8_t i_addr3[IEEE80211_ADDR_LEN]; - uint8_t i_seq[2]; - uint8_t i_addr4[IEEE80211_ADDR_LEN]; - uint8_t i_qos[2]; -} __packed; - -#define IEEE80211_FC0_VERSION_MASK 0x03 -#define IEEE80211_FC0_VERSION_SHIFT 0 -#define IEEE80211_FC0_VERSION_0 0x00 -#define IEEE80211_FC0_TYPE_MASK 0x0c -#define IEEE80211_FC0_TYPE_SHIFT 2 -#define IEEE80211_FC0_TYPE_MGT 0x00 -#define IEEE80211_FC0_TYPE_CTL 0x04 -#define IEEE80211_FC0_TYPE_DATA 0x08 - -#define IEEE80211_FC0_SUBTYPE_MASK 0xf0 -#define IEEE80211_FC0_SUBTYPE_SHIFT 4 -/* for TYPE_MGT */ -#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00 -#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10 -#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20 -#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30 -#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40 -#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50 -#define IEEE80211_FC0_SUBTYPE_BEACON 0x80 -#define IEEE80211_FC0_SUBTYPE_ATIM 0x90 -#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0 -#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0 -#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0 -#define IEEE80211_FC0_SUBTYPE_ACTION 0xd0 -#define IEEE80211_FC0_SUBTYPE_ACTION_NOACK 0xe0 -/* for TYPE_CTL */ -#define IEEE80211_FC0_SUBTYPE_BAR 0x80 -#define IEEE80211_FC0_SUBTYPE_BA 0x90 -#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0 -#define IEEE80211_FC0_SUBTYPE_RTS 0xb0 -#define IEEE80211_FC0_SUBTYPE_CTS 0xc0 -#define IEEE80211_FC0_SUBTYPE_ACK 0xd0 -#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0 -#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0 -/* for TYPE_DATA (bit combination) */ -#define IEEE80211_FC0_SUBTYPE_DATA 0x00 -#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10 -#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20 -#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30 -#define IEEE80211_FC0_SUBTYPE_NODATA 0x40 -#define IEEE80211_FC0_SUBTYPE_CFACK 0x50 -#define IEEE80211_FC0_SUBTYPE_CFPOLL 0x60 -#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70 -#define IEEE80211_FC0_SUBTYPE_QOS 0x80 -#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0 - -#define IEEE80211_FC1_DIR_MASK 0x03 -#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */ -#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */ -#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */ -#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */ - -#define IEEE80211_IS_DSTODS(wh) \ - (((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) - -#define IEEE80211_FC1_MORE_FRAG 0x04 -#define IEEE80211_FC1_RETRY 0x08 -#define IEEE80211_FC1_PWR_MGT 0x10 -#define IEEE80211_FC1_MORE_DATA 0x20 -#define IEEE80211_FC1_WEP 0x40 -#define IEEE80211_FC1_ORDER 0x80 - -#define IEEE80211_SEQ_FRAG_MASK 0x000f -#define IEEE80211_SEQ_FRAG_SHIFT 0 -#define IEEE80211_SEQ_SEQ_MASK 0xfff0 -#define IEEE80211_SEQ_SEQ_SHIFT 4 -#define IEEE80211_SEQ_RANGE 4096 - -#define IEEE80211_SEQ_ADD(seq, incr) \ - (((seq) + (incr)) & (IEEE80211_SEQ_RANGE-1)) -#define IEEE80211_SEQ_INC(seq) IEEE80211_SEQ_ADD(seq,1) -#define IEEE80211_SEQ_SUB(a, b) \ - (((a) + IEEE80211_SEQ_RANGE - (b)) & (IEEE80211_SEQ_RANGE-1)) - -#define IEEE80211_SEQ_BA_RANGE 2048 /* 2^11 */ -#define IEEE80211_SEQ_BA_BEFORE(a, b) \ - (IEEE80211_SEQ_SUB(b, a+1) < IEEE80211_SEQ_BA_RANGE-1) - -#define IEEE80211_NWID_LEN 32 -#define IEEE80211_MESHID_LEN 32 - -#define IEEE80211_QOS_TXOP 0x00ff -/* bit 8 is reserved */ -#define IEEE80211_QOS_AMSDU 0x80 -#define IEEE80211_QOS_AMSDU_S 7 -#define IEEE80211_QOS_ACKPOLICY 0x60 -#define IEEE80211_QOS_ACKPOLICY_S 5 -#define IEEE80211_QOS_ACKPOLICY_NOACK 0x20 /* No ACK required */ -#define IEEE80211_QOS_ACKPOLICY_BA 0x60 /* Block ACK */ -#define IEEE80211_QOS_EOSP 0x10 /* EndOfService Period*/ -#define IEEE80211_QOS_EOSP_S 4 -#define IEEE80211_QOS_TID 0x0f - -/* does frame have QoS sequence control data */ -#define IEEE80211_QOS_HAS_SEQ(wh) \ - (((wh)->i_fc[0] & \ - (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) == \ - (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) - -/* - * WME/802.11e information element. - */ -struct ieee80211_wme_info { - uint8_t wme_id; /* IEEE80211_ELEMID_VENDOR */ - uint8_t wme_len; /* length in bytes */ - uint8_t wme_oui[3]; /* 0x00, 0x50, 0xf2 */ - uint8_t wme_type; /* OUI type */ - uint8_t wme_subtype; /* OUI subtype */ - uint8_t wme_version; /* spec revision */ - uint8_t wme_info; /* QoS info */ -} __packed; - -/* - * WME/802.11e Tspec Element - */ -struct ieee80211_wme_tspec { - uint8_t ts_id; - uint8_t ts_len; - uint8_t ts_oui[3]; - uint8_t ts_oui_type; - uint8_t ts_oui_subtype; - uint8_t ts_version; - uint8_t ts_tsinfo[3]; - uint8_t ts_nom_msdu[2]; - uint8_t ts_max_msdu[2]; - uint8_t ts_min_svc[4]; - uint8_t ts_max_svc[4]; - uint8_t ts_inactv_intv[4]; - uint8_t ts_susp_intv[4]; - uint8_t ts_start_svc[4]; - uint8_t ts_min_rate[4]; - uint8_t ts_mean_rate[4]; - uint8_t ts_max_burst[4]; - uint8_t ts_min_phy[4]; - uint8_t ts_peak_rate[4]; - uint8_t ts_delay[4]; - uint8_t ts_surplus[2]; - uint8_t ts_medium_time[2]; -} __packed; - -/* - * WME AC parameter field - */ -struct ieee80211_wme_acparams { - uint8_t acp_aci_aifsn; - uint8_t acp_logcwminmax; - uint16_t acp_txop; -} __packed; - -#define WME_NUM_AC 4 /* 4 AC categories */ -#define WME_NUM_TID 16 /* 16 tids */ - -#define WME_PARAM_ACI 0x60 /* Mask for ACI field */ -#define WME_PARAM_ACI_S 5 /* Shift for ACI field */ -#define WME_PARAM_ACM 0x10 /* Mask for ACM bit */ -#define WME_PARAM_ACM_S 4 /* Shift for ACM bit */ -#define WME_PARAM_AIFSN 0x0f /* Mask for aifsn field */ -#define WME_PARAM_AIFSN_S 0 /* Shift for aifsn field */ -#define WME_PARAM_LOGCWMIN 0x0f /* Mask for CwMin field (in log) */ -#define WME_PARAM_LOGCWMIN_S 0 /* Shift for CwMin field */ -#define WME_PARAM_LOGCWMAX 0xf0 /* Mask for CwMax field (in log) */ -#define WME_PARAM_LOGCWMAX_S 4 /* Shift for CwMax field */ - -#define WME_AC_TO_TID(_ac) ( \ - ((_ac) == WME_AC_VO) ? 6 : \ - ((_ac) == WME_AC_VI) ? 5 : \ - ((_ac) == WME_AC_BK) ? 1 : \ - 0) - -#define TID_TO_WME_AC(_tid) ( \ - ((_tid) == 0 || (_tid) == 3) ? WME_AC_BE : \ - ((_tid) < 3) ? WME_AC_BK : \ - ((_tid) < 6) ? WME_AC_VI : \ - WME_AC_VO) - -/* - * WME Parameter Element - */ -struct ieee80211_wme_param { - uint8_t param_id; - uint8_t param_len; - uint8_t param_oui[3]; - uint8_t param_oui_type; - uint8_t param_oui_subtype; - uint8_t param_version; - uint8_t param_qosInfo; -#define WME_QOSINFO_COUNT 0x0f /* Mask for param count field */ - uint8_t param_reserved; - struct ieee80211_wme_acparams params_acParams[WME_NUM_AC]; -} __packed; - -/* - * Management Notification Frame - */ -struct ieee80211_mnf { - uint8_t mnf_category; - uint8_t mnf_action; - uint8_t mnf_dialog; - uint8_t mnf_status; -} __packed; -#define MNF_SETUP_REQ 0 -#define MNF_SETUP_RESP 1 -#define MNF_TEARDOWN 2 - -/* - * 802.11n Management Action Frames - */ -/* generic frame format */ -struct ieee80211_action { - uint8_t ia_category; - uint8_t ia_action; -} __packed; - -#define IEEE80211_ACTION_CAT_SM 0 /* Spectrum Management */ -#define IEEE80211_ACTION_CAT_QOS 1 /* QoS */ -#define IEEE80211_ACTION_CAT_DLS 2 /* DLS */ -#define IEEE80211_ACTION_CAT_BA 3 /* BA */ -#define IEEE80211_ACTION_CAT_HT 7 /* HT */ -#define IEEE80211_ACTION_CAT_VENDOR 127 /* Vendor Specific */ - -#define IEEE80211_ACTION_HT_TXCHWIDTH 0 /* recommended xmit chan width*/ -#define IEEE80211_ACTION_HT_MIMOPWRSAVE 1 /* MIMO power save */ - -/* HT - recommended transmission channel width */ -struct ieee80211_action_ht_txchwidth { - struct ieee80211_action at_header; - uint8_t at_chwidth; -} __packed; - -#define IEEE80211_A_HT_TXCHWIDTH_20 0 -#define IEEE80211_A_HT_TXCHWIDTH_2040 1 - -/* HT - MIMO Power Save (NB: D2.04) */ -struct ieee80211_action_ht_mimopowersave { - struct ieee80211_action am_header; - uint8_t am_control; -} __packed; - -#define IEEE80211_A_HT_MIMOPWRSAVE_ENA 0x01 /* PS enabled */ -#define IEEE80211_A_HT_MIMOPWRSAVE_MODE 0x02 -#define IEEE80211_A_HT_MIMOPWRSAVE_MODE_S 1 -#define IEEE80211_A_HT_MIMOPWRSAVE_DYNAMIC 0x02 /* Dynamic Mode */ -#define IEEE80211_A_HT_MIMOPWRSAVE_STATIC 0x00 /* no SM packets */ -/* bits 2-7 reserved */ - -/* Block Ack actions */ -#define IEEE80211_ACTION_BA_ADDBA_REQUEST 0 /* ADDBA request */ -#define IEEE80211_ACTION_BA_ADDBA_RESPONSE 1 /* ADDBA response */ -#define IEEE80211_ACTION_BA_DELBA 2 /* DELBA */ - -/* Block Ack Parameter Set */ -#define IEEE80211_BAPS_BUFSIZ 0xffc0 /* buffer size */ -#define IEEE80211_BAPS_BUFSIZ_S 6 -#define IEEE80211_BAPS_TID 0x003c /* TID */ -#define IEEE80211_BAPS_TID_S 2 -#define IEEE80211_BAPS_POLICY 0x0002 /* block ack policy */ -#define IEEE80211_BAPS_POLICY_S 1 - -#define IEEE80211_BAPS_POLICY_DELAYED (0< IEEE80211_MIN_LEN. The default - * mtu is Ethernet-compatible; it's set by ether_ifattach. - */ -#define IEEE80211_MTU_MAX 2290 -#define IEEE80211_MTU_MIN 32 - -#define IEEE80211_MAX_LEN (2300 + IEEE80211_CRC_LEN + \ - (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN)) -#define IEEE80211_ACK_LEN \ - (sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN) -#define IEEE80211_MIN_LEN \ - (sizeof(struct ieee80211_frame_min) + IEEE80211_CRC_LEN) - -/* - * The 802.11 spec says at most 2007 stations may be - * associated at once. For most AP's this is way more - * than is feasible so we use a default of IEEE80211_AID_DEF. - * This number may be overridden by the driver and/or by - * user configuration but may not be less than IEEE80211_AID_MIN - * (see _ieee80211.h for implementation-specific settings). - */ -#define IEEE80211_AID_MAX 2007 - -#define IEEE80211_AID(b) ((b) &~ 0xc000) - -/* - * RTS frame length parameters. The default is specified in - * the 802.11 spec as 512; we treat it as implementation-dependent - * so it's defined in ieee80211_var.h. The max may be wrong - * for jumbo frames. - */ -#define IEEE80211_RTS_MIN 1 -#define IEEE80211_RTS_MAX 2346 - -/* - * TX fragmentation parameters. As above for RTS, we treat - * default as implementation-dependent so define it elsewhere. - */ -#define IEEE80211_FRAG_MIN 256 -#define IEEE80211_FRAG_MAX 2346 - -/* - * Beacon interval (TU's). Min+max come from WiFi requirements. - * As above, we treat default as implementation-dependent so - * define it elsewhere. - */ -#define IEEE80211_BINTVAL_MAX 1000 /* max beacon interval (TU's) */ -#define IEEE80211_BINTVAL_MIN 25 /* min beacon interval (TU's) */ - -/* - * DTIM period (beacons). Min+max are not really defined - * by the protocol but we want them publicly visible so - * define them here. - */ -#define IEEE80211_DTIM_MAX 15 /* max DTIM period */ -#define IEEE80211_DTIM_MIN 1 /* min DTIM period */ - -/* - * Beacon miss threshold (beacons). As for DTIM, we define - * them here to be publicly visible. Note the max may be - * clamped depending on device capabilities. - */ -#define IEEE80211_HWBMISS_MIN 1 -#define IEEE80211_HWBMISS_MAX 255 - -/* - * 802.11 frame duration definitions. - */ - -struct ieee80211_duration { - uint16_t d_rts_dur; - uint16_t d_data_dur; - uint16_t d_plcp_len; - uint8_t d_residue; /* unused octets in time slot */ -}; - -/* One Time Unit (TU) is 1Kus = 1024 microseconds. */ -#define IEEE80211_DUR_TU 1024 - -/* IEEE 802.11b durations for DSSS PHY in microseconds */ -#define IEEE80211_DUR_DS_LONG_PREAMBLE 144 -#define IEEE80211_DUR_DS_SHORT_PREAMBLE 72 - -#define IEEE80211_DUR_DS_SLOW_PLCPHDR 48 -#define IEEE80211_DUR_DS_FAST_PLCPHDR 24 -#define IEEE80211_DUR_DS_SLOW_ACK 112 -#define IEEE80211_DUR_DS_FAST_ACK 56 -#define IEEE80211_DUR_DS_SLOW_CTS 112 -#define IEEE80211_DUR_DS_FAST_CTS 56 - -#define IEEE80211_DUR_DS_SLOT 20 -#define IEEE80211_DUR_DS_SIFS 10 -#define IEEE80211_DUR_DS_PIFS (IEEE80211_DUR_DS_SIFS + IEEE80211_DUR_DS_SLOT) -#define IEEE80211_DUR_DS_DIFS (IEEE80211_DUR_DS_SIFS + \ - 2 * IEEE80211_DUR_DS_SLOT) -#define IEEE80211_DUR_DS_EIFS (IEEE80211_DUR_DS_SIFS + \ - IEEE80211_DUR_DS_SLOW_ACK + \ - IEEE80211_DUR_DS_LONG_PREAMBLE + \ - IEEE80211_DUR_DS_SLOW_PLCPHDR + \ - IEEE80211_DUR_DIFS) - -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_acl.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_acl.c deleted file mode 100644 index da505e3b9d..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_acl.c +++ /dev/null @@ -1,340 +0,0 @@ -/*- - * Copyright (c) 2004-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 MAC ACL support. - * - * When this module is loaded the sender address of each auth mgt - * frame is passed to the iac_check method and the module indicates - * if the frame should be accepted or rejected. If the policy is - * set to ACL_POLICY_OPEN then all frames are accepted w/o checking - * the address. Otherwise, the address is looked up in the database - * and if found the frame is either accepted (ACL_POLICY_ALLOW) - * or rejected (ACL_POLICY_DENT). - */ -#include "opt_wlan.h" - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include - -enum { - ACL_POLICY_OPEN = 0, /* open, don't check ACL's */ - ACL_POLICY_ALLOW = 1, /* allow traffic from MAC */ - ACL_POLICY_DENY = 2, /* deny traffic from MAC */ - /* - * NB: ACL_POLICY_RADIUS must be the same value as - * IEEE80211_MACCMD_POLICY_RADIUS because of the way - * acl_getpolicy() works. - */ - ACL_POLICY_RADIUS = 7, /* defer to RADIUS ACL server */ -}; - -#define ACL_HASHSIZE 32 - -struct acl { - TAILQ_ENTRY(acl) acl_list; - LIST_ENTRY(acl) acl_hash; - uint8_t acl_macaddr[IEEE80211_ADDR_LEN]; -}; -struct aclstate { - acl_lock_t as_lock; - int as_policy; - uint32_t as_nacls; - TAILQ_HEAD(, acl) as_list; /* list of all ACL's */ - LIST_HEAD(, acl) as_hash[ACL_HASHSIZE]; - struct ieee80211vap *as_vap; -}; - -/* simple hash is enough for variation of macaddr */ -#define ACL_HASH(addr) \ - (((const uint8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % ACL_HASHSIZE) - -MALLOC_DEFINE(M_80211_ACL, "acl", "802.11 station acl"); - -static int acl_free_all(struct ieee80211vap *); - -/* number of references from net80211 layer */ -static int nrefs = 0; - -static int -acl_attach(struct ieee80211vap *vap) -{ - struct aclstate *as; - - as = (struct aclstate *) malloc(sizeof(struct aclstate), - M_80211_ACL, M_NOWAIT | M_ZERO); - if (as == NULL) - return 0; - ACL_LOCK_INIT(as, "acl"); - TAILQ_INIT(&as->as_list); - as->as_policy = ACL_POLICY_OPEN; - as->as_vap = vap; - vap->iv_as = as; - nrefs++; /* NB: we assume caller locking */ - return 1; -} - -static void -acl_detach(struct ieee80211vap *vap) -{ - struct aclstate *as = vap->iv_as; - - KASSERT(nrefs > 0, ("imbalanced attach/detach")); - nrefs--; /* NB: we assume caller locking */ - - acl_free_all(vap); - vap->iv_as = NULL; - ACL_LOCK_DESTROY(as); - free(as, M_80211_ACL); -} - -static __inline struct acl * -_find_acl(struct aclstate *as, const uint8_t *macaddr) -{ - struct acl *acl; - int hash; - - hash = ACL_HASH(macaddr); - LIST_FOREACH(acl, &as->as_hash[hash], acl_hash) { - if (IEEE80211_ADDR_EQ(acl->acl_macaddr, macaddr)) - return acl; - } - return NULL; -} - -static void -_acl_free(struct aclstate *as, struct acl *acl) -{ - ACL_LOCK_ASSERT(as); - - TAILQ_REMOVE(&as->as_list, acl, acl_list); - LIST_REMOVE(acl, acl_hash); - free(acl, M_80211_ACL); - as->as_nacls--; -} - -static int -acl_check(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) -{ - struct aclstate *as = vap->iv_as; - - switch (as->as_policy) { - case ACL_POLICY_OPEN: - case ACL_POLICY_RADIUS: - return 1; - case ACL_POLICY_ALLOW: - return _find_acl(as, mac) != NULL; - case ACL_POLICY_DENY: - return _find_acl(as, mac) == NULL; - } - return 0; /* should not happen */ -} - -static int -acl_add(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) -{ - struct aclstate *as = vap->iv_as; - struct acl *acl, *new; - int hash; - - new = (struct acl *) malloc(sizeof(struct acl), M_80211_ACL, M_NOWAIT | M_ZERO); - if (new == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL, - "ACL: add %s failed, no memory\n", ether_sprintf(mac)); - /* XXX statistic */ - return ENOMEM; - } - - ACL_LOCK(as); - hash = ACL_HASH(mac); - LIST_FOREACH(acl, &as->as_hash[hash], acl_hash) { - if (IEEE80211_ADDR_EQ(acl->acl_macaddr, mac)) { - ACL_UNLOCK(as); - free(new, M_80211_ACL); - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL, - "ACL: add %s failed, already present\n", - ether_sprintf(mac)); - return EEXIST; - } - } - IEEE80211_ADDR_COPY(new->acl_macaddr, mac); - TAILQ_INSERT_TAIL(&as->as_list, new, acl_list); - LIST_INSERT_HEAD(&as->as_hash[hash], new, acl_hash); - as->as_nacls++; - ACL_UNLOCK(as); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL, - "ACL: add %s\n", ether_sprintf(mac)); - return 0; -} - -static int -acl_remove(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) -{ - struct aclstate *as = vap->iv_as; - struct acl *acl; - - ACL_LOCK(as); - acl = _find_acl(as, mac); - if (acl != NULL) - _acl_free(as, acl); - ACL_UNLOCK(as); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL, - "ACL: remove %s%s\n", ether_sprintf(mac), - acl == NULL ? ", not present" : ""); - - return (acl == NULL ? ENOENT : 0); -} - -static int -acl_free_all(struct ieee80211vap *vap) -{ - struct aclstate *as = vap->iv_as; - struct acl *acl; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL, "ACL: %s\n", "free all"); - - ACL_LOCK(as); - while ((acl = TAILQ_FIRST(&as->as_list)) != NULL) - _acl_free(as, acl); - ACL_UNLOCK(as); - - return 0; -} - -static int -acl_setpolicy(struct ieee80211vap *vap, int policy) -{ - struct aclstate *as = vap->iv_as; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL, - "ACL: set policy to %u\n", policy); - - switch (policy) { - case IEEE80211_MACCMD_POLICY_OPEN: - as->as_policy = ACL_POLICY_OPEN; - break; - case IEEE80211_MACCMD_POLICY_ALLOW: - as->as_policy = ACL_POLICY_ALLOW; - break; - case IEEE80211_MACCMD_POLICY_DENY: - as->as_policy = ACL_POLICY_DENY; - break; - case IEEE80211_MACCMD_POLICY_RADIUS: - as->as_policy = ACL_POLICY_RADIUS; - break; - default: - return EINVAL; - } - return 0; -} - -static int -acl_getpolicy(struct ieee80211vap *vap) -{ - struct aclstate *as = vap->iv_as; - - return as->as_policy; -} - -static int -acl_setioctl(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - - return EINVAL; -} - -static int -acl_getioctl(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct aclstate *as = vap->iv_as; - struct acl *acl; - struct ieee80211req_maclist *ap; - int error; - uint32_t i, space; - - switch (ireq->i_val) { - case IEEE80211_MACCMD_POLICY: - ireq->i_val = as->as_policy; - return 0; - case IEEE80211_MACCMD_LIST: - space = as->as_nacls * IEEE80211_ADDR_LEN; - if (ireq->i_len == 0) { - ireq->i_len = space; /* return required space */ - return 0; /* NB: must not error */ - } - ap = (struct ieee80211req_maclist *) malloc(space, - M_TEMP, M_NOWAIT); - if (ap == NULL) - return ENOMEM; - i = 0; - ACL_LOCK(as); - TAILQ_FOREACH(acl, &as->as_list, acl_list) { - IEEE80211_ADDR_COPY(ap[i].ml_macaddr, acl->acl_macaddr); - i++; - } - ACL_UNLOCK(as); - if (ireq->i_len >= space) { - error = copyout(ap, ireq->i_data, space); - ireq->i_len = space; - } else - error = copyout(ap, ireq->i_data, ireq->i_len); - free(ap, M_TEMP); - return error; - } - return EINVAL; -} - -static const struct ieee80211_aclator mac = { - .iac_name = "mac", - .iac_attach = acl_attach, - .iac_detach = acl_detach, - .iac_check = acl_check, - .iac_add = acl_add, - .iac_remove = acl_remove, - .iac_flush = acl_free_all, - .iac_setpolicy = acl_setpolicy, - .iac_getpolicy = acl_getpolicy, - .iac_setioctl = acl_setioctl, - .iac_getioctl = acl_getioctl, -}; -IEEE80211_ACL_MODULE(wlan_acl, mac, 1); diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_action.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_action.c deleted file mode 100644 index 8c11471c89..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_action.c +++ /dev/null @@ -1,279 +0,0 @@ -/*- - * Copyright (c) 2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifdef __FreeBSD__ -__FBSDID("$FreeBSD$"); -#endif - -/* - * IEEE 802.11 send/recv action frame support. - */ - -#include "opt_inet.h" -#include "opt_wlan.h" - -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include - -static int -send_inval(struct ieee80211_node *ni, int cat, int act, void *sa) -{ - return EINVAL; -} - -static ieee80211_send_action_func *ba_send_action[8] = { - send_inval, send_inval, send_inval, send_inval, - send_inval, send_inval, send_inval, send_inval, -}; -static ieee80211_send_action_func *ht_send_action[8] = { - send_inval, send_inval, send_inval, send_inval, - send_inval, send_inval, send_inval, send_inval, -}; -static ieee80211_send_action_func *meshpl_send_action[8] = { - send_inval, send_inval, send_inval, send_inval, - send_inval, send_inval, send_inval, send_inval, -}; -static ieee80211_send_action_func *meshlm_send_action[4] = { - send_inval, send_inval, send_inval, send_inval, -}; -static ieee80211_send_action_func *hwmp_send_action[8] = { - send_inval, send_inval, send_inval, send_inval, - send_inval, send_inval, send_inval, send_inval, -}; -static ieee80211_send_action_func *vendor_send_action[8] = { - send_inval, send_inval, send_inval, send_inval, - send_inval, send_inval, send_inval, send_inval, -}; - -int -ieee80211_send_action_register(int cat, int act, ieee80211_send_action_func *f) -{ -#define N(a) (sizeof(a) / sizeof(a[0])) - switch (cat) { - case IEEE80211_ACTION_CAT_BA: - if (act >= N(ba_send_action)) - break; - ba_send_action[act] = f; - return 0; - case IEEE80211_ACTION_CAT_HT: - if (act >= N(ht_send_action)) - break; - ht_send_action[act] = f; - return 0; - case IEEE80211_ACTION_CAT_MESHPEERING: - if (act >= N(meshpl_send_action)) - break; - meshpl_send_action[act] = f; - return 0; - case IEEE80211_ACTION_CAT_MESHLMETRIC: - if (act >= N(meshlm_send_action)) - break; - meshlm_send_action[act] = f; - return 0; - case IEEE80211_ACTION_CAT_MESHPATH: - if (act >= N(hwmp_send_action)) - break; - hwmp_send_action[act] = f; - return 0; - case IEEE80211_ACTION_CAT_VENDOR: - if (act >= N(vendor_send_action)) - break; - vendor_send_action[act] = f; - return 0; - } - return EINVAL; -#undef N -} - -void -ieee80211_send_action_unregister(int cat, int act) -{ - ieee80211_send_action_register(cat, act, send_inval); -} - -int -ieee80211_send_action(struct ieee80211_node *ni, int cat, int act, void *sa) -{ -#define N(a) (sizeof(a) / sizeof(a[0])) - ieee80211_send_action_func *f = send_inval; - - switch (cat) { - case IEEE80211_ACTION_CAT_BA: - if (act < N(ba_send_action)) - f = ba_send_action[act]; - break; - case IEEE80211_ACTION_CAT_HT: - if (act < N(ht_send_action)) - f = ht_send_action[act]; - break; - case IEEE80211_ACTION_CAT_MESHPEERING: - if (act < N(meshpl_send_action)) - f = meshpl_send_action[act]; - break; - case IEEE80211_ACTION_CAT_MESHLMETRIC: - if (act < N(meshlm_send_action)) - f = meshlm_send_action[act]; - break; - case IEEE80211_ACTION_CAT_MESHPATH: - if (act < N(hwmp_send_action)) - f = hwmp_send_action[act]; - break; - case IEEE80211_ACTION_CAT_VENDOR: - if (act < N(vendor_send_action)) - f = vendor_send_action[act]; - break; - } - return f(ni, cat, act, sa); -#undef N -} - -static int -recv_inval(struct ieee80211_node *ni, const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ - return EINVAL; -} - -static ieee80211_recv_action_func *ba_recv_action[8] = { - recv_inval, recv_inval, recv_inval, recv_inval, - recv_inval, recv_inval, recv_inval, recv_inval, -}; -static ieee80211_recv_action_func *ht_recv_action[8] = { - recv_inval, recv_inval, recv_inval, recv_inval, - recv_inval, recv_inval, recv_inval, recv_inval, -}; -static ieee80211_recv_action_func *meshpl_recv_action[8] = { - recv_inval, recv_inval, recv_inval, recv_inval, - recv_inval, recv_inval, recv_inval, recv_inval, -}; -static ieee80211_recv_action_func *meshlm_recv_action[4] = { - recv_inval, recv_inval, recv_inval, recv_inval, -}; -static ieee80211_recv_action_func *hwmp_recv_action[8] = { - recv_inval, recv_inval, recv_inval, recv_inval, - recv_inval, recv_inval, recv_inval, recv_inval, -}; -static ieee80211_recv_action_func *vendor_recv_action[8] = { - recv_inval, recv_inval, recv_inval, recv_inval, - recv_inval, recv_inval, recv_inval, recv_inval, -}; - -int -ieee80211_recv_action_register(int cat, int act, ieee80211_recv_action_func *f) -{ -#define N(a) (sizeof(a) / sizeof(a[0])) - switch (cat) { - case IEEE80211_ACTION_CAT_BA: - if (act >= N(ba_recv_action)) - break; - ba_recv_action[act] = f; - return 0; - case IEEE80211_ACTION_CAT_HT: - if (act >= N(ht_recv_action)) - break; - ht_recv_action[act] = f; - return 0; - case IEEE80211_ACTION_CAT_MESHPEERING: - if (act >= N(meshpl_recv_action)) - break; - meshpl_recv_action[act] = f; - return 0; - case IEEE80211_ACTION_CAT_MESHLMETRIC: - if (act >= N(meshlm_recv_action)) - break; - meshlm_recv_action[act] = f; - return 0; - case IEEE80211_ACTION_CAT_MESHPATH: - if (act >= N(hwmp_recv_action)) - break; - hwmp_recv_action[act] = f; - return 0; - case IEEE80211_ACTION_CAT_VENDOR: - if (act >= N(vendor_recv_action)) - break; - vendor_recv_action[act] = f; - return 0; - } - return EINVAL; -#undef N -} - -void -ieee80211_recv_action_unregister(int cat, int act) -{ - ieee80211_recv_action_register(cat, act, recv_inval); -} - -int -ieee80211_recv_action(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ -#define N(a) (sizeof(a) / sizeof(a[0])) - ieee80211_recv_action_func *f = recv_inval; - const struct ieee80211_action *ia = - (const struct ieee80211_action *) frm; - - switch (ia->ia_category) { - case IEEE80211_ACTION_CAT_BA: - if (ia->ia_action < N(ba_recv_action)) - f = ba_recv_action[ia->ia_action]; - break; - case IEEE80211_ACTION_CAT_HT: - if (ia->ia_action < N(ht_recv_action)) - f = ht_recv_action[ia->ia_action]; - break; - case IEEE80211_ACTION_CAT_MESHPEERING: - if (ia->ia_action < N(meshpl_recv_action)) - f = meshpl_recv_action[ia->ia_action]; - break; - case IEEE80211_ACTION_CAT_MESHLMETRIC: - if (ia->ia_action < N(meshlm_recv_action)) - f = meshlm_recv_action[ia->ia_action]; - break; - case IEEE80211_ACTION_CAT_MESHPATH: - if (ia->ia_action < N(hwmp_recv_action)) - f = hwmp_recv_action[ia->ia_action]; - break; - case IEEE80211_ACTION_CAT_VENDOR: - if (ia->ia_action < N(vendor_recv_action)) - f = vendor_recv_action[ia->ia_action]; - break; - } - return f(ni, wh, frm, efrm); -#undef N -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_action.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_action.h deleted file mode 100644 index 9be0aba821..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_action.h +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * Copyright (c) 2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_ACTION_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_ACTION_H_ - -/* - * 802.11 send/recv action frame support. - */ - -struct ieee80211_node; -struct ieee80211_frame; - -typedef int ieee80211_send_action_func(struct ieee80211_node *, - int, int, void *); -int ieee80211_send_action_register(int cat, int act, - ieee80211_send_action_func *f); -void ieee80211_send_action_unregister(int cat, int act); -int ieee80211_send_action(struct ieee80211_node *, int, int, void *); - -typedef int ieee80211_recv_action_func(struct ieee80211_node *, - const struct ieee80211_frame *, const uint8_t *, const uint8_t *); -int ieee80211_recv_action_register(int cat, int act, - ieee80211_recv_action_func *); -void ieee80211_recv_action_unregister(int cat, int act); -int ieee80211_recv_action(struct ieee80211_node *, - const struct ieee80211_frame *, - const uint8_t *, const uint8_t *); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_ACTION_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_adhoc.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_adhoc.c deleted file mode 100644 index 8d9bcce589..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_adhoc.c +++ /dev/null @@ -1,919 +0,0 @@ -/*- - * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifdef __FreeBSD__ -__FBSDID("$FreeBSD$"); -#endif - -/* - * IEEE 802.11 IBSS mode support. - */ -#include "opt_inet.h" -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#ifdef IEEE80211_SUPPORT_SUPERG -#include -#endif -#ifdef IEEE80211_SUPPORT_TDMA -#include -#endif - -#define IEEE80211_RATE2MBS(r) (((r) & IEEE80211_RATE_VAL) / 2) - -static void adhoc_vattach(struct ieee80211vap *); -static int adhoc_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int adhoc_input(struct ieee80211_node *, struct mbuf *, int, int); -static void adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int, int); -static void ahdemo_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int, int); -static void adhoc_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype); - -void -ieee80211_adhoc_attach(struct ieee80211com *ic) -{ - ic->ic_vattach[IEEE80211_M_IBSS] = adhoc_vattach; - ic->ic_vattach[IEEE80211_M_AHDEMO] = adhoc_vattach; -} - -void -ieee80211_adhoc_detach(struct ieee80211com *ic) -{ -} - -static void -adhoc_vdetach(struct ieee80211vap *vap) -{ -} - -static void -adhoc_vattach(struct ieee80211vap *vap) -{ - vap->iv_newstate = adhoc_newstate; - vap->iv_input = adhoc_input; - if (vap->iv_opmode == IEEE80211_M_IBSS) - vap->iv_recv_mgmt = adhoc_recv_mgmt; - else - vap->iv_recv_mgmt = ahdemo_recv_mgmt; - vap->iv_recv_ctl = adhoc_recv_ctl; - vap->iv_opdetach = adhoc_vdetach; -#ifdef IEEE80211_SUPPORT_TDMA - /* - * Throw control to tdma support. Note we do this - * after setting up our callbacks so it can piggyback - * on top of us. - */ - if (vap->iv_caps & IEEE80211_C_TDMA) - ieee80211_tdma_vattach(vap); -#endif -} - -static void -sta_leave(void *arg, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = arg; - - if (ni->ni_vap == vap && ni != vap->iv_bss) - ieee80211_node_leave(ni); -} - -/* - * IEEE80211_M_IBSS+IEEE80211_M_AHDEMO vap state machine handler. - */ -static int -adhoc_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni; - enum ieee80211_state ostate; - - IEEE80211_LOCK_ASSERT(vap->iv_ic); - - ostate = vap->iv_state; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n", - __func__, ieee80211_state_name[ostate], - ieee80211_state_name[nstate], arg); - vap->iv_state = nstate; /* state transition */ - if (ostate != IEEE80211_S_SCAN) - ieee80211_cancel_scan(vap); /* background scan */ - ni = vap->iv_bss; /* NB: no reference held */ - switch (nstate) { - case IEEE80211_S_INIT: - switch (ostate) { - case IEEE80211_S_SCAN: - ieee80211_cancel_scan(vap); - break; - default: - break; - } - if (ostate != IEEE80211_S_INIT) { - /* NB: optimize INIT -> INIT case */ - ieee80211_reset_bss(vap); - } - break; - case IEEE80211_S_SCAN: - switch (ostate) { - case IEEE80211_S_RUN: /* beacon miss */ - /* purge station table; entries are stale */ - ieee80211_iterate_nodes(&ic->ic_sta, sta_leave, vap); - /* fall thru... */ - case IEEE80211_S_INIT: - if (vap->iv_des_chan != IEEE80211_CHAN_ANYC && - !IEEE80211_IS_CHAN_RADAR(vap->iv_des_chan)) { - /* - * Already have a channel; bypass the - * scan and startup immediately. - */ - ieee80211_create_ibss(vap, vap->iv_des_chan); - break; - } - /* - * Initiate a scan. We can come here as a result - * of an IEEE80211_IOC_SCAN_REQ too in which case - * the vap will be marked with IEEE80211_FEXT_SCANREQ - * and the scan request parameters will be present - * in iv_scanreq. Otherwise we do the default. - */ - if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) { - ieee80211_check_scan(vap, - vap->iv_scanreq_flags, - vap->iv_scanreq_duration, - vap->iv_scanreq_mindwell, - vap->iv_scanreq_maxdwell, - vap->iv_scanreq_nssid, vap->iv_scanreq_ssid); - vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; - } else - ieee80211_check_scan_current(vap); - break; - case IEEE80211_S_SCAN: - /* - * This can happen because of a change in state - * that requires a reset. Trigger a new scan - * unless we're in manual roaming mode in which - * case an application must issue an explicit request. - */ - if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) - ieee80211_check_scan_current(vap); - break; - default: - goto invalid; - } - break; - case IEEE80211_S_RUN: - if (vap->iv_flags & IEEE80211_F_WPA) { - /* XXX validate prerequisites */ - } - switch (ostate) { - case IEEE80211_S_SCAN: -#ifdef IEEE80211_DEBUG - if (ieee80211_msg_debug(vap)) { - ieee80211_note(vap, - "synchronized with %s ssid ", - ether_sprintf(ni->ni_bssid)); - ieee80211_print_essid(vap->iv_bss->ni_essid, - ni->ni_esslen); - /* XXX MCS/HT */ - printf(" channel %d start %uMb\n", - ieee80211_chan2ieee(ic, ic->ic_curchan), - IEEE80211_RATE2MBS(ni->ni_txrate)); - } -#endif - break; - default: - goto invalid; - } - /* - * When 802.1x is not in use mark the port authorized - * at this point so traffic can flow. - */ - if (ni->ni_authmode != IEEE80211_AUTH_8021X) - ieee80211_node_authorize(ni); - /* - * Fake association when joining an existing bss. - */ - if (!IEEE80211_ADDR_EQ(ni->ni_macaddr, vap->iv_myaddr) && - ic->ic_newassoc != NULL) - ic->ic_newassoc(ni, ostate != IEEE80211_S_RUN); - break; - case IEEE80211_S_SLEEP: - ieee80211_sta_pwrsave(vap, 0); - break; - default: - invalid: - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, - "%s: unexpected state transition %s -> %s\n", __func__, - ieee80211_state_name[ostate], ieee80211_state_name[nstate]); - break; - } - return 0; -} - -/* - * Decide if a received management frame should be - * printed when debugging is enabled. This filters some - * of the less interesting frames that come frequently - * (e.g. beacons). - */ -static __inline int -doprint(struct ieee80211vap *vap, int subtype) -{ - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_BEACON: - return (vap->iv_ic->ic_flags & IEEE80211_F_SCAN); - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - return 1; - } - return 1; -} - -/* - * Process a received frame. The node associated with the sender - * should be supplied. If nothing was found in the node table then - * the caller is assumed to supply a reference to iv_bss instead. - * The RSSI and a timestamp are also supplied. The RSSI data is used - * during AP scanning to select a AP to associate with; it can have - * any units so long as values have consistent units and higher values - * mean ``better signal''. The receive timestamp is currently not used - * by the 802.11 layer. - */ -static int -adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) -{ -#define HAS_SEQ(type) ((type & 0x4) == 0) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = vap->iv_ifp; - struct ieee80211_frame *wh; - struct ieee80211_key *key; - struct ether_header *eh; - int hdrspace, need_tap = 1; /* mbuf need to be tapped. */ - uint8_t dir, type, subtype, qos; - uint8_t *bssid; - uint16_t rxseq; - - if (m->m_flags & M_AMPDU_MPDU) { - /* - * Fastpath for A-MPDU reorder q resubmission. Frames - * w/ M_AMPDU_MPDU marked have already passed through - * here but were received out of order and been held on - * the reorder queue. When resubmitted they are marked - * with the M_AMPDU_MPDU flag and we can bypass most of - * the normal processing. - */ - wh = mtod(m, struct ieee80211_frame *); - type = IEEE80211_FC0_TYPE_DATA; - dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; - subtype = IEEE80211_FC0_SUBTYPE_QOS; - hdrspace = ieee80211_hdrspace(ic, wh); /* XXX optimize? */ - goto resubmit_ampdu; - } - - KASSERT(ni != NULL, ("null node")); - ni->ni_inact = ni->ni_inact_reload; - - type = -1; /* undefined */ - - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, - "too short (1): len %u", m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } - /* - * Bit of a cheat here, we use a pointer for a 3-address - * frame format but don't reference fields past outside - * ieee80211_frame_min w/o first validating the data is - * present. - */ - wh = mtod(m, struct ieee80211_frame *); - - if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != - IEEE80211_FC0_VERSION_0) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, "wrong version, fc %02x:%02x", - wh->i_fc[0], wh->i_fc[1]); - vap->iv_stats.is_rx_badversion++; - goto err; - } - - dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; - type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; - subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { - if (dir != IEEE80211_FC1_DIR_NODS) - bssid = wh->i_addr1; - else if (type == IEEE80211_FC0_TYPE_CTL) - bssid = wh->i_addr1; - else { - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_ANY, ni->ni_macaddr, - NULL, "too short (2): len %u", - m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } - bssid = wh->i_addr3; - } - /* - * Validate the bssid. - */ - if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bss->ni_bssid) && - !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) { - /* not interested in */ - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - bssid, NULL, "%s", "not to bss"); - vap->iv_stats.is_rx_wrongbss++; - goto out; - } - /* - * Data frame, cons up a node when it doesn't - * exist. This should probably done after an ACL check. - */ - if (type == IEEE80211_FC0_TYPE_DATA && - ni == vap->iv_bss && - !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { - /* - * Beware of frames that come in too early; we - * can receive broadcast frames and creating sta - * entries will blow up because there is no bss - * channel yet. - */ - if (vap->iv_state != IEEE80211_S_RUN) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "data", "not in RUN state (%s)", - ieee80211_state_name[vap->iv_state]); - vap->iv_stats.is_rx_badstate++; - goto err; - } - /* - * Fake up a node for this newly - * discovered member of the IBSS. - */ - ni = ieee80211_fakeup_adhoc_node(vap, wh->i_addr2); - if (ni == NULL) { - /* NB: stat kept for alloc failure */ - goto err; - } - } - IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = nf; - if (HAS_SEQ(type)) { - uint8_t tid = ieee80211_gettid(wh); - if (IEEE80211_QOS_HAS_SEQ(wh) && - TID_TO_WME_AC(tid) >= WME_AC_VI) - ic->ic_wme.wme_hipri_traffic++; - rxseq = le16toh(*(uint16_t *)wh->i_seq); - if (! ieee80211_check_rxseq(ni, wh)) { - /* duplicate, discard */ - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - bssid, "duplicate", - "seqno <%u,%u> fragno <%u,%u> tid %u", - rxseq >> IEEE80211_SEQ_SEQ_SHIFT, - ni->ni_rxseqs[tid] >> - IEEE80211_SEQ_SEQ_SHIFT, - rxseq & IEEE80211_SEQ_FRAG_MASK, - ni->ni_rxseqs[tid] & - IEEE80211_SEQ_FRAG_MASK, - tid); - vap->iv_stats.is_rx_dup++; - IEEE80211_NODE_STAT(ni, rx_dup); - goto out; - } - ni->ni_rxseqs[tid] = rxseq; - } - } - - switch (type) { - case IEEE80211_FC0_TYPE_DATA: - hdrspace = ieee80211_hdrspace(ic, wh); - if (m->m_len < hdrspace && - (m = m_pullup(m, hdrspace)) == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, - "data too short: expecting %u", hdrspace); - vap->iv_stats.is_rx_tooshort++; - goto out; /* XXX */ - } - if (dir != IEEE80211_FC1_DIR_NODS) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "data", "incorrect dir 0x%x", dir); - vap->iv_stats.is_rx_wrongdir++; - goto out; - } - /* XXX no power-save support */ - - /* - * Handle A-MPDU re-ordering. If the frame is to be - * processed directly then ieee80211_ampdu_reorder - * will return 0; otherwise it has consumed the mbuf - * and we should do nothing more with it. - */ - if ((m->m_flags & M_AMPDU) && - ieee80211_ampdu_reorder(ni, m) != 0) { - m = NULL; - goto out; - } - resubmit_ampdu: - - /* - * Handle privacy requirements. Note that we - * must not be preempted from here until after - * we (potentially) call ieee80211_crypto_demic; - * otherwise we may violate assumptions in the - * crypto cipher modules used to do delayed update - * of replay sequence numbers. - */ - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { - /* - * Discard encrypted frames when privacy is off. - */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "WEP", "%s", "PRIVACY off"); - vap->iv_stats.is_rx_noprivacy++; - IEEE80211_NODE_STAT(ni, rx_noprivacy); - goto out; - } - key = ieee80211_crypto_decap(ni, m, hdrspace); - if (key == NULL) { - /* NB: stats+msgs handled in crypto_decap */ - IEEE80211_NODE_STAT(ni, rx_wepfail); - goto out; - } - wh = mtod(m, struct ieee80211_frame *); - wh->i_fc[1] &= ~IEEE80211_FC1_WEP; - } else { - /* XXX M_WEP and IEEE80211_F_PRIVACY */ - key = NULL; - } - - /* - * Save QoS bits for use below--before we strip the header. - */ - if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { - qos = (dir == IEEE80211_FC1_DIR_DSTODS) ? - ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] : - ((struct ieee80211_qosframe *)wh)->i_qos[0]; - } else - qos = 0; - - /* - * Next up, any fragmentation. - */ - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - m = ieee80211_defrag(ni, m, hdrspace); - if (m == NULL) { - /* Fragment dropped or frame not complete yet */ - goto out; - } - } - wh = NULL; /* no longer valid, catch any uses */ - - /* - * Next strip any MSDU crypto bits. - */ - if (key != NULL && !ieee80211_crypto_demic(vap, key, m, 0)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - ni->ni_macaddr, "data", "%s", "demic error"); - vap->iv_stats.is_rx_demicfail++; - IEEE80211_NODE_STAT(ni, rx_demicfail); - goto out; - } - - /* copy to listener after decrypt */ - if (ieee80211_radiotap_active_vap(vap)) - ieee80211_radiotap_rx(vap, m); - need_tap = 0; - - /* - * Finally, strip the 802.11 header. - */ - m = ieee80211_decap(vap, m, hdrspace); - if (m == NULL) { - /* XXX mask bit to check for both */ - /* don't count Null data frames as errors */ - if (subtype == IEEE80211_FC0_SUBTYPE_NODATA || - subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL) - goto out; - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - ni->ni_macaddr, "data", "%s", "decap error"); - vap->iv_stats.is_rx_decap++; - IEEE80211_NODE_STAT(ni, rx_decap); - goto err; - } - eh = mtod(m, struct ether_header *); - if (!ieee80211_node_is_authorized(ni)) { - /* - * Deny any non-PAE frames received prior to - * authorization. For open/shared-key - * authentication the port is mark authorized - * after authentication completes. For 802.1x - * the port is not marked authorized by the - * authenticator until the handshake has completed. - */ - if (eh->ether_type != htons(ETHERTYPE_PAE)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - eh->ether_shost, "data", - "unauthorized port: ether type 0x%x len %u", - eh->ether_type, m->m_pkthdr.len); - vap->iv_stats.is_rx_unauth++; - IEEE80211_NODE_STAT(ni, rx_unauth); - goto err; - } - } else { - /* - * When denying unencrypted frames, discard - * any non-PAE frames received without encryption. - */ - if ((vap->iv_flags & IEEE80211_F_DROPUNENC) && - (key == NULL && (m->m_flags & M_WEP) == 0) && - eh->ether_type != htons(ETHERTYPE_PAE)) { - /* - * Drop unencrypted frames. - */ - vap->iv_stats.is_rx_unencrypted++; - IEEE80211_NODE_STAT(ni, rx_unencrypted); - goto out; - } - } - /* XXX require HT? */ - if (qos & IEEE80211_QOS_AMSDU) { - m = ieee80211_decap_amsdu(ni, m); - if (m == NULL) - return IEEE80211_FC0_TYPE_DATA; - } else { -#ifdef IEEE80211_SUPPORT_SUPERG - m = ieee80211_decap_fastframe(vap, ni, m); - if (m == NULL) - return IEEE80211_FC0_TYPE_DATA; -#endif - } - if (dir == IEEE80211_FC1_DIR_DSTODS && ni->ni_wdsvap != NULL) - ieee80211_deliver_data(ni->ni_wdsvap, ni, m); - else - ieee80211_deliver_data(vap, ni, m); - return IEEE80211_FC0_TYPE_DATA; - - case IEEE80211_FC0_TYPE_MGT: - vap->iv_stats.is_rx_mgmt++; - IEEE80211_NODE_STAT(ni, rx_mgmt); - if (dir != IEEE80211_FC1_DIR_NODS) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "data", "incorrect dir 0x%x", dir); - vap->iv_stats.is_rx_wrongdir++; - goto err; - } - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, "mgt", "too short: len %u", - m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } -#ifdef IEEE80211_DEBUG - if ((ieee80211_msg_debug(vap) && doprint(vap, subtype)) || - ieee80211_msg_dumppkts(vap)) { - if_printf(ifp, "received %s from %s rssi %d\n", - ieee80211_mgt_subtype_name[subtype >> - IEEE80211_FC0_SUBTYPE_SHIFT], - ether_sprintf(wh->i_addr2), rssi); - } -#endif - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "WEP set but not permitted"); - vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ - goto out; - } - vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); - goto out; - - case IEEE80211_FC0_TYPE_CTL: - vap->iv_stats.is_rx_ctl++; - IEEE80211_NODE_STAT(ni, rx_ctrl); - vap->iv_recv_ctl(ni, m, subtype); - goto out; - - default: - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "bad", "frame type 0x%x", type); - /* should not come here */ - break; - } -err: - ifp->if_ierrors++; -out: - if (m != NULL) { - if (need_tap && ieee80211_radiotap_active_vap(vap)) - ieee80211_radiotap_rx(vap, m); - m_freem(m); - } - return type; -} - -static int -is11bclient(const uint8_t *rates, const uint8_t *xrates) -{ - static const uint32_t brates = (1<<2*1)|(1<<2*2)|(1<<11)|(1<<2*11); - int i; - - /* NB: the 11b clients we care about will not have xrates */ - if (xrates != NULL || rates == NULL) - return 0; - for (i = 0; i < rates[1]; i++) { - int r = rates[2+i] & IEEE80211_RATE_VAL; - if (r > 2*11 || ((1<ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_frame *wh; - uint8_t *frm, *efrm, *sfrm; - uint8_t *ssid, *rates, *xrates; - - wh = mtod(m0, struct ieee80211_frame *); - frm = (uint8_t *)&wh[1]; - efrm = mtod(m0, uint8_t *) + m0->m_len; - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - case IEEE80211_FC0_SUBTYPE_BEACON: { - struct ieee80211_scanparams scan; - /* - * We process beacon/probe response - * frames to discover neighbors. - */ - if (ieee80211_parse_beacon(ni, m0, &scan) != 0) - return; - /* - * Count frame now that we know it's to be processed. - */ - if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) { - vap->iv_stats.is_rx_beacon++; /* XXX remove */ - IEEE80211_NODE_STAT(ni, rx_beacons); - } else - IEEE80211_NODE_STAT(ni, rx_proberesp); - /* - * If scanning, just pass information to the scan module. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) { - if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) { - /* - * Actively scanning a channel marked passive; - * send a probe request now that we know there - * is 802.11 traffic present. - * - * XXX check if the beacon we recv'd gives - * us what we need and suppress the probe req - */ - ieee80211_probe_curchan(vap, 1); - ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; - } - ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf); - return; - } - if (scan.capinfo & IEEE80211_CAPINFO_IBSS) { - if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { - /* - * Create a new entry in the neighbor table. - */ - ni = ieee80211_add_neighbor(vap, wh, &scan); - } else if (ni->ni_capinfo == 0) { - /* - * Update faked node created on transmit. - * Note this also updates the tsf. - */ - ieee80211_init_neighbor(ni, wh, &scan); - } else { - /* - * Record tsf for potential resync. - */ - memcpy(ni->ni_tstamp.data, scan.tstamp, - sizeof(ni->ni_tstamp)); - } - if (ni != NULL) { - IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = nf; - } - } - break; - } - - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - if (vap->iv_state != IEEE80211_S_RUN) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "wrong state %s", - ieee80211_state_name[vap->iv_state]); - vap->iv_stats.is_rx_mgtdiscard++; - return; - } - if (IEEE80211_IS_MULTICAST(wh->i_addr2)) { - /* frame must be directed */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not unicast"); - vap->iv_stats.is_rx_mgtdiscard++; /* XXX stat */ - return; - } - - /* - * prreq frame format - * [tlv] ssid - * [tlv] supported rates - * [tlv] extended supported rates - */ - ssid = rates = xrates = NULL; - sfrm = frm; - while (efrm - frm > 1) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); - switch (*frm) { - case IEEE80211_ELEMID_SSID: - ssid = frm; - break; - case IEEE80211_ELEMID_RATES: - rates = frm; - break; - case IEEE80211_ELEMID_XRATES: - xrates = frm; - break; - } - frm += frm[1] + 2; - } - IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return); - if (xrates != NULL) - IEEE80211_VERIFY_ELEMENT(xrates, - IEEE80211_RATE_MAXSIZE - rates[1], return); - IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN, return); - IEEE80211_VERIFY_SSID(vap->iv_bss, ssid, return); - if ((vap->iv_flags & IEEE80211_F_HIDESSID) && ssid[1] == 0) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, - "%s", "no ssid with ssid suppression enabled"); - vap->iv_stats.is_rx_ssidmismatch++; /*XXX*/ - return; - } - - /* XXX find a better class or define it's own */ - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2, - "%s", "recv probe req"); - /* - * Some legacy 11b clients cannot hack a complete - * probe response frame. When the request includes - * only a bare-bones rate set, communicate this to - * the transmit side. - */ - ieee80211_send_proberesp(vap, wh->i_addr2, - is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0); - break; - - case IEEE80211_FC0_SUBTYPE_ACTION: - case IEEE80211_FC0_SUBTYPE_ACTION_NOACK: - if (ni == vap->iv_bss) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "unknown node"); - vap->iv_stats.is_rx_mgtdiscard++; - } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) && - !IEEE80211_IS_MULTICAST(wh->i_addr1)) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not for us"); - vap->iv_stats.is_rx_mgtdiscard++; - } else if (vap->iv_state != IEEE80211_S_RUN) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "wrong state %s", - ieee80211_state_name[vap->iv_state]); - vap->iv_stats.is_rx_mgtdiscard++; - } else { - if (ieee80211_parse_action(ni, m0) == 0) - (void)ic->ic_recv_action(ni, wh, frm, efrm); - } - break; - - case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_ATIM: - case IEEE80211_FC0_SUBTYPE_DISASSOC: - case IEEE80211_FC0_SUBTYPE_AUTH: - case IEEE80211_FC0_SUBTYPE_DEAUTH: - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not handled"); - vap->iv_stats.is_rx_mgtdiscard++; - break; - - default: - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "mgt", "subtype 0x%x not handled", subtype); - vap->iv_stats.is_rx_badsubtype++; - break; - } -} -#undef IEEE80211_VERIFY_LENGTH -#undef IEEE80211_VERIFY_ELEMENT - -static void -ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int nf) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_frame *wh; - - /* - * Process management frames when scanning; useful for doing - * a site-survey. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) - adhoc_recv_mgmt(ni, m0, subtype, rssi, nf); - else { - wh = mtod(m0, struct ieee80211_frame *); - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - case IEEE80211_FC0_SUBTYPE_BEACON: - case IEEE80211_FC0_SUBTYPE_ATIM: - case IEEE80211_FC0_SUBTYPE_DISASSOC: - case IEEE80211_FC0_SUBTYPE_AUTH: - case IEEE80211_FC0_SUBTYPE_DEAUTH: - case IEEE80211_FC0_SUBTYPE_ACTION: - case IEEE80211_FC0_SUBTYPE_ACTION_NOACK: - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not handled"); - vap->iv_stats.is_rx_mgtdiscard++; - break; - default: - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "mgt", "subtype 0x%x not handled", subtype); - vap->iv_stats.is_rx_badsubtype++; - break; - } - } -} - -static void -adhoc_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype) -{ - - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_BAR: - ieee80211_recv_bar(ni, m); - break; - } -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_adhoc.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_adhoc.h deleted file mode 100644 index 461c938976..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_adhoc.h +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_ADHOC_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_ADHOC_H_ - -/* - * Adhoc-mode (ibss+ahdemo) implementation definitions. - */ -void ieee80211_adhoc_attach(struct ieee80211com *); -void ieee80211_adhoc_detach(struct ieee80211com *); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_STA_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ageq.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_ageq.c deleted file mode 100644 index 018ddc2711..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ageq.c +++ /dev/null @@ -1,237 +0,0 @@ -/*- - * Copyright (c) 2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 age queue support. - */ -#include "opt_wlan.h" - -#include -#include -#include - -#include - -#include -#include -#include - -#include - -/* - * Initialize an ageq. - */ -void -ieee80211_ageq_init(struct ieee80211_ageq *aq, int maxlen, const char *name) -{ - memset(aq, 0, sizeof(*aq)); - aq->aq_maxlen = maxlen; - IEEE80211_AGEQ_INIT(aq, name); /* OS-dependent setup */ -} - -/* - * Cleanup an ageq initialized with ieee80211_ageq_init. Note - * the queue is assumed empty; this can be done with ieee80211_ageq_drain. - */ -void -ieee80211_ageq_cleanup(struct ieee80211_ageq *aq) -{ - KASSERT(aq->aq_len == 0, ("%d frames on ageq", aq->aq_len)); - IEEE80211_AGEQ_DESTROY(aq); /* OS-dependent cleanup */ -} - -/* - * Free an mbuf according to ageq rules: if marked as holding - * and 802.11 frame then also reclaim a node reference from - * the packet header; this handles packets q'd in the tx path. - */ -static void -ageq_mfree(struct mbuf *m) -{ - if (m->m_flags & M_ENCAP) { - struct ieee80211_node *ni = (void *) m->m_pkthdr.rcvif; - ieee80211_free_node(ni); - } - m->m_nextpkt = NULL; - m_freem(m); -} - -/* - * Free a list of mbufs using ageq rules (see above). - */ -void -ieee80211_ageq_mfree(struct mbuf *m) -{ - struct mbuf *next; - - for (; m != NULL; m = next) { - next = m->m_nextpkt; - ageq_mfree(m); - } -} - -/* - * Append an mbuf to the ageq and mark it with the specified max age - * If the frame is not removed before the age (in seconds) expires - * then it is reclaimed (along with any node reference). - */ -int -ieee80211_ageq_append(struct ieee80211_ageq *aq, struct mbuf *m, int age) -{ - IEEE80211_AGEQ_LOCK(aq); - if (__predict_true(aq->aq_len < aq->aq_maxlen)) { - if (aq->aq_tail == NULL) { - aq->aq_head = m; - } else { - aq->aq_tail->m_nextpkt = m; - age -= M_AGE_GET(aq->aq_head); - } - KASSERT(age >= 0, ("age %d", age)); - M_AGE_SET(m, age); - m->m_nextpkt = NULL; - aq->aq_tail = m; - aq->aq_len++; - IEEE80211_AGEQ_UNLOCK(aq); - return 0; - } else { - /* - * No space, drop and cleanup references. - */ - aq->aq_drops++; - IEEE80211_AGEQ_UNLOCK(aq); - /* XXX tail drop? */ - ageq_mfree(m); - return ENOSPC; - } -} - -/* - * Drain/reclaim all frames from an ageq. - */ -void -ieee80211_ageq_drain(struct ieee80211_ageq *aq) -{ - ieee80211_ageq_mfree(ieee80211_ageq_remove(aq, NULL)); -} - -/* - * Drain/reclaim frames associated with a specific node from an ageq. - */ -void -ieee80211_ageq_drain_node(struct ieee80211_ageq *aq, - struct ieee80211_node *ni) -{ - ieee80211_ageq_mfree(ieee80211_ageq_remove(aq, ni)); -} - -/* - * Age frames on the age queue. Ages are stored as time - * deltas (in seconds) relative to the head so we can check - * and/or adjust only the head of the list. If a frame's age - * exceeds the time quanta then remove it. The list of removed - * frames is returned to the caller joined by m_nextpkt. - */ -struct mbuf * -ieee80211_ageq_age(struct ieee80211_ageq *aq, int quanta) -{ - struct mbuf *head, **phead; - struct mbuf *m; - - phead = &head; - if (aq->aq_len != 0) { - IEEE80211_AGEQ_LOCK(aq); - while ((m = aq->aq_head) != NULL && M_AGE_GET(m) < quanta) { - if ((aq->aq_head = m->m_nextpkt) == NULL) - aq->aq_tail = NULL; - KASSERT(aq->aq_len > 0, ("aq len %d", aq->aq_len)); - aq->aq_len--; - /* add to private list for return */ - *phead = m; - phead = &m->m_nextpkt; - } - if (m != NULL) - M_AGE_SUB(m, quanta); - IEEE80211_AGEQ_UNLOCK(aq); - } - *phead = NULL; - return head; -} - -/* - * Remove all frames matching the specified node identifier - * (NULL matches all). Frames are returned as a list joined - * by m_nextpkt. - */ -struct mbuf * -ieee80211_ageq_remove(struct ieee80211_ageq *aq, - struct ieee80211_node *match) -{ - struct mbuf *m, **prev, *ohead; - struct mbuf *head, **phead; - - IEEE80211_AGEQ_LOCK(aq); - ohead = aq->aq_head; - prev = &aq->aq_head; - phead = &head; - while ((m = *prev) != NULL) { - if (match != NULL && m->m_pkthdr.rcvif != (void *) match) { - prev = &m->m_nextpkt; - continue; - } - /* - * Adjust q length. - */ - KASSERT(aq->aq_len > 0, ("aq len %d", aq->aq_len)); - aq->aq_len--; - /* - * Remove from forward list; tail pointer is harder. - */ - if (aq->aq_tail == m) { - KASSERT(m->m_nextpkt == NULL, ("not last")); - if (aq->aq_head == m) { /* list empty */ - KASSERT(aq->aq_len == 0, - ("not empty, len %d", aq->aq_len)); - aq->aq_tail = NULL; - } else { /* must be one before */ - aq->aq_tail = (struct mbuf *)((uintptr_t)prev - - offsetof(struct mbuf, m_nextpkt)); - } - } - *prev = m->m_nextpkt; - - /* add to private list for return */ - *phead = m; - phead = &m->m_nextpkt; - } - if (head == ohead && aq->aq_head != NULL) /* correct age */ - M_AGE_SET(aq->aq_head, M_AGE_GET(head)); - IEEE80211_AGEQ_UNLOCK(aq); - - *phead = NULL; - return head; -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ageq.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_ageq.h deleted file mode 100644 index a187f41ac5..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ageq.h +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * Copyright (c) 2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_STAGEQ_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_STAGEQ_H_ - -struct ieee80211_node; -struct mbuf; - -struct ieee80211_ageq { - ieee80211_ageq_lock_t aq_lock; - int aq_len; /* # items on queue */ - int aq_maxlen; /* max queue length */ - int aq_drops; /* frames dropped */ - struct mbuf *aq_head; /* frames linked w/ m_nextpkt */ - struct mbuf *aq_tail; /* last frame in queue */ -}; - -void ieee80211_ageq_init(struct ieee80211_ageq *, int maxlen, - const char *name); -void ieee80211_ageq_cleanup(struct ieee80211_ageq *); -void ieee80211_ageq_mfree(struct mbuf *); -int ieee80211_ageq_append(struct ieee80211_ageq *, struct mbuf *, - int age); -void ieee80211_ageq_drain(struct ieee80211_ageq *); -void ieee80211_ageq_drain_node(struct ieee80211_ageq *, - struct ieee80211_node *); -struct mbuf *ieee80211_ageq_age(struct ieee80211_ageq *, int quanta); -struct mbuf *ieee80211_ageq_remove(struct ieee80211_ageq *, - struct ieee80211_node *match); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_STAGEQ_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_alq.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_alq.c deleted file mode 100644 index 0d06d4b9ef..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_alq.c +++ /dev/null @@ -1,155 +0,0 @@ -/*- - * Copyright (c) 2011 Adrian Chadd, Xenion Lty Ltd - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifdef __FreeBSD__ -__FBSDID("$FreeBSD$"); -#endif - -/* - * net80211 fast-logging support, primarily for debugging. - * - * This implements a single debugging queue which includes - * per-device enumeration where needed. - */ - -#include "opt_wlan.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static struct alq *ieee80211_alq; -static int ieee80211_alq_lost; -static int ieee80211_alq_logged; -static char ieee80211_alq_logfile[MAXPATHLEN] = "/tmp/net80211.log"; -static unsigned int ieee80211_alq_qsize = 64*1024; - -static int -ieee80211_alq_setlogging(int enable) -{ - int error; - - if (enable) { - if (ieee80211_alq) - alq_close(ieee80211_alq); - - error = alq_open(&ieee80211_alq, - ieee80211_alq_logfile, - curthread->td_ucred, - ALQ_DEFAULT_CMODE, - sizeof (struct ieee80211_alq_rec), - ieee80211_alq_qsize); - ieee80211_alq_lost = 0; - ieee80211_alq_logged = 0; - printf("net80211: logging to %s enabled; struct size %d bytes\n", - ieee80211_alq_logfile, sizeof(struct ieee80211_alq_rec)); - } else { - if (ieee80211_alq) - alq_close(ieee80211_alq); - ieee80211_alq = NULL; - printf("net80211: logging disabled\n"); - error = 0; - } - return (error); -} - -static int -sysctl_ieee80211_alq_log(SYSCTL_HANDLER_ARGS) -{ - int error, enable; - - enable = (ieee80211_alq != NULL); - error = sysctl_handle_int(oidp, &enable, 0, req); - if (error || !req->newptr) - return (error); - else - return (ieee80211_alq_setlogging(enable)); -} - -SYSCTL_PROC(_net_wlan, OID_AUTO, alq, CTLTYPE_INT|CTLFLAG_RW, - 0, 0, sysctl_ieee80211_alq_log, "I", "Enable net80211 alq logging"); -SYSCTL_INT(_net_wlan, OID_AUTO, alq_size, CTLFLAG_RW, - &ieee80211_alq_qsize, 0, "In-memory log size (#records)"); -SYSCTL_INT(_net_wlan, OID_AUTO, alq_lost, CTLFLAG_RW, - &ieee80211_alq_lost, 0, "Debugging operations not logged"); -SYSCTL_INT(_net_wlan, OID_AUTO, alq_logged, CTLFLAG_RW, - &ieee80211_alq_logged, 0, "Debugging operations logged"); - -static struct ale * -ieee80211_alq_get(void) -{ - struct ale *ale; - - ale = alq_get(ieee80211_alq, ALQ_NOWAIT); - if (!ale) - ieee80211_alq_lost++; - else - ieee80211_alq_logged++; - return ale; -} - -void -ieee80211_alq_log(struct ieee80211vap *vap, uint8_t op, u_char *p, int l) -{ - struct ale *ale; - struct ieee80211_alq_rec *r; - - if (ieee80211_alq == NULL) - return; - - ale = ieee80211_alq_get(); - if (! ale) - return; - - r = (struct ieee80211_alq_rec *) ale->ae_data; - r->r_timestamp = htonl(ticks); - r->r_version = 1; - r->r_wlan = htons(vap->iv_ifp->if_dunit); - r->r_op = op; - memcpy(&r->r_payload, p, MIN(l, sizeof(r->r_payload))); - alq_post(ieee80211_alq, ale); -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_alq.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_alq.h deleted file mode 100644 index 648eba2ba0..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_alq.h +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * Copyright (c) 2011 Adrian Chadd, Xenion Lty Ltd - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef __IEEE80211_ALQ_H__ -#define __IEEE80211_ALQ_H__ - -#define IEEE80211_ALQ_PAYLOAD_SIZE 24 - -/* - * timestamp - * wlan interface - * operation - * sub-operation - * rest of structure - operation specific - */ -struct ieee80211_alq_rec { - uint32_t r_timestamp; /* XXX may wrap! */ - uint16_t r_wlan; /* wlan interface number */ - uint8_t r_version; /* version */ - uint8_t r_op; /* top-level operation id */ - u_char r_payload[IEEE80211_ALQ_PAYLOAD_SIZE]; - /* operation-specific payload */ -}; - -/* General logging function */ -extern void ieee80211_alq_log(struct ieee80211vap *vap, uint8_t op, u_char *p, int l); - -#endif /* __IEEE80211_ALQ_H__ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_amrr.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_amrr.c deleted file mode 100644 index 73dd901a35..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_amrr.c +++ /dev/null @@ -1,317 +0,0 @@ -/* $OpenBSD: ieee80211_amrr.c,v 1.1 2006/06/17 19:07:19 damien Exp $ */ - -/*- - * Copyright (c) 2010 Rui Paulo - * Copyright (c) 2006 - * Damien Bergamini - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/*- - * Naive implementation of the Adaptive Multi Rate Retry algorithm: - * - * "IEEE 802.11 Rate Adaptation: A Practical Approach" - * Mathieu Lacage, Hossein Manshaei, Thierry Turletti - * INRIA Sophia - Projet Planete - * http://www-sop.inria.fr/rapports/sophia/RR-5208.html - */ -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include -#include - -#ifdef INET -#include -#include -#endif - -#include -#include -#include - -#define is_success(amn) \ - ((amn)->amn_retrycnt < (amn)->amn_txcnt / 10) -#define is_failure(amn) \ - ((amn)->amn_retrycnt > (amn)->amn_txcnt / 3) -#define is_enough(amn) \ - ((amn)->amn_txcnt > 10) - -static void amrr_setinterval(const struct ieee80211vap *, int); -static void amrr_init(struct ieee80211vap *); -static void amrr_deinit(struct ieee80211vap *); -static void amrr_node_init(struct ieee80211_node *); -static void amrr_node_deinit(struct ieee80211_node *); -static int amrr_update(struct ieee80211_amrr *, - struct ieee80211_amrr_node *, struct ieee80211_node *); -static int amrr_rate(struct ieee80211_node *, void *, uint32_t); -static void amrr_tx_complete(const struct ieee80211vap *, - const struct ieee80211_node *, int, - void *, void *); -static void amrr_tx_update(const struct ieee80211vap *vap, - const struct ieee80211_node *, void *, void *, void *); -static void amrr_sysctlattach(struct ieee80211vap *, - struct sysctl_ctx_list *, struct sysctl_oid *); - -/* number of references from net80211 layer */ -static int nrefs = 0; - -static const struct ieee80211_ratectl amrr = { - .ir_name = "amrr", - .ir_attach = NULL, - .ir_detach = NULL, - .ir_init = amrr_init, - .ir_deinit = amrr_deinit, - .ir_node_init = amrr_node_init, - .ir_node_deinit = amrr_node_deinit, - .ir_rate = amrr_rate, - .ir_tx_complete = amrr_tx_complete, - .ir_tx_update = amrr_tx_update, - .ir_setinterval = amrr_setinterval, -}; -IEEE80211_RATECTL_MODULE(amrr, 1); -IEEE80211_RATECTL_ALG(amrr, IEEE80211_RATECTL_AMRR, amrr); - -static void -amrr_setinterval(const struct ieee80211vap *vap, int msecs) -{ - struct ieee80211_amrr *amrr = vap->iv_rs; - int t; - - if (msecs < 100) - msecs = 100; - t = msecs_to_ticks(msecs); - amrr->amrr_interval = (t < 1) ? 1 : t; -} - -static void -amrr_init(struct ieee80211vap *vap) -{ - struct ieee80211_amrr *amrr; - - KASSERT(vap->iv_rs == NULL, ("%s called multiple times", __func__)); - - amrr = vap->iv_rs = malloc(sizeof(struct ieee80211_amrr), - M_80211_RATECTL, M_NOWAIT|M_ZERO); - if (amrr == NULL) { - if_printf(vap->iv_ifp, "couldn't alloc ratectl structure\n"); - return; - } - amrr->amrr_min_success_threshold = IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD; - amrr->amrr_max_success_threshold = IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD; - amrr_setinterval(vap, 500 /* ms */); - amrr_sysctlattach(vap, vap->iv_sysctl, vap->iv_oid); -} - -static void -amrr_deinit(struct ieee80211vap *vap) -{ - free(vap->iv_rs, M_80211_RATECTL); -} - -static void -amrr_node_init(struct ieee80211_node *ni) -{ - const struct ieee80211_rateset *rs = &ni->ni_rates; - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_amrr *amrr = vap->iv_rs; - struct ieee80211_amrr_node *amn; - - if (ni->ni_rctls == NULL) { - ni->ni_rctls = amn = malloc(sizeof(struct ieee80211_amrr_node), - M_80211_RATECTL, M_NOWAIT|M_ZERO); - if (amn == NULL) { - if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl " - "structure\n"); - return; - } - } else - amn = ni->ni_rctls; - amn->amn_amrr = amrr; - amn->amn_success = 0; - amn->amn_recovery = 0; - amn->amn_txcnt = amn->amn_retrycnt = 0; - amn->amn_success_threshold = amrr->amrr_min_success_threshold; - - /* pick initial rate */ - for (amn->amn_rix = rs->rs_nrates - 1; - amn->amn_rix > 0 && (rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL) > 72; - amn->amn_rix--) - ; - ni->ni_txrate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL; - amn->amn_ticks = ticks; - - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, - "AMRR initial rate %d", ni->ni_txrate); -} - -static void -amrr_node_deinit(struct ieee80211_node *ni) -{ - free(ni->ni_rctls, M_80211_RATECTL); -} - -static int -amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn, - struct ieee80211_node *ni) -{ - int rix = amn->amn_rix; - - KASSERT(is_enough(amn), ("txcnt %d", amn->amn_txcnt)); - - if (is_success(amn)) { - amn->amn_success++; - if (amn->amn_success >= amn->amn_success_threshold && - rix + 1 < ni->ni_rates.rs_nrates) { - amn->amn_recovery = 1; - amn->amn_success = 0; - rix++; - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, - "AMRR increasing rate %d (txcnt=%d retrycnt=%d)", - ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL, - amn->amn_txcnt, amn->amn_retrycnt); - } else { - amn->amn_recovery = 0; - } - } else if (is_failure(amn)) { - amn->amn_success = 0; - if (rix > 0) { - if (amn->amn_recovery) { - amn->amn_success_threshold *= 2; - if (amn->amn_success_threshold > - amrr->amrr_max_success_threshold) - amn->amn_success_threshold = - amrr->amrr_max_success_threshold; - } else { - amn->amn_success_threshold = - amrr->amrr_min_success_threshold; - } - rix--; - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, - "AMRR decreasing rate %d (txcnt=%d retrycnt=%d)", - ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL, - amn->amn_txcnt, amn->amn_retrycnt); - } - amn->amn_recovery = 0; - } - - /* reset counters */ - amn->amn_txcnt = 0; - amn->amn_retrycnt = 0; - - return rix; -} - -/* - * Return the rate index to use in sending a data frame. - * Update our internal state if it's been long enough. - * If the rate changes we also update ni_txrate to match. - */ -static int -amrr_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg __unused) -{ - struct ieee80211_amrr_node *amn = ni->ni_rctls; - struct ieee80211_amrr *amrr = amn->amn_amrr; - int rix; - - if (is_enough(amn) && (ticks - amn->amn_ticks) > amrr->amrr_interval) { - rix = amrr_update(amrr, amn, ni); - if (rix != amn->amn_rix) { - /* update public rate */ - ni->ni_txrate = - ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL; - amn->amn_rix = rix; - } - amn->amn_ticks = ticks; - } else - rix = amn->amn_rix; - return rix; -} - -/* - * Update statistics with tx complete status. Ok is non-zero - * if the packet is known to be ACK'd. Retries has the number - * retransmissions (i.e. xmit attempts - 1). - */ -static void -amrr_tx_complete(const struct ieee80211vap *vap, - const struct ieee80211_node *ni, int ok, - void *arg1, void *arg2 __unused) -{ - struct ieee80211_amrr_node *amn = ni->ni_rctls; - int retries = *(int *)arg1; - - amn->amn_txcnt++; - if (ok) - amn->amn_success++; - amn->amn_retrycnt += retries; -} - -/* - * Set tx count/retry statistics explicitly. Intended for - * drivers that poll the device for statistics maintained - * in the device. - */ -static void -amrr_tx_update(const struct ieee80211vap *vap, const struct ieee80211_node *ni, - void *arg1, void *arg2, void *arg3) -{ - struct ieee80211_amrr_node *amn = ni->ni_rctls; - int txcnt = *(int *)arg1, success = *(int *)arg2, retrycnt = *(int *)arg3; - - amn->amn_txcnt = txcnt; - amn->amn_success = success; - amn->amn_retrycnt = retrycnt; -} - -static int -amrr_sysctl_interval(SYSCTL_HANDLER_ARGS) -{ - struct ieee80211vap *vap = arg1; - struct ieee80211_amrr *amrr = vap->iv_rs; - int msecs = ticks_to_msecs(amrr->amrr_interval); - int error; - - error = sysctl_handle_int(oidp, &msecs, 0, req); - if (error || !req->newptr) - return error; - amrr_setinterval(vap, msecs); - return 0; -} - -static void -amrr_sysctlattach(struct ieee80211vap *vap, - struct sysctl_ctx_list *ctx, struct sysctl_oid *tree) -{ - struct ieee80211_amrr *amrr = vap->iv_rs; - - SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "amrr_rate_interval", CTLTYPE_INT | CTLFLAG_RW, vap, - 0, amrr_sysctl_interval, "I", "amrr operation interval (ms)"); - /* XXX bounds check values */ - SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "amrr_max_sucess_threshold", CTLFLAG_RW, - &amrr->amrr_max_success_threshold, 0, ""); - SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "amrr_min_sucess_threshold", CTLFLAG_RW, - &amrr->amrr_min_success_threshold, 0, ""); -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_amrr.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_amrr.h deleted file mode 100644 index 61357271cc..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_amrr.h +++ /dev/null @@ -1,61 +0,0 @@ -/* $FreeBSD$ */ -/* $OpenBSD: ieee80211_amrr.h,v 1.3 2006/06/17 19:34:31 damien Exp $ */ - -/*- - * Copyright (c) 2006 - * Damien Bergamini - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_AMRR_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_AMRR_H_ - -/*- - * Naive implementation of the Adaptive Multi Rate Retry algorithm: - * - * "IEEE 802.11 Rate Adaptation: A Practical Approach" - * Mathieu Lacage, Hossein Manshaei, Thierry Turletti - * INRIA Sophia - Projet Planete - * http://www-sop.inria.fr/rapports/sophia/RR-5208.html - */ - -/* - * Rate control settings. - */ -struct ieee80211vap; - -struct ieee80211_amrr { - u_int amrr_min_success_threshold; - u_int amrr_max_success_threshold; - int amrr_interval; /* update interval (ticks) */ -}; - -#define IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD 1 -#define IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD 15 - -/* - * Rate control state for a given node. - */ -struct ieee80211_amrr_node { - struct ieee80211_amrr *amn_amrr;/* backpointer */ - int amn_rix; /* current rate index */ - int amn_ticks; /* time of last update */ - /* statistics */ - u_int amn_txcnt; - u_int amn_success; - u_int amn_success_threshold; - u_int amn_recovery; - u_int amn_retrycnt; -}; - -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_AMRR_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto.c deleted file mode 100644 index 2ed4b886b2..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto.c +++ /dev/null @@ -1,669 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 generic crypto support. - */ -#include "opt_wlan.h" - -#include -#include -#include -#include - -#include - -#include -#include -#include /* XXX ETHER_HDR_LEN */ - -#include - -static int _ieee80211_crypto_delkey(struct ieee80211vap *, - struct ieee80211_key *); - -/* - * Table of registered cipher modules. - */ -static const struct ieee80211_cipher *ciphers[IEEE80211_CIPHER_MAX]; - -/* - * Default "null" key management routines. - */ -static int -null_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, - ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) -{ - if (!(&vap->iv_nw_keys[0] <= k && - k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) { - /* - * Not in the global key table, the driver should handle this - * by allocating a slot in the h/w key table/cache. In - * lieu of that return key slot 0 for any unicast key - * request. We disallow the request if this is a group key. - * This default policy does the right thing for legacy hardware - * with a 4 key table. It also handles devices that pass - * packets through untouched when marked with the WEP bit - * and key index 0. - */ - if (k->wk_flags & IEEE80211_KEY_GROUP) - return 0; - *keyix = 0; /* NB: use key index 0 for ucast key */ - } else { - *keyix = k - vap->iv_nw_keys; - } - *rxkeyix = IEEE80211_KEYIX_NONE; /* XXX maybe *keyix? */ - return 1; -} -static int -null_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) -{ - return 1; -} -static int -null_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, - const uint8_t mac[IEEE80211_ADDR_LEN]) -{ - return 1; -} -static void null_key_update(struct ieee80211vap *vap) {} - -/* - * Write-arounds for common operations. - */ -static __inline void -cipher_detach(struct ieee80211_key *key) -{ - key->wk_cipher->ic_detach(key); -} - -static __inline void * -cipher_attach(struct ieee80211vap *vap, struct ieee80211_key *key) -{ - return key->wk_cipher->ic_attach(vap, key); -} - -/* - * Wrappers for driver key management methods. - */ -static __inline int -dev_key_alloc(struct ieee80211vap *vap, - struct ieee80211_key *key, - ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) -{ - return vap->iv_key_alloc(vap, key, keyix, rxkeyix); -} - -static __inline int -dev_key_delete(struct ieee80211vap *vap, - const struct ieee80211_key *key) -{ - return vap->iv_key_delete(vap, key); -} - -static __inline int -dev_key_set(struct ieee80211vap *vap, const struct ieee80211_key *key) -{ - return vap->iv_key_set(vap, key, key->wk_macaddr); -} - -/* - * Setup crypto support for a device/shared instance. - */ -void -ieee80211_crypto_attach(struct ieee80211com *ic) -{ - /* NB: we assume everything is pre-zero'd */ - ciphers[IEEE80211_CIPHER_NONE] = &ieee80211_cipher_none; -#if defined(__HAIKU__) - ieee80211_crypto_ccmp_load(); - ieee80211_crypto_tkip_load(); - ieee80211_crypto_wep_load(); -#endif -} - -/* - * Teardown crypto support. - */ -void -ieee80211_crypto_detach(struct ieee80211com *ic) -{ -#if defined(__HAIKU__) - ieee80211_crypto_ccmp_unload(); - ieee80211_crypto_tkip_unload(); - ieee80211_crypto_wep_unload(); -#endif -} - -/* - * Setup crypto support for a vap. - */ -void -ieee80211_crypto_vattach(struct ieee80211vap *vap) -{ - int i; - - /* NB: we assume everything is pre-zero'd */ - vap->iv_max_keyix = IEEE80211_WEP_NKID; - vap->iv_def_txkey = IEEE80211_KEYIX_NONE; - for (i = 0; i < IEEE80211_WEP_NKID; i++) - ieee80211_crypto_resetkey(vap, &vap->iv_nw_keys[i], - IEEE80211_KEYIX_NONE); - /* - * Initialize the driver key support routines to noop entries. - * This is useful especially for the cipher test modules. - */ - vap->iv_key_alloc = null_key_alloc; - vap->iv_key_set = null_key_set; - vap->iv_key_delete = null_key_delete; - vap->iv_key_update_begin = null_key_update; - vap->iv_key_update_end = null_key_update; -} - -/* - * Teardown crypto support for a vap. - */ -void -ieee80211_crypto_vdetach(struct ieee80211vap *vap) -{ - ieee80211_crypto_delglobalkeys(vap); -} - -/* - * Register a crypto cipher module. - */ -void -ieee80211_crypto_register(const struct ieee80211_cipher *cip) -{ - if (cip->ic_cipher >= IEEE80211_CIPHER_MAX) { - printf("%s: cipher %s has an invalid cipher index %u\n", - __func__, cip->ic_name, cip->ic_cipher); - return; - } - if (ciphers[cip->ic_cipher] != NULL && ciphers[cip->ic_cipher] != cip) { - printf("%s: cipher %s registered with a different template\n", - __func__, cip->ic_name); - return; - } - ciphers[cip->ic_cipher] = cip; -} - -/* - * Unregister a crypto cipher module. - */ -void -ieee80211_crypto_unregister(const struct ieee80211_cipher *cip) -{ - if (cip->ic_cipher >= IEEE80211_CIPHER_MAX) { - printf("%s: cipher %s has an invalid cipher index %u\n", - __func__, cip->ic_name, cip->ic_cipher); - return; - } - if (ciphers[cip->ic_cipher] != NULL && ciphers[cip->ic_cipher] != cip) { - printf("%s: cipher %s registered with a different template\n", - __func__, cip->ic_name); - return; - } - /* NB: don't complain about not being registered */ - /* XXX disallow if references */ - ciphers[cip->ic_cipher] = NULL; -} - -int -ieee80211_crypto_available(u_int cipher) -{ - return cipher < IEEE80211_CIPHER_MAX && ciphers[cipher] != NULL; -} - -/* XXX well-known names! */ -static const char *cipher_modnames[IEEE80211_CIPHER_MAX] = { - [IEEE80211_CIPHER_WEP] = "wlan_wep", - [IEEE80211_CIPHER_TKIP] = "wlan_tkip", - [IEEE80211_CIPHER_AES_OCB] = "wlan_aes_ocb", - [IEEE80211_CIPHER_AES_CCM] = "wlan_ccmp", - [IEEE80211_CIPHER_TKIPMIC] = "#4", /* NB: reserved */ - [IEEE80211_CIPHER_CKIP] = "wlan_ckip", - [IEEE80211_CIPHER_NONE] = "wlan_none", -}; - -/* NB: there must be no overlap between user-supplied and device-owned flags */ -CTASSERT((IEEE80211_KEY_COMMON & IEEE80211_KEY_DEVICE) == 0); - -/* - * Establish a relationship between the specified key and cipher - * and, if necessary, allocate a hardware index from the driver. - * Note that when a fixed key index is required it must be specified. - * - * This must be the first call applied to a key; all the other key - * routines assume wk_cipher is setup. - * - * Locking must be handled by the caller using: - * ieee80211_key_update_begin(vap); - * ieee80211_key_update_end(vap); - */ -int -ieee80211_crypto_newkey(struct ieee80211vap *vap, - int cipher, int flags, struct ieee80211_key *key) -{ - struct ieee80211com *ic = vap->iv_ic; - const struct ieee80211_cipher *cip; - ieee80211_keyix keyix, rxkeyix; - void *keyctx; - int oflags; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: cipher %u flags 0x%x keyix %u\n", - __func__, cipher, flags, key->wk_keyix); - - /* - * Validate cipher and set reference to cipher routines. - */ - if (cipher >= IEEE80211_CIPHER_MAX) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: invalid cipher %u\n", __func__, cipher); - vap->iv_stats.is_crypto_badcipher++; - return 0; - } - cip = ciphers[cipher]; - if (cip == NULL) { - /* - * Auto-load cipher module if we have a well-known name - * for it. It might be better to use string names rather - * than numbers and craft a module name based on the cipher - * name; e.g. wlan_cipher_. - */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: unregistered cipher %u, load module %s\n", - __func__, cipher, cipher_modnames[cipher]); - ieee80211_load_module(cipher_modnames[cipher]); - /* - * If cipher module loaded it should immediately - * call ieee80211_crypto_register which will fill - * in the entry in the ciphers array. - */ - cip = ciphers[cipher]; - if (cip == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: unable to load cipher %u, module %s\n", - __func__, cipher, cipher_modnames[cipher]); - vap->iv_stats.is_crypto_nocipher++; - return 0; - } - } - - oflags = key->wk_flags; - flags &= IEEE80211_KEY_COMMON; - /* NB: preserve device attributes */ - flags |= (oflags & IEEE80211_KEY_DEVICE); - /* - * If the hardware does not support the cipher then - * fallback to a host-based implementation. - */ - if ((ic->ic_cryptocaps & (1<ic_name); - flags |= IEEE80211_KEY_SWCRYPT; - } - /* - * Hardware TKIP with software MIC is an important - * combination; we handle it by flagging each key, - * the cipher modules honor it. - */ - if (cipher == IEEE80211_CIPHER_TKIP && - (ic->ic_cryptocaps & IEEE80211_CRYPTO_TKIPMIC) == 0) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: no h/w support for TKIP MIC, falling back to s/w\n", - __func__); - flags |= IEEE80211_KEY_SWMIC; - } - - /* - * Bind cipher to key instance. Note we do this - * after checking the device capabilities so the - * cipher module can optimize space usage based on - * whether or not it needs to do the cipher work. - */ - if (key->wk_cipher != cip || key->wk_flags != flags) { - /* - * Fillin the flags so cipher modules can see s/w - * crypto requirements and potentially allocate - * different state and/or attach different method - * pointers. - */ - key->wk_flags = flags; - keyctx = cip->ic_attach(vap, key); - if (keyctx == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: unable to attach cipher %s\n", - __func__, cip->ic_name); - key->wk_flags = oflags; /* restore old flags */ - vap->iv_stats.is_crypto_attachfail++; - return 0; - } - cipher_detach(key); - key->wk_cipher = cip; /* XXX refcnt? */ - key->wk_private = keyctx; - } - - /* - * Ask the driver for a key index if we don't have one. - * Note that entries in the global key table always have - * an index; this means it's safe to call this routine - * for these entries just to setup the reference to the - * cipher template. Note also that when using software - * crypto we also call the driver to give us a key index. - */ - if ((key->wk_flags & IEEE80211_KEY_DEVKEY) == 0) { - if (!dev_key_alloc(vap, key, &keyix, &rxkeyix)) { - /* - * Unable to setup driver state. - */ - vap->iv_stats.is_crypto_keyfail++; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: unable to setup cipher %s\n", - __func__, cip->ic_name); - return 0; - } - if (key->wk_flags != flags) { - /* - * Driver overrode flags we setup; typically because - * resources were unavailable to handle _this_ key. - * Re-attach the cipher context to allow cipher - * modules to handle differing requirements. - */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: driver override for cipher %s, flags " - "0x%x -> 0x%x\n", __func__, cip->ic_name, - oflags, key->wk_flags); - keyctx = cip->ic_attach(vap, key); - if (keyctx == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: unable to attach cipher %s with " - "flags 0x%x\n", __func__, cip->ic_name, - key->wk_flags); - key->wk_flags = oflags; /* restore old flags */ - vap->iv_stats.is_crypto_attachfail++; - return 0; - } - cipher_detach(key); - key->wk_cipher = cip; /* XXX refcnt? */ - key->wk_private = keyctx; - } - key->wk_keyix = keyix; - key->wk_rxkeyix = rxkeyix; - key->wk_flags |= IEEE80211_KEY_DEVKEY; - } - return 1; -} - -/* - * Remove the key (no locking, for internal use). - */ -static int -_ieee80211_crypto_delkey(struct ieee80211vap *vap, struct ieee80211_key *key) -{ - KASSERT(key->wk_cipher != NULL, ("No cipher!")); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: %s keyix %u flags 0x%x rsc %ju tsc %ju len %u\n", - __func__, key->wk_cipher->ic_name, - key->wk_keyix, key->wk_flags, - key->wk_keyrsc[IEEE80211_NONQOS_TID], key->wk_keytsc, - key->wk_keylen); - - if (key->wk_flags & IEEE80211_KEY_DEVKEY) { - /* - * Remove hardware entry. - */ - /* XXX key cache */ - if (!dev_key_delete(vap, key)) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: driver did not delete key index %u\n", - __func__, key->wk_keyix); - vap->iv_stats.is_crypto_delkey++; - /* XXX recovery? */ - } - } - cipher_detach(key); - memset(key, 0, sizeof(*key)); - ieee80211_crypto_resetkey(vap, key, IEEE80211_KEYIX_NONE); - return 1; -} - -/* - * Remove the specified key. - */ -int -ieee80211_crypto_delkey(struct ieee80211vap *vap, struct ieee80211_key *key) -{ - int status; - - ieee80211_key_update_begin(vap); - status = _ieee80211_crypto_delkey(vap, key); - ieee80211_key_update_end(vap); - return status; -} - -/* - * Clear the global key table. - */ -void -ieee80211_crypto_delglobalkeys(struct ieee80211vap *vap) -{ - int i; - - ieee80211_key_update_begin(vap); - for (i = 0; i < IEEE80211_WEP_NKID; i++) - (void) _ieee80211_crypto_delkey(vap, &vap->iv_nw_keys[i]); - ieee80211_key_update_end(vap); -} - -/* - * Set the contents of the specified key. - * - * Locking must be handled by the caller using: - * ieee80211_key_update_begin(vap); - * ieee80211_key_update_end(vap); - */ -int -ieee80211_crypto_setkey(struct ieee80211vap *vap, struct ieee80211_key *key) -{ - const struct ieee80211_cipher *cip = key->wk_cipher; - - KASSERT(cip != NULL, ("No cipher!")); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: %s keyix %u flags 0x%x mac %s rsc %ju tsc %ju len %u\n", - __func__, cip->ic_name, key->wk_keyix, - key->wk_flags, ether_sprintf(key->wk_macaddr), - key->wk_keyrsc[IEEE80211_NONQOS_TID], key->wk_keytsc, - key->wk_keylen); - - if ((key->wk_flags & IEEE80211_KEY_DEVKEY) == 0) { - /* XXX nothing allocated, should not happen */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: no device key setup done; should not happen!\n", - __func__); - vap->iv_stats.is_crypto_setkey_nokey++; - return 0; - } - /* - * Give cipher a chance to validate key contents. - * XXX should happen before modifying state. - */ - if (!cip->ic_setkey(key)) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: cipher %s rejected key index %u len %u flags 0x%x\n", - __func__, cip->ic_name, key->wk_keyix, - key->wk_keylen, key->wk_flags); - vap->iv_stats.is_crypto_setkey_cipher++; - return 0; - } - return dev_key_set(vap, key); -} - -/* - * Add privacy headers appropriate for the specified key. - */ -struct ieee80211_key * -ieee80211_crypto_encap(struct ieee80211_node *ni, struct mbuf *m) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_key *k; - struct ieee80211_frame *wh; - const struct ieee80211_cipher *cip; - uint8_t keyid; - - /* - * Multicast traffic always uses the multicast key. - * Otherwise if a unicast key is set we use that and - * it is always key index 0. When no unicast key is - * set we fall back to the default transmit key. - */ - wh = mtod(m, struct ieee80211_frame *); - if (IEEE80211_IS_MULTICAST(wh->i_addr1) || - IEEE80211_KEY_UNDEFINED(&ni->ni_ucastkey)) { - if (vap->iv_def_txkey == IEEE80211_KEYIX_NONE) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, - wh->i_addr1, - "no default transmit key (%s) deftxkey %u", - __func__, vap->iv_def_txkey); - vap->iv_stats.is_tx_nodefkey++; - return NULL; - } - keyid = vap->iv_def_txkey; - k = &vap->iv_nw_keys[vap->iv_def_txkey]; - } else { - keyid = 0; - k = &ni->ni_ucastkey; - } - cip = k->wk_cipher; - return (cip->ic_encap(k, m, keyid<<6) ? k : NULL); -} - -/* - * Validate and strip privacy headers (and trailer) for a - * received frame that has the WEP/Privacy bit set. - */ -struct ieee80211_key * -ieee80211_crypto_decap(struct ieee80211_node *ni, struct mbuf *m, int hdrlen) -{ -#define IEEE80211_WEP_HDRLEN (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN) -#define IEEE80211_WEP_MINLEN \ - (sizeof(struct ieee80211_frame) + \ - IEEE80211_WEP_HDRLEN + IEEE80211_WEP_CRCLEN) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_key *k; - struct ieee80211_frame *wh; - const struct ieee80211_cipher *cip; - uint8_t keyid; - - /* NB: this minimum size data frame could be bigger */ - if (m->m_pkthdr.len < IEEE80211_WEP_MINLEN) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ANY, - "%s: WEP data frame too short, len %u\n", - __func__, m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; /* XXX need unique stat? */ - return NULL; - } - - /* - * Locate the key. If unicast and there is no unicast - * key then we fall back to the key id in the header. - * This assumes unicast keys are only configured when - * the key id in the header is meaningless (typically 0). - */ - wh = mtod(m, struct ieee80211_frame *); - m_copydata(m, hdrlen + IEEE80211_WEP_IVLEN, sizeof(keyid), &keyid); - if (IEEE80211_IS_MULTICAST(wh->i_addr1) || - IEEE80211_KEY_UNDEFINED(&ni->ni_ucastkey)) - k = &vap->iv_nw_keys[keyid >> 6]; - else - k = &ni->ni_ucastkey; - - /* - * Insure crypto header is contiguous for all decap work. - */ - cip = k->wk_cipher; - if (m->m_len < hdrlen + cip->ic_header && - (m = m_pullup(m, hdrlen + cip->ic_header)) == NULL) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, - "unable to pullup %s header", cip->ic_name); - vap->iv_stats.is_rx_wepfail++; /* XXX */ - return NULL; - } - - return (cip->ic_decap(k, m, hdrlen) ? k : NULL); -#undef IEEE80211_WEP_MINLEN -#undef IEEE80211_WEP_HDRLEN -} - -static void -load_ucastkey(void *arg, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_key *k; - - if (vap->iv_state != IEEE80211_S_RUN) - return; - k = &ni->ni_ucastkey; - if (k->wk_flags & IEEE80211_KEY_DEVKEY) - dev_key_set(vap, k); -} - -/* - * Re-load all keys known to the 802.11 layer that may - * have hardware state backing them. This is used by - * drivers on resume to push keys down into the device. - */ -void -ieee80211_crypto_reload_keys(struct ieee80211com *ic) -{ - struct ieee80211vap *vap; - int i; - - /* - * Keys in the global key table of each vap. - */ - /* NB: used only during resume so don't lock for now */ - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - if (vap->iv_state != IEEE80211_S_RUN) - continue; - for (i = 0; i < IEEE80211_WEP_NKID; i++) { - const struct ieee80211_key *k = &vap->iv_nw_keys[i]; - if (k->wk_flags & IEEE80211_KEY_DEVKEY) - dev_key_set(vap, k); - } - } - /* - * Unicast keys. - */ - ieee80211_iterate_nodes(&ic->ic_sta, load_ucastkey, NULL); -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto.h deleted file mode 100644 index 8294546c68..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto.h +++ /dev/null @@ -1,254 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_CRYPTO_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_CRYPTO_H_ - -/* - * 802.11 protocol crypto-related definitions. - */ -#define IEEE80211_KEYBUF_SIZE 16 -#define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx+rx keys */ - -/* - * Old WEP-style key. Deprecated. - */ -struct ieee80211_wepkey { - u_int wk_len; /* key length in bytes */ - uint8_t wk_key[IEEE80211_KEYBUF_SIZE]; -}; - -struct ieee80211_rsnparms { - uint8_t rsn_mcastcipher; /* mcast/group cipher */ - uint8_t rsn_mcastkeylen; /* mcast key length */ - uint8_t rsn_ucastcipher; /* selected unicast cipher */ - uint8_t rsn_ucastkeylen; /* unicast key length */ - uint8_t rsn_keymgmt; /* selected key mgmt algo */ - uint16_t rsn_caps; /* capabilities */ -}; - -struct ieee80211_cipher; - -/* - * Crypto key state. There is sufficient room for all supported - * ciphers (see below). The underlying ciphers are handled - * separately through loadable cipher modules that register with - * the generic crypto support. A key has a reference to an instance - * of the cipher; any per-key state is hung off wk_private by the - * cipher when it is attached. Ciphers are automatically called - * to detach and cleanup any such state when the key is deleted. - * - * The generic crypto support handles encap/decap of cipher-related - * frame contents for both hardware- and software-based implementations. - * A key requiring software crypto support is automatically flagged and - * the cipher is expected to honor this and do the necessary work. - * Ciphers such as TKIP may also support mixed hardware/software - * encrypt/decrypt and MIC processing. - */ -typedef uint16_t ieee80211_keyix; /* h/w key index */ - -struct ieee80211_key { - uint8_t wk_keylen; /* key length in bytes */ - uint8_t wk_pad; - uint16_t wk_flags; -#define IEEE80211_KEY_XMIT 0x0001 /* key used for xmit */ -#define IEEE80211_KEY_RECV 0x0002 /* key used for recv */ -#define IEEE80211_KEY_GROUP 0x0004 /* key used for WPA group operation */ -#define IEEE80211_KEY_NOREPLAY 0x0008 /* ignore replay failures */ -#define IEEE80211_KEY_SWENCRYPT 0x0010 /* host-based encrypt */ -#define IEEE80211_KEY_SWDECRYPT 0x0020 /* host-based decrypt */ -#define IEEE80211_KEY_SWENMIC 0x0040 /* host-based enmic */ -#define IEEE80211_KEY_SWDEMIC 0x0080 /* host-based demic */ -#define IEEE80211_KEY_DEVKEY 0x0100 /* device key request completed */ -#define IEEE80211_KEY_CIPHER0 0x1000 /* cipher-specific action 0 */ -#define IEEE80211_KEY_CIPHER1 0x2000 /* cipher-specific action 1 */ - ieee80211_keyix wk_keyix; /* h/w key index */ - ieee80211_keyix wk_rxkeyix; /* optional h/w rx key index */ - uint8_t wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE]; -#define wk_txmic wk_key+IEEE80211_KEYBUF_SIZE+0 /* XXX can't () right */ -#define wk_rxmic wk_key+IEEE80211_KEYBUF_SIZE+8 /* XXX can't () right */ - /* key receive sequence counter */ - uint64_t wk_keyrsc[IEEE80211_TID_SIZE]; - uint64_t wk_keytsc; /* key transmit sequence counter */ - const struct ieee80211_cipher *wk_cipher; - void *wk_private; /* private cipher state */ - uint8_t wk_macaddr[IEEE80211_ADDR_LEN]; -}; -#define IEEE80211_KEY_COMMON /* common flags passed in by apps */\ - (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP | \ - IEEE80211_KEY_NOREPLAY) -#define IEEE80211_KEY_DEVICE /* flags owned by device driver */\ - (IEEE80211_KEY_DEVKEY|IEEE80211_KEY_CIPHER0|IEEE80211_KEY_CIPHER1) - -#define IEEE80211_KEY_SWCRYPT \ - (IEEE80211_KEY_SWENCRYPT | IEEE80211_KEY_SWDECRYPT) -#define IEEE80211_KEY_SWMIC (IEEE80211_KEY_SWENMIC | IEEE80211_KEY_SWDEMIC) - -#define IEEE80211_KEY_BITS \ - "\20\1XMIT\2RECV\3GROUP\4SWENCRYPT\5SWDECRYPT\6SWENMIC\7SWDEMIC" \ - "\10DEVKEY\11CIPHER0\12CIPHER1" - -#define IEEE80211_KEYIX_NONE ((ieee80211_keyix) -1) - -/* - * NB: these values are ordered carefully; there are lots of - * of implications in any reordering. Beware that 4 is used - * only to indicate h/w TKIP MIC support in driver capabilities; - * there is no separate cipher support (it's rolled into the - * TKIP cipher support). - */ -#define IEEE80211_CIPHER_WEP 0 -#define IEEE80211_CIPHER_TKIP 1 -#define IEEE80211_CIPHER_AES_OCB 2 -#define IEEE80211_CIPHER_AES_CCM 3 -#define IEEE80211_CIPHER_TKIPMIC 4 /* TKIP MIC capability */ -#define IEEE80211_CIPHER_CKIP 5 -#define IEEE80211_CIPHER_NONE 6 /* pseudo value */ - -#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1) - -/* capability bits in ic_cryptocaps/iv_cryptocaps */ -#define IEEE80211_CRYPTO_WEP (1<wk_cipher == &ieee80211_cipher_none) - -void ieee80211_crypto_register(const struct ieee80211_cipher *); -void ieee80211_crypto_unregister(const struct ieee80211_cipher *); -int ieee80211_crypto_available(u_int cipher); - -struct ieee80211_key *ieee80211_crypto_encap(struct ieee80211_node *, - struct mbuf *); -struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211_node *, - struct mbuf *, int); - -/* - * Check and remove any MIC. - */ -static __inline int -ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k, - struct mbuf *m, int force) -{ - const struct ieee80211_cipher *cip = k->wk_cipher; - return (cip->ic_miclen > 0 ? cip->ic_demic(k, m, force) : 1); -} - -/* - * Add any MIC. - */ -static __inline int -ieee80211_crypto_enmic(struct ieee80211vap *vap, - struct ieee80211_key *k, struct mbuf *m, int force) -{ - const struct ieee80211_cipher *cip = k->wk_cipher; - return (cip->ic_miclen > 0 ? cip->ic_enmic(k, m, force) : 1); -} - -/* - * Reset key state to an unused state. The crypto - * key allocation mechanism insures other state (e.g. - * key data) is properly setup before a key is used. - */ -static __inline void -ieee80211_crypto_resetkey(struct ieee80211vap *vap, - struct ieee80211_key *k, ieee80211_keyix ix) -{ - k->wk_cipher = &ieee80211_cipher_none; - k->wk_private = k->wk_cipher->ic_attach(vap, k); - k->wk_keyix = k->wk_rxkeyix = ix; - k->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV; -} - -/* - * Crypt-related notification methods. - */ -void ieee80211_notify_replay_failure(struct ieee80211vap *, - const struct ieee80211_frame *, const struct ieee80211_key *, - uint64_t rsc, int tid); -void ieee80211_notify_michael_failure(struct ieee80211vap *, - const struct ieee80211_frame *, u_int keyix); -#endif /* defined(__KERNEL__) || defined(_KERNEL) */ -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_CRYPTO_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_ccmp.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_ccmp.c deleted file mode 100644 index cb9ed0af01..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_ccmp.c +++ /dev/null @@ -1,635 +0,0 @@ -/*- - * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11i AES-CCMP crypto support. - * - * Part of this module is derived from similar code in the Host - * AP driver. The code is used with the consent of the author and - * it's license is included below. - */ -#include "opt_wlan.h" - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include - -#include - -#define AES_BLOCK_LEN 16 - -struct ccmp_ctx { - struct ieee80211vap *cc_vap; /* for diagnostics+statistics */ - struct ieee80211com *cc_ic; - rijndael_ctx cc_aes; -}; - -static void *ccmp_attach(struct ieee80211vap *, struct ieee80211_key *); -static void ccmp_detach(struct ieee80211_key *); -static int ccmp_setkey(struct ieee80211_key *); -static int ccmp_encap(struct ieee80211_key *k, struct mbuf *, uint8_t keyid); -static int ccmp_decap(struct ieee80211_key *, struct mbuf *, int); -static int ccmp_enmic(struct ieee80211_key *, struct mbuf *, int); -static int ccmp_demic(struct ieee80211_key *, struct mbuf *, int); - -static const struct ieee80211_cipher ccmp = { - .ic_name = "AES-CCM", - .ic_cipher = IEEE80211_CIPHER_AES_CCM, - .ic_header = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + - IEEE80211_WEP_EXTIVLEN, - .ic_trailer = IEEE80211_WEP_MICLEN, - .ic_miclen = 0, - .ic_attach = ccmp_attach, - .ic_detach = ccmp_detach, - .ic_setkey = ccmp_setkey, - .ic_encap = ccmp_encap, - .ic_decap = ccmp_decap, - .ic_enmic = ccmp_enmic, - .ic_demic = ccmp_demic, -}; - -static int ccmp_encrypt(struct ieee80211_key *, struct mbuf *, int hdrlen); -static int ccmp_decrypt(struct ieee80211_key *, u_int64_t pn, - struct mbuf *, int hdrlen); - -/* number of references from net80211 layer */ -static int nrefs = 0; - -static void * -ccmp_attach(struct ieee80211vap *vap, struct ieee80211_key *k) -{ - struct ccmp_ctx *ctx; - - ctx = (struct ccmp_ctx *) malloc(sizeof(struct ccmp_ctx), - M_80211_CRYPTO, M_NOWAIT | M_ZERO); - if (ctx == NULL) { - vap->iv_stats.is_crypto_nomem++; - return NULL; - } - ctx->cc_vap = vap; - ctx->cc_ic = vap->iv_ic; - nrefs++; /* NB: we assume caller locking */ - return ctx; -} - -static void -ccmp_detach(struct ieee80211_key *k) -{ - struct ccmp_ctx *ctx = k->wk_private; - - free(ctx, M_80211_CRYPTO); - KASSERT(nrefs > 0, ("imbalanced attach/detach")); - nrefs--; /* NB: we assume caller locking */ -} - -static int -ccmp_setkey(struct ieee80211_key *k) -{ - struct ccmp_ctx *ctx = k->wk_private; - - if (k->wk_keylen != (128/NBBY)) { - IEEE80211_DPRINTF(ctx->cc_vap, IEEE80211_MSG_CRYPTO, - "%s: Invalid key length %u, expecting %u\n", - __func__, k->wk_keylen, 128/NBBY); - return 0; - } - if (k->wk_flags & IEEE80211_KEY_SWENCRYPT) - rijndael_set_key(&ctx->cc_aes, k->wk_key, k->wk_keylen*NBBY); - return 1; -} - -/* - * Add privacy headers appropriate for the specified key. - */ -static int -ccmp_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid) -{ - struct ccmp_ctx *ctx = k->wk_private; - struct ieee80211com *ic = ctx->cc_ic; - uint8_t *ivp; - int hdrlen; - - hdrlen = ieee80211_hdrspace(ic, mtod(m, void *)); - - /* - * Copy down 802.11 header and add the IV, KeyID, and ExtIV. - */ - M_PREPEND(m, ccmp.ic_header, M_NOWAIT); - if (m == NULL) - return 0; - ivp = mtod(m, uint8_t *); - ovbcopy(ivp + ccmp.ic_header, ivp, hdrlen); - ivp += hdrlen; - - k->wk_keytsc++; /* XXX wrap at 48 bits */ - ivp[0] = k->wk_keytsc >> 0; /* PN0 */ - ivp[1] = k->wk_keytsc >> 8; /* PN1 */ - ivp[2] = 0; /* Reserved */ - ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */ - ivp[4] = k->wk_keytsc >> 16; /* PN2 */ - ivp[5] = k->wk_keytsc >> 24; /* PN3 */ - ivp[6] = k->wk_keytsc >> 32; /* PN4 */ - ivp[7] = k->wk_keytsc >> 40; /* PN5 */ - - /* - * Finally, do software encrypt if neeed. - */ - if ((k->wk_flags & IEEE80211_KEY_SWENCRYPT) && - !ccmp_encrypt(k, m, hdrlen)) - return 0; - - return 1; -} - -/* - * Add MIC to the frame as needed. - */ -static int -ccmp_enmic(struct ieee80211_key *k, struct mbuf *m, int force) -{ - - return 1; -} - -static __inline uint64_t -READ_6(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5) -{ - uint32_t iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24); - uint16_t iv16 = (b4 << 0) | (b5 << 8); - return (((uint64_t)iv16) << 32) | iv32; -} - -/* - * Validate and strip privacy headers (and trailer) for a - * received frame. The specified key should be correct but - * is also verified. - */ -static int -ccmp_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen) -{ - struct ccmp_ctx *ctx = k->wk_private; - struct ieee80211vap *vap = ctx->cc_vap; - struct ieee80211_frame *wh; - uint8_t *ivp, tid; - uint64_t pn; - - /* - * Header should have extended IV and sequence number; - * verify the former and validate the latter. - */ - wh = mtod(m, struct ieee80211_frame *); - ivp = mtod(m, uint8_t *) + hdrlen; - if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) { - /* - * No extended IV; discard frame. - */ - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, - "%s", "missing ExtIV for AES-CCM cipher"); - vap->iv_stats.is_rx_ccmpformat++; - return 0; - } - tid = ieee80211_gettid(wh); - pn = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]); - if (pn <= k->wk_keyrsc[tid] && - (k->wk_flags & IEEE80211_KEY_NOREPLAY) == 0) { - /* - * Replay violation. - */ - ieee80211_notify_replay_failure(vap, wh, k, pn, tid); - vap->iv_stats.is_rx_ccmpreplay++; - return 0; - } - - /* - * Check if the device handled the decrypt in hardware. - * If so we just strip the header; otherwise we need to - * handle the decrypt in software. Note that for the - * latter we leave the header in place for use in the - * decryption work. - */ - if ((k->wk_flags & IEEE80211_KEY_SWDECRYPT) && - !ccmp_decrypt(k, pn, m, hdrlen)) - return 0; - - /* - * Copy up 802.11 header and strip crypto bits. - */ - ovbcopy(mtod(m, void *), mtod(m, uint8_t *) + ccmp.ic_header, hdrlen); - m_adj(m, ccmp.ic_header); - m_adj(m, -ccmp.ic_trailer); - - /* - * Ok to update rsc now. - */ - k->wk_keyrsc[tid] = pn; - - return 1; -} - -/* - * Verify and strip MIC from the frame. - */ -static int -ccmp_demic(struct ieee80211_key *k, struct mbuf *m, int force) -{ - return 1; -} - -static __inline void -xor_block(uint8_t *b, const uint8_t *a, size_t len) -{ - int i; - for (i = 0; i < len; i++) - b[i] ^= a[i]; -} - -/* - * Host AP crypt: host-based CCMP encryption implementation for Host AP driver - * - * Copyright (c) 2003-2004, Jouni Malinen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - */ - -static void -ccmp_init_blocks(rijndael_ctx *ctx, struct ieee80211_frame *wh, - u_int64_t pn, size_t dlen, - uint8_t b0[AES_BLOCK_LEN], uint8_t aad[2 * AES_BLOCK_LEN], - uint8_t auth[AES_BLOCK_LEN], uint8_t s0[AES_BLOCK_LEN]) -{ -#define IS_QOS_DATA(wh) IEEE80211_QOS_HAS_SEQ(wh) - - /* CCM Initial Block: - * Flag (Include authentication header, M=3 (8-octet MIC), - * L=1 (2-octet Dlen)) - * Nonce: 0x00 | A2 | PN - * Dlen */ - b0[0] = 0x59; - /* NB: b0[1] set below */ - IEEE80211_ADDR_COPY(b0 + 2, wh->i_addr2); - b0[8] = pn >> 40; - b0[9] = pn >> 32; - b0[10] = pn >> 24; - b0[11] = pn >> 16; - b0[12] = pn >> 8; - b0[13] = pn >> 0; - b0[14] = (dlen >> 8) & 0xff; - b0[15] = dlen & 0xff; - - /* AAD: - * FC with bits 4..6 and 11..13 masked to zero; 14 is always one - * A1 | A2 | A3 - * SC with bits 4..15 (seq#) masked to zero - * A4 (if present) - * QC (if present) - */ - aad[0] = 0; /* AAD length >> 8 */ - /* NB: aad[1] set below */ - aad[2] = wh->i_fc[0] & 0x8f; /* XXX magic #s */ - aad[3] = wh->i_fc[1] & 0xc7; /* XXX magic #s */ - /* NB: we know 3 addresses are contiguous */ - memcpy(aad + 4, wh->i_addr1, 3 * IEEE80211_ADDR_LEN); - aad[22] = wh->i_seq[0] & IEEE80211_SEQ_FRAG_MASK; - aad[23] = 0; /* all bits masked */ - /* - * Construct variable-length portion of AAD based - * on whether this is a 4-address frame/QOS frame. - * We always zero-pad to 32 bytes before running it - * through the cipher. - * - * We also fill in the priority bits of the CCM - * initial block as we know whether or not we have - * a QOS frame. - */ - if (IEEE80211_IS_DSTODS(wh)) { - IEEE80211_ADDR_COPY(aad + 24, - ((struct ieee80211_frame_addr4 *)wh)->i_addr4); - if (IS_QOS_DATA(wh)) { - struct ieee80211_qosframe_addr4 *qwh4 = - (struct ieee80211_qosframe_addr4 *) wh; - aad[30] = qwh4->i_qos[0] & 0x0f;/* just priority bits */ - aad[31] = 0; - b0[1] = aad[30]; - aad[1] = 22 + IEEE80211_ADDR_LEN + 2; - } else { - *(uint16_t *)&aad[30] = 0; - b0[1] = 0; - aad[1] = 22 + IEEE80211_ADDR_LEN; - } - } else { - if (IS_QOS_DATA(wh)) { - struct ieee80211_qosframe *qwh = - (struct ieee80211_qosframe*) wh; - aad[24] = qwh->i_qos[0] & 0x0f; /* just priority bits */ - aad[25] = 0; - b0[1] = aad[24]; - aad[1] = 22 + 2; - } else { - *(uint16_t *)&aad[24] = 0; - b0[1] = 0; - aad[1] = 22; - } - *(uint16_t *)&aad[26] = 0; - *(uint32_t *)&aad[28] = 0; - } - - /* Start with the first block and AAD */ - rijndael_encrypt(ctx, b0, auth); - xor_block(auth, aad, AES_BLOCK_LEN); - rijndael_encrypt(ctx, auth, auth); - xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); - rijndael_encrypt(ctx, auth, auth); - b0[0] &= 0x07; - b0[14] = b0[15] = 0; - rijndael_encrypt(ctx, b0, s0); -#undef IS_QOS_DATA -} - -#define CCMP_ENCRYPT(_i, _b, _b0, _pos, _e, _len) do { \ - /* Authentication */ \ - xor_block(_b, _pos, _len); \ - rijndael_encrypt(&ctx->cc_aes, _b, _b); \ - /* Encryption, with counter */ \ - _b0[14] = (_i >> 8) & 0xff; \ - _b0[15] = _i & 0xff; \ - rijndael_encrypt(&ctx->cc_aes, _b0, _e); \ - xor_block(_pos, _e, _len); \ -} while (0) - -static int -ccmp_encrypt(struct ieee80211_key *key, struct mbuf *m0, int hdrlen) -{ - struct ccmp_ctx *ctx = key->wk_private; - struct ieee80211_frame *wh; - struct mbuf *m = m0; - int data_len, i, space; - uint8_t aad[2 * AES_BLOCK_LEN], b0[AES_BLOCK_LEN], b[AES_BLOCK_LEN], - e[AES_BLOCK_LEN], s0[AES_BLOCK_LEN]; - uint8_t *pos; - - ctx->cc_vap->iv_stats.is_crypto_ccmp++; - - wh = mtod(m, struct ieee80211_frame *); - data_len = m->m_pkthdr.len - (hdrlen + ccmp.ic_header); - ccmp_init_blocks(&ctx->cc_aes, wh, key->wk_keytsc, - data_len, b0, aad, b, s0); - - i = 1; - pos = mtod(m, uint8_t *) + hdrlen + ccmp.ic_header; - /* NB: assumes header is entirely in first mbuf */ - space = m->m_len - (hdrlen + ccmp.ic_header); - for (;;) { - if (space > data_len) - space = data_len; - /* - * Do full blocks. - */ - while (space >= AES_BLOCK_LEN) { - CCMP_ENCRYPT(i, b, b0, pos, e, AES_BLOCK_LEN); - pos += AES_BLOCK_LEN, space -= AES_BLOCK_LEN; - data_len -= AES_BLOCK_LEN; - i++; - } - if (data_len <= 0) /* no more data */ - break; - m = m->m_next; - if (m == NULL) { /* last buffer */ - if (space != 0) { - /* - * Short last block. - */ - CCMP_ENCRYPT(i, b, b0, pos, e, space); - } - break; - } - if (space != 0) { - uint8_t *pos_next; - int space_next; - int len, dl, sp; - struct mbuf *n; - - /* - * Block straddles one or more mbufs, gather data - * into the block buffer b, apply the cipher, then - * scatter the results back into the mbuf chain. - * The buffer will automatically get space bytes - * of data at offset 0 copied in+out by the - * CCMP_ENCRYPT request so we must take care of - * the remaining data. - */ - n = m; - dl = data_len; - sp = space; - for (;;) { - pos_next = mtod(n, uint8_t *); - len = min(dl, AES_BLOCK_LEN); - space_next = len > sp ? len - sp : 0; - if (n->m_len >= space_next) { - /* - * This mbuf has enough data; just grab - * what we need and stop. - */ - xor_block(b+sp, pos_next, space_next); - break; - } - /* - * This mbuf's contents are insufficient, - * take 'em all and prepare to advance to - * the next mbuf. - */ - xor_block(b+sp, pos_next, n->m_len); - sp += n->m_len, dl -= n->m_len; - n = n->m_next; - if (n == NULL) - break; - } - - CCMP_ENCRYPT(i, b, b0, pos, e, space); - - /* NB: just like above, but scatter data to mbufs */ - dl = data_len; - sp = space; - for (;;) { - pos_next = mtod(m, uint8_t *); - len = min(dl, AES_BLOCK_LEN); - space_next = len > sp ? len - sp : 0; - if (m->m_len >= space_next) { - xor_block(pos_next, e+sp, space_next); - break; - } - xor_block(pos_next, e+sp, m->m_len); - sp += m->m_len, dl -= m->m_len; - m = m->m_next; - if (m == NULL) - goto done; - } - /* - * Do bookkeeping. m now points to the last mbuf - * we grabbed data from. We know we consumed a - * full block of data as otherwise we'd have hit - * the end of the mbuf chain, so deduct from data_len. - * Otherwise advance the block number (i) and setup - * pos+space to reflect contents of the new mbuf. - */ - data_len -= AES_BLOCK_LEN; - i++; - pos = pos_next + space_next; - space = m->m_len - space_next; - } else { - /* - * Setup for next buffer. - */ - pos = mtod(m, uint8_t *); - space = m->m_len; - } - } -done: - /* tack on MIC */ - xor_block(b, s0, ccmp.ic_trailer); - return m_append(m0, ccmp.ic_trailer, b); -} -#undef CCMP_ENCRYPT - -#define CCMP_DECRYPT(_i, _b, _b0, _pos, _a, _len) do { \ - /* Decrypt, with counter */ \ - _b0[14] = (_i >> 8) & 0xff; \ - _b0[15] = _i & 0xff; \ - rijndael_encrypt(&ctx->cc_aes, _b0, _b); \ - xor_block(_pos, _b, _len); \ - /* Authentication */ \ - xor_block(_a, _pos, _len); \ - rijndael_encrypt(&ctx->cc_aes, _a, _a); \ -} while (0) - -static int -ccmp_decrypt(struct ieee80211_key *key, u_int64_t pn, struct mbuf *m, int hdrlen) -{ - struct ccmp_ctx *ctx = key->wk_private; - struct ieee80211vap *vap = ctx->cc_vap; - struct ieee80211_frame *wh; - uint8_t aad[2 * AES_BLOCK_LEN]; - uint8_t b0[AES_BLOCK_LEN], b[AES_BLOCK_LEN], a[AES_BLOCK_LEN]; - uint8_t mic[AES_BLOCK_LEN]; - size_t data_len; - int i; - uint8_t *pos; - u_int space; - - ctx->cc_vap->iv_stats.is_crypto_ccmp++; - - wh = mtod(m, struct ieee80211_frame *); - data_len = m->m_pkthdr.len - (hdrlen + ccmp.ic_header + ccmp.ic_trailer); - ccmp_init_blocks(&ctx->cc_aes, wh, pn, data_len, b0, aad, a, b); - m_copydata(m, m->m_pkthdr.len - ccmp.ic_trailer, ccmp.ic_trailer, mic); - xor_block(mic, b, ccmp.ic_trailer); - - i = 1; - pos = mtod(m, uint8_t *) + hdrlen + ccmp.ic_header; - space = m->m_len - (hdrlen + ccmp.ic_header); - for (;;) { - if (space > data_len) - space = data_len; - while (space >= AES_BLOCK_LEN) { - CCMP_DECRYPT(i, b, b0, pos, a, AES_BLOCK_LEN); - pos += AES_BLOCK_LEN, space -= AES_BLOCK_LEN; - data_len -= AES_BLOCK_LEN; - i++; - } - if (data_len <= 0) /* no more data */ - break; - m = m->m_next; - if (m == NULL) { /* last buffer */ - if (space != 0) /* short last block */ - CCMP_DECRYPT(i, b, b0, pos, a, space); - break; - } - if (space != 0) { - uint8_t *pos_next; - u_int space_next; - u_int len; - - /* - * Block straddles buffers, split references. We - * do not handle splits that require >2 buffers - * since rx'd frames are never badly fragmented - * because drivers typically recv in clusters. - */ - pos_next = mtod(m, uint8_t *); - len = min(data_len, AES_BLOCK_LEN); - space_next = len > space ? len - space : 0; - KASSERT(m->m_len >= space_next, - ("not enough data in following buffer, " - "m_len %u need %u\n", m->m_len, space_next)); - - xor_block(b+space, pos_next, space_next); - CCMP_DECRYPT(i, b, b0, pos, a, space); - xor_block(pos_next, b+space, space_next); - data_len -= len; - i++; - - pos = pos_next + space_next; - space = m->m_len - space_next; - } else { - /* - * Setup for next buffer. - */ - pos = mtod(m, uint8_t *); - space = m->m_len; - } - } - if (memcmp(mic, a, ccmp.ic_trailer) != 0) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, - "%s", "AES-CCM decrypt failed; MIC mismatch"); - vap->iv_stats.is_rx_ccmpmic++; - return 0; - } - return 1; -} -#undef CCMP_DECRYPT - -/* - * Module glue. - */ -IEEE80211_CRYPTO_MODULE(ccmp, 1); diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_none.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_none.c deleted file mode 100644 index b1ffbb48aa..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_none.c +++ /dev/null @@ -1,144 +0,0 @@ -/*- - * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 NULL crypto support. - */ -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include - -static void *none_attach(struct ieee80211vap *, struct ieee80211_key *); -static void none_detach(struct ieee80211_key *); -static int none_setkey(struct ieee80211_key *); -static int none_encap(struct ieee80211_key *, struct mbuf *, uint8_t); -static int none_decap(struct ieee80211_key *, struct mbuf *, int); -static int none_enmic(struct ieee80211_key *, struct mbuf *, int); -static int none_demic(struct ieee80211_key *, struct mbuf *, int); - -const struct ieee80211_cipher ieee80211_cipher_none = { - .ic_name = "NONE", - .ic_cipher = IEEE80211_CIPHER_NONE, - .ic_header = 0, - .ic_trailer = 0, - .ic_miclen = 0, - .ic_attach = none_attach, - .ic_detach = none_detach, - .ic_setkey = none_setkey, - .ic_encap = none_encap, - .ic_decap = none_decap, - .ic_enmic = none_enmic, - .ic_demic = none_demic, -}; - -static void * -none_attach(struct ieee80211vap *vap, struct ieee80211_key *k) -{ - return vap; /* for diagnostics+stats */ -} - -static void -none_detach(struct ieee80211_key *k) -{ - (void) k; -} - -static int -none_setkey(struct ieee80211_key *k) -{ - (void) k; - return 1; -} - -static int -none_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid) -{ - struct ieee80211vap *vap = k->wk_private; -#ifdef IEEE80211_DEBUG - struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); -#endif - - /* - * The specified key is not setup; this can - * happen, at least, when changing keys. - */ - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr1, - "key id %u is not set (encap)", keyid>>6); - vap->iv_stats.is_tx_badcipher++; - return 0; -} - -static int -none_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen) -{ - struct ieee80211vap *vap = k->wk_private; -#ifdef IEEE80211_DEBUG - struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); - const uint8_t *ivp = (const uint8_t *)&wh[1]; -#endif - - /* - * The specified key is not setup; this can - * happen, at least, when changing keys. - */ - /* XXX useful to know dst too */ - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, - "key id %u is not set (decap)", ivp[IEEE80211_WEP_IVLEN] >> 6); - vap->iv_stats.is_rx_badkeyid++; - return 0; -} - -static int -none_enmic(struct ieee80211_key *k, struct mbuf *m, int force) -{ - struct ieee80211vap *vap = k->wk_private; - - vap->iv_stats.is_tx_badcipher++; - return 0; -} - -static int -none_demic(struct ieee80211_key *k, struct mbuf *m, int force) -{ - struct ieee80211vap *vap = k->wk_private; - - vap->iv_stats.is_rx_badkeyid++; - return 0; -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_tkip.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_tkip.c deleted file mode 100644 index 05d9c74bdf..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_tkip.c +++ /dev/null @@ -1,999 +0,0 @@ -/*- - * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11i TKIP crypto support. - * - * Part of this module is derived from similar code in the Host - * AP driver. The code is used with the consent of the author and - * it's license is included below. - */ -#include "opt_wlan.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include - -static void *tkip_attach(struct ieee80211vap *, struct ieee80211_key *); -static void tkip_detach(struct ieee80211_key *); -static int tkip_setkey(struct ieee80211_key *); -static int tkip_encap(struct ieee80211_key *, struct mbuf *m, uint8_t keyid); -static int tkip_enmic(struct ieee80211_key *, struct mbuf *, int); -static int tkip_decap(struct ieee80211_key *, struct mbuf *, int); -static int tkip_demic(struct ieee80211_key *, struct mbuf *, int); - -static const struct ieee80211_cipher tkip = { - .ic_name = "TKIP", - .ic_cipher = IEEE80211_CIPHER_TKIP, - .ic_header = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + - IEEE80211_WEP_EXTIVLEN, - .ic_trailer = IEEE80211_WEP_CRCLEN, - .ic_miclen = IEEE80211_WEP_MICLEN, - .ic_attach = tkip_attach, - .ic_detach = tkip_detach, - .ic_setkey = tkip_setkey, - .ic_encap = tkip_encap, - .ic_decap = tkip_decap, - .ic_enmic = tkip_enmic, - .ic_demic = tkip_demic, -}; - -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t __u32; -typedef uint32_t u32; - -struct tkip_ctx { - struct ieee80211vap *tc_vap; /* for diagnostics+statistics */ - - u16 tx_ttak[5]; - int tx_phase1_done; - u8 tx_rc4key[16]; /* XXX for test module; make locals? */ - - u16 rx_ttak[5]; - int rx_phase1_done; - u8 rx_rc4key[16]; /* XXX for test module; make locals? */ - uint64_t rx_rsc; /* held until MIC verified */ -}; - -static void michael_mic(struct tkip_ctx *, const u8 *key, - struct mbuf *m, u_int off, size_t data_len, - u8 mic[IEEE80211_WEP_MICLEN]); -static int tkip_encrypt(struct tkip_ctx *, struct ieee80211_key *, - struct mbuf *, int hdr_len); -static int tkip_decrypt(struct tkip_ctx *, struct ieee80211_key *, - struct mbuf *, int hdr_len); - -/* number of references from net80211 layer */ -static int nrefs = 0; - -static void * -tkip_attach(struct ieee80211vap *vap, struct ieee80211_key *k) -{ - struct tkip_ctx *ctx; - - ctx = (struct tkip_ctx *) malloc(sizeof(struct tkip_ctx), - M_80211_CRYPTO, M_NOWAIT | M_ZERO); - if (ctx == NULL) { - vap->iv_stats.is_crypto_nomem++; - return NULL; - } - - ctx->tc_vap = vap; - nrefs++; /* NB: we assume caller locking */ - return ctx; -} - -static void -tkip_detach(struct ieee80211_key *k) -{ - struct tkip_ctx *ctx = k->wk_private; - - free(ctx, M_80211_CRYPTO); - KASSERT(nrefs > 0, ("imbalanced attach/detach")); - nrefs--; /* NB: we assume caller locking */ -} - -static int -tkip_setkey(struct ieee80211_key *k) -{ - struct tkip_ctx *ctx = k->wk_private; - - if (k->wk_keylen != (128/NBBY)) { - (void) ctx; /* XXX */ - IEEE80211_DPRINTF(ctx->tc_vap, IEEE80211_MSG_CRYPTO, - "%s: Invalid key length %u, expecting %u\n", - __func__, k->wk_keylen, 128/NBBY); - return 0; - } - k->wk_keytsc = 1; /* TSC starts at 1 */ - ctx->rx_phase1_done = 0; - return 1; -} - -/* - * Add privacy headers and do any s/w encryption required. - */ -static int -tkip_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid) -{ - struct tkip_ctx *ctx = k->wk_private; - struct ieee80211vap *vap = ctx->tc_vap; - struct ieee80211com *ic = vap->iv_ic; - uint8_t *ivp; - int hdrlen; - - /* - * Handle TKIP counter measures requirement. - */ - if (vap->iv_flags & IEEE80211_F_COUNTERM) { -#ifdef IEEE80211_DEBUG - struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); -#endif - - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, - "discard frame due to countermeasures (%s)", __func__); - vap->iv_stats.is_crypto_tkipcm++; - return 0; - } - hdrlen = ieee80211_hdrspace(ic, mtod(m, void *)); - - /* - * Copy down 802.11 header and add the IV, KeyID, and ExtIV. - */ - M_PREPEND(m, tkip.ic_header, M_NOWAIT); - if (m == NULL) - return 0; - ivp = mtod(m, uint8_t *); - memmove(ivp, ivp + tkip.ic_header, hdrlen); - ivp += hdrlen; - - ivp[0] = k->wk_keytsc >> 8; /* TSC1 */ - ivp[1] = (ivp[0] | 0x20) & 0x7f; /* WEP seed */ - ivp[2] = k->wk_keytsc >> 0; /* TSC0 */ - ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */ - ivp[4] = k->wk_keytsc >> 16; /* TSC2 */ - ivp[5] = k->wk_keytsc >> 24; /* TSC3 */ - ivp[6] = k->wk_keytsc >> 32; /* TSC4 */ - ivp[7] = k->wk_keytsc >> 40; /* TSC5 */ - - /* - * Finally, do software encrypt if neeed. - */ - if (k->wk_flags & IEEE80211_KEY_SWENCRYPT) { - if (!tkip_encrypt(ctx, k, m, hdrlen)) - return 0; - /* NB: tkip_encrypt handles wk_keytsc */ - } else - k->wk_keytsc++; - - return 1; -} - -/* - * Add MIC to the frame as needed. - */ -static int -tkip_enmic(struct ieee80211_key *k, struct mbuf *m, int force) -{ - struct tkip_ctx *ctx = k->wk_private; - - if (force || (k->wk_flags & IEEE80211_KEY_SWENMIC)) { - struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); - struct ieee80211vap *vap = ctx->tc_vap; - struct ieee80211com *ic = vap->iv_ic; - int hdrlen; - uint8_t mic[IEEE80211_WEP_MICLEN]; - - vap->iv_stats.is_crypto_tkipenmic++; - - hdrlen = ieee80211_hdrspace(ic, wh); - - michael_mic(ctx, k->wk_txmic, - m, hdrlen, m->m_pkthdr.len - hdrlen, mic); - return m_append(m, tkip.ic_miclen, mic); - } - return 1; -} - -static __inline uint64_t -READ_6(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5) -{ - uint32_t iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24); - uint16_t iv16 = (b4 << 0) | (b5 << 8); - return (((uint64_t)iv16) << 32) | iv32; -} - -/* - * Validate and strip privacy headers (and trailer) for a - * received frame. If necessary, decrypt the frame using - * the specified key. - */ -static int -tkip_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen) -{ - struct tkip_ctx *ctx = k->wk_private; - struct ieee80211vap *vap = ctx->tc_vap; - struct ieee80211_frame *wh; - uint8_t *ivp, tid; - - /* - * Header should have extended IV and sequence number; - * verify the former and validate the latter. - */ - wh = mtod(m, struct ieee80211_frame *); - ivp = mtod(m, uint8_t *) + hdrlen; - if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) { - /* - * No extended IV; discard frame. - */ - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, - "%s", "missing ExtIV for TKIP cipher"); - vap->iv_stats.is_rx_tkipformat++; - return 0; - } - /* - * Handle TKIP counter measures requirement. - */ - if (vap->iv_flags & IEEE80211_F_COUNTERM) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, - "discard frame due to countermeasures (%s)", __func__); - vap->iv_stats.is_crypto_tkipcm++; - return 0; - } - - tid = ieee80211_gettid(wh); - ctx->rx_rsc = READ_6(ivp[2], ivp[0], ivp[4], ivp[5], ivp[6], ivp[7]); - if (ctx->rx_rsc <= k->wk_keyrsc[tid] && - (k->wk_flags & IEEE80211_KEY_NOREPLAY) == 0) { - /* - * Replay violation; notify upper layer. - */ - ieee80211_notify_replay_failure(vap, wh, k, ctx->rx_rsc, tid); - vap->iv_stats.is_rx_tkipreplay++; - return 0; - } - /* - * NB: We can't update the rsc in the key until MIC is verified. - * - * We assume we are not preempted between doing the check above - * and updating wk_keyrsc when stripping the MIC in tkip_demic. - * Otherwise we might process another packet and discard it as - * a replay. - */ - - /* - * Check if the device handled the decrypt in hardware. - * If so we just strip the header; otherwise we need to - * handle the decrypt in software. - */ - if ((k->wk_flags & IEEE80211_KEY_SWDECRYPT) && - !tkip_decrypt(ctx, k, m, hdrlen)) - return 0; - - /* - * Copy up 802.11 header and strip crypto bits. - */ - memmove(mtod(m, uint8_t *) + tkip.ic_header, mtod(m, void *), hdrlen); - m_adj(m, tkip.ic_header); - m_adj(m, -tkip.ic_trailer); - - return 1; -} - -/* - * Verify and strip MIC from the frame. - */ -static int -tkip_demic(struct ieee80211_key *k, struct mbuf *m, int force) -{ - struct tkip_ctx *ctx = k->wk_private; - struct ieee80211_frame *wh; - uint8_t tid; - - wh = mtod(m, struct ieee80211_frame *); - if ((k->wk_flags & IEEE80211_KEY_SWDEMIC) || force) { - struct ieee80211vap *vap = ctx->tc_vap; - int hdrlen = ieee80211_hdrspace(vap->iv_ic, wh); - u8 mic[IEEE80211_WEP_MICLEN]; - u8 mic0[IEEE80211_WEP_MICLEN]; - - vap->iv_stats.is_crypto_tkipdemic++; - - michael_mic(ctx, k->wk_rxmic, - m, hdrlen, m->m_pkthdr.len - (hdrlen + tkip.ic_miclen), - mic); - m_copydata(m, m->m_pkthdr.len - tkip.ic_miclen, - tkip.ic_miclen, mic0); - if (memcmp(mic, mic0, tkip.ic_miclen)) { - /* NB: 802.11 layer handles statistic and debug msg */ - ieee80211_notify_michael_failure(vap, wh, - k->wk_rxkeyix != IEEE80211_KEYIX_NONE ? - k->wk_rxkeyix : k->wk_keyix); - return 0; - } - } - /* - * Strip MIC from the tail. - */ - m_adj(m, -tkip.ic_miclen); - - /* - * Ok to update rsc now that MIC has been verified. - */ - tid = ieee80211_gettid(wh); - k->wk_keyrsc[tid] = ctx->rx_rsc; - - return 1; -} - -/* - * Host AP crypt: host-based TKIP encryption implementation for Host AP driver - * - * Copyright (c) 2003-2004, Jouni Malinen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - */ - -static const __u32 crc32_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; - -static __inline u16 RotR1(u16 val) -{ - return (val >> 1) | (val << 15); -} - -static __inline u8 Lo8(u16 val) -{ - return val & 0xff; -} - -static __inline u8 Hi8(u16 val) -{ - return val >> 8; -} - -static __inline u16 Lo16(u32 val) -{ - return val & 0xffff; -} - -static __inline u16 Hi16(u32 val) -{ - return val >> 16; -} - -static __inline u16 Mk16(u8 hi, u8 lo) -{ - return lo | (((u16) hi) << 8); -} - -static __inline u16 Mk16_le(const u16 *v) -{ - return le16toh(*v); -} - -static const u16 Sbox[256] = { - 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, - 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, - 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, - 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, - 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, - 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, - 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, - 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, - 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, - 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, - 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, - 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, - 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, - 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, - 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, - 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, - 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, - 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, - 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, - 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, - 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, - 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, - 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, - 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, - 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, - 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, - 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, - 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, - 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, - 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, - 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, - 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, -}; - -static __inline u16 _S_(u16 v) -{ - u16 t = Sbox[Hi8(v)]; - return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8)); -} - -#define PHASE1_LOOP_COUNT 8 - -static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32) -{ - int i, j; - - /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */ - TTAK[0] = Lo16(IV32); - TTAK[1] = Hi16(IV32); - TTAK[2] = Mk16(TA[1], TA[0]); - TTAK[3] = Mk16(TA[3], TA[2]); - TTAK[4] = Mk16(TA[5], TA[4]); - - for (i = 0; i < PHASE1_LOOP_COUNT; i++) { - j = 2 * (i & 1); - TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j])); - TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j])); - TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j])); - TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j])); - TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i; - } -} - -#ifndef _BYTE_ORDER -#error "Don't know native byte order" -#endif - -static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, - u16 IV16) -{ - /* Make temporary area overlap WEP seed so that the final copy can be - * avoided on little endian hosts. */ - u16 *PPK = (u16 *) &WEPSeed[4]; - - /* Step 1 - make copy of TTAK and bring in TSC */ - PPK[0] = TTAK[0]; - PPK[1] = TTAK[1]; - PPK[2] = TTAK[2]; - PPK[3] = TTAK[3]; - PPK[4] = TTAK[4]; - PPK[5] = TTAK[4] + IV16; - - /* Step 2 - 96-bit bijective mixing using S-box */ - PPK[0] += _S_(PPK[5] ^ Mk16_le((const u16 *) &TK[0])); - PPK[1] += _S_(PPK[0] ^ Mk16_le((const u16 *) &TK[2])); - PPK[2] += _S_(PPK[1] ^ Mk16_le((const u16 *) &TK[4])); - PPK[3] += _S_(PPK[2] ^ Mk16_le((const u16 *) &TK[6])); - PPK[4] += _S_(PPK[3] ^ Mk16_le((const u16 *) &TK[8])); - PPK[5] += _S_(PPK[4] ^ Mk16_le((const u16 *) &TK[10])); - - PPK[0] += RotR1(PPK[5] ^ Mk16_le((const u16 *) &TK[12])); - PPK[1] += RotR1(PPK[0] ^ Mk16_le((const u16 *) &TK[14])); - PPK[2] += RotR1(PPK[1]); - PPK[3] += RotR1(PPK[2]); - PPK[4] += RotR1(PPK[3]); - PPK[5] += RotR1(PPK[4]); - - /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value - * WEPSeed[0..2] is transmitted as WEP IV */ - WEPSeed[0] = Hi8(IV16); - WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F; - WEPSeed[2] = Lo8(IV16); - WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((const u16 *) &TK[0])) >> 1); - -#if _BYTE_ORDER == _BIG_ENDIAN - { - int i; - for (i = 0; i < 6; i++) - PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8); - } -#endif -} - -static void -wep_encrypt(u8 *key, struct mbuf *m0, u_int off, size_t data_len, - uint8_t icv[IEEE80211_WEP_CRCLEN]) -{ - u32 i, j, k, crc; - size_t buflen; - u8 S[256]; - u8 *pos; - struct mbuf *m; -#define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0) - - /* Setup RC4 state */ - for (i = 0; i < 256; i++) - S[i] = i; - j = 0; - for (i = 0; i < 256; i++) { - j = (j + S[i] + key[i & 0x0f]) & 0xff; - S_SWAP(i, j); - } - - /* Compute CRC32 over unencrypted data and apply RC4 to data */ - crc = ~0; - i = j = 0; - m = m0; - pos = mtod(m, uint8_t *) + off; - buflen = m->m_len - off; - for (;;) { - if (buflen > data_len) - buflen = data_len; - data_len -= buflen; - for (k = 0; k < buflen; k++) { - crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8); - i = (i + 1) & 0xff; - j = (j + S[i]) & 0xff; - S_SWAP(i, j); - *pos++ ^= S[(S[i] + S[j]) & 0xff]; - } - m = m->m_next; - if (m == NULL) { - KASSERT(data_len == 0, - ("out of buffers with data_len %zu\n", data_len)); - break; - } - pos = mtod(m, uint8_t *); - buflen = m->m_len; - } - crc = ~crc; - - /* Append little-endian CRC32 and encrypt it to produce ICV */ - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - for (k = 0; k < IEEE80211_WEP_CRCLEN; k++) { - i = (i + 1) & 0xff; - j = (j + S[i]) & 0xff; - S_SWAP(i, j); - icv[k] ^= S[(S[i] + S[j]) & 0xff]; - } -} - -static int -wep_decrypt(u8 *key, struct mbuf *m, u_int off, size_t data_len) -{ - u32 i, j, k, crc; - u8 S[256]; - u8 *pos, icv[4]; - size_t buflen; - - /* Setup RC4 state */ - for (i = 0; i < 256; i++) - S[i] = i; - j = 0; - for (i = 0; i < 256; i++) { - j = (j + S[i] + key[i & 0x0f]) & 0xff; - S_SWAP(i, j); - } - - /* Apply RC4 to data and compute CRC32 over decrypted data */ - crc = ~0; - i = j = 0; - pos = mtod(m, uint8_t *) + off; - buflen = m->m_len - off; - for (;;) { - if (buflen > data_len) - buflen = data_len; - data_len -= buflen; - for (k = 0; k < buflen; k++) { - i = (i + 1) & 0xff; - j = (j + S[i]) & 0xff; - S_SWAP(i, j); - *pos ^= S[(S[i] + S[j]) & 0xff]; - crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8); - pos++; - } - m = m->m_next; - if (m == NULL) { - KASSERT(data_len == 0, - ("out of buffers with data_len %zu\n", data_len)); - break; - } - pos = mtod(m, uint8_t *); - buflen = m->m_len; - } - crc = ~crc; - - /* Encrypt little-endian CRC32 and verify that it matches with the - * received ICV */ - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - for (k = 0; k < 4; k++) { - i = (i + 1) & 0xff; - j = (j + S[i]) & 0xff; - S_SWAP(i, j); - if ((icv[k] ^ S[(S[i] + S[j]) & 0xff]) != *pos++) { - /* ICV mismatch - drop frame */ - return -1; - } - } - - return 0; -} - - -static __inline u32 rotl(u32 val, int bits) -{ - return (val << bits) | (val >> (32 - bits)); -} - - -static __inline u32 rotr(u32 val, int bits) -{ - return (val >> bits) | (val << (32 - bits)); -} - - -static __inline u32 xswap(u32 val) -{ - return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8); -} - - -#define michael_block(l, r) \ -do { \ - r ^= rotl(l, 17); \ - l += r; \ - r ^= xswap(l); \ - l += r; \ - r ^= rotl(l, 3); \ - l += r; \ - r ^= rotr(l, 2); \ - l += r; \ -} while (0) - - -static __inline u32 get_le32_split(u8 b0, u8 b1, u8 b2, u8 b3) -{ - return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24); -} - -static __inline u32 get_le32(const u8 *p) -{ - return get_le32_split(p[0], p[1], p[2], p[3]); -} - - -static __inline void put_le32(u8 *p, u32 v) -{ - p[0] = v; - p[1] = v >> 8; - p[2] = v >> 16; - p[3] = v >> 24; -} - -/* - * Craft pseudo header used to calculate the MIC. - */ -static void -michael_mic_hdr(const struct ieee80211_frame *wh0, uint8_t hdr[16]) -{ - const struct ieee80211_frame_addr4 *wh = - (const struct ieee80211_frame_addr4 *) wh0; - - switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { - case IEEE80211_FC1_DIR_NODS: - IEEE80211_ADDR_COPY(hdr, wh->i_addr1); /* DA */ - IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr2); - break; - case IEEE80211_FC1_DIR_TODS: - IEEE80211_ADDR_COPY(hdr, wh->i_addr3); /* DA */ - IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr2); - break; - case IEEE80211_FC1_DIR_FROMDS: - IEEE80211_ADDR_COPY(hdr, wh->i_addr1); /* DA */ - IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr3); - break; - case IEEE80211_FC1_DIR_DSTODS: - IEEE80211_ADDR_COPY(hdr, wh->i_addr3); /* DA */ - IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr4); - break; - } - - if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) { - const struct ieee80211_qosframe *qwh = - (const struct ieee80211_qosframe *) wh; - hdr[12] = qwh->i_qos[0] & IEEE80211_QOS_TID; - } else - hdr[12] = 0; - hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ -} - -static void -michael_mic(struct tkip_ctx *ctx, const u8 *key, - struct mbuf *m, u_int off, size_t data_len, - u8 mic[IEEE80211_WEP_MICLEN]) -{ - uint8_t hdr[16]; - u32 l, r; - const uint8_t *data; - u_int space; - - michael_mic_hdr(mtod(m, struct ieee80211_frame *), hdr); - - l = get_le32(key); - r = get_le32(key + 4); - - /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */ - l ^= get_le32(hdr); - michael_block(l, r); - l ^= get_le32(&hdr[4]); - michael_block(l, r); - l ^= get_le32(&hdr[8]); - michael_block(l, r); - l ^= get_le32(&hdr[12]); - michael_block(l, r); - - /* first buffer has special handling */ - data = mtod(m, const uint8_t *) + off; - space = m->m_len - off; - for (;;) { - if (space > data_len) - space = data_len; - /* collect 32-bit blocks from current buffer */ - while (space >= sizeof(uint32_t)) { - l ^= get_le32(data); - michael_block(l, r); - data += sizeof(uint32_t), space -= sizeof(uint32_t); - data_len -= sizeof(uint32_t); - } - /* - * NB: when space is zero we make one more trip around - * the loop to advance to the next mbuf where there is - * data. This handles the case where there are 4*n - * bytes in an mbuf followed by <4 bytes in a later mbuf. - * By making an extra trip we'll drop out of the loop - * with m pointing at the mbuf with 3 bytes and space - * set as required by the remainder handling below. - */ - if (data_len == 0 || - (data_len < sizeof(uint32_t) && space != 0)) - break; - m = m->m_next; - if (m == NULL) { - KASSERT(0, ("out of data, data_len %zu\n", data_len)); - break; - } - if (space != 0) { - const uint8_t *data_next; - /* - * Block straddles buffers, split references. - */ - data_next = mtod(m, const uint8_t *); - KASSERT(m->m_len >= sizeof(uint32_t) - space, - ("not enough data in following buffer, " - "m_len %u need %zu\n", m->m_len, - sizeof(uint32_t) - space)); - switch (space) { - case 1: - l ^= get_le32_split(data[0], data_next[0], - data_next[1], data_next[2]); - data = data_next + 3; - space = m->m_len - 3; - break; - case 2: - l ^= get_le32_split(data[0], data[1], - data_next[0], data_next[1]); - data = data_next + 2; - space = m->m_len - 2; - break; - case 3: - l ^= get_le32_split(data[0], data[1], - data[2], data_next[0]); - data = data_next + 1; - space = m->m_len - 1; - break; - } - michael_block(l, r); - data_len -= sizeof(uint32_t); - } else { - /* - * Setup for next buffer. - */ - data = mtod(m, const uint8_t *); - space = m->m_len; - } - } - /* - * Catch degenerate cases like mbuf[4*n+1 bytes] followed by - * mbuf[2 bytes]. I don't believe these should happen; if they - * do then we'll need more involved logic. - */ - KASSERT(data_len <= space, - ("not enough data, data_len %zu space %u\n", data_len, space)); - - /* Last block and padding (0x5a, 4..7 x 0) */ - switch (data_len) { - case 0: - l ^= get_le32_split(0x5a, 0, 0, 0); - break; - case 1: - l ^= get_le32_split(data[0], 0x5a, 0, 0); - break; - case 2: - l ^= get_le32_split(data[0], data[1], 0x5a, 0); - break; - case 3: - l ^= get_le32_split(data[0], data[1], data[2], 0x5a); - break; - } - michael_block(l, r); - /* l ^= 0; */ - michael_block(l, r); - - put_le32(mic, l); - put_le32(mic + 4, r); -} - -static int -tkip_encrypt(struct tkip_ctx *ctx, struct ieee80211_key *key, - struct mbuf *m, int hdrlen) -{ - struct ieee80211_frame *wh; - uint8_t icv[IEEE80211_WEP_CRCLEN]; - - ctx->tc_vap->iv_stats.is_crypto_tkip++; - - wh = mtod(m, struct ieee80211_frame *); - if (!ctx->tx_phase1_done) { - tkip_mixing_phase1(ctx->tx_ttak, key->wk_key, wh->i_addr2, - (u32)(key->wk_keytsc >> 16)); - ctx->tx_phase1_done = 1; - } - tkip_mixing_phase2(ctx->tx_rc4key, key->wk_key, ctx->tx_ttak, - (u16) key->wk_keytsc); - - wep_encrypt(ctx->tx_rc4key, - m, hdrlen + tkip.ic_header, - m->m_pkthdr.len - (hdrlen + tkip.ic_header), - icv); - (void) m_append(m, IEEE80211_WEP_CRCLEN, icv); /* XXX check return */ - - key->wk_keytsc++; - if ((u16)(key->wk_keytsc) == 0) - ctx->tx_phase1_done = 0; - return 1; -} - -static int -tkip_decrypt(struct tkip_ctx *ctx, struct ieee80211_key *key, - struct mbuf *m, int hdrlen) -{ - struct ieee80211_frame *wh; - struct ieee80211vap *vap = ctx->tc_vap; - u32 iv32; - u16 iv16; - u8 tid; - - vap->iv_stats.is_crypto_tkip++; - - wh = mtod(m, struct ieee80211_frame *); - /* NB: tkip_decap already verified header and left seq in rx_rsc */ - iv16 = (u16) ctx->rx_rsc; - iv32 = (u32) (ctx->rx_rsc >> 16); - - tid = ieee80211_gettid(wh); - if (iv32 != (u32)(key->wk_keyrsc[tid] >> 16) || !ctx->rx_phase1_done) { - tkip_mixing_phase1(ctx->rx_ttak, key->wk_key, - wh->i_addr2, iv32); - ctx->rx_phase1_done = 1; - } - tkip_mixing_phase2(ctx->rx_rc4key, key->wk_key, ctx->rx_ttak, iv16); - - /* NB: m is unstripped; deduct headers + ICV to get payload */ - if (wep_decrypt(ctx->rx_rc4key, - m, hdrlen + tkip.ic_header, - m->m_pkthdr.len - (hdrlen + tkip.ic_header + tkip.ic_trailer))) { - if (iv32 != (u32)(key->wk_keyrsc[tid] >> 16)) { - /* Previously cached Phase1 result was already lost, so - * it needs to be recalculated for the next packet. */ - ctx->rx_phase1_done = 0; - } - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, - "%s", "TKIP ICV mismatch on decrypt"); - vap->iv_stats.is_rx_tkipicv++; - return 0; - } - return 1; -} - -/* - * Module glue. - */ -IEEE80211_CRYPTO_MODULE(tkip, 1); diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_wep.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_wep.c deleted file mode 100644 index 07c1797571..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_crypto_wep.c +++ /dev/null @@ -1,480 +0,0 @@ -/*- - * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 WEP crypto support. - */ -#include "opt_wlan.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include - -static void *wep_attach(struct ieee80211vap *, struct ieee80211_key *); -static void wep_detach(struct ieee80211_key *); -static int wep_setkey(struct ieee80211_key *); -static int wep_encap(struct ieee80211_key *, struct mbuf *, uint8_t keyid); -static int wep_decap(struct ieee80211_key *, struct mbuf *, int hdrlen); -static int wep_enmic(struct ieee80211_key *, struct mbuf *, int); -static int wep_demic(struct ieee80211_key *, struct mbuf *, int); - -static const struct ieee80211_cipher wep = { - .ic_name = "WEP", - .ic_cipher = IEEE80211_CIPHER_WEP, - .ic_header = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN, - .ic_trailer = IEEE80211_WEP_CRCLEN, - .ic_miclen = 0, - .ic_attach = wep_attach, - .ic_detach = wep_detach, - .ic_setkey = wep_setkey, - .ic_encap = wep_encap, - .ic_decap = wep_decap, - .ic_enmic = wep_enmic, - .ic_demic = wep_demic, -}; - -static int wep_encrypt(struct ieee80211_key *, struct mbuf *, int hdrlen); -static int wep_decrypt(struct ieee80211_key *, struct mbuf *, int hdrlen); - -struct wep_ctx { - struct ieee80211vap *wc_vap; /* for diagnostics+statistics */ - struct ieee80211com *wc_ic; - uint32_t wc_iv; /* initial vector for crypto */ -}; - -/* number of references from net80211 layer */ -static int nrefs = 0; - -static void * -wep_attach(struct ieee80211vap *vap, struct ieee80211_key *k) -{ - struct wep_ctx *ctx; - - ctx = (struct wep_ctx *) malloc(sizeof(struct wep_ctx), - M_80211_CRYPTO, M_NOWAIT | M_ZERO); - if (ctx == NULL) { - vap->iv_stats.is_crypto_nomem++; - return NULL; - } - - ctx->wc_vap = vap; - ctx->wc_ic = vap->iv_ic; - get_random_bytes(&ctx->wc_iv, sizeof(ctx->wc_iv)); - nrefs++; /* NB: we assume caller locking */ - return ctx; -} - -static void -wep_detach(struct ieee80211_key *k) -{ - struct wep_ctx *ctx = k->wk_private; - - free(ctx, M_80211_CRYPTO); - KASSERT(nrefs > 0, ("imbalanced attach/detach")); - nrefs--; /* NB: we assume caller locking */ -} - -static int -wep_setkey(struct ieee80211_key *k) -{ - return k->wk_keylen >= 40/NBBY; -} - -/* - * Add privacy headers appropriate for the specified key. - */ -static int -wep_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid) -{ - struct wep_ctx *ctx = k->wk_private; - struct ieee80211com *ic = ctx->wc_ic; - uint32_t iv; - uint8_t *ivp; - int hdrlen; - - hdrlen = ieee80211_hdrspace(ic, mtod(m, void *)); - - /* - * Copy down 802.11 header and add the IV + KeyID. - */ - M_PREPEND(m, wep.ic_header, M_NOWAIT); - if (m == NULL) - return 0; - ivp = mtod(m, uint8_t *); - ovbcopy(ivp + wep.ic_header, ivp, hdrlen); - ivp += hdrlen; - - /* - * XXX - * IV must not duplicate during the lifetime of the key. - * But no mechanism to renew keys is defined in IEEE 802.11 - * for WEP. And the IV may be duplicated at other stations - * because the session key itself is shared. So we use a - * pseudo random IV for now, though it is not the right way. - * - * NB: Rather than use a strictly random IV we select a - * random one to start and then increment the value for - * each frame. This is an explicit tradeoff between - * overhead and security. Given the basic insecurity of - * WEP this seems worthwhile. - */ - - /* - * Skip 'bad' IVs from Fluhrer/Mantin/Shamir: - * (B, 255, N) with 3 <= B < 16 and 0 <= N <= 255 - */ - iv = ctx->wc_iv; - if ((iv & 0xff00) == 0xff00) { - int B = (iv & 0xff0000) >> 16; - if (3 <= B && B < 16) - iv += 0x0100; - } - ctx->wc_iv = iv + 1; - - /* - * NB: Preserve byte order of IV for packet - * sniffers; it doesn't matter otherwise. - */ -#if _BYTE_ORDER == _BIG_ENDIAN - ivp[0] = iv >> 0; - ivp[1] = iv >> 8; - ivp[2] = iv >> 16; -#else - ivp[2] = iv >> 0; - ivp[1] = iv >> 8; - ivp[0] = iv >> 16; -#endif - ivp[3] = keyid; - - /* - * Finally, do software encrypt if neeed. - */ - if ((k->wk_flags & IEEE80211_KEY_SWENCRYPT) && - !wep_encrypt(k, m, hdrlen)) - return 0; - - return 1; -} - -/* - * Add MIC to the frame as needed. - */ -static int -wep_enmic(struct ieee80211_key *k, struct mbuf *m, int force) -{ - - return 1; -} - -/* - * Validate and strip privacy headers (and trailer) for a - * received frame. If necessary, decrypt the frame using - * the specified key. - */ -static int -wep_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen) -{ - struct wep_ctx *ctx = k->wk_private; - struct ieee80211vap *vap = ctx->wc_vap; - struct ieee80211_frame *wh; - - wh = mtod(m, struct ieee80211_frame *); - - /* - * Check if the device handled the decrypt in hardware. - * If so we just strip the header; otherwise we need to - * handle the decrypt in software. - */ - if ((k->wk_flags & IEEE80211_KEY_SWDECRYPT) && - !wep_decrypt(k, m, hdrlen)) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, - "%s", "WEP ICV mismatch on decrypt"); - vap->iv_stats.is_rx_wepfail++; - return 0; - } - - /* - * Copy up 802.11 header and strip crypto bits. - */ - ovbcopy(mtod(m, void *), mtod(m, uint8_t *) + wep.ic_header, hdrlen); - m_adj(m, wep.ic_header); - m_adj(m, -wep.ic_trailer); - - return 1; -} - -/* - * Verify and strip MIC from the frame. - */ -static int -wep_demic(struct ieee80211_key *k, struct mbuf *skb, int force) -{ - return 1; -} - -static const uint32_t crc32_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; - -static int -wep_encrypt(struct ieee80211_key *key, struct mbuf *m0, int hdrlen) -{ -#define S_SWAP(a,b) do { uint8_t t = S[a]; S[a] = S[b]; S[b] = t; } while(0) - struct wep_ctx *ctx = key->wk_private; - struct ieee80211vap *vap = ctx->wc_vap; - struct mbuf *m = m0; - uint8_t rc4key[IEEE80211_WEP_IVLEN + IEEE80211_KEYBUF_SIZE]; - uint8_t icv[IEEE80211_WEP_CRCLEN]; - uint32_t i, j, k, crc; - size_t buflen, data_len; - uint8_t S[256]; - uint8_t *pos; - u_int off, keylen; - - vap->iv_stats.is_crypto_wep++; - - /* NB: this assumes the header was pulled up */ - memcpy(rc4key, mtod(m, uint8_t *) + hdrlen, IEEE80211_WEP_IVLEN); - memcpy(rc4key + IEEE80211_WEP_IVLEN, key->wk_key, key->wk_keylen); - - /* Setup RC4 state */ - for (i = 0; i < 256; i++) - S[i] = i; - j = 0; - keylen = key->wk_keylen + IEEE80211_WEP_IVLEN; - for (i = 0; i < 256; i++) { - j = (j + S[i] + rc4key[i % keylen]) & 0xff; - S_SWAP(i, j); - } - - off = hdrlen + wep.ic_header; - data_len = m->m_pkthdr.len - off; - - /* Compute CRC32 over unencrypted data and apply RC4 to data */ - crc = ~0; - i = j = 0; - pos = mtod(m, uint8_t *) + off; - buflen = m->m_len - off; - for (;;) { - if (buflen > data_len) - buflen = data_len; - data_len -= buflen; - for (k = 0; k < buflen; k++) { - crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8); - i = (i + 1) & 0xff; - j = (j + S[i]) & 0xff; - S_SWAP(i, j); - *pos++ ^= S[(S[i] + S[j]) & 0xff]; - } - if (m->m_next == NULL) { - if (data_len != 0) { /* out of data */ - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, - ether_sprintf(mtod(m0, - struct ieee80211_frame *)->i_addr2), - "out of data for WEP (data_len %zu)", - data_len); - /* XXX stat */ - return 0; - } - break; - } - m = m->m_next; - pos = mtod(m, uint8_t *); - buflen = m->m_len; - } - crc = ~crc; - - /* Append little-endian CRC32 and encrypt it to produce ICV */ - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - for (k = 0; k < IEEE80211_WEP_CRCLEN; k++) { - i = (i + 1) & 0xff; - j = (j + S[i]) & 0xff; - S_SWAP(i, j); - icv[k] ^= S[(S[i] + S[j]) & 0xff]; - } - return m_append(m0, IEEE80211_WEP_CRCLEN, icv); -#undef S_SWAP -} - -static int -wep_decrypt(struct ieee80211_key *key, struct mbuf *m0, int hdrlen) -{ -#define S_SWAP(a,b) do { uint8_t t = S[a]; S[a] = S[b]; S[b] = t; } while(0) - struct wep_ctx *ctx = key->wk_private; - struct ieee80211vap *vap = ctx->wc_vap; - struct mbuf *m = m0; - uint8_t rc4key[IEEE80211_WEP_IVLEN + IEEE80211_KEYBUF_SIZE]; - uint8_t icv[IEEE80211_WEP_CRCLEN]; - uint32_t i, j, k, crc; - size_t buflen, data_len; - uint8_t S[256]; - uint8_t *pos; - u_int off, keylen; - - vap->iv_stats.is_crypto_wep++; - - /* NB: this assumes the header was pulled up */ - memcpy(rc4key, mtod(m, uint8_t *) + hdrlen, IEEE80211_WEP_IVLEN); - memcpy(rc4key + IEEE80211_WEP_IVLEN, key->wk_key, key->wk_keylen); - - /* Setup RC4 state */ - for (i = 0; i < 256; i++) - S[i] = i; - j = 0; - keylen = key->wk_keylen + IEEE80211_WEP_IVLEN; - for (i = 0; i < 256; i++) { - j = (j + S[i] + rc4key[i % keylen]) & 0xff; - S_SWAP(i, j); - } - - off = hdrlen + wep.ic_header; - data_len = m->m_pkthdr.len - (off + wep.ic_trailer), - - /* Compute CRC32 over unencrypted data and apply RC4 to data */ - crc = ~0; - i = j = 0; - pos = mtod(m, uint8_t *) + off; - buflen = m->m_len - off; - for (;;) { - if (buflen > data_len) - buflen = data_len; - data_len -= buflen; - for (k = 0; k < buflen; k++) { - i = (i + 1) & 0xff; - j = (j + S[i]) & 0xff; - S_SWAP(i, j); - *pos ^= S[(S[i] + S[j]) & 0xff]; - crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8); - pos++; - } - m = m->m_next; - if (m == NULL) { - if (data_len != 0) { /* out of data */ - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, - mtod(m0, struct ieee80211_frame *)->i_addr2, - "out of data for WEP (data_len %zu)", - data_len); - return 0; - } - break; - } - pos = mtod(m, uint8_t *); - buflen = m->m_len; - } - crc = ~crc; - - /* Encrypt little-endian CRC32 and verify that it matches with - * received ICV */ - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - for (k = 0; k < IEEE80211_WEP_CRCLEN; k++) { - i = (i + 1) & 0xff; - j = (j + S[i]) & 0xff; - S_SWAP(i, j); - /* XXX assumes ICV is contiguous in mbuf */ - if ((icv[k] ^ S[(S[i] + S[j]) & 0xff]) != *pos++) { - /* ICV mismatch - drop frame */ - return 0; - } - } - return 1; -#undef S_SWAP -} - -/* - * Module glue. - */ -IEEE80211_CRYPTO_MODULE(wep, 1); diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ddb.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_ddb.c deleted file mode 100644 index a38f12ac2e..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ddb.c +++ /dev/null @@ -1,879 +0,0 @@ -/*- - * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_ddb.h" -#include "opt_wlan.h" - -#ifdef DDB -/* - * IEEE 802.11 DDB support - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#ifdef IEEE80211_SUPPORT_TDMA -#include -#endif -#ifdef IEEE80211_SUPPORT_MESH -#include -#endif - -#include -#include - -#define DB_PRINTSYM(prefix, name, addr) do { \ - db_printf("%s%-25s : ", prefix, name); \ - db_printsym((db_addr_t) addr, DB_STGY_ANY); \ - db_printf("\n"); \ -} while (0) - -static void _db_show_sta(const struct ieee80211_node *); -static void _db_show_vap(const struct ieee80211vap *, int); -static void _db_show_com(const struct ieee80211com *, - int showvaps, int showsta, int showprocs); - -static void _db_show_node_table(const char *tag, - const struct ieee80211_node_table *); -static void _db_show_channel(const char *tag, const struct ieee80211_channel *); -static void _db_show_ssid(const char *tag, int ix, int len, const uint8_t *); -static void _db_show_appie(const char *tag, const struct ieee80211_appie *); -static void _db_show_key(const char *tag, int ix, const struct ieee80211_key *); -static void _db_show_roamparams(const char *tag, const void *arg, - const struct ieee80211_roamparam *rp); -static void _db_show_txparams(const char *tag, const void *arg, - const struct ieee80211_txparam *tp); -static void _db_show_ageq(const char *tag, const struct ieee80211_ageq *q); -static void _db_show_stats(const struct ieee80211_stats *); -#ifdef IEEE80211_SUPPORT_MESH -static void _db_show_mesh(const struct ieee80211_mesh_state *); -#endif - -DB_SHOW_COMMAND(sta, db_show_sta) -{ - if (!have_addr) { - db_printf("usage: show sta \n"); - return; - } - _db_show_sta((const struct ieee80211_node *) addr); -} - -DB_SHOW_COMMAND(statab, db_show_statab) -{ - if (!have_addr) { - db_printf("usage: show statab \n"); - return; - } - _db_show_node_table("", (const struct ieee80211_node_table *) addr); -} - -DB_SHOW_COMMAND(vap, db_show_vap) -{ - int i, showprocs = 0; - - if (!have_addr) { - db_printf("usage: show vap \n"); - return; - } - for (i = 0; modif[i] != '\0'; i++) - switch (modif[i]) { - case 'a': - showprocs = 1; - break; - case 'p': - showprocs = 1; - break; - } - _db_show_vap((const struct ieee80211vap *) addr, showprocs); -} - -DB_SHOW_COMMAND(com, db_show_com) -{ - const struct ieee80211com *ic; - int i, showprocs = 0, showvaps = 0, showsta = 0; - - if (!have_addr) { - db_printf("usage: show com \n"); - return; - } - for (i = 0; modif[i] != '\0'; i++) - switch (modif[i]) { - case 'a': - showsta = showvaps = showprocs = 1; - break; - case 's': - showsta = 1; - break; - case 'v': - showvaps = 1; - break; - case 'p': - showprocs = 1; - break; - } - - ic = (const struct ieee80211com *) addr; - _db_show_com(ic, showvaps, showsta, showprocs); -} - -DB_SHOW_ALL_COMMAND(vaps, db_show_all_vaps) -{ - VNET_ITERATOR_DECL(vnet_iter); - const struct ifnet *ifp; - int i, showall = 0; - - for (i = 0; modif[i] != '\0'; i++) - switch (modif[i]) { - case 'a': - showall = 1; - break; - } - - VNET_FOREACH(vnet_iter) { - TAILQ_FOREACH(ifp, &V_ifnet, if_list) - if (ifp->if_type == IFT_IEEE80211) { - const struct ieee80211com *ic = ifp->if_l2com; - - if (!showall) { - const struct ieee80211vap *vap; - db_printf("%s: com %p vaps:", - ifp->if_xname, ic); - TAILQ_FOREACH(vap, &ic->ic_vaps, - iv_next) - db_printf(" %s(%p)", - vap->iv_ifp->if_xname, vap); - db_printf("\n"); - } else - _db_show_com(ic, 1, 1, 1); - } - } -} - -#ifdef IEEE80211_SUPPORT_MESH -DB_SHOW_ALL_COMMAND(mesh, db_show_mesh) -{ - const struct ieee80211_mesh_state *ms; - - if (!have_addr) { - db_printf("usage: show mesh \n"); - return; - } - ms = (const struct ieee80211_mesh_state *) addr; - _db_show_mesh(ms); -} -#endif /* IEEE80211_SUPPORT_MESH */ - -static void -_db_show_txampdu(const char *sep, int ix, const struct ieee80211_tx_ampdu *tap) -{ - db_printf("%stxampdu[%d]: %p flags %b %s\n", - sep, ix, tap, tap->txa_flags, IEEE80211_AGGR_BITS, - ieee80211_wme_acnames[tap->txa_ac]); - db_printf("%s token %u lastsample %d pkts %d avgpps %d qbytes %d qframes %d\n", - sep, tap->txa_token, tap->txa_lastsample, tap->txa_pkts, - tap->txa_avgpps, tap->txa_qbytes, tap->txa_qframes); - db_printf("%s start %u seqpending %u wnd %u attempts %d nextrequest %d\n", - sep, tap->txa_start, tap->txa_seqpending, tap->txa_wnd, - tap->txa_attempts, tap->txa_nextrequest); - /* XXX timer */ -} - -static void -_db_show_rxampdu(const char *sep, int ix, const struct ieee80211_rx_ampdu *rap) -{ - int i; - - db_printf("%srxampdu[%d]: %p flags 0x%x tid %u\n", - sep, ix, rap, rap->rxa_flags, ix /*XXX */); - db_printf("%s qbytes %d qframes %d seqstart %u start %u wnd %u\n", - sep, rap->rxa_qbytes, rap->rxa_qframes, - rap->rxa_seqstart, rap->rxa_start, rap->rxa_wnd); - db_printf("%s age %d nframes %d\n", sep, - rap->rxa_age, rap->rxa_nframes); - for (i = 0; i < IEEE80211_AGGR_BAWMAX; i++) - if (rap->rxa_m[i] != NULL) - db_printf("%s m[%2u:%4u] %p\n", sep, i, - IEEE80211_SEQ_ADD(rap->rxa_start, i), - rap->rxa_m[i]); -} - -static void -_db_show_sta(const struct ieee80211_node *ni) -{ - int i; - - db_printf("0x%p: mac %s refcnt %d\n", ni, - ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)); - db_printf("\tvap %p wdsvap %p ic %p table %p\n", - ni->ni_vap, ni->ni_wdsvap, ni->ni_ic, ni->ni_table); - db_printf("\tflags=%b\n", ni->ni_flags, IEEE80211_NODE_BITS); - db_printf("\tscangen %u authmode %u ath_flags 0x%x ath_defkeyix %u\n", - ni->ni_scangen, ni->ni_authmode, - ni->ni_ath_flags, ni->ni_ath_defkeyix); - db_printf("\tassocid 0x%x txpower %u vlan %u\n", - ni->ni_associd, ni->ni_txpower, ni->ni_vlan); - db_printf("\tjointime %d (%lu secs) challenge %p\n", - ni->ni_jointime, (unsigned long)(time_uptime - ni->ni_jointime), - ni->ni_challenge); - db_printf("\ties: data %p len %d\n", ni->ni_ies.data, ni->ni_ies.len); - db_printf("\t[wpa_ie %p rsn_ie %p wme_ie %p ath_ie %p\n", - ni->ni_ies.wpa_ie, ni->ni_ies.rsn_ie, ni->ni_ies.wme_ie, - ni->ni_ies.ath_ie); - db_printf("\t htcap_ie %p htinfo_ie %p]\n", - ni->ni_ies.htcap_ie, ni->ni_ies.htinfo_ie); - if (ni->ni_flags & IEEE80211_NODE_QOS) { - for (i = 0; i < WME_NUM_TID; i++) { - if (ni->ni_txseqs[i] || ni->ni_rxseqs[i]) - db_printf("\t[%u] txseq %u rxseq %u fragno %u\n", - i, ni->ni_txseqs[i], - ni->ni_rxseqs[i] >> IEEE80211_SEQ_SEQ_SHIFT, - ni->ni_rxseqs[i] & IEEE80211_SEQ_FRAG_MASK); - } - } - db_printf("\ttxseq %u rxseq %u fragno %u rxfragstamp %u\n", - ni->ni_txseqs[IEEE80211_NONQOS_TID], - ni->ni_rxseqs[IEEE80211_NONQOS_TID] >> IEEE80211_SEQ_SEQ_SHIFT, - ni->ni_rxseqs[IEEE80211_NONQOS_TID] & IEEE80211_SEQ_FRAG_MASK, - ni->ni_rxfragstamp); - db_printf("\trxfrag[0] %p rxfrag[1] %p rxfrag[2] %p\n", - ni->ni_rxfrag[0], ni->ni_rxfrag[1], ni->ni_rxfrag[2]); - _db_show_key("\tucastkey", 0, &ni->ni_ucastkey); - db_printf("\tavgrssi 0x%x (rssi %d) noise %d\n", - ni->ni_avgrssi, IEEE80211_RSSI_GET(ni->ni_avgrssi), - ni->ni_noise); - db_printf("\tintval %u capinfo %b\n", - ni->ni_intval, ni->ni_capinfo, IEEE80211_CAPINFO_BITS); - db_printf("\tbssid %s", ether_sprintf(ni->ni_bssid)); - _db_show_ssid(" essid ", 0, ni->ni_esslen, ni->ni_essid); - db_printf("\n"); - _db_show_channel("\tchannel", ni->ni_chan); - db_printf("\n"); - db_printf("\terp %b dtim_period %u dtim_count %u\n", - ni->ni_erp, IEEE80211_ERP_BITS, - ni->ni_dtim_period, ni->ni_dtim_count); - - db_printf("\thtcap %b htparam 0x%x htctlchan %u ht2ndchan %u\n", - ni->ni_htcap, IEEE80211_HTCAP_BITS, - ni->ni_htparam, ni->ni_htctlchan, ni->ni_ht2ndchan); - db_printf("\thtopmode 0x%x htstbc 0x%x chw %u\n", - ni->ni_htopmode, ni->ni_htstbc, ni->ni_chw); - - /* XXX ampdu state */ - for (i = 0; i < WME_NUM_AC; i++) - if (ni->ni_tx_ampdu[i].txa_flags & IEEE80211_AGGR_SETUP) - _db_show_txampdu("\t", i, &ni->ni_tx_ampdu[i]); - for (i = 0; i < WME_NUM_TID; i++) - if (ni->ni_rx_ampdu[i].rxa_flags) - _db_show_rxampdu("\t", i, &ni->ni_rx_ampdu[i]); - - db_printf("\tinact %u inact_reload %u txrate %u\n", - ni->ni_inact, ni->ni_inact_reload, ni->ni_txrate); -#ifdef IEEE80211_SUPPORT_MESH - _db_show_ssid("\tmeshid ", 0, ni->ni_meshidlen, ni->ni_meshid); - db_printf(" mlstate %b mllid 0x%x mlpid 0x%x mlrcnt %u mltval %u\n", - ni->ni_mlstate, IEEE80211_MESH_MLSTATE_BITS, - ni->ni_mllid, ni->ni_mlpid, ni->ni_mlrcnt, ni->ni_mltval); -#endif -} - -#ifdef IEEE80211_SUPPORT_TDMA -static void -_db_show_tdma(const char *sep, const struct ieee80211_tdma_state *ts, int showprocs) -{ - db_printf("%stdma %p:\n", sep, ts); - db_printf("%s version %u slot %u bintval %u peer %p\n", sep, - ts->tdma_version, ts->tdma_slot, ts->tdma_bintval, ts->tdma_peer); - db_printf("%s slotlen %u slotcnt %u", sep, - ts->tdma_slotlen, ts->tdma_slotcnt); - db_printf(" inuse 0x%x active 0x%x count %d\n", - ts->tdma_inuse[0], ts->tdma_active[0], ts->tdma_count); - if (showprocs) { - DB_PRINTSYM(sep, " tdma_newstate", ts->tdma_newstate); - DB_PRINTSYM(sep, " tdma_recv_mgmt", ts->tdma_recv_mgmt); - DB_PRINTSYM(sep, " tdma_opdetach", ts->tdma_opdetach); - } -} -#endif /* IEEE80211_SUPPORT_TDMA */ - -static void -_db_show_vap(const struct ieee80211vap *vap, int showprocs) -{ - const struct ieee80211com *ic = vap->iv_ic; - int i; - - db_printf("%p:", vap); - db_printf(" bss %p", vap->iv_bss); - db_printf(" myaddr %s", ether_sprintf(vap->iv_myaddr)); - db_printf("\n"); - - db_printf("\topmode %s", ieee80211_opmode_name[vap->iv_opmode]); - db_printf(" state %s", ieee80211_state_name[vap->iv_state]); - db_printf(" ifp %p(%s)", vap->iv_ifp, vap->iv_ifp->if_xname); - db_printf("\n"); - - db_printf("\tic %p", vap->iv_ic); - db_printf(" media %p", &vap->iv_media); - db_printf(" bpf_if %p", vap->iv_rawbpf); - db_printf(" mgtsend %p", &vap->iv_mgtsend); -#if 0 - struct sysctllog *iv_sysctl; /* dynamic sysctl context */ -#endif - db_printf("\n"); - db_printf("\tdebug=%b\n", vap->iv_debug, IEEE80211_MSG_BITS); - - db_printf("\tflags=%b\n", vap->iv_flags, IEEE80211_F_BITS); - db_printf("\tflags_ext=%b\n", vap->iv_flags_ext, IEEE80211_FEXT_BITS); - db_printf("\tflags_ht=%b\n", vap->iv_flags_ht, IEEE80211_FHT_BITS); - db_printf("\tflags_ven=%b\n", vap->iv_flags_ven, IEEE80211_FVEN_BITS); - db_printf("\tcaps=%b\n", vap->iv_caps, IEEE80211_C_BITS); - db_printf("\thtcaps=%b\n", vap->iv_htcaps, IEEE80211_C_HTCAP_BITS); - - _db_show_stats(&vap->iv_stats); - - db_printf("\tinact_init %d", vap->iv_inact_init); - db_printf(" inact_auth %d", vap->iv_inact_auth); - db_printf(" inact_run %d", vap->iv_inact_run); - db_printf(" inact_probe %d", vap->iv_inact_probe); - db_printf("\n"); - - db_printf("\tdes_nssid %d", vap->iv_des_nssid); - if (vap->iv_des_nssid) - _db_show_ssid(" des_ssid[%u] ", 0, - vap->iv_des_ssid[0].len, vap->iv_des_ssid[0].ssid); - db_printf(" des_bssid %s", ether_sprintf(vap->iv_des_bssid)); - db_printf("\n"); - db_printf("\tdes_mode %d", vap->iv_des_mode); - _db_show_channel(" des_chan", vap->iv_des_chan); - db_printf("\n"); -#if 0 - int iv_nicknamelen; /* XXX junk */ - uint8_t iv_nickname[IEEE80211_NWID_LEN]; -#endif - db_printf("\tbgscanidle %u", vap->iv_bgscanidle); - db_printf(" bgscanintvl %u", vap->iv_bgscanintvl); - db_printf(" scanvalid %u", vap->iv_scanvalid); - db_printf("\n"); - db_printf("\tscanreq_duration %u", vap->iv_scanreq_duration); - db_printf(" scanreq_mindwell %u", vap->iv_scanreq_mindwell); - db_printf(" scanreq_maxdwell %u", vap->iv_scanreq_maxdwell); - db_printf("\n"); - db_printf("\tscanreq_flags 0x%x", vap->iv_scanreq_flags); - db_printf(" scanreq_nssid %d", vap->iv_scanreq_nssid); - for (i = 0; i < vap->iv_scanreq_nssid; i++) - _db_show_ssid(" scanreq_ssid[%u]", i, - vap->iv_scanreq_ssid[i].len, vap->iv_scanreq_ssid[i].ssid); - db_printf(" roaming %d", vap->iv_roaming); - db_printf("\n"); - for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_MAX; i++) - if (isset(ic->ic_modecaps, i)) { - _db_show_roamparams("\troamparms[%s]", - ieee80211_phymode_name[i], &vap->iv_roamparms[i]); - db_printf("\n"); - } - - db_printf("\tbmissthreshold %u", vap->iv_bmissthreshold); - db_printf(" bmiss_max %u", vap->iv_bmiss_count); - db_printf(" bmiss_max %d", vap->iv_bmiss_max); - db_printf("\n"); - db_printf("\tswbmiss_count %u", vap->iv_swbmiss_count); - db_printf(" swbmiss_period %u", vap->iv_swbmiss_period); - db_printf(" swbmiss %p", &vap->iv_swbmiss); - db_printf("\n"); - - db_printf("\tampdu_rxmax %d", vap->iv_ampdu_rxmax); - db_printf(" ampdu_density %d", vap->iv_ampdu_density); - db_printf(" ampdu_limit %d", vap->iv_ampdu_limit); - db_printf(" amsdu_limit %d", vap->iv_amsdu_limit); - db_printf("\n"); - - db_printf("\tmax_aid %u", vap->iv_max_aid); - db_printf(" aid_bitmap %p", vap->iv_aid_bitmap); - db_printf("\n"); - db_printf("\tsta_assoc %u", vap->iv_sta_assoc); - db_printf(" ps_sta %u", vap->iv_ps_sta); - db_printf(" ps_pending %u", vap->iv_ps_pending); - db_printf(" tim_len %u", vap->iv_tim_len); - db_printf(" tim_bitmap %p", vap->iv_tim_bitmap); - db_printf("\n"); - db_printf("\tdtim_period %u", vap->iv_dtim_period); - db_printf(" dtim_count %u", vap->iv_dtim_count); - db_printf(" set_tim %p", vap->iv_set_tim); - db_printf(" csa_count %d", vap->iv_csa_count); - db_printf("\n"); - - db_printf("\trtsthreshold %u", vap->iv_rtsthreshold); - db_printf(" fragthreshold %u", vap->iv_fragthreshold); - db_printf(" inact_timer %d", vap->iv_inact_timer); - db_printf("\n"); - for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_MAX; i++) - if (isset(ic->ic_modecaps, i)) { - _db_show_txparams("\ttxparms[%s]", - ieee80211_phymode_name[i], &vap->iv_txparms[i]); - db_printf("\n"); - } - - /* application-specified IE's to attach to mgt frames */ - _db_show_appie("\tappie_beacon", vap->iv_appie_beacon); - _db_show_appie("\tappie_probereq", vap->iv_appie_probereq); - _db_show_appie("\tappie_proberesp", vap->iv_appie_proberesp); - _db_show_appie("\tappie_assocreq", vap->iv_appie_assocreq); - _db_show_appie("\tappie_asscoresp", vap->iv_appie_assocresp); - _db_show_appie("\tappie_wpa", vap->iv_appie_wpa); - if (vap->iv_wpa_ie != NULL || vap->iv_rsn_ie != NULL) { - if (vap->iv_wpa_ie != NULL) - db_printf("\twpa_ie %p", vap->iv_wpa_ie); - if (vap->iv_rsn_ie != NULL) - db_printf("\trsn_ie %p", vap->iv_rsn_ie); - db_printf("\n"); - } - db_printf("\tmax_keyix %u", vap->iv_max_keyix); - db_printf(" def_txkey %d", vap->iv_def_txkey); - db_printf("\n"); - for (i = 0; i < IEEE80211_WEP_NKID; i++) - _db_show_key("\tnw_keys[%u]", i, &vap->iv_nw_keys[i]); - - db_printf("\tauth %p(%s)", vap->iv_auth, vap->iv_auth->ia_name); - db_printf(" ec %p", vap->iv_ec); - - db_printf(" acl %p", vap->iv_acl); - db_printf(" as %p", vap->iv_as); - db_printf("\n"); -#ifdef IEEE80211_SUPPORT_TDMA - if (vap->iv_tdma != NULL) - _db_show_tdma("\t", vap->iv_tdma, showprocs); -#endif /* IEEE80211_SUPPORT_TDMA */ - if (showprocs) { - DB_PRINTSYM("\t", "iv_key_alloc", vap->iv_key_alloc); - DB_PRINTSYM("\t", "iv_key_delete", vap->iv_key_delete); - DB_PRINTSYM("\t", "iv_key_set", vap->iv_key_set); - DB_PRINTSYM("\t", "iv_key_update_begin", vap->iv_key_update_begin); - DB_PRINTSYM("\t", "iv_key_update_end", vap->iv_key_update_end); - DB_PRINTSYM("\t", "iv_opdetach", vap->iv_opdetach); - DB_PRINTSYM("\t", "iv_input", vap->iv_input); - DB_PRINTSYM("\t", "iv_recv_mgmt", vap->iv_recv_mgmt); - DB_PRINTSYM("\t", "iv_deliver_data", vap->iv_deliver_data); - DB_PRINTSYM("\t", "iv_bmiss", vap->iv_bmiss); - DB_PRINTSYM("\t", "iv_reset", vap->iv_reset); - DB_PRINTSYM("\t", "iv_update_beacon", vap->iv_update_beacon); - DB_PRINTSYM("\t", "iv_newstate", vap->iv_newstate); - DB_PRINTSYM("\t", "iv_output", vap->iv_output); - } -} - -static void -_db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, int showprocs) -{ - struct ieee80211vap *vap; - - db_printf("%p:", ic); - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - db_printf(" %s(%p)", vap->iv_ifp->if_xname, vap); - db_printf("\n"); - db_printf("\tifp %p(%s)", ic->ic_ifp, ic->ic_ifp->if_xname); - db_printf(" comlock %p", &ic->ic_comlock); - db_printf("\n"); - db_printf("\theadroom %d", ic->ic_headroom); - db_printf(" phytype %d", ic->ic_phytype); - db_printf(" opmode %s", ieee80211_opmode_name[ic->ic_opmode]); - db_printf("\n"); - db_printf("\tmedia %p", &ic->ic_media); - db_printf(" inact %p", &ic->ic_inact); - db_printf("\n"); - - db_printf("\tflags=%b\n", ic->ic_flags, IEEE80211_F_BITS); - db_printf("\tflags_ext=%b\n", ic->ic_flags_ext, IEEE80211_FEXT_BITS); - db_printf("\tflags_ht=%b\n", ic->ic_flags_ht, IEEE80211_FHT_BITS); - db_printf("\tflags_ven=%b\n", ic->ic_flags_ven, IEEE80211_FVEN_BITS); - db_printf("\tcaps=%b\n", ic->ic_caps, IEEE80211_C_BITS); - db_printf("\tcryptocaps=%b\n", - ic->ic_cryptocaps, IEEE80211_CRYPTO_BITS); - db_printf("\thtcaps=%b\n", ic->ic_htcaps, IEEE80211_HTCAP_BITS); - -#if 0 - uint8_t ic_modecaps[2]; /* set of mode capabilities */ -#endif - db_printf("\tcurmode %u", ic->ic_curmode); - db_printf(" promisc %u", ic->ic_promisc); - db_printf(" allmulti %u", ic->ic_allmulti); - db_printf(" nrunning %u", ic->ic_nrunning); - db_printf("\n"); - db_printf("\tbintval %u", ic->ic_bintval); - db_printf(" lintval %u", ic->ic_lintval); - db_printf(" holdover %u", ic->ic_holdover); - db_printf(" txpowlimit %u", ic->ic_txpowlimit); - db_printf("\n"); -#if 0 - struct ieee80211_rateset ic_sup_rates[IEEE80211_MODE_MAX]; -#endif - /* - * Channel state: - * - * ic_channels is the set of available channels for the device; - * it is setup by the driver - * ic_nchans is the number of valid entries in ic_channels - * ic_chan_avail is a bit vector of these channels used to check - * whether a channel is available w/o searching the channel table. - * ic_chan_active is a (potentially) constrained subset of - * ic_chan_avail that reflects any mode setting or user-specified - * limit on the set of channels to use/scan - * ic_curchan is the current channel the device is set to; it may - * be different from ic_bsschan when we are off-channel scanning - * or otherwise doing background work - * ic_bsschan is the channel selected for operation; it may - * be undefined (IEEE80211_CHAN_ANYC) - * ic_prevchan is a cached ``previous channel'' used to optimize - * lookups when switching back+forth between two channels - * (e.g. for dynamic turbo) - */ - db_printf("\tnchans %d", ic->ic_nchans); -#if 0 - struct ieee80211_channel ic_channels[IEEE80211_CHAN_MAX]; - uint8_t ic_chan_avail[IEEE80211_CHAN_BYTES]; - uint8_t ic_chan_active[IEEE80211_CHAN_BYTES]; - uint8_t ic_chan_scan[IEEE80211_CHAN_BYTES]; -#endif - db_printf("\n"); - _db_show_channel("\tcurchan", ic->ic_curchan); - db_printf("\n"); - _db_show_channel("\tbsschan", ic->ic_bsschan); - db_printf("\n"); - _db_show_channel("\tprevchan", ic->ic_prevchan); - db_printf("\n"); - db_printf("\tregdomain %p", &ic->ic_regdomain); - db_printf("\n"); - - _db_show_channel("\tcsa_newchan", ic->ic_csa_newchan); - db_printf(" csa_count %d", ic->ic_csa_count); - db_printf( "dfs %p", &ic->ic_dfs); - db_printf("\n"); - - db_printf("\tscan %p", ic->ic_scan); - db_printf(" lastdata %d", ic->ic_lastdata); - db_printf(" lastscan %d", ic->ic_lastscan); - db_printf("\n"); - - db_printf("\tmax_keyix %d", ic->ic_max_keyix); - db_printf(" hash_key 0x%x", ic->ic_hash_key); - db_printf(" wme %p", &ic->ic_wme); - if (!showsta) - db_printf(" sta %p", &ic->ic_sta); - db_printf("\n"); - db_printf("\tstageq@%p:\n", &ic->ic_stageq); - _db_show_ageq("\t", &ic->ic_stageq); - if (showsta) - _db_show_node_table("\t", &ic->ic_sta); - - db_printf("\tprotmode %d", ic->ic_protmode); - db_printf(" nonerpsta %u", ic->ic_nonerpsta); - db_printf(" longslotsta %u", ic->ic_longslotsta); - db_printf(" lastnonerp %d", ic->ic_lastnonerp); - db_printf("\n"); - db_printf("\tsta_assoc %u", ic->ic_sta_assoc); - db_printf(" ht_sta_assoc %u", ic->ic_ht_sta_assoc); - db_printf(" ht40_sta_assoc %u", ic->ic_ht40_sta_assoc); - db_printf("\n"); - db_printf("\tcurhtprotmode 0x%x", ic->ic_curhtprotmode); - db_printf(" htprotmode %d", ic->ic_htprotmode); - db_printf(" lastnonht %d", ic->ic_lastnonht); - db_printf("\n"); - - db_printf("\tsuperg %p\n", ic->ic_superg); - - db_printf("\tmontaps %d th %p txchan %p rh %p rxchan %p\n", - ic->ic_montaps, ic->ic_th, ic->ic_txchan, ic->ic_rh, ic->ic_rxchan); - - if (showprocs) { - DB_PRINTSYM("\t", "ic_vap_create", ic->ic_vap_create); - DB_PRINTSYM("\t", "ic_vap_delete", ic->ic_vap_delete); -#if 0 - /* operating mode attachment */ - ieee80211vap_attach ic_vattach[IEEE80211_OPMODE_MAX]; -#endif - DB_PRINTSYM("\t", "ic_newassoc", ic->ic_newassoc); - DB_PRINTSYM("\t", "ic_getradiocaps", ic->ic_getradiocaps); - DB_PRINTSYM("\t", "ic_setregdomain", ic->ic_setregdomain); - DB_PRINTSYM("\t", "ic_send_mgmt", ic->ic_send_mgmt); - DB_PRINTSYM("\t", "ic_raw_xmit", ic->ic_raw_xmit); - DB_PRINTSYM("\t", "ic_updateslot", ic->ic_updateslot); - DB_PRINTSYM("\t", "ic_update_mcast", ic->ic_update_mcast); - DB_PRINTSYM("\t", "ic_update_promisc", ic->ic_update_promisc); - DB_PRINTSYM("\t", "ic_node_alloc", ic->ic_node_alloc); - DB_PRINTSYM("\t", "ic_node_free", ic->ic_node_free); - DB_PRINTSYM("\t", "ic_node_cleanup", ic->ic_node_cleanup); - DB_PRINTSYM("\t", "ic_node_getrssi", ic->ic_node_getrssi); - DB_PRINTSYM("\t", "ic_node_getsignal", ic->ic_node_getsignal); - DB_PRINTSYM("\t", "ic_node_getmimoinfo", ic->ic_node_getmimoinfo); - DB_PRINTSYM("\t", "ic_scan_start", ic->ic_scan_start); - DB_PRINTSYM("\t", "ic_scan_end", ic->ic_scan_end); - DB_PRINTSYM("\t", "ic_set_channel", ic->ic_set_channel); - DB_PRINTSYM("\t", "ic_scan_curchan", ic->ic_scan_curchan); - DB_PRINTSYM("\t", "ic_scan_mindwell", ic->ic_scan_mindwell); - DB_PRINTSYM("\t", "ic_recv_action", ic->ic_recv_action); - DB_PRINTSYM("\t", "ic_send_action", ic->ic_send_action); - DB_PRINTSYM("\t", "ic_addba_request", ic->ic_addba_request); - DB_PRINTSYM("\t", "ic_addba_response", ic->ic_addba_response); - DB_PRINTSYM("\t", "ic_addba_stop", ic->ic_addba_stop); - } - if (showvaps && !TAILQ_EMPTY(&ic->ic_vaps)) { - db_printf("\n"); - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - _db_show_vap(vap, showprocs); - } - if (showsta && !TAILQ_EMPTY(&ic->ic_sta.nt_node)) { - const struct ieee80211_node_table *nt = &ic->ic_sta; - const struct ieee80211_node *ni; - - TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { - db_printf("\n"); - _db_show_sta(ni); - } - } -} - -static void -_db_show_node_table(const char *tag, const struct ieee80211_node_table *nt) -{ - int i; - - db_printf("%s%s@%p:\n", tag, nt->nt_name, nt); - db_printf("%s nodelock %p", tag, &nt->nt_nodelock); - db_printf(" inact_init %d", nt->nt_inact_init); - db_printf(" scanlock %p", &nt->nt_scanlock); - db_printf(" scangen %u\n", nt->nt_scangen); - db_printf("%s keyixmax %d keyixmap %p\n", - tag, nt->nt_keyixmax, nt->nt_keyixmap); - for (i = 0; i < nt->nt_keyixmax; i++) { - const struct ieee80211_node *ni = nt->nt_keyixmap[i]; - if (ni != NULL) - db_printf("%s [%3u] %p %s\n", tag, i, ni, - ether_sprintf(ni->ni_macaddr)); - } -} - -static void -_db_show_channel(const char *tag, const struct ieee80211_channel *c) -{ - db_printf("%s ", tag); - if (c == NULL) - db_printf(""); - else if (c == IEEE80211_CHAN_ANYC) - db_printf(""); - else - db_printf("[%u (%u) flags=%b maxreg %d maxpow %d minpow %d state 0x%x extieee %u]", - c->ic_freq, c->ic_ieee, - c->ic_flags, IEEE80211_CHAN_BITS, - c->ic_maxregpower, c->ic_maxpower, c->ic_minpower, - c->ic_state, c->ic_extieee); -} - -static void -_db_show_ssid(const char *tag, int ix, int len, const uint8_t *ssid) -{ - const uint8_t *p; - int i; - - db_printf(tag, ix); - - if (len > IEEE80211_NWID_LEN) - len = IEEE80211_NWID_LEN; - /* determine printable or not */ - for (i = 0, p = ssid; i < len; i++, p++) { - if (*p < ' ' || *p > 0x7e) - break; - } - if (i == len) { - db_printf("\""); - for (i = 0, p = ssid; i < len; i++, p++) - db_printf("%c", *p); - db_printf("\""); - } else { - db_printf("0x"); - for (i = 0, p = ssid; i < len; i++, p++) - db_printf("%02x", *p); - } -} - -static void -_db_show_appie(const char *tag, const struct ieee80211_appie *ie) -{ - const uint8_t *p; - int i; - - if (ie == NULL) - return; - db_printf("%s [0x", tag); - for (i = 0, p = ie->ie_data; i < ie->ie_len; i++, p++) - db_printf("%02x", *p); - db_printf("]\n"); -} - -static void -_db_show_key(const char *tag, int ix, const struct ieee80211_key *wk) -{ - static const uint8_t zerodata[IEEE80211_KEYBUF_SIZE]; - const struct ieee80211_cipher *cip = wk->wk_cipher; - int keylen = wk->wk_keylen; - - db_printf(tag, ix); - switch (cip->ic_cipher) { - case IEEE80211_CIPHER_WEP: - /* compatibility */ - db_printf(" wepkey %u:%s", wk->wk_keyix, - keylen <= 5 ? "40-bit" : - keylen <= 13 ? "104-bit" : "128-bit"); - break; - case IEEE80211_CIPHER_TKIP: - if (keylen > 128/8) - keylen -= 128/8; /* ignore MIC for now */ - db_printf(" TKIP %u:%u-bit", wk->wk_keyix, 8*keylen); - break; - case IEEE80211_CIPHER_AES_OCB: - db_printf(" AES-OCB %u:%u-bit", wk->wk_keyix, 8*keylen); - break; - case IEEE80211_CIPHER_AES_CCM: - db_printf(" AES-CCM %u:%u-bit", wk->wk_keyix, 8*keylen); - break; - case IEEE80211_CIPHER_CKIP: - db_printf(" CKIP %u:%u-bit", wk->wk_keyix, 8*keylen); - break; - case IEEE80211_CIPHER_NONE: - db_printf(" NULL %u:%u-bit", wk->wk_keyix, 8*keylen); - break; - default: - db_printf(" UNKNOWN (0x%x) %u:%u-bit", - cip->ic_cipher, wk->wk_keyix, 8*keylen); - break; - } - if (wk->wk_rxkeyix != wk->wk_keyix) - db_printf(" rxkeyix %u", wk->wk_rxkeyix); - if (memcmp(wk->wk_key, zerodata, keylen) != 0) { - int i; - - db_printf(" <"); - for (i = 0; i < keylen; i++) - db_printf("%02x", wk->wk_key[i]); - db_printf(">"); - if (cip->ic_cipher != IEEE80211_CIPHER_WEP && - wk->wk_keyrsc[IEEE80211_NONQOS_TID] != 0) - db_printf(" rsc %ju", (uintmax_t)wk->wk_keyrsc[IEEE80211_NONQOS_TID]); - if (cip->ic_cipher != IEEE80211_CIPHER_WEP && - wk->wk_keytsc != 0) - db_printf(" tsc %ju", (uintmax_t)wk->wk_keytsc); - db_printf(" flags=%b", wk->wk_flags, IEEE80211_KEY_BITS); - } - db_printf("\n"); -} - -static void -printrate(const char *tag, int v) -{ - if (v == IEEE80211_FIXED_RATE_NONE) - db_printf(" %s ", tag); - else if (v == 11) - db_printf(" %s 5.5", tag); - else if (v & IEEE80211_RATE_MCS) - db_printf(" %s MCS%d", tag, v &~ IEEE80211_RATE_MCS); - else - db_printf(" %s %d", tag, v/2); -} - -static void -_db_show_roamparams(const char *tag, const void *arg, - const struct ieee80211_roamparam *rp) -{ - - db_printf(tag, arg); - if (rp->rssi & 1) - db_printf(" rssi %u.5", rp->rssi/2); - else - db_printf(" rssi %u", rp->rssi/2); - printrate("rate", rp->rate); -} - -static void -_db_show_txparams(const char *tag, const void *arg, - const struct ieee80211_txparam *tp) -{ - - db_printf(tag, arg); - printrate("ucastrate", tp->ucastrate); - printrate("mcastrate", tp->mcastrate); - printrate("mgmtrate", tp->mgmtrate); - db_printf(" maxretry %d", tp->maxretry); -} - -static void -_db_show_ageq(const char *tag, const struct ieee80211_ageq *q) -{ - const struct mbuf *m; - - db_printf("%s lock %p len %d maxlen %d drops %d head %p tail %p\n", - tag, &q->aq_lock, q->aq_len, q->aq_maxlen, q->aq_drops, - q->aq_head, q->aq_tail); - for (m = q->aq_head; m != NULL; m = m->m_nextpkt) - db_printf("%s %p (len %d, %b)\n", tag, m, m->m_len, - /* XXX could be either TX or RX but is mostly TX */ - m->m_flags, IEEE80211_MBUF_TX_FLAG_BITS); -} - -static void -_db_show_stats(const struct ieee80211_stats *is) -{ -} - -#ifdef IEEE80211_SUPPORT_MESH -static void -_db_show_mesh(const struct ieee80211_mesh_state *ms) -{ - struct ieee80211_mesh_route *rt; - int i; - - _db_show_ssid(" meshid ", 0, ms->ms_idlen, ms->ms_id); - db_printf("nextseq %u ttl %u flags 0x%x\n", ms->ms_seq, - ms->ms_ttl, ms->ms_flags); - db_printf("routing table:\n"); - i = 0; - TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) { - db_printf("entry %d:\tdest: %6D nexthop: %6D metric: %u", i, - rt->rt_dest, ":", rt->rt_nexthop, ":", rt->rt_metric); - db_printf("\tlifetime: %u lastseq: %u priv: %p\n", - rt->rt_lifetime, rt->rt_lastmseq, rt->rt_priv); - i++; - } -} -#endif /* IEEE80211_SUPPORT_MESH */ -#endif /* DDB */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_dfs.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_dfs.c deleted file mode 100644 index 4ea1ac0ecb..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_dfs.c +++ /dev/null @@ -1,377 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifdef __FreeBSD__ -__FBSDID("$FreeBSD$"); -#endif - -/* - * IEEE 802.11 DFS/Radar support. - */ -#include "opt_inet.h" -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -static int ieee80211_nol_timeout = 30*60; /* 30 minutes */ -SYSCTL_INT(_net_wlan, OID_AUTO, nol_timeout, CTLFLAG_RW, - &ieee80211_nol_timeout, 0, "NOL timeout (secs)"); -#define NOL_TIMEOUT msecs_to_ticks(ieee80211_nol_timeout*1000) - -static int ieee80211_cac_timeout = 60; /* 60 seconds */ -SYSCTL_INT(_net_wlan, OID_AUTO, cac_timeout, CTLFLAG_RW, - &ieee80211_cac_timeout, 0, "CAC timeout (secs)"); -#define CAC_TIMEOUT msecs_to_ticks(ieee80211_cac_timeout*1000) - -void -ieee80211_dfs_attach(struct ieee80211com *ic) -{ - struct ieee80211_dfs_state *dfs = &ic->ic_dfs; - - callout_init_mtx(&dfs->nol_timer, IEEE80211_LOCK_OBJ(ic), 0); - callout_init_mtx(&dfs->cac_timer, IEEE80211_LOCK_OBJ(ic), 0); -} - -void -ieee80211_dfs_detach(struct ieee80211com *ic) -{ - /* NB: we assume no locking is needed */ - ieee80211_dfs_reset(ic); -} - -void -ieee80211_dfs_reset(struct ieee80211com *ic) -{ - struct ieee80211_dfs_state *dfs = &ic->ic_dfs; - int i; - - /* NB: we assume no locking is needed */ - /* NB: cac_timer should be cleared by the state machine */ - callout_drain(&dfs->nol_timer); - for (i = 0; i < ic->ic_nchans; i++) - ic->ic_channels[i].ic_state = 0; - dfs->lastchan = NULL; -} - -static void -cac_timeout(void *arg) -{ - struct ieee80211vap *vap = arg; - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_dfs_state *dfs = &ic->ic_dfs; - int i; - - IEEE80211_LOCK_ASSERT(ic); - - if (vap->iv_state != IEEE80211_S_CAC) /* NB: just in case */ - return; - /* - * When radar is detected during a CAC we are woken - * up prematurely to switch to a new channel. - * Check the channel to decide how to act. - */ - if (IEEE80211_IS_CHAN_RADAR(ic->ic_curchan)) { - ieee80211_notify_cac(ic, ic->ic_curchan, - IEEE80211_NOTIFY_CAC_RADAR); - - if_printf(vap->iv_ifp, - "CAC timer on channel %u (%u MHz) stopped due to radar\n", - ic->ic_curchan->ic_ieee, ic->ic_curchan->ic_freq); - - /* XXX clobbers any existing desired channel */ - /* NB: dfs->newchan may be NULL, that's ok */ - vap->iv_des_chan = dfs->newchan; - /* XXX recursive lock need ieee80211_new_state_locked */ - ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); - } else { - if_printf(vap->iv_ifp, - "CAC timer on channel %u (%u MHz) expired; " - "no radar detected\n", - ic->ic_curchan->ic_ieee, ic->ic_curchan->ic_freq); - /* - * Mark all channels with the current frequency - * as having completed CAC; this keeps us from - * doing it again until we change channels. - */ - for (i = 0; i < ic->ic_nchans; i++) { - struct ieee80211_channel *c = &ic->ic_channels[i]; - if (c->ic_freq == ic->ic_curchan->ic_freq) - c->ic_state |= IEEE80211_CHANSTATE_CACDONE; - } - ieee80211_notify_cac(ic, ic->ic_curchan, - IEEE80211_NOTIFY_CAC_EXPIRE); - ieee80211_cac_completeswitch(vap); - } -} - -/* - * Initiate the CAC timer. The driver is responsible - * for setting up the hardware to scan for radar on the - * channnel, we just handle timing things out. - */ -void -ieee80211_dfs_cac_start(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_dfs_state *dfs = &ic->ic_dfs; - - IEEE80211_LOCK_ASSERT(ic); - - callout_reset(&dfs->cac_timer, CAC_TIMEOUT, cac_timeout, vap); - if_printf(vap->iv_ifp, "start %d second CAC timer on channel %u (%u MHz)\n", - ticks_to_secs(CAC_TIMEOUT), - ic->ic_curchan->ic_ieee, ic->ic_curchan->ic_freq); - ieee80211_notify_cac(ic, ic->ic_curchan, IEEE80211_NOTIFY_CAC_START); -} - -/* - * Clear the CAC timer. - */ -void -ieee80211_dfs_cac_stop(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_dfs_state *dfs = &ic->ic_dfs; - - IEEE80211_LOCK_ASSERT(ic); - - /* NB: racey but not important */ - if (callout_pending(&dfs->cac_timer)) { - if_printf(vap->iv_ifp, "stop CAC timer on channel %u (%u MHz)\n", - ic->ic_curchan->ic_ieee, ic->ic_curchan->ic_freq); - ieee80211_notify_cac(ic, ic->ic_curchan, - IEEE80211_NOTIFY_CAC_STOP); - } - callout_stop(&dfs->cac_timer); -} - -void -ieee80211_dfs_cac_clear(struct ieee80211com *ic, - const struct ieee80211_channel *chan) -{ - int i; - - for (i = 0; i < ic->ic_nchans; i++) { - struct ieee80211_channel *c = &ic->ic_channels[i]; - if (c->ic_freq == chan->ic_freq) - c->ic_state &= ~IEEE80211_CHANSTATE_CACDONE; - } -} - -static void -dfs_timeout(void *arg) -{ - struct ieee80211com *ic = arg; - struct ieee80211_dfs_state *dfs = &ic->ic_dfs; - struct ieee80211_channel *c; - int i, oldest, now; - - IEEE80211_LOCK_ASSERT(ic); - - now = oldest = ticks; - for (i = 0; i < ic->ic_nchans; i++) { - c = &ic->ic_channels[i]; - if (IEEE80211_IS_CHAN_RADAR(c)) { - if (time_after_eq(now, dfs->nol_event[i]+NOL_TIMEOUT)) { - c->ic_state &= ~IEEE80211_CHANSTATE_RADAR; - if (c->ic_state & IEEE80211_CHANSTATE_NORADAR) { - /* - * NB: do this here so we get only one - * msg instead of one for every channel - * table entry. - */ - if_printf(ic->ic_ifp, "radar on channel" - " %u (%u MHz) cleared after timeout\n", - c->ic_ieee, c->ic_freq); - /* notify user space */ - c->ic_state &= - ~IEEE80211_CHANSTATE_NORADAR; - ieee80211_notify_radar(ic, c); - } - } else if (dfs->nol_event[i] < oldest) - oldest = dfs->nol_event[i]; - } - } - if (oldest != now) { - /* arrange to process next channel up for a status change */ - callout_schedule(&dfs->nol_timer, oldest + NOL_TIMEOUT - now); - } -} - -static void -announce_radar(struct ifnet *ifp, const struct ieee80211_channel *curchan, - const struct ieee80211_channel *newchan) -{ - if (newchan == NULL) - if_printf(ifp, "radar detected on channel %u (%u MHz)\n", - curchan->ic_ieee, curchan->ic_freq); - else - if_printf(ifp, "radar detected on channel %u (%u MHz), " - "moving to channel %u (%u MHz)\n", - curchan->ic_ieee, curchan->ic_freq, - newchan->ic_ieee, newchan->ic_freq); -} - -/* - * Handle a radar detection event on a channel. The channel is - * added to the NOL list and we record the time of the event. - * Entries are aged out after NOL_TIMEOUT. If radar was - * detected while doing CAC we force a state/channel change. - * Otherwise radar triggers a channel switch using the CSA - * mechanism (when the channel is the bss channel). - */ -void -ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *chan) -{ - struct ieee80211_dfs_state *dfs = &ic->ic_dfs; - int i, now; - - IEEE80211_LOCK_ASSERT(ic); - - /* - * Mark all entries with this frequency. Notify user - * space and arrange for notification when the radar - * indication is cleared. Then kick the NOL processing - * thread if not already running. - */ - now = ticks; - for (i = 0; i < ic->ic_nchans; i++) { - struct ieee80211_channel *c = &ic->ic_channels[i]; - if (c->ic_freq == chan->ic_freq) { - c->ic_state &= ~IEEE80211_CHANSTATE_CACDONE; - c->ic_state |= IEEE80211_CHANSTATE_RADAR; - dfs->nol_event[i] = now; - } - } - ieee80211_notify_radar(ic, chan); - chan->ic_state |= IEEE80211_CHANSTATE_NORADAR; - if (!callout_pending(&dfs->nol_timer)) - callout_reset(&dfs->nol_timer, NOL_TIMEOUT, dfs_timeout, ic); - - /* - * If radar is detected on the bss channel while - * doing CAC; force a state change by scheduling the - * callout to be dispatched asap. Otherwise, if this - * event is for the bss channel then we must quiet - * traffic and schedule a channel switch. - * - * Note this allows us to receive notification about - * channels other than the bss channel; not sure - * that can/will happen but it's simple to support. - */ - if (chan == ic->ic_bsschan) { - /* XXX need a way to defer to user app */ - dfs->newchan = ieee80211_dfs_pickchannel(ic); - - announce_radar(ic->ic_ifp, chan, dfs->newchan); - - if (callout_pending(&dfs->cac_timer)) - callout_schedule(&dfs->cac_timer, 0); - else if (dfs->newchan != NULL) { - /* XXX mode 1, switch count 2 */ - /* XXX calculate switch count based on max - switch time and beacon interval? */ - ieee80211_csa_startswitch(ic, dfs->newchan, 1, 2); - } else { - /* - * Spec says to stop all transmissions and - * wait on the current channel for an entry - * on the NOL to expire. - */ - /*XXX*/ - if_printf(ic->ic_ifp, "%s: No free channels; waiting for entry " - "on NOL to expire\n", __func__); - } - } else { - /* - * Issue rate-limited console msgs. - */ - if (dfs->lastchan != chan) { - dfs->lastchan = chan; - dfs->cureps = 0; - announce_radar(ic->ic_ifp, chan, NULL); - } else if (ppsratecheck(&dfs->lastevent, &dfs->cureps, 1)) { - announce_radar(ic->ic_ifp, chan, NULL); - } - } -} - -struct ieee80211_channel * -ieee80211_dfs_pickchannel(struct ieee80211com *ic) -{ - struct ieee80211_channel *c; - int i, flags; - uint16_t v; - - /* - * Consult the scan cache first. - */ - flags = ic->ic_curchan->ic_flags & IEEE80211_CHAN_ALL; - /* - * XXX if curchan is HT this will never find a channel - * XXX 'cuz we scan only legacy channels - */ - c = ieee80211_scan_pickchannel(ic, flags); - if (c != NULL) - return c; - /* - * No channel found in scan cache; select a compatible - * one at random (skipping channels where radar has - * been detected). - */ - get_random_bytes(&v, sizeof(v)); - v %= ic->ic_nchans; - for (i = v; i < ic->ic_nchans; i++) { - c = &ic->ic_channels[i]; - if (!IEEE80211_IS_CHAN_RADAR(c) && - (c->ic_flags & flags) == flags) - return c; - } - for (i = 0; i < v; i++) { - c = &ic->ic_channels[i]; - if (!IEEE80211_IS_CHAN_RADAR(c) && - (c->ic_flags & flags) == flags) - return c; - } - if_printf(ic->ic_ifp, "HELP, no channel located to switch to!\n"); - return NULL; -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_dfs.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_dfs.h deleted file mode 100644 index e448cc5ceb..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_dfs.h +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_DFS_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_DFS_H_ - -/* - * 802.11h/DFS definitions. - */ - -struct ieee80211_dfs_state { - int nol_event[IEEE80211_CHAN_MAX]; - struct callout nol_timer; /* NOL list processing */ - struct callout cac_timer; /* CAC timer */ - struct timeval lastevent; /* time of last radar event */ - int cureps; /* current events/second */ - const struct ieee80211_channel *lastchan;/* chan w/ last radar event */ - struct ieee80211_channel *newchan; /* chan selected next */ -}; - -void ieee80211_dfs_attach(struct ieee80211com *); -void ieee80211_dfs_detach(struct ieee80211com *); - -void ieee80211_dfs_reset(struct ieee80211com *); - -void ieee80211_dfs_cac_start(struct ieee80211vap *); -void ieee80211_dfs_cac_stop(struct ieee80211vap *); -void ieee80211_dfs_cac_clear(struct ieee80211com *, - const struct ieee80211_channel *); - -void ieee80211_dfs_notify_radar(struct ieee80211com *, - struct ieee80211_channel *); -struct ieee80211_channel *ieee80211_dfs_pickchannel(struct ieee80211com *); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_DFS_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.cpp b/src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.cpp deleted file mode 100644 index 54e7ce714b..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.cpp +++ /dev/null @@ -1,753 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ - - -/*- - * Copyright (c) 2003-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -/* - * IEEE 802.11 support (Haiku-specific code) - */ - - -#include "ieee80211_haiku.h" - -extern "C" { -# include -# include -# include -# include - -# include -# include -# include -# include - -# include "ieee80211_var.h" -}; - -#include - -#include - -#include -#include -#include - -#include - - -#define TRACE_WLAN -#ifdef TRACE_WLAN -# define TRACE(x...) dprintf(x); -#else -# define TRACE(x...) ; -#endif - - -#define MC_ALIGN(m, len) \ -do { \ - (m)->m_data += (MCLBYTES - (len)) &~ (sizeof(long) - 1);\ -} while (/* CONSTCOND */ 0) - - -static net_notifications_module_info* sNotificationModule; - - -static struct ifnet* -get_ifnet(device_t device, int& i) -{ - int unit = device_get_unit(device); - - for (i = 0; i < MAX_DEVICES; i++) { - if (gDevices[i] != NULL && gDevices[i]->if_dunit == unit) - return gDevices[i]; - } - - return NULL; -} - - -status_t -init_wlan_stack(void) -{ - ieee80211_phy_init(); - ieee80211_auth_setup(); - ieee80211_ht_init(); - - get_module(NET_NOTIFICATIONS_MODULE_NAME, - (module_info**)&sNotificationModule); - - return B_OK; -} - - -void -uninit_wlan_stack(void) -{ - if (sNotificationModule != NULL) - put_module(NET_NOTIFICATIONS_MODULE_NAME); -} - - -status_t -start_wlan(device_t device) -{ - int i; - struct ifnet* ifp = get_ifnet(device, i); - if (ifp == NULL) - return B_BAD_VALUE; - -// TODO: review this and find a cleaner solution! - // This ensures that the cloned device gets - // the same index assigned as the base device - // Resulting in the same device name - // e.g.: /dev/net/atheros/0 instead of - // /dev/net/atheros/1 - gDevices[i] = NULL; - - struct ieee80211com* ic = (ieee80211com*)ifp->if_l2com; - - struct ieee80211vap* vap = ic->ic_vap_create(ic, "wlan", - device_get_unit(device), - IEEE80211_M_STA, // mode - 0, // flags - NULL, // BSSID - IF_LLADDR(ifp)); // MAC address - - if (vap == NULL) { - gDevices[i] = ifp; - return B_ERROR; - } - - // ic_vap_create() established that gDevices[i] links to vap->iv_ifp now - KASSERT(gDevices[i] == vap->iv_ifp, - ("start_wlan: gDevices[i] != vap->iv_ifp")); - - vap->iv_ifp->scan_done_sem = create_sem(0, "wlan scan done"); - - // We aren't connected to a WLAN, yet. - if_link_state_change(vap->iv_ifp, LINK_STATE_DOWN); - - dprintf("%s: wlan started.\n", __func__); - - return B_OK; -} - - -status_t -stop_wlan(device_t device) -{ - int i; - struct ifnet* ifp = get_ifnet(device, i); - if (ifp == NULL) - return B_BAD_VALUE; - - if (ifp->if_type == IFT_IEEE80211) { - // This happens when there was an error in starting the wlan before, - // resulting in never creating a clone device - return B_OK; - } - - delete_sem(ifp->scan_done_sem); - - struct ieee80211vap* vap = (ieee80211vap*)ifp->if_softc; - struct ieee80211com* ic = vap->iv_ic; - - ic->ic_vap_delete(vap); - - // ic_vap_delete freed gDevices[i] - KASSERT(gDevices[i] == NULL, ("stop_wlan: gDevices[i] != NULL")); - - // assign the base device ifp again - gDevices[i] = ic->ic_ifp; - - return B_OK; -} - - -status_t -wlan_open(void* cookie) -{ - dprintf("wlan_open(%p)\n", cookie); - struct ifnet* ifp = (struct ifnet*)cookie; - - ifp->if_init(ifp->if_softc); - - ifp->if_flags |= IFF_UP; - ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL); - - return B_OK; -} - - -status_t -wlan_close(void* cookie) -{ - dprintf("wlan_close(%p)\n", cookie); - struct ifnet* ifp = (struct ifnet*)cookie; - - ifp->if_flags &= ~IFF_UP; - ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL); - - return release_sem_etc(ifp->scan_done_sem, 1, B_RELEASE_ALL); -} - - -status_t -wlan_control(void* cookie, uint32 op, void* arg, size_t length) -{ - struct ifnet* ifp = (struct ifnet*)cookie; - - switch (op) { - case BOSII_DEVICE: - return B_OK; - - case BOSII_DETECT_NETWORKS: - { - struct ieee80211req request; - struct ieee80211_scan_req scanRequest; - - if_printf(ifp, "%s: BOSII_DETECT_NETWORKS\n", __func__); - memset(&scanRequest, 0, sizeof(scanRequest)); - scanRequest.sr_flags = IEEE80211_IOC_SCAN_ACTIVE - | IEEE80211_IOC_SCAN_NOPICK - | IEEE80211_IOC_SCAN_ONCE; - scanRequest.sr_duration = 10000; // 10 s - scanRequest.sr_nssid = 0; - - memset(&request, 0, sizeof(request)); - request.i_type = IEEE80211_IOC_SCAN_REQ; - request.i_data = &scanRequest; - request.i_len = sizeof(scanRequest); - - ifp->if_ioctl(ifp, SIOCS80211, (caddr_t)&request); - - acquire_sem_etc(ifp->scan_done_sem, 1, B_RELATIVE_TIMEOUT, - 10000000); // 10 s - - return B_OK; - } - - case BOSII_GET_DETECTED_NETWORKS: - { - struct ieee80211req request; - struct ifreq ifRequest; - struct route_entry* networkRequest = &ifRequest.ifr_route; - - if_printf(ifp, "%s: BOSII_GET_DETECTED_NETWORKS\n", __func__); - - if (length < sizeof(struct ieee80211req_scan_result)) - return B_BAD_VALUE; - - if (user_memcpy(&ifRequest, arg, sizeof(ifRequest)) < B_OK) - return B_BAD_ADDRESS; - - memset(&request, 0, sizeof(request)); - request.i_type = IEEE80211_IOC_SCAN_RESULTS; - request.i_len = length; - request.i_data = networkRequest->destination; - - // After return value of request.i_data is copied into user - // space, already. - if (ifp->if_ioctl(ifp, SIOCG80211, (caddr_t)&request) < B_OK) - return B_BAD_ADDRESS; - - // Tell the user space how much data was copied - networkRequest->mtu = request.i_len; - if (user_memcpy(&((struct ifreq*)arg)->ifr_route.mtu, - &networkRequest->mtu, sizeof(networkRequest->mtu)) < B_OK) - return B_BAD_ADDRESS; - - return B_OK; - } - - case BOSII_JOIN_NETWORK: - { - struct ieee80211req request; - struct ifreq ifRequest; - struct route_entry* networkRequest = &ifRequest.ifr_route; - struct ieee80211req_scan_result network; - - if_printf(ifp, "%s: BOSII_JOIN_NETWORK\n", __func__); - - if (length < sizeof(struct ifreq)) - return B_BAD_VALUE; - - if (user_memcpy(&ifRequest, arg, sizeof(ifRequest)) != B_OK - || user_memcpy(&network, networkRequest->source, - sizeof(ieee80211req_scan_result)) != B_OK) - return B_BAD_ADDRESS; - - memset(&request, 0, sizeof(ieee80211req)); - - request.i_type = IEEE80211_IOC_SSID; - request.i_val = 0; - request.i_len = network.isr_ssid_len; - request.i_data = (uint8*)networkRequest->source - + network.isr_ie_off; - if (ifp->if_ioctl(ifp, SIOCS80211, (caddr_t)&request) < B_OK) - return B_ERROR; - - // wait for network join - - return B_OK; - } - - case BOSII_GET_ASSOCIATED_NETWORK: - { - struct ieee80211req request; - struct ifreq ifRequest; - struct route_entry* networkRequest = &ifRequest.ifr_route; - - if_printf(ifp, "%s: BOSII_GET_ASSOCIATED_NETWORK\n", __func__); - - if (length < sizeof(struct ieee80211req_sta_req)) - return B_BAD_VALUE; - - if (user_memcpy(&ifRequest, arg, sizeof(ifRequest)) < B_OK) - return B_BAD_ADDRESS; - - // Only want station information about associated network. - memset(&request, 0, sizeof(request)); - request.i_type = IEEE80211_IOC_BSSID; - request.i_len = IEEE80211_ADDR_LEN; - request.i_data = ((struct ieee80211req_sta_req*)networkRequest-> - destination)->is_u.macaddr; - if (ifp->if_ioctl(ifp, SIOCG80211, (caddr_t)&request) < B_OK) - return B_BAD_ADDRESS; - - request.i_type = IEEE80211_IOC_STA_INFO; - request.i_len = length; - request.i_data = networkRequest->destination; - - // After return value of request.i_data is copied into user - // space, already. - if (ifp->if_ioctl(ifp, SIOCG80211, (caddr_t)&request) < B_OK) - return B_BAD_ADDRESS; - - // Tell the user space how much data was copied - networkRequest->mtu = request.i_len; - if (user_memcpy(&((struct ifreq*)arg)->ifr_route.mtu, - &networkRequest->mtu, sizeof(networkRequest->mtu)) != B_OK) - return B_BAD_ADDRESS; - - return B_OK; - } - - case SIOCG80211: - case SIOCS80211: - { - // Allowing FreeBSD based WLAN ioctls to pass, as those will become - // the future Haiku WLAN ioctls anyway. - - // FreeBSD drivers assume that the request structure has already - // been copied into kernel space - struct ieee80211req request; - if (user_memcpy(&request, arg, sizeof(struct ieee80211req)) != B_OK) - return B_BAD_ADDRESS; - - if (request.i_type == IEEE80211_IOC_HAIKU_COMPAT_WLAN_UP) - return wlan_open(cookie); - else if (request.i_type == IEEE80211_IOC_HAIKU_COMPAT_WLAN_DOWN) - return wlan_close(cookie); - - TRACE("wlan_control: %ld, %d\n", op, request.i_type); - status_t status = ifp->if_ioctl(ifp, op, (caddr_t)&request); - if (status != B_OK) - return status; - - if (op == SIOCG80211 && user_memcpy(arg, &request, - sizeof(struct ieee80211req)) != B_OK) - return B_BAD_ADDRESS; - return B_OK; - } - - case SIOCSIFFLAGS: - case SIOCSIFMEDIA: - case SIOCGIFMEDIA: - case SIOCSIFMTU: - // Requests that make it here always come from the kernel - return ifp->if_ioctl(ifp, op, (caddr_t)arg); - } - - return B_BAD_VALUE; -} - - -status_t -wlan_if_l2com_alloc(void* data) -{ - struct ifnet* ifp = (struct ifnet*)data; - - ifp->if_l2com = _kernel_malloc(sizeof(struct ieee80211com), M_ZERO); - if (ifp->if_l2com == NULL) - return B_NO_MEMORY; - ((struct ieee80211com*)(ifp->if_l2com))->ic_ifp = ifp; - return B_OK; -} - - -void -get_random_bytes(void* p, size_t n) -{ - uint8_t* dp = (uint8_t*)p; - - while (n > 0) { - uint32_t v = arc4random(); - size_t nb = n > sizeof(uint32_t) ? sizeof(uint32_t) : n; - bcopy(&v, dp, n > sizeof(uint32_t) ? sizeof(uint32_t) : n); - dp += sizeof(uint32_t), n -= nb; - } -} - - -struct mbuf* -ieee80211_getmgtframe(uint8_t** frm, int headroom, int pktlen) -{ - struct mbuf* m; - u_int len; - - len = roundup2(headroom + pktlen, 4); - KASSERT(len <= MCLBYTES, ("802.11 mgt frame too large: %u", len)); - if (len < MINCLSIZE) { - m = m_gethdr(M_NOWAIT, MT_DATA); - if (m != NULL) - MH_ALIGN(m, len); - } else { - m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); - if (m != NULL) - MC_ALIGN(m, len); - } - if (m != NULL) { - m->m_data += headroom; - *frm = (uint8_t*)m->m_data; - } - return m; -} - - -/* - * Decrements the reference-counter and - * tests whether it became zero. If so, sets it to one. - * - * @return 1 reference-counter became zero - * @return 0 reference-counter didn't became zero - */ -int -ieee80211_node_dectestref(struct ieee80211_node* ni) -{ - atomic_subtract_int(&ni->ni_refcnt, 1); - return atomic_cmpset_int(&ni->ni_refcnt, 0, 1); -} - - -void -ieee80211_drain_ifq(struct ifqueue* ifq) -{ - struct ieee80211_node* ni; - struct mbuf* m; - - for (;;) { - IF_DEQUEUE(ifq, m); - if (m == NULL) - break; - - ni = (struct ieee80211_node*)m->m_pkthdr.rcvif; - KASSERT(ni != NULL, ("frame w/o node")); - ieee80211_free_node(ni); - m->m_pkthdr.rcvif = NULL; - - m_freem(m); - } -} - - -void -ieee80211_flush_ifq(struct ifqueue* ifq, struct ieee80211vap* vap) -{ - struct ieee80211_node* ni; - struct mbuf* m; - struct mbuf** mprev; - - IF_LOCK(ifq); - mprev = &ifq->ifq_head; - while ((m = *mprev) != NULL) { - ni = (struct ieee80211_node*)m->m_pkthdr.rcvif; - if (ni != NULL && ni->ni_vap == vap) { - *mprev = m->m_nextpkt; - // remove from list - ifq->ifq_len--; - - m_freem(m); - ieee80211_free_node(ni); - // reclaim ref - } else - mprev = &m->m_nextpkt; - } - // recalculate tail ptr - m = ifq->ifq_head; - for (; m != NULL && m->m_nextpkt != NULL; m = m->m_nextpkt); - ifq->ifq_tail = m; - IF_UNLOCK(ifq); -} - - -int -ieee80211_add_callback(struct mbuf* m, - void (*func)(struct ieee80211_node*, void*, int), void* arg) -{ - struct m_tag* mtag; - struct ieee80211_cb* cb; - - mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_CALLBACK, - sizeof(struct ieee80211_cb), M_NOWAIT); - if (mtag == NULL) - return 0; - - cb = (struct ieee80211_cb*)(mtag+1); - cb->func = func; - cb->arg = arg; - m_tag_prepend(m, mtag); - m->m_flags |= M_TXCB; - return 1; -} - - -void -ieee80211_process_callback(struct ieee80211_node* ni, struct mbuf* m, - int status) -{ - struct m_tag* mtag; - - mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_CALLBACK, NULL); - if (mtag != NULL) { - struct ieee80211_cb* cb = (struct ieee80211_cb*)(mtag+1); - cb->func(ni, cb->arg, status); - } -} - - -void -ieee80211_sysctl_vattach(struct ieee80211vap* vap) -{ - vap->iv_debug = IEEE80211_MSG_XRATE - | IEEE80211_MSG_NODE - | IEEE80211_MSG_ASSOC - | IEEE80211_MSG_AUTH - | IEEE80211_MSG_STATE - | IEEE80211_MSG_POWER - | IEEE80211_MSG_WME - | IEEE80211_MSG_DOTH - | IEEE80211_MSG_INACT - | IEEE80211_MSG_ROAM - | IEEE80211_MSG_RATECTL; -} - - -void -ieee80211_sysctl_vdetach(struct ieee80211vap* vap) -{ - dprintf("%s not implemented, yet.\n", __func__); -} - - -void -ieee80211_vap_destroy(struct ieee80211vap* vap) -{ - struct ieee80211com* ic = vap->iv_ic; - - ic->ic_vap_delete(vap); - dprintf("%s: done.\n", __func__); -} - - -void -ieee80211_load_module(const char* modname) -{ - dprintf("%s not implemented, yet: modname %s\n", __func__, modname); -} - - -void -ieee80211_notify_node_join(struct ieee80211_node* ni, int newassoc) -{ - struct ieee80211vap* vap = ni->ni_vap; - struct ifnet* ifp = vap->iv_ifp; - - if (ni == vap->iv_bss) - if_link_state_change(ifp, LINK_STATE_UP); - - TRACE("%s\n", __FUNCTION__); - - if (sNotificationModule != NULL) { - char messageBuffer[512]; - KMessage message; - message.SetTo(messageBuffer, sizeof(messageBuffer), B_NETWORK_MONITOR); - message.AddInt32("opcode", B_NETWORK_WLAN_JOINED); - message.AddString("interface", ifp->device_name); - // TODO: add data about the node - - sNotificationModule->send_notification(&message); - } -} - - -void -ieee80211_notify_node_leave(struct ieee80211_node* ni) -{ - struct ieee80211vap* vap = ni->ni_vap; - struct ifnet* ifp = vap->iv_ifp; - - if (ni == vap->iv_bss) - if_link_state_change(ifp, LINK_STATE_DOWN); - - TRACE("%s\n", __FUNCTION__); - - if (sNotificationModule != NULL) { - char messageBuffer[512]; - KMessage message; - message.SetTo(messageBuffer, sizeof(messageBuffer), B_NETWORK_MONITOR); - message.AddInt32("opcode", B_NETWORK_WLAN_LEFT); - message.AddString("interface", ifp->device_name); - // TODO: add data about the node - - sNotificationModule->send_notification(&message); - } -} - - -void -ieee80211_notify_scan_done(struct ieee80211vap* vap) -{ - release_sem_etc(vap->iv_ifp->scan_done_sem, 1, - B_DO_NOT_RESCHEDULE | B_RELEASE_ALL); - - TRACE("%s\n", __FUNCTION__); - - if (sNotificationModule != NULL) { - char messageBuffer[512]; - KMessage message; - message.SetTo(messageBuffer, sizeof(messageBuffer), B_NETWORK_MONITOR); - message.AddInt32("opcode", B_NETWORK_WLAN_SCANNED); - message.AddString("interface", vap->iv_ifp->device_name); - - sNotificationModule->send_notification(&message); - } -} - - -void -ieee80211_notify_replay_failure(struct ieee80211vap* vap, - const struct ieee80211_frame* wh, const struct ieee80211_key* k, - u_int64_t rsc, int tid) -{ - dprintf("%s not implemented, yet.\n", __func__); -} - - -void -ieee80211_notify_michael_failure(struct ieee80211vap* vap, - const struct ieee80211_frame* wh, u_int keyix) -{ - dprintf("%s not implemented, yet.\n", __func__); -} - - -void -ieee80211_notify_wds_discover(struct ieee80211_node* ni) -{ - dprintf("%s not implemented, yet.\n", __func__); -} - - -void -ieee80211_notify_csa(struct ieee80211com* ic, - const struct ieee80211_channel* c, int mode, int count) -{ - dprintf("%s not implemented, yet.\n", __func__); -} - - -void -ieee80211_notify_radar(struct ieee80211com* ic, - const struct ieee80211_channel* c) -{ - dprintf("%s not implemented, yet.\n", __func__); -} - - -void -ieee80211_notify_cac(struct ieee80211com* ic, - const struct ieee80211_channel* c, enum ieee80211_notify_cac_event type) -{ - dprintf("%s not implemented, yet.\n", __func__); -} - - -void -ieee80211_notify_node_deauth(struct ieee80211_node* ni) -{ - dprintf("%s not implemented, yet.\n", __func__); -} - - -void -ieee80211_notify_node_auth(struct ieee80211_node* ni) -{ - dprintf("%s not implemented, yet.\n", __func__); -} - - -void -ieee80211_notify_country(struct ieee80211vap* vap, - const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t cc[2]) -{ - dprintf("%s not implemented, yet.\n", __func__); -} - - -void -ieee80211_notify_radio(struct ieee80211com* ic, int state) -{ - dprintf("%s not implemented, yet.\n", __func__); -} - - -void -ieee80211_sysctl_attach(struct ieee80211com* ic) -{ - dprintf("%s not implemented, yet.\n", __func__); -} - - -void -ieee80211_sysctl_detach(struct ieee80211com* ic) -{ - dprintf("%s not implemented, yet.\n", __func__); -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.h deleted file mode 100644 index c2735078f1..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.h +++ /dev/null @@ -1,395 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ - - -#include - - -#ifdef _KERNEL - -# ifdef __cplusplus -// Those includes are needed to avoid C/C++ function export clashes -# include -# include -extern "C" { -# endif - -#define INVARIANTS 1 - -#include -#include -#include -#include - - -#define IEEE80211_CRYPTO_MODULE(name, version) \ - void \ - ieee80211_crypto_##name##_load() { \ - ieee80211_crypto_register(&name); \ - } \ -\ -\ - void \ - ieee80211_crypto_##name##_unload() \ - { \ - ieee80211_crypto_unregister(&name); \ - } - - -/* - * Common state locking definitions. - */ -typedef struct { - char name[16]; /* e.g. "ath0_com_lock" */ - struct mtx mtx; -} ieee80211_com_lock_t; -#define IEEE80211_LOCK_INIT(_ic, _name) do { \ - ieee80211_com_lock_t *cl = &(_ic)->ic_comlock; \ - snprintf(cl->name, sizeof(cl->name), "%s_com_lock", _name); \ - mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF | MTX_RECURSE); \ -} while (0) -#define IEEE80211_LOCK_OBJ(_ic) (&(_ic)->ic_comlock.mtx) -#define IEEE80211_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_LOCK_OBJ(_ic)) -#define IEEE80211_LOCK(_ic) mtx_lock(IEEE80211_LOCK_OBJ(_ic)) -#define IEEE80211_UNLOCK(_ic) mtx_unlock(IEEE80211_LOCK_OBJ(_ic)) -#define IEEE80211_LOCK_ASSERT(_ic) \ - mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_OWNED) - -/* - * Node locking definitions. - */ -typedef struct { - char name[16]; /* e.g. "ath0_node_lock" */ - struct mtx mtx; -} ieee80211_node_lock_t; -#define IEEE80211_NODE_LOCK_INIT(_nt, _name) do { \ - ieee80211_node_lock_t *nl = &(_nt)->nt_nodelock; \ - snprintf(nl->name, sizeof(nl->name), "%s_node_lock", _name); \ - mtx_init(&nl->mtx, nl->name, NULL, MTX_DEF | MTX_RECURSE); \ -} while (0) -#define IEEE80211_NODE_LOCK_OBJ(_nt) (&(_nt)->nt_nodelock.mtx) -#define IEEE80211_NODE_LOCK_DESTROY(_nt) \ - mtx_destroy(IEEE80211_NODE_LOCK_OBJ(_nt)) -#define IEEE80211_NODE_LOCK(_nt) \ - mtx_lock(IEEE80211_NODE_LOCK_OBJ(_nt)) -#define IEEE80211_NODE_IS_LOCKED(_nt) \ - mtx_owned(IEEE80211_NODE_LOCK_OBJ(_nt)) -#define IEEE80211_NODE_UNLOCK(_nt) \ - mtx_unlock(IEEE80211_NODE_LOCK_OBJ(_nt)) -#define IEEE80211_NODE_LOCK_ASSERT(_nt) \ - mtx_assert(IEEE80211_NODE_LOCK_OBJ(_nt), MA_OWNED) - -/* - * Node table iteration locking definitions; this protects the - * scan generation # used to iterate over the station table - * while grabbing+releasing the node lock. - */ -typedef struct { - char name[16]; /* e.g. "ath0_scan_lock" */ - struct mtx mtx; -} ieee80211_scan_lock_t; -#define IEEE80211_NODE_ITERATE_LOCK_INIT(_nt, _name) do { \ - ieee80211_scan_lock_t *sl = &(_nt)->nt_scanlock; \ - snprintf(sl->name, sizeof(sl->name), "%s_scan_lock", _name); \ - mtx_init(&sl->mtx, sl->name, NULL, MTX_DEF); \ -} while (0) -#define IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt) (&(_nt)->nt_scanlock.mtx) -#define IEEE80211_NODE_ITERATE_LOCK_DESTROY(_nt) \ - mtx_destroy(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt)) -#define IEEE80211_NODE_ITERATE_LOCK(_nt) \ - mtx_lock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt)) -#define IEEE80211_NODE_ITERATE_UNLOCK(_nt) \ - mtx_unlock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt)) - -/* - * Power-save queue definitions. - */ -typedef struct mtx ieee80211_psq_lock_t; -#define IEEE80211_PSQ_INIT(_psq, _name) \ - mtx_init(&(_psq)->psq_lock, _name, "802.11 ps q", MTX_DEF) -#define IEEE80211_PSQ_DESTROY(_psq) mtx_destroy(&(_psq)->psq_lock) -#define IEEE80211_PSQ_LOCK(_psq) mtx_lock(&(_psq)->psq_lock) -#define IEEE80211_PSQ_UNLOCK(_psq) mtx_unlock(&(_psq)->psq_lock) - -#ifndef IF_PREPEND_LIST -#define _IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do { \ - (mtail)->m_nextpkt = (ifq)->ifq_head; \ - if ((ifq)->ifq_tail == NULL) \ - (ifq)->ifq_tail = (mtail); \ - (ifq)->ifq_head = (mhead); \ - (ifq)->ifq_len += (mcount); \ -} while (0) -#define IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do { \ - IF_LOCK(ifq); \ - _IF_PREPEND_LIST(ifq, mhead, mtail, mcount); \ - IF_UNLOCK(ifq); \ -} while (0) -#endif /* IF_PREPEND_LIST */ - -/* - * Age queue definitions. - */ -typedef struct mtx ieee80211_ageq_lock_t; -#define IEEE80211_AGEQ_INIT(_aq, _name) \ - mtx_init(&(_aq)->aq_lock, _name, "802.11 age q", MTX_DEF) -#define IEEE80211_AGEQ_DESTROY(_aq) mtx_destroy(&(_aq)->aq_lock) -#define IEEE80211_AGEQ_LOCK(_aq) mtx_lock(&(_aq)->aq_lock) -#define IEEE80211_AGEQ_UNLOCK(_aq) mtx_unlock(&(_aq)->aq_lock) - -/* - * Scan table definitions. - */ -typedef struct mtx ieee80211_scan_table_lock_t; -#define IEEE80211_SCAN_TABLE_LOCK_INIT(_st, _name) \ - mtx_init(&(_st)->st_lock, _name, "802.11 scan table", MTX_DEF) -#define IEEE80211_SCAN_TABLE_LOCK_DESTROY(_st) mtx_destroy(&(_st)->st_lock) -#define IEEE80211_SCAN_TABLE_LOCK(_st) mtx_lock(&(_st)->st_lock) -#define IEEE80211_SCAN_TABLE_UNLOCK(_st) mtx_unlock(&(_st)->st_lock) - -/* - * Node reference counting definitions. - * - * ieee80211_node_initref initialize the reference count to 1 - * ieee80211_node_incref add a reference - * ieee80211_node_decref remove a reference - * ieee80211_node_dectestref remove a reference and return 1 if this - * is the last reference, otherwise 0 - * ieee80211_node_refcnt reference count for printing (only) - */ -#include - -#define ieee80211_node_initref(_ni) \ - do { ((_ni)->ni_refcnt = 1); } while (0) -#define ieee80211_node_incref(_ni) \ - atomic_add_int(&(_ni)->ni_refcnt, 1) -#define ieee80211_node_decref(_ni) \ - atomic_subtract_int(&(_ni)->ni_refcnt, 1) -struct ieee80211_node; -int ieee80211_node_dectestref(struct ieee80211_node *ni); -#define ieee80211_node_refcnt(_ni) (_ni)->ni_refcnt - -struct ifqueue; -struct ieee80211vap; -void ieee80211_drain_ifq(struct ifqueue *); -void ieee80211_flush_ifq(struct ifqueue *, struct ieee80211vap *); - -void ieee80211_vap_destroy(struct ieee80211vap *); - -#define IFNET_IS_UP_RUNNING(_ifp) \ - (((_ifp)->if_flags & IFF_UP) && \ - ((_ifp)->if_drv_flags & IFF_DRV_RUNNING)) - -#define msecs_to_ticks(ms) (((ms)*hz)/1000) -#define ticks_to_msecs(t) (1000*(t) / hz) -#define ticks_to_secs(t) ((t) / hz) -#define time_after(a,b) ((long long)(b) - (long long)(a) < 0) -#define time_before(a,b) time_after(b,a) -#define time_after_eq(a,b) ((long long)(a) - (long long)(b) >= 0) -#define time_before_eq(a,b) time_after_eq(b,a) - -struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen); - -/* tx path usage */ -#define M_ENCAP M_PROTO1 /* 802.11 encap done */ -#define M_EAPOL M_PROTO3 /* PAE/EAPOL frame */ -#define M_PWR_SAV M_PROTO4 /* bypass PS handling */ -#define M_MORE_DATA M_PROTO5 /* more data frames to follow */ -#define M_FF M_PROTO6 /* fast frame */ -#define M_TXCB M_PROTO7 /* do tx complete callback */ -#define M_AMPDU_MPDU M_PROTO8 /* ok for A-MPDU aggregation */ -#define M_80211_TX \ - (M_FRAG|M_FIRSTFRAG|M_LASTFRAG|M_ENCAP|M_EAPOL|M_PWR_SAV|\ - M_MORE_DATA|M_FF|M_TXCB|M_AMPDU_MPDU) - -/* rx path usage */ -#define M_AMPDU M_PROTO1 /* A-MPDU subframe */ -#define M_WEP M_PROTO2 /* WEP done by hardware */ -#if 0 -#define M_AMPDU_MPDU M_PROTO8 /* A-MPDU re-order done */ -#endif -#define M_80211_RX (M_AMPDU|M_WEP|M_AMPDU_MPDU) - -/* - * Store WME access control bits in the vlan tag. - * This is safe since it's done after the packet is classified - * (where we use any previous tag) and because it's passed - * directly in to the driver and there's no chance someone - * else will clobber them on us. - */ -#define M_WME_SETAC(m, ac) \ - ((m)->m_pkthdr.ether_vtag = (ac)) -#define M_WME_GETAC(m) ((m)->m_pkthdr.ether_vtag) - -/* - * Mbufs on the power save queue are tagged with an age and - * timed out. We reuse the hardware checksum field in the - * mbuf packet header to store this data. - */ -#define M_AGE_SET(m,v) (m->m_pkthdr.csum_data = v) -#define M_AGE_GET(m) (m->m_pkthdr.csum_data) -#define M_AGE_SUB(m,adj) (m->m_pkthdr.csum_data -= adj) - -/* - * Store the sequence number. - */ -#define M_SEQNO_SET(m, seqno) \ - ((m)->m_pkthdr.tso_segsz = (seqno)) -#define M_SEQNO_GET(m) ((m)->m_pkthdr.tso_segsz) - -#define MTAG_ABI_NET80211 1132948340 /* net80211 ABI */ - -struct ieee80211_cb { - void (*func)(struct ieee80211_node *, void *, int status); - void *arg; -}; -#define NET80211_TAG_CALLBACK 0 /* xmit complete callback */ - -int ieee80211_add_callback(struct mbuf *m, - void (*func)(struct ieee80211_node *, void *, int), void *arg); -void ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int); - -void get_random_bytes(void *, size_t); - -struct ieee80211com; - -void ieee80211_sysctl_attach(struct ieee80211com *); -void ieee80211_sysctl_detach(struct ieee80211com *); -void ieee80211_sysctl_vattach(struct ieee80211vap *); -void ieee80211_sysctl_vdetach(struct ieee80211vap *); - -void ieee80211_load_module(const char *); - -/* - * A "policy module" is an adjunct module to net80211 that provides - * functionality that typically includes policy decisions. This - * modularity enables extensibility and vendor-supplied functionality. - */ -#define _IEEE80211_POLICY_MODULE(policy, name, version) \ -typedef void (*policy##_setup)(int); \ -SET_DECLARE(policy##_set, policy##_setup); - -/* - * Authenticator modules handle 802.1x/WPA authentication. - */ -#define IEEE80211_AUTH_MODULE(name, version) \ - _IEEE80211_POLICY_MODULE(auth, name, version) - -#define IEEE80211_AUTH_ALG(name, alg, v) \ -static void \ -name##_modevent(int type) \ -{ \ - if (type == MOD_LOAD) \ - ieee80211_authenticator_register(alg, &v); \ - else \ - ieee80211_authenticator_unregister(alg); \ -} \ -TEXT_SET(auth_set, name##_modevent) - -/* - * Scanner modules provide scanning policy. - */ -#define IEEE80211_SCANNER_MODULE(name, version) -#define IEEE80211_SCANNER_ALG(name, alg, v) - - -void ieee80211_scan_sta_init(void); -void ieee80211_scan_sta_uninit(void); - - -/* - * Rate control modules provide tx rate control support. - */ -#define IEEE80211_RATECTL_MODULE(alg, version) \ - _IEEE80211_POLICY_MODULE(ratectl, alg, version); \ - -#define IEEE80211_RATECTL_ALG(name, alg, v) \ - void \ - ieee80211_ratectl_##name##_load() { \ - ieee80211_ratectl_register(alg, &v); \ - } \ -\ -\ - void \ - ieee80211_ratectl_##name##_unload() \ - { \ - ieee80211_ratectl_unregister(alg); \ - } - - -struct ieee80211req; -typedef int ieee80211_ioctl_getfunc(struct ieee80211vap *, - struct ieee80211req *); -SET_DECLARE(ieee80211_ioctl_getset, ieee80211_ioctl_getfunc); -#define IEEE80211_IOCTL_GET(_name, _get) TEXT_SET(ieee80211_ioctl_getset, _get) - -typedef int ieee80211_ioctl_setfunc(struct ieee80211vap *, - struct ieee80211req *); -SET_DECLARE(ieee80211_ioctl_setset, ieee80211_ioctl_setfunc); -#define IEEE80211_IOCTL_SET(_name, _set) TEXT_SET(ieee80211_ioctl_setset, _set) - -#ifdef __cplusplus -} -#endif -#endif /* _KERNEL */ - -/* - * Structure prepended to raw packets sent through the bpf - * interface when set to DLT_IEEE802_11_RADIO. This allows - * user applications to specify pretty much everything in - * an Atheros tx descriptor. XXX need to generalize. - * - * XXX cannot be more than 14 bytes as it is copied to a sockaddr's - * XXX sa_data area. - */ -struct ieee80211_bpf_params { - uint8_t ibp_vers; /* version */ -#define IEEE80211_BPF_VERSION 0 - uint8_t ibp_len; /* header length in bytes */ - uint8_t ibp_flags; -#define IEEE80211_BPF_SHORTPRE 0x01 /* tx with short preamble */ -#define IEEE80211_BPF_NOACK 0x02 /* tx with no ack */ -#define IEEE80211_BPF_CRYPTO 0x04 /* tx with h/w encryption */ -#define IEEE80211_BPF_FCS 0x10 /* frame incldues FCS */ -#define IEEE80211_BPF_DATAPAD 0x20 /* frame includes data padding */ -#define IEEE80211_BPF_RTS 0x40 /* tx with RTS/CTS */ -#define IEEE80211_BPF_CTS 0x80 /* tx with CTS only */ - uint8_t ibp_pri; /* WME/WMM AC+tx antenna */ - uint8_t ibp_try0; /* series 1 try count */ - uint8_t ibp_rate0; /* series 1 IEEE tx rate */ - uint8_t ibp_power; /* tx power (device units) */ - uint8_t ibp_ctsrate; /* IEEE tx rate for CTS */ - uint8_t ibp_try1; /* series 2 try count */ - uint8_t ibp_rate1; /* series 2 IEEE tx rate */ - uint8_t ibp_try2; /* series 3 try count */ - uint8_t ibp_rate2; /* series 3 IEEE tx rate */ - uint8_t ibp_try3; /* series 4 try count */ - uint8_t ibp_rate3; /* series 4 IEEE tx rate */ -}; - -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_hostap.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_hostap.c deleted file mode 100644 index e190450037..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_hostap.c +++ /dev/null @@ -1,2321 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifdef __FreeBSD__ -__FBSDID("$FreeBSD$"); -#endif - -/* - * IEEE 802.11 HOSTAP mode support. - */ -#include "opt_inet.h" -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#ifdef IEEE80211_SUPPORT_SUPERG -#include -#endif -#include - -#define IEEE80211_RATE2MBS(r) (((r) & IEEE80211_RATE_VAL) / 2) - -static void hostap_vattach(struct ieee80211vap *); -static int hostap_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int hostap_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int nf); -static void hostap_deliver_data(struct ieee80211vap *, - struct ieee80211_node *, struct mbuf *); -static void hostap_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int nf); -static void hostap_recv_ctl(struct ieee80211_node *, struct mbuf *, int); -static void hostap_recv_pspoll(struct ieee80211_node *, struct mbuf *); - -void -ieee80211_hostap_attach(struct ieee80211com *ic) -{ - ic->ic_vattach[IEEE80211_M_HOSTAP] = hostap_vattach; -} - -void -ieee80211_hostap_detach(struct ieee80211com *ic) -{ -} - -static void -hostap_vdetach(struct ieee80211vap *vap) -{ -} - -static void -hostap_vattach(struct ieee80211vap *vap) -{ - vap->iv_newstate = hostap_newstate; - vap->iv_input = hostap_input; - vap->iv_recv_mgmt = hostap_recv_mgmt; - vap->iv_recv_ctl = hostap_recv_ctl; - vap->iv_opdetach = hostap_vdetach; - vap->iv_deliver_data = hostap_deliver_data; -} - -static void -sta_disassoc(void *arg, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = arg; - - if (ni->ni_vap == vap && ni->ni_associd != 0) { - IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DISASSOC, - IEEE80211_REASON_ASSOC_LEAVE); - ieee80211_node_leave(ni); - } -} - -static void -sta_csa(void *arg, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = arg; - - if (ni->ni_vap == vap && ni->ni_associd != 0) - if (ni->ni_inact > vap->iv_inact_init) { - ni->ni_inact = vap->iv_inact_init; - IEEE80211_NOTE(vap, IEEE80211_MSG_INACT, ni, - "%s: inact %u", __func__, ni->ni_inact); - } -} - -static void -sta_drop(void *arg, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = arg; - - if (ni->ni_vap == vap && ni->ni_associd != 0) - ieee80211_node_leave(ni); -} - -/* - * Does a channel change require associated stations to re-associate - * so protocol state is correct. This is used when doing CSA across - * bands or similar (e.g. HT -> legacy). - */ -static int -isbandchange(struct ieee80211com *ic) -{ - return ((ic->ic_bsschan->ic_flags ^ ic->ic_csa_newchan->ic_flags) & - (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_HALF | - IEEE80211_CHAN_QUARTER | IEEE80211_CHAN_HT)) != 0; -} - -/* - * IEEE80211_M_HOSTAP vap state machine handler. - */ -static int -hostap_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct ieee80211com *ic = vap->iv_ic; - enum ieee80211_state ostate; - - IEEE80211_LOCK_ASSERT(ic); - - ostate = vap->iv_state; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n", - __func__, ieee80211_state_name[ostate], - ieee80211_state_name[nstate], arg); - vap->iv_state = nstate; /* state transition */ - if (ostate != IEEE80211_S_SCAN) - ieee80211_cancel_scan(vap); /* background scan */ - switch (nstate) { - case IEEE80211_S_INIT: - switch (ostate) { - case IEEE80211_S_SCAN: - ieee80211_cancel_scan(vap); - break; - case IEEE80211_S_CAC: - ieee80211_dfs_cac_stop(vap); - break; - case IEEE80211_S_RUN: - ieee80211_iterate_nodes(&ic->ic_sta, sta_disassoc, vap); - break; - default: - break; - } - if (ostate != IEEE80211_S_INIT) { - /* NB: optimize INIT -> INIT case */ - ieee80211_reset_bss(vap); - } - if (vap->iv_auth->ia_detach != NULL) - vap->iv_auth->ia_detach(vap); - break; - case IEEE80211_S_SCAN: - switch (ostate) { - case IEEE80211_S_CSA: - case IEEE80211_S_RUN: - ieee80211_iterate_nodes(&ic->ic_sta, sta_disassoc, vap); - /* - * Clear overlapping BSS state; the beacon frame - * will be reconstructed on transition to the RUN - * state and the timeout routines check if the flag - * is set before doing anything so this is sufficient. - */ - ic->ic_flags_ext &= ~IEEE80211_FEXT_NONERP_PR; - ic->ic_flags_ht &= ~IEEE80211_FHT_NONHT_PR; - /* fall thru... */ - case IEEE80211_S_CAC: - /* - * NB: We may get here because of a manual channel - * change in which case we need to stop CAC - * XXX no need to stop if ostate RUN but it's ok - */ - ieee80211_dfs_cac_stop(vap); - /* fall thru... */ - case IEEE80211_S_INIT: - if (vap->iv_des_chan != IEEE80211_CHAN_ANYC && - !IEEE80211_IS_CHAN_RADAR(vap->iv_des_chan)) { - /* - * Already have a channel; bypass the - * scan and startup immediately. - * ieee80211_create_ibss will call back to - * move us to RUN state. - */ - ieee80211_create_ibss(vap, vap->iv_des_chan); - break; - } - /* - * Initiate a scan. We can come here as a result - * of an IEEE80211_IOC_SCAN_REQ too in which case - * the vap will be marked with IEEE80211_FEXT_SCANREQ - * and the scan request parameters will be present - * in iv_scanreq. Otherwise we do the default. - */ - if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) { - ieee80211_check_scan(vap, - vap->iv_scanreq_flags, - vap->iv_scanreq_duration, - vap->iv_scanreq_mindwell, - vap->iv_scanreq_maxdwell, - vap->iv_scanreq_nssid, vap->iv_scanreq_ssid); - vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; - } else - ieee80211_check_scan_current(vap); - break; - case IEEE80211_S_SCAN: - /* - * A state change requires a reset; scan. - */ - ieee80211_check_scan_current(vap); - break; - default: - break; - } - break; - case IEEE80211_S_CAC: - /* - * Start CAC on a DFS channel. We come here when starting - * a bss on a DFS channel (see ieee80211_create_ibss). - */ - ieee80211_dfs_cac_start(vap); - break; - case IEEE80211_S_RUN: - if (vap->iv_flags & IEEE80211_F_WPA) { - /* XXX validate prerequisites */ - } - switch (ostate) { - case IEEE80211_S_INIT: - /* - * Already have a channel; bypass the - * scan and startup immediately. - * Note that ieee80211_create_ibss will call - * back to do a RUN->RUN state change. - */ - ieee80211_create_ibss(vap, - ieee80211_ht_adjust_channel(ic, - ic->ic_curchan, vap->iv_flags_ht)); - /* NB: iv_bss is changed on return */ - break; - case IEEE80211_S_CAC: - /* - * NB: This is the normal state change when CAC - * expires and no radar was detected; no need to - * clear the CAC timer as it's already expired. - */ - /* fall thru... */ - case IEEE80211_S_CSA: - /* - * Shorten inactivity timer of associated stations - * to weed out sta's that don't follow a CSA. - */ - ieee80211_iterate_nodes(&ic->ic_sta, sta_csa, vap); - /* - * Update bss node channel to reflect where - * we landed after CSA. - */ - ieee80211_node_set_chan(vap->iv_bss, - ieee80211_ht_adjust_channel(ic, ic->ic_curchan, - ieee80211_htchanflags(vap->iv_bss->ni_chan))); - /* XXX bypass debug msgs */ - break; - case IEEE80211_S_SCAN: - case IEEE80211_S_RUN: -#ifdef IEEE80211_DEBUG - if (ieee80211_msg_debug(vap)) { - struct ieee80211_node *ni = vap->iv_bss; - ieee80211_note(vap, - "synchronized with %s ssid ", - ether_sprintf(ni->ni_bssid)); - ieee80211_print_essid(ni->ni_essid, - ni->ni_esslen); - /* XXX MCS/HT */ - printf(" channel %d start %uMb\n", - ieee80211_chan2ieee(ic, ic->ic_curchan), - IEEE80211_RATE2MBS(ni->ni_txrate)); - } -#endif - break; - default: - break; - } - /* - * Start/stop the authenticator. We delay until here - * to allow configuration to happen out of order. - */ - if (vap->iv_auth->ia_attach != NULL) { - /* XXX check failure */ - vap->iv_auth->ia_attach(vap); - } else if (vap->iv_auth->ia_detach != NULL) { - vap->iv_auth->ia_detach(vap); - } - ieee80211_node_authorize(vap->iv_bss); - break; - case IEEE80211_S_CSA: - if (ostate == IEEE80211_S_RUN && isbandchange(ic)) { - /* - * On a ``band change'' silently drop associated - * stations as they must re-associate before they - * can pass traffic (as otherwise protocol state - * such as capabilities and the negotiated rate - * set may/will be wrong). - */ - ieee80211_iterate_nodes(&ic->ic_sta, sta_drop, vap); - } - break; - default: - break; - } - return 0; -} - -static void -hostap_deliver_data(struct ieee80211vap *vap, - struct ieee80211_node *ni, struct mbuf *m) -{ - struct ether_header *eh = mtod(m, struct ether_header *); - struct ifnet *ifp = vap->iv_ifp; - - /* clear driver/net80211 flags before passing up */ - m->m_flags &= ~(M_80211_RX | M_MCAST | M_BCAST); - - KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP, - ("gack, opmode %d", vap->iv_opmode)); - /* - * Do accounting. - */ - ifp->if_ipackets++; - IEEE80211_NODE_STAT(ni, rx_data); - IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len); - if (ETHER_IS_MULTICAST(eh->ether_dhost)) { - m->m_flags |= M_MCAST; /* XXX M_BCAST? */ - IEEE80211_NODE_STAT(ni, rx_mcast); - } else - IEEE80211_NODE_STAT(ni, rx_ucast); - - /* perform as a bridge within the AP */ - if ((vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0) { - struct mbuf *mcopy = NULL; - - if (m->m_flags & M_MCAST) { - mcopy = m_dup(m, M_DONTWAIT); - if (mcopy == NULL) - ifp->if_oerrors++; - else - mcopy->m_flags |= M_MCAST; - } else { - /* - * Check if the destination is associated with the - * same vap and authorized to receive traffic. - * Beware of traffic destined for the vap itself; - * sending it will not work; just let it be delivered - * normally. - */ - struct ieee80211_node *sta = ieee80211_find_vap_node( - &vap->iv_ic->ic_sta, vap, eh->ether_dhost); - if (sta != NULL) { - if (ieee80211_node_is_authorized(sta)) { - /* - * Beware of sending to ourself; this - * needs to happen via the normal - * input path. - */ - if (sta != vap->iv_bss) { - mcopy = m; - m = NULL; - } - } else { - vap->iv_stats.is_rx_unauth++; - IEEE80211_NODE_STAT(sta, rx_unauth); - } - ieee80211_free_node(sta); - } - } - if (mcopy != NULL) { - int len, err; - len = mcopy->m_pkthdr.len; - err = ifp->if_transmit(ifp, mcopy); - if (err) { - /* NB: IFQ_HANDOFF reclaims mcopy */ - } else { - ifp->if_opackets++; - } - } - } - if (m != NULL) { - /* - * Mark frame as coming from vap's interface. - */ - m->m_pkthdr.rcvif = ifp; - if (m->m_flags & M_MCAST) { - /* - * Spam DWDS vap's w/ multicast traffic. - */ - /* XXX only if dwds in use? */ - ieee80211_dwds_mcast(vap, m); - } - if (ni->ni_vlan != 0) { - /* attach vlan tag */ - m->m_pkthdr.ether_vtag = ni->ni_vlan; - m->m_flags |= M_VLANTAG; - } - ifp->if_input(ifp, m); - } -} - -/* - * Decide if a received management frame should be - * printed when debugging is enabled. This filters some - * of the less interesting frames that come frequently - * (e.g. beacons). - */ -static __inline int -doprint(struct ieee80211vap *vap, int subtype) -{ - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_BEACON: - return (vap->iv_ic->ic_flags & IEEE80211_F_SCAN); - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - return 0; - } - return 1; -} - -/* - * Process a received frame. The node associated with the sender - * should be supplied. If nothing was found in the node table then - * the caller is assumed to supply a reference to iv_bss instead. - * The RSSI and a timestamp are also supplied. The RSSI data is used - * during AP scanning to select a AP to associate with; it can have - * any units so long as values have consistent units and higher values - * mean ``better signal''. The receive timestamp is currently not used - * by the 802.11 layer. - */ -static int -hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) -{ -#define HAS_SEQ(type) ((type & 0x4) == 0) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = vap->iv_ifp; - struct ieee80211_frame *wh; - struct ieee80211_key *key; - struct ether_header *eh; - int hdrspace, need_tap = 1; /* mbuf need to be tapped. */ - uint8_t dir, type, subtype, qos; - uint8_t *bssid; - uint16_t rxseq; - - if (m->m_flags & M_AMPDU_MPDU) { - /* - * Fastpath for A-MPDU reorder q resubmission. Frames - * w/ M_AMPDU_MPDU marked have already passed through - * here but were received out of order and been held on - * the reorder queue. When resubmitted they are marked - * with the M_AMPDU_MPDU flag and we can bypass most of - * the normal processing. - */ - wh = mtod(m, struct ieee80211_frame *); - type = IEEE80211_FC0_TYPE_DATA; - dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; - subtype = IEEE80211_FC0_SUBTYPE_QOS; - hdrspace = ieee80211_hdrspace(ic, wh); /* XXX optimize? */ - goto resubmit_ampdu; - } - - KASSERT(ni != NULL, ("null node")); - ni->ni_inact = ni->ni_inact_reload; - - type = -1; /* undefined */ - - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, - "too short (1): len %u", m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } - /* - * Bit of a cheat here, we use a pointer for a 3-address - * frame format but don't reference fields past outside - * ieee80211_frame_min w/o first validating the data is - * present. - */ - wh = mtod(m, struct ieee80211_frame *); - - if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != - IEEE80211_FC0_VERSION_0) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, "wrong version, fc %02x:%02x", - wh->i_fc[0], wh->i_fc[1]); - vap->iv_stats.is_rx_badversion++; - goto err; - } - - dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; - type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; - subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { - if (dir != IEEE80211_FC1_DIR_NODS) - bssid = wh->i_addr1; - else if (type == IEEE80211_FC0_TYPE_CTL) - bssid = wh->i_addr1; - else { - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_ANY, ni->ni_macaddr, - NULL, "too short (2): len %u", - m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } - bssid = wh->i_addr3; - } - /* - * Validate the bssid. - */ - if (!(type == IEEE80211_FC0_TYPE_MGT && - subtype == IEEE80211_FC0_SUBTYPE_BEACON) && - !IEEE80211_ADDR_EQ(bssid, vap->iv_bss->ni_bssid) && - !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) { - /* not interested in */ - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - bssid, NULL, "%s", "not to bss"); - vap->iv_stats.is_rx_wrongbss++; - goto out; - } - - IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = nf; - if (HAS_SEQ(type)) { - uint8_t tid = ieee80211_gettid(wh); - if (IEEE80211_QOS_HAS_SEQ(wh) && - TID_TO_WME_AC(tid) >= WME_AC_VI) - ic->ic_wme.wme_hipri_traffic++; - rxseq = le16toh(*(uint16_t *)wh->i_seq); - if (! ieee80211_check_rxseq(ni, wh)) { - /* duplicate, discard */ - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - bssid, "duplicate", - "seqno <%u,%u> fragno <%u,%u> tid %u", - rxseq >> IEEE80211_SEQ_SEQ_SHIFT, - ni->ni_rxseqs[tid] >> - IEEE80211_SEQ_SEQ_SHIFT, - rxseq & IEEE80211_SEQ_FRAG_MASK, - ni->ni_rxseqs[tid] & - IEEE80211_SEQ_FRAG_MASK, - tid); - vap->iv_stats.is_rx_dup++; - IEEE80211_NODE_STAT(ni, rx_dup); - goto out; - } - ni->ni_rxseqs[tid] = rxseq; - } - } - - switch (type) { - case IEEE80211_FC0_TYPE_DATA: - hdrspace = ieee80211_hdrspace(ic, wh); - if (m->m_len < hdrspace && - (m = m_pullup(m, hdrspace)) == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, - "data too short: expecting %u", hdrspace); - vap->iv_stats.is_rx_tooshort++; - goto out; /* XXX */ - } - if (!(dir == IEEE80211_FC1_DIR_TODS || - (dir == IEEE80211_FC1_DIR_DSTODS && - (vap->iv_flags & IEEE80211_F_DWDS)))) { - if (dir != IEEE80211_FC1_DIR_DSTODS) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_INPUT, wh, "data", - "incorrect dir 0x%x", dir); - } else { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_INPUT | - IEEE80211_MSG_WDS, wh, - "4-address data", - "%s", "DWDS not enabled"); - } - vap->iv_stats.is_rx_wrongdir++; - goto out; - } - /* check if source STA is associated */ - if (ni == vap->iv_bss) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "data", "%s", "unknown src"); - ieee80211_send_error(ni, wh->i_addr2, - IEEE80211_FC0_SUBTYPE_DEAUTH, - IEEE80211_REASON_NOT_AUTHED); - vap->iv_stats.is_rx_notassoc++; - goto err; - } - if (ni->ni_associd == 0) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "data", "%s", "unassoc src"); - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_DISASSOC, - IEEE80211_REASON_NOT_ASSOCED); - vap->iv_stats.is_rx_notassoc++; - goto err; - } - - /* - * Check for power save state change. - * XXX out-of-order A-MPDU frames? - */ - if (((wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) ^ - (ni->ni_flags & IEEE80211_NODE_PWR_MGT))) - ieee80211_node_pwrsave(ni, - wh->i_fc[1] & IEEE80211_FC1_PWR_MGT); - /* - * For 4-address packets handle WDS discovery - * notifications. Once a WDS link is setup frames - * are just delivered to the WDS vap (see below). - */ - if (dir == IEEE80211_FC1_DIR_DSTODS && ni->ni_wdsvap == NULL) { - if (!ieee80211_node_is_authorized(ni)) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_INPUT | - IEEE80211_MSG_WDS, wh, - "4-address data", - "%s", "unauthorized port"); - vap->iv_stats.is_rx_unauth++; - IEEE80211_NODE_STAT(ni, rx_unauth); - goto err; - } - ieee80211_dwds_discover(ni, m); - return type; - } - - /* - * Handle A-MPDU re-ordering. If the frame is to be - * processed directly then ieee80211_ampdu_reorder - * will return 0; otherwise it has consumed the mbuf - * and we should do nothing more with it. - */ - if ((m->m_flags & M_AMPDU) && - ieee80211_ampdu_reorder(ni, m) != 0) { - m = NULL; - goto out; - } - resubmit_ampdu: - - /* - * Handle privacy requirements. Note that we - * must not be preempted from here until after - * we (potentially) call ieee80211_crypto_demic; - * otherwise we may violate assumptions in the - * crypto cipher modules used to do delayed update - * of replay sequence numbers. - */ - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { - /* - * Discard encrypted frames when privacy is off. - */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "WEP", "%s", "PRIVACY off"); - vap->iv_stats.is_rx_noprivacy++; - IEEE80211_NODE_STAT(ni, rx_noprivacy); - goto out; - } - key = ieee80211_crypto_decap(ni, m, hdrspace); - if (key == NULL) { - /* NB: stats+msgs handled in crypto_decap */ - IEEE80211_NODE_STAT(ni, rx_wepfail); - goto out; - } - wh = mtod(m, struct ieee80211_frame *); - wh->i_fc[1] &= ~IEEE80211_FC1_WEP; - } else { - /* XXX M_WEP and IEEE80211_F_PRIVACY */ - key = NULL; - } - - /* - * Save QoS bits for use below--before we strip the header. - */ - if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { - qos = (dir == IEEE80211_FC1_DIR_DSTODS) ? - ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] : - ((struct ieee80211_qosframe *)wh)->i_qos[0]; - } else - qos = 0; - - /* - * Next up, any fragmentation. - */ - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - m = ieee80211_defrag(ni, m, hdrspace); - if (m == NULL) { - /* Fragment dropped or frame not complete yet */ - goto out; - } - } - wh = NULL; /* no longer valid, catch any uses */ - - /* - * Next strip any MSDU crypto bits. - */ - if (key != NULL && !ieee80211_crypto_demic(vap, key, m, 0)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - ni->ni_macaddr, "data", "%s", "demic error"); - vap->iv_stats.is_rx_demicfail++; - IEEE80211_NODE_STAT(ni, rx_demicfail); - goto out; - } - /* copy to listener after decrypt */ - if (ieee80211_radiotap_active_vap(vap)) - ieee80211_radiotap_rx(vap, m); - need_tap = 0; - /* - * Finally, strip the 802.11 header. - */ - m = ieee80211_decap(vap, m, hdrspace); - if (m == NULL) { - /* XXX mask bit to check for both */ - /* don't count Null data frames as errors */ - if (subtype == IEEE80211_FC0_SUBTYPE_NODATA || - subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL) - goto out; - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - ni->ni_macaddr, "data", "%s", "decap error"); - vap->iv_stats.is_rx_decap++; - IEEE80211_NODE_STAT(ni, rx_decap); - goto err; - } - eh = mtod(m, struct ether_header *); - if (!ieee80211_node_is_authorized(ni)) { - /* - * Deny any non-PAE frames received prior to - * authorization. For open/shared-key - * authentication the port is mark authorized - * after authentication completes. For 802.1x - * the port is not marked authorized by the - * authenticator until the handshake has completed. - */ - if (eh->ether_type != htons(ETHERTYPE_PAE)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - eh->ether_shost, "data", - "unauthorized port: ether type 0x%x len %u", - eh->ether_type, m->m_pkthdr.len); - vap->iv_stats.is_rx_unauth++; - IEEE80211_NODE_STAT(ni, rx_unauth); - goto err; - } - } else { - /* - * When denying unencrypted frames, discard - * any non-PAE frames received without encryption. - */ - if ((vap->iv_flags & IEEE80211_F_DROPUNENC) && - (key == NULL && (m->m_flags & M_WEP) == 0) && - eh->ether_type != htons(ETHERTYPE_PAE)) { - /* - * Drop unencrypted frames. - */ - vap->iv_stats.is_rx_unencrypted++; - IEEE80211_NODE_STAT(ni, rx_unencrypted); - goto out; - } - } - /* XXX require HT? */ - if (qos & IEEE80211_QOS_AMSDU) { - m = ieee80211_decap_amsdu(ni, m); - if (m == NULL) - return IEEE80211_FC0_TYPE_DATA; - } else { -#ifdef IEEE80211_SUPPORT_SUPERG - m = ieee80211_decap_fastframe(vap, ni, m); - if (m == NULL) - return IEEE80211_FC0_TYPE_DATA; -#endif - } - if (dir == IEEE80211_FC1_DIR_DSTODS && ni->ni_wdsvap != NULL) - ieee80211_deliver_data(ni->ni_wdsvap, ni, m); - else - hostap_deliver_data(vap, ni, m); - return IEEE80211_FC0_TYPE_DATA; - - case IEEE80211_FC0_TYPE_MGT: - vap->iv_stats.is_rx_mgmt++; - IEEE80211_NODE_STAT(ni, rx_mgmt); - if (dir != IEEE80211_FC1_DIR_NODS) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "mgt", "incorrect dir 0x%x", dir); - vap->iv_stats.is_rx_wrongdir++; - goto err; - } - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, "mgt", "too short: len %u", - m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } - if (IEEE80211_IS_MULTICAST(wh->i_addr2)) { - /* ensure return frames are unicast */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, NULL, "source is multicast: %s", - ether_sprintf(wh->i_addr2)); - vap->iv_stats.is_rx_mgtdiscard++; /* XXX stat */ - goto out; - } -#ifdef IEEE80211_DEBUG - if ((ieee80211_msg_debug(vap) && doprint(vap, subtype)) || - ieee80211_msg_dumppkts(vap)) { - if_printf(ifp, "received %s from %s rssi %d\n", - ieee80211_mgt_subtype_name[subtype >> - IEEE80211_FC0_SUBTYPE_SHIFT], - ether_sprintf(wh->i_addr2), rssi); - } -#endif - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - if (subtype != IEEE80211_FC0_SUBTYPE_AUTH) { - /* - * Only shared key auth frames with a challenge - * should be encrypted, discard all others. - */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, - "%s", "WEP set but not permitted"); - vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ - goto out; - } - if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { - /* - * Discard encrypted frames when privacy is off. - */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "WEP set but PRIVACY off"); - vap->iv_stats.is_rx_noprivacy++; - goto out; - } - hdrspace = ieee80211_hdrspace(ic, wh); - key = ieee80211_crypto_decap(ni, m, hdrspace); - if (key == NULL) { - /* NB: stats+msgs handled in crypto_decap */ - goto out; - } - wh = mtod(m, struct ieee80211_frame *); - wh->i_fc[1] &= ~IEEE80211_FC1_WEP; - } - /* - * Pass the packet to radiotap before calling iv_recv_mgmt(). - * Otherwise iv_recv_mgmt() might pass another packet to - * radiotap, resulting in out of order packet captures. - */ - if (ieee80211_radiotap_active_vap(vap)) - ieee80211_radiotap_rx(vap, m); - need_tap = 0; - vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); - goto out; - - case IEEE80211_FC0_TYPE_CTL: - vap->iv_stats.is_rx_ctl++; - IEEE80211_NODE_STAT(ni, rx_ctrl); - vap->iv_recv_ctl(ni, m, subtype); - goto out; - default: - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "bad", "frame type 0x%x", type); - /* should not come here */ - break; - } -err: - ifp->if_ierrors++; -out: - if (m != NULL) { - if (need_tap && ieee80211_radiotap_active_vap(vap)) - ieee80211_radiotap_rx(vap, m); - m_freem(m); - } - return type; -} - -static void -hostap_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh, - int rssi, int nf, uint16_t seq, uint16_t status) -{ - struct ieee80211vap *vap = ni->ni_vap; - - KASSERT(vap->iv_state == IEEE80211_S_RUN, ("state %d", vap->iv_state)); - - if (ni->ni_authmode == IEEE80211_AUTH_SHARED) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "open auth", - "bad sta auth mode %u", ni->ni_authmode); - vap->iv_stats.is_rx_bad_auth++; /* XXX */ - /* - * Clear any challenge text that may be there if - * a previous shared key auth failed and then an - * open auth is attempted. - */ - if (ni->ni_challenge != NULL) { - free(ni->ni_challenge, M_80211_NODE); - ni->ni_challenge = NULL; - } - /* XXX hack to workaround calling convention */ - ieee80211_send_error(ni, wh->i_addr2, - IEEE80211_FC0_SUBTYPE_AUTH, - (seq + 1) | (IEEE80211_STATUS_ALG<<16)); - return; - } - if (seq != IEEE80211_AUTH_OPEN_REQUEST) { - vap->iv_stats.is_rx_bad_auth++; - return; - } - /* always accept open authentication requests */ - if (ni == vap->iv_bss) { - ni = ieee80211_dup_bss(vap, wh->i_addr2); - if (ni == NULL) - return; - } else if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) - (void) ieee80211_ref_node(ni); - /* - * Mark the node as referenced to reflect that it's - * reference count has been bumped to insure it remains - * after the transaction completes. - */ - ni->ni_flags |= IEEE80211_NODE_AREF; - /* - * Mark the node as requiring a valid association id - * before outbound traffic is permitted. - */ - ni->ni_flags |= IEEE80211_NODE_ASSOCID; - - if (vap->iv_acl != NULL && - vap->iv_acl->iac_getpolicy(vap) == IEEE80211_MACCMD_POLICY_RADIUS) { - /* - * When the ACL policy is set to RADIUS we defer the - * authorization to a user agent. Dispatch an event, - * a subsequent MLME call will decide the fate of the - * station. If the user agent is not present then the - * node will be reclaimed due to inactivity. - */ - IEEE80211_NOTE_MAC(vap, - IEEE80211_MSG_AUTH | IEEE80211_MSG_ACL, ni->ni_macaddr, - "%s", "station authentication defered (radius acl)"); - ieee80211_notify_node_auth(ni); - } else { - IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); - IEEE80211_NOTE_MAC(vap, - IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, ni->ni_macaddr, - "%s", "station authenticated (open)"); - /* - * When 802.1x is not in use mark the port - * authorized at this point so traffic can flow. - */ - if (ni->ni_authmode != IEEE80211_AUTH_8021X) - ieee80211_node_authorize(ni); - } -} - -static void -hostap_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh, - uint8_t *frm, uint8_t *efrm, int rssi, int nf, - uint16_t seq, uint16_t status) -{ - struct ieee80211vap *vap = ni->ni_vap; - uint8_t *challenge; - int allocbs, estatus; - - KASSERT(vap->iv_state == IEEE80211_S_RUN, ("state %d", vap->iv_state)); - - /* - * NB: this can happen as we allow pre-shared key - * authentication to be enabled w/o wep being turned - * on so that configuration of these can be done - * in any order. It may be better to enforce the - * ordering in which case this check would just be - * for sanity/consistency. - */ - if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key auth", - "%s", " PRIVACY is disabled"); - estatus = IEEE80211_STATUS_ALG; - goto bad; - } - /* - * Pre-shared key authentication is evil; accept - * it only if explicitly configured (it is supported - * mainly for compatibility with clients like Mac OS X). - */ - if (ni->ni_authmode != IEEE80211_AUTH_AUTO && - ni->ni_authmode != IEEE80211_AUTH_SHARED) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key auth", - "bad sta auth mode %u", ni->ni_authmode); - vap->iv_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */ - estatus = IEEE80211_STATUS_ALG; - goto bad; - } - - challenge = NULL; - if (frm + 1 < efrm) { - if ((frm[1] + 2) > (efrm - frm)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key auth", - "ie %d/%d too long", - frm[0], (frm[1] + 2) - (efrm - frm)); - vap->iv_stats.is_rx_bad_auth++; - estatus = IEEE80211_STATUS_CHALLENGE; - goto bad; - } - if (*frm == IEEE80211_ELEMID_CHALLENGE) - challenge = frm; - frm += frm[1] + 2; - } - switch (seq) { - case IEEE80211_AUTH_SHARED_CHALLENGE: - case IEEE80211_AUTH_SHARED_RESPONSE: - if (challenge == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key auth", - "%s", "no challenge"); - vap->iv_stats.is_rx_bad_auth++; - estatus = IEEE80211_STATUS_CHALLENGE; - goto bad; - } - if (challenge[1] != IEEE80211_CHALLENGE_LEN) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key auth", - "bad challenge len %d", challenge[1]); - vap->iv_stats.is_rx_bad_auth++; - estatus = IEEE80211_STATUS_CHALLENGE; - goto bad; - } - default: - break; - } - switch (seq) { - case IEEE80211_AUTH_SHARED_REQUEST: - if (ni == vap->iv_bss) { - ni = ieee80211_dup_bss(vap, wh->i_addr2); - if (ni == NULL) { - /* NB: no way to return an error */ - return; - } - allocbs = 1; - } else { - if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) - (void) ieee80211_ref_node(ni); - allocbs = 0; - } - /* - * Mark the node as referenced to reflect that it's - * reference count has been bumped to insure it remains - * after the transaction completes. - */ - ni->ni_flags |= IEEE80211_NODE_AREF; - /* - * Mark the node as requiring a valid associatio id - * before outbound traffic is permitted. - */ - ni->ni_flags |= IEEE80211_NODE_ASSOCID; - IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = nf; - if (!ieee80211_alloc_challenge(ni)) { - /* NB: don't return error so they rexmit */ - return; - } - get_random_bytes(ni->ni_challenge, - IEEE80211_CHALLENGE_LEN); - IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, - ni, "shared key %sauth request", allocbs ? "" : "re"); - /* - * When the ACL policy is set to RADIUS we defer the - * authorization to a user agent. Dispatch an event, - * a subsequent MLME call will decide the fate of the - * station. If the user agent is not present then the - * node will be reclaimed due to inactivity. - */ - if (vap->iv_acl != NULL && - vap->iv_acl->iac_getpolicy(vap) == IEEE80211_MACCMD_POLICY_RADIUS) { - IEEE80211_NOTE_MAC(vap, - IEEE80211_MSG_AUTH | IEEE80211_MSG_ACL, - ni->ni_macaddr, - "%s", "station authentication defered (radius acl)"); - ieee80211_notify_node_auth(ni); - return; - } - break; - case IEEE80211_AUTH_SHARED_RESPONSE: - if (ni == vap->iv_bss) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key response", - "%s", "unknown station"); - /* NB: don't send a response */ - return; - } - if (ni->ni_challenge == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key response", - "%s", "no challenge recorded"); - vap->iv_stats.is_rx_bad_auth++; - estatus = IEEE80211_STATUS_CHALLENGE; - goto bad; - } - if (memcmp(ni->ni_challenge, &challenge[2], - challenge[1]) != 0) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key response", - "%s", "challenge mismatch"); - vap->iv_stats.is_rx_auth_fail++; - estatus = IEEE80211_STATUS_CHALLENGE; - goto bad; - } - IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, - ni, "%s", "station authenticated (shared key)"); - ieee80211_node_authorize(ni); - break; - default: - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key auth", - "bad seq %d", seq); - vap->iv_stats.is_rx_bad_auth++; - estatus = IEEE80211_STATUS_SEQUENCE; - goto bad; - } - IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); - return; -bad: - /* - * Send an error response; but only when operating as an AP. - */ - /* XXX hack to workaround calling convention */ - ieee80211_send_error(ni, wh->i_addr2, - IEEE80211_FC0_SUBTYPE_AUTH, - (seq + 1) | (estatus<<16)); -} - -/* - * Convert a WPA cipher selector OUI to an internal - * cipher algorithm. Where appropriate we also - * record any key length. - */ -static int -wpa_cipher(const uint8_t *sel, uint8_t *keylen) -{ -#define WPA_SEL(x) (((x)<<24)|WPA_OUI) - uint32_t w = LE_READ_4(sel); - - switch (w) { - case WPA_SEL(WPA_CSE_NULL): - return IEEE80211_CIPHER_NONE; - case WPA_SEL(WPA_CSE_WEP40): - if (keylen) - *keylen = 40 / NBBY; - return IEEE80211_CIPHER_WEP; - case WPA_SEL(WPA_CSE_WEP104): - if (keylen) - *keylen = 104 / NBBY; - return IEEE80211_CIPHER_WEP; - case WPA_SEL(WPA_CSE_TKIP): - return IEEE80211_CIPHER_TKIP; - case WPA_SEL(WPA_CSE_CCMP): - return IEEE80211_CIPHER_AES_CCM; - } - return 32; /* NB: so 1<< is discarded */ -#undef WPA_SEL -} - -/* - * Convert a WPA key management/authentication algorithm - * to an internal code. - */ -static int -wpa_keymgmt(const uint8_t *sel) -{ -#define WPA_SEL(x) (((x)<<24)|WPA_OUI) - uint32_t w = LE_READ_4(sel); - - switch (w) { - case WPA_SEL(WPA_ASE_8021X_UNSPEC): - return WPA_ASE_8021X_UNSPEC; - case WPA_SEL(WPA_ASE_8021X_PSK): - return WPA_ASE_8021X_PSK; - case WPA_SEL(WPA_ASE_NONE): - return WPA_ASE_NONE; - } - return 0; /* NB: so is discarded */ -#undef WPA_SEL -} - -/* - * Parse a WPA information element to collect parameters. - * Note that we do not validate security parameters; that - * is handled by the authenticator; the parsing done here - * is just for internal use in making operational decisions. - */ -static int -ieee80211_parse_wpa(struct ieee80211vap *vap, const uint8_t *frm, - struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh) -{ - uint8_t len = frm[1]; - uint32_t w; - int n; - - /* - * Check the length once for fixed parts: OUI, type, - * version, mcast cipher, and 2 selector counts. - * Other, variable-length data, must be checked separately. - */ - if ((vap->iv_flags & IEEE80211_F_WPA1) == 0) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, - wh, "WPA", "not WPA, flags 0x%x", vap->iv_flags); - return IEEE80211_REASON_IE_INVALID; - } - if (len < 14) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, - wh, "WPA", "too short, len %u", len); - return IEEE80211_REASON_IE_INVALID; - } - frm += 6, len -= 4; /* NB: len is payload only */ - /* NB: iswpaoui already validated the OUI and type */ - w = LE_READ_2(frm); - if (w != WPA_VERSION) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, - wh, "WPA", "bad version %u", w); - return IEEE80211_REASON_IE_INVALID; - } - frm += 2, len -= 2; - - memset(rsn, 0, sizeof(*rsn)); - - /* multicast/group cipher */ - rsn->rsn_mcastcipher = wpa_cipher(frm, &rsn->rsn_mcastkeylen); - frm += 4, len -= 4; - - /* unicast ciphers */ - n = LE_READ_2(frm); - frm += 2, len -= 2; - if (len < n*4+2) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, - wh, "WPA", "ucast cipher data too short; len %u, n %u", - len, n); - return IEEE80211_REASON_IE_INVALID; - } - w = 0; - for (; n > 0; n--) { - w |= 1<rsn_ucastkeylen); - frm += 4, len -= 4; - } - if (w & (1<rsn_ucastcipher = IEEE80211_CIPHER_TKIP; - else - rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM; - - /* key management algorithms */ - n = LE_READ_2(frm); - frm += 2, len -= 2; - if (len < n*4) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, - wh, "WPA", "key mgmt alg data too short; len %u, n %u", - len, n); - return IEEE80211_REASON_IE_INVALID; - } - w = 0; - for (; n > 0; n--) { - w |= wpa_keymgmt(frm); - frm += 4, len -= 4; - } - if (w & WPA_ASE_8021X_UNSPEC) - rsn->rsn_keymgmt = WPA_ASE_8021X_UNSPEC; - else - rsn->rsn_keymgmt = WPA_ASE_8021X_PSK; - - if (len > 2) /* optional capabilities */ - rsn->rsn_caps = LE_READ_2(frm); - - return 0; -} - -/* - * Convert an RSN cipher selector OUI to an internal - * cipher algorithm. Where appropriate we also - * record any key length. - */ -static int -rsn_cipher(const uint8_t *sel, uint8_t *keylen) -{ -#define RSN_SEL(x) (((x)<<24)|RSN_OUI) - uint32_t w = LE_READ_4(sel); - - switch (w) { - case RSN_SEL(RSN_CSE_NULL): - return IEEE80211_CIPHER_NONE; - case RSN_SEL(RSN_CSE_WEP40): - if (keylen) - *keylen = 40 / NBBY; - return IEEE80211_CIPHER_WEP; - case RSN_SEL(RSN_CSE_WEP104): - if (keylen) - *keylen = 104 / NBBY; - return IEEE80211_CIPHER_WEP; - case RSN_SEL(RSN_CSE_TKIP): - return IEEE80211_CIPHER_TKIP; - case RSN_SEL(RSN_CSE_CCMP): - return IEEE80211_CIPHER_AES_CCM; - case RSN_SEL(RSN_CSE_WRAP): - return IEEE80211_CIPHER_AES_OCB; - } - return 32; /* NB: so 1<< is discarded */ -#undef WPA_SEL -} - -/* - * Convert an RSN key management/authentication algorithm - * to an internal code. - */ -static int -rsn_keymgmt(const uint8_t *sel) -{ -#define RSN_SEL(x) (((x)<<24)|RSN_OUI) - uint32_t w = LE_READ_4(sel); - - switch (w) { - case RSN_SEL(RSN_ASE_8021X_UNSPEC): - return RSN_ASE_8021X_UNSPEC; - case RSN_SEL(RSN_ASE_8021X_PSK): - return RSN_ASE_8021X_PSK; - case RSN_SEL(RSN_ASE_NONE): - return RSN_ASE_NONE; - } - return 0; /* NB: so is discarded */ -#undef RSN_SEL -} - -/* - * Parse a WPA/RSN information element to collect parameters - * and validate the parameters against what has been - * configured for the system. - */ -static int -ieee80211_parse_rsn(struct ieee80211vap *vap, const uint8_t *frm, - struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh) -{ - uint8_t len = frm[1]; - uint32_t w; - int n; - - /* - * Check the length once for fixed parts: - * version, mcast cipher, and 2 selector counts. - * Other, variable-length data, must be checked separately. - */ - if ((vap->iv_flags & IEEE80211_F_WPA2) == 0) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, - wh, "WPA", "not RSN, flags 0x%x", vap->iv_flags); - return IEEE80211_REASON_IE_INVALID; - } - if (len < 10) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, - wh, "RSN", "too short, len %u", len); - return IEEE80211_REASON_IE_INVALID; - } - frm += 2; - w = LE_READ_2(frm); - if (w != RSN_VERSION) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, - wh, "RSN", "bad version %u", w); - return IEEE80211_REASON_IE_INVALID; - } - frm += 2, len -= 2; - - memset(rsn, 0, sizeof(*rsn)); - - /* multicast/group cipher */ - rsn->rsn_mcastcipher = rsn_cipher(frm, &rsn->rsn_mcastkeylen); - frm += 4, len -= 4; - - /* unicast ciphers */ - n = LE_READ_2(frm); - frm += 2, len -= 2; - if (len < n*4+2) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, - wh, "RSN", "ucast cipher data too short; len %u, n %u", - len, n); - return IEEE80211_REASON_IE_INVALID; - } - w = 0; - for (; n > 0; n--) { - w |= 1<rsn_ucastkeylen); - frm += 4, len -= 4; - } - if (w & (1<rsn_ucastcipher = IEEE80211_CIPHER_TKIP; - else - rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM; - - /* key management algorithms */ - n = LE_READ_2(frm); - frm += 2, len -= 2; - if (len < n*4) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, - wh, "RSN", "key mgmt alg data too short; len %u, n %u", - len, n); - return IEEE80211_REASON_IE_INVALID; - } - w = 0; - for (; n > 0; n--) { - w |= rsn_keymgmt(frm); - frm += 4, len -= 4; - } - if (w & RSN_ASE_8021X_UNSPEC) - rsn->rsn_keymgmt = RSN_ASE_8021X_UNSPEC; - else - rsn->rsn_keymgmt = RSN_ASE_8021X_PSK; - - /* optional RSN capabilities */ - if (len > 2) - rsn->rsn_caps = LE_READ_2(frm); - /* XXXPMKID */ - - return 0; -} - -/* - * WPA/802.11i assocation request processing. - */ -static int -wpa_assocreq(struct ieee80211_node *ni, struct ieee80211_rsnparms *rsnparms, - const struct ieee80211_frame *wh, const uint8_t *wpa, - const uint8_t *rsn, uint16_t capinfo) -{ - struct ieee80211vap *vap = ni->ni_vap; - uint8_t reason; - int badwparsn; - - ni->ni_flags &= ~(IEEE80211_NODE_WPS|IEEE80211_NODE_TSN); - if (wpa == NULL && rsn == NULL) { - if (vap->iv_flags_ext & IEEE80211_FEXT_WPS) { - /* - * W-Fi Protected Setup (WPS) permits - * clients to associate and pass EAPOL frames - * to establish initial credentials. - */ - ni->ni_flags |= IEEE80211_NODE_WPS; - return 1; - } - if ((vap->iv_flags_ext & IEEE80211_FEXT_TSN) && - (capinfo & IEEE80211_CAPINFO_PRIVACY)) { - /* - * Transitional Security Network. Permits clients - * to associate and use WEP while WPA is configured. - */ - ni->ni_flags |= IEEE80211_NODE_TSN; - return 1; - } - IEEE80211_DISCARD(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, - wh, NULL, "%s", "no WPA/RSN IE in association request"); - vap->iv_stats.is_rx_assoc_badwpaie++; - reason = IEEE80211_REASON_IE_INVALID; - goto bad; - } - /* assert right association security credentials */ - badwparsn = 0; /* NB: to silence compiler */ - switch (vap->iv_flags & IEEE80211_F_WPA) { - case IEEE80211_F_WPA1: - badwparsn = (wpa == NULL); - break; - case IEEE80211_F_WPA2: - badwparsn = (rsn == NULL); - break; - case IEEE80211_F_WPA1|IEEE80211_F_WPA2: - badwparsn = (wpa == NULL && rsn == NULL); - break; - } - if (badwparsn) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, - wh, NULL, - "%s", "missing WPA/RSN IE in association request"); - vap->iv_stats.is_rx_assoc_badwpaie++; - reason = IEEE80211_REASON_IE_INVALID; - goto bad; - } - /* - * Parse WPA/RSN information element. - */ - if (wpa != NULL) - reason = ieee80211_parse_wpa(vap, wpa, rsnparms, wh); - else - reason = ieee80211_parse_rsn(vap, rsn, rsnparms, wh); - if (reason != 0) { - /* XXX distinguish WPA/RSN? */ - vap->iv_stats.is_rx_assoc_badwpaie++; - goto bad; - } - IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, ni, - "%s ie: mc %u/%u uc %u/%u key %u caps 0x%x", - wpa != NULL ? "WPA" : "RSN", - rsnparms->rsn_mcastcipher, rsnparms->rsn_mcastkeylen, - rsnparms->rsn_ucastcipher, rsnparms->rsn_ucastkeylen, - rsnparms->rsn_keymgmt, rsnparms->rsn_caps); - - return 1; -bad: - ieee80211_node_deauth(ni, reason); - return 0; -} - -/* XXX find a better place for definition */ -struct l2_update_frame { - struct ether_header eh; - uint8_t dsap; - uint8_t ssap; - uint8_t control; - uint8_t xid[3]; -} __packed; - -/* - * Deliver a TGf L2UF frame on behalf of a station. - * This primes any bridge when the station is roaming - * between ap's on the same wired network. - */ -static void -ieee80211_deliver_l2uf(struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ifnet *ifp = vap->iv_ifp; - struct mbuf *m; - struct l2_update_frame *l2uf; - struct ether_header *eh; - - m = m_gethdr(M_NOWAIT, MT_DATA); - if (m == NULL) { - IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, - "%s", "no mbuf for l2uf frame"); - vap->iv_stats.is_rx_nobuf++; /* XXX not right */ - return; - } - l2uf = mtod(m, struct l2_update_frame *); - eh = &l2uf->eh; - /* dst: Broadcast address */ - IEEE80211_ADDR_COPY(eh->ether_dhost, ifp->if_broadcastaddr); - /* src: associated STA */ - IEEE80211_ADDR_COPY(eh->ether_shost, ni->ni_macaddr); - eh->ether_type = htons(sizeof(*l2uf) - sizeof(*eh)); - - l2uf->dsap = 0; - l2uf->ssap = 0; - l2uf->control = 0xf5; - l2uf->xid[0] = 0x81; - l2uf->xid[1] = 0x80; - l2uf->xid[2] = 0x00; - - m->m_pkthdr.len = m->m_len = sizeof(*l2uf); - hostap_deliver_data(vap, ni, m); -} - -static void -ratesetmismatch(struct ieee80211_node *ni, const struct ieee80211_frame *wh, - int reassoc, int resp, const char *tag, int rate) -{ - IEEE80211_NOTE_MAC(ni->ni_vap, IEEE80211_MSG_ANY, wh->i_addr2, - "deny %s request, %s rate set mismatch, rate/MCS %d", - reassoc ? "reassoc" : "assoc", tag, rate & IEEE80211_RATE_VAL); - IEEE80211_SEND_MGMT(ni, resp, IEEE80211_STATUS_BASIC_RATE); - ieee80211_node_leave(ni); -} - -static void -capinfomismatch(struct ieee80211_node *ni, const struct ieee80211_frame *wh, - int reassoc, int resp, const char *tag, int capinfo) -{ - struct ieee80211vap *vap = ni->ni_vap; - - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY, wh->i_addr2, - "deny %s request, %s mismatch 0x%x", - reassoc ? "reassoc" : "assoc", tag, capinfo); - IEEE80211_SEND_MGMT(ni, resp, IEEE80211_STATUS_CAPINFO); - ieee80211_node_leave(ni); - vap->iv_stats.is_rx_assoc_capmismatch++; -} - -static void -htcapmismatch(struct ieee80211_node *ni, const struct ieee80211_frame *wh, - int reassoc, int resp) -{ - IEEE80211_NOTE_MAC(ni->ni_vap, IEEE80211_MSG_ANY, wh->i_addr2, - "deny %s request, %s missing HT ie", reassoc ? "reassoc" : "assoc"); - /* XXX no better code */ - IEEE80211_SEND_MGMT(ni, resp, IEEE80211_STATUS_MISSING_HT_CAPS); - ieee80211_node_leave(ni); -} - -static void -authalgreject(struct ieee80211_node *ni, const struct ieee80211_frame *wh, - int algo, int seq, int status) -{ - struct ieee80211vap *vap = ni->ni_vap; - - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, NULL, "unsupported alg %d", algo); - vap->iv_stats.is_rx_auth_unsupported++; - ieee80211_send_error(ni, wh->i_addr2, IEEE80211_FC0_SUBTYPE_AUTH, - seq | (status << 16)); -} - -static __inline int -ishtmixed(const uint8_t *ie) -{ - const struct ieee80211_ie_htinfo *ht = - (const struct ieee80211_ie_htinfo *) ie; - return (ht->hi_byte2 & IEEE80211_HTINFO_OPMODE) == - IEEE80211_HTINFO_OPMODE_MIXED; -} - -static int -is11bclient(const uint8_t *rates, const uint8_t *xrates) -{ - static const uint32_t brates = (1<<2*1)|(1<<2*2)|(1<<11)|(1<<2*11); - int i; - - /* NB: the 11b clients we care about will not have xrates */ - if (xrates != NULL || rates == NULL) - return 0; - for (i = 0; i < rates[1]; i++) { - int r = rates[2+i] & IEEE80211_RATE_VAL; - if (r > 2*11 || ((1<ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_frame *wh; - uint8_t *frm, *efrm, *sfrm; - uint8_t *ssid, *rates, *xrates, *wpa, *rsn, *wme, *ath, *htcap; - int reassoc, resp; - uint8_t rate; - - wh = mtod(m0, struct ieee80211_frame *); - frm = (uint8_t *)&wh[1]; - efrm = mtod(m0, uint8_t *) + m0->m_len; - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - case IEEE80211_FC0_SUBTYPE_BEACON: { - struct ieee80211_scanparams scan; - /* - * We process beacon/probe response frames when scanning; - * otherwise we check beacon frames for overlapping non-ERP - * BSS in 11g and/or overlapping legacy BSS when in HT. - */ - if ((ic->ic_flags & IEEE80211_F_SCAN) == 0 && - subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) { - vap->iv_stats.is_rx_mgtdiscard++; - return; - } - /* NB: accept off-channel frames */ - if (ieee80211_parse_beacon(ni, m0, &scan) &~ IEEE80211_BPARSE_OFFCHAN) - return; - /* - * Count frame now that we know it's to be processed. - */ - if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) { - vap->iv_stats.is_rx_beacon++; /* XXX remove */ - IEEE80211_NODE_STAT(ni, rx_beacons); - } else - IEEE80211_NODE_STAT(ni, rx_proberesp); - /* - * If scanning, just pass information to the scan module. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) { - if (scan.status == 0 && /* NB: on channel */ - (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN)) { - /* - * Actively scanning a channel marked passive; - * send a probe request now that we know there - * is 802.11 traffic present. - * - * XXX check if the beacon we recv'd gives - * us what we need and suppress the probe req - */ - ieee80211_probe_curchan(vap, 1); - ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; - } - ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf); - return; - } - /* - * Check beacon for overlapping bss w/ non ERP stations. - * If we detect one and protection is configured but not - * enabled, enable it and start a timer that'll bring us - * out if we stop seeing the bss. - */ - if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) && - scan.status == 0 && /* NB: on-channel */ - ((scan.erp & 0x100) == 0 || /* NB: no ERP, 11b sta*/ - (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) { - ic->ic_lastnonerp = ticks; - ic->ic_flags_ext |= IEEE80211_FEXT_NONERP_PR; - if (ic->ic_protmode != IEEE80211_PROT_NONE && - (ic->ic_flags & IEEE80211_F_USEPROT) == 0) { - IEEE80211_NOTE_FRAME(vap, - IEEE80211_MSG_ASSOC, wh, - "non-ERP present on channel %d " - "(saw erp 0x%x from channel %d), " - "enable use of protection", - ic->ic_curchan->ic_ieee, - scan.erp, scan.chan); - ic->ic_flags |= IEEE80211_F_USEPROT; - ieee80211_notify_erp(ic); - } - } - /* - * Check beacon for non-HT station on HT channel - * and update HT BSS occupancy as appropriate. - */ - if (IEEE80211_IS_CHAN_HT(ic->ic_curchan)) { - if (scan.status & IEEE80211_BPARSE_OFFCHAN) { - /* - * Off control channel; only check frames - * that come in the extension channel when - * operating w/ HT40. - */ - if (!IEEE80211_IS_CHAN_HT40(ic->ic_curchan)) - break; - if (scan.chan != ic->ic_curchan->ic_extieee) - break; - } - if (scan.htinfo == NULL) { - ieee80211_htprot_update(ic, - IEEE80211_HTINFO_OPMODE_PROTOPT | - IEEE80211_HTINFO_NONHT_PRESENT); - } else if (ishtmixed(scan.htinfo)) { - /* XXX? take NONHT_PRESENT from beacon? */ - ieee80211_htprot_update(ic, - IEEE80211_HTINFO_OPMODE_MIXED | - IEEE80211_HTINFO_NONHT_PRESENT); - } - } - break; - } - - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - if (vap->iv_state != IEEE80211_S_RUN) { - vap->iv_stats.is_rx_mgtdiscard++; - return; - } - /* - * prreq frame format - * [tlv] ssid - * [tlv] supported rates - * [tlv] extended supported rates - */ - ssid = rates = xrates = NULL; - sfrm = frm; - while (efrm - frm > 1) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); - switch (*frm) { - case IEEE80211_ELEMID_SSID: - ssid = frm; - break; - case IEEE80211_ELEMID_RATES: - rates = frm; - break; - case IEEE80211_ELEMID_XRATES: - xrates = frm; - break; - } - frm += frm[1] + 2; - } - IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return); - if (xrates != NULL) - IEEE80211_VERIFY_ELEMENT(xrates, - IEEE80211_RATE_MAXSIZE - rates[1], return); - IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN, return); - IEEE80211_VERIFY_SSID(vap->iv_bss, ssid, return); - if ((vap->iv_flags & IEEE80211_F_HIDESSID) && ssid[1] == 0) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, - "%s", "no ssid with ssid suppression enabled"); - vap->iv_stats.is_rx_ssidmismatch++; /*XXX*/ - return; - } - - /* XXX find a better class or define it's own */ - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2, - "%s", "recv probe req"); - /* - * Some legacy 11b clients cannot hack a complete - * probe response frame. When the request includes - * only a bare-bones rate set, communicate this to - * the transmit side. - */ - ieee80211_send_proberesp(vap, wh->i_addr2, - is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0); - break; - - case IEEE80211_FC0_SUBTYPE_AUTH: { - uint16_t algo, seq, status; - - if (vap->iv_state != IEEE80211_S_RUN) { - vap->iv_stats.is_rx_mgtdiscard++; - return; - } - if (!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bss->ni_bssid)) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, NULL, "%s", "wrong bssid"); - vap->iv_stats.is_rx_wrongbss++; /*XXX unique stat?*/ - return; - } - /* - * auth frame format - * [2] algorithm - * [2] sequence - * [2] status - * [tlv*] challenge - */ - IEEE80211_VERIFY_LENGTH(efrm - frm, 6, return); - algo = le16toh(*(uint16_t *)frm); - seq = le16toh(*(uint16_t *)(frm + 2)); - status = le16toh(*(uint16_t *)(frm + 4)); - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_AUTH, wh->i_addr2, - "recv auth frame with algorithm %d seq %d", algo, seq); - /* - * Consult the ACL policy module if setup. - */ - if (vap->iv_acl != NULL && - !vap->iv_acl->iac_check(vap, wh->i_addr2)) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_ACL, - wh, NULL, "%s", "disallowed by ACL"); - vap->iv_stats.is_rx_acl++; - ieee80211_send_error(ni, wh->i_addr2, - IEEE80211_FC0_SUBTYPE_AUTH, - (seq+1) | (IEEE80211_STATUS_UNSPECIFIED<<16)); - return; - } - if (vap->iv_flags & IEEE80211_F_COUNTERM) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_AUTH | IEEE80211_MSG_CRYPTO, - wh, NULL, "%s", "TKIP countermeasures enabled"); - vap->iv_stats.is_rx_auth_countermeasures++; - ieee80211_send_error(ni, wh->i_addr2, - IEEE80211_FC0_SUBTYPE_AUTH, - IEEE80211_REASON_MIC_FAILURE); - return; - } - if (algo == IEEE80211_AUTH_ALG_SHARED) - hostap_auth_shared(ni, wh, frm + 6, efrm, rssi, nf, - seq, status); - else if (algo == IEEE80211_AUTH_ALG_OPEN) - hostap_auth_open(ni, wh, rssi, nf, seq, status); - else if (algo == IEEE80211_AUTH_ALG_LEAP) { - authalgreject(ni, wh, algo, - seq+1, IEEE80211_STATUS_ALG); - return; - } else { - /* - * We assume that an unknown algorithm is the result - * of a decryption failure on a shared key auth frame; - * return a status code appropriate for that instead - * of IEEE80211_STATUS_ALG. - * - * NB: a seq# of 4 is intentional; the decrypted - * frame likely has a bogus seq value. - */ - authalgreject(ni, wh, algo, - 4, IEEE80211_STATUS_CHALLENGE); - return; - } - break; - } - - case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: { - uint16_t capinfo, lintval; - struct ieee80211_rsnparms rsnparms; - - if (vap->iv_state != IEEE80211_S_RUN) { - vap->iv_stats.is_rx_mgtdiscard++; - return; - } - if (!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bss->ni_bssid)) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, NULL, "%s", "wrong bssid"); - vap->iv_stats.is_rx_assoc_bss++; - return; - } - if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) { - reassoc = 1; - resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP; - } else { - reassoc = 0; - resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP; - } - if (ni == vap->iv_bss) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY, wh->i_addr2, - "deny %s request, sta not authenticated", - reassoc ? "reassoc" : "assoc"); - ieee80211_send_error(ni, wh->i_addr2, - IEEE80211_FC0_SUBTYPE_DEAUTH, - IEEE80211_REASON_ASSOC_NOT_AUTHED); - vap->iv_stats.is_rx_assoc_notauth++; - return; - } - - /* - * asreq frame format - * [2] capability information - * [2] listen interval - * [6*] current AP address (reassoc only) - * [tlv] ssid - * [tlv] supported rates - * [tlv] extended supported rates - * [tlv] WPA or RSN - * [tlv] HT capabilities - * [tlv] Atheros capabilities - */ - IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4), return); - capinfo = le16toh(*(uint16_t *)frm); frm += 2; - lintval = le16toh(*(uint16_t *)frm); frm += 2; - if (reassoc) - frm += 6; /* ignore current AP info */ - ssid = rates = xrates = wpa = rsn = wme = ath = htcap = NULL; - sfrm = frm; - while (efrm - frm > 1) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); - switch (*frm) { - case IEEE80211_ELEMID_SSID: - ssid = frm; - break; - case IEEE80211_ELEMID_RATES: - rates = frm; - break; - case IEEE80211_ELEMID_XRATES: - xrates = frm; - break; - case IEEE80211_ELEMID_RSN: - rsn = frm; - break; - case IEEE80211_ELEMID_HTCAP: - htcap = frm; - break; - case IEEE80211_ELEMID_VENDOR: - if (iswpaoui(frm)) - wpa = frm; - else if (iswmeinfo(frm)) - wme = frm; -#ifdef IEEE80211_SUPPORT_SUPERG - else if (isatherosoui(frm)) - ath = frm; -#endif - else if (vap->iv_flags_ht & IEEE80211_FHT_HTCOMPAT) { - if (ishtcapoui(frm) && htcap == NULL) - htcap = frm; - } - break; - } - frm += frm[1] + 2; - } - IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return); - if (xrates != NULL) - IEEE80211_VERIFY_ELEMENT(xrates, - IEEE80211_RATE_MAXSIZE - rates[1], return); - IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN, return); - IEEE80211_VERIFY_SSID(vap->iv_bss, ssid, return); - if (htcap != NULL) { - IEEE80211_VERIFY_LENGTH(htcap[1], - htcap[0] == IEEE80211_ELEMID_VENDOR ? - 4 + sizeof(struct ieee80211_ie_htcap)-2 : - sizeof(struct ieee80211_ie_htcap)-2, - return); /* XXX just NULL out? */ - } - - if ((vap->iv_flags & IEEE80211_F_WPA) && - !wpa_assocreq(ni, &rsnparms, wh, wpa, rsn, capinfo)) - return; - /* discard challenge after association */ - if (ni->ni_challenge != NULL) { - free(ni->ni_challenge, M_80211_NODE); - ni->ni_challenge = NULL; - } - /* NB: 802.11 spec says to ignore station's privacy bit */ - if ((capinfo & IEEE80211_CAPINFO_ESS) == 0) { - capinfomismatch(ni, wh, reassoc, resp, - "capability", capinfo); - return; - } - /* - * Disallow re-associate w/ invalid slot time setting. - */ - if (ni->ni_associd != 0 && - IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan) && - ((ni->ni_capinfo ^ capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME)) { - capinfomismatch(ni, wh, reassoc, resp, - "slot time", capinfo); - return; - } - rate = ieee80211_setup_rates(ni, rates, xrates, - IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | - IEEE80211_F_DONEGO | IEEE80211_F_DODEL); - if (rate & IEEE80211_RATE_BASIC) { - ratesetmismatch(ni, wh, reassoc, resp, "legacy", rate); - vap->iv_stats.is_rx_assoc_norate++; - return; - } - /* - * If constrained to 11g-only stations reject an - * 11b-only station. We cheat a bit here by looking - * at the max negotiated xmit rate and assuming anyone - * with a best rate <24Mb/s is an 11b station. - */ - if ((vap->iv_flags & IEEE80211_F_PUREG) && rate < 48) { - ratesetmismatch(ni, wh, reassoc, resp, "11g", rate); - vap->iv_stats.is_rx_assoc_norate++; - return; - } - /* - * Do HT rate set handling and setup HT node state. - */ - ni->ni_chan = vap->iv_bss->ni_chan; - if (IEEE80211_IS_CHAN_HT(ni->ni_chan) && htcap != NULL) { - rate = ieee80211_setup_htrates(ni, htcap, - IEEE80211_F_DOFMCS | IEEE80211_F_DONEGO | - IEEE80211_F_DOBRS); - if (rate & IEEE80211_RATE_BASIC) { - ratesetmismatch(ni, wh, reassoc, resp, - "HT", rate); - vap->iv_stats.is_ht_assoc_norate++; - return; - } - ieee80211_ht_node_init(ni); - ieee80211_ht_updatehtcap(ni, htcap); - } else if (ni->ni_flags & IEEE80211_NODE_HT) - ieee80211_ht_node_cleanup(ni); -#ifdef IEEE80211_SUPPORT_SUPERG - else if (ni->ni_ath_flags & IEEE80211_NODE_ATH) - ieee80211_ff_node_cleanup(ni); -#endif - /* - * Allow AMPDU operation only with unencrypted traffic - * or AES-CCM; the 11n spec only specifies these ciphers - * so permitting any others is undefined and can lead - * to interoperability problems. - */ - if ((ni->ni_flags & IEEE80211_NODE_HT) && - (((vap->iv_flags & IEEE80211_F_WPA) && - rsnparms.rsn_ucastcipher != IEEE80211_CIPHER_AES_CCM) || - (vap->iv_flags & (IEEE80211_F_WPA|IEEE80211_F_PRIVACY)) == IEEE80211_F_PRIVACY)) { - IEEE80211_NOTE(vap, - IEEE80211_MSG_ASSOC | IEEE80211_MSG_11N, ni, - "disallow HT use because WEP or TKIP requested, " - "capinfo 0x%x ucastcipher %d", capinfo, - rsnparms.rsn_ucastcipher); - ieee80211_ht_node_cleanup(ni); - vap->iv_stats.is_ht_assoc_downgrade++; - } - /* - * If constrained to 11n-only stations reject legacy stations. - */ - if ((vap->iv_flags_ht & IEEE80211_FHT_PUREN) && - (ni->ni_flags & IEEE80211_NODE_HT) == 0) { - htcapmismatch(ni, wh, reassoc, resp); - vap->iv_stats.is_ht_assoc_nohtcap++; - return; - } - IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = nf; - ni->ni_intval = lintval; - ni->ni_capinfo = capinfo; - ni->ni_fhdwell = vap->iv_bss->ni_fhdwell; - ni->ni_fhindex = vap->iv_bss->ni_fhindex; - /* - * Store the IEs. - * XXX maybe better to just expand - */ - if (ieee80211_ies_init(&ni->ni_ies, sfrm, efrm - sfrm)) { -#define setie(_ie, _off) ieee80211_ies_setie(ni->ni_ies, _ie, _off) - if (wpa != NULL) - setie(wpa_ie, wpa - sfrm); - if (rsn != NULL) - setie(rsn_ie, rsn - sfrm); - if (htcap != NULL) - setie(htcap_ie, htcap - sfrm); - if (wme != NULL) { - setie(wme_ie, wme - sfrm); - /* - * Mark node as capable of QoS. - */ - ni->ni_flags |= IEEE80211_NODE_QOS; - } else - ni->ni_flags &= ~IEEE80211_NODE_QOS; -#ifdef IEEE80211_SUPPORT_SUPERG - if (ath != NULL) { - setie(ath_ie, ath - sfrm); - /* - * Parse ATH station parameters. - */ - ieee80211_parse_ath(ni, ni->ni_ies.ath_ie); - } else -#endif - ni->ni_ath_flags = 0; -#undef setie - } else { - ni->ni_flags &= ~IEEE80211_NODE_QOS; - ni->ni_ath_flags = 0; - } - ieee80211_node_join(ni, resp); - ieee80211_deliver_l2uf(ni); - break; - } - - case IEEE80211_FC0_SUBTYPE_DEAUTH: - case IEEE80211_FC0_SUBTYPE_DISASSOC: { - uint16_t reason; - - if (vap->iv_state != IEEE80211_S_RUN || - /* NB: can happen when in promiscuous mode */ - !IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr)) { - vap->iv_stats.is_rx_mgtdiscard++; - break; - } - /* - * deauth/disassoc frame format - * [2] reason - */ - IEEE80211_VERIFY_LENGTH(efrm - frm, 2, return); - reason = le16toh(*(uint16_t *)frm); - if (subtype == IEEE80211_FC0_SUBTYPE_DEAUTH) { - vap->iv_stats.is_rx_deauth++; - IEEE80211_NODE_STAT(ni, rx_deauth); - } else { - vap->iv_stats.is_rx_disassoc++; - IEEE80211_NODE_STAT(ni, rx_disassoc); - } - IEEE80211_NOTE(vap, IEEE80211_MSG_AUTH, ni, - "recv %s (reason %d)", ieee80211_mgt_subtype_name[subtype >> - IEEE80211_FC0_SUBTYPE_SHIFT], reason); - if (ni != vap->iv_bss) - ieee80211_node_leave(ni); - break; - } - - case IEEE80211_FC0_SUBTYPE_ACTION: - case IEEE80211_FC0_SUBTYPE_ACTION_NOACK: - if (ni == vap->iv_bss) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "unknown node"); - vap->iv_stats.is_rx_mgtdiscard++; - } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) && - !IEEE80211_IS_MULTICAST(wh->i_addr1)) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not for us"); - vap->iv_stats.is_rx_mgtdiscard++; - } else if (vap->iv_state != IEEE80211_S_RUN) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "wrong state %s", - ieee80211_state_name[vap->iv_state]); - vap->iv_stats.is_rx_mgtdiscard++; - } else { - if (ieee80211_parse_action(ni, m0) == 0) - (void)ic->ic_recv_action(ni, wh, frm, efrm); - } - break; - - case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_ATIM: - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not handled"); - vap->iv_stats.is_rx_mgtdiscard++; - break; - - default: - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "mgt", "subtype 0x%x not handled", subtype); - vap->iv_stats.is_rx_badsubtype++; - break; - } -} - -static void -hostap_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype) -{ - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_PS_POLL: - hostap_recv_pspoll(ni, m); - break; - case IEEE80211_FC0_SUBTYPE_BAR: - ieee80211_recv_bar(ni, m); - break; - } -} - -/* - * Process a received ps-poll frame. - */ -static void -hostap_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m0) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_frame_min *wh; - struct ifnet *ifp; - struct mbuf *m; - uint16_t aid; - int qlen; - - wh = mtod(m0, struct ieee80211_frame_min *); - if (ni->ni_associd == 0) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG, - (struct ieee80211_frame *) wh, NULL, - "%s", "unassociated station"); - vap->iv_stats.is_ps_unassoc++; - IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DEAUTH, - IEEE80211_REASON_NOT_ASSOCED); - return; - } - - aid = le16toh(*(uint16_t *)wh->i_dur); - if (aid != ni->ni_associd) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG, - (struct ieee80211_frame *) wh, NULL, - "aid mismatch: sta aid 0x%x poll aid 0x%x", - ni->ni_associd, aid); - vap->iv_stats.is_ps_badaid++; - /* - * NB: We used to deauth the station but it turns out - * the Blackberry Curve 8230 (and perhaps other devices) - * sometimes send the wrong AID when WME is negotiated. - * Being more lenient here seems ok as we already check - * the station is associated and we only return frames - * queued for the station (i.e. we don't use the AID). - */ - return; - } - - /* Okay, take the first queued packet and put it out... */ - m = ieee80211_node_psq_dequeue(ni, &qlen); - if (m == NULL) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_POWER, wh->i_addr2, - "%s", "recv ps-poll, but queue empty"); - ieee80211_send_nulldata(ieee80211_ref_node(ni)); - vap->iv_stats.is_ps_qempty++; /* XXX node stat */ - if (vap->iv_set_tim != NULL) - vap->iv_set_tim(ni, 0); /* just in case */ - return; - } - /* - * If there are more packets, set the more packets bit - * in the packet dispatched to the station; otherwise - * turn off the TIM bit. - */ - if (qlen != 0) { - IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, - "recv ps-poll, send packet, %u still queued", qlen); - m->m_flags |= M_MORE_DATA; - } else { - IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, - "%s", "recv ps-poll, send packet, queue empty"); - if (vap->iv_set_tim != NULL) - vap->iv_set_tim(ni, 0); - } - m->m_flags |= M_PWR_SAV; /* bypass PS handling */ - - if (m->m_flags & M_ENCAP) - ifp = vap->iv_ic->ic_ifp; - else - ifp = vap->iv_ifp; - IF_ENQUEUE(&ifp->if_snd, m); - if_start(ifp); -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_hostap.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_hostap.h deleted file mode 100644 index f3ecd69704..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_hostap.h +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_HOSTAP_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_HOSTAP_H_ - -/* - * Hostap implementation definitions. - */ -void ieee80211_hostap_attach(struct ieee80211com *); -void ieee80211_hostap_detach(struct ieee80211com *); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_HOSTAP_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ht.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_ht.c deleted file mode 100644 index aef705957b..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ht.c +++ /dev/null @@ -1,2781 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifdef __FreeBSD__ -__FBSDID("$FreeBSD$"); -#endif - -/* - * IEEE 802.11n protocol support. - */ - -#include "opt_inet.h" -#include "opt_wlan.h" - -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include - -/* define here, used throughout file */ -#define MS(_v, _f) (((_v) & _f) >> _f##_S) -#define SM(_v, _f) (((_v) << _f##_S) & _f) - -const struct ieee80211_mcs_rates ieee80211_htrates[IEEE80211_HTRATE_MAXSIZE] = { - { 13, 14, 27, 30 }, /* MCS 0 */ - { 26, 29, 54, 60 }, /* MCS 1 */ - { 39, 43, 81, 90 }, /* MCS 2 */ - { 52, 58, 108, 120 }, /* MCS 3 */ - { 78, 87, 162, 180 }, /* MCS 4 */ - { 104, 116, 216, 240 }, /* MCS 5 */ - { 117, 130, 243, 270 }, /* MCS 6 */ - { 130, 144, 270, 300 }, /* MCS 7 */ - { 26, 29, 54, 60 }, /* MCS 8 */ - { 52, 58, 108, 120 }, /* MCS 9 */ - { 78, 87, 162, 180 }, /* MCS 10 */ - { 104, 116, 216, 240 }, /* MCS 11 */ - { 156, 173, 324, 360 }, /* MCS 12 */ - { 208, 231, 432, 480 }, /* MCS 13 */ - { 234, 260, 486, 540 }, /* MCS 14 */ - { 260, 289, 540, 600 }, /* MCS 15 */ - { 39, 43, 81, 90 }, /* MCS 16 */ - { 78, 87, 162, 180 }, /* MCS 17 */ - { 117, 130, 243, 270 }, /* MCS 18 */ - { 156, 173, 324, 360 }, /* MCS 19 */ - { 234, 260, 486, 540 }, /* MCS 20 */ - { 312, 347, 648, 720 }, /* MCS 21 */ - { 351, 390, 729, 810 }, /* MCS 22 */ - { 390, 433, 810, 900 }, /* MCS 23 */ - { 52, 58, 108, 120 }, /* MCS 24 */ - { 104, 116, 216, 240 }, /* MCS 25 */ - { 156, 173, 324, 360 }, /* MCS 26 */ - { 208, 231, 432, 480 }, /* MCS 27 */ - { 312, 347, 648, 720 }, /* MCS 28 */ - { 416, 462, 864, 960 }, /* MCS 29 */ - { 468, 520, 972, 1080 }, /* MCS 30 */ - { 520, 578, 1080, 1200 }, /* MCS 31 */ - { 0, 0, 12, 13 }, /* MCS 32 */ - { 78, 87, 162, 180 }, /* MCS 33 */ - { 104, 116, 216, 240 }, /* MCS 34 */ - { 130, 144, 270, 300 }, /* MCS 35 */ - { 117, 130, 243, 270 }, /* MCS 36 */ - { 156, 173, 324, 360 }, /* MCS 37 */ - { 195, 217, 405, 450 }, /* MCS 38 */ - { 104, 116, 216, 240 }, /* MCS 39 */ - { 130, 144, 270, 300 }, /* MCS 40 */ - { 130, 144, 270, 300 }, /* MCS 41 */ - { 156, 173, 324, 360 }, /* MCS 42 */ - { 182, 202, 378, 420 }, /* MCS 43 */ - { 182, 202, 378, 420 }, /* MCS 44 */ - { 208, 231, 432, 480 }, /* MCS 45 */ - { 156, 173, 324, 360 }, /* MCS 46 */ - { 195, 217, 405, 450 }, /* MCS 47 */ - { 195, 217, 405, 450 }, /* MCS 48 */ - { 234, 260, 486, 540 }, /* MCS 49 */ - { 273, 303, 567, 630 }, /* MCS 50 */ - { 273, 303, 567, 630 }, /* MCS 51 */ - { 312, 347, 648, 720 }, /* MCS 52 */ - { 130, 144, 270, 300 }, /* MCS 53 */ - { 156, 173, 324, 360 }, /* MCS 54 */ - { 182, 202, 378, 420 }, /* MCS 55 */ - { 156, 173, 324, 360 }, /* MCS 56 */ - { 182, 202, 378, 420 }, /* MCS 57 */ - { 208, 231, 432, 480 }, /* MCS 58 */ - { 234, 260, 486, 540 }, /* MCS 59 */ - { 208, 231, 432, 480 }, /* MCS 60 */ - { 234, 260, 486, 540 }, /* MCS 61 */ - { 260, 289, 540, 600 }, /* MCS 62 */ - { 260, 289, 540, 600 }, /* MCS 63 */ - { 286, 318, 594, 660 }, /* MCS 64 */ - { 195, 217, 405, 450 }, /* MCS 65 */ - { 234, 260, 486, 540 }, /* MCS 66 */ - { 273, 303, 567, 630 }, /* MCS 67 */ - { 234, 260, 486, 540 }, /* MCS 68 */ - { 273, 303, 567, 630 }, /* MCS 69 */ - { 312, 347, 648, 720 }, /* MCS 70 */ - { 351, 390, 729, 810 }, /* MCS 71 */ - { 312, 347, 648, 720 }, /* MCS 72 */ - { 351, 390, 729, 810 }, /* MCS 73 */ - { 390, 433, 810, 900 }, /* MCS 74 */ - { 390, 433, 810, 900 }, /* MCS 75 */ - { 429, 477, 891, 990 }, /* MCS 76 */ -}; - -#ifdef IEEE80211_AMPDU_AGE -static int ieee80211_ampdu_age = -1; /* threshold for ampdu reorder q (ms) */ -SYSCTL_PROC(_net_wlan, OID_AUTO, ampdu_age, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_ampdu_age, 0, ieee80211_sysctl_msecs_ticks, "I", - "AMPDU max reorder age (ms)"); -#endif - -static int ieee80211_recv_bar_ena = 1; -SYSCTL_INT(_net_wlan, OID_AUTO, recv_bar, CTLFLAG_RW, &ieee80211_recv_bar_ena, - 0, "BAR frame processing (ena/dis)"); - -static int ieee80211_addba_timeout = -1;/* timeout for ADDBA response */ -SYSCTL_PROC(_net_wlan, OID_AUTO, addba_timeout, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_addba_timeout, 0, ieee80211_sysctl_msecs_ticks, "I", - "ADDBA request timeout (ms)"); -static int ieee80211_addba_backoff = -1;/* backoff after max ADDBA requests */ -SYSCTL_PROC(_net_wlan, OID_AUTO, addba_backoff, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_addba_backoff, 0, ieee80211_sysctl_msecs_ticks, "I", - "ADDBA request backoff (ms)"); -static int ieee80211_addba_maxtries = 3;/* max ADDBA requests before backoff */ -SYSCTL_INT(_net_wlan, OID_AUTO, addba_maxtries, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_addba_maxtries, 0, "max ADDBA requests sent before backoff"); - -static int ieee80211_bar_timeout = -1; /* timeout waiting for BAR response */ -static int ieee80211_bar_maxtries = 50;/* max BAR requests before DELBA */ - -static ieee80211_recv_action_func ht_recv_action_ba_addba_request; -static ieee80211_recv_action_func ht_recv_action_ba_addba_response; -static ieee80211_recv_action_func ht_recv_action_ba_delba; -static ieee80211_recv_action_func ht_recv_action_ht_mimopwrsave; -static ieee80211_recv_action_func ht_recv_action_ht_txchwidth; - -static ieee80211_send_action_func ht_send_action_ba_addba; -static ieee80211_send_action_func ht_send_action_ba_delba; -static ieee80211_send_action_func ht_send_action_ht_txchwidth; - -void -ieee80211_ht_init(void) -{ - /* - * Setup HT parameters that depends on the clock frequency. - */ -#ifdef IEEE80211_AMPDU_AGE - ieee80211_ampdu_age = msecs_to_ticks(500); -#endif - ieee80211_addba_timeout = msecs_to_ticks(250); - ieee80211_addba_backoff = msecs_to_ticks(10*1000); - ieee80211_bar_timeout = msecs_to_ticks(250); - /* - * Register action frame handlers. - */ - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_BA, - IEEE80211_ACTION_BA_ADDBA_REQUEST, ht_recv_action_ba_addba_request); - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_BA, - IEEE80211_ACTION_BA_ADDBA_RESPONSE, ht_recv_action_ba_addba_response); - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_BA, - IEEE80211_ACTION_BA_DELBA, ht_recv_action_ba_delba); - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_HT, - IEEE80211_ACTION_HT_MIMOPWRSAVE, ht_recv_action_ht_mimopwrsave); - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_HT, - IEEE80211_ACTION_HT_TXCHWIDTH, ht_recv_action_ht_txchwidth); - - ieee80211_send_action_register(IEEE80211_ACTION_CAT_BA, - IEEE80211_ACTION_BA_ADDBA_REQUEST, ht_send_action_ba_addba); - ieee80211_send_action_register(IEEE80211_ACTION_CAT_BA, - IEEE80211_ACTION_BA_ADDBA_RESPONSE, ht_send_action_ba_addba); - ieee80211_send_action_register(IEEE80211_ACTION_CAT_BA, - IEEE80211_ACTION_BA_DELBA, ht_send_action_ba_delba); - ieee80211_send_action_register(IEEE80211_ACTION_CAT_HT, - IEEE80211_ACTION_HT_TXCHWIDTH, ht_send_action_ht_txchwidth); -} -SYSINIT(wlan_ht, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_ht_init, NULL); - -static int ieee80211_ampdu_enable(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap); -static int ieee80211_addba_request(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap, - int dialogtoken, int baparamset, int batimeout); -static int ieee80211_addba_response(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap, - int code, int baparamset, int batimeout); -static void ieee80211_addba_stop(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap); -static void null_addba_response_timeout(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap); - -static void ieee80211_bar_response(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap, int status); -static void ampdu_tx_stop(struct ieee80211_tx_ampdu *tap); -static void bar_stop_timer(struct ieee80211_tx_ampdu *tap); -static int ampdu_rx_start(struct ieee80211_node *, struct ieee80211_rx_ampdu *, - int baparamset, int batimeout, int baseqctl); -static void ampdu_rx_stop(struct ieee80211_node *, struct ieee80211_rx_ampdu *); - -void -ieee80211_ht_attach(struct ieee80211com *ic) -{ - /* setup default aggregation policy */ - ic->ic_recv_action = ieee80211_recv_action; - ic->ic_send_action = ieee80211_send_action; - ic->ic_ampdu_enable = ieee80211_ampdu_enable; - ic->ic_addba_request = ieee80211_addba_request; - ic->ic_addba_response = ieee80211_addba_response; - ic->ic_addba_response_timeout = null_addba_response_timeout; - ic->ic_addba_stop = ieee80211_addba_stop; - ic->ic_bar_response = ieee80211_bar_response; - ic->ic_ampdu_rx_start = ampdu_rx_start; - ic->ic_ampdu_rx_stop = ampdu_rx_stop; - - ic->ic_htprotmode = IEEE80211_PROT_RTSCTS; - ic->ic_curhtprotmode = IEEE80211_HTINFO_OPMODE_PURE; -} - -void -ieee80211_ht_detach(struct ieee80211com *ic) -{ -} - -void -ieee80211_ht_vattach(struct ieee80211vap *vap) -{ - - /* driver can override defaults */ - vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_8K; - vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_NA; - vap->iv_ampdu_limit = vap->iv_ampdu_rxmax; - vap->iv_amsdu_limit = vap->iv_htcaps & IEEE80211_HTCAP_MAXAMSDU; - /* tx aggregation traffic thresholds */ - vap->iv_ampdu_mintraffic[WME_AC_BK] = 128; - vap->iv_ampdu_mintraffic[WME_AC_BE] = 64; - vap->iv_ampdu_mintraffic[WME_AC_VO] = 32; - vap->iv_ampdu_mintraffic[WME_AC_VI] = 32; - - if (vap->iv_htcaps & IEEE80211_HTC_HT) { - /* - * Device is HT capable; enable all HT-related - * facilities by default. - * XXX these choices may be too aggressive. - */ - vap->iv_flags_ht |= IEEE80211_FHT_HT - | IEEE80211_FHT_HTCOMPAT - ; - if (vap->iv_htcaps & IEEE80211_HTCAP_SHORTGI20) - vap->iv_flags_ht |= IEEE80211_FHT_SHORTGI20; - /* XXX infer from channel list? */ - if (vap->iv_htcaps & IEEE80211_HTCAP_CHWIDTH40) { - vap->iv_flags_ht |= IEEE80211_FHT_USEHT40; - if (vap->iv_htcaps & IEEE80211_HTCAP_SHORTGI40) - vap->iv_flags_ht |= IEEE80211_FHT_SHORTGI40; - } - /* enable RIFS if capable */ - if (vap->iv_htcaps & IEEE80211_HTC_RIFS) - vap->iv_flags_ht |= IEEE80211_FHT_RIFS; - - /* NB: A-MPDU and A-MSDU rx are mandated, these are tx only */ - vap->iv_flags_ht |= IEEE80211_FHT_AMPDU_RX; - if (vap->iv_htcaps & IEEE80211_HTC_AMPDU) - vap->iv_flags_ht |= IEEE80211_FHT_AMPDU_TX; - vap->iv_flags_ht |= IEEE80211_FHT_AMSDU_RX; - if (vap->iv_htcaps & IEEE80211_HTC_AMSDU) - vap->iv_flags_ht |= IEEE80211_FHT_AMSDU_TX; - } - /* NB: disable default legacy WDS, too many issues right now */ - if (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY) - vap->iv_flags_ht &= ~IEEE80211_FHT_HT; -} - -void -ieee80211_ht_vdetach(struct ieee80211vap *vap) -{ -} - -static int -ht_getrate(struct ieee80211com *ic, int index, int mode, int ratetype) -{ - int mword, rate; - - mword = ieee80211_rate2media(ic, index | IEEE80211_RATE_MCS, mode); - if (IFM_SUBTYPE(mword) != IFM_IEEE80211_MCS) - return (0); - switch (ratetype) { - case 0: - rate = ieee80211_htrates[index].ht20_rate_800ns; - break; - case 1: - rate = ieee80211_htrates[index].ht20_rate_400ns; - break; - case 2: - rate = ieee80211_htrates[index].ht40_rate_800ns; - break; - default: - rate = ieee80211_htrates[index].ht40_rate_400ns; - break; - } - return (rate); -} - -static struct printranges { - int minmcs; - int maxmcs; - int txstream; - int ratetype; - int htcapflags; -} ranges[] = { - { 0, 7, 1, 0, 0 }, - { 8, 15, 2, 0, 0 }, - { 16, 23, 3, 0, 0 }, - { 24, 31, 4, 0, 0 }, - { 32, 0, 1, 2, IEEE80211_HTC_TXMCS32 }, - { 33, 38, 2, 0, IEEE80211_HTC_TXUNEQUAL }, - { 39, 52, 3, 0, IEEE80211_HTC_TXUNEQUAL }, - { 53, 76, 4, 0, IEEE80211_HTC_TXUNEQUAL }, - { 0, 0, 0, 0, 0 }, -}; - -static void -ht_rateprint(struct ieee80211com *ic, int mode, int ratetype) -{ - struct ifnet *ifp = ic->ic_ifp; - int minrate, maxrate; - struct printranges *range; - - for (range = ranges; range->txstream != 0; range++) { - if (ic->ic_txstream < range->txstream) - continue; - if (range->htcapflags && - (ic->ic_htcaps & range->htcapflags) == 0) - continue; - if (ratetype < range->ratetype) - continue; - minrate = ht_getrate(ic, range->minmcs, mode, ratetype); - maxrate = ht_getrate(ic, range->maxmcs, mode, ratetype); - if (range->maxmcs) { - if_printf(ifp, "MCS %d-%d: %d%sMbps - %d%sMbps\n", - range->minmcs, range->maxmcs, - minrate/2, ((minrate & 0x1) != 0 ? ".5" : ""), - maxrate/2, ((maxrate & 0x1) != 0 ? ".5" : "")); - } else { - if_printf(ifp, "MCS %d: %d%sMbps\n", range->minmcs, - minrate/2, ((minrate & 0x1) != 0 ? ".5" : "")); - } - } -} - -static void -ht_announce(struct ieee80211com *ic, int mode) -{ - struct ifnet *ifp = ic->ic_ifp; - const char *modestr = ieee80211_phymode_name[mode]; - - if_printf(ifp, "%s MCS 20MHz\n", modestr); - ht_rateprint(ic, mode, 0); - if (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20) { - if_printf(ifp, "%s MCS 20MHz SGI\n", modestr); - ht_rateprint(ic, mode, 1); - } - if (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) { - if_printf(ifp, "%s MCS 40MHz:\n", modestr); - ht_rateprint(ic, mode, 2); - } - if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) && - (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40)) { - if_printf(ifp, "%s MCS 40MHz SGI:\n", modestr); - ht_rateprint(ic, mode, 3); - } -} - -void -ieee80211_ht_announce(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - - if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA) || - isset(ic->ic_modecaps, IEEE80211_MODE_11NG)) - if_printf(ifp, "%dT%dR\n", ic->ic_txstream, ic->ic_rxstream); - if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA)) - ht_announce(ic, IEEE80211_MODE_11NA); - if (isset(ic->ic_modecaps, IEEE80211_MODE_11NG)) - ht_announce(ic, IEEE80211_MODE_11NG); -} - -static struct ieee80211_htrateset htrateset; - -const struct ieee80211_htrateset * -ieee80211_get_suphtrates(struct ieee80211com *ic, - const struct ieee80211_channel *c) -{ -#define ADDRATE(x) do { \ - htrateset.rs_rates[htrateset.rs_nrates] = x; \ - htrateset.rs_nrates++; \ -} while (0) - int i; - - memset(&htrateset, 0, sizeof(struct ieee80211_htrateset)); - for (i = 0; i < ic->ic_txstream * 8; i++) - ADDRATE(i); - if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) && - (ic->ic_htcaps & IEEE80211_HTC_TXMCS32)) - ADDRATE(i); - if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) { - if (ic->ic_txstream >= 2) { - for (i = 33; i <= 38; i++) - ADDRATE(i); - } - if (ic->ic_txstream >= 3) { - for (i = 39; i <= 52; i++) - ADDRATE(i); - } - if (ic->ic_txstream == 4) { - for (i = 53; i <= 76; i++) - ADDRATE(i); - } - } - return &htrateset; -#undef ADDRATE -} - -/* - * Receive processing. - */ - -/* - * Decap the encapsulated A-MSDU frames and dispatch all but - * the last for delivery. The last frame is returned for - * delivery via the normal path. - */ -struct mbuf * -ieee80211_decap_amsdu(struct ieee80211_node *ni, struct mbuf *m) -{ - struct ieee80211vap *vap = ni->ni_vap; - int framelen; - struct mbuf *n; - - /* discard 802.3 header inserted by ieee80211_decap */ - m_adj(m, sizeof(struct ether_header)); - - vap->iv_stats.is_amsdu_decap++; - - for (;;) { - /* - * Decap the first frame, bust it apart from the - * remainder and deliver. We leave the last frame - * delivery to the caller (for consistency with other - * code paths, could also do it here). - */ - m = ieee80211_decap1(m, &framelen); - if (m == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, "a-msdu", "%s", "decap failed"); - vap->iv_stats.is_amsdu_tooshort++; - return NULL; - } - if (m->m_pkthdr.len == framelen) - break; - n = m_split(m, framelen, M_NOWAIT); - if (n == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, "a-msdu", - "%s", "unable to split encapsulated frames"); - vap->iv_stats.is_amsdu_split++; - m_freem(m); /* NB: must reclaim */ - return NULL; - } - vap->iv_deliver_data(vap, ni, m); - - /* - * Remove frame contents; each intermediate frame - * is required to be aligned to a 4-byte boundary. - */ - m = n; - m_adj(m, roundup2(framelen, 4) - framelen); /* padding */ - } - return m; /* last delivered by caller */ -} - -/* - * Purge all frames in the A-MPDU re-order queue. - */ -static void -ampdu_rx_purge(struct ieee80211_rx_ampdu *rap) -{ - struct mbuf *m; - int i; - - for (i = 0; i < rap->rxa_wnd; i++) { - m = rap->rxa_m[i]; - if (m != NULL) { - rap->rxa_m[i] = NULL; - rap->rxa_qbytes -= m->m_pkthdr.len; - m_freem(m); - if (--rap->rxa_qframes == 0) - break; - } - } - KASSERT(rap->rxa_qbytes == 0 && rap->rxa_qframes == 0, - ("lost %u data, %u frames on ampdu rx q", - rap->rxa_qbytes, rap->rxa_qframes)); -} - -/* - * Start A-MPDU rx/re-order processing for the specified TID. - */ -static int -ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap, - int baparamset, int batimeout, int baseqctl) -{ - int bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ); - - if (rap->rxa_flags & IEEE80211_AGGR_RUNNING) { - /* - * AMPDU previously setup and not terminated with a DELBA, - * flush the reorder q's in case anything remains. - */ - ampdu_rx_purge(rap); - } - memset(rap, 0, sizeof(*rap)); - rap->rxa_wnd = (bufsiz == 0) ? - IEEE80211_AGGR_BAWMAX : min(bufsiz, IEEE80211_AGGR_BAWMAX); - rap->rxa_start = MS(baseqctl, IEEE80211_BASEQ_START); - rap->rxa_flags |= IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND; - - return 0; -} - -/* - * Stop A-MPDU rx processing for the specified TID. - */ -static void -ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap) -{ - - ampdu_rx_purge(rap); - rap->rxa_flags &= ~(IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND); -} - -/* - * Dispatch a frame from the A-MPDU reorder queue. The - * frame is fed back into ieee80211_input marked with an - * M_AMPDU_MPDU flag so it doesn't come back to us (it also - * permits ieee80211_input to optimize re-processing). - */ -static __inline void -ampdu_dispatch(struct ieee80211_node *ni, struct mbuf *m) -{ - m->m_flags |= M_AMPDU_MPDU; /* bypass normal processing */ - /* NB: rssi and noise are ignored w/ M_AMPDU_MPDU set */ - (void) ieee80211_input(ni, m, 0, 0); -} - -/* - * Dispatch as many frames as possible from the re-order queue. - * Frames will always be "at the front"; we process all frames - * up to the first empty slot in the window. On completion we - * cleanup state if there are still pending frames in the current - * BA window. We assume the frame at slot 0 is already handled - * by the caller; we always start at slot 1. - */ -static void -ampdu_rx_dispatch(struct ieee80211_rx_ampdu *rap, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct mbuf *m; - int i; - - /* flush run of frames */ - for (i = 1; i < rap->rxa_wnd; i++) { - m = rap->rxa_m[i]; - if (m == NULL) - break; - rap->rxa_m[i] = NULL; - rap->rxa_qbytes -= m->m_pkthdr.len; - rap->rxa_qframes--; - - ampdu_dispatch(ni, m); - } - /* - * If frames remain, copy the mbuf pointers down so - * they correspond to the offsets in the new window. - */ - if (rap->rxa_qframes != 0) { - int n = rap->rxa_qframes, j; - for (j = i+1; j < rap->rxa_wnd; j++) { - if (rap->rxa_m[j] != NULL) { - rap->rxa_m[j-i] = rap->rxa_m[j]; - rap->rxa_m[j] = NULL; - if (--n == 0) - break; - } - } - KASSERT(n == 0, ("lost %d frames", n)); - vap->iv_stats.is_ampdu_rx_copy += rap->rxa_qframes; - } - /* - * Adjust the start of the BA window to - * reflect the frames just dispatched. - */ - rap->rxa_start = IEEE80211_SEQ_ADD(rap->rxa_start, i); - vap->iv_stats.is_ampdu_rx_oor += i; -} - -#ifdef IEEE80211_AMPDU_AGE -/* - * Dispatch all frames in the A-MPDU re-order queue. - */ -static void -ampdu_rx_flush(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct mbuf *m; - int i; - - for (i = 0; i < rap->rxa_wnd; i++) { - m = rap->rxa_m[i]; - if (m == NULL) - continue; - rap->rxa_m[i] = NULL; - rap->rxa_qbytes -= m->m_pkthdr.len; - rap->rxa_qframes--; - vap->iv_stats.is_ampdu_rx_oor++; - - ampdu_dispatch(ni, m); - if (rap->rxa_qframes == 0) - break; - } -} -#endif /* IEEE80211_AMPDU_AGE */ - -/* - * Dispatch all frames in the A-MPDU re-order queue - * preceding the specified sequence number. This logic - * handles window moves due to a received MSDU or BAR. - */ -static void -ampdu_rx_flush_upto(struct ieee80211_node *ni, - struct ieee80211_rx_ampdu *rap, ieee80211_seq winstart) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct mbuf *m; - ieee80211_seq seqno; - int i; - - /* - * Flush any complete MSDU's with a sequence number lower - * than winstart. Gaps may exist. Note that we may actually - * dispatch frames past winstart if a run continues; this is - * an optimization that avoids having to do a separate pass - * to dispatch frames after moving the BA window start. - */ - seqno = rap->rxa_start; - for (i = 0; i < rap->rxa_wnd; i++) { - m = rap->rxa_m[i]; - if (m != NULL) { - rap->rxa_m[i] = NULL; - rap->rxa_qbytes -= m->m_pkthdr.len; - rap->rxa_qframes--; - vap->iv_stats.is_ampdu_rx_oor++; - - ampdu_dispatch(ni, m); - } else { - if (!IEEE80211_SEQ_BA_BEFORE(seqno, winstart)) - break; - } - seqno = IEEE80211_SEQ_INC(seqno); - } - /* - * If frames remain, copy the mbuf pointers down so - * they correspond to the offsets in the new window. - */ - if (rap->rxa_qframes != 0) { - int n = rap->rxa_qframes, j; - - /* NB: this loop assumes i > 0 and/or rxa_m[0] is NULL */ - KASSERT(rap->rxa_m[0] == NULL, - ("%s: BA window slot 0 occupied", __func__)); - for (j = i+1; j < rap->rxa_wnd; j++) { - if (rap->rxa_m[j] != NULL) { - rap->rxa_m[j-i] = rap->rxa_m[j]; - rap->rxa_m[j] = NULL; - if (--n == 0) - break; - } - } - KASSERT(n == 0, ("%s: lost %d frames, qframes %d off %d " - "BA win <%d:%d> winstart %d", - __func__, n, rap->rxa_qframes, i, rap->rxa_start, - IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), - winstart)); - vap->iv_stats.is_ampdu_rx_copy += rap->rxa_qframes; - } - /* - * Move the start of the BA window; we use the - * sequence number of the last MSDU that was - * passed up the stack+1 or winstart if stopped on - * a gap in the reorder buffer. - */ - rap->rxa_start = seqno; -} - -/* - * Process a received QoS data frame for an HT station. Handle - * A-MPDU reordering: if this frame is received out of order - * and falls within the BA window hold onto it. Otherwise if - * this frame completes a run, flush any pending frames. We - * return 1 if the frame is consumed. A 0 is returned if - * the frame should be processed normally by the caller. - */ -int -ieee80211_ampdu_reorder(struct ieee80211_node *ni, struct mbuf *m) -{ -#define IEEE80211_FC0_QOSDATA \ - (IEEE80211_FC0_TYPE_DATA|IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_VERSION_0) -#define PROCESS 0 /* caller should process frame */ -#define CONSUMED 1 /* frame consumed, caller does nothing */ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_qosframe *wh; - struct ieee80211_rx_ampdu *rap; - ieee80211_seq rxseq; - uint8_t tid; - int off; - - KASSERT((m->m_flags & (M_AMPDU | M_AMPDU_MPDU)) == M_AMPDU, - ("!a-mpdu or already re-ordered, flags 0x%x", m->m_flags)); - KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT sta")); - - /* NB: m_len known to be sufficient */ - wh = mtod(m, struct ieee80211_qosframe *); - if (wh->i_fc[0] != IEEE80211_FC0_QOSDATA) { - /* - * Not QoS data, shouldn't get here but just - * return it to the caller for processing. - */ - return PROCESS; - } - if (IEEE80211_IS_DSTODS(wh)) - tid = ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0]; - else - tid = wh->i_qos[0]; - tid &= IEEE80211_QOS_TID; - rap = &ni->ni_rx_ampdu[tid]; - if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0) { - /* - * No ADDBA request yet, don't touch. - */ - return PROCESS; - } - rxseq = le16toh(*(uint16_t *)wh->i_seq); - if ((rxseq & IEEE80211_SEQ_FRAG_MASK) != 0) { - /* - * Fragments are not allowed; toss. - */ - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr, - "A-MPDU", "fragment, rxseq 0x%x tid %u%s", rxseq, tid, - wh->i_fc[1] & IEEE80211_FC1_RETRY ? " (retransmit)" : ""); - vap->iv_stats.is_ampdu_rx_drop++; - IEEE80211_NODE_STAT(ni, rx_drop); - m_freem(m); - return CONSUMED; - } - rxseq >>= IEEE80211_SEQ_SEQ_SHIFT; - rap->rxa_nframes++; -again: - if (rxseq == rap->rxa_start) { - /* - * First frame in window. - */ - if (rap->rxa_qframes != 0) { - /* - * Dispatch as many packets as we can. - */ - KASSERT(rap->rxa_m[0] == NULL, ("unexpected dup")); - ampdu_dispatch(ni, m); - ampdu_rx_dispatch(rap, ni); - return CONSUMED; - } else { - /* - * In order; advance window and notify - * caller to dispatch directly. - */ - rap->rxa_start = IEEE80211_SEQ_INC(rxseq); - return PROCESS; - } - } - /* - * Frame is out of order; store if in the BA window. - */ - /* calculate offset in BA window */ - off = IEEE80211_SEQ_SUB(rxseq, rap->rxa_start); - if (off < rap->rxa_wnd) { - /* - * Common case (hopefully): in the BA window. - * Sec 9.10.7.6.2 a) (p.137) - */ -#ifdef IEEE80211_AMPDU_AGE - /* - * Check for frames sitting too long in the reorder queue. - * This should only ever happen if frames are not delivered - * without the sender otherwise notifying us (e.g. with a - * BAR to move the window). Typically this happens because - * of vendor bugs that cause the sequence number to jump. - * When this happens we get a gap in the reorder queue that - * leaves frame sitting on the queue until they get pushed - * out due to window moves. When the vendor does not send - * BAR this move only happens due to explicit packet sends - * - * NB: we only track the time of the oldest frame in the - * reorder q; this means that if we flush we might push - * frames that still "new"; if this happens then subsequent - * frames will result in BA window moves which cost something - * but is still better than a big throughput dip. - */ - if (rap->rxa_qframes != 0) { - /* XXX honor batimeout? */ - if (ticks - rap->rxa_age > ieee80211_ampdu_age) { - /* - * Too long since we received the first - * frame; flush the reorder buffer. - */ - if (rap->rxa_qframes != 0) { - vap->iv_stats.is_ampdu_rx_age += - rap->rxa_qframes; - ampdu_rx_flush(ni, rap); - } - rap->rxa_start = IEEE80211_SEQ_INC(rxseq); - return PROCESS; - } - } else { - /* - * First frame, start aging timer. - */ - rap->rxa_age = ticks; - } -#endif /* IEEE80211_AMPDU_AGE */ - /* save packet */ - if (rap->rxa_m[off] == NULL) { - rap->rxa_m[off] = m; - rap->rxa_qframes++; - rap->rxa_qbytes += m->m_pkthdr.len; - vap->iv_stats.is_ampdu_rx_reorder++; - } else { - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, - ni->ni_macaddr, "a-mpdu duplicate", - "seqno %u tid %u BA win <%u:%u>", - rxseq, tid, rap->rxa_start, - IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1)); - vap->iv_stats.is_rx_dup++; - IEEE80211_NODE_STAT(ni, rx_dup); - m_freem(m); - } - return CONSUMED; - } - if (off < IEEE80211_SEQ_BA_RANGE) { - /* - * Outside the BA window, but within range; - * flush the reorder q and move the window. - * Sec 9.10.7.6.2 b) (p.138) - */ - IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni, - "move BA win <%u:%u> (%u frames) rxseq %u tid %u", - rap->rxa_start, - IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), - rap->rxa_qframes, rxseq, tid); - vap->iv_stats.is_ampdu_rx_move++; - - /* - * The spec says to flush frames up to but not including: - * WinStart_B = rxseq - rap->rxa_wnd + 1 - * Then insert the frame or notify the caller to process - * it immediately. We can safely do this by just starting - * over again because we know the frame will now be within - * the BA window. - */ - /* NB: rxa_wnd known to be >0 */ - ampdu_rx_flush_upto(ni, rap, - IEEE80211_SEQ_SUB(rxseq, rap->rxa_wnd-1)); - goto again; - } else { - /* - * Outside the BA window and out of range; toss. - * Sec 9.10.7.6.2 c) (p.138) - */ - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr, - "MPDU", "BA win <%u:%u> (%u frames) rxseq %u tid %u%s", - rap->rxa_start, - IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), - rap->rxa_qframes, rxseq, tid, - wh->i_fc[1] & IEEE80211_FC1_RETRY ? " (retransmit)" : ""); - vap->iv_stats.is_ampdu_rx_drop++; - IEEE80211_NODE_STAT(ni, rx_drop); - m_freem(m); - return CONSUMED; - } -#undef CONSUMED -#undef PROCESS -#undef IEEE80211_FC0_QOSDATA -} - -/* - * Process a BAR ctl frame. Dispatch all frames up to - * the sequence number of the frame. If this frame is - * out of range it's discarded. - */ -void -ieee80211_recv_bar(struct ieee80211_node *ni, struct mbuf *m0) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_frame_bar *wh; - struct ieee80211_rx_ampdu *rap; - ieee80211_seq rxseq; - int tid, off; - - if (!ieee80211_recv_bar_ena) { -#if 0 - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_11N, - ni->ni_macaddr, "BAR", "%s", "processing disabled"); -#endif - vap->iv_stats.is_ampdu_bar_bad++; - return; - } - wh = mtod(m0, struct ieee80211_frame_bar *); - /* XXX check basic BAR */ - tid = MS(le16toh(wh->i_ctl), IEEE80211_BAR_TID); - rap = &ni->ni_rx_ampdu[tid]; - if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0) { - /* - * No ADDBA request yet, don't touch. - */ - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, - ni->ni_macaddr, "BAR", "no BA stream, tid %u", tid); - vap->iv_stats.is_ampdu_bar_bad++; - return; - } - vap->iv_stats.is_ampdu_bar_rx++; - rxseq = le16toh(wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT; - if (rxseq == rap->rxa_start) - return; - /* calculate offset in BA window */ - off = IEEE80211_SEQ_SUB(rxseq, rap->rxa_start); - if (off < IEEE80211_SEQ_BA_RANGE) { - /* - * Flush the reorder q up to rxseq and move the window. - * Sec 9.10.7.6.3 a) (p.138) - */ - IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni, - "BAR moves BA win <%u:%u> (%u frames) rxseq %u tid %u", - rap->rxa_start, - IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), - rap->rxa_qframes, rxseq, tid); - vap->iv_stats.is_ampdu_bar_move++; - - ampdu_rx_flush_upto(ni, rap, rxseq); - if (off >= rap->rxa_wnd) { - /* - * BAR specifies a window start to the right of BA - * window; we must move it explicitly since - * ampdu_rx_flush_upto will not. - */ - rap->rxa_start = rxseq; - } - } else { - /* - * Out of range; toss. - * Sec 9.10.7.6.3 b) (p.138) - */ - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr, - "BAR", "BA win <%u:%u> (%u frames) rxseq %u tid %u%s", - rap->rxa_start, - IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), - rap->rxa_qframes, rxseq, tid, - wh->i_fc[1] & IEEE80211_FC1_RETRY ? " (retransmit)" : ""); - vap->iv_stats.is_ampdu_bar_oow++; - IEEE80211_NODE_STAT(ni, rx_drop); - } -} - -/* - * Setup HT-specific state in a node. Called only - * when HT use is negotiated so we don't do extra - * work for temporary and/or legacy sta's. - */ -void -ieee80211_ht_node_init(struct ieee80211_node *ni) -{ - struct ieee80211_tx_ampdu *tap; - int ac; - - if (ni->ni_flags & IEEE80211_NODE_HT) { - /* - * Clean AMPDU state on re-associate. This handles the case - * where a station leaves w/o notifying us and then returns - * before node is reaped for inactivity. - */ - ieee80211_ht_node_cleanup(ni); - } - for (ac = 0; ac < WME_NUM_AC; ac++) { - tap = &ni->ni_tx_ampdu[ac]; - tap->txa_ac = ac; - tap->txa_ni = ni; - /* NB: further initialization deferred */ - } - ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU; -} - -/* - * Cleanup HT-specific state in a node. Called only - * when HT use has been marked. - */ -void -ieee80211_ht_node_cleanup(struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - int i; - - KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT node")); - - /* XXX optimize this */ - for (i = 0; i < WME_NUM_AC; i++) { - struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[i]; - if (tap->txa_flags & IEEE80211_AGGR_SETUP) - ampdu_tx_stop(tap); - } - for (i = 0; i < WME_NUM_TID; i++) - ic->ic_ampdu_rx_stop(ni, &ni->ni_rx_ampdu[i]); - - ni->ni_htcap = 0; - ni->ni_flags &= ~IEEE80211_NODE_HT_ALL; -} - -/* - * Age out HT resources for a station. - */ -void -ieee80211_ht_node_age(struct ieee80211_node *ni) -{ -#ifdef IEEE80211_AMPDU_AGE - struct ieee80211vap *vap = ni->ni_vap; - uint8_t tid; -#endif - - KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT sta")); - -#ifdef IEEE80211_AMPDU_AGE - for (tid = 0; tid < WME_NUM_TID; tid++) { - struct ieee80211_rx_ampdu *rap; - - rap = &ni->ni_rx_ampdu[tid]; - if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0) - continue; - if (rap->rxa_qframes == 0) - continue; - /* - * Check for frames sitting too long in the reorder queue. - * See above for more details on what's happening here. - */ - /* XXX honor batimeout? */ - if (ticks - rap->rxa_age > ieee80211_ampdu_age) { - /* - * Too long since we received the first - * frame; flush the reorder buffer. - */ - vap->iv_stats.is_ampdu_rx_age += rap->rxa_qframes; - ampdu_rx_flush(ni, rap); - } - } -#endif /* IEEE80211_AMPDU_AGE */ -} - -static struct ieee80211_channel * -findhtchan(struct ieee80211com *ic, struct ieee80211_channel *c, int htflags) -{ - return ieee80211_find_channel(ic, c->ic_freq, - (c->ic_flags &~ IEEE80211_CHAN_HT) | htflags); -} - -/* - * Adjust a channel to be HT/non-HT according to the vap's configuration. - */ -struct ieee80211_channel * -ieee80211_ht_adjust_channel(struct ieee80211com *ic, - struct ieee80211_channel *chan, int flags) -{ - struct ieee80211_channel *c; - - if (flags & IEEE80211_FHT_HT) { - /* promote to HT if possible */ - if (flags & IEEE80211_FHT_USEHT40) { - if (!IEEE80211_IS_CHAN_HT40(chan)) { - /* NB: arbitrarily pick ht40+ over ht40- */ - c = findhtchan(ic, chan, IEEE80211_CHAN_HT40U); - if (c == NULL) - c = findhtchan(ic, chan, - IEEE80211_CHAN_HT40D); - if (c == NULL) - c = findhtchan(ic, chan, - IEEE80211_CHAN_HT20); - if (c != NULL) - chan = c; - } - } else if (!IEEE80211_IS_CHAN_HT20(chan)) { - c = findhtchan(ic, chan, IEEE80211_CHAN_HT20); - if (c != NULL) - chan = c; - } - } else if (IEEE80211_IS_CHAN_HT(chan)) { - /* demote to legacy, HT use is disabled */ - c = ieee80211_find_channel(ic, chan->ic_freq, - chan->ic_flags &~ IEEE80211_CHAN_HT); - if (c != NULL) - chan = c; - } - return chan; -} - -/* - * Setup HT-specific state for a legacy WDS peer. - */ -void -ieee80211_ht_wds_init(struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_tx_ampdu *tap; - int ac; - - KASSERT(vap->iv_flags_ht & IEEE80211_FHT_HT, ("no HT requested")); - - /* XXX check scan cache in case peer has an ap and we have info */ - /* - * If setup with a legacy channel; locate an HT channel. - * Otherwise if the inherited channel (from a companion - * AP) is suitable use it so we use the same location - * for the extension channel). - */ - ni->ni_chan = ieee80211_ht_adjust_channel(ni->ni_ic, - ni->ni_chan, ieee80211_htchanflags(ni->ni_chan)); - - ni->ni_htcap = 0; - if (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) - ni->ni_htcap |= IEEE80211_HTCAP_SHORTGI20; - if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) { - ni->ni_htcap |= IEEE80211_HTCAP_CHWIDTH40; - ni->ni_chw = 40; - if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan)) - ni->ni_ht2ndchan = IEEE80211_HTINFO_2NDCHAN_ABOVE; - else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan)) - ni->ni_ht2ndchan = IEEE80211_HTINFO_2NDCHAN_BELOW; - if (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) - ni->ni_htcap |= IEEE80211_HTCAP_SHORTGI40; - } else { - ni->ni_chw = 20; - ni->ni_ht2ndchan = IEEE80211_HTINFO_2NDCHAN_NONE; - } - ni->ni_htctlchan = ni->ni_chan->ic_ieee; - if (vap->iv_flags_ht & IEEE80211_FHT_RIFS) - ni->ni_flags |= IEEE80211_NODE_RIFS; - /* XXX does it make sense to enable SMPS? */ - - ni->ni_htopmode = 0; /* XXX need protection state */ - ni->ni_htstbc = 0; /* XXX need info */ - - for (ac = 0; ac < WME_NUM_AC; ac++) { - tap = &ni->ni_tx_ampdu[ac]; - tap->txa_ac = ac; - } - /* NB: AMPDU tx/rx governed by IEEE80211_FHT_AMPDU_{TX,RX} */ - ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU; -} - -/* - * Notify hostap vaps of a change in the HTINFO ie. - */ -static void -htinfo_notify(struct ieee80211com *ic) -{ - struct ieee80211vap *vap; - int first = 1; - - IEEE80211_LOCK_ASSERT(ic); - - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - if (vap->iv_opmode != IEEE80211_M_HOSTAP) - continue; - if (vap->iv_state != IEEE80211_S_RUN || - !IEEE80211_IS_CHAN_HT(vap->iv_bss->ni_chan)) - continue; - if (first) { - IEEE80211_NOTE(vap, - IEEE80211_MSG_ASSOC | IEEE80211_MSG_11N, - vap->iv_bss, - "HT bss occupancy change: %d sta, %d ht, " - "%d ht40%s, HT protmode now 0x%x" - , ic->ic_sta_assoc - , ic->ic_ht_sta_assoc - , ic->ic_ht40_sta_assoc - , (ic->ic_flags_ht & IEEE80211_FHT_NONHT_PR) ? - ", non-HT sta present" : "" - , ic->ic_curhtprotmode); - first = 0; - } - ieee80211_beacon_notify(vap, IEEE80211_BEACON_HTINFO); - } -} - -/* - * Calculate HT protection mode from current - * state and handle updates. - */ -static void -htinfo_update(struct ieee80211com *ic) -{ - uint8_t protmode; - - if (ic->ic_sta_assoc != ic->ic_ht_sta_assoc) { - protmode = IEEE80211_HTINFO_OPMODE_MIXED - | IEEE80211_HTINFO_NONHT_PRESENT; - } else if (ic->ic_flags_ht & IEEE80211_FHT_NONHT_PR) { - protmode = IEEE80211_HTINFO_OPMODE_PROTOPT - | IEEE80211_HTINFO_NONHT_PRESENT; - } else if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && - IEEE80211_IS_CHAN_HT40(ic->ic_bsschan) && - ic->ic_sta_assoc != ic->ic_ht40_sta_assoc) { - protmode = IEEE80211_HTINFO_OPMODE_HT20PR; - } else { - protmode = IEEE80211_HTINFO_OPMODE_PURE; - } - if (protmode != ic->ic_curhtprotmode) { - ic->ic_curhtprotmode = protmode; - htinfo_notify(ic); - } -} - -/* - * Handle an HT station joining a BSS. - */ -void -ieee80211_ht_node_join(struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - - IEEE80211_LOCK_ASSERT(ic); - - if (ni->ni_flags & IEEE80211_NODE_HT) { - ic->ic_ht_sta_assoc++; - if (ni->ni_chw == 40) - ic->ic_ht40_sta_assoc++; - } - htinfo_update(ic); -} - -/* - * Handle an HT station leaving a BSS. - */ -void -ieee80211_ht_node_leave(struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - - IEEE80211_LOCK_ASSERT(ic); - - if (ni->ni_flags & IEEE80211_NODE_HT) { - ic->ic_ht_sta_assoc--; - if (ni->ni_chw == 40) - ic->ic_ht40_sta_assoc--; - } - htinfo_update(ic); -} - -/* - * Public version of htinfo_update; used for processing - * beacon frames from overlapping bss. - * - * Caller can specify either IEEE80211_HTINFO_OPMODE_MIXED - * (on receipt of a beacon that advertises MIXED) or - * IEEE80211_HTINFO_OPMODE_PROTOPT (on receipt of a beacon - * from an overlapping legacy bss). We treat MIXED with - * a higher precedence than PROTOPT (i.e. we will not change - * change PROTOPT -> MIXED; only MIXED -> PROTOPT). This - * corresponds to how we handle things in htinfo_update. - */ -void -ieee80211_htprot_update(struct ieee80211com *ic, int protmode) -{ -#define OPMODE(x) SM(x, IEEE80211_HTINFO_OPMODE) - IEEE80211_LOCK(ic); - - /* track non-HT station presence */ - KASSERT(protmode & IEEE80211_HTINFO_NONHT_PRESENT, - ("protmode 0x%x", protmode)); - ic->ic_flags_ht |= IEEE80211_FHT_NONHT_PR; - ic->ic_lastnonht = ticks; - - if (protmode != ic->ic_curhtprotmode && - (OPMODE(ic->ic_curhtprotmode) != IEEE80211_HTINFO_OPMODE_MIXED || - OPMODE(protmode) == IEEE80211_HTINFO_OPMODE_PROTOPT)) { - /* push beacon update */ - ic->ic_curhtprotmode = protmode; - htinfo_notify(ic); - } - IEEE80211_UNLOCK(ic); -#undef OPMODE -} - -/* - * Time out presence of an overlapping bss with non-HT - * stations. When operating in hostap mode we listen for - * beacons from other stations and if we identify a non-HT - * station is present we update the opmode field of the - * HTINFO ie. To identify when all non-HT stations are - * gone we time out this condition. - */ -void -ieee80211_ht_timeout(struct ieee80211com *ic) -{ - IEEE80211_LOCK_ASSERT(ic); - - if ((ic->ic_flags_ht & IEEE80211_FHT_NONHT_PR) && - time_after(ticks, ic->ic_lastnonht + IEEE80211_NONHT_PRESENT_AGE)) { -#if 0 - IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni, - "%s", "time out non-HT STA present on channel"); -#endif - ic->ic_flags_ht &= ~IEEE80211_FHT_NONHT_PR; - htinfo_update(ic); - } -} - -/* unalligned little endian access */ -#define LE_READ_2(p) \ - ((uint16_t) \ - ((((const uint8_t *)(p))[0] ) | \ - (((const uint8_t *)(p))[1] << 8))) - -/* - * Process an 802.11n HT capabilities ie. - */ -void -ieee80211_parse_htcap(struct ieee80211_node *ni, const uint8_t *ie) -{ - if (ie[0] == IEEE80211_ELEMID_VENDOR) { - /* - * Station used Vendor OUI ie to associate; - * mark the node so when we respond we'll use - * the Vendor OUI's and not the standard ie's. - */ - ni->ni_flags |= IEEE80211_NODE_HTCOMPAT; - ie += 4; - } else - ni->ni_flags &= ~IEEE80211_NODE_HTCOMPAT; - - ni->ni_htcap = LE_READ_2(ie + - __offsetof(struct ieee80211_ie_htcap, hc_cap)); - ni->ni_htparam = ie[__offsetof(struct ieee80211_ie_htcap, hc_param)]; -} - -static void -htinfo_parse(struct ieee80211_node *ni, - const struct ieee80211_ie_htinfo *htinfo) -{ - uint16_t w; - - ni->ni_htctlchan = htinfo->hi_ctrlchannel; - ni->ni_ht2ndchan = SM(htinfo->hi_byte1, IEEE80211_HTINFO_2NDCHAN); - w = LE_READ_2(&htinfo->hi_byte2); - ni->ni_htopmode = SM(w, IEEE80211_HTINFO_OPMODE); - w = LE_READ_2(&htinfo->hi_byte45); - ni->ni_htstbc = SM(w, IEEE80211_HTINFO_BASIC_STBCMCS); -} - -/* - * Parse an 802.11n HT info ie and save useful information - * to the node state. Note this does not effect any state - * changes such as for channel width change. - */ -void -ieee80211_parse_htinfo(struct ieee80211_node *ni, const uint8_t *ie) -{ - if (ie[0] == IEEE80211_ELEMID_VENDOR) - ie += 4; - htinfo_parse(ni, (const struct ieee80211_ie_htinfo *) ie); -} - -/* - * Handle 11n channel switch. Use the received HT ie's to - * identify the right channel to use. If we cannot locate it - * in the channel table then fallback to legacy operation. - * Note that we use this information to identify the node's - * channel only; the caller is responsible for insuring any - * required channel change is done (e.g. in sta mode when - * parsing the contents of a beacon frame). - */ -static void -htinfo_update_chw(struct ieee80211_node *ni, int htflags) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_channel *c; - int chanflags; - - chanflags = (ni->ni_chan->ic_flags &~ IEEE80211_CHAN_HT) | htflags; - if (chanflags != ni->ni_chan->ic_flags) { - /* XXX not right for ht40- */ - c = ieee80211_find_channel(ic, ni->ni_chan->ic_freq, chanflags); - if (c == NULL && (htflags & IEEE80211_CHAN_HT40)) { - /* - * No HT40 channel entry in our table; fall back - * to HT20 operation. This should not happen. - */ - c = findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT20); -#if 0 - IEEE80211_NOTE(ni->ni_vap, - IEEE80211_MSG_ASSOC | IEEE80211_MSG_11N, ni, - "no HT40 channel (freq %u), falling back to HT20", - ni->ni_chan->ic_freq); -#endif - /* XXX stat */ - } - if (c != NULL && c != ni->ni_chan) { - IEEE80211_NOTE(ni->ni_vap, - IEEE80211_MSG_ASSOC | IEEE80211_MSG_11N, ni, - "switch station to HT%d channel %u/0x%x", - IEEE80211_IS_CHAN_HT40(c) ? 40 : 20, - c->ic_freq, c->ic_flags); - ni->ni_chan = c; - } - /* NB: caller responsible for forcing any channel change */ - } - /* update node's tx channel width */ - ni->ni_chw = IEEE80211_IS_CHAN_HT40(ni->ni_chan)? 40 : 20; -} - -/* - * Update 11n MIMO PS state according to received htcap. - */ -static __inline int -htcap_update_mimo_ps(struct ieee80211_node *ni) -{ - uint16_t oflags = ni->ni_flags; - - switch (ni->ni_htcap & IEEE80211_HTCAP_SMPS) { - case IEEE80211_HTCAP_SMPS_DYNAMIC: - ni->ni_flags |= IEEE80211_NODE_MIMO_PS; - ni->ni_flags |= IEEE80211_NODE_MIMO_RTS; - break; - case IEEE80211_HTCAP_SMPS_ENA: - ni->ni_flags |= IEEE80211_NODE_MIMO_PS; - ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; - break; - case IEEE80211_HTCAP_SMPS_OFF: - default: /* disable on rx of reserved value */ - ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS; - ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; - break; - } - return (oflags ^ ni->ni_flags); -} - -/* - * Update short GI state according to received htcap - * and local settings. - */ -static __inline void -htcap_update_shortgi(struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - - ni->ni_flags &= ~(IEEE80211_NODE_SGI20|IEEE80211_NODE_SGI40); - if ((ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) && - (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20)) - ni->ni_flags |= IEEE80211_NODE_SGI20; - if ((ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) && - (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40)) - ni->ni_flags |= IEEE80211_NODE_SGI40; -} - -/* - * Parse and update HT-related state extracted from - * the HT cap and info ie's. - */ -void -ieee80211_ht_updateparams(struct ieee80211_node *ni, - const uint8_t *htcapie, const uint8_t *htinfoie) -{ - struct ieee80211vap *vap = ni->ni_vap; - const struct ieee80211_ie_htinfo *htinfo; - int htflags; - - ieee80211_parse_htcap(ni, htcapie); - if (vap->iv_htcaps & IEEE80211_HTCAP_SMPS) - htcap_update_mimo_ps(ni); - htcap_update_shortgi(ni); - - if (htinfoie[0] == IEEE80211_ELEMID_VENDOR) - htinfoie += 4; - htinfo = (const struct ieee80211_ie_htinfo *) htinfoie; - htinfo_parse(ni, htinfo); - - htflags = (vap->iv_flags_ht & IEEE80211_FHT_HT) ? - IEEE80211_CHAN_HT20 : 0; - /* NB: honor operating mode constraint */ - if ((htinfo->hi_byte1 & IEEE80211_HTINFO_TXWIDTH_2040) && - (vap->iv_flags_ht & IEEE80211_FHT_USEHT40)) { - if (ni->ni_ht2ndchan == IEEE80211_HTINFO_2NDCHAN_ABOVE) - htflags = IEEE80211_CHAN_HT40U; - else if (ni->ni_ht2ndchan == IEEE80211_HTINFO_2NDCHAN_BELOW) - htflags = IEEE80211_CHAN_HT40D; - } - htinfo_update_chw(ni, htflags); - - if ((htinfo->hi_byte1 & IEEE80211_HTINFO_RIFSMODE_PERM) && - (vap->iv_flags_ht & IEEE80211_FHT_RIFS)) - ni->ni_flags |= IEEE80211_NODE_RIFS; - else - ni->ni_flags &= ~IEEE80211_NODE_RIFS; -} - -/* - * Parse and update HT-related state extracted from the HT cap ie - * for a station joining an HT BSS. - */ -void -ieee80211_ht_updatehtcap(struct ieee80211_node *ni, const uint8_t *htcapie) -{ - struct ieee80211vap *vap = ni->ni_vap; - int htflags; - - ieee80211_parse_htcap(ni, htcapie); - if (vap->iv_htcaps & IEEE80211_HTCAP_SMPS) - htcap_update_mimo_ps(ni); - htcap_update_shortgi(ni); - - /* NB: honor operating mode constraint */ - /* XXX 40 MHz intolerant */ - htflags = (vap->iv_flags_ht & IEEE80211_FHT_HT) ? - IEEE80211_CHAN_HT20 : 0; - if ((ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) && - (vap->iv_flags_ht & IEEE80211_FHT_USEHT40)) { - if (IEEE80211_IS_CHAN_HT40U(vap->iv_bss->ni_chan)) - htflags = IEEE80211_CHAN_HT40U; - else if (IEEE80211_IS_CHAN_HT40D(vap->iv_bss->ni_chan)) - htflags = IEEE80211_CHAN_HT40D; - } - htinfo_update_chw(ni, htflags); -} - -/* - * Install received HT rate set by parsing the HT cap ie. - */ -int -ieee80211_setup_htrates(struct ieee80211_node *ni, const uint8_t *ie, int flags) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211vap *vap = ni->ni_vap; - const struct ieee80211_ie_htcap *htcap; - struct ieee80211_htrateset *rs; - int i, maxequalmcs, maxunequalmcs; - - maxequalmcs = ic->ic_txstream * 8 - 1; - if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) { - if (ic->ic_txstream >= 2) - maxunequalmcs = 38; - if (ic->ic_txstream >= 3) - maxunequalmcs = 52; - if (ic->ic_txstream >= 4) - maxunequalmcs = 76; - } else - maxunequalmcs = 0; - - rs = &ni->ni_htrates; - memset(rs, 0, sizeof(*rs)); - if (ie != NULL) { - if (ie[0] == IEEE80211_ELEMID_VENDOR) - ie += 4; - htcap = (const struct ieee80211_ie_htcap *) ie; - for (i = 0; i < IEEE80211_HTRATE_MAXSIZE; i++) { - if (isclr(htcap->hc_mcsset, i)) - continue; - if (rs->rs_nrates == IEEE80211_HTRATE_MAXSIZE) { - IEEE80211_NOTE(vap, - IEEE80211_MSG_XRATE | IEEE80211_MSG_11N, ni, - "WARNING, HT rate set too large; only " - "using %u rates", IEEE80211_HTRATE_MAXSIZE); - vap->iv_stats.is_rx_rstoobig++; - break; - } - if (i <= 31 && i > maxequalmcs) - continue; - if (i == 32 && - (ic->ic_htcaps & IEEE80211_HTC_TXMCS32) == 0) - continue; - if (i > 32 && i > maxunequalmcs) - continue; - rs->rs_rates[rs->rs_nrates++] = i; - } - } - return ieee80211_fix_rate(ni, (struct ieee80211_rateset *) rs, flags); -} - -/* - * Mark rates in a node's HT rate set as basic according - * to the information in the supplied HT info ie. - */ -void -ieee80211_setup_basic_htrates(struct ieee80211_node *ni, const uint8_t *ie) -{ - const struct ieee80211_ie_htinfo *htinfo; - struct ieee80211_htrateset *rs; - int i, j; - - if (ie[0] == IEEE80211_ELEMID_VENDOR) - ie += 4; - htinfo = (const struct ieee80211_ie_htinfo *) ie; - rs = &ni->ni_htrates; - if (rs->rs_nrates == 0) { - IEEE80211_NOTE(ni->ni_vap, - IEEE80211_MSG_XRATE | IEEE80211_MSG_11N, ni, - "%s", "WARNING, empty HT rate set"); - return; - } - for (i = 0; i < IEEE80211_HTRATE_MAXSIZE; i++) { - if (isclr(htinfo->hi_basicmcsset, i)) - continue; - for (j = 0; j < rs->rs_nrates; j++) - if ((rs->rs_rates[j] & IEEE80211_RATE_VAL) == i) - rs->rs_rates[j] |= IEEE80211_RATE_BASIC; - } -} - -static void -ampdu_tx_setup(struct ieee80211_tx_ampdu *tap) -{ - callout_init(&tap->txa_timer, CALLOUT_MPSAFE); - tap->txa_flags |= IEEE80211_AGGR_SETUP; -} - -static void -ampdu_tx_stop(struct ieee80211_tx_ampdu *tap) -{ - struct ieee80211_node *ni = tap->txa_ni; - struct ieee80211com *ic = ni->ni_ic; - - KASSERT(tap->txa_flags & IEEE80211_AGGR_SETUP, - ("txa_flags 0x%x ac %d", tap->txa_flags, tap->txa_ac)); - - /* - * Stop BA stream if setup so driver has a chance - * to reclaim any resources it might have allocated. - */ - ic->ic_addba_stop(ni, tap); - /* - * Stop any pending BAR transmit. - */ - bar_stop_timer(tap); - - tap->txa_lastsample = 0; - tap->txa_avgpps = 0; - /* NB: clearing NAK means we may re-send ADDBA */ - tap->txa_flags &= ~(IEEE80211_AGGR_SETUP | IEEE80211_AGGR_NAK); -} - -/* - * ADDBA response timeout. - * - * If software aggregation and per-TID queue management was done here, - * that queue would be unpaused after the ADDBA timeout occurs. - */ -static void -addba_timeout(void *arg) -{ - struct ieee80211_tx_ampdu *tap = arg; - struct ieee80211_node *ni = tap->txa_ni; - struct ieee80211com *ic = ni->ni_ic; - - /* XXX ? */ - tap->txa_flags &= ~IEEE80211_AGGR_XCHGPEND; - tap->txa_attempts++; - ic->ic_addba_response_timeout(ni, tap); -} - -static void -addba_start_timeout(struct ieee80211_tx_ampdu *tap) -{ - /* XXX use CALLOUT_PENDING instead? */ - callout_reset(&tap->txa_timer, ieee80211_addba_timeout, - addba_timeout, tap); - tap->txa_flags |= IEEE80211_AGGR_XCHGPEND; - tap->txa_nextrequest = ticks + ieee80211_addba_timeout; -} - -static void -addba_stop_timeout(struct ieee80211_tx_ampdu *tap) -{ - /* XXX use CALLOUT_PENDING instead? */ - if (tap->txa_flags & IEEE80211_AGGR_XCHGPEND) { - callout_stop(&tap->txa_timer); - tap->txa_flags &= ~IEEE80211_AGGR_XCHGPEND; - } -} - -static void -null_addba_response_timeout(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap) -{ -} - -/* - * Default method for requesting A-MPDU tx aggregation. - * We setup the specified state block and start a timer - * to wait for an ADDBA response frame. - */ -static int -ieee80211_addba_request(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap, - int dialogtoken, int baparamset, int batimeout) -{ - int bufsiz; - - /* XXX locking */ - tap->txa_token = dialogtoken; - tap->txa_flags |= IEEE80211_AGGR_IMMEDIATE; - bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ); - tap->txa_wnd = (bufsiz == 0) ? - IEEE80211_AGGR_BAWMAX : min(bufsiz, IEEE80211_AGGR_BAWMAX); - addba_start_timeout(tap); - return 1; -} - -/* - * Default method for processing an A-MPDU tx aggregation - * response. We shutdown any pending timer and update the - * state block according to the reply. - */ -static int -ieee80211_addba_response(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap, - int status, int baparamset, int batimeout) -{ - int bufsiz, tid; - - /* XXX locking */ - addba_stop_timeout(tap); - if (status == IEEE80211_STATUS_SUCCESS) { - bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ); - /* XXX override our request? */ - tap->txa_wnd = (bufsiz == 0) ? - IEEE80211_AGGR_BAWMAX : min(bufsiz, IEEE80211_AGGR_BAWMAX); - /* XXX AC/TID */ - tid = MS(baparamset, IEEE80211_BAPS_TID); - tap->txa_flags |= IEEE80211_AGGR_RUNNING; - tap->txa_attempts = 0; - } else { - /* mark tid so we don't try again */ - tap->txa_flags |= IEEE80211_AGGR_NAK; - } - return 1; -} - -/* - * Default method for stopping A-MPDU tx aggregation. - * Any timer is cleared and we drain any pending frames. - */ -static void -ieee80211_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) -{ - /* XXX locking */ - addba_stop_timeout(tap); - if (tap->txa_flags & IEEE80211_AGGR_RUNNING) { - /* XXX clear aggregation queue */ - tap->txa_flags &= ~IEEE80211_AGGR_RUNNING; - } - tap->txa_attempts = 0; -} - -/* - * Process a received action frame using the default aggregation - * policy. We intercept ADDBA-related frames and use them to - * update our aggregation state. All other frames are passed up - * for processing by ieee80211_recv_action. - */ -static int -ht_recv_action_ba_addba_request(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_rx_ampdu *rap; - uint8_t dialogtoken; - uint16_t baparamset, batimeout, baseqctl; - uint16_t args[5]; - int tid; - - dialogtoken = frm[2]; - baparamset = LE_READ_2(frm+3); - batimeout = LE_READ_2(frm+5); - baseqctl = LE_READ_2(frm+7); - - tid = MS(baparamset, IEEE80211_BAPS_TID); - - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "recv ADDBA request: dialogtoken %u baparamset 0x%x " - "(tid %d bufsiz %d) batimeout %d baseqctl %d:%d", - dialogtoken, baparamset, - tid, MS(baparamset, IEEE80211_BAPS_BUFSIZ), - batimeout, - MS(baseqctl, IEEE80211_BASEQ_START), - MS(baseqctl, IEEE80211_BASEQ_FRAG)); - - rap = &ni->ni_rx_ampdu[tid]; - - /* Send ADDBA response */ - args[0] = dialogtoken; - /* - * NB: We ack only if the sta associated with HT and - * the ap is configured to do AMPDU rx (the latter - * violates the 11n spec and is mostly for testing). - */ - if ((ni->ni_flags & IEEE80211_NODE_AMPDU_RX) && - (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_RX)) { - /* XXX handle ampdu_rx_start failure */ - ic->ic_ampdu_rx_start(ni, rap, - baparamset, batimeout, baseqctl); - - args[1] = IEEE80211_STATUS_SUCCESS; - } else { - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, - ni, "reject ADDBA request: %s", - ni->ni_flags & IEEE80211_NODE_AMPDU_RX ? - "administratively disabled" : - "not negotiated for station"); - vap->iv_stats.is_addba_reject++; - args[1] = IEEE80211_STATUS_UNSPECIFIED; - } - /* XXX honor rap flags? */ - args[2] = IEEE80211_BAPS_POLICY_IMMEDIATE - | SM(tid, IEEE80211_BAPS_TID) - | SM(rap->rxa_wnd, IEEE80211_BAPS_BUFSIZ) - ; - args[3] = 0; - args[4] = 0; - ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA, - IEEE80211_ACTION_BA_ADDBA_RESPONSE, args); - return 0; -} - -static int -ht_recv_action_ba_addba_response(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_tx_ampdu *tap; - uint8_t dialogtoken, policy; - uint16_t baparamset, batimeout, code; - int tid, ac, bufsiz; - - dialogtoken = frm[2]; - code = LE_READ_2(frm+3); - baparamset = LE_READ_2(frm+5); - tid = MS(baparamset, IEEE80211_BAPS_TID); - bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ); - policy = MS(baparamset, IEEE80211_BAPS_POLICY); - batimeout = LE_READ_2(frm+7); - - ac = TID_TO_WME_AC(tid); - tap = &ni->ni_tx_ampdu[ac]; - if ((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0) { - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, - ni->ni_macaddr, "ADDBA response", - "no pending ADDBA, tid %d dialogtoken %u " - "code %d", tid, dialogtoken, code); - vap->iv_stats.is_addba_norequest++; - return 0; - } - if (dialogtoken != tap->txa_token) { - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, - ni->ni_macaddr, "ADDBA response", - "dialogtoken mismatch: waiting for %d, " - "received %d, tid %d code %d", - tap->txa_token, dialogtoken, tid, code); - vap->iv_stats.is_addba_badtoken++; - return 0; - } - /* NB: assumes IEEE80211_AGGR_IMMEDIATE is 1 */ - if (policy != (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE)) { - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, - ni->ni_macaddr, "ADDBA response", - "policy mismatch: expecting %s, " - "received %s, tid %d code %d", - tap->txa_flags & IEEE80211_AGGR_IMMEDIATE, - policy, tid, code); - vap->iv_stats.is_addba_badpolicy++; - return 0; - } -#if 0 - /* XXX we take MIN in ieee80211_addba_response */ - if (bufsiz > IEEE80211_AGGR_BAWMAX) { - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, - ni->ni_macaddr, "ADDBA response", - "BA window too large: max %d, " - "received %d, tid %d code %d", - bufsiz, IEEE80211_AGGR_BAWMAX, tid, code); - vap->iv_stats.is_addba_badbawinsize++; - return 0; - } -#endif - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "recv ADDBA response: dialogtoken %u code %d " - "baparamset 0x%x (tid %d bufsiz %d) batimeout %d", - dialogtoken, code, baparamset, tid, bufsiz, - batimeout); - ic->ic_addba_response(ni, tap, code, baparamset, batimeout); - return 0; -} - -static int -ht_recv_action_ba_delba(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_rx_ampdu *rap; - struct ieee80211_tx_ampdu *tap; - uint16_t baparamset, code; - int tid, ac; - - baparamset = LE_READ_2(frm+2); - code = LE_READ_2(frm+4); - - tid = MS(baparamset, IEEE80211_DELBAPS_TID); - - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "recv DELBA: baparamset 0x%x (tid %d initiator %d) " - "code %d", baparamset, tid, - MS(baparamset, IEEE80211_DELBAPS_INIT), code); - - if ((baparamset & IEEE80211_DELBAPS_INIT) == 0) { - ac = TID_TO_WME_AC(tid); - tap = &ni->ni_tx_ampdu[ac]; - ic->ic_addba_stop(ni, tap); - } else { - rap = &ni->ni_rx_ampdu[tid]; - ic->ic_ampdu_rx_stop(ni, rap); - } - return 0; -} - -static int -ht_recv_action_ht_txchwidth(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ - int chw; - - chw = (frm[2] == IEEE80211_A_HT_TXCHWIDTH_2040) ? 40 : 20; - - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "%s: HT txchwidth, width %d%s", - __func__, chw, ni->ni_chw != chw ? "*" : ""); - if (chw != ni->ni_chw) { - ni->ni_chw = chw; - /* XXX notify on change */ - } - return 0; -} - -static int -ht_recv_action_ht_mimopwrsave(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ - const struct ieee80211_action_ht_mimopowersave *mps = - (const struct ieee80211_action_ht_mimopowersave *) frm; - - /* XXX check iv_htcaps */ - if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_ENA) - ni->ni_flags |= IEEE80211_NODE_MIMO_PS; - else - ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS; - if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_MODE) - ni->ni_flags |= IEEE80211_NODE_MIMO_RTS; - else - ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; - /* XXX notify on change */ - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "%s: HT MIMO PS (%s%s)", __func__, - (ni->ni_flags & IEEE80211_NODE_MIMO_PS) ? "on" : "off", - (ni->ni_flags & IEEE80211_NODE_MIMO_RTS) ? "+rts" : "" - ); - return 0; -} - -/* - * Transmit processing. - */ - -/* - * Check if A-MPDU should be requested/enabled for a stream. - * We require a traffic rate above a per-AC threshold and we - * also handle backoff from previous failed attempts. - * - * Drivers may override this method to bring in information - * such as link state conditions in making the decision. - */ -static int -ieee80211_ampdu_enable(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap) -{ - struct ieee80211vap *vap = ni->ni_vap; - - if (tap->txa_avgpps < vap->iv_ampdu_mintraffic[tap->txa_ac]) - return 0; - /* XXX check rssi? */ - if (tap->txa_attempts >= ieee80211_addba_maxtries && - ticks < tap->txa_nextrequest) { - /* - * Don't retry too often; txa_nextrequest is set - * to the minimum interval we'll retry after - * ieee80211_addba_maxtries failed attempts are made. - */ - return 0; - } - IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni, - "enable AMPDU on %s, avgpps %d pkts %d", - ieee80211_wme_acnames[tap->txa_ac], tap->txa_avgpps, tap->txa_pkts); - return 1; -} - -/* - * Request A-MPDU tx aggregation. Setup local state and - * issue an ADDBA request. BA use will only happen after - * the other end replies with ADDBA response. - */ -int -ieee80211_ampdu_request(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap) -{ - struct ieee80211com *ic = ni->ni_ic; - uint16_t args[5]; - int tid, dialogtoken; - static int tokens = 0; /* XXX */ - - /* XXX locking */ - if ((tap->txa_flags & IEEE80211_AGGR_SETUP) == 0) { - /* do deferred setup of state */ - ampdu_tx_setup(tap); - } - /* XXX hack for not doing proper locking */ - tap->txa_flags &= ~IEEE80211_AGGR_NAK; - - dialogtoken = (tokens+1) % 63; /* XXX */ - tid = WME_AC_TO_TID(tap->txa_ac); - tap->txa_start = ni->ni_txseqs[tid]; - - args[0] = dialogtoken; - args[1] = 0; /* NB: status code not used */ - args[2] = IEEE80211_BAPS_POLICY_IMMEDIATE - | SM(tid, IEEE80211_BAPS_TID) - | SM(IEEE80211_AGGR_BAWMAX, IEEE80211_BAPS_BUFSIZ) - ; - args[3] = 0; /* batimeout */ - /* NB: do first so there's no race against reply */ - if (!ic->ic_addba_request(ni, tap, dialogtoken, args[2], args[3])) { - /* unable to setup state, don't make request */ - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, - ni, "%s: could not setup BA stream for AC %d", - __func__, tap->txa_ac); - /* defer next try so we don't slam the driver with requests */ - tap->txa_attempts = ieee80211_addba_maxtries; - /* NB: check in case driver wants to override */ - if (tap->txa_nextrequest <= ticks) - tap->txa_nextrequest = ticks + ieee80211_addba_backoff; - return 0; - } - tokens = dialogtoken; /* allocate token */ - /* NB: after calling ic_addba_request so driver can set txa_start */ - args[4] = SM(tap->txa_start, IEEE80211_BASEQ_START) - | SM(0, IEEE80211_BASEQ_FRAG) - ; - return ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA, - IEEE80211_ACTION_BA_ADDBA_REQUEST, args); -} - -/* - * Terminate an AMPDU tx stream. State is reclaimed - * and the peer notified with a DelBA Action frame. - */ -void -ieee80211_ampdu_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, - int reason) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211vap *vap = ni->ni_vap; - uint16_t args[4]; - - /* XXX locking */ - tap->txa_flags &= ~IEEE80211_AGGR_BARPEND; - if (IEEE80211_AMPDU_RUNNING(tap)) { - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, - ni, "%s: stop BA stream for AC %d (reason %d)", - __func__, tap->txa_ac, reason); - vap->iv_stats.is_ampdu_stop++; - - ic->ic_addba_stop(ni, tap); - args[0] = WME_AC_TO_TID(tap->txa_ac); - args[1] = IEEE80211_DELBAPS_INIT; - args[2] = reason; /* XXX reason code */ - ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA, - IEEE80211_ACTION_BA_DELBA, args); - } else { - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, - ni, "%s: BA stream for AC %d not running (reason %d)", - __func__, tap->txa_ac, reason); - vap->iv_stats.is_ampdu_stop_failed++; - } -} - -static void -bar_timeout(void *arg) -{ - struct ieee80211_tx_ampdu *tap = arg; - struct ieee80211_node *ni = tap->txa_ni; - - KASSERT((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0, - ("bar/addba collision, flags 0x%x", tap->txa_flags)); - - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, - ni, "%s: tid %u flags 0x%x attempts %d", __func__, - tap->txa_ac, tap->txa_flags, tap->txa_attempts); - - /* guard against race with bar_tx_complete */ - if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) == 0) - return; - /* XXX ? */ - if (tap->txa_attempts >= ieee80211_bar_maxtries) - ieee80211_ampdu_stop(ni, tap, IEEE80211_REASON_TIMEOUT); - else - ieee80211_send_bar(ni, tap, tap->txa_seqpending); -} - -static void -bar_start_timer(struct ieee80211_tx_ampdu *tap) -{ - callout_reset(&tap->txa_timer, ieee80211_bar_timeout, bar_timeout, tap); -} - -static void -bar_stop_timer(struct ieee80211_tx_ampdu *tap) -{ - callout_stop(&tap->txa_timer); -} - -static void -bar_tx_complete(struct ieee80211_node *ni, void *arg, int status) -{ - struct ieee80211_tx_ampdu *tap = arg; - - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, - ni, "%s: tid %u flags 0x%x pending %d status %d", - __func__, tap->txa_ac, tap->txa_flags, - callout_pending(&tap->txa_timer), status); - - /* XXX locking */ - if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) && - callout_pending(&tap->txa_timer)) { - struct ieee80211com *ic = ni->ni_ic; - - if (status == 0) /* ACK'd */ - bar_stop_timer(tap); - ic->ic_bar_response(ni, tap, status); - /* NB: just let timer expire so we pace requests */ - } -} - -static void -ieee80211_bar_response(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap, int status) -{ - - if (status == 0) { /* got ACK */ - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, - ni, "BAR moves BA win <%u:%u> (%u frames) txseq %u tid %u", - tap->txa_start, - IEEE80211_SEQ_ADD(tap->txa_start, tap->txa_wnd-1), - tap->txa_qframes, tap->txa_seqpending, - WME_AC_TO_TID(tap->txa_ac)); - - /* NB: timer already stopped in bar_tx_complete */ - tap->txa_start = tap->txa_seqpending; - tap->txa_flags &= ~IEEE80211_AGGR_BARPEND; - } -} - -/* - * Transmit a BAR frame to the specified node. The - * BAR contents are drawn from the supplied aggregation - * state associated with the node. - * - * NB: we only handle immediate ACK w/ compressed bitmap. - */ -int -ieee80211_send_bar(struct ieee80211_node *ni, - struct ieee80211_tx_ampdu *tap, ieee80211_seq seq) -{ -#define senderr(_x, _v) do { vap->iv_stats._v++; ret = _x; goto bad; } while (0) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_frame_bar *bar; - struct mbuf *m; - uint16_t barctl, barseqctl; - uint8_t *frm; - int tid, ret; - - if ((tap->txa_flags & IEEE80211_AGGR_RUNNING) == 0) { - /* no ADDBA response, should not happen */ - /* XXX stat+msg */ - return EINVAL; - } - /* XXX locking */ - bar_stop_timer(tap); - - ieee80211_ref_node(ni); - - m = ieee80211_getmgtframe(&frm, ic->ic_headroom, sizeof(*bar)); - if (m == NULL) - senderr(ENOMEM, is_tx_nobuf); - - if (!ieee80211_add_callback(m, bar_tx_complete, tap)) { - m_freem(m); - senderr(ENOMEM, is_tx_nobuf); /* XXX */ - /* NOTREACHED */ - } - - bar = mtod(m, struct ieee80211_frame_bar *); - bar->i_fc[0] = IEEE80211_FC0_VERSION_0 | - IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR; - bar->i_fc[1] = 0; - IEEE80211_ADDR_COPY(bar->i_ra, ni->ni_macaddr); - IEEE80211_ADDR_COPY(bar->i_ta, vap->iv_myaddr); - - tid = WME_AC_TO_TID(tap->txa_ac); - barctl = (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE ? - 0 : IEEE80211_BAR_NOACK) - | IEEE80211_BAR_COMP - | SM(tid, IEEE80211_BAR_TID) - ; - barseqctl = SM(seq, IEEE80211_BAR_SEQ_START); - /* NB: known to have proper alignment */ - bar->i_ctl = htole16(barctl); - bar->i_seq = htole16(barseqctl); - m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame_bar); - - M_WME_SETAC(m, WME_AC_VO); - - IEEE80211_NODE_STAT(ni, tx_mgmt); /* XXX tx_ctl? */ - - /* XXX locking */ - /* init/bump attempts counter */ - if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) == 0) - tap->txa_attempts = 1; - else - tap->txa_attempts++; - tap->txa_seqpending = seq; - tap->txa_flags |= IEEE80211_AGGR_BARPEND; - - IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_11N, - ni, "send BAR: tid %u ctl 0x%x start %u (attempt %d)", - tid, barctl, seq, tap->txa_attempts); - - /* - * ic_raw_xmit will free the node reference - * regardless of queue/TX success or failure. - */ - ret = ic->ic_raw_xmit(ni, m, NULL); - if (ret != 0) { - /* xmit failed, clear state flag */ - tap->txa_flags &= ~IEEE80211_AGGR_BARPEND; - return ret; - } - /* XXX hack against tx complete happening before timer is started */ - if (tap->txa_flags & IEEE80211_AGGR_BARPEND) - bar_start_timer(tap); - return 0; -bad: - ieee80211_free_node(ni); - return ret; -#undef senderr -} - -static int -ht_action_output(struct ieee80211_node *ni, struct mbuf *m) -{ - struct ieee80211_bpf_params params; - - memset(¶ms, 0, sizeof(params)); - params.ibp_pri = WME_AC_VO; - params.ibp_rate0 = ni->ni_txparms->mgmtrate; - /* NB: we know all frames are unicast */ - params.ibp_try0 = ni->ni_txparms->maxretry; - params.ibp_power = ni->ni_txpower; - return ieee80211_mgmt_output(ni, m, IEEE80211_FC0_SUBTYPE_ACTION, - ¶ms); -} - -#define ADDSHORT(frm, v) do { \ - frm[0] = (v) & 0xff; \ - frm[1] = (v) >> 8; \ - frm += 2; \ -} while (0) - -/* - * Send an action management frame. The arguments are stuff - * into a frame without inspection; the caller is assumed to - * prepare them carefully (e.g. based on the aggregation state). - */ -static int -ht_send_action_ba_addba(struct ieee80211_node *ni, - int category, int action, void *arg0) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - uint16_t *args = arg0; - struct mbuf *m; - uint8_t *frm; - - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "send ADDBA %s: dialogtoken %d status %d " - "baparamset 0x%x (tid %d) batimeout 0x%x baseqctl 0x%x", - (action == IEEE80211_ACTION_BA_ADDBA_REQUEST) ? - "request" : "response", - args[0], args[1], args[2], MS(args[2], IEEE80211_BAPS_TID), - args[3], args[4]); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); - ieee80211_ref_node(ni); - - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t) /* action+category */ - /* XXX may action payload */ - + sizeof(struct ieee80211_action_ba_addbaresponse) - ); - if (m != NULL) { - *frm++ = category; - *frm++ = action; - *frm++ = args[0]; /* dialog token */ - if (action == IEEE80211_ACTION_BA_ADDBA_RESPONSE) - ADDSHORT(frm, args[1]); /* status code */ - ADDSHORT(frm, args[2]); /* baparamset */ - ADDSHORT(frm, args[3]); /* batimeout */ - if (action == IEEE80211_ACTION_BA_ADDBA_REQUEST) - ADDSHORT(frm, args[4]); /* baseqctl */ - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - return ht_action_output(ni, m); - } else { - vap->iv_stats.is_tx_nobuf++; - ieee80211_free_node(ni); - return ENOMEM; - } -} - -static int -ht_send_action_ba_delba(struct ieee80211_node *ni, - int category, int action, void *arg0) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - uint16_t *args = arg0; - struct mbuf *m; - uint16_t baparamset; - uint8_t *frm; - - baparamset = SM(args[0], IEEE80211_DELBAPS_TID) - | args[1] - ; - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "send DELBA action: tid %d, initiator %d reason %d", - args[0], args[1], args[2]); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); - ieee80211_ref_node(ni); - - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t) /* action+category */ - /* XXX may action payload */ - + sizeof(struct ieee80211_action_ba_addbaresponse) - ); - if (m != NULL) { - *frm++ = category; - *frm++ = action; - ADDSHORT(frm, baparamset); - ADDSHORT(frm, args[2]); /* reason code */ - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - return ht_action_output(ni, m); - } else { - vap->iv_stats.is_tx_nobuf++; - ieee80211_free_node(ni); - return ENOMEM; - } -} - -static int -ht_send_action_ht_txchwidth(struct ieee80211_node *ni, - int category, int action, void *arg0) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct mbuf *m; - uint8_t *frm; - - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "send HT txchwidth: width %d", - IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? 40 : 20); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); - ieee80211_ref_node(ni); - - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t) /* action+category */ - /* XXX may action payload */ - + sizeof(struct ieee80211_action_ba_addbaresponse) - ); - if (m != NULL) { - *frm++ = category; - *frm++ = action; - *frm++ = IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? - IEEE80211_A_HT_TXCHWIDTH_2040 : - IEEE80211_A_HT_TXCHWIDTH_20; - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - return ht_action_output(ni, m); - } else { - vap->iv_stats.is_tx_nobuf++; - ieee80211_free_node(ni); - return ENOMEM; - } -} -#undef ADDSHORT - -/* - * Construct the MCS bit mask for inclusion in an HT capabilities - * information element. - */ -static void -ieee80211_set_mcsset(struct ieee80211com *ic, uint8_t *frm) -{ - int i; - uint8_t txparams; - - KASSERT((ic->ic_rxstream > 0 && ic->ic_rxstream <= 4), - ("ic_rxstream %d out of range", ic->ic_rxstream)); - KASSERT((ic->ic_txstream > 0 && ic->ic_txstream <= 4), - ("ic_txstream %d out of range", ic->ic_txstream)); - - for (i = 0; i < ic->ic_rxstream * 8; i++) - setbit(frm, i); - if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) && - (ic->ic_htcaps & IEEE80211_HTC_RXMCS32)) - setbit(frm, 32); - if (ic->ic_htcaps & IEEE80211_HTC_RXUNEQUAL) { - if (ic->ic_rxstream >= 2) { - for (i = 33; i <= 38; i++) - setbit(frm, i); - } - if (ic->ic_rxstream >= 3) { - for (i = 39; i <= 52; i++) - setbit(frm, i); - } - if (ic->ic_txstream >= 4) { - for (i = 53; i <= 76; i++) - setbit(frm, i); - } - } - - if (ic->ic_rxstream != ic->ic_txstream) { - txparams = 0x1; /* TX MCS set defined */ - txparams |= 0x2; /* TX RX MCS not equal */ - txparams |= (ic->ic_txstream - 1) << 2; /* num TX streams */ - if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) - txparams |= 0x16; /* TX unequal modulation sup */ - } else - txparams = 0; - frm[12] = txparams; -} - -/* - * Add body of an HTCAP information element. - */ -static uint8_t * -ieee80211_add_htcap_body(uint8_t *frm, struct ieee80211_node *ni) -{ -#define ADDSHORT(frm, v) do { \ - frm[0] = (v) & 0xff; \ - frm[1] = (v) >> 8; \ - frm += 2; \ -} while (0) - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211vap *vap = ni->ni_vap; - uint16_t caps, extcaps; - int rxmax, density; - - /* HT capabilities */ - caps = vap->iv_htcaps & 0xffff; - /* - * Note channel width depends on whether we are operating as - * a sta or not. When operating as a sta we are generating - * a request based on our desired configuration. Otherwise - * we are operational and the channel attributes identify - * how we've been setup (which might be different if a fixed - * channel is specified). - */ - if (vap->iv_opmode == IEEE80211_M_STA) { - /* override 20/40 use based on config */ - if (vap->iv_flags_ht & IEEE80211_FHT_USEHT40) - caps |= IEEE80211_HTCAP_CHWIDTH40; - else - caps &= ~IEEE80211_HTCAP_CHWIDTH40; - /* use advertised setting (XXX locally constraint) */ - rxmax = MS(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU); - density = MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY); - - /* - * NB: Hardware might support HT40 on some but not all - * channels. We can't determine this earlier because only - * after association the channel is upgraded to HT based - * on the negotiated capabilities. - */ - if (ni->ni_chan != IEEE80211_CHAN_ANYC && - findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT40U) == NULL && - findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT40D) == NULL) - caps &= ~IEEE80211_HTCAP_CHWIDTH40; - } else { - /* override 20/40 use based on current channel */ - if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) - caps |= IEEE80211_HTCAP_CHWIDTH40; - else - caps &= ~IEEE80211_HTCAP_CHWIDTH40; - rxmax = vap->iv_ampdu_rxmax; - density = vap->iv_ampdu_density; - } - /* adjust short GI based on channel and config */ - if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) == 0) - caps &= ~IEEE80211_HTCAP_SHORTGI20; - if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) == 0 || - (caps & IEEE80211_HTCAP_CHWIDTH40) == 0) - caps &= ~IEEE80211_HTCAP_SHORTGI40; - ADDSHORT(frm, caps); - - /* HT parameters */ - *frm = SM(rxmax, IEEE80211_HTCAP_MAXRXAMPDU) - | SM(density, IEEE80211_HTCAP_MPDUDENSITY) - ; - frm++; - - /* pre-zero remainder of ie */ - memset(frm, 0, sizeof(struct ieee80211_ie_htcap) - - __offsetof(struct ieee80211_ie_htcap, hc_mcsset)); - - /* supported MCS set */ - /* - * XXX: For sta mode the rate set should be restricted based - * on the AP's capabilities, but ni_htrates isn't setup when - * we're called to form an AssocReq frame so for now we're - * restricted to the device capabilities. - */ - ieee80211_set_mcsset(ni->ni_ic, frm); - - frm += __offsetof(struct ieee80211_ie_htcap, hc_extcap) - - __offsetof(struct ieee80211_ie_htcap, hc_mcsset); - - /* HT extended capabilities */ - extcaps = vap->iv_htextcaps & 0xffff; - - ADDSHORT(frm, extcaps); - - frm += sizeof(struct ieee80211_ie_htcap) - - __offsetof(struct ieee80211_ie_htcap, hc_txbf); - - return frm; -#undef ADDSHORT -} - -/* - * Add 802.11n HT capabilities information element - */ -uint8_t * -ieee80211_add_htcap(uint8_t *frm, struct ieee80211_node *ni) -{ - frm[0] = IEEE80211_ELEMID_HTCAP; - frm[1] = sizeof(struct ieee80211_ie_htcap) - 2; - return ieee80211_add_htcap_body(frm + 2, ni); -} - -/* - * Add Broadcom OUI wrapped standard HTCAP ie; this is - * used for compatibility w/ pre-draft implementations. - */ -uint8_t * -ieee80211_add_htcap_vendor(uint8_t *frm, struct ieee80211_node *ni) -{ - frm[0] = IEEE80211_ELEMID_VENDOR; - frm[1] = 4 + sizeof(struct ieee80211_ie_htcap) - 2; - frm[2] = (BCM_OUI >> 0) & 0xff; - frm[3] = (BCM_OUI >> 8) & 0xff; - frm[4] = (BCM_OUI >> 16) & 0xff; - frm[5] = BCM_OUI_HTCAP; - return ieee80211_add_htcap_body(frm + 6, ni); -} - -/* - * Construct the MCS bit mask of basic rates - * for inclusion in an HT information element. - */ -static void -ieee80211_set_basic_htrates(uint8_t *frm, const struct ieee80211_htrateset *rs) -{ - int i; - - for (i = 0; i < rs->rs_nrates; i++) { - int r = rs->rs_rates[i] & IEEE80211_RATE_VAL; - if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) && - r < IEEE80211_HTRATE_MAXSIZE) { - /* NB: this assumes a particular implementation */ - setbit(frm, r); - } - } -} - -/* - * Update the HTINFO ie for a beacon frame. - */ -void -ieee80211_ht_update_beacon(struct ieee80211vap *vap, - struct ieee80211_beacon_offsets *bo) -{ -#define PROTMODE (IEEE80211_HTINFO_OPMODE|IEEE80211_HTINFO_NONHT_PRESENT) - const struct ieee80211_channel *bsschan = vap->iv_bss->ni_chan; - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_ie_htinfo *ht = - (struct ieee80211_ie_htinfo *) bo->bo_htinfo; - - /* XXX only update on channel change */ - ht->hi_ctrlchannel = ieee80211_chan2ieee(ic, bsschan); - if (vap->iv_flags_ht & IEEE80211_FHT_RIFS) - ht->hi_byte1 = IEEE80211_HTINFO_RIFSMODE_PERM; - else - ht->hi_byte1 = IEEE80211_HTINFO_RIFSMODE_PROH; - if (IEEE80211_IS_CHAN_HT40U(bsschan)) - ht->hi_byte1 |= IEEE80211_HTINFO_2NDCHAN_ABOVE; - else if (IEEE80211_IS_CHAN_HT40D(bsschan)) - ht->hi_byte1 |= IEEE80211_HTINFO_2NDCHAN_BELOW; - else - ht->hi_byte1 |= IEEE80211_HTINFO_2NDCHAN_NONE; - if (IEEE80211_IS_CHAN_HT40(bsschan)) - ht->hi_byte1 |= IEEE80211_HTINFO_TXWIDTH_2040; - - /* protection mode */ - ht->hi_byte2 = (ht->hi_byte2 &~ PROTMODE) | ic->ic_curhtprotmode; - - /* XXX propagate to vendor ie's */ -#undef PROTMODE -} - -/* - * Add body of an HTINFO information element. - * - * NB: We don't use struct ieee80211_ie_htinfo because we can - * be called to fillin both a standard ie and a compat ie that - * has a vendor OUI at the front. - */ -static uint8_t * -ieee80211_add_htinfo_body(uint8_t *frm, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - - /* pre-zero remainder of ie */ - memset(frm, 0, sizeof(struct ieee80211_ie_htinfo) - 2); - - /* primary/control channel center */ - *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan); - - if (vap->iv_flags_ht & IEEE80211_FHT_RIFS) - frm[0] = IEEE80211_HTINFO_RIFSMODE_PERM; - else - frm[0] = IEEE80211_HTINFO_RIFSMODE_PROH; - if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan)) - frm[0] |= IEEE80211_HTINFO_2NDCHAN_ABOVE; - else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan)) - frm[0] |= IEEE80211_HTINFO_2NDCHAN_BELOW; - else - frm[0] |= IEEE80211_HTINFO_2NDCHAN_NONE; - if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) - frm[0] |= IEEE80211_HTINFO_TXWIDTH_2040; - - frm[1] = ic->ic_curhtprotmode; - - frm += 5; - - /* basic MCS set */ - ieee80211_set_basic_htrates(frm, &ni->ni_htrates); - frm += sizeof(struct ieee80211_ie_htinfo) - - __offsetof(struct ieee80211_ie_htinfo, hi_basicmcsset); - return frm; -} - -/* - * Add 802.11n HT information information element. - */ -uint8_t * -ieee80211_add_htinfo(uint8_t *frm, struct ieee80211_node *ni) -{ - frm[0] = IEEE80211_ELEMID_HTINFO; - frm[1] = sizeof(struct ieee80211_ie_htinfo) - 2; - return ieee80211_add_htinfo_body(frm + 2, ni); -} - -/* - * Add Broadcom OUI wrapped standard HTINFO ie; this is - * used for compatibility w/ pre-draft implementations. - */ -uint8_t * -ieee80211_add_htinfo_vendor(uint8_t *frm, struct ieee80211_node *ni) -{ - frm[0] = IEEE80211_ELEMID_VENDOR; - frm[1] = 4 + sizeof(struct ieee80211_ie_htinfo) - 2; - frm[2] = (BCM_OUI >> 0) & 0xff; - frm[3] = (BCM_OUI >> 8) & 0xff; - frm[4] = (BCM_OUI >> 16) & 0xff; - frm[5] = BCM_OUI_HTINFO; - return ieee80211_add_htinfo_body(frm + 6, ni); -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ht.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_ht.h deleted file mode 100644 index d345fe9fb3..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ht.h +++ /dev/null @@ -1,205 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_HT_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_HT_H_ - -/* - * 802.11n protocol implementation definitions. - */ - -void ieee80211_ht_init(void); - -#define IEEE80211_AGGR_BAWMAX 64 /* max block ack window size */ -/* threshold for aging overlapping non-HT bss */ -#define IEEE80211_NONHT_PRESENT_AGE msecs_to_ticks(60*1000) - -struct ieee80211_tx_ampdu { - struct ieee80211_node *txa_ni; /* back pointer */ - u_short txa_flags; -#define IEEE80211_AGGR_IMMEDIATE 0x0001 /* BA policy */ -#define IEEE80211_AGGR_XCHGPEND 0x0002 /* ADDBA response pending */ -#define IEEE80211_AGGR_RUNNING 0x0004 /* ADDBA response received */ -#define IEEE80211_AGGR_SETUP 0x0008 /* deferred state setup */ -#define IEEE80211_AGGR_NAK 0x0010 /* peer NAK'd ADDBA request */ -#define IEEE80211_AGGR_BARPEND 0x0020 /* BAR response pending */ - uint8_t txa_ac; - uint8_t txa_token; /* dialog token */ - int txa_lastsample; /* ticks @ last traffic sample */ - int txa_pkts; /* packets over last sample interval */ - int txa_avgpps; /* filtered traffic over window */ - int txa_qbytes; /* data queued (bytes) */ - short txa_qframes; /* data queued (frames) */ - ieee80211_seq txa_start; /* BA window left edge */ - ieee80211_seq txa_seqpending; /* new txa_start pending BAR response */ - uint16_t txa_wnd; /* BA window size */ - uint8_t txa_attempts; /* # ADDBA/BAR requests w/o a response*/ - int txa_nextrequest;/* soonest to make next request */ - struct callout txa_timer; - void *txa_private; /* driver-private storage */ - uint64_t txa_pad[4]; -}; - -/* return non-zero if AMPDU tx for the TID is running */ -#define IEEE80211_AMPDU_RUNNING(tap) \ - (((tap)->txa_flags & IEEE80211_AGGR_RUNNING) != 0) - -/* return non-zero if AMPDU tx for the TID is running or started */ -#define IEEE80211_AMPDU_REQUESTED(tap) \ - (((tap)->txa_flags & \ - (IEEE80211_AGGR_RUNNING|IEEE80211_AGGR_XCHGPEND|IEEE80211_AGGR_NAK)) != 0) - -#define IEEE80211_AGGR_BITS \ - "\20\1IMMEDIATE\2XCHGPEND\3RUNNING\4SETUP\5NAK" - -/* - * Traffic estimator support. We estimate packets/sec for - * each AC that is setup for AMPDU or will potentially be - * setup for AMPDU. The traffic rate can be used to decide - * when AMPDU should be setup (according to a threshold) - * and is available for drivers to do things like cache - * eviction when only a limited number of BA streams are - * available and more streams are requested than available. - */ - -static __inline void -ieee80211_txampdu_update_pps(struct ieee80211_tx_ampdu *tap) -{ - /* NB: scale factor of 2 was picked heuristically */ - tap->txa_avgpps = ((tap->txa_avgpps << 2) - - tap->txa_avgpps + tap->txa_pkts) >> 2; -} - -/* - * Count a packet towards the pps estimate. - */ -static __inline void -ieee80211_txampdu_count_packet(struct ieee80211_tx_ampdu *tap) -{ - /* XXX bound loop/do more crude estimate? */ - while (ticks - tap->txa_lastsample >= hz) { - ieee80211_txampdu_update_pps(tap); - /* reset to start new sample interval */ - tap->txa_pkts = 0; - if (tap->txa_avgpps == 0) { - tap->txa_lastsample = ticks; - break; - } - tap->txa_lastsample += hz; - } - tap->txa_pkts++; -} - -/* - * Get the current pps estimate. If the average is out of - * date due to lack of traffic then we decay the estimate - * to account for the idle time. - */ -static __inline int -ieee80211_txampdu_getpps(struct ieee80211_tx_ampdu *tap) -{ - /* XXX bound loop/do more crude estimate? */ - while (ticks - tap->txa_lastsample >= hz) { - ieee80211_txampdu_update_pps(tap); - tap->txa_pkts = 0; - if (tap->txa_avgpps == 0) { - tap->txa_lastsample = ticks; - break; - } - tap->txa_lastsample += hz; - } - return tap->txa_avgpps; -} - -struct ieee80211_rx_ampdu { - int rxa_flags; - int rxa_qbytes; /* data queued (bytes) */ - short rxa_qframes; /* data queued (frames) */ - ieee80211_seq rxa_seqstart; - ieee80211_seq rxa_start; /* start of current BA window */ - uint16_t rxa_wnd; /* BA window size */ - int rxa_age; /* age of oldest frame in window */ - int rxa_nframes; /* frames since ADDBA */ - struct mbuf *rxa_m[IEEE80211_AGGR_BAWMAX]; - void *rxa_private; - uint64_t rxa_pad[3]; -}; - -void ieee80211_ht_attach(struct ieee80211com *); -void ieee80211_ht_detach(struct ieee80211com *); -void ieee80211_ht_vattach(struct ieee80211vap *); -void ieee80211_ht_vdetach(struct ieee80211vap *); - -void ieee80211_ht_announce(struct ieee80211com *); - -struct ieee80211_mcs_rates { - uint16_t ht20_rate_800ns; - uint16_t ht20_rate_400ns; - uint16_t ht40_rate_800ns; - uint16_t ht40_rate_400ns; -}; -extern const struct ieee80211_mcs_rates ieee80211_htrates[]; -const struct ieee80211_htrateset *ieee80211_get_suphtrates( - struct ieee80211com *, const struct ieee80211_channel *); - -struct ieee80211_node; -int ieee80211_setup_htrates(struct ieee80211_node *, - const uint8_t *htcap, int flags); -void ieee80211_setup_basic_htrates(struct ieee80211_node *, - const uint8_t *htinfo); -struct mbuf *ieee80211_decap_amsdu(struct ieee80211_node *, struct mbuf *); -int ieee80211_ampdu_reorder(struct ieee80211_node *, struct mbuf *); -void ieee80211_recv_bar(struct ieee80211_node *, struct mbuf *); -void ieee80211_ht_node_init(struct ieee80211_node *); -void ieee80211_ht_node_cleanup(struct ieee80211_node *); -void ieee80211_ht_node_age(struct ieee80211_node *); - -struct ieee80211_channel *ieee80211_ht_adjust_channel(struct ieee80211com *, - struct ieee80211_channel *, int); -void ieee80211_ht_wds_init(struct ieee80211_node *); -void ieee80211_ht_node_join(struct ieee80211_node *); -void ieee80211_ht_node_leave(struct ieee80211_node *); -void ieee80211_htprot_update(struct ieee80211com *, int protmode); -void ieee80211_ht_timeout(struct ieee80211com *); -void ieee80211_parse_htcap(struct ieee80211_node *, const uint8_t *); -void ieee80211_parse_htinfo(struct ieee80211_node *, const uint8_t *); -void ieee80211_ht_updateparams(struct ieee80211_node *, const uint8_t *, - const uint8_t *); -void ieee80211_ht_updatehtcap(struct ieee80211_node *, const uint8_t *); -int ieee80211_ampdu_request(struct ieee80211_node *, - struct ieee80211_tx_ampdu *); -void ieee80211_ampdu_stop(struct ieee80211_node *, - struct ieee80211_tx_ampdu *, int); -int ieee80211_send_bar(struct ieee80211_node *, struct ieee80211_tx_ampdu *, - ieee80211_seq); -uint8_t *ieee80211_add_htcap(uint8_t *, struct ieee80211_node *); -uint8_t *ieee80211_add_htcap_vendor(uint8_t *, struct ieee80211_node *); -uint8_t *ieee80211_add_htinfo(uint8_t *, struct ieee80211_node *); -uint8_t *ieee80211_add_htinfo_vendor(uint8_t *, struct ieee80211_node *); -struct ieee80211_beacon_offsets; -void ieee80211_ht_update_beacon(struct ieee80211vap *, - struct ieee80211_beacon_offsets *); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_HT_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_hwmp.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_hwmp.c deleted file mode 100644 index 78729fcb1a..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_hwmp.c +++ /dev/null @@ -1,1438 +0,0 @@ -/*- - * Copyright (c) 2009 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Rui Paulo under sponsorship from the - * FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#include -#ifdef __FreeBSD__ -__FBSDID("$FreeBSD$"); -#endif - -/* - * IEEE 802.11s Hybrid Wireless Mesh Protocol, HWMP. - * - * Based on March 2009, D3.0 802.11s draft spec. - */ -#include "opt_inet.h" -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -static void hwmp_vattach(struct ieee80211vap *); -static void hwmp_vdetach(struct ieee80211vap *); -static int hwmp_newstate(struct ieee80211vap *, - enum ieee80211_state, int); -static int hwmp_send_action(struct ieee80211_node *, - const uint8_t [IEEE80211_ADDR_LEN], - const uint8_t [IEEE80211_ADDR_LEN], - uint8_t *, size_t); -static uint8_t * hwmp_add_meshpreq(uint8_t *, - const struct ieee80211_meshpreq_ie *); -static uint8_t * hwmp_add_meshprep(uint8_t *, - const struct ieee80211_meshprep_ie *); -static uint8_t * hwmp_add_meshperr(uint8_t *, - const struct ieee80211_meshperr_ie *); -static uint8_t * hwmp_add_meshrann(uint8_t *, - const struct ieee80211_meshrann_ie *); -static void hwmp_rootmode_setup(struct ieee80211vap *); -static void hwmp_rootmode_cb(void *); -static void hwmp_rootmode_rann_cb(void *); -static void hwmp_recv_preq(struct ieee80211vap *, struct ieee80211_node *, - const struct ieee80211_frame *, - const struct ieee80211_meshpreq_ie *); -static int hwmp_send_preq(struct ieee80211_node *, - const uint8_t [IEEE80211_ADDR_LEN], - const uint8_t [IEEE80211_ADDR_LEN], - struct ieee80211_meshpreq_ie *); -static void hwmp_recv_prep(struct ieee80211vap *, struct ieee80211_node *, - const struct ieee80211_frame *, - const struct ieee80211_meshprep_ie *); -static int hwmp_send_prep(struct ieee80211_node *, - const uint8_t [IEEE80211_ADDR_LEN], - const uint8_t [IEEE80211_ADDR_LEN], - struct ieee80211_meshprep_ie *); -static void hwmp_recv_perr(struct ieee80211vap *, struct ieee80211_node *, - const struct ieee80211_frame *, - const struct ieee80211_meshperr_ie *); -static int hwmp_send_perr(struct ieee80211_node *, - const uint8_t [IEEE80211_ADDR_LEN], - const uint8_t [IEEE80211_ADDR_LEN], - struct ieee80211_meshperr_ie *); -static void hwmp_recv_rann(struct ieee80211vap *, struct ieee80211_node *, - const struct ieee80211_frame *, - const struct ieee80211_meshrann_ie *); -static int hwmp_send_rann(struct ieee80211_node *, - const uint8_t [IEEE80211_ADDR_LEN], - const uint8_t [IEEE80211_ADDR_LEN], - struct ieee80211_meshrann_ie *); -static struct ieee80211_node * - hwmp_discover(struct ieee80211vap *, - const uint8_t [IEEE80211_ADDR_LEN], struct mbuf *); -static void hwmp_peerdown(struct ieee80211_node *); - -static struct timeval ieee80211_hwmp_preqminint = { 0, 100000 }; -static struct timeval ieee80211_hwmp_perrminint = { 0, 100000 }; - -/* unalligned little endian access */ -#define LE_WRITE_2(p, v) do { \ - ((uint8_t *)(p))[0] = (v) & 0xff; \ - ((uint8_t *)(p))[1] = ((v) >> 8) & 0xff; \ -} while (0) -#define LE_WRITE_4(p, v) do { \ - ((uint8_t *)(p))[0] = (v) & 0xff; \ - ((uint8_t *)(p))[1] = ((v) >> 8) & 0xff; \ - ((uint8_t *)(p))[2] = ((v) >> 16) & 0xff; \ - ((uint8_t *)(p))[3] = ((v) >> 24) & 0xff; \ -} while (0) - - -/* NB: the Target Address set in a Proactive PREQ is the broadcast address. */ -static const uint8_t broadcastaddr[IEEE80211_ADDR_LEN] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - -typedef uint32_t ieee80211_hwmp_seq; -#define HWMP_SEQ_LT(a, b) ((int32_t)((a)-(b)) < 0) -#define HWMP_SEQ_LEQ(a, b) ((int32_t)((a)-(b)) <= 0) -#define HWMP_SEQ_GT(a, b) ((int32_t)((a)-(b)) > 0) -#define HWMP_SEQ_GEQ(a, b) ((int32_t)((a)-(b)) >= 0) - -/* - * Private extension of ieee80211_mesh_route. - */ -struct ieee80211_hwmp_route { - ieee80211_hwmp_seq hr_seq; /* last HWMP seq seen from dst*/ - ieee80211_hwmp_seq hr_preqid; /* last PREQ ID seen from dst */ - ieee80211_hwmp_seq hr_origseq; /* seq. no. on our latest PREQ*/ - int hr_preqretries; -}; -struct ieee80211_hwmp_state { - ieee80211_hwmp_seq hs_seq; /* next seq to be used */ - ieee80211_hwmp_seq hs_preqid; /* next PREQ ID to be used */ - struct timeval hs_lastpreq; /* last time we sent a PREQ */ - struct timeval hs_lastperr; /* last time we sent a PERR */ - int hs_rootmode; /* proactive HWMP */ - struct callout hs_roottimer; - uint8_t hs_maxhops; /* max hop count */ -}; - -SYSCTL_NODE(_net_wlan, OID_AUTO, hwmp, CTLFLAG_RD, 0, - "IEEE 802.11s HWMP parameters"); -static int ieee80211_hwmp_targetonly = 0; -SYSCTL_INT(_net_wlan_hwmp, OID_AUTO, targetonly, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_hwmp_targetonly, 0, "Set TO bit on generated PREQs"); -static int ieee80211_hwmp_replyforward = 1; -SYSCTL_INT(_net_wlan_hwmp, OID_AUTO, replyforward, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_hwmp_replyforward, 0, "Set RF bit on generated PREQs"); -static int ieee80211_hwmp_pathtimeout = -1; -SYSCTL_PROC(_net_wlan_hwmp, OID_AUTO, pathlifetime, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_hwmp_pathtimeout, 0, ieee80211_sysctl_msecs_ticks, "I", - "path entry lifetime (ms)"); -static int ieee80211_hwmp_roottimeout = -1; -SYSCTL_PROC(_net_wlan_hwmp, OID_AUTO, roottimeout, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_hwmp_roottimeout, 0, ieee80211_sysctl_msecs_ticks, "I", - "root PREQ timeout (ms)"); -static int ieee80211_hwmp_rootint = -1; -SYSCTL_PROC(_net_wlan_hwmp, OID_AUTO, rootint, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_hwmp_rootint, 0, ieee80211_sysctl_msecs_ticks, "I", - "root interval (ms)"); -static int ieee80211_hwmp_rannint = -1; -SYSCTL_PROC(_net_wlan_hwmp, OID_AUTO, rannint, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_hwmp_rannint, 0, ieee80211_sysctl_msecs_ticks, "I", - "root announcement interval (ms)"); - -#define IEEE80211_HWMP_DEFAULT_MAXHOPS 31 - -static ieee80211_recv_action_func hwmp_recv_action_meshpath; - -static struct ieee80211_mesh_proto_path mesh_proto_hwmp = { - .mpp_descr = "HWMP", - .mpp_ie = IEEE80211_MESHCONF_PATH_HWMP, - .mpp_discover = hwmp_discover, - .mpp_peerdown = hwmp_peerdown, - .mpp_vattach = hwmp_vattach, - .mpp_vdetach = hwmp_vdetach, - .mpp_newstate = hwmp_newstate, - .mpp_privlen = sizeof(struct ieee80211_hwmp_route), -}; -SYSCTL_PROC(_net_wlan_hwmp, OID_AUTO, inact, CTLTYPE_INT | CTLFLAG_RW, - &mesh_proto_hwmp.mpp_inact, 0, ieee80211_sysctl_msecs_ticks, "I", - "mesh route inactivity timeout (ms)"); - - -static void -ieee80211_hwmp_init(void) -{ - ieee80211_hwmp_pathtimeout = msecs_to_ticks(5*1000); - ieee80211_hwmp_roottimeout = msecs_to_ticks(5*1000); - ieee80211_hwmp_rootint = msecs_to_ticks(2*1000); - ieee80211_hwmp_rannint = msecs_to_ticks(1*1000); - - /* - * Register action frame handler. - */ - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH, - IEEE80211_ACTION_MESHPATH_SEL, hwmp_recv_action_meshpath); - - /* NB: default is 5 secs per spec */ - mesh_proto_hwmp.mpp_inact = msecs_to_ticks(5*1000); - - /* - * Register HWMP. - */ - ieee80211_mesh_register_proto_path(&mesh_proto_hwmp); -} -SYSINIT(wlan_hwmp, SI_SUB_DRIVERS, SI_ORDER_SECOND, ieee80211_hwmp_init, NULL); - -void -hwmp_vattach(struct ieee80211vap *vap) -{ - struct ieee80211_hwmp_state *hs; - - KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, - ("not a mesh vap, opmode %d", vap->iv_opmode)); - - hs = malloc(sizeof(struct ieee80211_hwmp_state), M_80211_VAP, - M_NOWAIT | M_ZERO); - if (hs == NULL) { - printf("%s: couldn't alloc HWMP state\n", __func__); - return; - } - hs->hs_maxhops = IEEE80211_HWMP_DEFAULT_MAXHOPS; - callout_init(&hs->hs_roottimer, CALLOUT_MPSAFE); - vap->iv_hwmp = hs; -} - -void -hwmp_vdetach(struct ieee80211vap *vap) -{ - struct ieee80211_hwmp_state *hs = vap->iv_hwmp; - - callout_drain(&hs->hs_roottimer); - free(vap->iv_hwmp, M_80211_VAP); - vap->iv_hwmp = NULL; -} - -int -hwmp_newstate(struct ieee80211vap *vap, enum ieee80211_state ostate, int arg) -{ - enum ieee80211_state nstate = vap->iv_state; - struct ieee80211_hwmp_state *hs = vap->iv_hwmp; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n", - __func__, ieee80211_state_name[ostate], - ieee80211_state_name[nstate], arg); - - if (nstate != IEEE80211_S_RUN && ostate == IEEE80211_S_RUN) - callout_drain(&hs->hs_roottimer); - if (nstate == IEEE80211_S_RUN) - hwmp_rootmode_setup(vap); - return 0; -} - -static int -hwmp_recv_action_meshpath(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_meshpreq_ie preq; - struct ieee80211_meshprep_ie prep; - struct ieee80211_meshperr_ie perr; - struct ieee80211_meshrann_ie rann; - const uint8_t *iefrm = frm + 2; /* action + code */ - int found = 0; - - while (efrm - iefrm > 1) { - IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0); - switch (*iefrm) { - case IEEE80211_ELEMID_MESHPREQ: - { - const struct ieee80211_meshpreq_ie *mpreq = - (const struct ieee80211_meshpreq_ie *) iefrm; - /* XXX > 1 target */ - if (mpreq->preq_len != - sizeof(struct ieee80211_meshpreq_ie) - 2) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, - wh, NULL, "%s", "PREQ with wrong len"); - vap->iv_stats.is_rx_mgtdiscard++; - break; - } - memcpy(&preq, mpreq, sizeof(preq)); - preq.preq_id = LE_READ_4(&mpreq->preq_id); - preq.preq_origseq = LE_READ_4(&mpreq->preq_origseq); - preq.preq_lifetime = LE_READ_4(&mpreq->preq_lifetime); - preq.preq_metric = LE_READ_4(&mpreq->preq_metric); - preq.preq_targets[0].target_seq = - LE_READ_4(&mpreq->preq_targets[0].target_seq); - hwmp_recv_preq(vap, ni, wh, &preq); - found++; - break; - } - case IEEE80211_ELEMID_MESHPREP: - { - const struct ieee80211_meshprep_ie *mprep = - (const struct ieee80211_meshprep_ie *) iefrm; - if (mprep->prep_len != - sizeof(struct ieee80211_meshprep_ie) - 2) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, - wh, NULL, "%s", "PREP with wrong len"); - vap->iv_stats.is_rx_mgtdiscard++; - break; - } - memcpy(&prep, mprep, sizeof(prep)); - prep.prep_targetseq = LE_READ_4(&mprep->prep_targetseq); - prep.prep_lifetime = LE_READ_4(&mprep->prep_lifetime); - prep.prep_metric = LE_READ_4(&mprep->prep_metric); - prep.prep_origseq = LE_READ_4(&mprep->prep_origseq); - hwmp_recv_prep(vap, ni, wh, &prep); - found++; - break; - } - case IEEE80211_ELEMID_MESHPERR: - { - const struct ieee80211_meshperr_ie *mperr = - (const struct ieee80211_meshperr_ie *) iefrm; - /* XXX > 1 target */ - if (mperr->perr_len != - sizeof(struct ieee80211_meshperr_ie) - 2) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, - wh, NULL, "%s", "PERR with wrong len"); - vap->iv_stats.is_rx_mgtdiscard++; - break; - } - memcpy(&perr, mperr, sizeof(perr)); - perr.perr_dests[0].dest_seq = - LE_READ_4(&mperr->perr_dests[0].dest_seq); - hwmp_recv_perr(vap, ni, wh, &perr); - found++; - break; - } - case IEEE80211_ELEMID_MESHRANN: - { - const struct ieee80211_meshrann_ie *mrann = - (const struct ieee80211_meshrann_ie *) iefrm; - if (mrann->rann_len != - sizeof(struct ieee80211_meshrann_ie) - 2) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, - wh, NULL, "%s", "RAN with wrong len"); - vap->iv_stats.is_rx_mgtdiscard++; - return 1; - } - memcpy(&rann, mrann, sizeof(rann)); - rann.rann_seq = LE_READ_4(&mrann->rann_seq); - rann.rann_metric = LE_READ_4(&mrann->rann_metric); - hwmp_recv_rann(vap, ni, wh, &rann); - found++; - break; - } - } - iefrm += iefrm[1] + 2; - } - if (!found) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, - wh, NULL, "%s", "PATH SEL action without IE"); - vap->iv_stats.is_rx_mgtdiscard++; - } - return 0; -} - -static int -hwmp_send_action(struct ieee80211_node *ni, - const uint8_t sa[IEEE80211_ADDR_LEN], - const uint8_t da[IEEE80211_ADDR_LEN], - uint8_t *ie, size_t len) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_bpf_params params; - struct mbuf *m; - uint8_t *frm; - - if (vap->iv_state == IEEE80211_S_CAC) { - IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, ni, - "block %s frame in CAC state", "HWMP action"); - vap->iv_stats.is_tx_badstate++; - return EIO; /* XXX */ - } - - KASSERT(ni != NULL, ("null node")); - /* - * Hold a reference on the node so it doesn't go away until after - * the xmit is complete all the way in the driver. On error we - * will remove our reference. - */ -#ifdef IEEE80211_DEBUG_REFCNT - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", - __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), - ieee80211_node_refcnt(ni)+1); -#endif - ieee80211_ref_node(ni); - - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(struct ieee80211_action) + len - ); - if (m == NULL) { - ieee80211_free_node(ni); - vap->iv_stats.is_tx_nobuf++; - return ENOMEM; - } - *frm++ = IEEE80211_ACTION_CAT_MESHPATH; - *frm++ = IEEE80211_ACTION_MESHPATH_SEL; - switch (*ie) { - case IEEE80211_ELEMID_MESHPREQ: - frm = hwmp_add_meshpreq(frm, - (struct ieee80211_meshpreq_ie *)ie); - break; - case IEEE80211_ELEMID_MESHPREP: - frm = hwmp_add_meshprep(frm, - (struct ieee80211_meshprep_ie *)ie); - break; - case IEEE80211_ELEMID_MESHPERR: - frm = hwmp_add_meshperr(frm, - (struct ieee80211_meshperr_ie *)ie); - break; - case IEEE80211_ELEMID_MESHRANN: - frm = hwmp_add_meshrann(frm, - (struct ieee80211_meshrann_ie *)ie); - break; - } - - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT); - if (m == NULL) { - ieee80211_free_node(ni); - vap->iv_stats.is_tx_nobuf++; - return ENOMEM; - } - ieee80211_send_setup(ni, m, - IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ACTION, - IEEE80211_NONQOS_TID, sa, da, sa); - - m->m_flags |= M_ENCAP; /* mark encapsulated */ - IEEE80211_NODE_STAT(ni, tx_mgmt); - - memset(¶ms, 0, sizeof(params)); - params.ibp_pri = WME_AC_VO; - params.ibp_rate0 = ni->ni_txparms->mgmtrate; - if (IEEE80211_IS_MULTICAST(da)) - params.ibp_try0 = 1; - else - params.ibp_try0 = ni->ni_txparms->maxretry; - params.ibp_power = ni->ni_txpower; - return ic->ic_raw_xmit(ni, m, ¶ms); -} - -#define ADDSHORT(frm, v) do { \ - frm[0] = (v) & 0xff; \ - frm[1] = (v) >> 8; \ - frm += 2; \ -} while (0) -#define ADDWORD(frm, v) do { \ - LE_WRITE_4(frm, v); \ - frm += 4; \ -} while (0) -/* - * Add a Mesh Path Request IE to a frame. - */ -static uint8_t * -hwmp_add_meshpreq(uint8_t *frm, const struct ieee80211_meshpreq_ie *preq) -{ - int i; - - *frm++ = IEEE80211_ELEMID_MESHPREQ; - *frm++ = sizeof(struct ieee80211_meshpreq_ie) - 2 + - (preq->preq_tcount - 1) * sizeof(*preq->preq_targets); - *frm++ = preq->preq_flags; - *frm++ = preq->preq_hopcount; - *frm++ = preq->preq_ttl; - ADDWORD(frm, preq->preq_id); - IEEE80211_ADDR_COPY(frm, preq->preq_origaddr); frm += 6; - ADDWORD(frm, preq->preq_origseq); - ADDWORD(frm, preq->preq_lifetime); - ADDWORD(frm, preq->preq_metric); - *frm++ = preq->preq_tcount; - for (i = 0; i < preq->preq_tcount; i++) { - *frm++ = preq->preq_targets[i].target_flags; - IEEE80211_ADDR_COPY(frm, preq->preq_targets[i].target_addr); - frm += 6; - ADDWORD(frm, preq->preq_targets[i].target_seq); - } - return frm; -} - -/* - * Add a Mesh Path Reply IE to a frame. - */ -static uint8_t * -hwmp_add_meshprep(uint8_t *frm, const struct ieee80211_meshprep_ie *prep) -{ - *frm++ = IEEE80211_ELEMID_MESHPREP; - *frm++ = sizeof(struct ieee80211_meshprep_ie) - 2; - *frm++ = prep->prep_flags; - *frm++ = prep->prep_hopcount; - *frm++ = prep->prep_ttl; - IEEE80211_ADDR_COPY(frm, prep->prep_targetaddr); frm += 6; - ADDWORD(frm, prep->prep_targetseq); - ADDWORD(frm, prep->prep_lifetime); - ADDWORD(frm, prep->prep_metric); - IEEE80211_ADDR_COPY(frm, prep->prep_origaddr); frm += 6; - ADDWORD(frm, prep->prep_origseq); - return frm; -} - -/* - * Add a Mesh Path Error IE to a frame. - */ -static uint8_t * -hwmp_add_meshperr(uint8_t *frm, const struct ieee80211_meshperr_ie *perr) -{ - int i; - - *frm++ = IEEE80211_ELEMID_MESHPERR; - *frm++ = sizeof(struct ieee80211_meshperr_ie) - 2 + - (perr->perr_ndests - 1) * sizeof(*perr->perr_dests); - *frm++ = perr->perr_ttl; - *frm++ = perr->perr_ndests; - for (i = 0; i < perr->perr_ndests; i++) { - *frm++ = perr->perr_dests[i].dest_flags; - IEEE80211_ADDR_COPY(frm, perr->perr_dests[i].dest_addr); - frm += 6; - ADDWORD(frm, perr->perr_dests[i].dest_seq); - ADDSHORT(frm, perr->perr_dests[i].dest_rcode); - } - return frm; -} - -/* - * Add a Root Annoucement IE to a frame. - */ -static uint8_t * -hwmp_add_meshrann(uint8_t *frm, const struct ieee80211_meshrann_ie *rann) -{ - *frm++ = IEEE80211_ELEMID_MESHRANN; - *frm++ = sizeof(struct ieee80211_meshrann_ie) - 2; - *frm++ = rann->rann_flags; - *frm++ = rann->rann_hopcount; - *frm++ = rann->rann_ttl; - IEEE80211_ADDR_COPY(frm, rann->rann_addr); frm += 6; - ADDWORD(frm, rann->rann_seq); - ADDWORD(frm, rann->rann_metric); - return frm; -} - -static void -hwmp_rootmode_setup(struct ieee80211vap *vap) -{ - struct ieee80211_hwmp_state *hs = vap->iv_hwmp; - - switch (hs->hs_rootmode) { - case IEEE80211_HWMP_ROOTMODE_DISABLED: - callout_drain(&hs->hs_roottimer); - break; - case IEEE80211_HWMP_ROOTMODE_NORMAL: - case IEEE80211_HWMP_ROOTMODE_PROACTIVE: - callout_reset(&hs->hs_roottimer, ieee80211_hwmp_rootint, - hwmp_rootmode_cb, vap); - break; - case IEEE80211_HWMP_ROOTMODE_RANN: - callout_reset(&hs->hs_roottimer, ieee80211_hwmp_rannint, - hwmp_rootmode_rann_cb, vap); - break; - } -} - -/* - * Send a broadcast Path Request to find all nodes on the mesh. We are - * called when the vap is configured as a HWMP root node. - */ -#define PREQ_TFLAGS(n) preq.preq_targets[n].target_flags -#define PREQ_TADDR(n) preq.preq_targets[n].target_addr -#define PREQ_TSEQ(n) preq.preq_targets[n].target_seq -static void -hwmp_rootmode_cb(void *arg) -{ - struct ieee80211vap *vap = (struct ieee80211vap *)arg; - struct ieee80211_hwmp_state *hs = vap->iv_hwmp; - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_meshpreq_ie preq; - - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss, - "%s", "send broadcast PREQ"); - - preq.preq_flags = IEEE80211_MESHPREQ_FLAGS_AM; - if (ms->ms_flags & IEEE80211_MESHFLAGS_PORTAL) - preq.preq_flags |= IEEE80211_MESHPREQ_FLAGS_PR; - if (hs->hs_rootmode == IEEE80211_HWMP_ROOTMODE_PROACTIVE) - preq.preq_flags |= IEEE80211_MESHPREQ_FLAGS_PP; - preq.preq_hopcount = 0; - preq.preq_ttl = ms->ms_ttl; - preq.preq_id = ++hs->hs_preqid; - IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr); - preq.preq_origseq = ++hs->hs_seq; - preq.preq_lifetime = ticks_to_msecs(ieee80211_hwmp_roottimeout); - preq.preq_metric = IEEE80211_MESHLMETRIC_INITIALVAL; - preq.preq_tcount = 1; - IEEE80211_ADDR_COPY(PREQ_TADDR(0), broadcastaddr); - PREQ_TFLAGS(0) = IEEE80211_MESHPREQ_TFLAGS_TO | - IEEE80211_MESHPREQ_TFLAGS_RF; - PREQ_TSEQ(0) = 0; - vap->iv_stats.is_hwmp_rootreqs++; - hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &preq); - hwmp_rootmode_setup(vap); -} -#undef PREQ_TFLAGS -#undef PREQ_TADDR -#undef PREQ_TSEQ - -/* - * Send a Root Annoucement (RANN) to find all the nodes on the mesh. We are - * called when the vap is configured as a HWMP RANN root node. - */ -static void -hwmp_rootmode_rann_cb(void *arg) -{ - struct ieee80211vap *vap = (struct ieee80211vap *)arg; - struct ieee80211_hwmp_state *hs = vap->iv_hwmp; - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_meshrann_ie rann; - - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss, - "%s", "send broadcast RANN"); - - rann.rann_flags = 0; - if (ms->ms_flags & IEEE80211_MESHFLAGS_PORTAL) - rann.rann_flags |= IEEE80211_MESHRANN_FLAGS_PR; - rann.rann_hopcount = 0; - rann.rann_ttl = ms->ms_ttl; - IEEE80211_ADDR_COPY(rann.rann_addr, vap->iv_myaddr); - rann.rann_seq = ++hs->hs_seq; - rann.rann_metric = IEEE80211_MESHLMETRIC_INITIALVAL; - - vap->iv_stats.is_hwmp_rootrann++; - hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &rann); - hwmp_rootmode_setup(vap); -} - -#define PREQ_TFLAGS(n) preq->preq_targets[n].target_flags -#define PREQ_TADDR(n) preq->preq_targets[n].target_addr -#define PREQ_TSEQ(n) preq->preq_targets[n].target_seq -static void -hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni, - const struct ieee80211_frame *wh, const struct ieee80211_meshpreq_ie *preq) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_mesh_route *rt = NULL; - struct ieee80211_mesh_route *rtorig = NULL; - struct ieee80211_hwmp_route *hrorig; - struct ieee80211_hwmp_state *hs = vap->iv_hwmp; - struct ieee80211_meshprep_ie prep; - - if (ni == vap->iv_bss || - ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) - return; - /* - * Ignore PREQs from us. Could happen because someone forward it - * back to us. - */ - if (IEEE80211_ADDR_EQ(vap->iv_myaddr, preq->preq_origaddr)) - return; - - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "received PREQ, source %s", ether_sprintf(preq->preq_origaddr)); - - /* - * Acceptance criteria: if the PREQ is not for us and - * forwarding is disabled, discard this PREQ. - */ - if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, PREQ_TADDR(0)) && - !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_HWMP, - preq->preq_origaddr, NULL, "%s", "not accepting PREQ"); - return; - } - rtorig = ieee80211_mesh_rt_find(vap, preq->preq_origaddr); - if (rtorig == NULL) - rtorig = ieee80211_mesh_rt_add(vap, preq->preq_origaddr); - if (rtorig == NULL) { - /* XXX stat */ - return; - } - hrorig = IEEE80211_MESH_ROUTE_PRIV(rtorig, struct ieee80211_hwmp_route); - /* - * Sequence number validation. - */ - if (HWMP_SEQ_LEQ(preq->preq_id, hrorig->hr_preqid) && - HWMP_SEQ_LEQ(preq->preq_origseq, hrorig->hr_seq)) { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "discard PREQ from %s, old seq no %u <= %u", - ether_sprintf(preq->preq_origaddr), - preq->preq_origseq, hrorig->hr_seq); - return; - } - hrorig->hr_preqid = preq->preq_id; - hrorig->hr_seq = preq->preq_origseq; - - /* - * Check if the PREQ is addressed to us. - */ - if (IEEE80211_ADDR_EQ(vap->iv_myaddr, PREQ_TADDR(0))) { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "reply to %s", ether_sprintf(preq->preq_origaddr)); - /* - * Build and send a PREP frame. - */ - prep.prep_flags = 0; - prep.prep_hopcount = 0; - prep.prep_ttl = ms->ms_ttl; - IEEE80211_ADDR_COPY(prep.prep_targetaddr, vap->iv_myaddr); - prep.prep_targetseq = ++hs->hs_seq; - prep.prep_lifetime = preq->preq_lifetime; - prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL; - IEEE80211_ADDR_COPY(prep.prep_origaddr, preq->preq_origaddr); - prep.prep_origseq = preq->preq_origseq; - hwmp_send_prep(ni, vap->iv_myaddr, wh->i_addr2, &prep); - /* - * Build the reverse path, if we don't have it already. - */ - rt = ieee80211_mesh_rt_find(vap, preq->preq_origaddr); - if (rt == NULL) - hwmp_discover(vap, preq->preq_origaddr, NULL); - else if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) - hwmp_discover(vap, rt->rt_dest, NULL); - return; - } - /* - * Proactive PREQ: reply with a proactive PREP to the - * root STA if requested. - */ - if (IEEE80211_ADDR_EQ(PREQ_TADDR(0), broadcastaddr) && - (PREQ_TFLAGS(0) & - ((IEEE80211_MESHPREQ_TFLAGS_TO|IEEE80211_MESHPREQ_TFLAGS_RF) == - (IEEE80211_MESHPREQ_TFLAGS_TO|IEEE80211_MESHPREQ_TFLAGS_RF)))) { - uint8_t rootmac[IEEE80211_ADDR_LEN]; - - IEEE80211_ADDR_COPY(rootmac, preq->preq_origaddr); - rt = ieee80211_mesh_rt_find(vap, rootmac); - if (rt == NULL) { - rt = ieee80211_mesh_rt_add(vap, rootmac); - if (rt == NULL) { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "unable to add root mesh path to %s", - ether_sprintf(rootmac)); - vap->iv_stats.is_mesh_rtaddfailed++; - return; - } - } - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "root mesh station @ %s", ether_sprintf(rootmac)); - - /* - * Reply with a PREP if we don't have a path to the root - * or if the root sent us a proactive PREQ. - */ - if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0 || - (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_PP)) { - prep.prep_flags = 0; - prep.prep_hopcount = 0; - prep.prep_ttl = ms->ms_ttl; - IEEE80211_ADDR_COPY(prep.prep_origaddr, rootmac); - prep.prep_origseq = preq->preq_origseq; - prep.prep_lifetime = preq->preq_lifetime; - prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL; - IEEE80211_ADDR_COPY(prep.prep_targetaddr, - vap->iv_myaddr); - prep.prep_targetseq = ++hs->hs_seq; - hwmp_send_prep(vap->iv_bss, vap->iv_myaddr, - broadcastaddr, &prep); - } - hwmp_discover(vap, rootmac, NULL); - return; - } - rt = ieee80211_mesh_rt_find(vap, PREQ_TADDR(0)); - - /* - * Forwarding and Intermediate reply for PREQs with 1 target. - */ - if (preq->preq_tcount == 1) { - struct ieee80211_meshpreq_ie ppreq; /* propagated PREQ */ - - memcpy(&ppreq, preq, sizeof(ppreq)); - /* - * We have a valid route to this node. - */ - if (rt != NULL && - (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID)) { - if (preq->preq_ttl > 1 && - preq->preq_hopcount < hs->hs_maxhops) { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "forward PREQ from %s", - ether_sprintf(preq->preq_origaddr)); - /* - * Propagate the original PREQ. - */ - ppreq.preq_hopcount += 1; - ppreq.preq_ttl -= 1; - ppreq.preq_metric += - ms->ms_pmetric->mpm_metric(ni); - /* - * Set TO and unset RF bits because we are going - * to send a PREP next. - */ - ppreq.preq_targets[0].target_flags |= - IEEE80211_MESHPREQ_TFLAGS_TO; - ppreq.preq_targets[0].target_flags &= - ~IEEE80211_MESHPREQ_TFLAGS_RF; - hwmp_send_preq(ni, vap->iv_myaddr, - broadcastaddr, &ppreq); - } - /* - * Check if we can send an intermediate Path Reply, - * i.e., Target Only bit is not set. - */ - if (!(PREQ_TFLAGS(0) & IEEE80211_MESHPREQ_TFLAGS_TO)) { - struct ieee80211_meshprep_ie prep; - - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "intermediate reply for PREQ from %s", - ether_sprintf(preq->preq_origaddr)); - prep.prep_flags = 0; - prep.prep_hopcount = rt->rt_nhops + 1; - prep.prep_ttl = ms->ms_ttl; - IEEE80211_ADDR_COPY(&prep.prep_targetaddr, - PREQ_TADDR(0)); - prep.prep_targetseq = hrorig->hr_seq; - prep.prep_lifetime = preq->preq_lifetime; - prep.prep_metric = rt->rt_metric + - ms->ms_pmetric->mpm_metric(ni); - IEEE80211_ADDR_COPY(&prep.prep_origaddr, - preq->preq_origaddr); - prep.prep_origseq = hrorig->hr_seq; - hwmp_send_prep(ni, vap->iv_myaddr, - broadcastaddr, &prep); - } - /* - * We have no information about this path, - * propagate the PREQ. - */ - } else if (preq->preq_ttl > 1 && - preq->preq_hopcount < hs->hs_maxhops) { - if (rt == NULL) { - rt = ieee80211_mesh_rt_add(vap, PREQ_TADDR(0)); - if (rt == NULL) { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, - ni, "unable to add PREQ path to %s", - ether_sprintf(PREQ_TADDR(0))); - vap->iv_stats.is_mesh_rtaddfailed++; - return; - } - } - rt->rt_metric = preq->preq_metric; - rt->rt_lifetime = preq->preq_lifetime; - hrorig = IEEE80211_MESH_ROUTE_PRIV(rt, - struct ieee80211_hwmp_route); - hrorig->hr_seq = preq->preq_origseq; - hrorig->hr_preqid = preq->preq_id; - - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "forward PREQ from %s", - ether_sprintf(preq->preq_origaddr)); - ppreq.preq_hopcount += 1; - ppreq.preq_ttl -= 1; - ppreq.preq_metric += ms->ms_pmetric->mpm_metric(ni); - hwmp_send_preq(ni, vap->iv_myaddr, broadcastaddr, - &ppreq); - } - } - -} -#undef PREQ_TFLAGS -#undef PREQ_TADDR -#undef PREQ_TSEQ - -static int -hwmp_send_preq(struct ieee80211_node *ni, - const uint8_t sa[IEEE80211_ADDR_LEN], - const uint8_t da[IEEE80211_ADDR_LEN], - struct ieee80211_meshpreq_ie *preq) -{ - struct ieee80211_hwmp_state *hs = ni->ni_vap->iv_hwmp; - - /* - * Enforce PREQ interval. - */ - if (ratecheck(&hs->hs_lastpreq, &ieee80211_hwmp_preqminint) == 0) - return EALREADY; - getmicrouptime(&hs->hs_lastpreq); - - /* - * mesh preq action frame format - * [6] da - * [6] sa - * [6] addr3 = sa - * [1] action - * [1] category - * [tlv] mesh path request - */ - preq->preq_ie = IEEE80211_ELEMID_MESHPREQ; - return hwmp_send_action(ni, sa, da, (uint8_t *)preq, - sizeof(struct ieee80211_meshpreq_ie)); -} - -static void -hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni, - const struct ieee80211_frame *wh, const struct ieee80211_meshprep_ie *prep) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_hwmp_state *hs = vap->iv_hwmp; - struct ieee80211_mesh_route *rt = NULL; - struct ieee80211_hwmp_route *hr; - struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = vap->iv_ifp; - struct mbuf *m, *next; - - /* - * Acceptance criteria: if the corresponding PREQ was not generated - * by us and forwarding is disabled, discard this PREP. - */ - if (ni == vap->iv_bss || - ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) - return; - if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) && - !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) - return; - - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "received PREP from %s", ether_sprintf(prep->prep_targetaddr)); - - rt = ieee80211_mesh_rt_find(vap, prep->prep_targetaddr); - if (rt == NULL) { - /* - * If we have no entry this could be a reply to a root PREQ. - */ - if (hs->hs_rootmode != IEEE80211_HWMP_ROOTMODE_DISABLED) { - rt = ieee80211_mesh_rt_add(vap, prep->prep_targetaddr); - if (rt == NULL) { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, - ni, "unable to add PREP path to %s", - ether_sprintf(prep->prep_targetaddr)); - vap->iv_stats.is_mesh_rtaddfailed++; - return; - } - IEEE80211_ADDR_COPY(rt->rt_nexthop, wh->i_addr2); - rt->rt_nhops = prep->prep_hopcount; - rt->rt_lifetime = prep->prep_lifetime; - rt->rt_metric = prep->prep_metric; - rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID; - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "add root path to %s nhops %d metric %d (PREP)", - ether_sprintf(prep->prep_targetaddr), - rt->rt_nhops, rt->rt_metric); - return; - } - return; - } - /* - * Sequence number validation. - */ - hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); - if (HWMP_SEQ_LEQ(prep->prep_targetseq, hr->hr_seq)) { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "discard PREP from %s, old seq no %u <= %u", - ether_sprintf(prep->prep_targetaddr), - prep->prep_targetseq, hr->hr_seq); - return; - } - hr->hr_seq = prep->prep_targetseq; - /* - * If it's NOT for us, propagate the PREP. - */ - if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) && - prep->prep_ttl > 1 && prep->prep_hopcount < hs->hs_maxhops) { - struct ieee80211_meshprep_ie pprep; /* propagated PREP */ - - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "propagate PREP from %s", - ether_sprintf(prep->prep_targetaddr)); - - memcpy(&pprep, prep, sizeof(pprep)); - pprep.prep_hopcount += 1; - pprep.prep_ttl -= 1; - pprep.prep_metric += ms->ms_pmetric->mpm_metric(ni); - IEEE80211_ADDR_COPY(pprep.prep_targetaddr, vap->iv_myaddr); - hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &pprep); - } - hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); - if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY) { - /* NB: never clobber a proxy entry */; - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "discard PREP for %s, route is marked PROXY", - ether_sprintf(prep->prep_targetaddr)); - vap->iv_stats.is_hwmp_proxy++; - } else if (prep->prep_origseq == hr->hr_origseq) { - /* - * Check if we already have a path to this node. - * If we do, check if this path reply contains a - * better route. - */ - if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0 || - (prep->prep_hopcount < rt->rt_nhops || - prep->prep_metric < rt->rt_metric)) { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "%s path to %s, hopcount %d:%d metric %d:%d", - rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID ? - "prefer" : "update", - ether_sprintf(prep->prep_origaddr), - rt->rt_nhops, prep->prep_hopcount, - rt->rt_metric, prep->prep_metric); - IEEE80211_ADDR_COPY(rt->rt_nexthop, wh->i_addr2); - rt->rt_nhops = prep->prep_hopcount; - rt->rt_lifetime = prep->prep_lifetime; - rt->rt_metric = prep->prep_metric; - rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID; - } else { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "ignore PREP for %s, hopcount %d:%d metric %d:%d", - ether_sprintf(prep->prep_targetaddr), - rt->rt_nhops, prep->prep_hopcount, - rt->rt_metric, prep->prep_metric); - } - } else { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "discard PREP for %s, wrong seqno %u != %u", - ether_sprintf(prep->prep_targetaddr), prep->prep_origseq, - hr->hr_seq); - vap->iv_stats.is_hwmp_wrongseq++; - } - /* - * Check for frames queued awaiting path discovery. - * XXX probably can tell exactly and avoid remove call - * NB: hash may have false matches, if so they will get - * stuck back on the stageq because there won't be - * a path. - */ - m = ieee80211_ageq_remove(&ic->ic_stageq, - (struct ieee80211_node *)(uintptr_t) - ieee80211_mac_hash(ic, rt->rt_dest)); - for (; m != NULL; m = next) { - next = m->m_nextpkt; - m->m_nextpkt = NULL; - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "flush queued frame %p len %d", m, m->m_pkthdr.len); - ifp->if_transmit(ifp, m); - } -} - -static int -hwmp_send_prep(struct ieee80211_node *ni, - const uint8_t sa[IEEE80211_ADDR_LEN], - const uint8_t da[IEEE80211_ADDR_LEN], - struct ieee80211_meshprep_ie *prep) -{ - /* NB: there's no PREP minimum interval. */ - - /* - * mesh prep action frame format - * [6] da - * [6] sa - * [6] addr3 = sa - * [1] action - * [1] category - * [tlv] mesh path reply - */ - prep->prep_ie = IEEE80211_ELEMID_MESHPREP; - return hwmp_send_action(ni, sa, da, (uint8_t *)prep, - sizeof(struct ieee80211_meshprep_ie)); -} - -#define PERR_DFLAGS(n) perr.perr_dests[n].dest_flags -#define PERR_DADDR(n) perr.perr_dests[n].dest_addr -#define PERR_DSEQ(n) perr.perr_dests[n].dest_seq -#define PERR_DRCODE(n) perr.perr_dests[n].dest_rcode -static void -hwmp_peerdown(struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_meshperr_ie perr; - struct ieee80211_mesh_route *rt; - struct ieee80211_hwmp_route *hr; - - rt = ieee80211_mesh_rt_find(vap, ni->ni_macaddr); - if (rt == NULL) - return; - hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "%s", "delete route entry"); - perr.perr_ttl = ms->ms_ttl; - perr.perr_ndests = 1; - PERR_DFLAGS(0) = 0; - if (hr->hr_seq == 0) - PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_USN; - PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_RC; - IEEE80211_ADDR_COPY(PERR_DADDR(0), rt->rt_dest); - PERR_DSEQ(0) = hr->hr_seq; - PERR_DRCODE(0) = IEEE80211_REASON_MESH_PERR_DEST_UNREACH; - /* NB: flush everything passing through peer */ - ieee80211_mesh_rt_flush_peer(vap, ni->ni_macaddr); - hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr); -} -#undef PERR_DFLAGS -#undef PERR_DADDR -#undef PERR_DSEQ -#undef PERR_DRCODE - -#define PERR_DFLAGS(n) perr->perr_dests[n].dest_flags -#define PERR_DADDR(n) perr->perr_dests[n].dest_addr -#define PERR_DSEQ(n) perr->perr_dests[n].dest_seq -#define PERR_DRCODE(n) perr->perr_dests[n].dest_rcode -static void -hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni, - const struct ieee80211_frame *wh, const struct ieee80211_meshperr_ie *perr) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_mesh_route *rt = NULL; - struct ieee80211_hwmp_route *hr; - struct ieee80211_meshperr_ie pperr; - int i, forward = 0; - - /* - * Acceptance criteria: check if we received a PERR from a - * neighbor and forwarding is enabled. - */ - if (ni == vap->iv_bss || - ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED || - !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) - return; - /* - * Find all routing entries that match and delete them. - */ - for (i = 0; i < perr->perr_ndests; i++) { - rt = ieee80211_mesh_rt_find(vap, PERR_DADDR(i)); - if (rt == NULL) - continue; - hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); - if (!(PERR_DFLAGS(0) & IEEE80211_MESHPERR_DFLAGS_USN) && - HWMP_SEQ_GEQ(PERR_DSEQ(i), hr->hr_seq)) { - ieee80211_mesh_rt_del(vap, rt->rt_dest); - ieee80211_mesh_rt_flush_peer(vap, rt->rt_dest); - rt = NULL; - forward = 1; - } - } - /* - * Propagate the PERR if we previously found it on our routing table. - * XXX handle ndest > 1 - */ - if (forward && perr->perr_ttl > 1) { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "propagate PERR from %s", ether_sprintf(wh->i_addr2)); - memcpy(&pperr, perr, sizeof(*perr)); - pperr.perr_ttl--; - hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, - &pperr); - } -} -#undef PEER_DADDR -#undef PERR_DSEQ - -static int -hwmp_send_perr(struct ieee80211_node *ni, - const uint8_t sa[IEEE80211_ADDR_LEN], - const uint8_t da[IEEE80211_ADDR_LEN], - struct ieee80211_meshperr_ie *perr) -{ - struct ieee80211_hwmp_state *hs = ni->ni_vap->iv_hwmp; - - /* - * Enforce PERR interval. - */ - if (ratecheck(&hs->hs_lastperr, &ieee80211_hwmp_perrminint) == 0) - return EALREADY; - getmicrouptime(&hs->hs_lastperr); - - /* - * mesh perr action frame format - * [6] da - * [6] sa - * [6] addr3 = sa - * [1] action - * [1] category - * [tlv] mesh path error - */ - perr->perr_ie = IEEE80211_ELEMID_MESHPERR; - return hwmp_send_action(ni, sa, da, (uint8_t *)perr, - sizeof(struct ieee80211_meshperr_ie)); -} - -static void -hwmp_recv_rann(struct ieee80211vap *vap, struct ieee80211_node *ni, - const struct ieee80211_frame *wh, const struct ieee80211_meshrann_ie *rann) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_hwmp_state *hs = vap->iv_hwmp; - struct ieee80211_mesh_route *rt = NULL; - struct ieee80211_hwmp_route *hr; - struct ieee80211_meshrann_ie prann; - - if (ni == vap->iv_bss || - ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED || - IEEE80211_ADDR_EQ(rann->rann_addr, vap->iv_myaddr)) - return; - - rt = ieee80211_mesh_rt_find(vap, rann->rann_addr); - /* - * Discover the path to the root mesh STA. - * If we already know it, propagate the RANN element. - */ - if (rt == NULL) { - hwmp_discover(vap, rann->rann_addr, NULL); - return; - } - hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); - if (HWMP_SEQ_GT(rann->rann_seq, hr->hr_seq)) { - hr->hr_seq = rann->rann_seq; - if (rann->rann_ttl > 1 && - rann->rann_hopcount < hs->hs_maxhops && - (ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) { - memcpy(&prann, rann, sizeof(prann)); - prann.rann_hopcount += 1; - prann.rann_ttl -= 1; - prann.rann_metric += ms->ms_pmetric->mpm_metric(ni); - hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, - broadcastaddr, &prann); - } - } -} - -static int -hwmp_send_rann(struct ieee80211_node *ni, - const uint8_t sa[IEEE80211_ADDR_LEN], - const uint8_t da[IEEE80211_ADDR_LEN], - struct ieee80211_meshrann_ie *rann) -{ - /* - * mesh rann action frame format - * [6] da - * [6] sa - * [6] addr3 = sa - * [1] action - * [1] category - * [tlv] root annoucement - */ - rann->rann_ie = IEEE80211_ELEMID_MESHRANN; - return hwmp_send_action(ni, sa, da, (uint8_t *)rann, - sizeof(struct ieee80211_meshrann_ie)); -} - -#define PREQ_TFLAGS(n) preq.preq_targets[n].target_flags -#define PREQ_TADDR(n) preq.preq_targets[n].target_addr -#define PREQ_TSEQ(n) preq.preq_targets[n].target_seq -static struct ieee80211_node * -hwmp_discover(struct ieee80211vap *vap, - const uint8_t dest[IEEE80211_ADDR_LEN], struct mbuf *m) -{ - struct ieee80211_hwmp_state *hs = vap->iv_hwmp; - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_mesh_route *rt = NULL; - struct ieee80211_hwmp_route *hr; - struct ieee80211_meshpreq_ie preq; - struct ieee80211_node *ni; - int sendpreq = 0; - - KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, - ("not a mesh vap, opmode %d", vap->iv_opmode)); - - KASSERT(!IEEE80211_ADDR_EQ(vap->iv_myaddr, dest), - ("%s: discovering self!", __func__)); - - ni = NULL; - if (!IEEE80211_IS_MULTICAST(dest)) { - rt = ieee80211_mesh_rt_find(vap, dest); - if (rt == NULL) { - rt = ieee80211_mesh_rt_add(vap, dest); - if (rt == NULL) { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, - ni, "unable to add discovery path to %s", - ether_sprintf(dest)); - vap->iv_stats.is_mesh_rtaddfailed++; - goto done; - } - } - hr = IEEE80211_MESH_ROUTE_PRIV(rt, - struct ieee80211_hwmp_route); - if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) { - if (hr->hr_origseq == 0) - hr->hr_origseq = ++hs->hs_seq; - rt->rt_metric = IEEE80211_MESHLMETRIC_INITIALVAL; - rt->rt_lifetime = - ticks_to_msecs(ieee80211_hwmp_pathtimeout); - /* XXX check preq retries */ - sendpreq = 1; - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP, dest, - "start path discovery (src %s)", - m == NULL ? "" : ether_sprintf( - mtod(m, struct ether_header *)->ether_shost)); - /* - * Try to discover the path for this node. - */ - preq.preq_flags = 0; - preq.preq_hopcount = 0; - preq.preq_ttl = ms->ms_ttl; - preq.preq_id = ++hs->hs_preqid; - IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr); - preq.preq_origseq = hr->hr_origseq; - preq.preq_lifetime = rt->rt_lifetime; - preq.preq_metric = rt->rt_metric; - preq.preq_tcount = 1; - IEEE80211_ADDR_COPY(PREQ_TADDR(0), dest); - PREQ_TFLAGS(0) = 0; - if (ieee80211_hwmp_targetonly) - PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_TO; - if (ieee80211_hwmp_replyforward) - PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_RF; - PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_USN; - PREQ_TSEQ(0) = 0; - /* XXX check return value */ - hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, - broadcastaddr, &preq); - } - if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) - ni = ieee80211_find_txnode(vap, rt->rt_nexthop); - } else { - ni = ieee80211_find_txnode(vap, dest); - /* NB: if null then we leak mbuf */ - KASSERT(ni != NULL, ("leak mcast frame")); - return ni; - } -done: - if (ni == NULL && m != NULL) { - if (sendpreq) { - struct ieee80211com *ic = vap->iv_ic; - /* - * Queue packet for transmit when path discovery - * completes. If discovery never completes the - * frame will be flushed by way of the aging timer. - */ - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP, dest, - "%s", "queue frame until path found"); - m->m_pkthdr.rcvif = (void *)(uintptr_t) - ieee80211_mac_hash(ic, dest); - /* XXX age chosen randomly */ - ieee80211_ageq_append(&ic->ic_stageq, m, - IEEE80211_INACT_WAIT); - } else { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_HWMP, - dest, NULL, "%s", "no valid path to this node"); - m_freem(m); - } - } - return ni; -} -#undef PREQ_TFLAGS -#undef PREQ_TADDR -#undef PREQ_TSEQ - -static int -hwmp_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211_hwmp_state *hs = vap->iv_hwmp; - int error; - - if (vap->iv_opmode != IEEE80211_M_MBSS) - return ENOSYS; - error = 0; - switch (ireq->i_type) { - case IEEE80211_IOC_HWMP_ROOTMODE: - ireq->i_val = hs->hs_rootmode; - break; - case IEEE80211_IOC_HWMP_MAXHOPS: - ireq->i_val = hs->hs_maxhops; - break; - default: - return ENOSYS; - } - return error; -} -IEEE80211_IOCTL_GET(hwmp, hwmp_ioctl_get80211); - -static int -hwmp_ioctl_set80211(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211_hwmp_state *hs = vap->iv_hwmp; - int error; - - if (vap->iv_opmode != IEEE80211_M_MBSS) - return ENOSYS; - error = 0; - switch (ireq->i_type) { - case IEEE80211_IOC_HWMP_ROOTMODE: - if (ireq->i_val < 0 || ireq->i_val > 3) - return EINVAL; - hs->hs_rootmode = ireq->i_val; - hwmp_rootmode_setup(vap); - break; - case IEEE80211_IOC_HWMP_MAXHOPS: - if (ireq->i_val <= 0 || ireq->i_val > 255) - return EINVAL; - hs->hs_maxhops = ireq->i_val; - break; - default: - return ENOSYS; - } - return error; -} -IEEE80211_IOCTL_SET(hwmp, hwmp_ioctl_set80211); diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_input.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_input.c deleted file mode 100644 index a18da4afe2..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_input.c +++ /dev/null @@ -1,894 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_wlan.h" - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include -#ifdef IEEE80211_SUPPORT_MESH -#include -#endif - -#include - -#ifdef INET -#include -#include -#endif - -static void -ieee80211_process_mimo(struct ieee80211_node *ni, struct ieee80211_rx_stats *rx) -{ - int i; - - /* Verify the required MIMO bits are set */ - if ((rx->r_flags & (IEEE80211_R_C_CHAIN | IEEE80211_R_C_NF | IEEE80211_R_C_RSSI)) != - (IEEE80211_R_C_CHAIN | IEEE80211_R_C_NF | IEEE80211_R_C_RSSI)) - return; - - /* XXX This assumes the MIMO radios have both ctl and ext chains */ - for (i = 0; i < MIN(rx->c_chain, IEEE80211_MAX_CHAINS); i++) { - IEEE80211_RSSI_LPF(ni->ni_mimo_rssi_ctl[i], rx->c_rssi_ctl[i]); - IEEE80211_RSSI_LPF(ni->ni_mimo_rssi_ext[i], rx->c_rssi_ext[i]); - } - - /* XXX This also assumes the MIMO radios have both ctl and ext chains */ - for(i = 0; i < MIN(rx->c_chain, IEEE80211_MAX_CHAINS); i++) { - ni->ni_mimo_noise_ctl[i] = rx->c_nf_ctl[i]; - ni->ni_mimo_noise_ext[i] = rx->c_nf_ext[i]; - } - ni->ni_mimo_chains = rx->c_chain; -} - -int -ieee80211_input_mimo(struct ieee80211_node *ni, struct mbuf *m, - struct ieee80211_rx_stats *rx) -{ - /* XXX should assert IEEE80211_R_NF and IEEE80211_R_RSSI are set */ - ieee80211_process_mimo(ni, rx); - return ieee80211_input(ni, m, rx->rssi, rx->nf); -} - -int -ieee80211_input_all(struct ieee80211com *ic, struct mbuf *m, int rssi, int nf) -{ - struct ieee80211_rx_stats rx; - - rx.r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI; - rx.nf = nf; - rx.rssi = rssi; - return ieee80211_input_mimo_all(ic, m, &rx); -} - -int -ieee80211_input_mimo_all(struct ieee80211com *ic, struct mbuf *m, - struct ieee80211_rx_stats *rx) -{ - struct ieee80211vap *vap; - int type = -1; - - m->m_flags |= M_BCAST; /* NB: mark for bpf tap'ing */ - - /* XXX locking */ - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - struct ieee80211_node *ni; - struct mbuf *mcopy; - - /* NB: could check for IFF_UP but this is cheaper */ - if (vap->iv_state == IEEE80211_S_INIT) - continue; - /* - * WDS vap's only receive directed traffic from the - * station at the ``far end''. That traffic should - * be passed through the AP vap the station is associated - * to--so don't spam them with mcast frames. - */ - if (vap->iv_opmode == IEEE80211_M_WDS) - continue; - if (TAILQ_NEXT(vap, iv_next) != NULL) { - /* - * Packet contents are changed by ieee80211_decap - * so do a deep copy of the packet. - */ - mcopy = m_dup(m, M_DONTWAIT); - if (mcopy == NULL) { - /* XXX stat+msg */ - continue; - } - } else { - mcopy = m; - m = NULL; - } - ni = ieee80211_ref_node(vap->iv_bss); - type = ieee80211_input_mimo(ni, mcopy, rx); - ieee80211_free_node(ni); - } - if (m != NULL) /* no vaps, reclaim mbuf */ - m_freem(m); - return type; -} - -/* - * This function reassembles fragments. - * - * XXX should handle 3 concurrent reassemblies per-spec. - */ -struct mbuf * -ieee80211_defrag(struct ieee80211_node *ni, struct mbuf *m, int hdrspace) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); - struct ieee80211_frame *lwh; - uint16_t rxseq; - uint8_t fragno; - uint8_t more_frag = wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG; - struct mbuf *mfrag; - - KASSERT(!IEEE80211_IS_MULTICAST(wh->i_addr1), ("multicast fragm?")); - - rxseq = le16toh(*(uint16_t *)wh->i_seq); - fragno = rxseq & IEEE80211_SEQ_FRAG_MASK; - - /* Quick way out, if there's nothing to defragment */ - if (!more_frag && fragno == 0 && ni->ni_rxfrag[0] == NULL) - return m; - - /* - * Remove frag to insure it doesn't get reaped by timer. - */ - if (ni->ni_table == NULL) { - /* - * Should never happen. If the node is orphaned (not in - * the table) then input packets should not reach here. - * Otherwise, a concurrent request that yanks the table - * should be blocked by other interlocking and/or by first - * shutting the driver down. Regardless, be defensive - * here and just bail - */ - /* XXX need msg+stat */ - m_freem(m); - return NULL; - } - IEEE80211_NODE_LOCK(ni->ni_table); - mfrag = ni->ni_rxfrag[0]; - ni->ni_rxfrag[0] = NULL; - IEEE80211_NODE_UNLOCK(ni->ni_table); - - /* - * Validate new fragment is in order and - * related to the previous ones. - */ - if (mfrag != NULL) { - uint16_t last_rxseq; - - lwh = mtod(mfrag, struct ieee80211_frame *); - last_rxseq = le16toh(*(uint16_t *)lwh->i_seq); - /* NB: check seq # and frag together */ - if (rxseq != last_rxseq+1 || - !IEEE80211_ADDR_EQ(wh->i_addr1, lwh->i_addr1) || - !IEEE80211_ADDR_EQ(wh->i_addr2, lwh->i_addr2)) { - /* - * Unrelated fragment or no space for it, - * clear current fragments. - */ - m_freem(mfrag); - mfrag = NULL; - } - } - - if (mfrag == NULL) { - if (fragno != 0) { /* !first fragment, discard */ - vap->iv_stats.is_rx_defrag++; - IEEE80211_NODE_STAT(ni, rx_defrag); - m_freem(m); - return NULL; - } - mfrag = m; - } else { /* concatenate */ - m_adj(m, hdrspace); /* strip header */ - m_cat(mfrag, m); - /* NB: m_cat doesn't update the packet header */ - mfrag->m_pkthdr.len += m->m_pkthdr.len; - /* track last seqnum and fragno */ - lwh = mtod(mfrag, struct ieee80211_frame *); - *(uint16_t *) lwh->i_seq = *(uint16_t *) wh->i_seq; - } - if (more_frag) { /* more to come, save */ - ni->ni_rxfragstamp = ticks; - ni->ni_rxfrag[0] = mfrag; - mfrag = NULL; - } - return mfrag; -} - -void -ieee80211_deliver_data(struct ieee80211vap *vap, - struct ieee80211_node *ni, struct mbuf *m) -{ - struct ether_header *eh = mtod(m, struct ether_header *); - struct ifnet *ifp = vap->iv_ifp; - - /* clear driver/net80211 flags before passing up */ - m->m_flags &= ~(M_80211_RX | M_MCAST | M_BCAST); - - /* NB: see hostap_deliver_data, this path doesn't handle hostap */ - KASSERT(vap->iv_opmode != IEEE80211_M_HOSTAP, ("gack, hostap")); - /* - * Do accounting. - */ - ifp->if_ipackets++; - IEEE80211_NODE_STAT(ni, rx_data); - IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len); - if (ETHER_IS_MULTICAST(eh->ether_dhost)) { - m->m_flags |= M_MCAST; /* XXX M_BCAST? */ - IEEE80211_NODE_STAT(ni, rx_mcast); - } else - IEEE80211_NODE_STAT(ni, rx_ucast); - m->m_pkthdr.rcvif = ifp; - - if (ni->ni_vlan != 0) { - /* attach vlan tag */ - m->m_pkthdr.ether_vtag = ni->ni_vlan; - m->m_flags |= M_VLANTAG; - } - ifp->if_input(ifp, m); -} - -struct mbuf * -ieee80211_decap(struct ieee80211vap *vap, struct mbuf *m, int hdrlen) -{ - struct ieee80211_qosframe_addr4 wh; - struct ether_header *eh; - struct llc *llc; - - KASSERT(hdrlen <= sizeof(wh), - ("hdrlen %d > max %zd", hdrlen, sizeof(wh))); - - if (m->m_len < hdrlen + sizeof(*llc) && - (m = m_pullup(m, hdrlen + sizeof(*llc))) == NULL) { - vap->iv_stats.is_rx_tooshort++; - /* XXX msg */ - return NULL; - } - memcpy(&wh, mtod(m, caddr_t), hdrlen); - llc = (struct llc *)(mtod(m, caddr_t) + hdrlen); - if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && - llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && - llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0 && - /* NB: preserve AppleTalk frames that have a native SNAP hdr */ - !(llc->llc_snap.ether_type == htons(ETHERTYPE_AARP) || - llc->llc_snap.ether_type == htons(ETHERTYPE_IPX))) { - m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh)); - llc = NULL; - } else { - m_adj(m, hdrlen - sizeof(*eh)); - } - eh = mtod(m, struct ether_header *); - switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { - case IEEE80211_FC1_DIR_NODS: - IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); - IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); - break; - case IEEE80211_FC1_DIR_TODS: - IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); - IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); - break; - case IEEE80211_FC1_DIR_FROMDS: - IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); - IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3); - break; - case IEEE80211_FC1_DIR_DSTODS: - IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); - IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr4); - break; - } -#ifdef ALIGNED_POINTER - if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), uint32_t)) { - m = ieee80211_realign(vap, m, sizeof(*eh)); - if (m == NULL) - return NULL; - } -#endif /* ALIGNED_POINTER */ - if (llc != NULL) { - eh = mtod(m, struct ether_header *); - eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh)); - } - return m; -} - -/* - * Decap a frame encapsulated in a fast-frame/A-MSDU. - */ -struct mbuf * -ieee80211_decap1(struct mbuf *m, int *framelen) -{ -#define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc)) - struct ether_header *eh; - struct llc *llc; - - /* - * The frame has an 802.3 header followed by an 802.2 - * LLC header. The encapsulated frame length is in the - * first header type field; save that and overwrite it - * with the true type field found in the second. Then - * copy the 802.3 header up to where it belongs and - * adjust the mbuf contents to remove the void. - */ - if (m->m_len < FF_LLC_SIZE && (m = m_pullup(m, FF_LLC_SIZE)) == NULL) - return NULL; - eh = mtod(m, struct ether_header *); /* 802.3 header is first */ - llc = (struct llc *)&eh[1]; /* 802.2 header follows */ - *framelen = ntohs(eh->ether_type) /* encap'd frame size */ - + sizeof(struct ether_header) - sizeof(struct llc); - eh->ether_type = llc->llc_un.type_snap.ether_type; - ovbcopy(eh, mtod(m, uint8_t *) + sizeof(struct llc), - sizeof(struct ether_header)); - m_adj(m, sizeof(struct llc)); - return m; -#undef FF_LLC_SIZE -} - -/* - * Install received rate set information in the node's state block. - */ -int -ieee80211_setup_rates(struct ieee80211_node *ni, - const uint8_t *rates, const uint8_t *xrates, int flags) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_rateset *rs = &ni->ni_rates; - - memset(rs, 0, sizeof(*rs)); - rs->rs_nrates = rates[1]; - memcpy(rs->rs_rates, rates + 2, rs->rs_nrates); - if (xrates != NULL) { - uint8_t nxrates; - /* - * Tack on 11g extended supported rate element. - */ - nxrates = xrates[1]; - if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) { - nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates; - IEEE80211_NOTE(vap, IEEE80211_MSG_XRATE, ni, - "extended rate set too large; only using " - "%u of %u rates", nxrates, xrates[1]); - vap->iv_stats.is_rx_rstoobig++; - } - memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates); - rs->rs_nrates += nxrates; - } - return ieee80211_fix_rate(ni, rs, flags); -} - -/* - * Send a management frame error response to the specified - * station. If ni is associated with the station then use - * it; otherwise allocate a temporary node suitable for - * transmitting the frame and then free the reference so - * it will go away as soon as the frame has been transmitted. - */ -void -ieee80211_send_error(struct ieee80211_node *ni, - const uint8_t mac[IEEE80211_ADDR_LEN], int subtype, int arg) -{ - struct ieee80211vap *vap = ni->ni_vap; - int istmp; - - if (ni == vap->iv_bss) { - if (vap->iv_state != IEEE80211_S_RUN) { - /* - * XXX hack until we get rid of this routine. - * We can be called prior to the vap reaching - * run state under certain conditions in which - * case iv_bss->ni_chan will not be setup. - * Check for this explicitly and and just ignore - * the request. - */ - return; - } - ni = ieee80211_tmp_node(vap, mac); - if (ni == NULL) { - /* XXX msg */ - return; - } - istmp = 1; - } else - istmp = 0; - IEEE80211_SEND_MGMT(ni, subtype, arg); - if (istmp) - ieee80211_free_node(ni); -} - -int -ieee80211_alloc_challenge(struct ieee80211_node *ni) -{ - if (ni->ni_challenge == NULL) - ni->ni_challenge = (uint32_t *) malloc(IEEE80211_CHALLENGE_LEN, - M_80211_NODE, M_NOWAIT); - if (ni->ni_challenge == NULL) { - IEEE80211_NOTE(ni->ni_vap, - IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, ni, - "%s", "shared key challenge alloc failed"); - /* XXX statistic */ - } - return (ni->ni_challenge != NULL); -} - -/* - * Parse a Beacon or ProbeResponse frame and return the - * useful information in an ieee80211_scanparams structure. - * Status is set to 0 if no problems were found; otherwise - * a bitmask of IEEE80211_BPARSE_* items is returned that - * describes the problems detected. - */ -int -ieee80211_parse_beacon(struct ieee80211_node *ni, struct mbuf *m, - struct ieee80211_scanparams *scan) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_frame *wh; - uint8_t *frm, *efrm; - - wh = mtod(m, struct ieee80211_frame *); - frm = (uint8_t *)&wh[1]; - efrm = mtod(m, uint8_t *) + m->m_len; - scan->status = 0; - /* - * beacon/probe response frame format - * [8] time stamp - * [2] beacon interval - * [2] capability information - * [tlv] ssid - * [tlv] supported rates - * [tlv] country information - * [tlv] channel switch announcement (CSA) - * [tlv] parameter set (FH/DS) - * [tlv] erp information - * [tlv] extended supported rates - * [tlv] WME - * [tlv] WPA or RSN - * [tlv] HT capabilities - * [tlv] HT information - * [tlv] Atheros capabilities - * [tlv] Mesh ID - * [tlv] Mesh Configuration - */ - IEEE80211_VERIFY_LENGTH(efrm - frm, 12, - return (scan->status = IEEE80211_BPARSE_BADIELEN)); - memset(scan, 0, sizeof(*scan)); - scan->tstamp = frm; frm += 8; - scan->bintval = le16toh(*(uint16_t *)frm); frm += 2; - scan->capinfo = le16toh(*(uint16_t *)frm); frm += 2; - scan->bchan = ieee80211_chan2ieee(ic, ic->ic_curchan); - scan->chan = scan->bchan; - scan->ies = frm; - scan->ies_len = efrm - frm; - - while (efrm - frm > 1) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, - return (scan->status = IEEE80211_BPARSE_BADIELEN)); - switch (*frm) { - case IEEE80211_ELEMID_SSID: - scan->ssid = frm; - break; - case IEEE80211_ELEMID_RATES: - scan->rates = frm; - break; - case IEEE80211_ELEMID_COUNTRY: - scan->country = frm; - break; - case IEEE80211_ELEMID_CSA: - scan->csa = frm; - break; - case IEEE80211_ELEMID_FHPARMS: - if (ic->ic_phytype == IEEE80211_T_FH) { - scan->fhdwell = LE_READ_2(&frm[2]); - scan->chan = IEEE80211_FH_CHAN(frm[4], frm[5]); - scan->fhindex = frm[6]; - } - break; - case IEEE80211_ELEMID_DSPARMS: - /* - * XXX hack this since depending on phytype - * is problematic for multi-mode devices. - */ - if (ic->ic_phytype != IEEE80211_T_FH) - scan->chan = frm[2]; - break; - case IEEE80211_ELEMID_TIM: - /* XXX ATIM? */ - scan->tim = frm; - scan->timoff = frm - mtod(m, uint8_t *); - break; - case IEEE80211_ELEMID_IBSSPARMS: - case IEEE80211_ELEMID_CFPARMS: - case IEEE80211_ELEMID_PWRCNSTR: - /* NB: avoid debugging complaints */ - break; - case IEEE80211_ELEMID_XRATES: - scan->xrates = frm; - break; - case IEEE80211_ELEMID_ERP: - if (frm[1] != 1) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID, wh, "ERP", - "bad len %u", frm[1]); - vap->iv_stats.is_rx_elem_toobig++; - break; - } - scan->erp = frm[2] | 0x100; - break; - case IEEE80211_ELEMID_HTCAP: - scan->htcap = frm; - break; - case IEEE80211_ELEMID_RSN: - scan->rsn = frm; - break; - case IEEE80211_ELEMID_HTINFO: - scan->htinfo = frm; - break; -#ifdef IEEE80211_SUPPORT_MESH - case IEEE80211_ELEMID_MESHID: - scan->meshid = frm; - break; - case IEEE80211_ELEMID_MESHCONF: - scan->meshconf = frm; - break; -#endif - case IEEE80211_ELEMID_VENDOR: - if (iswpaoui(frm)) - scan->wpa = frm; - else if (iswmeparam(frm) || iswmeinfo(frm)) - scan->wme = frm; -#ifdef IEEE80211_SUPPORT_SUPERG - else if (isatherosoui(frm)) - scan->ath = frm; -#endif -#ifdef IEEE80211_SUPPORT_TDMA - else if (istdmaoui(frm)) - scan->tdma = frm; -#endif - else if (vap->iv_flags_ht & IEEE80211_FHT_HTCOMPAT) { - /* - * Accept pre-draft HT ie's if the - * standard ones have not been seen. - */ - if (ishtcapoui(frm)) { - if (scan->htcap == NULL) - scan->htcap = frm; - } else if (ishtinfooui(frm)) { - if (scan->htinfo == NULL) - scan->htcap = frm; - } - } - break; - default: - IEEE80211_DISCARD_IE(vap, IEEE80211_MSG_ELEMID, - wh, "unhandled", - "id %u, len %u", *frm, frm[1]); - vap->iv_stats.is_rx_elem_unknown++; - break; - } - frm += frm[1] + 2; - } - IEEE80211_VERIFY_ELEMENT(scan->rates, IEEE80211_RATE_MAXSIZE, - scan->status |= IEEE80211_BPARSE_RATES_INVALID); - if (scan->rates != NULL && scan->xrates != NULL) { - /* - * NB: don't process XRATES if RATES is missing. This - * avoids a potential null ptr deref and should be ok - * as the return code will already note RATES is missing - * (so callers shouldn't otherwise process the frame). - */ - IEEE80211_VERIFY_ELEMENT(scan->xrates, - IEEE80211_RATE_MAXSIZE - scan->rates[1], - scan->status |= IEEE80211_BPARSE_XRATES_INVALID); - } - IEEE80211_VERIFY_ELEMENT(scan->ssid, IEEE80211_NWID_LEN, - scan->status |= IEEE80211_BPARSE_SSID_INVALID); - if (scan->chan != scan->bchan && ic->ic_phytype != IEEE80211_T_FH) { - /* - * Frame was received on a channel different from the - * one indicated in the DS params element id; - * silently discard it. - * - * NB: this can happen due to signal leakage. - * But we should take it for FH phy because - * the rssi value should be correct even for - * different hop pattern in FH. - */ - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT, - wh, NULL, "for off-channel %u", scan->chan); - vap->iv_stats.is_rx_chanmismatch++; - scan->status |= IEEE80211_BPARSE_OFFCHAN; - } - if (!(IEEE80211_BINTVAL_MIN <= scan->bintval && - scan->bintval <= IEEE80211_BINTVAL_MAX)) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT, - wh, NULL, "bogus beacon interval", scan->bintval); - vap->iv_stats.is_rx_badbintval++; - scan->status |= IEEE80211_BPARSE_BINTVAL_INVALID; - } - if (scan->country != NULL) { - /* - * Validate we have at least enough data to extract - * the country code. Not sure if we should return an - * error instead of discarding the IE; consider this - * being lenient as we don't depend on the data for - * correct operation. - */ - IEEE80211_VERIFY_LENGTH(scan->country[1], 3 * sizeof(uint8_t), - scan->country = NULL); - } - if (scan->csa != NULL) { - /* - * Validate Channel Switch Announcement; this must - * be the correct length or we toss the frame. - */ - IEEE80211_VERIFY_LENGTH(scan->csa[1], 3 * sizeof(uint8_t), - scan->status |= IEEE80211_BPARSE_CSA_INVALID); - } - /* - * Process HT ie's. This is complicated by our - * accepting both the standard ie's and the pre-draft - * vendor OUI ie's that some vendors still use/require. - */ - if (scan->htcap != NULL) { - IEEE80211_VERIFY_LENGTH(scan->htcap[1], - scan->htcap[0] == IEEE80211_ELEMID_VENDOR ? - 4 + sizeof(struct ieee80211_ie_htcap)-2 : - sizeof(struct ieee80211_ie_htcap)-2, - scan->htcap = NULL); - } - if (scan->htinfo != NULL) { - IEEE80211_VERIFY_LENGTH(scan->htinfo[1], - scan->htinfo[0] == IEEE80211_ELEMID_VENDOR ? - 4 + sizeof(struct ieee80211_ie_htinfo)-2 : - sizeof(struct ieee80211_ie_htinfo)-2, - scan->htinfo = NULL); - } - return scan->status; -} - -/* - * Parse an Action frame. Return 0 on success, non-zero on failure. - */ -int -ieee80211_parse_action(struct ieee80211_node *ni, struct mbuf *m) -{ - struct ieee80211vap *vap = ni->ni_vap; - const struct ieee80211_action *ia; - struct ieee80211_frame *wh; - uint8_t *frm, *efrm; - - /* - * action frame format: - * [1] category - * [1] action - * [tlv] parameters - */ - wh = mtod(m, struct ieee80211_frame *); - frm = (u_int8_t *)&wh[1]; - efrm = mtod(m, u_int8_t *) + m->m_len; - IEEE80211_VERIFY_LENGTH(efrm - frm, - sizeof(struct ieee80211_action), return EINVAL); - ia = (const struct ieee80211_action *) frm; - - vap->iv_stats.is_rx_action++; - IEEE80211_NODE_STAT(ni, rx_action); - - /* verify frame payloads but defer processing */ - switch (ia->ia_category) { - case IEEE80211_ACTION_CAT_BA: - switch (ia->ia_action) { - case IEEE80211_ACTION_BA_ADDBA_REQUEST: - IEEE80211_VERIFY_LENGTH(efrm - frm, - sizeof(struct ieee80211_action_ba_addbarequest), - return EINVAL); - break; - case IEEE80211_ACTION_BA_ADDBA_RESPONSE: - IEEE80211_VERIFY_LENGTH(efrm - frm, - sizeof(struct ieee80211_action_ba_addbaresponse), - return EINVAL); - break; - case IEEE80211_ACTION_BA_DELBA: - IEEE80211_VERIFY_LENGTH(efrm - frm, - sizeof(struct ieee80211_action_ba_delba), - return EINVAL); - break; - } - break; - case IEEE80211_ACTION_CAT_HT: - switch (ia->ia_action) { - case IEEE80211_ACTION_HT_TXCHWIDTH: - IEEE80211_VERIFY_LENGTH(efrm - frm, - sizeof(struct ieee80211_action_ht_txchwidth), - return EINVAL); - break; - case IEEE80211_ACTION_HT_MIMOPWRSAVE: - IEEE80211_VERIFY_LENGTH(efrm - frm, - sizeof(struct ieee80211_action_ht_mimopowersave), - return EINVAL); - break; - } - break; - } - return 0; -} - -#ifdef IEEE80211_DEBUG -/* - * Debugging support. - */ -void -ieee80211_ssid_mismatch(struct ieee80211vap *vap, const char *tag, - uint8_t mac[IEEE80211_ADDR_LEN], uint8_t *ssid) -{ - printf("[%s] discard %s frame, ssid mismatch: ", - ether_sprintf(mac), tag); - ieee80211_print_essid(ssid + 2, ssid[1]); - printf("\n"); -} - -/* - * Return the bssid of a frame. - */ -static const uint8_t * -ieee80211_getbssid(const struct ieee80211vap *vap, - const struct ieee80211_frame *wh) -{ - if (vap->iv_opmode == IEEE80211_M_STA) - return wh->i_addr2; - if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != IEEE80211_FC1_DIR_NODS) - return wh->i_addr1; - if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL) - return wh->i_addr1; - return wh->i_addr3; -} - -#include - -void -ieee80211_note(const struct ieee80211vap *vap, const char *fmt, ...) -{ - char buf[128]; /* XXX */ - va_list ap; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - if_printf(vap->iv_ifp, "%s", buf); /* NB: no \n */ -} - -void -ieee80211_note_frame(const struct ieee80211vap *vap, - const struct ieee80211_frame *wh, - const char *fmt, ...) -{ - char buf[128]; /* XXX */ - va_list ap; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - if_printf(vap->iv_ifp, "[%s] %s\n", - ether_sprintf(ieee80211_getbssid(vap, wh)), buf); -} - -void -ieee80211_note_mac(const struct ieee80211vap *vap, - const uint8_t mac[IEEE80211_ADDR_LEN], - const char *fmt, ...) -{ - char buf[128]; /* XXX */ - va_list ap; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - if_printf(vap->iv_ifp, "[%s] %s\n", ether_sprintf(mac), buf); -} - -void -ieee80211_discard_frame(const struct ieee80211vap *vap, - const struct ieee80211_frame *wh, - const char *type, const char *fmt, ...) -{ - va_list ap; - - if_printf(vap->iv_ifp, "[%s] discard ", - ether_sprintf(ieee80211_getbssid(vap, wh))); - if (type == NULL) { - printf("%s frame, ", ieee80211_mgt_subtype_name[ - (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >> - IEEE80211_FC0_SUBTYPE_SHIFT]); - } else - printf("%s frame, ", type); - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - printf("\n"); -} - -void -ieee80211_discard_ie(const struct ieee80211vap *vap, - const struct ieee80211_frame *wh, - const char *type, const char *fmt, ...) -{ - va_list ap; - - if_printf(vap->iv_ifp, "[%s] discard ", - ether_sprintf(ieee80211_getbssid(vap, wh))); - if (type != NULL) - printf("%s information element, ", type); - else - printf("information element, "); - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - printf("\n"); -} - -void -ieee80211_discard_mac(const struct ieee80211vap *vap, - const uint8_t mac[IEEE80211_ADDR_LEN], - const char *type, const char *fmt, ...) -{ - va_list ap; - - if_printf(vap->iv_ifp, "[%s] discard ", ether_sprintf(mac)); - if (type != NULL) - printf("%s frame, ", type); - else - printf("frame, "); - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - printf("\n"); -} -#endif /* IEEE80211_DEBUG */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_input.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_input.h deleted file mode 100644 index c5638a9579..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_input.h +++ /dev/null @@ -1,258 +0,0 @@ -/*- - * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_INPUT_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_INPUT_H_ - -/* Verify the existence and length of __elem or get out. */ -#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen, _action) do { \ - if ((__elem) == NULL) { \ - IEEE80211_DISCARD(vap, IEEE80211_MSG_ELEMID, \ - wh, NULL, "%s", "no " #__elem ); \ - vap->iv_stats.is_rx_elem_missing++; \ - _action; \ - } else if ((__elem)[1] > (__maxlen)) { \ - IEEE80211_DISCARD(vap, IEEE80211_MSG_ELEMID, \ - wh, NULL, "bad " #__elem " len %d", (__elem)[1]); \ - vap->iv_stats.is_rx_elem_toobig++; \ - _action; \ - } \ -} while (0) - -#define IEEE80211_VERIFY_LENGTH(_len, _minlen, _action) do { \ - if ((_len) < (_minlen)) { \ - IEEE80211_DISCARD(vap, IEEE80211_MSG_ELEMID, \ - wh, NULL, "ie too short, got %d, expected %d", \ - (_len), (_minlen)); \ - vap->iv_stats.is_rx_elem_toosmall++; \ - _action; \ - } \ -} while (0) - -#ifdef IEEE80211_DEBUG -void ieee80211_ssid_mismatch(struct ieee80211vap *, const char *tag, - uint8_t mac[IEEE80211_ADDR_LEN], uint8_t *ssid); - -#define IEEE80211_VERIFY_SSID(_ni, _ssid, _action) do { \ - if ((_ssid)[1] != 0 && \ - ((_ssid)[1] != (_ni)->ni_esslen || \ - memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \ - if (ieee80211_msg_input(vap)) \ - ieee80211_ssid_mismatch(vap, \ - ieee80211_mgt_subtype_name[subtype >> \ - IEEE80211_FC0_SUBTYPE_SHIFT], \ - wh->i_addr2, _ssid); \ - vap->iv_stats.is_rx_ssidmismatch++; \ - _action; \ - } \ -} while (0) -#else /* !IEEE80211_DEBUG */ -#define IEEE80211_VERIFY_SSID(_ni, _ssid, _action) do { \ - if ((_ssid)[1] != 0 && \ - ((_ssid)[1] != (_ni)->ni_esslen || \ - memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \ - vap->iv_stats.is_rx_ssidmismatch++; \ - _action; \ - } \ -} while (0) -#endif /* !IEEE80211_DEBUG */ - -/* unalligned little endian access */ -#define LE_READ_2(p) \ - ((uint16_t) \ - ((((const uint8_t *)(p))[0] ) | \ - (((const uint8_t *)(p))[1] << 8))) -#define LE_READ_4(p) \ - ((uint32_t) \ - ((((const uint8_t *)(p))[0] ) | \ - (((const uint8_t *)(p))[1] << 8) | \ - (((const uint8_t *)(p))[2] << 16) | \ - (((const uint8_t *)(p))[3] << 24))) - -static __inline int -iswpaoui(const uint8_t *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); -} - -static __inline int -iswmeoui(const uint8_t *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI); -} - -static __inline int -iswmeparam(const uint8_t *frm) -{ - return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && - frm[6] == WME_PARAM_OUI_SUBTYPE; -} - -static __inline int -iswmeinfo(const uint8_t *frm) -{ - return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && - frm[6] == WME_INFO_OUI_SUBTYPE; -} - -static __inline int -isatherosoui(const uint8_t *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI); -} - -static __inline int -istdmaoui(const uint8_t *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((TDMA_OUI_TYPE<<24)|TDMA_OUI); -} - -static __inline int -ishtcapoui(const uint8_t *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((BCM_OUI_HTCAP<<24)|BCM_OUI); -} - -static __inline int -ishtinfooui(const uint8_t *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((BCM_OUI_HTINFO<<24)|BCM_OUI); -} - -#include /* For le16toh() */ - -/* - * Check the current frame sequence number against the current TID - * state and return whether it's in sequence or should be dropped. - * - * Since out of order packet and duplicate packet eliminations should - * be done by the AMPDU RX code, this routine blindly accepts all - * frames from a HT station w/ a TID that is currently doing AMPDU-RX. - * HT stations without WME or where the TID is not doing AMPDU-RX - * are checked like non-HT stations. - * - * The routine only eliminates packets whose sequence/fragment - * match or are less than the last seen sequence/fragment number - * AND are retransmits It doesn't try to eliminate out of order packets. - * - * Since all frames after sequence number 4095 will be less than 4095 - * (as the seqnum wraps), handle that special case so packets aren't - * incorrectly dropped - ie, if the next packet is sequence number 0 - * but a retransmit since the initial packet didn't make it. - */ -static __inline int -ieee80211_check_rxseq(struct ieee80211_node *ni, struct ieee80211_frame *wh) -{ -#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) -#define SEQ_EQ(a,b) ((int)((a)-(b)) == 0) -#define HAS_SEQ(type) ((type & 0x4) == 0) -#define SEQNO(a) ((a) >> IEEE80211_SEQ_SEQ_SHIFT) -#define FRAGNO(a) ((a) & IEEE80211_SEQ_FRAG_MASK) - uint16_t rxseq; - uint8_t type; - uint8_t tid; - struct ieee80211_rx_ampdu *rap; - - rxseq = le16toh(*(uint16_t *)wh->i_seq); - type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; - - /* Types with no sequence number are always treated valid */ - if (! HAS_SEQ(type)) - return 1; - - tid = ieee80211_gettid(wh); - - /* - * Only do the HT AMPDU check for WME stations; non-WME HT stations - * shouldn't exist outside of debugging. We should at least - * handle that. - */ - if (tid < WME_NUM_TID) { - rap = &ni->ni_rx_ampdu[tid]; - /* HT nodes currently doing RX AMPDU are always valid */ - if ((ni->ni_flags & IEEE80211_NODE_HT) && - (rap->rxa_flags & IEEE80211_AGGR_RUNNING)) - return 1; - } - - /* - * Otherwise, retries for packets below or equal to the last - * seen sequence number should be dropped. - */ - - /* - * Treat frame seqnum 4095 as special due to boundary - * wrapping conditions. - */ - if (SEQNO(ni->ni_rxseqs[tid]) == 4095) { - /* - * Drop retransmits on seqnum 4095/current fragment for itself. - */ - if (SEQ_EQ(rxseq, ni->ni_rxseqs[tid]) && - (wh->i_fc[1] & IEEE80211_FC1_RETRY)) - return 0; - /* - * Treat any subsequent frame as fine if the last seen frame - * is 4095 and it's not a retransmit for the same sequence - * number. However, this doesn't capture incorrectly ordered - * fragments w/ sequence number 4095. It shouldn't be seen - * in practice, but see the comment above for further info. - */ - return 1; - } - - /* - * At this point we assume that retransmitted seq/frag numbers below - * the current can simply be eliminated. - */ - if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && - SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) - return 0; - - return 1; -#undef SEQ_LEQ -#undef SEQ_EQ -#undef HAS_SEQ -#undef SEQNO -#undef FRAGNO -} - -void ieee80211_deliver_data(struct ieee80211vap *, - struct ieee80211_node *, struct mbuf *); -struct mbuf *ieee80211_defrag(struct ieee80211_node *, - struct mbuf *, int); -struct mbuf *ieee80211_realign(struct ieee80211vap *, struct mbuf *, size_t); -struct mbuf *ieee80211_decap(struct ieee80211vap *, struct mbuf *, int); -struct mbuf *ieee80211_decap1(struct mbuf *, int *); -int ieee80211_setup_rates(struct ieee80211_node *ni, - const uint8_t *rates, const uint8_t *xrates, int flags); -void ieee80211_send_error(struct ieee80211_node *, - const uint8_t mac[IEEE80211_ADDR_LEN], int subtype, int arg); -int ieee80211_alloc_challenge(struct ieee80211_node *); -int ieee80211_parse_beacon(struct ieee80211_node *, struct mbuf *, - struct ieee80211_scanparams *); -int ieee80211_parse_action(struct ieee80211_node *, struct mbuf *); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_INPUT_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.c deleted file mode 100644 index 269ab45790..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.c +++ /dev/null @@ -1,3420 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 ioctl support (FreeBSD-specific) - */ - -#include "opt_inet.h" -#include "opt_ipx.h" -#include "opt_wlan.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef INET -#include -#include -#endif - -#ifdef IPX -#include -#include -#endif - -#include -#include -#include -#include - -#define IS_UP_AUTO(_vap) \ - (IFNET_IS_UP_RUNNING((_vap)->iv_ifp) && \ - (_vap)->iv_roaming == IEEE80211_ROAMING_AUTO) - -static const uint8_t zerobssid[IEEE80211_ADDR_LEN]; -static struct ieee80211_channel *findchannel(struct ieee80211com *, - int ieee, int mode); -static int ieee80211_scanreq(struct ieee80211vap *, - struct ieee80211_scan_req *); - -static __noinline int -ieee80211_ioctl_getkey(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni; - struct ieee80211req_key ik; - struct ieee80211_key *wk; - const struct ieee80211_cipher *cip; - u_int kid; - int error; - - if (ireq->i_len != sizeof(ik)) - return EINVAL; - error = copyin(ireq->i_data, &ik, sizeof(ik)); - if (error) - return error; - kid = ik.ik_keyix; - if (kid == IEEE80211_KEYIX_NONE) { - ni = ieee80211_find_vap_node(&ic->ic_sta, vap, ik.ik_macaddr); - if (ni == NULL) - return ENOENT; - wk = &ni->ni_ucastkey; - } else { - if (kid >= IEEE80211_WEP_NKID) - return EINVAL; - wk = &vap->iv_nw_keys[kid]; - IEEE80211_ADDR_COPY(&ik.ik_macaddr, vap->iv_bss->ni_macaddr); - ni = NULL; - } - cip = wk->wk_cipher; - ik.ik_type = cip->ic_cipher; - ik.ik_keylen = wk->wk_keylen; - ik.ik_flags = wk->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV); - if (wk->wk_keyix == vap->iv_def_txkey) - ik.ik_flags |= IEEE80211_KEY_DEFAULT; - if (priv_check(curthread, PRIV_NET80211_GETKEY) == 0) { - /* NB: only root can read key data */ - ik.ik_keyrsc = wk->wk_keyrsc[IEEE80211_NONQOS_TID]; - ik.ik_keytsc = wk->wk_keytsc; - memcpy(ik.ik_keydata, wk->wk_key, wk->wk_keylen); - if (cip->ic_cipher == IEEE80211_CIPHER_TKIP) { - memcpy(ik.ik_keydata+wk->wk_keylen, - wk->wk_key + IEEE80211_KEYBUF_SIZE, - IEEE80211_MICBUF_SIZE); - ik.ik_keylen += IEEE80211_MICBUF_SIZE; - } - } else { - ik.ik_keyrsc = 0; - ik.ik_keytsc = 0; - memset(ik.ik_keydata, 0, sizeof(ik.ik_keydata)); - } - if (ni != NULL) - ieee80211_free_node(ni); - return copyout(&ik, ireq->i_data, sizeof(ik)); -} - -static __noinline int -ieee80211_ioctl_getchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - - if (sizeof(ic->ic_chan_active) < ireq->i_len) - ireq->i_len = sizeof(ic->ic_chan_active); - return copyout(&ic->ic_chan_active, ireq->i_data, ireq->i_len); -} - -static __noinline int -ieee80211_ioctl_getchaninfo(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - uint32_t space; - - space = __offsetof(struct ieee80211req_chaninfo, - ic_chans[ic->ic_nchans]); - if (space > ireq->i_len) - space = ireq->i_len; - /* XXX assumes compatible layout */ - return copyout(&ic->ic_nchans, ireq->i_data, space); -} - -static __noinline int -ieee80211_ioctl_getwpaie(struct ieee80211vap *vap, - struct ieee80211req *ireq, int req) -{ - struct ieee80211_node *ni; - struct ieee80211req_wpaie2 wpaie; - int error; - - if (ireq->i_len < IEEE80211_ADDR_LEN) - return EINVAL; - error = copyin(ireq->i_data, wpaie.wpa_macaddr, IEEE80211_ADDR_LEN); - if (error != 0) - return error; - ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, wpaie.wpa_macaddr); - if (ni == NULL) - return ENOENT; - memset(wpaie.wpa_ie, 0, sizeof(wpaie.wpa_ie)); - if (ni->ni_ies.wpa_ie != NULL) { - int ielen = ni->ni_ies.wpa_ie[1] + 2; - if (ielen > sizeof(wpaie.wpa_ie)) - ielen = sizeof(wpaie.wpa_ie); - memcpy(wpaie.wpa_ie, ni->ni_ies.wpa_ie, ielen); - } - if (req == IEEE80211_IOC_WPAIE2) { - memset(wpaie.rsn_ie, 0, sizeof(wpaie.rsn_ie)); - if (ni->ni_ies.rsn_ie != NULL) { - int ielen = ni->ni_ies.rsn_ie[1] + 2; - if (ielen > sizeof(wpaie.rsn_ie)) - ielen = sizeof(wpaie.rsn_ie); - memcpy(wpaie.rsn_ie, ni->ni_ies.rsn_ie, ielen); - } - if (ireq->i_len > sizeof(struct ieee80211req_wpaie2)) - ireq->i_len = sizeof(struct ieee80211req_wpaie2); - } else { - /* compatibility op, may overwrite wpa ie */ - /* XXX check ic_flags? */ - if (ni->ni_ies.rsn_ie != NULL) { - int ielen = ni->ni_ies.rsn_ie[1] + 2; - if (ielen > sizeof(wpaie.wpa_ie)) - ielen = sizeof(wpaie.wpa_ie); - memcpy(wpaie.wpa_ie, ni->ni_ies.rsn_ie, ielen); - } - if (ireq->i_len > sizeof(struct ieee80211req_wpaie)) - ireq->i_len = sizeof(struct ieee80211req_wpaie); - } - ieee80211_free_node(ni); - return copyout(&wpaie, ireq->i_data, ireq->i_len); -} - -static __noinline int -ieee80211_ioctl_getstastats(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211_node *ni; - uint8_t macaddr[IEEE80211_ADDR_LEN]; - const size_t off = __offsetof(struct ieee80211req_sta_stats, is_stats); - int error; - - if (ireq->i_len < off) - return EINVAL; - error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); - if (error != 0) - return error; - ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr); - if (ni == NULL) - return ENOENT; - if (ireq->i_len > sizeof(struct ieee80211req_sta_stats)) - ireq->i_len = sizeof(struct ieee80211req_sta_stats); - /* NB: copy out only the statistics */ - error = copyout(&ni->ni_stats, (uint8_t *) ireq->i_data + off, - ireq->i_len - off); - ieee80211_free_node(ni); - return error; -} - -struct scanreq { - struct ieee80211req_scan_result *sr; - size_t space; -}; - -static size_t -scan_space(const struct ieee80211_scan_entry *se, int *ielen) -{ - size_t len; - - *ielen = se->se_ies.len; - /* - * NB: ie's can be no more than 255 bytes and the max 802.11 - * packet is <3Kbytes so we are sure this doesn't overflow - * 16-bits; if this is a concern we can drop the ie's. - */ - len = sizeof(struct ieee80211req_scan_result) + se->se_ssid[1] + - se->se_meshid[1] + *ielen; - return roundup(len, sizeof(uint32_t)); -} - -static void -get_scan_space(void *arg, const struct ieee80211_scan_entry *se) -{ - struct scanreq *req = arg; - int ielen; - - req->space += scan_space(se, &ielen); -} - -static __noinline void -get_scan_result(void *arg, const struct ieee80211_scan_entry *se) -{ - struct scanreq *req = arg; - struct ieee80211req_scan_result *sr; - int ielen, len, nr, nxr; - uint8_t *cp; - - len = scan_space(se, &ielen); - if (len > req->space) - return; - - sr = req->sr; - KASSERT(len <= 65535 && ielen <= 65535, - ("len %u ssid %u ie %u", len, se->se_ssid[1], ielen)); - sr->isr_len = len; - sr->isr_ie_off = sizeof(struct ieee80211req_scan_result); - sr->isr_ie_len = ielen; -#ifdef __HAIKU__ - memcpy(&sr->isr_chan, se->se_chan, sizeof(sr->isr_chan)); -#else - sr->isr_freq = se->se_chan->ic_freq; - sr->isr_flags = se->se_chan->ic_flags; -#endif - sr->isr_rssi = se->se_rssi; - sr->isr_noise = se->se_noise; - sr->isr_intval = se->se_intval; - sr->isr_capinfo = se->se_capinfo; - sr->isr_erp = se->se_erp; - IEEE80211_ADDR_COPY(sr->isr_bssid, se->se_bssid); - nr = min(se->se_rates[1], IEEE80211_RATE_MAXSIZE); - memcpy(sr->isr_rates, se->se_rates+2, nr); - nxr = min(se->se_xrates[1], IEEE80211_RATE_MAXSIZE - nr); - memcpy(sr->isr_rates+nr, se->se_xrates+2, nxr); - sr->isr_nrates = nr + nxr; - - /* copy SSID */ - sr->isr_ssid_len = se->se_ssid[1]; - cp = ((uint8_t *)sr) + sr->isr_ie_off; - memcpy(cp, se->se_ssid+2, sr->isr_ssid_len); - - /* copy mesh id */ - cp += sr->isr_ssid_len; - sr->isr_meshid_len = se->se_meshid[1]; - memcpy(cp, se->se_meshid+2, sr->isr_meshid_len); - cp += sr->isr_meshid_len; - - if (ielen) - memcpy(cp, se->se_ies.data, ielen); - - req->space -= len; - req->sr = (struct ieee80211req_scan_result *)(((uint8_t *)sr) + len); -} - -static __noinline int -ieee80211_ioctl_getscanresults(struct ieee80211vap *vap, - struct ieee80211req *ireq) -{ - struct scanreq req; - int error; - - if (ireq->i_len < sizeof(struct scanreq)) - return EFAULT; - - error = 0; - req.space = 0; - ieee80211_scan_iterate(vap, get_scan_space, &req); - if (req.space > ireq->i_len) - req.space = ireq->i_len; - if (req.space > 0) { - uint32_t space; - void *p; - - space = req.space; - /* XXX M_WAITOK after driver lock released */ - p = malloc(space, M_TEMP, M_NOWAIT | M_ZERO); - if (p == NULL) - return ENOMEM; - req.sr = p; - ieee80211_scan_iterate(vap, get_scan_result, &req); - ireq->i_len = space - req.space; - error = copyout(p, ireq->i_data, ireq->i_len); - free(p, M_TEMP); - } else - ireq->i_len = 0; - - return error; -} - -struct stainforeq { - struct ieee80211vap *vap; - struct ieee80211req_sta_info *si; - size_t space; -}; - -static size_t -sta_space(const struct ieee80211_node *ni, size_t *ielen) -{ - *ielen = ni->ni_ies.len; - return roundup(sizeof(struct ieee80211req_sta_info) + *ielen, - sizeof(uint32_t)); -} - -static void -get_sta_space(void *arg, struct ieee80211_node *ni) -{ - struct stainforeq *req = arg; - size_t ielen; - - if (req->vap != ni->ni_vap) - return; - if (ni->ni_vap->iv_opmode == IEEE80211_M_HOSTAP && - ni->ni_associd == 0) /* only associated stations */ - return; - req->space += sta_space(ni, &ielen); -} - -static __noinline void -get_sta_info(void *arg, struct ieee80211_node *ni) -{ - struct stainforeq *req = arg; - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211req_sta_info *si; - size_t ielen, len; - uint8_t *cp; - - if (req->vap != ni->ni_vap) - return; - if (vap->iv_opmode == IEEE80211_M_HOSTAP && - ni->ni_associd == 0) /* only associated stations */ - return; - if (ni->ni_chan == IEEE80211_CHAN_ANYC) /* XXX bogus entry */ - return; - len = sta_space(ni, &ielen); - if (len > req->space) - return; - si = req->si; - si->isi_len = len; - si->isi_ie_off = sizeof(struct ieee80211req_sta_info); - si->isi_ie_len = ielen; -#ifdef __HAIKU__ - memcpy(&si->isi_chan, ni->ni_chan, sizeof(si->isi_chan)); -#else - si->isi_freq = ni->ni_chan->ic_freq; - si->isi_flags = ni->ni_chan->ic_flags; -#endif - si->isi_state = ni->ni_flags; - si->isi_authmode = ni->ni_authmode; - vap->iv_ic->ic_node_getsignal(ni, &si->isi_rssi, &si->isi_noise); - vap->iv_ic->ic_node_getmimoinfo(ni, &si->isi_mimo); - si->isi_capinfo = ni->ni_capinfo; - si->isi_erp = ni->ni_erp; - IEEE80211_ADDR_COPY(si->isi_macaddr, ni->ni_macaddr); - si->isi_nrates = ni->ni_rates.rs_nrates; - if (si->isi_nrates > 15) - si->isi_nrates = 15; - memcpy(si->isi_rates, ni->ni_rates.rs_rates, si->isi_nrates); - si->isi_txrate = ni->ni_txrate; - if (si->isi_txrate & IEEE80211_RATE_MCS) { - const struct ieee80211_mcs_rates *mcs = - &ieee80211_htrates[ni->ni_txrate &~ IEEE80211_RATE_MCS]; - if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) { - if (ni->ni_flags & IEEE80211_NODE_SGI40) - si->isi_txmbps = mcs->ht40_rate_800ns; - else - si->isi_txmbps = mcs->ht40_rate_400ns; - } else { - if (ni->ni_flags & IEEE80211_NODE_SGI20) - si->isi_txmbps = mcs->ht20_rate_800ns; - else - si->isi_txmbps = mcs->ht20_rate_400ns; - } - } else - si->isi_txmbps = si->isi_txrate; - si->isi_associd = ni->ni_associd; - si->isi_txpower = ni->ni_txpower; - si->isi_vlan = ni->ni_vlan; - if (ni->ni_flags & IEEE80211_NODE_QOS) { - memcpy(si->isi_txseqs, ni->ni_txseqs, sizeof(ni->ni_txseqs)); - memcpy(si->isi_rxseqs, ni->ni_rxseqs, sizeof(ni->ni_rxseqs)); - } else { - si->isi_txseqs[0] = ni->ni_txseqs[IEEE80211_NONQOS_TID]; - si->isi_rxseqs[0] = ni->ni_rxseqs[IEEE80211_NONQOS_TID]; - } - /* NB: leave all cases in case we relax ni_associd == 0 check */ - if (ieee80211_node_is_authorized(ni)) - si->isi_inact = vap->iv_inact_run; - else if (ni->ni_associd != 0 || - (vap->iv_opmode == IEEE80211_M_WDS && - (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY))) - si->isi_inact = vap->iv_inact_auth; - else - si->isi_inact = vap->iv_inact_init; - si->isi_inact = (si->isi_inact - ni->ni_inact) * IEEE80211_INACT_WAIT; - si->isi_localid = ni->ni_mllid; - si->isi_peerid = ni->ni_mlpid; - si->isi_peerstate = ni->ni_mlstate; - - if (ielen) { - cp = ((uint8_t *)si) + si->isi_ie_off; - memcpy(cp, ni->ni_ies.data, ielen); - } - - req->si = (struct ieee80211req_sta_info *)(((uint8_t *)si) + len); - req->space -= len; -} - -static __noinline int -getstainfo_common(struct ieee80211vap *vap, struct ieee80211req *ireq, - struct ieee80211_node *ni, size_t off) -{ - struct ieee80211com *ic = vap->iv_ic; - struct stainforeq req; - size_t space; - void *p; - int error; - - error = 0; - req.space = 0; - req.vap = vap; - if (ni == NULL) - ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req); - else - get_sta_space(&req, ni); - if (req.space > ireq->i_len) - req.space = ireq->i_len; - if (req.space > 0) { - space = req.space; - /* XXX M_WAITOK after driver lock released */ - p = malloc(space, M_TEMP, M_NOWAIT | M_ZERO); - if (p == NULL) { - error = ENOMEM; - goto bad; - } - req.si = p; - if (ni == NULL) - ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req); - else - get_sta_info(&req, ni); - ireq->i_len = space - req.space; - error = copyout(p, (uint8_t *) ireq->i_data+off, ireq->i_len); - free(p, M_TEMP); - } else - ireq->i_len = 0; -bad: - if (ni != NULL) - ieee80211_free_node(ni); - return error; -} - -static __noinline int -ieee80211_ioctl_getstainfo(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - uint8_t macaddr[IEEE80211_ADDR_LEN]; - const size_t off = __offsetof(struct ieee80211req_sta_req, info); - struct ieee80211_node *ni; - int error; - - if (ireq->i_len < sizeof(struct ieee80211req_sta_req)) - return EFAULT; - error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); - if (error != 0) - return error; - if (IEEE80211_ADDR_EQ(macaddr, vap->iv_ifp->if_broadcastaddr)) { - ni = NULL; - } else { - ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr); - if (ni == NULL) - return ENOENT; - } - return getstainfo_common(vap, ireq, ni, off); -} - -static __noinline int -ieee80211_ioctl_getstatxpow(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211_node *ni; - struct ieee80211req_sta_txpow txpow; - int error; - - if (ireq->i_len != sizeof(txpow)) - return EINVAL; - error = copyin(ireq->i_data, &txpow, sizeof(txpow)); - if (error != 0) - return error; - ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, txpow.it_macaddr); - if (ni == NULL) - return ENOENT; - txpow.it_txpow = ni->ni_txpower; - error = copyout(&txpow, ireq->i_data, sizeof(txpow)); - ieee80211_free_node(ni); - return error; -} - -static __noinline int -ieee80211_ioctl_getwmeparam(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_wme_state *wme = &ic->ic_wme; - struct wmeParams *wmep; - int ac; - - if ((ic->ic_caps & IEEE80211_C_WME) == 0) - return EINVAL; - - ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL); - if (ac >= WME_NUM_AC) - ac = WME_AC_BE; - if (ireq->i_len & IEEE80211_WMEPARAM_BSS) - wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; - else - wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; - switch (ireq->i_type) { - case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ - ireq->i_val = wmep->wmep_logcwmin; - break; - case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ - ireq->i_val = wmep->wmep_logcwmax; - break; - case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ - ireq->i_val = wmep->wmep_aifsn; - break; - case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ - ireq->i_val = wmep->wmep_txopLimit; - break; - case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ - wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; - ireq->i_val = wmep->wmep_acm; - break; - case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only)*/ - wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; - ireq->i_val = !wmep->wmep_noackPolicy; - break; - } - return 0; -} - -static __noinline int -ieee80211_ioctl_getmaccmd(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - const struct ieee80211_aclator *acl = vap->iv_acl; - - return (acl == NULL ? EINVAL : acl->iac_getioctl(vap, ireq)); -} - -static __noinline int -ieee80211_ioctl_getcurchan(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_channel *c; - - if (ireq->i_len != sizeof(struct ieee80211_channel)) - return EINVAL; - /* - * vap's may have different operating channels when HT is - * in use. When in RUN state report the vap-specific channel. - * Otherwise return curchan. - */ - if (vap->iv_state == IEEE80211_S_RUN) - c = vap->iv_bss->ni_chan; - else - c = ic->ic_curchan; - return copyout(c, ireq->i_data, sizeof(*c)); -} - -static int -getappie(const struct ieee80211_appie *aie, struct ieee80211req *ireq) -{ - if (aie == NULL) - return EINVAL; - /* NB: truncate, caller can check length */ - if (ireq->i_len > aie->ie_len) - ireq->i_len = aie->ie_len; - return copyout(aie->ie_data, ireq->i_data, ireq->i_len); -} - -static int -ieee80211_ioctl_getappie(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - uint8_t fc0; - - fc0 = ireq->i_val & 0xff; - if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT) - return EINVAL; - /* NB: could check iv_opmode and reject but hardly worth the effort */ - switch (fc0 & IEEE80211_FC0_SUBTYPE_MASK) { - case IEEE80211_FC0_SUBTYPE_BEACON: - return getappie(vap->iv_appie_beacon, ireq); - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - return getappie(vap->iv_appie_proberesp, ireq); - case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: - return getappie(vap->iv_appie_assocresp, ireq); - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - return getappie(vap->iv_appie_probereq, ireq); - case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - return getappie(vap->iv_appie_assocreq, ireq); - case IEEE80211_FC0_SUBTYPE_BEACON|IEEE80211_FC0_SUBTYPE_PROBE_RESP: - return getappie(vap->iv_appie_wpa, ireq); - } - return EINVAL; -} - -static __noinline int -ieee80211_ioctl_getregdomain(struct ieee80211vap *vap, - const struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - - if (ireq->i_len != sizeof(ic->ic_regdomain)) - return EINVAL; - return copyout(&ic->ic_regdomain, ireq->i_data, - sizeof(ic->ic_regdomain)); -} - -static __noinline int -ieee80211_ioctl_getroam(struct ieee80211vap *vap, - const struct ieee80211req *ireq) -{ - size_t len = ireq->i_len; - /* NB: accept short requests for backwards compat */ - if (len > sizeof(vap->iv_roamparms)) - len = sizeof(vap->iv_roamparms); - return copyout(vap->iv_roamparms, ireq->i_data, len); -} - -static __noinline int -ieee80211_ioctl_gettxparams(struct ieee80211vap *vap, - const struct ieee80211req *ireq) -{ - size_t len = ireq->i_len; - /* NB: accept short requests for backwards compat */ - if (len > sizeof(vap->iv_txparms)) - len = sizeof(vap->iv_txparms); - return copyout(vap->iv_txparms, ireq->i_data, len); -} - -static __noinline int -ieee80211_ioctl_getdevcaps(struct ieee80211com *ic, - const struct ieee80211req *ireq) -{ - struct ieee80211_devcaps_req *dc; - struct ieee80211req_chaninfo *ci; - int maxchans, error; - - maxchans = 1 + ((ireq->i_len - sizeof(struct ieee80211_devcaps_req)) / - sizeof(struct ieee80211_channel)); - /* NB: require 1 so we know ic_nchans is accessible */ - if (maxchans < 1) - return EINVAL; - /* constrain max request size, 2K channels is ~24Kbytes */ - if (maxchans > 2048) - maxchans = 2048; - dc = (struct ieee80211_devcaps_req *) - malloc(IEEE80211_DEVCAPS_SIZE(maxchans), M_TEMP, M_NOWAIT | M_ZERO); - if (dc == NULL) - return ENOMEM; - dc->dc_drivercaps = ic->ic_caps; - dc->dc_cryptocaps = ic->ic_cryptocaps; - dc->dc_htcaps = ic->ic_htcaps; - ci = &dc->dc_chaninfo; - ic->ic_getradiocaps(ic, maxchans, &ci->ic_nchans, ci->ic_chans); - KASSERT(ci->ic_nchans <= maxchans, - ("nchans %d maxchans %d", ci->ic_nchans, maxchans)); - ieee80211_sort_channels(ci->ic_chans, ci->ic_nchans); - error = copyout(dc, ireq->i_data, IEEE80211_DEVCAPS_SPACE(dc)); - free(dc, M_TEMP); - return error; -} - -static __noinline int -ieee80211_ioctl_getstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211_node *ni; - struct ieee80211req_sta_vlan vlan; - int error; - - if (ireq->i_len != sizeof(vlan)) - return EINVAL; - error = copyin(ireq->i_data, &vlan, sizeof(vlan)); - if (error != 0) - return error; - if (!IEEE80211_ADDR_EQ(vlan.sv_macaddr, zerobssid)) { - ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, - vlan.sv_macaddr); - if (ni == NULL) - return ENOENT; - } else - ni = ieee80211_ref_node(vap->iv_bss); - vlan.sv_vlan = ni->ni_vlan; - error = copyout(&vlan, ireq->i_data, sizeof(vlan)); - ieee80211_free_node(ni); - return error; -} - -/* - * Dummy ioctl get handler so the linker set is defined. - */ -static int -dummy_ioctl_get(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - return ENOSYS; -} -IEEE80211_IOCTL_GET(dummy, dummy_ioctl_get); - -static int -ieee80211_ioctl_getdefault(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - ieee80211_ioctl_getfunc * const *get; - int error; - - SET_FOREACH(get, ieee80211_ioctl_getset) { - error = (*get)(vap, ireq); - if (error != ENOSYS) - return error; - } - return EINVAL; -} - -/* - * When building the kernel with -O2 on the i386 architecture, gcc - * seems to want to inline this function into ieee80211_ioctl() - * (which is the only routine that calls it). When this happens, - * ieee80211_ioctl() ends up consuming an additional 2K of stack - * space. (Exactly why it needs so much is unclear.) The problem - * is that it's possible for ieee80211_ioctl() to invoke other - * routines (including driver init functions) which could then find - * themselves perilously close to exhausting the stack. - * - * To avoid this, we deliberately prevent gcc from inlining this - * routine. Another way to avoid this is to use less agressive - * optimization when compiling this file (i.e. -O instead of -O2) - * but special-casing the compilation of this one module in the - * build system would be awkward. - */ -static __noinline int -ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd, - struct ieee80211req *ireq) -{ -#define MS(_v, _f) (((_v) & _f) >> _f##_S) - struct ieee80211com *ic = vap->iv_ic; - u_int kid, len; - uint8_t tmpkey[IEEE80211_KEYBUF_SIZE]; - char tmpssid[IEEE80211_NWID_LEN]; - int error = 0; - - switch (ireq->i_type) { - case IEEE80211_IOC_SSID: - switch (vap->iv_state) { - case IEEE80211_S_INIT: - case IEEE80211_S_SCAN: - ireq->i_len = vap->iv_des_ssid[0].len; - memcpy(tmpssid, vap->iv_des_ssid[0].ssid, ireq->i_len); - break; - default: - ireq->i_len = vap->iv_bss->ni_esslen; - memcpy(tmpssid, vap->iv_bss->ni_essid, ireq->i_len); - break; - } - error = copyout(tmpssid, ireq->i_data, ireq->i_len); - break; - case IEEE80211_IOC_NUMSSIDS: - ireq->i_val = 1; - break; - case IEEE80211_IOC_WEP: - if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) - ireq->i_val = IEEE80211_WEP_OFF; - else if (vap->iv_flags & IEEE80211_F_DROPUNENC) - ireq->i_val = IEEE80211_WEP_ON; - else - ireq->i_val = IEEE80211_WEP_MIXED; - break; - case IEEE80211_IOC_WEPKEY: - kid = (u_int) ireq->i_val; - if (kid >= IEEE80211_WEP_NKID) - return EINVAL; - len = (u_int) vap->iv_nw_keys[kid].wk_keylen; - /* NB: only root can read WEP keys */ - if (priv_check(curthread, PRIV_NET80211_GETKEY) == 0) { - bcopy(vap->iv_nw_keys[kid].wk_key, tmpkey, len); - } else { - bzero(tmpkey, len); - } - ireq->i_len = len; - error = copyout(tmpkey, ireq->i_data, len); - break; - case IEEE80211_IOC_NUMWEPKEYS: - ireq->i_val = IEEE80211_WEP_NKID; - break; - case IEEE80211_IOC_WEPTXKEY: - ireq->i_val = vap->iv_def_txkey; - break; - case IEEE80211_IOC_AUTHMODE: - if (vap->iv_flags & IEEE80211_F_WPA) - ireq->i_val = IEEE80211_AUTH_WPA; - else - ireq->i_val = vap->iv_bss->ni_authmode; - break; - case IEEE80211_IOC_CHANNEL: - ireq->i_val = ieee80211_chan2ieee(ic, ic->ic_curchan); - break; - case IEEE80211_IOC_POWERSAVE: - if (vap->iv_flags & IEEE80211_F_PMGTON) - ireq->i_val = IEEE80211_POWERSAVE_ON; - else - ireq->i_val = IEEE80211_POWERSAVE_OFF; - break; - case IEEE80211_IOC_POWERSAVESLEEP: - ireq->i_val = ic->ic_lintval; - break; - case IEEE80211_IOC_RTSTHRESHOLD: - ireq->i_val = vap->iv_rtsthreshold; - break; - case IEEE80211_IOC_PROTMODE: - ireq->i_val = ic->ic_protmode; - break; - case IEEE80211_IOC_TXPOWER: - /* - * Tx power limit is the min of max regulatory - * power, any user-set limit, and the max the - * radio can do. - */ - ireq->i_val = 2*ic->ic_curchan->ic_maxregpower; - if (ireq->i_val > ic->ic_txpowlimit) - ireq->i_val = ic->ic_txpowlimit; - if (ireq->i_val > ic->ic_curchan->ic_maxpower) - ireq->i_val = ic->ic_curchan->ic_maxpower; - break; - case IEEE80211_IOC_WPA: - switch (vap->iv_flags & IEEE80211_F_WPA) { - case IEEE80211_F_WPA1: - ireq->i_val = 1; - break; - case IEEE80211_F_WPA2: - ireq->i_val = 2; - break; - case IEEE80211_F_WPA1 | IEEE80211_F_WPA2: - ireq->i_val = 3; - break; - default: - ireq->i_val = 0; - break; - } - break; - case IEEE80211_IOC_CHANLIST: - error = ieee80211_ioctl_getchanlist(vap, ireq); - break; - case IEEE80211_IOC_ROAMING: - ireq->i_val = vap->iv_roaming; - break; - case IEEE80211_IOC_PRIVACY: - ireq->i_val = (vap->iv_flags & IEEE80211_F_PRIVACY) != 0; - break; - case IEEE80211_IOC_DROPUNENCRYPTED: - ireq->i_val = (vap->iv_flags & IEEE80211_F_DROPUNENC) != 0; - break; - case IEEE80211_IOC_COUNTERMEASURES: - ireq->i_val = (vap->iv_flags & IEEE80211_F_COUNTERM) != 0; - break; - case IEEE80211_IOC_WME: - ireq->i_val = (vap->iv_flags & IEEE80211_F_WME) != 0; - break; - case IEEE80211_IOC_HIDESSID: - ireq->i_val = (vap->iv_flags & IEEE80211_F_HIDESSID) != 0; - break; - case IEEE80211_IOC_APBRIDGE: - ireq->i_val = (vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0; - break; - case IEEE80211_IOC_WPAKEY: - error = ieee80211_ioctl_getkey(vap, ireq); - break; - case IEEE80211_IOC_CHANINFO: - error = ieee80211_ioctl_getchaninfo(vap, ireq); - break; - case IEEE80211_IOC_BSSID: - if (ireq->i_len != IEEE80211_ADDR_LEN) - return EINVAL; - if (vap->iv_state == IEEE80211_S_RUN) { - error = copyout(vap->iv_opmode == IEEE80211_M_WDS ? - vap->iv_bss->ni_macaddr : vap->iv_bss->ni_bssid, - ireq->i_data, ireq->i_len); - } else - error = copyout(vap->iv_des_bssid, ireq->i_data, - ireq->i_len); - break; - case IEEE80211_IOC_WPAIE: - error = ieee80211_ioctl_getwpaie(vap, ireq, ireq->i_type); - break; - case IEEE80211_IOC_WPAIE2: - error = ieee80211_ioctl_getwpaie(vap, ireq, ireq->i_type); - break; - case IEEE80211_IOC_SCAN_RESULTS: - error = ieee80211_ioctl_getscanresults(vap, ireq); - break; - case IEEE80211_IOC_STA_STATS: - error = ieee80211_ioctl_getstastats(vap, ireq); - break; - case IEEE80211_IOC_TXPOWMAX: - ireq->i_val = vap->iv_bss->ni_txpower; - break; - case IEEE80211_IOC_STA_TXPOW: - error = ieee80211_ioctl_getstatxpow(vap, ireq); - break; - case IEEE80211_IOC_STA_INFO: - error = ieee80211_ioctl_getstainfo(vap, ireq); - break; - case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ - case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ - case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ - case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ - case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ - case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ - error = ieee80211_ioctl_getwmeparam(vap, ireq); - break; - case IEEE80211_IOC_DTIM_PERIOD: - ireq->i_val = vap->iv_dtim_period; - break; - case IEEE80211_IOC_BEACON_INTERVAL: - /* NB: get from ic_bss for station mode */ - ireq->i_val = vap->iv_bss->ni_intval; - break; - case IEEE80211_IOC_PUREG: - ireq->i_val = (vap->iv_flags & IEEE80211_F_PUREG) != 0; - break; - case IEEE80211_IOC_BGSCAN: - ireq->i_val = (vap->iv_flags & IEEE80211_F_BGSCAN) != 0; - break; - case IEEE80211_IOC_BGSCAN_IDLE: - ireq->i_val = vap->iv_bgscanidle*hz/1000; /* ms */ - break; - case IEEE80211_IOC_BGSCAN_INTERVAL: - ireq->i_val = vap->iv_bgscanintvl/hz; /* seconds */ - break; - case IEEE80211_IOC_SCANVALID: - ireq->i_val = vap->iv_scanvalid/hz; /* seconds */ - break; - case IEEE80211_IOC_FRAGTHRESHOLD: - ireq->i_val = vap->iv_fragthreshold; - break; - case IEEE80211_IOC_MACCMD: - error = ieee80211_ioctl_getmaccmd(vap, ireq); - break; - case IEEE80211_IOC_BURST: - ireq->i_val = (vap->iv_flags & IEEE80211_F_BURST) != 0; - break; - case IEEE80211_IOC_BMISSTHRESHOLD: - ireq->i_val = vap->iv_bmissthreshold; - break; - case IEEE80211_IOC_CURCHAN: - error = ieee80211_ioctl_getcurchan(vap, ireq); - break; - case IEEE80211_IOC_SHORTGI: - ireq->i_val = 0; - if (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) - ireq->i_val |= IEEE80211_HTCAP_SHORTGI20; - if (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) - ireq->i_val |= IEEE80211_HTCAP_SHORTGI40; - break; - case IEEE80211_IOC_AMPDU: - ireq->i_val = 0; - if (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_TX) - ireq->i_val |= 1; - if (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_RX) - ireq->i_val |= 2; - break; - case IEEE80211_IOC_AMPDU_LIMIT: - if (vap->iv_opmode == IEEE80211_M_HOSTAP) - ireq->i_val = vap->iv_ampdu_rxmax; - else if (vap->iv_state == IEEE80211_S_RUN) - ireq->i_val = MS(vap->iv_bss->ni_htparam, - IEEE80211_HTCAP_MAXRXAMPDU); - else - ireq->i_val = vap->iv_ampdu_limit; - break; - case IEEE80211_IOC_AMPDU_DENSITY: - if (vap->iv_opmode == IEEE80211_M_STA && - vap->iv_state == IEEE80211_S_RUN) - ireq->i_val = MS(vap->iv_bss->ni_htparam, - IEEE80211_HTCAP_MPDUDENSITY); - else - ireq->i_val = vap->iv_ampdu_density; - break; - case IEEE80211_IOC_AMSDU: - ireq->i_val = 0; - if (vap->iv_flags_ht & IEEE80211_FHT_AMSDU_TX) - ireq->i_val |= 1; - if (vap->iv_flags_ht & IEEE80211_FHT_AMSDU_RX) - ireq->i_val |= 2; - break; - case IEEE80211_IOC_AMSDU_LIMIT: - ireq->i_val = vap->iv_amsdu_limit; /* XXX truncation? */ - break; - case IEEE80211_IOC_PUREN: - ireq->i_val = (vap->iv_flags_ht & IEEE80211_FHT_PUREN) != 0; - break; - case IEEE80211_IOC_DOTH: - ireq->i_val = (vap->iv_flags & IEEE80211_F_DOTH) != 0; - break; - case IEEE80211_IOC_REGDOMAIN: - error = ieee80211_ioctl_getregdomain(vap, ireq); - break; - case IEEE80211_IOC_ROAM: - error = ieee80211_ioctl_getroam(vap, ireq); - break; - case IEEE80211_IOC_TXPARAMS: - error = ieee80211_ioctl_gettxparams(vap, ireq); - break; - case IEEE80211_IOC_HTCOMPAT: - ireq->i_val = (vap->iv_flags_ht & IEEE80211_FHT_HTCOMPAT) != 0; - break; - case IEEE80211_IOC_DWDS: - ireq->i_val = (vap->iv_flags & IEEE80211_F_DWDS) != 0; - break; - case IEEE80211_IOC_INACTIVITY: - ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_INACT) != 0; - break; - case IEEE80211_IOC_APPIE: - error = ieee80211_ioctl_getappie(vap, ireq); - break; - case IEEE80211_IOC_WPS: - ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_WPS) != 0; - break; - case IEEE80211_IOC_TSN: - ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_TSN) != 0; - break; - case IEEE80211_IOC_DFS: - ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_DFS) != 0; - break; - case IEEE80211_IOC_DOTD: - ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_DOTD) != 0; - break; - case IEEE80211_IOC_DEVCAPS: - error = ieee80211_ioctl_getdevcaps(ic, ireq); - break; - case IEEE80211_IOC_HTPROTMODE: - ireq->i_val = ic->ic_htprotmode; - break; - case IEEE80211_IOC_HTCONF: - if (vap->iv_flags_ht & IEEE80211_FHT_HT) { - ireq->i_val = 1; - if (vap->iv_flags_ht & IEEE80211_FHT_USEHT40) - ireq->i_val |= 2; - } else - ireq->i_val = 0; - break; - case IEEE80211_IOC_STA_VLAN: - error = ieee80211_ioctl_getstavlan(vap, ireq); - break; - case IEEE80211_IOC_SMPS: - if (vap->iv_opmode == IEEE80211_M_STA && - vap->iv_state == IEEE80211_S_RUN) { - if (vap->iv_bss->ni_flags & IEEE80211_NODE_MIMO_RTS) - ireq->i_val = IEEE80211_HTCAP_SMPS_DYNAMIC; - else if (vap->iv_bss->ni_flags & IEEE80211_NODE_MIMO_PS) - ireq->i_val = IEEE80211_HTCAP_SMPS_ENA; - else - ireq->i_val = IEEE80211_HTCAP_SMPS_OFF; - } else - ireq->i_val = vap->iv_htcaps & IEEE80211_HTCAP_SMPS; - break; - case IEEE80211_IOC_RIFS: - if (vap->iv_opmode == IEEE80211_M_STA && - vap->iv_state == IEEE80211_S_RUN) - ireq->i_val = - (vap->iv_bss->ni_flags & IEEE80211_NODE_RIFS) != 0; - else - ireq->i_val = - (vap->iv_flags_ht & IEEE80211_FHT_RIFS) != 0; - break; - default: - error = ieee80211_ioctl_getdefault(vap, ireq); - break; - } - return error; -#undef MS -} - -static __noinline int -ieee80211_ioctl_setkey(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211req_key ik; - struct ieee80211_node *ni; - struct ieee80211_key *wk; - uint16_t kid; - int error, i; - - if (ireq->i_len != sizeof(ik)) - return EINVAL; - error = copyin(ireq->i_data, &ik, sizeof(ik)); - if (error) - return error; - /* NB: cipher support is verified by ieee80211_crypt_newkey */ - /* NB: this also checks ik->ik_keylen > sizeof(wk->wk_key) */ - if (ik.ik_keylen > sizeof(ik.ik_keydata)) - return E2BIG; - kid = ik.ik_keyix; - if (kid == IEEE80211_KEYIX_NONE) { - /* XXX unicast keys currently must be tx/rx */ - if (ik.ik_flags != (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV)) - return EINVAL; - if (vap->iv_opmode == IEEE80211_M_STA) { - ni = ieee80211_ref_node(vap->iv_bss); - if (!IEEE80211_ADDR_EQ(ik.ik_macaddr, ni->ni_bssid)) { - ieee80211_free_node(ni); - return EADDRNOTAVAIL; - } - } else { - ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, - ik.ik_macaddr); - if (ni == NULL) - return ENOENT; - } - wk = &ni->ni_ucastkey; - } else { - if (kid >= IEEE80211_WEP_NKID) - return EINVAL; - wk = &vap->iv_nw_keys[kid]; - /* - * Global slots start off w/o any assigned key index. - * Force one here for consistency with IEEE80211_IOC_WEPKEY. - */ - if (wk->wk_keyix == IEEE80211_KEYIX_NONE) - wk->wk_keyix = kid; - ni = NULL; - } - error = 0; - ieee80211_key_update_begin(vap); - if (ieee80211_crypto_newkey(vap, ik.ik_type, ik.ik_flags, wk)) { - wk->wk_keylen = ik.ik_keylen; - /* NB: MIC presence is implied by cipher type */ - if (wk->wk_keylen > IEEE80211_KEYBUF_SIZE) - wk->wk_keylen = IEEE80211_KEYBUF_SIZE; - for (i = 0; i < IEEE80211_TID_SIZE; i++) - wk->wk_keyrsc[i] = ik.ik_keyrsc; - wk->wk_keytsc = 0; /* new key, reset */ - memset(wk->wk_key, 0, sizeof(wk->wk_key)); - memcpy(wk->wk_key, ik.ik_keydata, ik.ik_keylen); - IEEE80211_ADDR_COPY(wk->wk_macaddr, - ni != NULL ? ni->ni_macaddr : ik.ik_macaddr); - if (!ieee80211_crypto_setkey(vap, wk)) - error = EIO; - else if ((ik.ik_flags & IEEE80211_KEY_DEFAULT)) - vap->iv_def_txkey = kid; - } else - error = ENXIO; - ieee80211_key_update_end(vap); - if (ni != NULL) - ieee80211_free_node(ni); - return error; -} - -static __noinline int -ieee80211_ioctl_delkey(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211req_del_key dk; - int kid, error; - - if (ireq->i_len != sizeof(dk)) - return EINVAL; - error = copyin(ireq->i_data, &dk, sizeof(dk)); - if (error) - return error; - kid = dk.idk_keyix; - /* XXX uint8_t -> uint16_t */ - if (dk.idk_keyix == (uint8_t) IEEE80211_KEYIX_NONE) { - struct ieee80211_node *ni; - - if (vap->iv_opmode == IEEE80211_M_STA) { - ni = ieee80211_ref_node(vap->iv_bss); - if (!IEEE80211_ADDR_EQ(dk.idk_macaddr, ni->ni_bssid)) { - ieee80211_free_node(ni); - return EADDRNOTAVAIL; - } - } else { - ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, - dk.idk_macaddr); - if (ni == NULL) - return ENOENT; - } - /* XXX error return */ - ieee80211_node_delucastkey(ni); - ieee80211_free_node(ni); - } else { - if (kid >= IEEE80211_WEP_NKID) - return EINVAL; - /* XXX error return */ - ieee80211_crypto_delkey(vap, &vap->iv_nw_keys[kid]); - } - return 0; -} - -struct mlmeop { - struct ieee80211vap *vap; - int op; - int reason; -}; - -static void -mlmedebug(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], - int op, int reason) -{ -#ifdef IEEE80211_DEBUG - static const struct { - int mask; - const char *opstr; - } ops[] = { - { 0, "op#0" }, - { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | - IEEE80211_MSG_ASSOC, "assoc" }, - { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | - IEEE80211_MSG_ASSOC, "disassoc" }, - { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | - IEEE80211_MSG_AUTH, "deauth" }, - { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | - IEEE80211_MSG_AUTH, "authorize" }, - { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | - IEEE80211_MSG_AUTH, "unauthorize" }, - }; - - if (op == IEEE80211_MLME_AUTH) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_IOCTL | - IEEE80211_MSG_STATE | IEEE80211_MSG_AUTH, mac, - "station authenticate %s via MLME (reason %d)", - reason == IEEE80211_STATUS_SUCCESS ? "ACCEPT" : "REJECT", - reason); - } else if (!(IEEE80211_MLME_ASSOC <= op && op <= IEEE80211_MLME_AUTH)) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY, mac, - "unknown MLME request %d (reason %d)", op, reason); - } else if (reason == IEEE80211_STATUS_SUCCESS) { - IEEE80211_NOTE_MAC(vap, ops[op].mask, mac, - "station %s via MLME", ops[op].opstr); - } else { - IEEE80211_NOTE_MAC(vap, ops[op].mask, mac, - "station %s via MLME (reason %d)", ops[op].opstr, reason); - } -#endif /* IEEE80211_DEBUG */ -} - -static void -domlme(void *arg, struct ieee80211_node *ni) -{ - struct mlmeop *mop = arg; - struct ieee80211vap *vap = ni->ni_vap; - - if (vap != mop->vap) - return; - /* - * NB: if ni_associd is zero then the node is already cleaned - * up and we don't need to do this (we're safely holding a - * reference but should otherwise not modify it's state). - */ - if (ni->ni_associd == 0) - return; - mlmedebug(vap, ni->ni_macaddr, mop->op, mop->reason); - if (mop->op == IEEE80211_MLME_DEAUTH) { - IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DEAUTH, - mop->reason); - } else { - IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DISASSOC, - mop->reason); - } - ieee80211_node_leave(ni); -} - -static int -setmlme_dropsta(struct ieee80211vap *vap, - const uint8_t mac[IEEE80211_ADDR_LEN], struct mlmeop *mlmeop) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node_table *nt = &ic->ic_sta; - struct ieee80211_node *ni; - int error = 0; - - /* NB: the broadcast address means do 'em all */ - if (!IEEE80211_ADDR_EQ(mac, ic->ic_ifp->if_broadcastaddr)) { - IEEE80211_NODE_LOCK(nt); - ni = ieee80211_find_node_locked(nt, mac); - if (ni != NULL) { - domlme(mlmeop, ni); - ieee80211_free_node(ni); - } else - error = ENOENT; - IEEE80211_NODE_UNLOCK(nt); - } else { - ieee80211_iterate_nodes(nt, domlme, mlmeop); - } - return error; -} - -static __noinline int -setmlme_common(struct ieee80211vap *vap, int op, - const uint8_t mac[IEEE80211_ADDR_LEN], int reason) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node_table *nt = &ic->ic_sta; - struct ieee80211_node *ni; - struct mlmeop mlmeop; - int error; - - error = 0; - switch (op) { - case IEEE80211_MLME_DISASSOC: - case IEEE80211_MLME_DEAUTH: - switch (vap->iv_opmode) { - case IEEE80211_M_STA: - mlmedebug(vap, vap->iv_bss->ni_macaddr, op, reason); - /* XXX not quite right */ - ieee80211_new_state(vap, IEEE80211_S_INIT, reason); - break; - case IEEE80211_M_HOSTAP: - mlmeop.vap = vap; - mlmeop.op = op; - mlmeop.reason = reason; - error = setmlme_dropsta(vap, mac, &mlmeop); - break; - case IEEE80211_M_WDS: - /* XXX user app should send raw frame? */ - if (op != IEEE80211_MLME_DEAUTH) { - error = EINVAL; - break; - } -#if 0 - /* XXX accept any address, simplifies user code */ - if (!IEEE80211_ADDR_EQ(mac, vap->iv_bss->ni_macaddr)) { - error = EINVAL; - break; - } -#endif - mlmedebug(vap, vap->iv_bss->ni_macaddr, op, reason); - ni = ieee80211_ref_node(vap->iv_bss); - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_DEAUTH, reason); - ieee80211_free_node(ni); - break; - default: - error = EINVAL; - break; - } - break; - case IEEE80211_MLME_AUTHORIZE: - case IEEE80211_MLME_UNAUTHORIZE: - if (vap->iv_opmode != IEEE80211_M_HOSTAP && - vap->iv_opmode != IEEE80211_M_WDS) { - error = EINVAL; - break; - } - IEEE80211_NODE_LOCK(nt); - ni = ieee80211_find_vap_node_locked(nt, vap, mac); - if (ni != NULL) { - mlmedebug(vap, mac, op, reason); - if (op == IEEE80211_MLME_AUTHORIZE) - ieee80211_node_authorize(ni); - else - ieee80211_node_unauthorize(ni); - ieee80211_free_node(ni); - } else - error = ENOENT; - IEEE80211_NODE_UNLOCK(nt); - break; - case IEEE80211_MLME_AUTH: - if (vap->iv_opmode != IEEE80211_M_HOSTAP) { - error = EINVAL; - break; - } - IEEE80211_NODE_LOCK(nt); - ni = ieee80211_find_vap_node_locked(nt, vap, mac); - if (ni != NULL) { - mlmedebug(vap, mac, op, reason); - if (reason == IEEE80211_STATUS_SUCCESS) { - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_AUTH, 2); - /* - * For shared key auth, just continue the - * exchange. Otherwise when 802.1x is not in - * use mark the port authorized at this point - * so traffic can flow. - */ - if (ni->ni_authmode != IEEE80211_AUTH_8021X && - ni->ni_challenge == NULL) - ieee80211_node_authorize(ni); - } else { - vap->iv_stats.is_rx_acl++; - ieee80211_send_error(ni, ni->ni_macaddr, - IEEE80211_FC0_SUBTYPE_AUTH, 2|(reason<<16)); - ieee80211_node_leave(ni); - } - ieee80211_free_node(ni); - } else - error = ENOENT; - IEEE80211_NODE_UNLOCK(nt); - break; - default: - error = EINVAL; - break; - } - return error; -} - -struct scanlookup { - const uint8_t *mac; - int esslen; - const uint8_t *essid; - const struct ieee80211_scan_entry *se; -}; - -/* - * Match mac address and any ssid. - */ -static void -mlmelookup(void *arg, const struct ieee80211_scan_entry *se) -{ - struct scanlookup *look = arg; - - if (!IEEE80211_ADDR_EQ(look->mac, se->se_macaddr)) - return; - if (look->esslen != 0) { - if (se->se_ssid[1] != look->esslen) - return; - if (memcmp(look->essid, se->se_ssid+2, look->esslen)) - return; - } - look->se = se; -} - -static __noinline int -setmlme_assoc_sta(struct ieee80211vap *vap, - const uint8_t mac[IEEE80211_ADDR_LEN], int ssid_len, - const uint8_t ssid[IEEE80211_NWID_LEN]) -{ - struct scanlookup lookup; - - KASSERT(vap->iv_opmode == IEEE80211_M_STA, - ("expected opmode STA not %s", - ieee80211_opmode_name[vap->iv_opmode])); - - /* NB: this is racey if roaming is !manual */ - lookup.se = NULL; - lookup.mac = mac; - lookup.esslen = ssid_len; - lookup.essid = ssid; - ieee80211_scan_iterate(vap, mlmelookup, &lookup); - if (lookup.se == NULL) - return ENOENT; - mlmedebug(vap, mac, IEEE80211_MLME_ASSOC, 0); - if (!ieee80211_sta_join(vap, lookup.se->se_chan, lookup.se)) - return EIO; /* XXX unique but could be better */ - return 0; -} - -static __noinline int -setmlme_assoc_adhoc(struct ieee80211vap *vap, - const uint8_t mac[IEEE80211_ADDR_LEN], int ssid_len, - const uint8_t ssid[IEEE80211_NWID_LEN]) -{ - struct ieee80211_scan_req sr; - - KASSERT(vap->iv_opmode == IEEE80211_M_IBSS || - vap->iv_opmode == IEEE80211_M_AHDEMO, - ("expected opmode IBSS or AHDEMO not %s", - ieee80211_opmode_name[vap->iv_opmode])); - - if (ssid_len == 0) - return EINVAL; - - /* NB: IEEE80211_IOC_SSID call missing for ap_scan=2. */ - memset(vap->iv_des_ssid[0].ssid, 0, IEEE80211_NWID_LEN); - vap->iv_des_ssid[0].len = ssid_len; - memcpy(vap->iv_des_ssid[0].ssid, ssid, ssid_len); - vap->iv_des_nssid = 1; - - memset(&sr, 0, sizeof(sr)); - sr.sr_flags = IEEE80211_IOC_SCAN_ACTIVE | IEEE80211_IOC_SCAN_ONCE; - sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER; - memcpy(sr.sr_ssid[0].ssid, ssid, ssid_len); - sr.sr_ssid[0].len = ssid_len; - sr.sr_nssid = 1; - - return ieee80211_scanreq(vap, &sr); -} - -static __noinline int -ieee80211_ioctl_setmlme(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211req_mlme mlme; - int error; - - if (ireq->i_len != sizeof(mlme)) - return EINVAL; - error = copyin(ireq->i_data, &mlme, sizeof(mlme)); - if (error) - return error; - if (vap->iv_opmode == IEEE80211_M_STA && - mlme.im_op == IEEE80211_MLME_ASSOC) -#ifndef __HAIKU__ - return setmlme_assoc_sta(vap, mlme.im_macaddr, - vap->iv_des_ssid[0].len, vap->iv_des_ssid[0].ssid); -#else - /* The wpa_supplicant (rightfully) supplies the SSID with this request. - However, with the code above it gets ignored and the desired SSID, - as set by IEEE80211_IOC_SSID is used instead. This still works if - the wpa_supplicant is the only client in use and IEEE80211_IOC_SSID - is never used, as then the mlme.im_macaddr is used as the only - identifying element. If we used IEEE80211_IOC_SSID before though, - for example because we joined an open network from the net_server - directly, there will always be a mismatch between the desired SSID - and the one the wpa_supplicant tries to associate with using this - MLME request. No association is then possible. As there is no - obvious reason why the request supplied SSID shouldn't be used, we - simply do so. */ - return setmlme_assoc_sta(vap, mlme.im_macaddr, - mlme.im_ssid_len, mlme.im_ssid); -#endif - else if (mlme.im_op == IEEE80211_MLME_ASSOC) - return setmlme_assoc_adhoc(vap, mlme.im_macaddr, - mlme.im_ssid_len, mlme.im_ssid); - else - return setmlme_common(vap, mlme.im_op, - mlme.im_macaddr, mlme.im_reason); -} - -static __noinline int -ieee80211_ioctl_macmac(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - uint8_t mac[IEEE80211_ADDR_LEN]; - const struct ieee80211_aclator *acl = vap->iv_acl; - int error; - - if (ireq->i_len != sizeof(mac)) - return EINVAL; - error = copyin(ireq->i_data, mac, ireq->i_len); - if (error) - return error; - if (acl == NULL) { - acl = ieee80211_aclator_get("mac"); - if (acl == NULL || !acl->iac_attach(vap)) - return EINVAL; - vap->iv_acl = acl; - } - if (ireq->i_type == IEEE80211_IOC_ADDMAC) - acl->iac_add(vap, mac); - else - acl->iac_remove(vap, mac); - return 0; -} - -static __noinline int -ieee80211_ioctl_setmaccmd(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - const struct ieee80211_aclator *acl = vap->iv_acl; - - switch (ireq->i_val) { - case IEEE80211_MACCMD_POLICY_OPEN: - case IEEE80211_MACCMD_POLICY_ALLOW: - case IEEE80211_MACCMD_POLICY_DENY: - case IEEE80211_MACCMD_POLICY_RADIUS: - if (acl == NULL) { - acl = ieee80211_aclator_get("mac"); - if (acl == NULL || !acl->iac_attach(vap)) - return EINVAL; - vap->iv_acl = acl; - } - acl->iac_setpolicy(vap, ireq->i_val); - break; - case IEEE80211_MACCMD_FLUSH: - if (acl != NULL) - acl->iac_flush(vap); - /* NB: silently ignore when not in use */ - break; - case IEEE80211_MACCMD_DETACH: - if (acl != NULL) { - vap->iv_acl = NULL; - acl->iac_detach(vap); - } - break; - default: - if (acl == NULL) - return EINVAL; - else - return acl->iac_setioctl(vap, ireq); - } - return 0; -} - -static __noinline int -ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - uint8_t *chanlist, *list; - int i, nchan, maxchan, error; - - if (ireq->i_len > sizeof(ic->ic_chan_active)) - ireq->i_len = sizeof(ic->ic_chan_active); - list = malloc(ireq->i_len + IEEE80211_CHAN_BYTES, M_TEMP, - M_NOWAIT | M_ZERO); - if (list == NULL) - return ENOMEM; - error = copyin(ireq->i_data, list, ireq->i_len); - if (error) { - free(list, M_TEMP); - return error; - } - nchan = 0; - chanlist = list + ireq->i_len; /* NB: zero'd already */ - maxchan = ireq->i_len * NBBY; - for (i = 0; i < ic->ic_nchans; i++) { - const struct ieee80211_channel *c = &ic->ic_channels[i]; - /* - * Calculate the intersection of the user list and the - * available channels so users can do things like specify - * 1-255 to get all available channels. - */ - if (c->ic_ieee < maxchan && isset(list, c->ic_ieee)) { - setbit(chanlist, c->ic_ieee); - nchan++; - } - } - if (nchan == 0) { - free(list, M_TEMP); - return EINVAL; - } - if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && /* XXX */ - isclr(chanlist, ic->ic_bsschan->ic_ieee)) - ic->ic_bsschan = IEEE80211_CHAN_ANYC; - memcpy(ic->ic_chan_active, chanlist, IEEE80211_CHAN_BYTES); - ieee80211_scan_flush(vap); - free(list, M_TEMP); - return ENETRESET; -} - -static __noinline int -ieee80211_ioctl_setstastats(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211_node *ni; - uint8_t macaddr[IEEE80211_ADDR_LEN]; - int error; - - /* - * NB: we could copyin ieee80211req_sta_stats so apps - * could make selective changes but that's overkill; - * just clear all stats for now. - */ - if (ireq->i_len < IEEE80211_ADDR_LEN) - return EINVAL; - error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); - if (error != 0) - return error; - ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr); - if (ni == NULL) - return ENOENT; - /* XXX require ni_vap == vap? */ - memset(&ni->ni_stats, 0, sizeof(ni->ni_stats)); - ieee80211_free_node(ni); - return 0; -} - -static __noinline int -ieee80211_ioctl_setstatxpow(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211_node *ni; - struct ieee80211req_sta_txpow txpow; - int error; - - if (ireq->i_len != sizeof(txpow)) - return EINVAL; - error = copyin(ireq->i_data, &txpow, sizeof(txpow)); - if (error != 0) - return error; - ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, txpow.it_macaddr); - if (ni == NULL) - return ENOENT; - ni->ni_txpower = txpow.it_txpow; - ieee80211_free_node(ni); - return error; -} - -static __noinline int -ieee80211_ioctl_setwmeparam(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_wme_state *wme = &ic->ic_wme; - struct wmeParams *wmep, *chanp; - int isbss, ac; - - if ((ic->ic_caps & IEEE80211_C_WME) == 0) - return EOPNOTSUPP; - - isbss = (ireq->i_len & IEEE80211_WMEPARAM_BSS); - ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL); - if (ac >= WME_NUM_AC) - ac = WME_AC_BE; - if (isbss) { - chanp = &wme->wme_bssChanParams.cap_wmeParams[ac]; - wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; - } else { - chanp = &wme->wme_chanParams.cap_wmeParams[ac]; - wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; - } - switch (ireq->i_type) { - case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ - if (isbss) { - wmep->wmep_logcwmin = ireq->i_val; - if ((wme->wme_flags & WME_F_AGGRMODE) == 0) - chanp->wmep_logcwmin = ireq->i_val; - } else { - wmep->wmep_logcwmin = chanp->wmep_logcwmin = - ireq->i_val; - } - break; - case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ - if (isbss) { - wmep->wmep_logcwmax = ireq->i_val; - if ((wme->wme_flags & WME_F_AGGRMODE) == 0) - chanp->wmep_logcwmax = ireq->i_val; - } else { - wmep->wmep_logcwmax = chanp->wmep_logcwmax = - ireq->i_val; - } - break; - case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ - if (isbss) { - wmep->wmep_aifsn = ireq->i_val; - if ((wme->wme_flags & WME_F_AGGRMODE) == 0) - chanp->wmep_aifsn = ireq->i_val; - } else { - wmep->wmep_aifsn = chanp->wmep_aifsn = ireq->i_val; - } - break; - case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ - if (isbss) { - wmep->wmep_txopLimit = ireq->i_val; - if ((wme->wme_flags & WME_F_AGGRMODE) == 0) - chanp->wmep_txopLimit = ireq->i_val; - } else { - wmep->wmep_txopLimit = chanp->wmep_txopLimit = - ireq->i_val; - } - break; - case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ - wmep->wmep_acm = ireq->i_val; - if ((wme->wme_flags & WME_F_AGGRMODE) == 0) - chanp->wmep_acm = ireq->i_val; - break; - case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only)*/ - wmep->wmep_noackPolicy = chanp->wmep_noackPolicy = - (ireq->i_val) == 0; - break; - } - ieee80211_wme_updateparams(vap); - return 0; -} - -static int -find11gchannel(struct ieee80211com *ic, int start, int freq) -{ - const struct ieee80211_channel *c; - int i; - - for (i = start+1; i < ic->ic_nchans; i++) { - c = &ic->ic_channels[i]; - if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) - return 1; - } - /* NB: should not be needed but in case things are mis-sorted */ - for (i = 0; i < start; i++) { - c = &ic->ic_channels[i]; - if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) - return 1; - } - return 0; -} - -static struct ieee80211_channel * -findchannel(struct ieee80211com *ic, int ieee, int mode) -{ - static const u_int chanflags[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = 0, - [IEEE80211_MODE_11A] = IEEE80211_CHAN_A, - [IEEE80211_MODE_11B] = IEEE80211_CHAN_B, - [IEEE80211_MODE_11G] = IEEE80211_CHAN_G, - [IEEE80211_MODE_FH] = IEEE80211_CHAN_FHSS, - [IEEE80211_MODE_TURBO_A] = IEEE80211_CHAN_108A, - [IEEE80211_MODE_TURBO_G] = IEEE80211_CHAN_108G, - [IEEE80211_MODE_STURBO_A] = IEEE80211_CHAN_STURBO, - [IEEE80211_MODE_HALF] = IEEE80211_CHAN_HALF, - [IEEE80211_MODE_QUARTER] = IEEE80211_CHAN_QUARTER, - /* NB: handled specially below */ - [IEEE80211_MODE_11NA] = IEEE80211_CHAN_A, - [IEEE80211_MODE_11NG] = IEEE80211_CHAN_G, - }; - u_int modeflags; - int i; - - modeflags = chanflags[mode]; - for (i = 0; i < ic->ic_nchans; i++) { - struct ieee80211_channel *c = &ic->ic_channels[i]; - - if (c->ic_ieee != ieee) - continue; - if (mode == IEEE80211_MODE_AUTO) { - /* ignore turbo channels for autoselect */ - if (IEEE80211_IS_CHAN_TURBO(c)) - continue; - /* - * XXX special-case 11b/g channels so we - * always select the g channel if both - * are present. - * XXX prefer HT to non-HT? - */ - if (!IEEE80211_IS_CHAN_B(c) || - !find11gchannel(ic, i, c->ic_freq)) - return c; - } else { - /* must check HT specially */ - if ((mode == IEEE80211_MODE_11NA || - mode == IEEE80211_MODE_11NG) && - !IEEE80211_IS_CHAN_HT(c)) - continue; - if ((c->ic_flags & modeflags) == modeflags) - return c; - } - } - return NULL; -} - -/* - * Check the specified against any desired mode (aka netband). - * This is only used (presently) when operating in hostap mode - * to enforce consistency. - */ -static int -check_mode_consistency(const struct ieee80211_channel *c, int mode) -{ - KASSERT(c != IEEE80211_CHAN_ANYC, ("oops, no channel")); - - switch (mode) { - case IEEE80211_MODE_11B: - return (IEEE80211_IS_CHAN_B(c)); - case IEEE80211_MODE_11G: - return (IEEE80211_IS_CHAN_ANYG(c) && !IEEE80211_IS_CHAN_HT(c)); - case IEEE80211_MODE_11A: - return (IEEE80211_IS_CHAN_A(c) && !IEEE80211_IS_CHAN_HT(c)); - case IEEE80211_MODE_STURBO_A: - return (IEEE80211_IS_CHAN_STURBO(c)); - case IEEE80211_MODE_11NA: - return (IEEE80211_IS_CHAN_HTA(c)); - case IEEE80211_MODE_11NG: - return (IEEE80211_IS_CHAN_HTG(c)); - } - return 1; - -} - -/* - * Common code to set the current channel. If the device - * is up and running this may result in an immediate channel - * change or a kick of the state machine. - */ -static int -setcurchan(struct ieee80211vap *vap, struct ieee80211_channel *c) -{ - struct ieee80211com *ic = vap->iv_ic; - int error; - - if (c != IEEE80211_CHAN_ANYC) { - if (IEEE80211_IS_CHAN_RADAR(c)) - return EBUSY; /* XXX better code? */ - if (vap->iv_opmode == IEEE80211_M_HOSTAP) { - if (IEEE80211_IS_CHAN_NOHOSTAP(c)) - return EINVAL; - if (!check_mode_consistency(c, vap->iv_des_mode)) - return EINVAL; - } else if (vap->iv_opmode == IEEE80211_M_IBSS) { - if (IEEE80211_IS_CHAN_NOADHOC(c)) - return EINVAL; - } - if (vap->iv_state == IEEE80211_S_RUN && - vap->iv_bss->ni_chan == c) - return 0; /* NB: nothing to do */ - } - vap->iv_des_chan = c; - - error = 0; - if (vap->iv_opmode == IEEE80211_M_MONITOR && - vap->iv_des_chan != IEEE80211_CHAN_ANYC) { - /* - * Monitor mode can switch directly. - */ - if (IFNET_IS_UP_RUNNING(vap->iv_ifp)) { - /* XXX need state machine for other vap's to follow */ - ieee80211_setcurchan(ic, vap->iv_des_chan); - vap->iv_bss->ni_chan = ic->ic_curchan; - } else - ic->ic_curchan = vap->iv_des_chan; - ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan); - } else { - /* - * Need to go through the state machine in case we - * need to reassociate or the like. The state machine - * will pickup the desired channel and avoid scanning. - */ - if (IS_UP_AUTO(vap)) - ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); - else if (vap->iv_des_chan != IEEE80211_CHAN_ANYC) { - /* - * When not up+running and a real channel has - * been specified fix the current channel so - * there is immediate feedback; e.g. via ifconfig. - */ - ic->ic_curchan = vap->iv_des_chan; - ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan); - } - } - return error; -} - -/* - * Old api for setting the current channel; this is - * deprecated because channel numbers are ambiguous. - */ -static __noinline int -ieee80211_ioctl_setchannel(struct ieee80211vap *vap, - const struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_channel *c; - - /* XXX 0xffff overflows 16-bit signed */ - if (ireq->i_val == 0 || - ireq->i_val == (int16_t) IEEE80211_CHAN_ANY) { - c = IEEE80211_CHAN_ANYC; - } else { - struct ieee80211_channel *c2; - - c = findchannel(ic, ireq->i_val, vap->iv_des_mode); - if (c == NULL) { - c = findchannel(ic, ireq->i_val, - IEEE80211_MODE_AUTO); - if (c == NULL) - return EINVAL; - } - /* - * Fine tune channel selection based on desired mode: - * if 11b is requested, find the 11b version of any - * 11g channel returned, - * if static turbo, find the turbo version of any - * 11a channel return, - * if 11na is requested, find the ht version of any - * 11a channel returned, - * if 11ng is requested, find the ht version of any - * 11g channel returned, - * otherwise we should be ok with what we've got. - */ - switch (vap->iv_des_mode) { - case IEEE80211_MODE_11B: - if (IEEE80211_IS_CHAN_ANYG(c)) { - c2 = findchannel(ic, ireq->i_val, - IEEE80211_MODE_11B); - /* NB: should not happen, =>'s 11g w/o 11b */ - if (c2 != NULL) - c = c2; - } - break; - case IEEE80211_MODE_TURBO_A: - if (IEEE80211_IS_CHAN_A(c)) { - c2 = findchannel(ic, ireq->i_val, - IEEE80211_MODE_TURBO_A); - if (c2 != NULL) - c = c2; - } - break; - case IEEE80211_MODE_11NA: - if (IEEE80211_IS_CHAN_A(c)) { - c2 = findchannel(ic, ireq->i_val, - IEEE80211_MODE_11NA); - if (c2 != NULL) - c = c2; - } - break; - case IEEE80211_MODE_11NG: - if (IEEE80211_IS_CHAN_ANYG(c)) { - c2 = findchannel(ic, ireq->i_val, - IEEE80211_MODE_11NG); - if (c2 != NULL) - c = c2; - } - break; - default: /* NB: no static turboG */ - break; - } - } - return setcurchan(vap, c); -} - -/* - * New/current api for setting the current channel; a complete - * channel description is provide so there is no ambiguity in - * identifying the channel. - */ -static __noinline int -ieee80211_ioctl_setcurchan(struct ieee80211vap *vap, - const struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_channel chan, *c; - int error; - - if (ireq->i_len != sizeof(chan)) - return EINVAL; - error = copyin(ireq->i_data, &chan, sizeof(chan)); - if (error != 0) - return error; - /* XXX 0xffff overflows 16-bit signed */ - if (chan.ic_freq == 0 || chan.ic_freq == IEEE80211_CHAN_ANY) { - c = IEEE80211_CHAN_ANYC; - } else { - c = ieee80211_find_channel(ic, chan.ic_freq, chan.ic_flags); - if (c == NULL) - return EINVAL; - } - return setcurchan(vap, c); -} - -static __noinline int -ieee80211_ioctl_setregdomain(struct ieee80211vap *vap, - const struct ieee80211req *ireq) -{ - struct ieee80211_regdomain_req *reg; - int nchans, error; - - nchans = 1 + ((ireq->i_len - sizeof(struct ieee80211_regdomain_req)) / - sizeof(struct ieee80211_channel)); - if (!(1 <= nchans && nchans <= IEEE80211_CHAN_MAX)) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL, - "%s: bad # chans, i_len %d nchans %d\n", __func__, - ireq->i_len, nchans); - return EINVAL; - } - reg = (struct ieee80211_regdomain_req *) - malloc(IEEE80211_REGDOMAIN_SIZE(nchans), M_TEMP, M_NOWAIT); - if (reg == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL, - "%s: no memory, nchans %d\n", __func__, nchans); - return ENOMEM; - } - error = copyin(ireq->i_data, reg, IEEE80211_REGDOMAIN_SIZE(nchans)); - if (error == 0) { - /* NB: validate inline channel count against storage size */ - if (reg->chaninfo.ic_nchans != nchans) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL, - "%s: chan cnt mismatch, %d != %d\n", __func__, - reg->chaninfo.ic_nchans, nchans); - error = EINVAL; - } else - error = ieee80211_setregdomain(vap, reg); - } - free(reg, M_TEMP); - - return (error == 0 ? ENETRESET : error); -} - -static int -ieee80211_ioctl_setroam(struct ieee80211vap *vap, - const struct ieee80211req *ireq) -{ - if (ireq->i_len != sizeof(vap->iv_roamparms)) - return EINVAL; - /* XXX validate params */ - /* XXX? ENETRESET to push to device? */ - return copyin(ireq->i_data, vap->iv_roamparms, - sizeof(vap->iv_roamparms)); -} - -static int -checkrate(const struct ieee80211_rateset *rs, int rate) -{ - int i; - - if (rate == IEEE80211_FIXED_RATE_NONE) - return 1; - for (i = 0; i < rs->rs_nrates; i++) - if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rate) - return 1; - return 0; -} - -static int -checkmcs(int mcs) -{ - if (mcs == IEEE80211_FIXED_RATE_NONE) - return 1; - if ((mcs & IEEE80211_RATE_MCS) == 0) /* MCS always have 0x80 set */ - return 0; - return (mcs & 0x7f) <= 15; /* XXX could search ht rate set */ -} - -static __noinline int -ieee80211_ioctl_settxparams(struct ieee80211vap *vap, - const struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_txparams_req parms; /* XXX stack use? */ - struct ieee80211_txparam *src, *dst; - const struct ieee80211_rateset *rs; - int error, mode, changed, is11n, nmodes; - - /* NB: accept short requests for backwards compat */ - if (ireq->i_len > sizeof(parms)) - return EINVAL; - error = copyin(ireq->i_data, &parms, ireq->i_len); - if (error != 0) - return error; - nmodes = ireq->i_len / sizeof(struct ieee80211_txparam); - changed = 0; - /* validate parameters and check if anything changed */ - for (mode = IEEE80211_MODE_11A; mode < nmodes; mode++) { - if (isclr(ic->ic_modecaps, mode)) - continue; - src = &parms.params[mode]; - dst = &vap->iv_txparms[mode]; - rs = &ic->ic_sup_rates[mode]; /* NB: 11n maps to legacy */ - is11n = (mode == IEEE80211_MODE_11NA || - mode == IEEE80211_MODE_11NG); - if (src->ucastrate != dst->ucastrate) { - if (!checkrate(rs, src->ucastrate) && - (!is11n || !checkmcs(src->ucastrate))) - return EINVAL; - changed++; - } - if (src->mcastrate != dst->mcastrate) { - if (!checkrate(rs, src->mcastrate) && - (!is11n || !checkmcs(src->mcastrate))) - return EINVAL; - changed++; - } - if (src->mgmtrate != dst->mgmtrate) { - if (!checkrate(rs, src->mgmtrate) && - (!is11n || !checkmcs(src->mgmtrate))) - return EINVAL; - changed++; - } - if (src->maxretry != dst->maxretry) /* NB: no bounds */ - changed++; - } - if (changed) { - /* - * Copy new parameters in place and notify the - * driver so it can push state to the device. - */ - for (mode = IEEE80211_MODE_11A; mode < nmodes; mode++) { - if (isset(ic->ic_modecaps, mode)) - vap->iv_txparms[mode] = parms.params[mode]; - } - /* XXX could be more intelligent, - e.g. don't reset if setting not being used */ - return ENETRESET; - } - return 0; -} - -/* - * Application Information Element support. - */ -static int -setappie(struct ieee80211_appie **aie, const struct ieee80211req *ireq) -{ - struct ieee80211_appie *app = *aie; - struct ieee80211_appie *napp; - int error; - - if (ireq->i_len == 0) { /* delete any existing ie */ - if (app != NULL) { - *aie = NULL; /* XXX racey */ - free(app, M_80211_NODE_IE); - } - return 0; - } - if (!(2 <= ireq->i_len && ireq->i_len <= IEEE80211_MAX_APPIE)) - return EINVAL; - /* - * Allocate a new appie structure and copy in the user data. - * When done swap in the new structure. Note that we do not - * guard against users holding a ref to the old structure; - * this must be handled outside this code. - * - * XXX bad bad bad - */ - napp = (struct ieee80211_appie *) malloc( - sizeof(struct ieee80211_appie) + ireq->i_len, M_80211_NODE_IE, M_NOWAIT); - if (napp == NULL) - return ENOMEM; - /* XXX holding ic lock */ - error = copyin(ireq->i_data, napp->ie_data, ireq->i_len); - if (error) { - free(napp, M_80211_NODE_IE); - return error; - } - napp->ie_len = ireq->i_len; - *aie = napp; - if (app != NULL) - free(app, M_80211_NODE_IE); - return 0; -} - -static void -setwparsnie(struct ieee80211vap *vap, uint8_t *ie, int space) -{ - /* validate data is present as best we can */ - if (space == 0 || 2+ie[1] > space) - return; - if (ie[0] == IEEE80211_ELEMID_VENDOR) - vap->iv_wpa_ie = ie; - else if (ie[0] == IEEE80211_ELEMID_RSN) - vap->iv_rsn_ie = ie; -} - -static __noinline int -ieee80211_ioctl_setappie_locked(struct ieee80211vap *vap, - const struct ieee80211req *ireq, int fc0) -{ - int error; - - IEEE80211_LOCK_ASSERT(vap->iv_ic); - - switch (fc0 & IEEE80211_FC0_SUBTYPE_MASK) { - case IEEE80211_FC0_SUBTYPE_BEACON: - if (vap->iv_opmode != IEEE80211_M_HOSTAP && - vap->iv_opmode != IEEE80211_M_IBSS) { - error = EINVAL; - break; - } - error = setappie(&vap->iv_appie_beacon, ireq); - if (error == 0) - ieee80211_beacon_notify(vap, IEEE80211_BEACON_APPIE); - break; - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - error = setappie(&vap->iv_appie_proberesp, ireq); - break; - case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: - if (vap->iv_opmode == IEEE80211_M_HOSTAP) - error = setappie(&vap->iv_appie_assocresp, ireq); - else - error = EINVAL; - break; - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - error = setappie(&vap->iv_appie_probereq, ireq); - break; - case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - if (vap->iv_opmode == IEEE80211_M_STA) - error = setappie(&vap->iv_appie_assocreq, ireq); - else - error = EINVAL; - break; - case (IEEE80211_APPIE_WPA & IEEE80211_FC0_SUBTYPE_MASK): - error = setappie(&vap->iv_appie_wpa, ireq); - if (error == 0) { - /* - * Must split single blob of data into separate - * WPA and RSN ie's because they go in different - * locations in the mgt frames. - * XXX use IEEE80211_IOC_WPA2 so user code does split - */ - vap->iv_wpa_ie = NULL; - vap->iv_rsn_ie = NULL; - if (vap->iv_appie_wpa != NULL) { - struct ieee80211_appie *appie = - vap->iv_appie_wpa; - uint8_t *data = appie->ie_data; - - /* XXX ie length validate is painful, cheat */ - setwparsnie(vap, data, appie->ie_len); - setwparsnie(vap, data + 2 + data[1], - appie->ie_len - (2 + data[1])); - } - if (vap->iv_opmode == IEEE80211_M_HOSTAP || - vap->iv_opmode == IEEE80211_M_IBSS) { - /* - * Must rebuild beacon frame as the update - * mechanism doesn't handle WPA/RSN ie's. - * Could extend it but it doesn't normally - * change; this is just to deal with hostapd - * plumbing the ie after the interface is up. - */ - error = ENETRESET; - } - } - break; - default: - error = EINVAL; - break; - } - return error; -} - -static __noinline int -ieee80211_ioctl_setappie(struct ieee80211vap *vap, - const struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - int error; - uint8_t fc0; - - fc0 = ireq->i_val & 0xff; - if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT) - return EINVAL; - /* NB: could check iv_opmode and reject but hardly worth the effort */ - IEEE80211_LOCK(ic); - error = ieee80211_ioctl_setappie_locked(vap, ireq, fc0); - IEEE80211_UNLOCK(ic); - return error; -} - -static __noinline int -ieee80211_ioctl_chanswitch(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_chanswitch_req csr; - struct ieee80211_channel *c; - int error; - - if (ireq->i_len != sizeof(csr)) - return EINVAL; - error = copyin(ireq->i_data, &csr, sizeof(csr)); - if (error != 0) - return error; - /* XXX adhoc mode not supported */ - if (vap->iv_opmode != IEEE80211_M_HOSTAP || - (vap->iv_flags & IEEE80211_F_DOTH) == 0) - return EOPNOTSUPP; - c = ieee80211_find_channel(ic, - csr.csa_chan.ic_freq, csr.csa_chan.ic_flags); - if (c == NULL) - return ENOENT; - IEEE80211_LOCK(ic); - if ((ic->ic_flags & IEEE80211_F_CSAPENDING) == 0) - ieee80211_csa_startswitch(ic, c, csr.csa_mode, csr.csa_count); - else if (csr.csa_count == 0) - ieee80211_csa_cancelswitch(ic); - else - error = EBUSY; - IEEE80211_UNLOCK(ic); - return error; -} - -static int -ieee80211_scanreq(struct ieee80211vap *vap, struct ieee80211_scan_req *sr) -{ -#define IEEE80211_IOC_SCAN_FLAGS \ - (IEEE80211_IOC_SCAN_NOPICK | IEEE80211_IOC_SCAN_ACTIVE | \ - IEEE80211_IOC_SCAN_PICK1ST | IEEE80211_IOC_SCAN_BGSCAN | \ - IEEE80211_IOC_SCAN_ONCE | IEEE80211_IOC_SCAN_NOBCAST | \ - IEEE80211_IOC_SCAN_NOJOIN | IEEE80211_IOC_SCAN_FLUSH | \ - IEEE80211_IOC_SCAN_CHECK) - struct ieee80211com *ic = vap->iv_ic; - int error, i; - - /* convert duration */ - if (sr->sr_duration == IEEE80211_IOC_SCAN_FOREVER) - sr->sr_duration = IEEE80211_SCAN_FOREVER; - else { - if (sr->sr_duration < IEEE80211_IOC_SCAN_DURATION_MIN || - sr->sr_duration > IEEE80211_IOC_SCAN_DURATION_MAX) - return EINVAL; - sr->sr_duration = msecs_to_ticks(sr->sr_duration); - if (sr->sr_duration < 1) - sr->sr_duration = 1; - } - /* convert min/max channel dwell */ - if (sr->sr_mindwell != 0) { - sr->sr_mindwell = msecs_to_ticks(sr->sr_mindwell); - if (sr->sr_mindwell < 1) - sr->sr_mindwell = 1; - } - if (sr->sr_maxdwell != 0) { - sr->sr_maxdwell = msecs_to_ticks(sr->sr_maxdwell); - if (sr->sr_maxdwell < 1) - sr->sr_maxdwell = 1; - } - /* NB: silently reduce ssid count to what is supported */ - if (sr->sr_nssid > IEEE80211_SCAN_MAX_SSID) - sr->sr_nssid = IEEE80211_SCAN_MAX_SSID; - for (i = 0; i < sr->sr_nssid; i++) - if (sr->sr_ssid[i].len > IEEE80211_NWID_LEN) - return EINVAL; - /* cleanse flags just in case, could reject if invalid flags */ - sr->sr_flags &= IEEE80211_IOC_SCAN_FLAGS; - /* - * Add an implicit NOPICK if the vap is not marked UP. This - * allows applications to scan without joining a bss (or picking - * a channel and setting up a bss) and without forcing manual - * roaming mode--you just need to mark the parent device UP. - */ - if ((vap->iv_ifp->if_flags & IFF_UP) == 0) - sr->sr_flags |= IEEE80211_IOC_SCAN_NOPICK; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: flags 0x%x%s duration 0x%x mindwell %u maxdwell %u nssid %d\n", - __func__, sr->sr_flags, - (vap->iv_ifp->if_flags & IFF_UP) == 0 ? " (!IFF_UP)" : "", - sr->sr_duration, sr->sr_mindwell, sr->sr_maxdwell, sr->sr_nssid); - /* - * If we are in INIT state then the driver has never had a chance - * to setup hardware state to do a scan; we must use the state - * machine to get us up to the SCAN state but once we reach SCAN - * state we then want to use the supplied params. Stash the - * parameters in the vap and mark IEEE80211_FEXT_SCANREQ; the - * state machines will recognize this and use the stashed params - * to issue the scan request. - * - * Otherwise just invoke the scan machinery directly. - */ - IEEE80211_LOCK(ic); - if (vap->iv_state == IEEE80211_S_INIT) { - /* NB: clobbers previous settings */ - vap->iv_scanreq_flags = sr->sr_flags; - vap->iv_scanreq_duration = sr->sr_duration; - vap->iv_scanreq_nssid = sr->sr_nssid; - for (i = 0; i < sr->sr_nssid; i++) { - vap->iv_scanreq_ssid[i].len = sr->sr_ssid[i].len; - memcpy(vap->iv_scanreq_ssid[i].ssid, - sr->sr_ssid[i].ssid, sr->sr_ssid[i].len); - } - vap->iv_flags_ext |= IEEE80211_FEXT_SCANREQ; - IEEE80211_UNLOCK(ic); - ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); - } else { - vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; - IEEE80211_UNLOCK(ic); - if (sr->sr_flags & IEEE80211_IOC_SCAN_CHECK) { - error = ieee80211_check_scan(vap, sr->sr_flags, - sr->sr_duration, sr->sr_mindwell, sr->sr_maxdwell, - sr->sr_nssid, - /* NB: cheat, we assume structures are compatible */ - (const struct ieee80211_scan_ssid *) &sr->sr_ssid[0]); - } else { - error = ieee80211_start_scan(vap, sr->sr_flags, - sr->sr_duration, sr->sr_mindwell, sr->sr_maxdwell, - sr->sr_nssid, - /* NB: cheat, we assume structures are compatible */ - (const struct ieee80211_scan_ssid *) &sr->sr_ssid[0]); - } - if (error == 0) - return EINPROGRESS; - } - return 0; -#undef IEEE80211_IOC_SCAN_FLAGS -} - -static __noinline int -ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_req sr; /* XXX off stack? */ - int error; - - /* NB: parent must be running */ - if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return ENXIO; - - if (ireq->i_len != sizeof(sr)) - return EINVAL; - error = copyin(ireq->i_data, &sr, sizeof(sr)); - if (error != 0) - return error; - return ieee80211_scanreq(vap, &sr); -} - -static __noinline int -ieee80211_ioctl_setstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211_node *ni; - struct ieee80211req_sta_vlan vlan; - int error; - - if (ireq->i_len != sizeof(vlan)) - return EINVAL; - error = copyin(ireq->i_data, &vlan, sizeof(vlan)); - if (error != 0) - return error; - if (!IEEE80211_ADDR_EQ(vlan.sv_macaddr, zerobssid)) { - ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, - vlan.sv_macaddr); - if (ni == NULL) - return ENOENT; - } else - ni = ieee80211_ref_node(vap->iv_bss); - ni->ni_vlan = vlan.sv_vlan; - ieee80211_free_node(ni); - return error; -} - -static int -isvap11g(const struct ieee80211vap *vap) -{ - const struct ieee80211_node *bss = vap->iv_bss; - return bss->ni_chan != IEEE80211_CHAN_ANYC && - IEEE80211_IS_CHAN_ANYG(bss->ni_chan); -} - -static int -isvapht(const struct ieee80211vap *vap) -{ - const struct ieee80211_node *bss = vap->iv_bss; - return bss->ni_chan != IEEE80211_CHAN_ANYC && - IEEE80211_IS_CHAN_HT(bss->ni_chan); -} - -/* - * Dummy ioctl set handler so the linker set is defined. - */ -static int -dummy_ioctl_set(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - return ENOSYS; -} -IEEE80211_IOCTL_SET(dummy, dummy_ioctl_set); - -static int -ieee80211_ioctl_setdefault(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - ieee80211_ioctl_setfunc * const *set; - int error; - - SET_FOREACH(set, ieee80211_ioctl_setset) { - error = (*set)(vap, ireq); - if (error != ENOSYS) - return error; - } - return EINVAL; -} - -static __noinline int -ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211req *ireq) -{ - struct ieee80211com *ic = vap->iv_ic; - int error; - const struct ieee80211_authenticator *auth; - uint8_t tmpkey[IEEE80211_KEYBUF_SIZE]; - char tmpssid[IEEE80211_NWID_LEN]; - uint8_t tmpbssid[IEEE80211_ADDR_LEN]; - struct ieee80211_key *k; - u_int kid; - uint32_t flags; - - error = 0; - switch (ireq->i_type) { - case IEEE80211_IOC_SSID: - if (ireq->i_val != 0 || - ireq->i_len > IEEE80211_NWID_LEN) - return EINVAL; - error = copyin(ireq->i_data, tmpssid, ireq->i_len); - if (error) - break; - memset(vap->iv_des_ssid[0].ssid, 0, IEEE80211_NWID_LEN); - vap->iv_des_ssid[0].len = ireq->i_len; - memcpy(vap->iv_des_ssid[0].ssid, tmpssid, ireq->i_len); - vap->iv_des_nssid = (ireq->i_len > 0); - error = ENETRESET; - break; - case IEEE80211_IOC_WEP: - switch (ireq->i_val) { - case IEEE80211_WEP_OFF: - vap->iv_flags &= ~IEEE80211_F_PRIVACY; - vap->iv_flags &= ~IEEE80211_F_DROPUNENC; - break; - case IEEE80211_WEP_ON: - vap->iv_flags |= IEEE80211_F_PRIVACY; - vap->iv_flags |= IEEE80211_F_DROPUNENC; - break; - case IEEE80211_WEP_MIXED: - vap->iv_flags |= IEEE80211_F_PRIVACY; - vap->iv_flags &= ~IEEE80211_F_DROPUNENC; - break; - } - error = ENETRESET; - break; - case IEEE80211_IOC_WEPKEY: - kid = (u_int) ireq->i_val; - if (kid >= IEEE80211_WEP_NKID) - return EINVAL; - k = &vap->iv_nw_keys[kid]; - if (ireq->i_len == 0) { - /* zero-len =>'s delete any existing key */ - (void) ieee80211_crypto_delkey(vap, k); - break; - } - if (ireq->i_len > sizeof(tmpkey)) - return EINVAL; - memset(tmpkey, 0, sizeof(tmpkey)); - error = copyin(ireq->i_data, tmpkey, ireq->i_len); - if (error) - break; - ieee80211_key_update_begin(vap); - k->wk_keyix = kid; /* NB: force fixed key id */ - if (ieee80211_crypto_newkey(vap, IEEE80211_CIPHER_WEP, - IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, k)) { - k->wk_keylen = ireq->i_len; - memcpy(k->wk_key, tmpkey, sizeof(tmpkey)); - IEEE80211_ADDR_COPY(k->wk_macaddr, vap->iv_myaddr); - if (!ieee80211_crypto_setkey(vap, k)) - error = EINVAL; - } else - error = EINVAL; - ieee80211_key_update_end(vap); - break; - case IEEE80211_IOC_WEPTXKEY: - kid = (u_int) ireq->i_val; - if (kid >= IEEE80211_WEP_NKID && - (uint16_t) kid != IEEE80211_KEYIX_NONE) - return EINVAL; - vap->iv_def_txkey = kid; - break; - case IEEE80211_IOC_AUTHMODE: - switch (ireq->i_val) { - case IEEE80211_AUTH_WPA: - case IEEE80211_AUTH_8021X: /* 802.1x */ - case IEEE80211_AUTH_OPEN: /* open */ - case IEEE80211_AUTH_SHARED: /* shared-key */ - case IEEE80211_AUTH_AUTO: /* auto */ - auth = ieee80211_authenticator_get(ireq->i_val); - if (auth == NULL) - return EINVAL; - break; - default: - return EINVAL; - } - switch (ireq->i_val) { - case IEEE80211_AUTH_WPA: /* WPA w/ 802.1x */ - vap->iv_flags |= IEEE80211_F_PRIVACY; - ireq->i_val = IEEE80211_AUTH_8021X; - break; - case IEEE80211_AUTH_OPEN: /* open */ - vap->iv_flags &= ~(IEEE80211_F_WPA|IEEE80211_F_PRIVACY); - break; - case IEEE80211_AUTH_SHARED: /* shared-key */ - case IEEE80211_AUTH_8021X: /* 802.1x */ - vap->iv_flags &= ~IEEE80211_F_WPA; - /* both require a key so mark the PRIVACY capability */ - vap->iv_flags |= IEEE80211_F_PRIVACY; - break; - case IEEE80211_AUTH_AUTO: /* auto */ - vap->iv_flags &= ~IEEE80211_F_WPA; - /* XXX PRIVACY handling? */ - /* XXX what's the right way to do this? */ - break; - } - /* NB: authenticator attach/detach happens on state change */ - vap->iv_bss->ni_authmode = ireq->i_val; - /* XXX mixed/mode/usage? */ - vap->iv_auth = auth; - error = ENETRESET; - break; - case IEEE80211_IOC_CHANNEL: - error = ieee80211_ioctl_setchannel(vap, ireq); - break; - case IEEE80211_IOC_POWERSAVE: - switch (ireq->i_val) { - case IEEE80211_POWERSAVE_OFF: - if (vap->iv_flags & IEEE80211_F_PMGTON) { - ieee80211_syncflag(vap, -IEEE80211_F_PMGTON); - error = ERESTART; - } - break; - case IEEE80211_POWERSAVE_ON: - if ((vap->iv_caps & IEEE80211_C_PMGT) == 0) - error = EOPNOTSUPP; - else if ((vap->iv_flags & IEEE80211_F_PMGTON) == 0) { - ieee80211_syncflag(vap, IEEE80211_F_PMGTON); - error = ERESTART; - } - break; - default: - error = EINVAL; - break; - } - break; - case IEEE80211_IOC_POWERSAVESLEEP: - if (ireq->i_val < 0) - return EINVAL; - ic->ic_lintval = ireq->i_val; - error = ERESTART; - break; - case IEEE80211_IOC_RTSTHRESHOLD: - if (!(IEEE80211_RTS_MIN <= ireq->i_val && - ireq->i_val <= IEEE80211_RTS_MAX)) - return EINVAL; - vap->iv_rtsthreshold = ireq->i_val; - error = ERESTART; - break; - case IEEE80211_IOC_PROTMODE: - if (ireq->i_val > IEEE80211_PROT_RTSCTS) - return EINVAL; - ic->ic_protmode = ireq->i_val; - /* NB: if not operating in 11g this can wait */ - if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && - IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) - error = ERESTART; - break; - case IEEE80211_IOC_TXPOWER: - if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0) - return EOPNOTSUPP; - if (!(IEEE80211_TXPOWER_MIN <= ireq->i_val && - ireq->i_val <= IEEE80211_TXPOWER_MAX)) - return EINVAL; - ic->ic_txpowlimit = ireq->i_val; - error = ERESTART; - break; - case IEEE80211_IOC_ROAMING: - if (!(IEEE80211_ROAMING_DEVICE <= ireq->i_val && - ireq->i_val <= IEEE80211_ROAMING_MANUAL)) - return EINVAL; - vap->iv_roaming = ireq->i_val; - /* XXXX reset? */ - break; - case IEEE80211_IOC_PRIVACY: - if (ireq->i_val) { - /* XXX check for key state? */ - vap->iv_flags |= IEEE80211_F_PRIVACY; - } else - vap->iv_flags &= ~IEEE80211_F_PRIVACY; - /* XXX ERESTART? */ - break; - case IEEE80211_IOC_DROPUNENCRYPTED: - if (ireq->i_val) - vap->iv_flags |= IEEE80211_F_DROPUNENC; - else - vap->iv_flags &= ~IEEE80211_F_DROPUNENC; - /* XXX ERESTART? */ - break; - case IEEE80211_IOC_WPAKEY: - error = ieee80211_ioctl_setkey(vap, ireq); - break; - case IEEE80211_IOC_DELKEY: - error = ieee80211_ioctl_delkey(vap, ireq); - break; - case IEEE80211_IOC_MLME: - error = ieee80211_ioctl_setmlme(vap, ireq); - break; - case IEEE80211_IOC_COUNTERMEASURES: - if (ireq->i_val) { - if ((vap->iv_flags & IEEE80211_F_WPA) == 0) - return EOPNOTSUPP; - vap->iv_flags |= IEEE80211_F_COUNTERM; - } else - vap->iv_flags &= ~IEEE80211_F_COUNTERM; - /* XXX ERESTART? */ - break; - case IEEE80211_IOC_WPA: - if (ireq->i_val > 3) - return EINVAL; - /* XXX verify ciphers available */ - flags = vap->iv_flags & ~IEEE80211_F_WPA; - switch (ireq->i_val) { - case 1: - if (!(vap->iv_caps & IEEE80211_C_WPA1)) - return EOPNOTSUPP; - flags |= IEEE80211_F_WPA1; - break; - case 2: - if (!(vap->iv_caps & IEEE80211_C_WPA2)) - return EOPNOTSUPP; - flags |= IEEE80211_F_WPA2; - break; - case 3: - if ((vap->iv_caps & IEEE80211_C_WPA) != IEEE80211_C_WPA) - return EOPNOTSUPP; - flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2; - break; - default: /* Can't set any -> error */ - return EOPNOTSUPP; - } - vap->iv_flags = flags; - error = ERESTART; /* NB: can change beacon frame */ - break; - case IEEE80211_IOC_WME: - if (ireq->i_val) { - if ((vap->iv_caps & IEEE80211_C_WME) == 0) - return EOPNOTSUPP; - ieee80211_syncflag(vap, IEEE80211_F_WME); - } else - ieee80211_syncflag(vap, -IEEE80211_F_WME); - error = ERESTART; /* NB: can change beacon frame */ - break; - case IEEE80211_IOC_HIDESSID: - if (ireq->i_val) - vap->iv_flags |= IEEE80211_F_HIDESSID; - else - vap->iv_flags &= ~IEEE80211_F_HIDESSID; - error = ERESTART; /* XXX ENETRESET? */ - break; - case IEEE80211_IOC_APBRIDGE: - if (ireq->i_val == 0) - vap->iv_flags |= IEEE80211_F_NOBRIDGE; - else - vap->iv_flags &= ~IEEE80211_F_NOBRIDGE; - break; - case IEEE80211_IOC_BSSID: - if (ireq->i_len != sizeof(tmpbssid)) - return EINVAL; - error = copyin(ireq->i_data, tmpbssid, ireq->i_len); - if (error) - break; - IEEE80211_ADDR_COPY(vap->iv_des_bssid, tmpbssid); - if (IEEE80211_ADDR_EQ(vap->iv_des_bssid, zerobssid)) - vap->iv_flags &= ~IEEE80211_F_DESBSSID; - else - vap->iv_flags |= IEEE80211_F_DESBSSID; - error = ENETRESET; - break; - case IEEE80211_IOC_CHANLIST: - error = ieee80211_ioctl_setchanlist(vap, ireq); - break; -#define OLD_IEEE80211_IOC_SCAN_REQ 23 -#ifdef OLD_IEEE80211_IOC_SCAN_REQ - case OLD_IEEE80211_IOC_SCAN_REQ: - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: active scan request\n", __func__); - /* - * If we are in INIT state then the driver has never - * had a chance to setup hardware state to do a scan; - * use the state machine to get us up the SCAN state. - * Otherwise just invoke the scan machinery to start - * a one-time scan. - */ - if (vap->iv_state == IEEE80211_S_INIT) - ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); - else - (void) ieee80211_start_scan(vap, - IEEE80211_SCAN_ACTIVE | - IEEE80211_SCAN_NOPICK | - IEEE80211_SCAN_ONCE, - IEEE80211_SCAN_FOREVER, 0, 0, - /* XXX use ioctl params */ - vap->iv_des_nssid, vap->iv_des_ssid); - break; -#endif /* OLD_IEEE80211_IOC_SCAN_REQ */ - case IEEE80211_IOC_SCAN_REQ: - error = ieee80211_ioctl_scanreq(vap, ireq); - break; - case IEEE80211_IOC_SCAN_CANCEL: - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: cancel scan\n", __func__); - ieee80211_cancel_scan(vap); - break; - case IEEE80211_IOC_HTCONF: - if (ireq->i_val & 1) - ieee80211_syncflag_ht(vap, IEEE80211_FHT_HT); - else - ieee80211_syncflag_ht(vap, -IEEE80211_FHT_HT); - if (ireq->i_val & 2) - ieee80211_syncflag_ht(vap, IEEE80211_FHT_USEHT40); - else - ieee80211_syncflag_ht(vap, -IEEE80211_FHT_USEHT40); - error = ENETRESET; - break; - case IEEE80211_IOC_ADDMAC: - case IEEE80211_IOC_DELMAC: - error = ieee80211_ioctl_macmac(vap, ireq); - break; - case IEEE80211_IOC_MACCMD: - error = ieee80211_ioctl_setmaccmd(vap, ireq); - break; - case IEEE80211_IOC_STA_STATS: - error = ieee80211_ioctl_setstastats(vap, ireq); - break; - case IEEE80211_IOC_STA_TXPOW: - error = ieee80211_ioctl_setstatxpow(vap, ireq); - break; - case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ - case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ - case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ - case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ - case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ - case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ - error = ieee80211_ioctl_setwmeparam(vap, ireq); - break; - case IEEE80211_IOC_DTIM_PERIOD: - if (vap->iv_opmode != IEEE80211_M_HOSTAP && - vap->iv_opmode != IEEE80211_M_MBSS && - vap->iv_opmode != IEEE80211_M_IBSS) - return EINVAL; - if (IEEE80211_DTIM_MIN <= ireq->i_val && - ireq->i_val <= IEEE80211_DTIM_MAX) { - vap->iv_dtim_period = ireq->i_val; - error = ENETRESET; /* requires restart */ - } else - error = EINVAL; - break; - case IEEE80211_IOC_BEACON_INTERVAL: - if (vap->iv_opmode != IEEE80211_M_HOSTAP && - vap->iv_opmode != IEEE80211_M_MBSS && - vap->iv_opmode != IEEE80211_M_IBSS) - return EINVAL; - if (IEEE80211_BINTVAL_MIN <= ireq->i_val && - ireq->i_val <= IEEE80211_BINTVAL_MAX) { - ic->ic_bintval = ireq->i_val; - error = ENETRESET; /* requires restart */ - } else - error = EINVAL; - break; - case IEEE80211_IOC_PUREG: - if (ireq->i_val) - vap->iv_flags |= IEEE80211_F_PUREG; - else - vap->iv_flags &= ~IEEE80211_F_PUREG; - /* NB: reset only if we're operating on an 11g channel */ - if (isvap11g(vap)) - error = ENETRESET; - break; - case IEEE80211_IOC_BGSCAN: - if (ireq->i_val) { - if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0) - return EOPNOTSUPP; - vap->iv_flags |= IEEE80211_F_BGSCAN; - } else - vap->iv_flags &= ~IEEE80211_F_BGSCAN; - break; - case IEEE80211_IOC_BGSCAN_IDLE: - if (ireq->i_val >= IEEE80211_BGSCAN_IDLE_MIN) - vap->iv_bgscanidle = ireq->i_val*hz/1000; - else - error = EINVAL; - break; - case IEEE80211_IOC_BGSCAN_INTERVAL: - if (ireq->i_val >= IEEE80211_BGSCAN_INTVAL_MIN) - vap->iv_bgscanintvl = ireq->i_val*hz; - else - error = EINVAL; - break; - case IEEE80211_IOC_SCANVALID: - if (ireq->i_val >= IEEE80211_SCAN_VALID_MIN) - vap->iv_scanvalid = ireq->i_val*hz; - else - error = EINVAL; - break; - case IEEE80211_IOC_FRAGTHRESHOLD: - if ((vap->iv_caps & IEEE80211_C_TXFRAG) == 0 && - ireq->i_val != IEEE80211_FRAG_MAX) - return EOPNOTSUPP; - if (!(IEEE80211_FRAG_MIN <= ireq->i_val && - ireq->i_val <= IEEE80211_FRAG_MAX)) - return EINVAL; - vap->iv_fragthreshold = ireq->i_val; - error = ERESTART; - break; - case IEEE80211_IOC_BURST: - if (ireq->i_val) { - if ((vap->iv_caps & IEEE80211_C_BURST) == 0) - return EOPNOTSUPP; - ieee80211_syncflag(vap, IEEE80211_F_BURST); - } else - ieee80211_syncflag(vap, -IEEE80211_F_BURST); - error = ERESTART; - break; - case IEEE80211_IOC_BMISSTHRESHOLD: - if (!(IEEE80211_HWBMISS_MIN <= ireq->i_val && - ireq->i_val <= IEEE80211_HWBMISS_MAX)) - return EINVAL; - vap->iv_bmissthreshold = ireq->i_val; - error = ERESTART; - break; - case IEEE80211_IOC_CURCHAN: - error = ieee80211_ioctl_setcurchan(vap, ireq); - break; - case IEEE80211_IOC_SHORTGI: - if (ireq->i_val) { -#define IEEE80211_HTCAP_SHORTGI \ - (IEEE80211_HTCAP_SHORTGI20 | IEEE80211_HTCAP_SHORTGI40) - if (((ireq->i_val ^ vap->iv_htcaps) & IEEE80211_HTCAP_SHORTGI) != 0) - return EINVAL; - if (ireq->i_val & IEEE80211_HTCAP_SHORTGI20) - vap->iv_flags_ht |= IEEE80211_FHT_SHORTGI20; - if (ireq->i_val & IEEE80211_HTCAP_SHORTGI40) - vap->iv_flags_ht |= IEEE80211_FHT_SHORTGI40; -#undef IEEE80211_HTCAP_SHORTGI - } else - vap->iv_flags_ht &= - ~(IEEE80211_FHT_SHORTGI20 | IEEE80211_FHT_SHORTGI40); - error = ERESTART; - break; - case IEEE80211_IOC_AMPDU: - if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMPDU) == 0) - return EINVAL; - if (ireq->i_val & 1) - vap->iv_flags_ht |= IEEE80211_FHT_AMPDU_TX; - else - vap->iv_flags_ht &= ~IEEE80211_FHT_AMPDU_TX; - if (ireq->i_val & 2) - vap->iv_flags_ht |= IEEE80211_FHT_AMPDU_RX; - else - vap->iv_flags_ht &= ~IEEE80211_FHT_AMPDU_RX; - /* NB: reset only if we're operating on an 11n channel */ - if (isvapht(vap)) - error = ERESTART; - break; - case IEEE80211_IOC_AMPDU_LIMIT: - if (!(IEEE80211_HTCAP_MAXRXAMPDU_8K <= ireq->i_val && - ireq->i_val <= IEEE80211_HTCAP_MAXRXAMPDU_64K)) - return EINVAL; - if (vap->iv_opmode == IEEE80211_M_HOSTAP) - vap->iv_ampdu_rxmax = ireq->i_val; - else - vap->iv_ampdu_limit = ireq->i_val; - error = ERESTART; - break; - case IEEE80211_IOC_AMPDU_DENSITY: - if (!(IEEE80211_HTCAP_MPDUDENSITY_NA <= ireq->i_val && - ireq->i_val <= IEEE80211_HTCAP_MPDUDENSITY_16)) - return EINVAL; - vap->iv_ampdu_density = ireq->i_val; - error = ERESTART; - break; - case IEEE80211_IOC_AMSDU: - if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMSDU) == 0) - return EINVAL; - if (ireq->i_val & 1) - vap->iv_flags_ht |= IEEE80211_FHT_AMSDU_TX; - else - vap->iv_flags_ht &= ~IEEE80211_FHT_AMSDU_TX; - if (ireq->i_val & 2) - vap->iv_flags_ht |= IEEE80211_FHT_AMSDU_RX; - else - vap->iv_flags_ht &= ~IEEE80211_FHT_AMSDU_RX; - /* NB: reset only if we're operating on an 11n channel */ - if (isvapht(vap)) - error = ERESTART; - break; - case IEEE80211_IOC_AMSDU_LIMIT: - /* XXX validate */ - vap->iv_amsdu_limit = ireq->i_val; /* XXX truncation? */ - break; - case IEEE80211_IOC_PUREN: - if (ireq->i_val) { - if ((vap->iv_flags_ht & IEEE80211_FHT_HT) == 0) - return EINVAL; - vap->iv_flags_ht |= IEEE80211_FHT_PUREN; - } else - vap->iv_flags_ht &= ~IEEE80211_FHT_PUREN; - /* NB: reset only if we're operating on an 11n channel */ - if (isvapht(vap)) - error = ERESTART; - break; - case IEEE80211_IOC_DOTH: - if (ireq->i_val) { -#if 0 - /* XXX no capability */ - if ((vap->iv_caps & IEEE80211_C_DOTH) == 0) - return EOPNOTSUPP; -#endif - vap->iv_flags |= IEEE80211_F_DOTH; - } else - vap->iv_flags &= ~IEEE80211_F_DOTH; - error = ENETRESET; - break; - case IEEE80211_IOC_REGDOMAIN: - error = ieee80211_ioctl_setregdomain(vap, ireq); - break; - case IEEE80211_IOC_ROAM: - error = ieee80211_ioctl_setroam(vap, ireq); - break; - case IEEE80211_IOC_TXPARAMS: - error = ieee80211_ioctl_settxparams(vap, ireq); - break; - case IEEE80211_IOC_HTCOMPAT: - if (ireq->i_val) { - if ((vap->iv_flags_ht & IEEE80211_FHT_HT) == 0) - return EOPNOTSUPP; - vap->iv_flags_ht |= IEEE80211_FHT_HTCOMPAT; - } else - vap->iv_flags_ht &= ~IEEE80211_FHT_HTCOMPAT; - /* NB: reset only if we're operating on an 11n channel */ - if (isvapht(vap)) - error = ERESTART; - break; - case IEEE80211_IOC_DWDS: - if (ireq->i_val) { - /* NB: DWDS only makes sense for WDS-capable devices */ - if ((ic->ic_caps & IEEE80211_C_WDS) == 0) - return EOPNOTSUPP; - /* NB: DWDS is used only with ap+sta vaps */ - if (vap->iv_opmode != IEEE80211_M_HOSTAP && - vap->iv_opmode != IEEE80211_M_STA) - return EINVAL; - vap->iv_flags |= IEEE80211_F_DWDS; - if (vap->iv_opmode == IEEE80211_M_STA) - vap->iv_flags_ext |= IEEE80211_FEXT_4ADDR; - } else { - vap->iv_flags &= ~IEEE80211_F_DWDS; - if (vap->iv_opmode == IEEE80211_M_STA) - vap->iv_flags_ext &= ~IEEE80211_FEXT_4ADDR; - } - break; - case IEEE80211_IOC_INACTIVITY: - if (ireq->i_val) - vap->iv_flags_ext |= IEEE80211_FEXT_INACT; - else - vap->iv_flags_ext &= ~IEEE80211_FEXT_INACT; - break; - case IEEE80211_IOC_APPIE: - error = ieee80211_ioctl_setappie(vap, ireq); - break; - case IEEE80211_IOC_WPS: - if (ireq->i_val) { - if ((vap->iv_caps & IEEE80211_C_WPA) == 0) - return EOPNOTSUPP; - vap->iv_flags_ext |= IEEE80211_FEXT_WPS; - } else - vap->iv_flags_ext &= ~IEEE80211_FEXT_WPS; - break; - case IEEE80211_IOC_TSN: - if (ireq->i_val) { - if ((vap->iv_caps & IEEE80211_C_WPA) == 0) - return EOPNOTSUPP; - vap->iv_flags_ext |= IEEE80211_FEXT_TSN; - } else - vap->iv_flags_ext &= ~IEEE80211_FEXT_TSN; - break; - case IEEE80211_IOC_CHANSWITCH: - error = ieee80211_ioctl_chanswitch(vap, ireq); - break; - case IEEE80211_IOC_DFS: - if (ireq->i_val) { - if ((vap->iv_caps & IEEE80211_C_DFS) == 0) - return EOPNOTSUPP; - /* NB: DFS requires 11h support */ - if ((vap->iv_flags & IEEE80211_F_DOTH) == 0) - return EINVAL; - vap->iv_flags_ext |= IEEE80211_FEXT_DFS; - } else - vap->iv_flags_ext &= ~IEEE80211_FEXT_DFS; - break; - case IEEE80211_IOC_DOTD: - if (ireq->i_val) - vap->iv_flags_ext |= IEEE80211_FEXT_DOTD; - else - vap->iv_flags_ext &= ~IEEE80211_FEXT_DOTD; - if (vap->iv_opmode == IEEE80211_M_STA) - error = ENETRESET; - break; - case IEEE80211_IOC_HTPROTMODE: - if (ireq->i_val > IEEE80211_PROT_RTSCTS) - return EINVAL; - ic->ic_htprotmode = ireq->i_val ? - IEEE80211_PROT_RTSCTS : IEEE80211_PROT_NONE; - /* NB: if not operating in 11n this can wait */ - if (isvapht(vap)) - error = ERESTART; - break; - case IEEE80211_IOC_STA_VLAN: - error = ieee80211_ioctl_setstavlan(vap, ireq); - break; - case IEEE80211_IOC_SMPS: - if ((ireq->i_val &~ IEEE80211_HTCAP_SMPS) != 0 || - ireq->i_val == 0x0008) /* value of 2 is reserved */ - return EINVAL; - if (ireq->i_val != IEEE80211_HTCAP_SMPS_OFF && - (vap->iv_htcaps & IEEE80211_HTC_SMPS) == 0) - return EOPNOTSUPP; - vap->iv_htcaps = (vap->iv_htcaps &~ IEEE80211_HTCAP_SMPS) | - ireq->i_val; - /* NB: if not operating in 11n this can wait */ - if (isvapht(vap)) - error = ERESTART; - break; - case IEEE80211_IOC_RIFS: - if (ireq->i_val != 0) { - if ((vap->iv_htcaps & IEEE80211_HTC_RIFS) == 0) - return EOPNOTSUPP; - vap->iv_flags_ht |= IEEE80211_FHT_RIFS; - } else - vap->iv_flags_ht &= ~IEEE80211_FHT_RIFS; - /* NB: if not operating in 11n this can wait */ - if (isvapht(vap)) - error = ERESTART; - break; - default: - error = ieee80211_ioctl_setdefault(vap, ireq); - break; - } - /* - * The convention is that ENETRESET means an operation - * requires a complete re-initialization of the device (e.g. - * changing something that affects the association state). - * ERESTART means the request may be handled with only a - * reload of the hardware state. We hand ERESTART requests - * to the iv_reset callback so the driver can decide. If - * a device does not fillin iv_reset then it defaults to one - * that returns ENETRESET. Otherwise a driver may return - * ENETRESET (in which case a full reset will be done) or - * 0 to mean there's no need to do anything (e.g. when the - * change has no effect on the driver/device). - */ - if (error == ERESTART) - error = IFNET_IS_UP_RUNNING(vap->iv_ifp) ? - vap->iv_reset(vap, ireq->i_type) : 0; - if (error == ENETRESET) { - /* XXX need to re-think AUTO handling */ - if (IS_UP_AUTO(vap)) - ieee80211_init(vap); - error = 0; - } - return error; -} - -/* - * Rebuild the parent's multicast address list after an add/del - * of a multicast address for a vap. We have no way to tell - * what happened above to optimize the work so we purge the entire - * list and rebuild from scratch. This is way expensive. - * Note also the half-baked workaround for if_addmulti calling - * back to the parent device; there's no way to insert mcast - * entries quietly and/or cheaply. - */ -static void -ieee80211_ioctl_updatemulti(struct ieee80211com *ic) -{ - struct ifnet *parent = ic->ic_ifp; - struct ieee80211vap *vap; - void *ioctl; - - IEEE80211_LOCK(ic); - if_delallmulti(parent); - ioctl = parent->if_ioctl; /* XXX WAR if_allmulti */ - parent->if_ioctl = NULL; - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - struct ifnet *ifp = vap->iv_ifp; - struct ifmultiaddr *ifma; - - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - (void) if_addmulti(parent, ifma->ifma_addr, NULL); - } - } - parent->if_ioctl = ioctl; - ieee80211_runtask(ic, &ic->ic_mcast_task); - IEEE80211_UNLOCK(ic); -} - -int -ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) -{ - struct ieee80211vap *vap = ifp->if_softc; - struct ieee80211com *ic = vap->iv_ic; - int error = 0; - struct ifreq *ifr; - struct ifaddr *ifa; /* XXX */ - - switch (cmd) { - case SIOCSIFFLAGS: - IEEE80211_LOCK(ic); - ieee80211_syncifflag_locked(ic, IFF_PROMISC); - ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); - if (ifp->if_flags & IFF_UP) { - /* - * Bring ourself up unless we're already operational. - * If we're the first vap and the parent is not up - * then it will automatically be brought up as a - * side-effect of bringing ourself up. - */ - if (vap->iv_state == IEEE80211_S_INIT) - ieee80211_start_locked(vap); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - /* - * Stop ourself. If we are the last vap to be - * marked down the parent will also be taken down. - */ - ieee80211_stop_locked(vap); - } - IEEE80211_UNLOCK(ic); - /* Wait for parent ioctl handler if it was queued */ - ieee80211_waitfor_parent(ic); - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - ieee80211_ioctl_updatemulti(ic); - break; - case SIOCSIFMEDIA: - case SIOCGIFMEDIA: - ifr = (struct ifreq *)data; - error = ifmedia_ioctl(ifp, ifr, &vap->iv_media, cmd); - break; - case SIOCG80211: - error = ieee80211_ioctl_get80211(vap, cmd, - (struct ieee80211req *) data); - break; - case SIOCS80211: - error = priv_check(curthread, PRIV_NET80211_MANAGE); - if (error == 0) - error = ieee80211_ioctl_set80211(vap, cmd, - (struct ieee80211req *) data); - break; - case SIOCG80211STATS: - ifr = (struct ifreq *)data; - copyout(&vap->iv_stats, ifr->ifr_data, sizeof (vap->iv_stats)); - break; - case SIOCSIFMTU: - ifr = (struct ifreq *)data; - if (!(IEEE80211_MTU_MIN <= ifr->ifr_mtu && - ifr->ifr_mtu <= IEEE80211_MTU_MAX)) - error = EINVAL; - else - ifp->if_mtu = ifr->ifr_mtu; - break; - case SIOCSIFADDR: - /* - * XXX Handle this directly so we can supress if_init calls. - * XXX This should be done in ether_ioctl but for the moment - * XXX there are too many other parts of the system that - * XXX set IFF_UP and so supress if_init being called when - * XXX it should be. - */ - ifa = (struct ifaddr *) data; - switch (ifa->ifa_addr->sa_family) { -#ifdef INET - case AF_INET: - if ((ifp->if_flags & IFF_UP) == 0) { - ifp->if_flags |= IFF_UP; - ifp->if_init(ifp->if_softc); - } - arp_ifinit(ifp, ifa); - break; -#endif -#ifdef IPX - /* - * XXX - This code is probably wrong, - * but has been copied many times. - */ - case AF_IPX: { - struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); - - if (ipx_nullhost(*ina)) - ina->x_host = *(union ipx_host *) - IF_LLADDR(ifp); - else - bcopy((caddr_t) ina->x_host.c_host, - (caddr_t) IF_LLADDR(ifp), - ETHER_ADDR_LEN); - /* fall thru... */ - } -#endif - default: - if ((ifp->if_flags & IFF_UP) == 0) { - ifp->if_flags |= IFF_UP; - ifp->if_init(ifp->if_softc); - } - break; - } - break; - /* Pass NDIS ioctls up to the driver */ - case SIOCGDRVSPEC: - case SIOCSDRVSPEC: - case SIOCGPRIVATE_0: { - struct ifnet *parent = vap->iv_ic->ic_ifp; - error = parent->if_ioctl(parent, cmd, data); - break; - } - default: - error = ether_ioctl(ifp, cmd, data); - break; - } - return error; -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.h deleted file mode 100644 index 551d1877a4..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.h +++ /dev/null @@ -1,873 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_IOCTL_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_IOCTL_H_ - -/* - * IEEE 802.11 ioctls. - */ -#include -#include -#include - -/* - * Per/node (station) statistics. - */ -struct ieee80211_nodestats { - uint32_t ns_rx_data; /* rx data frames */ - uint32_t ns_rx_mgmt; /* rx management frames */ - uint32_t ns_rx_ctrl; /* rx control frames */ - uint32_t ns_rx_ucast; /* rx unicast frames */ - uint32_t ns_rx_mcast; /* rx multi/broadcast frames */ - uint64_t ns_rx_bytes; /* rx data count (bytes) */ - uint64_t ns_rx_beacons; /* rx beacon frames */ - uint32_t ns_rx_proberesp; /* rx probe response frames */ - - uint32_t ns_rx_dup; /* rx discard 'cuz dup */ - uint32_t ns_rx_noprivacy; /* rx w/ wep but privacy off */ - uint32_t ns_rx_wepfail; /* rx wep processing failed */ - uint32_t ns_rx_demicfail; /* rx demic failed */ - uint32_t ns_rx_decap; /* rx decapsulation failed */ - uint32_t ns_rx_defrag; /* rx defragmentation failed */ - uint32_t ns_rx_disassoc; /* rx disassociation */ - uint32_t ns_rx_deauth; /* rx deauthentication */ - uint32_t ns_rx_action; /* rx action */ - uint32_t ns_rx_decryptcrc; /* rx decrypt failed on crc */ - uint32_t ns_rx_unauth; /* rx on unauthorized port */ - uint32_t ns_rx_unencrypted; /* rx unecrypted w/ privacy */ - uint32_t ns_rx_drop; /* rx discard other reason */ - - uint32_t ns_tx_data; /* tx data frames */ - uint32_t ns_tx_mgmt; /* tx management frames */ - uint32_t ns_tx_ctrl; /* tx control frames */ - uint32_t ns_tx_ucast; /* tx unicast frames */ - uint32_t ns_tx_mcast; /* tx multi/broadcast frames */ - uint64_t ns_tx_bytes; /* tx data count (bytes) */ - uint32_t ns_tx_probereq; /* tx probe request frames */ - - uint32_t ns_tx_novlantag; /* tx discard 'cuz no tag */ - uint32_t ns_tx_vlanmismatch; /* tx discard 'cuz bad tag */ - - uint32_t ns_ps_discard; /* ps discard 'cuz of age */ - - /* MIB-related state */ - uint32_t ns_tx_assoc; /* [re]associations */ - uint32_t ns_tx_assoc_fail; /* [re]association failures */ - uint32_t ns_tx_auth; /* [re]authentications */ - uint32_t ns_tx_auth_fail; /* [re]authentication failures*/ - uint32_t ns_tx_deauth; /* deauthentications */ - uint32_t ns_tx_deauth_code; /* last deauth reason */ - uint32_t ns_tx_disassoc; /* disassociations */ - uint32_t ns_tx_disassoc_code; /* last disassociation reason */ - uint32_t ns_spare[8]; -}; - -/* - * Summary statistics. - */ -struct ieee80211_stats { - uint32_t is_rx_badversion; /* rx frame with bad version */ - uint32_t is_rx_tooshort; /* rx frame too short */ - uint32_t is_rx_wrongbss; /* rx from wrong bssid */ - uint32_t is_rx_dup; /* rx discard 'cuz dup */ - uint32_t is_rx_wrongdir; /* rx w/ wrong direction */ - uint32_t is_rx_mcastecho; /* rx discard 'cuz mcast echo */ - uint32_t is_rx_notassoc; /* rx discard 'cuz sta !assoc */ - uint32_t is_rx_noprivacy; /* rx w/ wep but privacy off */ - uint32_t is_rx_unencrypted; /* rx w/o wep and privacy on */ - uint32_t is_rx_wepfail; /* rx wep processing failed */ - uint32_t is_rx_decap; /* rx decapsulation failed */ - uint32_t is_rx_mgtdiscard; /* rx discard mgt frames */ - uint32_t is_rx_ctl; /* rx ctrl frames */ - uint32_t is_rx_beacon; /* rx beacon frames */ - uint32_t is_rx_rstoobig; /* rx rate set truncated */ - uint32_t is_rx_elem_missing; /* rx required element missing*/ - uint32_t is_rx_elem_toobig; /* rx element too big */ - uint32_t is_rx_elem_toosmall; /* rx element too small */ - uint32_t is_rx_elem_unknown; /* rx element unknown */ - uint32_t is_rx_badchan; /* rx frame w/ invalid chan */ - uint32_t is_rx_chanmismatch; /* rx frame chan mismatch */ - uint32_t is_rx_nodealloc; /* rx frame dropped */ - uint32_t is_rx_ssidmismatch; /* rx frame ssid mismatch */ - uint32_t is_rx_auth_unsupported; /* rx w/ unsupported auth alg */ - uint32_t is_rx_auth_fail; /* rx sta auth failure */ - uint32_t is_rx_auth_countermeasures;/* rx auth discard 'cuz CM */ - uint32_t is_rx_assoc_bss; /* rx assoc from wrong bssid */ - uint32_t is_rx_assoc_notauth; /* rx assoc w/o auth */ - uint32_t is_rx_assoc_capmismatch;/* rx assoc w/ cap mismatch */ - uint32_t is_rx_assoc_norate; /* rx assoc w/ no rate match */ - uint32_t is_rx_assoc_badwpaie; /* rx assoc w/ bad WPA IE */ - uint32_t is_rx_deauth; /* rx deauthentication */ - uint32_t is_rx_disassoc; /* rx disassociation */ - uint32_t is_rx_badsubtype; /* rx frame w/ unknown subtype*/ - uint32_t is_rx_nobuf; /* rx failed for lack of buf */ - uint32_t is_rx_decryptcrc; /* rx decrypt failed on crc */ - uint32_t is_rx_ahdemo_mgt; /* rx discard ahdemo mgt frame*/ - uint32_t is_rx_bad_auth; /* rx bad auth request */ - uint32_t is_rx_unauth; /* rx on unauthorized port */ - uint32_t is_rx_badkeyid; /* rx w/ incorrect keyid */ - uint32_t is_rx_ccmpreplay; /* rx seq# violation (CCMP) */ - uint32_t is_rx_ccmpformat; /* rx format bad (CCMP) */ - uint32_t is_rx_ccmpmic; /* rx MIC check failed (CCMP) */ - uint32_t is_rx_tkipreplay; /* rx seq# violation (TKIP) */ - uint32_t is_rx_tkipformat; /* rx format bad (TKIP) */ - uint32_t is_rx_tkipmic; /* rx MIC check failed (TKIP) */ - uint32_t is_rx_tkipicv; /* rx ICV check failed (TKIP) */ - uint32_t is_rx_badcipher; /* rx failed 'cuz key type */ - uint32_t is_rx_nocipherctx; /* rx failed 'cuz key !setup */ - uint32_t is_rx_acl; /* rx discard 'cuz acl policy */ - uint32_t is_tx_nobuf; /* tx failed for lack of buf */ - uint32_t is_tx_nonode; /* tx failed for no node */ - uint32_t is_tx_unknownmgt; /* tx of unknown mgt frame */ - uint32_t is_tx_badcipher; /* tx failed 'cuz key type */ - uint32_t is_tx_nodefkey; /* tx failed 'cuz no defkey */ - uint32_t is_tx_noheadroom; /* tx failed 'cuz no space */ - uint32_t is_tx_fragframes; /* tx frames fragmented */ - uint32_t is_tx_frags; /* tx fragments created */ - uint32_t is_scan_active; /* active scans started */ - uint32_t is_scan_passive; /* passive scans started */ - uint32_t is_node_timeout; /* nodes timed out inactivity */ - uint32_t is_crypto_nomem; /* no memory for crypto ctx */ - uint32_t is_crypto_tkip; /* tkip crypto done in s/w */ - uint32_t is_crypto_tkipenmic; /* tkip en-MIC done in s/w */ - uint32_t is_crypto_tkipdemic; /* tkip de-MIC done in s/w */ - uint32_t is_crypto_tkipcm; /* tkip counter measures */ - uint32_t is_crypto_ccmp; /* ccmp crypto done in s/w */ - uint32_t is_crypto_wep; /* wep crypto done in s/w */ - uint32_t is_crypto_setkey_cipher;/* cipher rejected key */ - uint32_t is_crypto_setkey_nokey; /* no key index for setkey */ - uint32_t is_crypto_delkey; /* driver key delete failed */ - uint32_t is_crypto_badcipher; /* unknown cipher */ - uint32_t is_crypto_nocipher; /* cipher not available */ - uint32_t is_crypto_attachfail; /* cipher attach failed */ - uint32_t is_crypto_swfallback; /* cipher fallback to s/w */ - uint32_t is_crypto_keyfail; /* driver key alloc failed */ - uint32_t is_crypto_enmicfail; /* en-MIC failed */ - uint32_t is_ibss_capmismatch; /* merge failed-cap mismatch */ - uint32_t is_ibss_norate; /* merge failed-rate mismatch */ - uint32_t is_ps_unassoc; /* ps-poll for unassoc. sta */ - uint32_t is_ps_badaid; /* ps-poll w/ incorrect aid */ - uint32_t is_ps_qempty; /* ps-poll w/ nothing to send */ - uint32_t is_ff_badhdr; /* fast frame rx'd w/ bad hdr */ - uint32_t is_ff_tooshort; /* fast frame rx decap error */ - uint32_t is_ff_split; /* fast frame rx split error */ - uint32_t is_ff_decap; /* fast frames decap'd */ - uint32_t is_ff_encap; /* fast frames encap'd for tx */ - uint32_t is_rx_badbintval; /* rx frame w/ bogus bintval */ - uint32_t is_rx_demicfail; /* rx demic failed */ - uint32_t is_rx_defrag; /* rx defragmentation failed */ - uint32_t is_rx_mgmt; /* rx management frames */ - uint32_t is_rx_action; /* rx action mgt frames */ - uint32_t is_amsdu_tooshort; /* A-MSDU rx decap error */ - uint32_t is_amsdu_split; /* A-MSDU rx split error */ - uint32_t is_amsdu_decap; /* A-MSDU decap'd */ - uint32_t is_amsdu_encap; /* A-MSDU encap'd for tx */ - uint32_t is_ampdu_bar_bad; /* A-MPDU BAR out of window */ - uint32_t is_ampdu_bar_oow; /* A-MPDU BAR before ADDBA */ - uint32_t is_ampdu_bar_move; /* A-MPDU BAR moved window */ - uint32_t is_ampdu_bar_rx; /* A-MPDU BAR frames handled */ - uint32_t is_ampdu_rx_flush; /* A-MPDU frames flushed */ - uint32_t is_ampdu_rx_oor; /* A-MPDU frames out-of-order */ - uint32_t is_ampdu_rx_copy; /* A-MPDU frames copied down */ - uint32_t is_ampdu_rx_drop; /* A-MPDU frames dropped */ - uint32_t is_tx_badstate; /* tx discard state != RUN */ - uint32_t is_tx_notassoc; /* tx failed, sta not assoc */ - uint32_t is_tx_classify; /* tx classification failed */ - uint32_t is_dwds_mcast; /* discard mcast over dwds */ - uint32_t is_dwds_qdrop; /* dwds pending frame q full */ - uint32_t is_ht_assoc_nohtcap; /* non-HT sta rejected */ - uint32_t is_ht_assoc_downgrade; /* HT sta forced to legacy */ - uint32_t is_ht_assoc_norate; /* HT assoc w/ rate mismatch */ - uint32_t is_ampdu_rx_age; /* A-MPDU sent up 'cuz of age */ - uint32_t is_ampdu_rx_move; /* A-MPDU MSDU moved window */ - uint32_t is_addba_reject; /* ADDBA reject 'cuz disabled */ - uint32_t is_addba_norequest; /* ADDBA response w/o ADDBA */ - uint32_t is_addba_badtoken; /* ADDBA response w/ wrong - dialogtoken */ - uint32_t is_addba_badpolicy; /* ADDBA resp w/ wrong policy */ - uint32_t is_ampdu_stop; /* A-MPDU stream stopped */ - uint32_t is_ampdu_stop_failed; /* A-MPDU stream not running */ - uint32_t is_ampdu_rx_reorder; /* A-MPDU held for rx reorder */ - uint32_t is_scan_bg; /* background scans started */ - uint8_t is_rx_deauth_code; /* last rx'd deauth reason */ - uint8_t is_rx_disassoc_code; /* last rx'd disassoc reason */ - uint8_t is_rx_authfail_code; /* last rx'd auth fail reason */ - uint32_t is_beacon_miss; /* beacon miss notification */ - uint32_t is_rx_badstate; /* rx discard state != RUN */ - uint32_t is_ff_flush; /* ff's flush'd from stageq */ - uint32_t is_tx_ctl; /* tx ctrl frames */ - uint32_t is_ampdu_rexmt; /* A-MPDU frames rexmt ok */ - uint32_t is_ampdu_rexmt_fail; /* A-MPDU frames rexmt fail */ - - uint32_t is_mesh_wrongmesh; /* dropped 'cuz not mesh sta*/ - uint32_t is_mesh_nolink; /* dropped 'cuz link not estab*/ - uint32_t is_mesh_fwd_ttl; /* mesh not fwd'd 'cuz ttl 0 */ - uint32_t is_mesh_fwd_nobuf; /* mesh not fwd'd 'cuz no mbuf*/ - uint32_t is_mesh_fwd_tooshort; /* mesh not fwd'd 'cuz no hdr */ - uint32_t is_mesh_fwd_disabled; /* mesh not fwd'd 'cuz disabled */ - uint32_t is_mesh_fwd_nopath; /* mesh not fwd'd 'cuz path unknown */ - - uint32_t is_hwmp_wrongseq; /* wrong hwmp seq no. */ - uint32_t is_hwmp_rootreqs; /* root PREQs sent */ - uint32_t is_hwmp_rootrann; /* root RANNs sent */ - - uint32_t is_mesh_badae; /* dropped 'cuz invalid AE */ - uint32_t is_mesh_rtaddfailed; /* route add failed */ - uint32_t is_mesh_notproxy; /* dropped 'cuz not proxying */ - uint32_t is_rx_badalign; /* dropped 'cuz misaligned */ - uint32_t is_hwmp_proxy; /* PREP for proxy route */ - - uint32_t is_spare[11]; -}; - -/* - * Max size of optional information elements. We artificially - * constrain this; it's limited only by the max frame size (and - * the max parameter size of the wireless extensions). - */ -#define IEEE80211_MAX_OPT_IE 256 - -/* - * WPA/RSN get/set key request. Specify the key/cipher - * type and whether the key is to be used for sending and/or - * receiving. The key index should be set only when working - * with global keys (use IEEE80211_KEYIX_NONE for ``no index''). - * Otherwise a unicast/pairwise key is specified by the bssid - * (on a station) or mac address (on an ap). They key length - * must include any MIC key data; otherwise it should be no - * more than IEEE80211_KEYBUF_SIZE. - */ -struct ieee80211req_key { - uint8_t ik_type; /* key/cipher type */ - uint8_t ik_pad; - uint16_t ik_keyix; /* key index */ - uint8_t ik_keylen; /* key length in bytes */ - uint8_t ik_flags; -/* NB: IEEE80211_KEY_XMIT and IEEE80211_KEY_RECV defined elsewhere */ -#define IEEE80211_KEY_DEFAULT 0x80 /* default xmit key */ - uint8_t ik_macaddr[IEEE80211_ADDR_LEN]; - uint64_t ik_keyrsc; /* key receive sequence counter */ - uint64_t ik_keytsc; /* key transmit sequence counter */ - uint8_t ik_keydata[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE]; -}; - -/* - * Delete a key either by index or address. Set the index - * to IEEE80211_KEYIX_NONE when deleting a unicast key. - */ -struct ieee80211req_del_key { - uint8_t idk_keyix; /* key index */ - uint8_t idk_macaddr[IEEE80211_ADDR_LEN]; -}; - -/* - * MLME state manipulation request. IEEE80211_MLME_ASSOC - * only makes sense when operating as a station. The other - * requests can be used when operating as a station or an - * ap (to effect a station). - */ -struct ieee80211req_mlme { - uint8_t im_op; /* operation to perform */ -#define IEEE80211_MLME_ASSOC 1 /* associate station */ -#define IEEE80211_MLME_DISASSOC 2 /* disassociate station */ -#define IEEE80211_MLME_DEAUTH 3 /* deauthenticate station */ -#define IEEE80211_MLME_AUTHORIZE 4 /* authorize station */ -#define IEEE80211_MLME_UNAUTHORIZE 5 /* unauthorize station */ -#define IEEE80211_MLME_AUTH 6 /* authenticate station */ - uint8_t im_ssid_len; /* length of optional ssid */ - uint16_t im_reason; /* 802.11 reason code */ - uint8_t im_macaddr[IEEE80211_ADDR_LEN]; - uint8_t im_ssid[IEEE80211_NWID_LEN]; -}; - -/* - * MAC ACL operations. - */ -enum { - IEEE80211_MACCMD_POLICY_OPEN = 0, /* set policy: no ACL's */ - IEEE80211_MACCMD_POLICY_ALLOW = 1, /* set policy: allow traffic */ - IEEE80211_MACCMD_POLICY_DENY = 2, /* set policy: deny traffic */ - IEEE80211_MACCMD_FLUSH = 3, /* flush ACL database */ - IEEE80211_MACCMD_DETACH = 4, /* detach ACL policy */ - IEEE80211_MACCMD_POLICY = 5, /* get ACL policy */ - IEEE80211_MACCMD_LIST = 6, /* get ACL database */ - IEEE80211_MACCMD_POLICY_RADIUS = 7, /* set policy: RADIUS managed */ -}; - -struct ieee80211req_maclist { - uint8_t ml_macaddr[IEEE80211_ADDR_LEN]; -} __packed; - -/* - * Mesh Routing Table Operations. - */ -enum { - IEEE80211_MESH_RTCMD_LIST = 0, /* list HWMP routing table */ - IEEE80211_MESH_RTCMD_FLUSH = 1, /* flush HWMP routing table */ - IEEE80211_MESH_RTCMD_ADD = 2, /* add entry to the table */ - IEEE80211_MESH_RTCMD_DELETE = 3, /* delete an entry from the table */ -}; - -struct ieee80211req_mesh_route { - uint8_t imr_flags; -#define IEEE80211_MESHRT_FLAGS_VALID 0x01 -#define IEEE80211_MESHRT_FLAGS_PROXY 0x02 - uint8_t imr_dest[IEEE80211_ADDR_LEN]; - uint8_t imr_nexthop[IEEE80211_ADDR_LEN]; - uint16_t imr_nhops; - uint8_t imr_pad; - uint32_t imr_metric; - uint32_t imr_lifetime; - uint32_t imr_lastmseq; -}; - -/* - * HWMP root modes - */ -enum { - IEEE80211_HWMP_ROOTMODE_DISABLED = 0, /* disabled */ - IEEE80211_HWMP_ROOTMODE_NORMAL = 1, /* normal PREPs */ - IEEE80211_HWMP_ROOTMODE_PROACTIVE = 2, /* proactive PREPS */ - IEEE80211_HWMP_ROOTMODE_RANN = 3, /* use RANN elemid */ -}; - - -/* - * Set the active channel list by IEEE channel #: each channel - * to be marked active is set in a bit vector. Note this list is - * intersected with the available channel list in calculating - * the set of channels actually used in scanning. - */ -struct ieee80211req_chanlist { - uint8_t ic_channels[32]; /* NB: can be variable length */ -}; - -/* - * Get the active channel list info. - */ -struct ieee80211req_chaninfo { - u_int ic_nchans; - struct ieee80211_channel ic_chans[1]; /* NB: variable length */ -}; -#define IEEE80211_CHANINFO_SIZE(_nchan) \ - (sizeof(struct ieee80211req_chaninfo) + \ - (((_nchan)-1) * sizeof(struct ieee80211_channel))) -#define IEEE80211_CHANINFO_SPACE(_ci) \ - IEEE80211_CHANINFO_SIZE((_ci)->ic_nchans) - -/* - * Retrieve the WPA/RSN information element for an associated station. - */ -struct ieee80211req_wpaie { /* old version w/ only one ie */ - uint8_t wpa_macaddr[IEEE80211_ADDR_LEN]; - uint8_t wpa_ie[IEEE80211_MAX_OPT_IE]; -}; -struct ieee80211req_wpaie2 { - uint8_t wpa_macaddr[IEEE80211_ADDR_LEN]; - uint8_t wpa_ie[IEEE80211_MAX_OPT_IE]; - uint8_t rsn_ie[IEEE80211_MAX_OPT_IE]; -}; - -/* - * Retrieve per-node statistics. - */ -struct ieee80211req_sta_stats { - union { - /* NB: explicitly force 64-bit alignment */ - uint8_t macaddr[IEEE80211_ADDR_LEN]; - uint64_t pad; - } is_u; - struct ieee80211_nodestats is_stats; -}; - -/* - * Station information block; the mac address is used - * to retrieve other data like stats, unicast key, etc. - */ -struct ieee80211req_sta_info { - uint16_t isi_len; /* total length (mult of 4) */ - uint16_t isi_ie_off; /* offset to IE data */ - uint16_t isi_ie_len; /* IE length */ -#ifdef __HAIKU__ - struct ieee80211_channel isi_chan; /* Handing out the conmplete channel info */ -#else - uint16_t isi_freq; /* MHz */ - uint32_t isi_flags; /* channel flags */ -#endif - uint32_t isi_state; /* state flags */ - uint8_t isi_authmode; /* authentication algorithm */ - int8_t isi_rssi; /* receive signal strength */ - int8_t isi_noise; /* noise floor */ - uint8_t isi_capinfo; /* capabilities */ - uint8_t isi_erp; /* ERP element */ - uint8_t isi_macaddr[IEEE80211_ADDR_LEN]; - uint8_t isi_nrates; - /* negotiated rates */ - uint8_t isi_rates[IEEE80211_RATE_MAXSIZE]; - uint8_t isi_txrate; /* legacy/IEEE rate or MCS */ - uint16_t isi_associd; /* assoc response */ - uint16_t isi_txpower; /* current tx power */ - uint16_t isi_vlan; /* vlan tag */ - /* NB: [IEEE80211_NONQOS_TID] holds seq#'s for non-QoS stations */ - uint16_t isi_txseqs[IEEE80211_TID_SIZE];/* tx seq #/TID */ - uint16_t isi_rxseqs[IEEE80211_TID_SIZE];/* rx seq#/TID */ - uint16_t isi_inact; /* inactivity timer */ - uint16_t isi_txmbps; /* current tx rate in .5 Mb/s */ - uint16_t isi_pad; - uint32_t isi_jointime; /* time of assoc/join */ - struct ieee80211_mimo_info isi_mimo; /* MIMO info for 11n sta's */ - /* 11s info */ - uint16_t isi_peerid; - uint16_t isi_localid; - uint8_t isi_peerstate; - /* XXX frag state? */ - /* variable length IE data */ -}; - -/* - * Retrieve per-station information; to retrieve all - * specify a mac address of ff:ff:ff:ff:ff:ff. - */ -struct ieee80211req_sta_req { - union { - /* NB: explicitly force 64-bit alignment */ - uint8_t macaddr[IEEE80211_ADDR_LEN]; - uint64_t pad; - } is_u; - struct ieee80211req_sta_info info[1]; /* variable length */ -}; - -/* - * Get/set per-station tx power cap. - */ -struct ieee80211req_sta_txpow { - uint8_t it_macaddr[IEEE80211_ADDR_LEN]; - uint8_t it_txpow; -}; - -/* - * WME parameters manipulated with IEEE80211_IOC_WME_CWMIN - * through IEEE80211_IOC_WME_ACKPOLICY are set and return - * using i_val and i_len. i_val holds the value itself. - * i_len specifies the AC and, as appropriate, then high bit - * specifies whether the operation is to be applied to the - * BSS or ourself. - */ -#define IEEE80211_WMEPARAM_SELF 0x0000 /* parameter applies to self */ -#define IEEE80211_WMEPARAM_BSS 0x8000 /* parameter applies to BSS */ -#define IEEE80211_WMEPARAM_VAL 0x7fff /* parameter value */ - -/* - * Application Information Elements can be appended to a variety - * of frames with the IEE80211_IOC_APPIE request. This request - * piggybacks on a normal ieee80211req; the frame type is passed - * in i_val as the 802.11 FC0 bytes and the length of the IE data - * is passed in i_len. The data is referenced in i_data. If i_len - * is zero then any previously configured IE data is removed. At - * most IEEE80211_MAX_APPIE data be appened. Note that multiple - * IE's can be supplied; the data is treated opaquely. - */ -#define IEEE80211_MAX_APPIE 1024 /* max app IE data */ -/* - * Hack: the WPA authenticator uses this mechanism to specify WPA - * ie's that are used instead of the ones normally constructed using - * the cipher state setup with separate ioctls. This avoids issues - * like the authenticator ordering ie data differently than the - * net80211 layer and needing to keep separate state for WPA and RSN. - */ -#define IEEE80211_APPIE_WPA \ - (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON | \ - IEEE80211_FC0_SUBTYPE_PROBE_RESP) - -/* - * Station mode roaming parameters. These are maintained - * per band/mode and control the roaming algorithm. - */ -struct ieee80211_roamparams_req { - struct ieee80211_roamparam params[IEEE80211_MODE_MAX]; -}; - -/* - * Transmit parameters. These can be used to set fixed transmit - * rate for each operating mode when operating as client or on a - * per-client basis according to the capabilities of the client - * (e.g. an 11b client associated to an 11g ap) when operating as - * an ap. - * - * MCS are distinguished from legacy rates by or'ing in 0x80. - */ -struct ieee80211_txparams_req { - struct ieee80211_txparam params[IEEE80211_MODE_MAX]; -}; - -/* - * Set regulatory domain state with IEEE80211_IOC_REGDOMAIN. - * Note this is both the regulatory description and the channel - * list. The get request for IEEE80211_IOC_REGDOMAIN returns - * only the regdomain info; the channel list is obtained - * separately with IEEE80211_IOC_CHANINFO. - */ -struct ieee80211_regdomain_req { - struct ieee80211_regdomain rd; - struct ieee80211req_chaninfo chaninfo; -}; -#define IEEE80211_REGDOMAIN_SIZE(_nchan) \ - (sizeof(struct ieee80211_regdomain_req) + \ - (((_nchan)-1) * sizeof(struct ieee80211_channel))) -#define IEEE80211_REGDOMAIN_SPACE(_req) \ - IEEE80211_REGDOMAIN_SIZE((_req)->chaninfo.ic_nchans) - -/* - * Get driver capabilities. Driver, hardware crypto, and - * HT/802.11n capabilities, and a table that describes what - * the radio can do. - */ -struct ieee80211_devcaps_req { - uint32_t dc_drivercaps; /* general driver caps */ - uint32_t dc_cryptocaps; /* hardware crypto support */ - uint32_t dc_htcaps; /* HT/802.11n support */ - struct ieee80211req_chaninfo dc_chaninfo; -}; -#define IEEE80211_DEVCAPS_SIZE(_nchan) \ - (sizeof(struct ieee80211_devcaps_req) + \ - (((_nchan)-1) * sizeof(struct ieee80211_channel))) -#define IEEE80211_DEVCAPS_SPACE(_dc) \ - IEEE80211_DEVCAPS_SIZE((_dc)->dc_chaninfo.ic_nchans) - -struct ieee80211_chanswitch_req { - struct ieee80211_channel csa_chan; /* new channel */ - int csa_mode; /* CSA mode */ - int csa_count; /* beacon count to switch */ -}; - -/* - * Get/set per-station vlan tag. - */ -struct ieee80211req_sta_vlan { - uint8_t sv_macaddr[IEEE80211_ADDR_LEN]; - uint16_t sv_vlan; -}; - -#if defined(__FreeBSD__) || defined(__HAIKU__) -/* - * FreeBSD-style ioctls. - */ -/* the first member must be matched with struct ifreq */ -struct ieee80211req { - char i_name[IFNAMSIZ]; /* if_name, e.g. "wi0" */ - uint16_t i_type; /* req type */ - int16_t i_val; /* Index or simple value */ - uint16_t i_len; /* Index or simple value */ - void *i_data; /* Extra data */ -}; -#define SIOCS80211 _IOW('i', 234, struct ieee80211req) -#define SIOCG80211 _IOWR('i', 235, struct ieee80211req) -#define SIOCG80211STATS _IOWR('i', 236, struct ifreq) - -#define IEEE80211_IOC_SSID 1 -#define IEEE80211_IOC_NUMSSIDS 2 -#define IEEE80211_IOC_WEP 3 -#define IEEE80211_WEP_NOSUP -1 -#define IEEE80211_WEP_OFF 0 -#define IEEE80211_WEP_ON 1 -#define IEEE80211_WEP_MIXED 2 -#define IEEE80211_IOC_WEPKEY 4 -#define IEEE80211_IOC_NUMWEPKEYS 5 -#define IEEE80211_IOC_WEPTXKEY 6 -#define IEEE80211_IOC_AUTHMODE 7 -#define IEEE80211_IOC_STATIONNAME 8 -#define IEEE80211_IOC_CHANNEL 9 -#define IEEE80211_IOC_POWERSAVE 10 -#define IEEE80211_POWERSAVE_NOSUP -1 -#define IEEE80211_POWERSAVE_OFF 0 -#define IEEE80211_POWERSAVE_CAM 1 -#define IEEE80211_POWERSAVE_PSP 2 -#define IEEE80211_POWERSAVE_PSP_CAM 3 -#define IEEE80211_POWERSAVE_ON IEEE80211_POWERSAVE_CAM -#define IEEE80211_IOC_POWERSAVESLEEP 11 -#define IEEE80211_IOC_RTSTHRESHOLD 12 -#define IEEE80211_IOC_PROTMODE 13 -#define IEEE80211_PROTMODE_OFF 0 -#define IEEE80211_PROTMODE_CTS 1 -#define IEEE80211_PROTMODE_RTSCTS 2 -#define IEEE80211_IOC_TXPOWER 14 /* global tx power limit */ -#define IEEE80211_IOC_BSSID 15 -#define IEEE80211_IOC_ROAMING 16 /* roaming mode */ -#define IEEE80211_IOC_PRIVACY 17 /* privacy invoked */ -#define IEEE80211_IOC_DROPUNENCRYPTED 18 /* discard unencrypted frames */ -#define IEEE80211_IOC_WPAKEY 19 -#define IEEE80211_IOC_DELKEY 20 -#define IEEE80211_IOC_MLME 21 -/* 22 was IEEE80211_IOC_OPTIE, replaced by IEEE80211_IOC_APPIE */ -/* 23 was IEEE80211_IOC_SCAN_REQ */ -/* 24 was IEEE80211_IOC_SCAN_RESULTS */ -#define IEEE80211_IOC_COUNTERMEASURES 25 /* WPA/TKIP countermeasures */ -#define IEEE80211_IOC_WPA 26 /* WPA mode (0,1,2) */ -#define IEEE80211_IOC_CHANLIST 27 /* channel list */ -#define IEEE80211_IOC_WME 28 /* WME mode (on, off) */ -#define IEEE80211_IOC_HIDESSID 29 /* hide SSID mode (on, off) */ -#define IEEE80211_IOC_APBRIDGE 30 /* AP inter-sta bridging */ -/* 31-35,37-38 were for WPA authenticator settings */ -/* 36 was IEEE80211_IOC_DRIVER_CAPS */ -#define IEEE80211_IOC_WPAIE 39 /* WPA information element */ -#define IEEE80211_IOC_STA_STATS 40 /* per-station statistics */ -#define IEEE80211_IOC_MACCMD 41 /* MAC ACL operation */ -#define IEEE80211_IOC_CHANINFO 42 /* channel info list */ -#define IEEE80211_IOC_TXPOWMAX 43 /* max tx power for channel */ -#define IEEE80211_IOC_STA_TXPOW 44 /* per-station tx power limit */ -/* 45 was IEEE80211_IOC_STA_INFO */ -#define IEEE80211_IOC_WME_CWMIN 46 /* WME: ECWmin */ -#define IEEE80211_IOC_WME_CWMAX 47 /* WME: ECWmax */ -#define IEEE80211_IOC_WME_AIFS 48 /* WME: AIFSN */ -#define IEEE80211_IOC_WME_TXOPLIMIT 49 /* WME: txops limit */ -#define IEEE80211_IOC_WME_ACM 50 /* WME: ACM (bss only) */ -#define IEEE80211_IOC_WME_ACKPOLICY 51 /* WME: ACK policy (!bss only)*/ -#define IEEE80211_IOC_DTIM_PERIOD 52 /* DTIM period (beacons) */ -#define IEEE80211_IOC_BEACON_INTERVAL 53 /* beacon interval (ms) */ -#define IEEE80211_IOC_ADDMAC 54 /* add sta to MAC ACL table */ -#define IEEE80211_IOC_DELMAC 55 /* del sta from MAC ACL table */ -#define IEEE80211_IOC_PUREG 56 /* pure 11g (no 11b stations) */ -#define IEEE80211_IOC_FF 57 /* ATH fast frames (on, off) */ -#define IEEE80211_IOC_TURBOP 58 /* ATH turbo' (on, off) */ -#define IEEE80211_IOC_BGSCAN 59 /* bg scanning (on, off) */ -#define IEEE80211_IOC_BGSCAN_IDLE 60 /* bg scan idle threshold */ -#define IEEE80211_IOC_BGSCAN_INTERVAL 61 /* bg scan interval */ -#define IEEE80211_IOC_SCANVALID 65 /* scan cache valid threshold */ -/* 66-72 were IEEE80211_IOC_ROAM_* and IEEE80211_IOC_MCAST_RATE */ -#define IEEE80211_IOC_FRAGTHRESHOLD 73 /* tx fragmentation threshold */ -#define IEEE80211_IOC_BURST 75 /* packet bursting */ -#define IEEE80211_IOC_SCAN_RESULTS 76 /* get scan results */ -#define IEEE80211_IOC_BMISSTHRESHOLD 77 /* beacon miss threshold */ -#define IEEE80211_IOC_STA_INFO 78 /* station/neighbor info */ -#define IEEE80211_IOC_WPAIE2 79 /* WPA+RSN info elements */ -#define IEEE80211_IOC_CURCHAN 80 /* current channel */ -#define IEEE80211_IOC_SHORTGI 81 /* 802.11n half GI */ -#define IEEE80211_IOC_AMPDU 82 /* 802.11n A-MPDU (on, off) */ -#define IEEE80211_IOC_AMPDU_LIMIT 83 /* A-MPDU length limit */ -#define IEEE80211_IOC_AMPDU_DENSITY 84 /* A-MPDU density */ -#define IEEE80211_IOC_AMSDU 85 /* 802.11n A-MSDU (on, off) */ -#define IEEE80211_IOC_AMSDU_LIMIT 86 /* A-MSDU length limit */ -#define IEEE80211_IOC_PUREN 87 /* pure 11n (no legacy sta's) */ -#define IEEE80211_IOC_DOTH 88 /* 802.11h (on, off) */ -/* 89-91 were regulatory items */ -#define IEEE80211_IOC_HTCOMPAT 92 /* support pre-D1.10 HT ie's */ -#define IEEE80211_IOC_DWDS 93 /* DWDS/4-address handling */ -#define IEEE80211_IOC_INACTIVITY 94 /* sta inactivity handling */ -#define IEEE80211_IOC_APPIE 95 /* application IE's */ -#define IEEE80211_IOC_WPS 96 /* WPS operation */ -#define IEEE80211_IOC_TSN 97 /* TSN operation */ -#define IEEE80211_IOC_DEVCAPS 98 /* driver+device capabilities */ -#define IEEE80211_IOC_CHANSWITCH 99 /* start 11h channel switch */ -#define IEEE80211_IOC_DFS 100 /* DFS (on, off) */ -#define IEEE80211_IOC_DOTD 101 /* 802.11d (on, off) */ -#define IEEE80211_IOC_HTPROTMODE 102 /* HT protection (off, rts) */ -#define IEEE80211_IOC_SCAN_REQ 103 /* scan w/ specified params */ -#define IEEE80211_IOC_SCAN_CANCEL 104 /* cancel ongoing scan */ -#define IEEE80211_IOC_HTCONF 105 /* HT config (off, HT20, HT40)*/ -#define IEEE80211_IOC_REGDOMAIN 106 /* regulatory domain info */ -#define IEEE80211_IOC_ROAM 107 /* roaming params en masse */ -#define IEEE80211_IOC_TXPARAMS 108 /* tx parameters */ -#define IEEE80211_IOC_STA_VLAN 109 /* per-station vlan tag */ -#define IEEE80211_IOC_SMPS 110 /* MIMO power save */ -#define IEEE80211_IOC_RIFS 111 /* RIFS config (on, off) */ -#define IEEE80211_IOC_GREENFIELD 112 /* Greenfield (on, off) */ -#define IEEE80211_IOC_STBC 113 /* STBC Tx/RX (on, off) */ - -#define IEEE80211_IOC_MESH_ID 170 /* mesh identifier */ -#define IEEE80211_IOC_MESH_AP 171 /* accepting peerings */ -#define IEEE80211_IOC_MESH_FWRD 172 /* forward frames */ -#define IEEE80211_IOC_MESH_PROTO 173 /* mesh protocols */ -#define IEEE80211_IOC_MESH_TTL 174 /* mesh TTL */ -#define IEEE80211_IOC_MESH_RTCMD 175 /* mesh routing table commands*/ -#define IEEE80211_IOC_MESH_PR_METRIC 176 /* mesh metric protocol */ -#define IEEE80211_IOC_MESH_PR_PATH 177 /* mesh path protocol */ -#define IEEE80211_IOC_MESH_PR_SIG 178 /* mesh sig protocol */ -#define IEEE80211_IOC_MESH_PR_CC 179 /* mesh congestion protocol */ -#define IEEE80211_IOC_MESH_PR_AUTH 180 /* mesh auth protocol */ - -#define IEEE80211_IOC_HWMP_ROOTMODE 190 /* HWMP root mode */ -#define IEEE80211_IOC_HWMP_MAXHOPS 191 /* number of hops before drop */ -#define IEEE80211_IOC_HWMP_TTL 192 /* HWMP TTL */ - -#define IEEE80211_IOC_TDMA_SLOT 201 /* TDMA: assigned slot */ -#define IEEE80211_IOC_TDMA_SLOTCNT 202 /* TDMA: slots in bss */ -#define IEEE80211_IOC_TDMA_SLOTLEN 203 /* TDMA: slot length (usecs) */ -#define IEEE80211_IOC_TDMA_BINTERVAL 204 /* TDMA: beacon intvl (slots) */ - -#ifdef __HAIKU__ -/* - These are here to allow overcoming a difference between Haiku and - FreeBSD drivers. In FreeBSD a device can be set into the down state - but is still fully configurable using the ioctl interface. The Haiku - network stack on the other hand opens and closes the driver on the - transition form up to down and vice versa. This difference can become - problematic with ported software that depends on the original behaviour. - Therefore IEEE80211_IOC_HAIKU_COMPAT_WLAN_{UP|DOWN} provide a way to - achieve the behaviour of setting and clearing IFF_UP without opening - or closing the driver itself. -*/ -#define IEEE80211_IOC_HAIKU_COMPAT_WLAN_UP 0x6000 -#define IEEE80211_IOC_HAIKU_COMPAT_WLAN_DOWN 0x6001 -#endif /* __HAIKU__ */ - -/* - * Parameters for controlling a scan requested with - * IEEE80211_IOC_SCAN_REQ. - * - * Active scans cause ProbeRequest frames to be issued for each - * specified ssid and, by default, a broadcast ProbeRequest frame. - * The set of ssid's is specified in the request. - * - * By default the scan will cause a BSS to be joined (in station/adhoc - * mode) or a channel to be selected for operation (hostap mode). - * To disable that specify IEEE80211_IOC_SCAN_NOPICK and if the - * - * If the station is currently associated to an AP then a scan request - * will cause the station to leave the current channel and potentially - * miss frames from the AP. Alternatively the station may notify the - * AP that it is going into power save mode before it leaves the channel. - * This ensures frames for the station are buffered by the AP. This is - * termed a ``bg scan'' and is requested with the IEEE80211_IOC_SCAN_BGSCAN - * flag. Background scans may take longer than foreground scans and may - * be preempted by traffic. If a station is not associated to an AP - * then a request for a background scan is automatically done in the - * foreground. - * - * The results of the scan request are cached by the system. This - * information is aged out and/or invalidated based on events like not - * being able to associated to an AP. To flush the current cache - * contents before doing a scan the IEEE80211_IOC_SCAN_FLUSH flag may - * be specified. - * - * By default the scan will be done until a suitable AP is located - * or a channel is found for use. A scan can also be constrained - * to be done once (IEEE80211_IOC_SCAN_ONCE) or to last for no more - * than a specified duration. - */ -struct ieee80211_scan_req { - int sr_flags; -#define IEEE80211_IOC_SCAN_NOPICK 0x00001 /* scan only, no selection */ -#define IEEE80211_IOC_SCAN_ACTIVE 0x00002 /* active scan (probe req) */ -#define IEEE80211_IOC_SCAN_PICK1ST 0x00004 /* ``hey sailor'' mode */ -#define IEEE80211_IOC_SCAN_BGSCAN 0x00008 /* bg scan, exit ps at end */ -#define IEEE80211_IOC_SCAN_ONCE 0x00010 /* do one complete pass */ -#define IEEE80211_IOC_SCAN_NOBCAST 0x00020 /* don't send bcast probe req */ -#define IEEE80211_IOC_SCAN_NOJOIN 0x00040 /* no auto-sequencing */ -#define IEEE80211_IOC_SCAN_FLUSH 0x10000 /* flush scan cache first */ -#define IEEE80211_IOC_SCAN_CHECK 0x20000 /* check scan cache first */ - u_int sr_duration; /* duration (ms) */ -#define IEEE80211_IOC_SCAN_DURATION_MIN 1 -#define IEEE80211_IOC_SCAN_DURATION_MAX 0x7fffffff -#define IEEE80211_IOC_SCAN_FOREVER IEEE80211_IOC_SCAN_DURATION_MAX - u_int sr_mindwell; /* min channel dwelltime (ms) */ - u_int sr_maxdwell; /* max channel dwelltime (ms) */ - int sr_nssid; -#define IEEE80211_IOC_SCAN_MAX_SSID 3 - struct { - int len; /* length in bytes */ - uint8_t ssid[IEEE80211_NWID_LEN]; /* ssid contents */ - } sr_ssid[IEEE80211_IOC_SCAN_MAX_SSID]; -}; - -/* - * Scan result data returned for IEEE80211_IOC_SCAN_RESULTS. - * Each result is a fixed size structure followed by a variable - * length SSID and one or more variable length information elements. - * The size of each variable length item is found in the fixed - * size structure and the entire length of the record is specified - * in isr_len. Result records are rounded to a multiple of 4 bytes. - */ -struct ieee80211req_scan_result { - uint16_t isr_len; /* total length (mult of 4) */ - uint16_t isr_ie_off; /* offset to SSID+IE data */ - uint16_t isr_ie_len; /* IE length */ -#ifdef __HAIKU__ - struct ieee80211_channel isr_chan; /* Handing out the conmplete channel info */ -#else - uint16_t isr_freq; /* MHz */ - uint16_t isr_flags; /* channel flags */ -#endif - int8_t isr_noise; - int8_t isr_rssi; - uint16_t isr_intval; /* beacon interval */ - uint8_t isr_capinfo; /* capabilities */ - uint8_t isr_erp; /* ERP element */ - uint8_t isr_bssid[IEEE80211_ADDR_LEN]; - uint8_t isr_nrates; - uint8_t isr_rates[IEEE80211_RATE_MAXSIZE]; - uint8_t isr_ssid_len; /* SSID length */ - uint8_t isr_meshid_len; /* MESH ID length */ - /* variable length SSID, followed by variable length MESH ID, - followed by IE data */ -}; - -/* - * Virtual AP cloning parameters. The parent device must - * be a vap-capable device. All parameters specified with - * the clone request are fixed for the lifetime of the vap. - * - * There are two flavors of WDS vaps: legacy and dynamic. - * Legacy WDS operation implements a static binding between - * two stations encapsulating traffic in 4-address frames. - * Dynamic WDS vaps are created when a station associates to - * an AP and sends a 4-address frame. If the AP vap is - * configured to support WDS then this will generate an - * event to user programs listening on the routing socket - * and a Dynamic WDS vap will be created to handle traffic - * to/from that station. In both cases the bssid of the - * peer must be specified when creating the vap. - * - * By default a vap will inherit the mac address/bssid of - * the underlying device. To request a unique address the - * IEEE80211_CLONE_BSSID flag should be supplied. This is - * meaningless for WDS vaps as they share the bssid of an - * AP vap that must otherwise exist. Note that some devices - * may not be able to support multiple addresses. - * - * Station mode vap's normally depend on the device to notice - * when the AP stops sending beacon frames. If IEEE80211_CLONE_NOBEACONS - * is specified the net80211 layer will do this in s/w. This - * is mostly useful when setting up a WDS repeater/extender where - * an AP vap is combined with a sta vap and the device isn't able - * to track beacon frames in hardware. - */ -struct ieee80211_clone_params { - char icp_parent[IFNAMSIZ]; /* parent device */ - uint16_t icp_opmode; /* operating mode */ - uint16_t icp_flags; /* see below */ - uint8_t icp_bssid[IEEE80211_ADDR_LEN]; /* for WDS links */ - uint8_t icp_macaddr[IEEE80211_ADDR_LEN];/* local address */ -}; -#define IEEE80211_CLONE_BSSID 0x0001 /* allocate unique mac/bssid */ -#define IEEE80211_CLONE_NOBEACONS 0x0002 /* don't setup beacon timers */ -#define IEEE80211_CLONE_WDSLEGACY 0x0004 /* legacy WDS processing */ -#define IEEE80211_CLONE_MACADDR 0x0008 /* use specified mac addr */ -#define IEEE80211_CLONE_TDMA 0x0010 /* operate in TDMA mode */ -#endif /* __FreeBSD__ */ - -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_IOCTL_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_mesh.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_mesh.c deleted file mode 100644 index 571a733539..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_mesh.c +++ /dev/null @@ -1,2765 +0,0 @@ -/*- - * Copyright (c) 2009 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Rui Paulo under sponsorship from the - * FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#include -#ifdef __FreeBSD__ -__FBSDID("$FreeBSD$"); -#endif - -/* - * IEEE 802.11s Mesh Point (MBSS) support. - * - * Based on March 2009, D3.0 802.11s draft spec. - */ -#include "opt_inet.h" -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -static void mesh_rt_flush_invalid(struct ieee80211vap *); -static int mesh_select_proto_path(struct ieee80211vap *, const char *); -static int mesh_select_proto_metric(struct ieee80211vap *, const char *); -static void mesh_vattach(struct ieee80211vap *); -static int mesh_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static void mesh_rt_cleanup_cb(void *); -static void mesh_linkchange(struct ieee80211_node *, - enum ieee80211_mesh_mlstate); -static void mesh_checkid(void *, struct ieee80211_node *); -static uint32_t mesh_generateid(struct ieee80211vap *); -static int mesh_checkpseq(struct ieee80211vap *, - const uint8_t [IEEE80211_ADDR_LEN], uint32_t); -static struct ieee80211_node * - mesh_find_txnode(struct ieee80211vap *, - const uint8_t [IEEE80211_ADDR_LEN]); -static void mesh_forward(struct ieee80211vap *, struct mbuf *, - const struct ieee80211_meshcntl *); -static int mesh_input(struct ieee80211_node *, struct mbuf *, int, int); -static void mesh_recv_mgmt(struct ieee80211_node *, struct mbuf *, int, - int, int); -static void mesh_recv_ctl(struct ieee80211_node *, struct mbuf *, int); -static void mesh_peer_timeout_setup(struct ieee80211_node *); -static void mesh_peer_timeout_backoff(struct ieee80211_node *); -static void mesh_peer_timeout_cb(void *); -static __inline void - mesh_peer_timeout_stop(struct ieee80211_node *); -static int mesh_verify_meshid(struct ieee80211vap *, const uint8_t *); -static int mesh_verify_meshconf(struct ieee80211vap *, const uint8_t *); -static int mesh_verify_meshpeer(struct ieee80211vap *, uint8_t, - const uint8_t *); -uint32_t mesh_airtime_calc(struct ieee80211_node *); - -/* - * Timeout values come from the specification and are in milliseconds. - */ -SYSCTL_NODE(_net_wlan, OID_AUTO, mesh, CTLFLAG_RD, 0, - "IEEE 802.11s parameters"); -static int ieee80211_mesh_retrytimeout = -1; -SYSCTL_PROC(_net_wlan_mesh, OID_AUTO, retrytimeout, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_mesh_retrytimeout, 0, ieee80211_sysctl_msecs_ticks, "I", - "Retry timeout (msec)"); -static int ieee80211_mesh_holdingtimeout = -1; -SYSCTL_PROC(_net_wlan_mesh, OID_AUTO, holdingtimeout, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_mesh_holdingtimeout, 0, ieee80211_sysctl_msecs_ticks, "I", - "Holding state timeout (msec)"); -static int ieee80211_mesh_confirmtimeout = -1; -SYSCTL_PROC(_net_wlan_mesh, OID_AUTO, confirmtimeout, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_mesh_confirmtimeout, 0, ieee80211_sysctl_msecs_ticks, "I", - "Confirm state timeout (msec)"); -static int ieee80211_mesh_maxretries = 2; -SYSCTL_INT(_net_wlan_mesh, OID_AUTO, maxretries, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_mesh_maxretries, 0, - "Maximum retries during peer link establishment"); - -static const uint8_t broadcastaddr[IEEE80211_ADDR_LEN] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - -static ieee80211_recv_action_func mesh_recv_action_meshpeering_open; -static ieee80211_recv_action_func mesh_recv_action_meshpeering_confirm; -static ieee80211_recv_action_func mesh_recv_action_meshpeering_close; -static ieee80211_recv_action_func mesh_recv_action_meshlmetric_req; -static ieee80211_recv_action_func mesh_recv_action_meshlmetric_rep; - -static ieee80211_send_action_func mesh_send_action_meshpeering_open; -static ieee80211_send_action_func mesh_send_action_meshpeering_confirm; -static ieee80211_send_action_func mesh_send_action_meshpeering_close; -static ieee80211_send_action_func mesh_send_action_meshlink_request; -static ieee80211_send_action_func mesh_send_action_meshlink_reply; - -static const struct ieee80211_mesh_proto_metric mesh_metric_airtime = { - .mpm_descr = "AIRTIME", - .mpm_ie = IEEE80211_MESHCONF_METRIC_AIRTIME, - .mpm_metric = mesh_airtime_calc, -}; - -static struct ieee80211_mesh_proto_path mesh_proto_paths[4]; -static struct ieee80211_mesh_proto_metric mesh_proto_metrics[4]; - -#define MESH_RT_LOCK(ms) mtx_lock(&(ms)->ms_rt_lock) -#define MESH_RT_LOCK_ASSERT(ms) mtx_assert(&(ms)->ms_rt_lock, MA_OWNED) -#define MESH_RT_UNLOCK(ms) mtx_unlock(&(ms)->ms_rt_lock) - -MALLOC_DEFINE(M_80211_MESH_RT, "80211mesh", "802.11s routing table"); - -/* - * Helper functions to manipulate the Mesh routing table. - */ - -static struct ieee80211_mesh_route * -mesh_rt_find_locked(struct ieee80211_mesh_state *ms, - const uint8_t dest[IEEE80211_ADDR_LEN]) -{ - struct ieee80211_mesh_route *rt; - - MESH_RT_LOCK_ASSERT(ms); - - TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) { - if (IEEE80211_ADDR_EQ(dest, rt->rt_dest)) - return rt; - } - return NULL; -} - -static struct ieee80211_mesh_route * -mesh_rt_add_locked(struct ieee80211_mesh_state *ms, - const uint8_t dest[IEEE80211_ADDR_LEN]) -{ - struct ieee80211_mesh_route *rt; - - KASSERT(!IEEE80211_ADDR_EQ(broadcastaddr, dest), - ("%s: adding broadcast to the routing table", __func__)); - - MESH_RT_LOCK_ASSERT(ms); - - rt = malloc(ALIGN(sizeof(struct ieee80211_mesh_route)) + - ms->ms_ppath->mpp_privlen, M_80211_MESH_RT, M_NOWAIT | M_ZERO); - if (rt != NULL) { - IEEE80211_ADDR_COPY(rt->rt_dest, dest); - rt->rt_priv = (void *)ALIGN(&rt[1]); - rt->rt_crtime = ticks; - TAILQ_INSERT_TAIL(&ms->ms_routes, rt, rt_next); - } - return rt; -} - -struct ieee80211_mesh_route * -ieee80211_mesh_rt_find(struct ieee80211vap *vap, - const uint8_t dest[IEEE80211_ADDR_LEN]) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_mesh_route *rt; - - MESH_RT_LOCK(ms); - rt = mesh_rt_find_locked(ms, dest); - MESH_RT_UNLOCK(ms); - return rt; -} - -struct ieee80211_mesh_route * -ieee80211_mesh_rt_add(struct ieee80211vap *vap, - const uint8_t dest[IEEE80211_ADDR_LEN]) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_mesh_route *rt; - - KASSERT(ieee80211_mesh_rt_find(vap, dest) == NULL, - ("%s: duplicate entry in the routing table", __func__)); - KASSERT(!IEEE80211_ADDR_EQ(vap->iv_myaddr, dest), - ("%s: adding self to the routing table", __func__)); - - MESH_RT_LOCK(ms); - rt = mesh_rt_add_locked(ms, dest); - MESH_RT_UNLOCK(ms); - return rt; -} - -/* - * Add a proxy route (as needed) for the specified destination. - */ -void -ieee80211_mesh_proxy_check(struct ieee80211vap *vap, - const uint8_t dest[IEEE80211_ADDR_LEN]) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_mesh_route *rt; - - MESH_RT_LOCK(ms); - rt = mesh_rt_find_locked(ms, dest); - if (rt == NULL) { - rt = mesh_rt_add_locked(ms, dest); - if (rt == NULL) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, dest, - "%s", "unable to add proxy entry"); - vap->iv_stats.is_mesh_rtaddfailed++; - } else { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, dest, - "%s", "add proxy entry"); - IEEE80211_ADDR_COPY(rt->rt_nexthop, vap->iv_myaddr); - rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID - | IEEE80211_MESHRT_FLAGS_PROXY; - } - /* XXX assert PROXY? */ - } else if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) { - struct ieee80211com *ic = vap->iv_ic; - /* - * Fix existing entry created by received frames from - * stations that have some memory of dest. We also - * flush any frames held on the staging queue; delivering - * them is too much trouble right now. - */ - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, dest, - "%s", "fix proxy entry"); - IEEE80211_ADDR_COPY(rt->rt_nexthop, vap->iv_myaddr); - rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID - | IEEE80211_MESHRT_FLAGS_PROXY; - /* XXX belongs in hwmp */ - ieee80211_ageq_drain_node(&ic->ic_stageq, - (void *)(uintptr_t) ieee80211_mac_hash(ic, dest)); - /* XXX stat? */ - } - MESH_RT_UNLOCK(ms); -} - -static __inline void -mesh_rt_del(struct ieee80211_mesh_state *ms, struct ieee80211_mesh_route *rt) -{ - TAILQ_REMOVE(&ms->ms_routes, rt, rt_next); - free(rt, M_80211_MESH_RT); -} - -void -ieee80211_mesh_rt_del(struct ieee80211vap *vap, - const uint8_t dest[IEEE80211_ADDR_LEN]) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_mesh_route *rt, *next; - - MESH_RT_LOCK(ms); - TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) { - if (IEEE80211_ADDR_EQ(rt->rt_dest, dest)) { - mesh_rt_del(ms, rt); - MESH_RT_UNLOCK(ms); - return; - } - } - MESH_RT_UNLOCK(ms); -} - -void -ieee80211_mesh_rt_flush(struct ieee80211vap *vap) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_mesh_route *rt, *next; - - if (ms == NULL) - return; - MESH_RT_LOCK(ms); - TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) - mesh_rt_del(ms, rt); - MESH_RT_UNLOCK(ms); -} - -void -ieee80211_mesh_rt_flush_peer(struct ieee80211vap *vap, - const uint8_t peer[IEEE80211_ADDR_LEN]) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_mesh_route *rt, *next; - - MESH_RT_LOCK(ms); - TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) { - if (IEEE80211_ADDR_EQ(rt->rt_nexthop, peer)) - mesh_rt_del(ms, rt); - } - MESH_RT_UNLOCK(ms); -} - -/* - * Flush expired routing entries, i.e. those in invalid state for - * some time. - */ -static void -mesh_rt_flush_invalid(struct ieee80211vap *vap) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_mesh_route *rt, *next; - - if (ms == NULL) - return; - MESH_RT_LOCK(ms); - TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) { - if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0 && - ticks - rt->rt_crtime >= ms->ms_ppath->mpp_inact) - mesh_rt_del(ms, rt); - } - MESH_RT_UNLOCK(ms); -} - -#define N(a) (sizeof(a) / sizeof(a[0])) -int -ieee80211_mesh_register_proto_path(const struct ieee80211_mesh_proto_path *mpp) -{ - int i, firstempty = -1; - - for (i = 0; i < N(mesh_proto_paths); i++) { - if (strncmp(mpp->mpp_descr, mesh_proto_paths[i].mpp_descr, - IEEE80211_MESH_PROTO_DSZ) == 0) - return EEXIST; - if (!mesh_proto_paths[i].mpp_active && firstempty == -1) - firstempty = i; - } - if (firstempty < 0) - return ENOSPC; - memcpy(&mesh_proto_paths[firstempty], mpp, sizeof(*mpp)); - mesh_proto_paths[firstempty].mpp_active = 1; - return 0; -} - -int -ieee80211_mesh_register_proto_metric(const struct - ieee80211_mesh_proto_metric *mpm) -{ - int i, firstempty = -1; - - for (i = 0; i < N(mesh_proto_metrics); i++) { - if (strncmp(mpm->mpm_descr, mesh_proto_metrics[i].mpm_descr, - IEEE80211_MESH_PROTO_DSZ) == 0) - return EEXIST; - if (!mesh_proto_metrics[i].mpm_active && firstempty == -1) - firstempty = i; - } - if (firstempty < 0) - return ENOSPC; - memcpy(&mesh_proto_metrics[firstempty], mpm, sizeof(*mpm)); - mesh_proto_metrics[firstempty].mpm_active = 1; - return 0; -} - -static int -mesh_select_proto_path(struct ieee80211vap *vap, const char *name) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - int i; - - for (i = 0; i < N(mesh_proto_paths); i++) { - if (strcasecmp(mesh_proto_paths[i].mpp_descr, name) == 0) { - ms->ms_ppath = &mesh_proto_paths[i]; - return 0; - } - } - return ENOENT; -} - -static int -mesh_select_proto_metric(struct ieee80211vap *vap, const char *name) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - int i; - - for (i = 0; i < N(mesh_proto_metrics); i++) { - if (strcasecmp(mesh_proto_metrics[i].mpm_descr, name) == 0) { - ms->ms_pmetric = &mesh_proto_metrics[i]; - return 0; - } - } - return ENOENT; -} -#undef N - -static void -ieee80211_mesh_init(void) -{ - - memset(mesh_proto_paths, 0, sizeof(mesh_proto_paths)); - memset(mesh_proto_metrics, 0, sizeof(mesh_proto_metrics)); - - /* - * Setup mesh parameters that depends on the clock frequency. - */ - ieee80211_mesh_retrytimeout = msecs_to_ticks(40); - ieee80211_mesh_holdingtimeout = msecs_to_ticks(40); - ieee80211_mesh_confirmtimeout = msecs_to_ticks(40); - - /* - * Register action frame handlers. - */ - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_OPEN, - mesh_recv_action_meshpeering_open); - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CONFIRM, - mesh_recv_action_meshpeering_confirm); - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, - mesh_recv_action_meshpeering_close); - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC, - IEEE80211_ACTION_MESHLMETRIC_REQ, mesh_recv_action_meshlmetric_req); - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC, - IEEE80211_ACTION_MESHLMETRIC_REP, mesh_recv_action_meshlmetric_rep); - - ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_OPEN, - mesh_send_action_meshpeering_open); - ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CONFIRM, - mesh_send_action_meshpeering_confirm); - ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, - mesh_send_action_meshpeering_close); - ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC, - IEEE80211_ACTION_MESHLMETRIC_REQ, - mesh_send_action_meshlink_request); - ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC, - IEEE80211_ACTION_MESHLMETRIC_REP, - mesh_send_action_meshlink_reply); - - /* - * Register Airtime Link Metric. - */ - ieee80211_mesh_register_proto_metric(&mesh_metric_airtime); - -} -SYSINIT(wlan_mesh, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_mesh_init, NULL); - -void -ieee80211_mesh_attach(struct ieee80211com *ic) -{ - ic->ic_vattach[IEEE80211_M_MBSS] = mesh_vattach; -} - -void -ieee80211_mesh_detach(struct ieee80211com *ic) -{ -} - -static void -mesh_vdetach_peers(void *arg, struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - uint16_t args[3]; - - if (ni->ni_mlstate == IEEE80211_NODE_MESH_ESTABLISHED) { - args[0] = ni->ni_mlpid; - args[1] = ni->ni_mllid; - args[2] = IEEE80211_REASON_PEER_LINK_CANCELED; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, - args); - } - callout_drain(&ni->ni_mltimer); - /* XXX belongs in hwmp */ - ieee80211_ageq_drain_node(&ic->ic_stageq, - (void *)(uintptr_t) ieee80211_mac_hash(ic, ni->ni_macaddr)); -} - -static void -mesh_vdetach(struct ieee80211vap *vap) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - - callout_drain(&ms->ms_cleantimer); - ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, mesh_vdetach_peers, - NULL); - ieee80211_mesh_rt_flush(vap); - mtx_destroy(&ms->ms_rt_lock); - ms->ms_ppath->mpp_vdetach(vap); - free(vap->iv_mesh, M_80211_VAP); - vap->iv_mesh = NULL; -} - -static void -mesh_vattach(struct ieee80211vap *vap) -{ - struct ieee80211_mesh_state *ms; - vap->iv_newstate = mesh_newstate; - vap->iv_input = mesh_input; - vap->iv_opdetach = mesh_vdetach; - vap->iv_recv_mgmt = mesh_recv_mgmt; - vap->iv_recv_ctl = mesh_recv_ctl; - ms = malloc(sizeof(struct ieee80211_mesh_state), M_80211_VAP, - M_NOWAIT | M_ZERO); - if (ms == NULL) { - printf("%s: couldn't alloc MBSS state\n", __func__); - return; - } - vap->iv_mesh = ms; - ms->ms_seq = 0; - ms->ms_flags = (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_FWD); - ms->ms_ttl = IEEE80211_MESH_DEFAULT_TTL; - TAILQ_INIT(&ms->ms_routes); - mtx_init(&ms->ms_rt_lock, "MBSS", "802.11s routing table", MTX_DEF); - callout_init(&ms->ms_cleantimer, CALLOUT_MPSAFE); - mesh_select_proto_metric(vap, "AIRTIME"); - KASSERT(ms->ms_pmetric, ("ms_pmetric == NULL")); - mesh_select_proto_path(vap, "HWMP"); - KASSERT(ms->ms_ppath, ("ms_ppath == NULL")); - ms->ms_ppath->mpp_vattach(vap); -} - -/* - * IEEE80211_M_MBSS vap state machine handler. - */ -static int -mesh_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni; - enum ieee80211_state ostate; - - IEEE80211_LOCK_ASSERT(ic); - - ostate = vap->iv_state; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n", - __func__, ieee80211_state_name[ostate], - ieee80211_state_name[nstate], arg); - vap->iv_state = nstate; /* state transition */ - if (ostate != IEEE80211_S_SCAN) - ieee80211_cancel_scan(vap); /* background scan */ - ni = vap->iv_bss; /* NB: no reference held */ - if (nstate != IEEE80211_S_RUN && ostate == IEEE80211_S_RUN) - callout_drain(&ms->ms_cleantimer); - switch (nstate) { - case IEEE80211_S_INIT: - switch (ostate) { - case IEEE80211_S_SCAN: - ieee80211_cancel_scan(vap); - break; - case IEEE80211_S_CAC: - ieee80211_dfs_cac_stop(vap); - break; - case IEEE80211_S_RUN: - ieee80211_iterate_nodes(&ic->ic_sta, - mesh_vdetach_peers, NULL); - break; - default: - break; - } - if (ostate != IEEE80211_S_INIT) { - /* NB: optimize INIT -> INIT case */ - ieee80211_reset_bss(vap); - ieee80211_mesh_rt_flush(vap); - } - break; - case IEEE80211_S_SCAN: - switch (ostate) { - case IEEE80211_S_INIT: - if (vap->iv_des_chan != IEEE80211_CHAN_ANYC && - !IEEE80211_IS_CHAN_RADAR(vap->iv_des_chan) && - ms->ms_idlen != 0) { - /* - * Already have a channel and a mesh ID; bypass - * the scan and startup immediately. - */ - ieee80211_create_ibss(vap, vap->iv_des_chan); - break; - } - /* - * Initiate a scan. We can come here as a result - * of an IEEE80211_IOC_SCAN_REQ too in which case - * the vap will be marked with IEEE80211_FEXT_SCANREQ - * and the scan request parameters will be present - * in iv_scanreq. Otherwise we do the default. - */ - if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) { - ieee80211_check_scan(vap, - vap->iv_scanreq_flags, - vap->iv_scanreq_duration, - vap->iv_scanreq_mindwell, - vap->iv_scanreq_maxdwell, - vap->iv_scanreq_nssid, vap->iv_scanreq_ssid); - vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; - } else - ieee80211_check_scan_current(vap); - break; - default: - break; - } - break; - case IEEE80211_S_CAC: - /* - * Start CAC on a DFS channel. We come here when starting - * a bss on a DFS channel (see ieee80211_create_ibss). - */ - ieee80211_dfs_cac_start(vap); - break; - case IEEE80211_S_RUN: - switch (ostate) { - case IEEE80211_S_INIT: - /* - * Already have a channel; bypass the - * scan and startup immediately. - * Note that ieee80211_create_ibss will call - * back to do a RUN->RUN state change. - */ - ieee80211_create_ibss(vap, - ieee80211_ht_adjust_channel(ic, - ic->ic_curchan, vap->iv_flags_ht)); - /* NB: iv_bss is changed on return */ - break; - case IEEE80211_S_CAC: - /* - * NB: This is the normal state change when CAC - * expires and no radar was detected; no need to - * clear the CAC timer as it's already expired. - */ - /* fall thru... */ - case IEEE80211_S_CSA: -#if 0 - /* - * Shorten inactivity timer of associated stations - * to weed out sta's that don't follow a CSA. - */ - ieee80211_iterate_nodes(&ic->ic_sta, sta_csa, vap); -#endif - /* - * Update bss node channel to reflect where - * we landed after CSA. - */ - ieee80211_node_set_chan(vap->iv_bss, - ieee80211_ht_adjust_channel(ic, ic->ic_curchan, - ieee80211_htchanflags(vap->iv_bss->ni_chan))); - /* XXX bypass debug msgs */ - break; - case IEEE80211_S_SCAN: - case IEEE80211_S_RUN: -#ifdef IEEE80211_DEBUG - if (ieee80211_msg_debug(vap)) { - struct ieee80211_node *ni = vap->iv_bss; - ieee80211_note(vap, - "synchronized with %s meshid ", - ether_sprintf(ni->ni_meshid)); - ieee80211_print_essid(ni->ni_meshid, - ni->ni_meshidlen); - /* XXX MCS/HT */ - printf(" channel %d\n", - ieee80211_chan2ieee(ic, ic->ic_curchan)); - } -#endif - break; - default: - break; - } - ieee80211_node_authorize(vap->iv_bss); - callout_reset(&ms->ms_cleantimer, ms->ms_ppath->mpp_inact, - mesh_rt_cleanup_cb, vap); - break; - default: - break; - } - /* NB: ostate not nstate */ - ms->ms_ppath->mpp_newstate(vap, ostate, arg); - return 0; -} - -static void -mesh_rt_cleanup_cb(void *arg) -{ - struct ieee80211vap *vap = arg; - struct ieee80211_mesh_state *ms = vap->iv_mesh; - - mesh_rt_flush_invalid(vap); - callout_reset(&ms->ms_cleantimer, ms->ms_ppath->mpp_inact, - mesh_rt_cleanup_cb, vap); -} - - -/* - * Helper function to note the Mesh Peer Link FSM change. - */ -static void -mesh_linkchange(struct ieee80211_node *ni, enum ieee80211_mesh_mlstate state) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_mesh_state *ms = vap->iv_mesh; -#ifdef IEEE80211_DEBUG - static const char *meshlinkstates[] = { - [IEEE80211_NODE_MESH_IDLE] = "IDLE", - [IEEE80211_NODE_MESH_OPENSNT] = "OPEN SENT", - [IEEE80211_NODE_MESH_OPENRCV] = "OPEN RECEIVED", - [IEEE80211_NODE_MESH_CONFIRMRCV] = "CONFIRM RECEIVED", - [IEEE80211_NODE_MESH_ESTABLISHED] = "ESTABLISHED", - [IEEE80211_NODE_MESH_HOLDING] = "HOLDING" - }; -#endif - IEEE80211_NOTE(vap, IEEE80211_MSG_MESH, - ni, "peer link: %s -> %s", - meshlinkstates[ni->ni_mlstate], meshlinkstates[state]); - - /* track neighbor count */ - if (state == IEEE80211_NODE_MESH_ESTABLISHED && - ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) { - KASSERT(ms->ms_neighbors < 65535, ("neighbor count overflow")); - ms->ms_neighbors++; - ieee80211_beacon_notify(vap, IEEE80211_BEACON_MESHCONF); - } else if (ni->ni_mlstate == IEEE80211_NODE_MESH_ESTABLISHED && - state != IEEE80211_NODE_MESH_ESTABLISHED) { - KASSERT(ms->ms_neighbors > 0, ("neighbor count 0")); - ms->ms_neighbors--; - ieee80211_beacon_notify(vap, IEEE80211_BEACON_MESHCONF); - } - ni->ni_mlstate = state; - switch (state) { - case IEEE80211_NODE_MESH_HOLDING: - ms->ms_ppath->mpp_peerdown(ni); - break; - case IEEE80211_NODE_MESH_ESTABLISHED: - ieee80211_mesh_discover(vap, ni->ni_macaddr, NULL); - break; - default: - break; - } -} - -/* - * Helper function to generate a unique local ID required for mesh - * peer establishment. - */ -static void -mesh_checkid(void *arg, struct ieee80211_node *ni) -{ - uint16_t *r = arg; - - if (*r == ni->ni_mllid) - *(uint16_t *)arg = 0; -} - -static uint32_t -mesh_generateid(struct ieee80211vap *vap) -{ - int maxiter = 4; - uint16_t r; - - do { - get_random_bytes(&r, 2); - ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, mesh_checkid, &r); - maxiter--; - } while (r == 0 && maxiter > 0); - return r; -} - -/* - * Verifies if we already received this packet by checking its - * sequence number. - * Returns 0 if the frame is to be accepted, 1 otherwise. - */ -static int -mesh_checkpseq(struct ieee80211vap *vap, - const uint8_t source[IEEE80211_ADDR_LEN], uint32_t seq) -{ - struct ieee80211_mesh_route *rt; - - rt = ieee80211_mesh_rt_find(vap, source); - if (rt == NULL) { - rt = ieee80211_mesh_rt_add(vap, source); - if (rt == NULL) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, source, - "%s", "add mcast route failed"); - vap->iv_stats.is_mesh_rtaddfailed++; - return 1; - } - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, source, - "add mcast route, mesh seqno %d", seq); - rt->rt_lastmseq = seq; - return 0; - } - if (IEEE80211_MESH_SEQ_GEQ(rt->rt_lastmseq, seq)) { - return 1; - } else { - rt->rt_lastmseq = seq; - return 0; - } -} - -/* - * Iterate the routing table and locate the next hop. - */ -static struct ieee80211_node * -mesh_find_txnode(struct ieee80211vap *vap, - const uint8_t dest[IEEE80211_ADDR_LEN]) -{ - struct ieee80211_mesh_route *rt; - - rt = ieee80211_mesh_rt_find(vap, dest); - if (rt == NULL) - return NULL; - if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0 || - (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY)) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, dest, - "%s: !valid or proxy, flags 0x%x", __func__, rt->rt_flags); - /* XXX stat */ - return NULL; - } - return ieee80211_find_txnode(vap, rt->rt_nexthop); -} - -/* - * Forward the specified frame. - * Decrement the TTL and set TA to our MAC address. - */ -static void -mesh_forward(struct ieee80211vap *vap, struct mbuf *m, - const struct ieee80211_meshcntl *mc) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ifnet *ifp = vap->iv_ifp; - struct ifnet *parent = ic->ic_ifp; - const struct ieee80211_frame *wh = - mtod(m, const struct ieee80211_frame *); - struct mbuf *mcopy; - struct ieee80211_meshcntl *mccopy; - struct ieee80211_frame *whcopy; - struct ieee80211_node *ni; - int err; - - if (mc->mc_ttl == 0) { - IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh, - "%s", "frame not fwd'd, ttl 0"); - vap->iv_stats.is_mesh_fwd_ttl++; - return; - } - if (!(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) { - IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh, - "%s", "frame not fwd'd, fwding disabled"); - vap->iv_stats.is_mesh_fwd_disabled++; - return; - } - mcopy = m_dup(m, M_DONTWAIT); - if (mcopy == NULL) { - IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh, - "%s", "frame not fwd'd, cannot dup"); - vap->iv_stats.is_mesh_fwd_nobuf++; - ifp->if_oerrors++; - return; - } - mcopy = m_pullup(mcopy, ieee80211_hdrspace(ic, wh) + - sizeof(struct ieee80211_meshcntl)); - if (mcopy == NULL) { - IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh, - "%s", "frame not fwd'd, too short"); - vap->iv_stats.is_mesh_fwd_tooshort++; - ifp->if_oerrors++; - m_freem(mcopy); - return; - } - whcopy = mtod(mcopy, struct ieee80211_frame *); - mccopy = (struct ieee80211_meshcntl *) - (mtod(mcopy, uint8_t *) + ieee80211_hdrspace(ic, wh)); - /* XXX clear other bits? */ - whcopy->i_fc[1] &= ~IEEE80211_FC1_RETRY; - IEEE80211_ADDR_COPY(whcopy->i_addr2, vap->iv_myaddr); - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { - ni = ieee80211_ref_node(vap->iv_bss); - mcopy->m_flags |= M_MCAST; - } else { - ni = mesh_find_txnode(vap, whcopy->i_addr3); - if (ni == NULL) { - IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh, - "%s", "frame not fwd'd, no path"); - vap->iv_stats.is_mesh_fwd_nopath++; - m_freem(mcopy); - return; - } - IEEE80211_ADDR_COPY(whcopy->i_addr1, ni->ni_macaddr); - } - KASSERT(mccopy->mc_ttl > 0, ("%s called with wrong ttl", __func__)); - mccopy->mc_ttl--; - - /* XXX calculate priority so drivers can find the tx queue */ - M_WME_SETAC(mcopy, WME_AC_BE); - - /* XXX do we know m_nextpkt is NULL? */ - mcopy->m_pkthdr.rcvif = (void *) ni; - err = parent->if_transmit(parent, mcopy); - if (err != 0) { - /* NB: IFQ_HANDOFF reclaims mbuf */ - ieee80211_free_node(ni); - } else { - ifp->if_opackets++; - } -} - -static struct mbuf * -mesh_decap(struct ieee80211vap *vap, struct mbuf *m, int hdrlen, int meshdrlen) -{ -#define WHDIR(wh) ((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) - uint8_t b[sizeof(struct ieee80211_qosframe_addr4) + - sizeof(struct ieee80211_meshcntl_ae11)]; - const struct ieee80211_qosframe_addr4 *wh; - const struct ieee80211_meshcntl_ae10 *mc; - struct ether_header *eh; - struct llc *llc; - int ae; - - if (m->m_len < hdrlen + sizeof(*llc) && - (m = m_pullup(m, hdrlen + sizeof(*llc))) == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ANY, - "discard data frame: %s", "m_pullup failed"); - vap->iv_stats.is_rx_tooshort++; - return NULL; - } - memcpy(b, mtod(m, caddr_t), hdrlen); - wh = (const struct ieee80211_qosframe_addr4 *)&b[0]; - mc = (const struct ieee80211_meshcntl_ae10 *)&b[hdrlen - meshdrlen]; - KASSERT(WHDIR(wh) == IEEE80211_FC1_DIR_FROMDS || - WHDIR(wh) == IEEE80211_FC1_DIR_DSTODS, - ("bogus dir, fc 0x%x:0x%x", wh->i_fc[0], wh->i_fc[1])); - - llc = (struct llc *)(mtod(m, caddr_t) + hdrlen); - if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && - llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && - llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0 && - /* NB: preserve AppleTalk frames that have a native SNAP hdr */ - !(llc->llc_snap.ether_type == htons(ETHERTYPE_AARP) || - llc->llc_snap.ether_type == htons(ETHERTYPE_IPX))) { - m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh)); - llc = NULL; - } else { - m_adj(m, hdrlen - sizeof(*eh)); - } - eh = mtod(m, struct ether_header *); - ae = mc->mc_flags & 3; - if (WHDIR(wh) == IEEE80211_FC1_DIR_FROMDS) { - IEEE80211_ADDR_COPY(eh->ether_dhost, wh->i_addr1); - if (ae == 0) { - IEEE80211_ADDR_COPY(eh->ether_shost, wh->i_addr3); - } else if (ae == 1) { - IEEE80211_ADDR_COPY(eh->ether_shost, mc->mc_addr4); - } else { - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - (const struct ieee80211_frame *)wh, NULL, - "bad AE %d", ae); - vap->iv_stats.is_mesh_badae++; - m_freem(m); - return NULL; - } - } else { - if (ae == 0) { - IEEE80211_ADDR_COPY(eh->ether_dhost, wh->i_addr3); - IEEE80211_ADDR_COPY(eh->ether_shost, wh->i_addr4); - } else if (ae == 2) { - IEEE80211_ADDR_COPY(eh->ether_dhost, mc->mc_addr4); - IEEE80211_ADDR_COPY(eh->ether_shost, mc->mc_addr5); - } else { - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - (const struct ieee80211_frame *)wh, NULL, - "bad AE %d", ae); - vap->iv_stats.is_mesh_badae++; - m_freem(m); - return NULL; - } - } -#ifdef ALIGNED_POINTER - if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), uint32_t)) { - m = ieee80211_realign(vap, m, sizeof(*eh)); - if (m == NULL) - return NULL; - } -#endif /* ALIGNED_POINTER */ - if (llc != NULL) { - eh = mtod(m, struct ether_header *); - eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh)); - } - return m; -#undef WDIR -} - -/* - * Return non-zero if the unicast mesh data frame should be processed - * locally. Frames that are not proxy'd have our address, otherwise - * we need to consult the routing table to look for a proxy entry. - */ -static __inline int -mesh_isucastforme(struct ieee80211vap *vap, const struct ieee80211_frame *wh, - const struct ieee80211_meshcntl *mc) -{ - int ae = mc->mc_flags & 3; - - KASSERT((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS, - ("bad dir 0x%x:0x%x", wh->i_fc[0], wh->i_fc[1])); - KASSERT(ae == 0 || ae == 2, ("bad AE %d", ae)); - if (ae == 2) { /* ucast w/ proxy */ - const struct ieee80211_meshcntl_ae10 *mc10 = - (const struct ieee80211_meshcntl_ae10 *) mc; - struct ieee80211_mesh_route *rt = - ieee80211_mesh_rt_find(vap, mc10->mc_addr4); - /* check for proxy route to ourself */ - return (rt != NULL && - (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY)); - } else /* ucast w/o proxy */ - return IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_myaddr); -} - -static int -mesh_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) -{ -#define HAS_SEQ(type) ((type & 0x4) == 0) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = vap->iv_ifp; - struct ieee80211_frame *wh; - const struct ieee80211_meshcntl *mc; - int hdrspace, meshdrlen, need_tap; - uint8_t dir, type, subtype, qos; - uint32_t seq; - uint8_t *addr; - ieee80211_seq rxseq; - - KASSERT(ni != NULL, ("null node")); - ni->ni_inact = ni->ni_inact_reload; - - need_tap = 1; /* mbuf need to be tapped. */ - type = -1; /* undefined */ - - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, - "too short (1): len %u", m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } - /* - * Bit of a cheat here, we use a pointer for a 3-address - * frame format but don't reference fields past outside - * ieee80211_frame_min w/o first validating the data is - * present. - */ - wh = mtod(m, struct ieee80211_frame *); - - if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != - IEEE80211_FC0_VERSION_0) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, "wrong version %x", wh->i_fc[0]); - vap->iv_stats.is_rx_badversion++; - goto err; - } - dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; - type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; - subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { - IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = nf; - if (HAS_SEQ(type)) { - uint8_t tid = ieee80211_gettid(wh); - - if (IEEE80211_QOS_HAS_SEQ(wh) && - TID_TO_WME_AC(tid) >= WME_AC_VI) - ic->ic_wme.wme_hipri_traffic++; - rxseq = le16toh(*(uint16_t *)wh->i_seq); - if (! ieee80211_check_rxseq(ni, wh)) { - /* duplicate, discard */ - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - wh->i_addr1, "duplicate", - "seqno <%u,%u> fragno <%u,%u> tid %u", - rxseq >> IEEE80211_SEQ_SEQ_SHIFT, - ni->ni_rxseqs[tid] >> - IEEE80211_SEQ_SEQ_SHIFT, - rxseq & IEEE80211_SEQ_FRAG_MASK, - ni->ni_rxseqs[tid] & - IEEE80211_SEQ_FRAG_MASK, - tid); - vap->iv_stats.is_rx_dup++; - IEEE80211_NODE_STAT(ni, rx_dup); - goto out; - } - ni->ni_rxseqs[tid] = rxseq; - } - } -#ifdef IEEE80211_DEBUG - /* - * It's easier, but too expensive, to simulate different mesh - * topologies by consulting the ACL policy very early, so do this - * only under DEBUG. - * - * NB: this check is also done upon peering link initiation. - */ - if (vap->iv_acl != NULL && !vap->iv_acl->iac_check(vap, wh->i_addr2)) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_ACL, - wh, NULL, "%s", "disallowed by ACL"); - vap->iv_stats.is_rx_acl++; - goto out; - } -#endif - switch (type) { - case IEEE80211_FC0_TYPE_DATA: - if (ni == vap->iv_bss) - goto out; - if (ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH, - ni->ni_macaddr, NULL, - "peer link not yet established (%d)", - ni->ni_mlstate); - vap->iv_stats.is_mesh_nolink++; - goto out; - } - if (dir != IEEE80211_FC1_DIR_FROMDS && - dir != IEEE80211_FC1_DIR_DSTODS) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "data", "incorrect dir 0x%x", dir); - vap->iv_stats.is_rx_wrongdir++; - goto err; - } - /* pull up enough to get to the mesh control */ - hdrspace = ieee80211_hdrspace(ic, wh); - if (m->m_len < hdrspace + sizeof(struct ieee80211_meshcntl) && - (m = m_pullup(m, hdrspace + - sizeof(struct ieee80211_meshcntl))) == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, - "data too short: expecting %u", hdrspace); - vap->iv_stats.is_rx_tooshort++; - goto out; /* XXX */ - } - /* - * Now calculate the full extent of the headers. Note - * mesh_decap will pull up anything we didn't get - * above when it strips the 802.11 headers. - */ - mc = (const struct ieee80211_meshcntl *) - (mtod(m, const uint8_t *) + hdrspace); - meshdrlen = sizeof(struct ieee80211_meshcntl) + - (mc->mc_flags & 3) * IEEE80211_ADDR_LEN; - hdrspace += meshdrlen; - seq = LE_READ_4(mc->mc_seq); - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) - addr = wh->i_addr3; - else - addr = ((struct ieee80211_qosframe_addr4 *)wh)->i_addr4; - if (IEEE80211_ADDR_EQ(vap->iv_myaddr, addr)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - addr, "data", "%s", "not to me"); - vap->iv_stats.is_rx_wrongbss++; /* XXX kinda */ - goto out; - } - if (mesh_checkpseq(vap, addr, seq) != 0) { - vap->iv_stats.is_rx_dup++; - goto out; - } - - /* - * Potentially forward packet. See table s36 (p140) - * for the rules. XXX tap fwd'd packets not for us? - */ - if (dir == IEEE80211_FC1_DIR_FROMDS || - !mesh_isucastforme(vap, wh, mc)) { - mesh_forward(vap, m, mc); - if (dir == IEEE80211_FC1_DIR_DSTODS) - goto out; - /* NB: fall thru to deliver mcast frames locally */ - } - - /* - * Save QoS bits for use below--before we strip the header. - */ - if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { - qos = (dir == IEEE80211_FC1_DIR_DSTODS) ? - ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] : - ((struct ieee80211_qosframe *)wh)->i_qos[0]; - } else - qos = 0; - /* - * Next up, any fragmentation. - */ - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - m = ieee80211_defrag(ni, m, hdrspace); - if (m == NULL) { - /* Fragment dropped or frame not complete yet */ - goto out; - } - } - wh = NULL; /* no longer valid, catch any uses */ - - if (ieee80211_radiotap_active_vap(vap)) - ieee80211_radiotap_rx(vap, m); - need_tap = 0; - - /* - * Finally, strip the 802.11 header. - */ - m = mesh_decap(vap, m, hdrspace, meshdrlen); - if (m == NULL) { - /* XXX mask bit to check for both */ - /* don't count Null data frames as errors */ - if (subtype == IEEE80211_FC0_SUBTYPE_NODATA || - subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL) - goto out; - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - ni->ni_macaddr, "data", "%s", "decap error"); - vap->iv_stats.is_rx_decap++; - IEEE80211_NODE_STAT(ni, rx_decap); - goto err; - } - if (qos & IEEE80211_QOS_AMSDU) { - m = ieee80211_decap_amsdu(ni, m); - if (m == NULL) - return IEEE80211_FC0_TYPE_DATA; - } - ieee80211_deliver_data(vap, ni, m); - return type; - case IEEE80211_FC0_TYPE_MGT: - vap->iv_stats.is_rx_mgmt++; - IEEE80211_NODE_STAT(ni, rx_mgmt); - if (dir != IEEE80211_FC1_DIR_NODS) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "mgt", "incorrect dir 0x%x", dir); - vap->iv_stats.is_rx_wrongdir++; - goto err; - } - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, "mgt", "too short: len %u", - m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } -#ifdef IEEE80211_DEBUG - if ((ieee80211_msg_debug(vap) && - (vap->iv_ic->ic_flags & IEEE80211_F_SCAN)) || - ieee80211_msg_dumppkts(vap)) { - if_printf(ifp, "received %s from %s rssi %d\n", - ieee80211_mgt_subtype_name[subtype >> - IEEE80211_FC0_SUBTYPE_SHIFT], - ether_sprintf(wh->i_addr2), rssi); - } -#endif - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "WEP set but not permitted"); - vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ - goto out; - } - vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); - goto out; - case IEEE80211_FC0_TYPE_CTL: - vap->iv_stats.is_rx_ctl++; - IEEE80211_NODE_STAT(ni, rx_ctrl); - goto out; - default: - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "bad", "frame type 0x%x", type); - /* should not come here */ - break; - } -err: - ifp->if_ierrors++; -out: - if (m != NULL) { - if (need_tap && ieee80211_radiotap_active_vap(vap)) - ieee80211_radiotap_rx(vap, m); - m_freem(m); - } - return type; -} - -static void -mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype, - int rssi, int nf) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_frame *wh; - uint8_t *frm, *efrm; - - wh = mtod(m0, struct ieee80211_frame *); - frm = (uint8_t *)&wh[1]; - efrm = mtod(m0, uint8_t *) + m0->m_len; - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - case IEEE80211_FC0_SUBTYPE_BEACON: - { - struct ieee80211_scanparams scan; - /* - * We process beacon/probe response - * frames to discover neighbors. - */ - if (ieee80211_parse_beacon(ni, m0, &scan) != 0) - return; - /* - * Count frame now that we know it's to be processed. - */ - if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) { - vap->iv_stats.is_rx_beacon++; /* XXX remove */ - IEEE80211_NODE_STAT(ni, rx_beacons); - } else - IEEE80211_NODE_STAT(ni, rx_proberesp); - /* - * If scanning, just pass information to the scan module. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) { - if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) { - /* - * Actively scanning a channel marked passive; - * send a probe request now that we know there - * is 802.11 traffic present. - * - * XXX check if the beacon we recv'd gives - * us what we need and suppress the probe req - */ - ieee80211_probe_curchan(vap, 1); - ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; - } - ieee80211_add_scan(vap, &scan, wh, - subtype, rssi, nf); - return; - } - - /* The rest of this code assumes we are running */ - if (vap->iv_state != IEEE80211_S_RUN) - return; - /* - * Ignore non-mesh STAs. - */ - if ((scan.capinfo & - (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) || - scan.meshid == NULL || scan.meshconf == NULL) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "beacon", "%s", "not a mesh sta"); - vap->iv_stats.is_mesh_wrongmesh++; - return; - } - /* - * Ignore STAs for other mesh networks. - */ - if (memcmp(scan.meshid+2, ms->ms_id, ms->ms_idlen) != 0 || - mesh_verify_meshconf(vap, scan.meshconf)) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "beacon", "%s", "not for our mesh"); - vap->iv_stats.is_mesh_wrongmesh++; - return; - } - /* - * Peer only based on the current ACL policy. - */ - if (vap->iv_acl != NULL && - !vap->iv_acl->iac_check(vap, wh->i_addr2)) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_ACL, - wh, NULL, "%s", "disallowed by ACL"); - vap->iv_stats.is_rx_acl++; - return; - } - /* - * Do neighbor discovery. - */ - if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { - /* - * Create a new entry in the neighbor table. - */ - ni = ieee80211_add_neighbor(vap, wh, &scan); - } - /* - * Automatically peer with discovered nodes if possible. - * XXX backoff on repeated failure - */ - if (ni != vap->iv_bss && - (ms->ms_flags & IEEE80211_MESHFLAGS_AP) && - ni->ni_mlstate == IEEE80211_NODE_MESH_IDLE) { - uint16_t args[1]; - - ni->ni_mlpid = mesh_generateid(vap); - if (ni->ni_mlpid == 0) - return; - mesh_linkchange(ni, IEEE80211_NODE_MESH_OPENSNT); - args[0] = ni->ni_mlpid; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_OPEN, args); - ni->ni_mlrcnt = 0; - mesh_peer_timeout_setup(ni); - } - break; - } - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - { - uint8_t *ssid, *meshid, *rates, *xrates; - uint8_t *sfrm; - - if (vap->iv_state != IEEE80211_S_RUN) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "wrong state %s", - ieee80211_state_name[vap->iv_state]); - vap->iv_stats.is_rx_mgtdiscard++; - return; - } - if (IEEE80211_IS_MULTICAST(wh->i_addr2)) { - /* frame must be directed */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not unicast"); - vap->iv_stats.is_rx_mgtdiscard++; /* XXX stat */ - return; - } - /* - * prreq frame format - * [tlv] ssid - * [tlv] supported rates - * [tlv] extended supported rates - * [tlv] mesh id - */ - ssid = meshid = rates = xrates = NULL; - sfrm = frm; - while (efrm - frm > 1) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); - switch (*frm) { - case IEEE80211_ELEMID_SSID: - ssid = frm; - break; - case IEEE80211_ELEMID_RATES: - rates = frm; - break; - case IEEE80211_ELEMID_XRATES: - xrates = frm; - break; - case IEEE80211_ELEMID_MESHID: - meshid = frm; - break; - } - frm += frm[1] + 2; - } - IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN, return); - IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return); - if (xrates != NULL) - IEEE80211_VERIFY_ELEMENT(xrates, - IEEE80211_RATE_MAXSIZE - rates[1], return); - if (meshid != NULL) { - IEEE80211_VERIFY_ELEMENT(meshid, - IEEE80211_MESHID_LEN, return); - /* NB: meshid, not ssid */ - IEEE80211_VERIFY_SSID(vap->iv_bss, meshid, return); - } - - /* XXX find a better class or define it's own */ - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2, - "%s", "recv probe req"); - /* - * Some legacy 11b clients cannot hack a complete - * probe response frame. When the request includes - * only a bare-bones rate set, communicate this to - * the transmit side. - */ - ieee80211_send_proberesp(vap, wh->i_addr2, 0); - break; - } - - case IEEE80211_FC0_SUBTYPE_ACTION: - case IEEE80211_FC0_SUBTYPE_ACTION_NOACK: - if (ni == vap->iv_bss) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "unknown node"); - vap->iv_stats.is_rx_mgtdiscard++; - } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) && - !IEEE80211_IS_MULTICAST(wh->i_addr1)) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not for us"); - vap->iv_stats.is_rx_mgtdiscard++; - } else if (vap->iv_state != IEEE80211_S_RUN) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "wrong state %s", - ieee80211_state_name[vap->iv_state]); - vap->iv_stats.is_rx_mgtdiscard++; - } else { - if (ieee80211_parse_action(ni, m0) == 0) - (void)ic->ic_recv_action(ni, wh, frm, efrm); - } - break; - - case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_ATIM: - case IEEE80211_FC0_SUBTYPE_DISASSOC: - case IEEE80211_FC0_SUBTYPE_AUTH: - case IEEE80211_FC0_SUBTYPE_DEAUTH: - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not handled"); - vap->iv_stats.is_rx_mgtdiscard++; - break; - - default: - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "mgt", "subtype 0x%x not handled", subtype); - vap->iv_stats.is_rx_badsubtype++; - break; - } -} - -static void -mesh_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype) -{ - - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_BAR: - ieee80211_recv_bar(ni, m); - break; - } -} - -/* - * Parse meshpeering action ie's for open+confirm frames; the - * important bits are returned in the supplied structure. - */ -static const struct ieee80211_meshpeer_ie * -mesh_parse_meshpeering_action(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, /* XXX for VERIFY_LENGTH */ - const uint8_t *frm, const uint8_t *efrm, - struct ieee80211_meshpeer_ie *mp, uint8_t subtype) -{ - struct ieee80211vap *vap = ni->ni_vap; - const struct ieee80211_meshpeer_ie *mpie; - const uint8_t *meshid, *meshconf, *meshpeer; - - meshid = meshconf = meshpeer = NULL; - while (efrm - frm > 1) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return NULL); - switch (*frm) { - case IEEE80211_ELEMID_MESHID: - meshid = frm; - break; - case IEEE80211_ELEMID_MESHCONF: - meshconf = frm; - break; - case IEEE80211_ELEMID_MESHPEER: - meshpeer = frm; - mpie = (const struct ieee80211_meshpeer_ie *) frm; - memset(mp, 0, sizeof(*mp)); - mp->peer_llinkid = LE_READ_2(&mpie->peer_llinkid); - /* NB: peer link ID is optional on these frames */ - if (subtype == IEEE80211_MESH_PEER_LINK_CLOSE && - mpie->peer_len == 8) { - mp->peer_linkid = 0; - mp->peer_rcode = LE_READ_2(&mpie->peer_linkid); - } else { - mp->peer_linkid = LE_READ_2(&mpie->peer_linkid); - mp->peer_rcode = LE_READ_2(&mpie->peer_rcode); - } - break; - } - frm += frm[1] + 2; - } - - /* - * Verify the contents of the frame. Action frames with - * close subtype don't have a Mesh Configuration IE. - * If if fails validation, close the peer link. - */ - KASSERT(meshpeer != NULL && - subtype != IEEE80211_ACTION_MESHPEERING_CLOSE, - ("parsing close action")); - - if (mesh_verify_meshid(vap, meshid) || - mesh_verify_meshpeer(vap, subtype, meshpeer) || - mesh_verify_meshconf(vap, meshconf)) { - uint16_t args[3]; - - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, - wh, NULL, "%s", "not for our mesh"); - vap->iv_stats.is_rx_mgtdiscard++; - switch (ni->ni_mlstate) { - case IEEE80211_NODE_MESH_IDLE: - case IEEE80211_NODE_MESH_ESTABLISHED: - case IEEE80211_NODE_MESH_HOLDING: - /* ignore */ - break; - case IEEE80211_NODE_MESH_OPENSNT: - case IEEE80211_NODE_MESH_OPENRCV: - case IEEE80211_NODE_MESH_CONFIRMRCV: - args[0] = ni->ni_mlpid; - args[1] = ni->ni_mllid; - args[2] = IEEE80211_REASON_PEER_LINK_CANCELED; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, - args); - mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); - mesh_peer_timeout_setup(ni); - break; - } - return NULL; - } - return (const struct ieee80211_meshpeer_ie *) mp; -} - -static int -mesh_recv_action_meshpeering_open(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_meshpeer_ie ie; - const struct ieee80211_meshpeer_ie *meshpeer; - uint16_t args[3]; - - /* +2+2 for action + code + capabilites */ - meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2, efrm, &ie, - IEEE80211_ACTION_MESHPEERING_OPEN); - if (meshpeer == NULL) { - return 0; - } - - /* XXX move up */ - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni, - "recv PEER OPEN, lid 0x%x", meshpeer->peer_llinkid); - - switch (ni->ni_mlstate) { - case IEEE80211_NODE_MESH_IDLE: - mesh_linkchange(ni, IEEE80211_NODE_MESH_OPENRCV); - ni->ni_mllid = meshpeer->peer_llinkid; - ni->ni_mlpid = mesh_generateid(vap); - if (ni->ni_mlpid == 0) - return 0; /* XXX */ - args[0] = ni->ni_mlpid; - /* Announce we're open too... */ - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_OPEN, args); - /* ...and confirm the link. */ - args[0] = ni->ni_mlpid; - args[1] = ni->ni_mllid; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CONFIRM, - args); - mesh_peer_timeout_setup(ni); - break; - case IEEE80211_NODE_MESH_OPENRCV: - /* Wrong Link ID */ - if (ni->ni_mllid != meshpeer->peer_llinkid) { - args[0] = ni->ni_mllid; - args[1] = ni->ni_mlpid; - args[2] = IEEE80211_REASON_PEER_LINK_CANCELED; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, - args); - mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); - mesh_peer_timeout_setup(ni); - break; - } - /* Duplicate open, confirm again. */ - args[0] = ni->ni_mlpid; - args[1] = ni->ni_mllid; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CONFIRM, - args); - break; - case IEEE80211_NODE_MESH_OPENSNT: - ni->ni_mllid = meshpeer->peer_llinkid; - mesh_linkchange(ni, IEEE80211_NODE_MESH_OPENRCV); - args[0] = ni->ni_mlpid; - args[1] = ni->ni_mllid; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CONFIRM, - args); - /* NB: don't setup/clear any timeout */ - break; - case IEEE80211_NODE_MESH_CONFIRMRCV: - if (ni->ni_mlpid != meshpeer->peer_linkid || - ni->ni_mllid != meshpeer->peer_llinkid) { - args[0] = ni->ni_mlpid; - args[1] = ni->ni_mllid; - args[2] = IEEE80211_REASON_PEER_LINK_CANCELED; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, - args); - mesh_linkchange(ni, - IEEE80211_NODE_MESH_HOLDING); - mesh_peer_timeout_setup(ni); - break; - } - mesh_linkchange(ni, IEEE80211_NODE_MESH_ESTABLISHED); - ni->ni_mllid = meshpeer->peer_llinkid; - args[0] = ni->ni_mlpid; - args[1] = ni->ni_mllid; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CONFIRM, - args); - mesh_peer_timeout_stop(ni); - break; - case IEEE80211_NODE_MESH_ESTABLISHED: - if (ni->ni_mllid != meshpeer->peer_llinkid) { - args[0] = ni->ni_mllid; - args[1] = ni->ni_mlpid; - args[2] = IEEE80211_REASON_PEER_LINK_CANCELED; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, - args); - mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); - mesh_peer_timeout_setup(ni); - break; - } - args[0] = ni->ni_mlpid; - args[1] = ni->ni_mllid; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CONFIRM, - args); - break; - case IEEE80211_NODE_MESH_HOLDING: - args[0] = ni->ni_mlpid; - args[1] = meshpeer->peer_llinkid; - args[2] = IEEE80211_REASON_MESH_MAX_RETRIES; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, - args); - break; - } - return 0; -} - -static int -mesh_recv_action_meshpeering_confirm(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_meshpeer_ie ie; - const struct ieee80211_meshpeer_ie *meshpeer; - uint16_t args[3]; - - /* +2+2+2+2 for action + code + capabilites + status code + AID */ - meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2+2+2, efrm, &ie, - IEEE80211_ACTION_MESHPEERING_CONFIRM); - if (meshpeer == NULL) { - return 0; - } - - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni, - "recv PEER CONFIRM, local id 0x%x, peer id 0x%x", - meshpeer->peer_llinkid, meshpeer->peer_linkid); - - switch (ni->ni_mlstate) { - case IEEE80211_NODE_MESH_OPENRCV: - mesh_linkchange(ni, IEEE80211_NODE_MESH_ESTABLISHED); - mesh_peer_timeout_stop(ni); - break; - case IEEE80211_NODE_MESH_OPENSNT: - mesh_linkchange(ni, IEEE80211_NODE_MESH_CONFIRMRCV); - break; - case IEEE80211_NODE_MESH_HOLDING: - args[0] = ni->ni_mlpid; - args[1] = meshpeer->peer_llinkid; - args[2] = IEEE80211_REASON_MESH_MAX_RETRIES; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, - args); - break; - case IEEE80211_NODE_MESH_CONFIRMRCV: - if (ni->ni_mllid != meshpeer->peer_llinkid) { - args[0] = ni->ni_mlpid; - args[1] = ni->ni_mllid; - args[2] = IEEE80211_REASON_PEER_LINK_CANCELED; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, - args); - mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); - mesh_peer_timeout_setup(ni); - } - break; - default: - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, - wh, NULL, "received confirm in invalid state %d", - ni->ni_mlstate); - vap->iv_stats.is_rx_mgtdiscard++; - break; - } - return 0; -} - -static int -mesh_recv_action_meshpeering_close(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ - uint16_t args[3]; - - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, - ni, "%s", "recv PEER CLOSE"); - - switch (ni->ni_mlstate) { - case IEEE80211_NODE_MESH_IDLE: - /* ignore */ - break; - case IEEE80211_NODE_MESH_OPENRCV: - case IEEE80211_NODE_MESH_OPENSNT: - case IEEE80211_NODE_MESH_CONFIRMRCV: - case IEEE80211_NODE_MESH_ESTABLISHED: - args[0] = ni->ni_mlpid; - args[1] = ni->ni_mllid; - args[2] = IEEE80211_REASON_MESH_CLOSE_RCVD; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, - args); - mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); - mesh_peer_timeout_setup(ni); - break; - case IEEE80211_NODE_MESH_HOLDING: - mesh_linkchange(ni, IEEE80211_NODE_MESH_IDLE); - mesh_peer_timeout_setup(ni); - break; - } - return 0; -} - -/* - * Link Metric handling. - */ -static int -mesh_recv_action_meshlmetric_req(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ - uint32_t metric; - - metric = mesh_airtime_calc(ni); - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHLMETRIC, - IEEE80211_ACTION_MESHLMETRIC_REP, - &metric); - return 0; -} - -static int -mesh_recv_action_meshlmetric_rep(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const uint8_t *frm, const uint8_t *efrm) -{ - return 0; -} - -static int -mesh_send_action(struct ieee80211_node *ni, struct mbuf *m) -{ - struct ieee80211_bpf_params params; - - memset(¶ms, 0, sizeof(params)); - params.ibp_pri = WME_AC_VO; - params.ibp_rate0 = ni->ni_txparms->mgmtrate; - /* XXX ucast/mcast */ - params.ibp_try0 = ni->ni_txparms->maxretry; - params.ibp_power = ni->ni_txpower; - return ieee80211_mgmt_output(ni, m, IEEE80211_FC0_SUBTYPE_ACTION, - ¶ms); -} - -#define ADDSHORT(frm, v) do { \ - frm[0] = (v) & 0xff; \ - frm[1] = (v) >> 8; \ - frm += 2; \ -} while (0) -#define ADDWORD(frm, v) do { \ - frm[0] = (v) & 0xff; \ - frm[1] = ((v) >> 8) & 0xff; \ - frm[2] = ((v) >> 16) & 0xff; \ - frm[3] = ((v) >> 24) & 0xff; \ - frm += 4; \ -} while (0) - -static int -mesh_send_action_meshpeering_open(struct ieee80211_node *ni, - int category, int action, void *args0) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - uint16_t *args = args0; - const struct ieee80211_rateset *rs; - struct mbuf *m; - uint8_t *frm; - - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni, - "send PEER OPEN action: localid 0x%x", args[0]); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); - ieee80211_ref_node(ni); - - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t) /* action+category */ - + sizeof(uint16_t) /* capabilites */ - + 2 + IEEE80211_RATE_SIZE - + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) - + 2 + IEEE80211_MESHID_LEN - + sizeof(struct ieee80211_meshconf_ie) - + sizeof(struct ieee80211_meshpeer_ie) - ); - if (m != NULL) { - /* - * mesh peer open action frame format: - * [1] category - * [1] action - * [2] capabilities - * [tlv] rates - * [tlv] xrates - * [tlv] mesh id - * [tlv] mesh conf - * [tlv] mesh peer link mgmt - */ - *frm++ = category; - *frm++ = action; - ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan)); - rs = ieee80211_get_suprates(ic, ic->ic_curchan); - frm = ieee80211_add_rates(frm, rs); - frm = ieee80211_add_xrates(frm, rs); - frm = ieee80211_add_meshid(frm, vap); - frm = ieee80211_add_meshconf(frm, vap); - frm = ieee80211_add_meshpeer(frm, IEEE80211_MESH_PEER_LINK_OPEN, - args[0], 0, 0); - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - return mesh_send_action(ni, m); - } else { - vap->iv_stats.is_tx_nobuf++; - ieee80211_free_node(ni); - return ENOMEM; - } -} - -static int -mesh_send_action_meshpeering_confirm(struct ieee80211_node *ni, - int category, int action, void *args0) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - uint16_t *args = args0; - const struct ieee80211_rateset *rs; - struct mbuf *m; - uint8_t *frm; - - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni, - "send PEER CONFIRM action: localid 0x%x, peerid 0x%x", - args[0], args[1]); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); - ieee80211_ref_node(ni); - - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t) /* action+category */ - + sizeof(uint16_t) /* capabilites */ - + sizeof(uint16_t) /* status code */ - + sizeof(uint16_t) /* AID */ - + 2 + IEEE80211_RATE_SIZE - + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) - + 2 + IEEE80211_MESHID_LEN - + sizeof(struct ieee80211_meshconf_ie) - + sizeof(struct ieee80211_meshpeer_ie) - ); - if (m != NULL) { - /* - * mesh peer confirm action frame format: - * [1] category - * [1] action - * [2] capabilities - * [2] status code - * [2] association id (peer ID) - * [tlv] rates - * [tlv] xrates - * [tlv] mesh id - * [tlv] mesh conf - * [tlv] mesh peer link mgmt - */ - *frm++ = category; - *frm++ = action; - ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan)); - ADDSHORT(frm, 0); /* status code */ - ADDSHORT(frm, args[1]); /* AID */ - rs = ieee80211_get_suprates(ic, ic->ic_curchan); - frm = ieee80211_add_rates(frm, rs); - frm = ieee80211_add_xrates(frm, rs); - frm = ieee80211_add_meshid(frm, vap); - frm = ieee80211_add_meshconf(frm, vap); - frm = ieee80211_add_meshpeer(frm, - IEEE80211_MESH_PEER_LINK_CONFIRM, - args[0], args[1], 0); - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - return mesh_send_action(ni, m); - } else { - vap->iv_stats.is_tx_nobuf++; - ieee80211_free_node(ni); - return ENOMEM; - } -} - -static int -mesh_send_action_meshpeering_close(struct ieee80211_node *ni, - int category, int action, void *args0) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - uint16_t *args = args0; - struct mbuf *m; - uint8_t *frm; - - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni, - "send PEER CLOSE action: localid 0x%x, peerid 0x%x reason %d", - args[0], args[1], args[2]); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); - ieee80211_ref_node(ni); - - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t) /* action+category */ - + sizeof(uint16_t) /* reason code */ - + 2 + IEEE80211_MESHID_LEN - + sizeof(struct ieee80211_meshpeer_ie) - ); - if (m != NULL) { - /* - * mesh peer close action frame format: - * [1] category - * [1] action - * [2] reason code - * [tlv] mesh id - * [tlv] mesh peer link mgmt - */ - *frm++ = category; - *frm++ = action; - ADDSHORT(frm, args[2]); /* reason code */ - frm = ieee80211_add_meshid(frm, vap); - frm = ieee80211_add_meshpeer(frm, - IEEE80211_MESH_PEER_LINK_CLOSE, - args[0], args[1], args[2]); - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - return mesh_send_action(ni, m); - } else { - vap->iv_stats.is_tx_nobuf++; - ieee80211_free_node(ni); - return ENOMEM; - } -} - -static int -mesh_send_action_meshlink_request(struct ieee80211_node *ni, - int category, int action, void *arg0) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct mbuf *m; - uint8_t *frm; - - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni, - "%s", "send LINK METRIC REQUEST action"); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); - ieee80211_ref_node(ni); - - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t) /* action+category */ - ); - if (m != NULL) { - /* - * mesh link metric request - * [1] category - * [1] action - */ - *frm++ = category; - *frm++ = action; - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - return mesh_send_action(ni, m); - } else { - vap->iv_stats.is_tx_nobuf++; - ieee80211_free_node(ni); - return ENOMEM; - } -} - -static int -mesh_send_action_meshlink_reply(struct ieee80211_node *ni, - int category, int action, void *args0) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - uint32_t *metric = args0; - struct mbuf *m; - uint8_t *frm; - - IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni, - "send LINK METRIC REPLY action: metric 0x%x", *metric); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); - ieee80211_ref_node(ni); - - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t) /* action+category */ - + sizeof(struct ieee80211_meshlmetric_ie) - ); - if (m != NULL) { - /* - * mesh link metric reply - * [1] category - * [1] action - * [tlv] mesh link metric - */ - *frm++ = category; - *frm++ = action; - frm = ieee80211_add_meshlmetric(frm, *metric); - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - return mesh_send_action(ni, m); - } else { - vap->iv_stats.is_tx_nobuf++; - ieee80211_free_node(ni); - return ENOMEM; - } -} - -static void -mesh_peer_timeout_setup(struct ieee80211_node *ni) -{ - switch (ni->ni_mlstate) { - case IEEE80211_NODE_MESH_HOLDING: - ni->ni_mltval = ieee80211_mesh_holdingtimeout; - break; - case IEEE80211_NODE_MESH_CONFIRMRCV: - ni->ni_mltval = ieee80211_mesh_confirmtimeout; - break; - case IEEE80211_NODE_MESH_IDLE: - ni->ni_mltval = 0; - break; - default: - ni->ni_mltval = ieee80211_mesh_retrytimeout; - break; - } - if (ni->ni_mltval) - callout_reset(&ni->ni_mltimer, ni->ni_mltval, - mesh_peer_timeout_cb, ni); -} - -/* - * Same as above but backoffs timer statisically 50%. - */ -static void -mesh_peer_timeout_backoff(struct ieee80211_node *ni) -{ - uint32_t r; - - r = arc4random(); - ni->ni_mltval += r % ni->ni_mltval; - callout_reset(&ni->ni_mltimer, ni->ni_mltval, mesh_peer_timeout_cb, - ni); -} - -static __inline void -mesh_peer_timeout_stop(struct ieee80211_node *ni) -{ - callout_drain(&ni->ni_mltimer); -} - -/* - * Mesh Peer Link Management FSM timeout handling. - */ -static void -mesh_peer_timeout_cb(void *arg) -{ - struct ieee80211_node *ni = (struct ieee80211_node *)arg; - uint16_t args[3]; - - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_MESH, - ni, "mesh link timeout, state %d, retry counter %d", - ni->ni_mlstate, ni->ni_mlrcnt); - - switch (ni->ni_mlstate) { - case IEEE80211_NODE_MESH_IDLE: - case IEEE80211_NODE_MESH_ESTABLISHED: - break; - case IEEE80211_NODE_MESH_OPENSNT: - case IEEE80211_NODE_MESH_OPENRCV: - if (ni->ni_mlrcnt == ieee80211_mesh_maxretries) { - args[0] = ni->ni_mlpid; - args[2] = IEEE80211_REASON_MESH_MAX_RETRIES; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, args); - ni->ni_mlrcnt = 0; - mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); - mesh_peer_timeout_setup(ni); - } else { - args[0] = ni->ni_mlpid; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_OPEN, args); - ni->ni_mlrcnt++; - mesh_peer_timeout_backoff(ni); - } - break; - case IEEE80211_NODE_MESH_CONFIRMRCV: - if (ni->ni_mlrcnt == ieee80211_mesh_maxretries) { - args[0] = ni->ni_mlpid; - args[2] = IEEE80211_REASON_MESH_CONFIRM_TIMEOUT; - ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, - IEEE80211_ACTION_MESHPEERING_CLOSE, args); - ni->ni_mlrcnt = 0; - mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); - mesh_peer_timeout_setup(ni); - } else { - ni->ni_mlrcnt++; - mesh_peer_timeout_setup(ni); - } - break; - case IEEE80211_NODE_MESH_HOLDING: - mesh_linkchange(ni, IEEE80211_NODE_MESH_IDLE); - break; - } -} - -static int -mesh_verify_meshid(struct ieee80211vap *vap, const uint8_t *ie) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - - if (ie == NULL || ie[1] != ms->ms_idlen) - return 1; - return memcmp(ms->ms_id, ie + 2, ms->ms_idlen); -} - -/* - * Check if we are using the same algorithms for this mesh. - */ -static int -mesh_verify_meshconf(struct ieee80211vap *vap, const uint8_t *ie) -{ - const struct ieee80211_meshconf_ie *meshconf = - (const struct ieee80211_meshconf_ie *) ie; - const struct ieee80211_mesh_state *ms = vap->iv_mesh; - uint16_t cap; - - if (meshconf == NULL) - return 1; - if (meshconf->conf_pselid != ms->ms_ppath->mpp_ie) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH, - "unknown path selection algorithm: 0x%x\n", - meshconf->conf_pselid); - return 1; - } - if (meshconf->conf_pmetid != ms->ms_pmetric->mpm_ie) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH, - "unknown path metric algorithm: 0x%x\n", - meshconf->conf_pmetid); - return 1; - } - if (meshconf->conf_ccid != 0) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH, - "unknown congestion control algorithm: 0x%x\n", - meshconf->conf_ccid); - return 1; - } - if (meshconf->conf_syncid != IEEE80211_MESHCONF_SYNC_NEIGHOFF) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH, - "unknown sync algorithm: 0x%x\n", - meshconf->conf_syncid); - return 1; - } - if (meshconf->conf_authid != 0) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH, - "unknown auth auth algorithm: 0x%x\n", - meshconf->conf_pselid); - return 1; - } - /* NB: conf_cap is only read correctly here */ - cap = LE_READ_2(&meshconf->conf_cap); - /* Not accepting peers */ - if (!(cap & IEEE80211_MESHCONF_CAP_AP)) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH, - "not accepting peers: 0x%x\n", meshconf->conf_cap); - return 1; - } - return 0; -} - -static int -mesh_verify_meshpeer(struct ieee80211vap *vap, uint8_t subtype, - const uint8_t *ie) -{ - const struct ieee80211_meshpeer_ie *meshpeer = - (const struct ieee80211_meshpeer_ie *) ie; - - if (meshpeer == NULL || meshpeer->peer_len < 6 || - meshpeer->peer_len > 10) - return 1; - switch (subtype) { - case IEEE80211_MESH_PEER_LINK_OPEN: - if (meshpeer->peer_len != 6) - return 1; - break; - case IEEE80211_MESH_PEER_LINK_CONFIRM: - if (meshpeer->peer_len != 8) - return 1; - break; - case IEEE80211_MESH_PEER_LINK_CLOSE: - if (meshpeer->peer_len < 8) - return 1; - if (meshpeer->peer_len == 8 && meshpeer->peer_linkid != 0) - return 1; - if (meshpeer->peer_rcode == 0) - return 1; - break; - } - return 0; -} - -/* - * Add a Mesh ID IE to a frame. - */ -uint8_t * -ieee80211_add_meshid(uint8_t *frm, struct ieee80211vap *vap) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - - KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a mbss vap")); - - *frm++ = IEEE80211_ELEMID_MESHID; - *frm++ = ms->ms_idlen; - memcpy(frm, ms->ms_id, ms->ms_idlen); - return frm + ms->ms_idlen; -} - -/* - * Add a Mesh Configuration IE to a frame. - * For now just use HWMP routing, Airtime link metric, Null Congestion - * Signaling, Null Sync Protocol and Null Authentication. - */ -uint8_t * -ieee80211_add_meshconf(uint8_t *frm, struct ieee80211vap *vap) -{ - const struct ieee80211_mesh_state *ms = vap->iv_mesh; - uint16_t caps; - - KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap")); - - *frm++ = IEEE80211_ELEMID_MESHCONF; - *frm++ = sizeof(struct ieee80211_meshconf_ie) - 2; - *frm++ = ms->ms_ppath->mpp_ie; /* path selection */ - *frm++ = ms->ms_pmetric->mpm_ie; /* link metric */ - *frm++ = IEEE80211_MESHCONF_CC_DISABLED; - *frm++ = IEEE80211_MESHCONF_SYNC_NEIGHOFF; - *frm++ = IEEE80211_MESHCONF_AUTH_DISABLED; - /* NB: set the number of neighbors before the rest */ - *frm = (ms->ms_neighbors > 15 ? 15 : ms->ms_neighbors) << 1; - if (ms->ms_flags & IEEE80211_MESHFLAGS_PORTAL) - *frm |= IEEE80211_MESHCONF_FORM_MP; - frm += 1; - caps = 0; - if (ms->ms_flags & IEEE80211_MESHFLAGS_AP) - caps |= IEEE80211_MESHCONF_CAP_AP; - if (ms->ms_flags & IEEE80211_MESHFLAGS_FWD) - caps |= IEEE80211_MESHCONF_CAP_FWRD; - ADDSHORT(frm, caps); - return frm; -} - -/* - * Add a Mesh Peer Management IE to a frame. - */ -uint8_t * -ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid, - uint16_t peerid, uint16_t reason) -{ - /* XXX change for AH */ - static const uint8_t meshpeerproto[4] = IEEE80211_MESH_PEER_PROTO; - - KASSERT(localid != 0, ("localid == 0")); - - *frm++ = IEEE80211_ELEMID_MESHPEER; - switch (subtype) { - case IEEE80211_MESH_PEER_LINK_OPEN: - *frm++ = 6; /* length */ - memcpy(frm, meshpeerproto, 4); - frm += 4; - ADDSHORT(frm, localid); /* local ID */ - break; - case IEEE80211_MESH_PEER_LINK_CONFIRM: - KASSERT(peerid != 0, ("sending peer confirm without peer id")); - *frm++ = 8; /* length */ - memcpy(frm, meshpeerproto, 4); - frm += 4; - ADDSHORT(frm, localid); /* local ID */ - ADDSHORT(frm, peerid); /* peer ID */ - break; - case IEEE80211_MESH_PEER_LINK_CLOSE: - if (peerid) - *frm++ = 10; /* length */ - else - *frm++ = 8; /* length */ - memcpy(frm, meshpeerproto, 4); - frm += 4; - ADDSHORT(frm, localid); /* local ID */ - if (peerid) - ADDSHORT(frm, peerid); /* peer ID */ - ADDSHORT(frm, reason); - break; - } - return frm; -} - -/* - * Compute an Airtime Link Metric for the link with this node. - * - * Based on Draft 3.0 spec (11B.10, p.149). - */ -/* - * Max 802.11s overhead. - */ -#define IEEE80211_MESH_MAXOVERHEAD \ - (sizeof(struct ieee80211_qosframe_addr4) \ - + sizeof(struct ieee80211_meshcntl_ae11) \ - + sizeof(struct llc) \ - + IEEE80211_ADDR_LEN \ - + IEEE80211_WEP_IVLEN \ - + IEEE80211_WEP_KIDLEN \ - + IEEE80211_WEP_CRCLEN \ - + IEEE80211_WEP_MICLEN \ - + IEEE80211_CRC_LEN) -uint32_t -mesh_airtime_calc(struct ieee80211_node *ni) -{ -#define M_BITS 8 -#define S_FACTOR (2 * M_BITS) - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ni->ni_vap->iv_ifp; - const static int nbits = 8192 << M_BITS; - uint32_t overhead, rate, errrate; - uint64_t res; - - /* Time to transmit a frame */ - rate = ni->ni_txrate; - overhead = ieee80211_compute_duration(ic->ic_rt, - ifp->if_mtu + IEEE80211_MESH_MAXOVERHEAD, rate, 0) << M_BITS; - /* Error rate in percentage */ - /* XXX assuming small failures are ok */ - errrate = (((ifp->if_oerrors + - ifp->if_ierrors) / 100) << M_BITS) / 100; - res = (overhead + (nbits / rate)) * - ((1 << S_FACTOR) / ((1 << M_BITS) - errrate)); - - return (uint32_t)(res >> S_FACTOR); -#undef M_BITS -#undef S_FACTOR -} - -/* - * Add a Mesh Link Metric report IE to a frame. - */ -uint8_t * -ieee80211_add_meshlmetric(uint8_t *frm, uint32_t metric) -{ - *frm++ = IEEE80211_ELEMID_MESHLINK; - *frm++ = 4; - ADDWORD(frm, metric); - return frm; -} -#undef ADDSHORT -#undef ADDWORD - -/* - * Initialize any mesh-specific node state. - */ -void -ieee80211_mesh_node_init(struct ieee80211vap *vap, struct ieee80211_node *ni) -{ - ni->ni_flags |= IEEE80211_NODE_QOS; - callout_init(&ni->ni_mltimer, CALLOUT_MPSAFE); -} - -/* - * Cleanup any mesh-specific node state. - */ -void -ieee80211_mesh_node_cleanup(struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_mesh_state *ms = vap->iv_mesh; - - callout_drain(&ni->ni_mltimer); - /* NB: short-circuit callbacks after mesh_vdetach */ - if (vap->iv_mesh != NULL) - ms->ms_ppath->mpp_peerdown(ni); -} - -void -ieee80211_parse_meshid(struct ieee80211_node *ni, const uint8_t *ie) -{ - ni->ni_meshidlen = ie[1]; - memcpy(ni->ni_meshid, ie + 2, ie[1]); -} - -/* - * Setup mesh-specific node state on neighbor discovery. - */ -void -ieee80211_mesh_init_neighbor(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const struct ieee80211_scanparams *sp) -{ - ieee80211_parse_meshid(ni, sp->meshid); -} - -void -ieee80211_mesh_update_beacon(struct ieee80211vap *vap, - struct ieee80211_beacon_offsets *bo) -{ - KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap")); - - if (isset(bo->bo_flags, IEEE80211_BEACON_MESHCONF)) { - (void)ieee80211_add_meshconf(bo->bo_meshconf, vap); - clrbit(bo->bo_flags, IEEE80211_BEACON_MESHCONF); - } -} - -static int -mesh_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - uint8_t tmpmeshid[IEEE80211_NWID_LEN]; - struct ieee80211_mesh_route *rt; - struct ieee80211req_mesh_route *imr; - size_t len, off; - uint8_t *p; - int error; - - if (vap->iv_opmode != IEEE80211_M_MBSS) - return ENOSYS; - - error = 0; - switch (ireq->i_type) { - case IEEE80211_IOC_MESH_ID: - ireq->i_len = ms->ms_idlen; - memcpy(tmpmeshid, ms->ms_id, ireq->i_len); - error = copyout(tmpmeshid, ireq->i_data, ireq->i_len); - break; - case IEEE80211_IOC_MESH_AP: - ireq->i_val = (ms->ms_flags & IEEE80211_MESHFLAGS_AP) != 0; - break; - case IEEE80211_IOC_MESH_FWRD: - ireq->i_val = (ms->ms_flags & IEEE80211_MESHFLAGS_FWD) != 0; - break; - case IEEE80211_IOC_MESH_TTL: - ireq->i_val = ms->ms_ttl; - break; - case IEEE80211_IOC_MESH_RTCMD: - switch (ireq->i_val) { - case IEEE80211_MESH_RTCMD_LIST: - len = 0; - MESH_RT_LOCK(ms); - TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) { - len += sizeof(*imr); - } - MESH_RT_UNLOCK(ms); - if (len > ireq->i_len || ireq->i_len < sizeof(*imr)) { - ireq->i_len = len; - return ENOMEM; - } - ireq->i_len = len; - /* XXX M_WAIT? */ - p = malloc(len, M_TEMP, M_NOWAIT | M_ZERO); - if (p == NULL) - return ENOMEM; - off = 0; - MESH_RT_LOCK(ms); - TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) { - if (off >= len) - break; - imr = (struct ieee80211req_mesh_route *) - (p + off); - imr->imr_flags = rt->rt_flags; - IEEE80211_ADDR_COPY(imr->imr_dest, - rt->rt_dest); - IEEE80211_ADDR_COPY(imr->imr_nexthop, - rt->rt_nexthop); - imr->imr_metric = rt->rt_metric; - imr->imr_nhops = rt->rt_nhops; - imr->imr_lifetime = rt->rt_lifetime; - imr->imr_lastmseq = rt->rt_lastmseq; - off += sizeof(*imr); - } - MESH_RT_UNLOCK(ms); - error = copyout(p, (uint8_t *)ireq->i_data, - ireq->i_len); - free(p, M_TEMP); - break; - case IEEE80211_MESH_RTCMD_FLUSH: - case IEEE80211_MESH_RTCMD_ADD: - case IEEE80211_MESH_RTCMD_DELETE: - return EINVAL; - default: - return ENOSYS; - } - break; - case IEEE80211_IOC_MESH_PR_METRIC: - len = strlen(ms->ms_pmetric->mpm_descr); - if (ireq->i_len < len) - return EINVAL; - ireq->i_len = len; - error = copyout(ms->ms_pmetric->mpm_descr, - (uint8_t *)ireq->i_data, len); - break; - case IEEE80211_IOC_MESH_PR_PATH: - len = strlen(ms->ms_ppath->mpp_descr); - if (ireq->i_len < len) - return EINVAL; - ireq->i_len = len; - error = copyout(ms->ms_ppath->mpp_descr, - (uint8_t *)ireq->i_data, len); - break; - default: - return ENOSYS; - } - - return error; -} -IEEE80211_IOCTL_GET(mesh, mesh_ioctl_get80211); - -static int -mesh_ioctl_set80211(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - uint8_t tmpmeshid[IEEE80211_NWID_LEN]; - uint8_t tmpaddr[IEEE80211_ADDR_LEN]; - char tmpproto[IEEE80211_MESH_PROTO_DSZ]; - int error; - - if (vap->iv_opmode != IEEE80211_M_MBSS) - return ENOSYS; - - error = 0; - switch (ireq->i_type) { - case IEEE80211_IOC_MESH_ID: - if (ireq->i_val != 0 || ireq->i_len > IEEE80211_MESHID_LEN) - return EINVAL; - error = copyin(ireq->i_data, tmpmeshid, ireq->i_len); - if (error != 0) - break; - memset(ms->ms_id, 0, IEEE80211_NWID_LEN); - ms->ms_idlen = ireq->i_len; - memcpy(ms->ms_id, tmpmeshid, ireq->i_len); - error = ENETRESET; - break; - case IEEE80211_IOC_MESH_AP: - if (ireq->i_val) - ms->ms_flags |= IEEE80211_MESHFLAGS_AP; - else - ms->ms_flags &= ~IEEE80211_MESHFLAGS_AP; - error = ENETRESET; - break; - case IEEE80211_IOC_MESH_FWRD: - if (ireq->i_val) - ms->ms_flags |= IEEE80211_MESHFLAGS_FWD; - else - ms->ms_flags &= ~IEEE80211_MESHFLAGS_FWD; - break; - case IEEE80211_IOC_MESH_TTL: - ms->ms_ttl = (uint8_t) ireq->i_val; - break; - case IEEE80211_IOC_MESH_RTCMD: - switch (ireq->i_val) { - case IEEE80211_MESH_RTCMD_LIST: - return EINVAL; - case IEEE80211_MESH_RTCMD_FLUSH: - ieee80211_mesh_rt_flush(vap); - break; - case IEEE80211_MESH_RTCMD_ADD: - if (IEEE80211_ADDR_EQ(vap->iv_myaddr, ireq->i_data) || - IEEE80211_ADDR_EQ(broadcastaddr, ireq->i_data)) - return EINVAL; - error = copyin(ireq->i_data, &tmpaddr, - IEEE80211_ADDR_LEN); - if (error == 0) - ieee80211_mesh_discover(vap, tmpaddr, NULL); - break; - case IEEE80211_MESH_RTCMD_DELETE: - ieee80211_mesh_rt_del(vap, ireq->i_data); - break; - default: - return ENOSYS; - } - break; - case IEEE80211_IOC_MESH_PR_METRIC: - error = copyin(ireq->i_data, tmpproto, sizeof(tmpproto)); - if (error == 0) { - error = mesh_select_proto_metric(vap, tmpproto); - if (error == 0) - error = ENETRESET; - } - break; - case IEEE80211_IOC_MESH_PR_PATH: - error = copyin(ireq->i_data, tmpproto, sizeof(tmpproto)); - if (error == 0) { - error = mesh_select_proto_path(vap, tmpproto); - if (error == 0) - error = ENETRESET; - } - break; - default: - return ENOSYS; - } - return error; -} -IEEE80211_IOCTL_SET(mesh, mesh_ioctl_set80211); diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_mesh.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_mesh.h deleted file mode 100644 index a748be32f8..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_mesh.h +++ /dev/null @@ -1,503 +0,0 @@ -/*- - * Copyright (c) 2009 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Rui Paulo under sponsorship from the - * FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_MESH_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_MESH_H_ - -#define IEEE80211_MESH_DEFAULT_TTL 31 - -/* - * NB: all structures are __packed so sizeof works on arm, et. al. - */ -/* - * 802.11s Information Elements. -*/ -/* Mesh Configuration */ -struct ieee80211_meshconf_ie { - uint8_t conf_ie; /* IEEE80211_ELEMID_MESHCONF */ - uint8_t conf_len; - uint8_t conf_pselid; /* Active Path Sel. Proto. ID */ - uint8_t conf_pmetid; /* Active Metric Identifier */ - uint8_t conf_ccid; /* Congestion Control Mode ID */ - uint8_t conf_syncid; /* Sync. Protocol ID */ - uint8_t conf_authid; /* Auth. Protocol ID */ - uint8_t conf_form; /* Formation Information */ - uint16_t conf_cap; -} __packed; - -/* Hybrid Wireless Mesh Protocol */ -#define IEEE80211_MESHCONF_PATH_HWMP 0x00 -/* Airtime Link Metric */ -#define IEEE80211_MESHCONF_METRIC_AIRTIME 0x00 -/* Congestion Control */ -#define IEEE80211_MESHCONF_CC_DISABLED 0x00 -#define IEEE80211_MESHCONF_CC_SIG 0x01 -/* Neighbour Offset */ -#define IEEE80211_MESHCONF_SYNC_NEIGHOFF 0x00 -#define IEEE80211_MESHCONF_AUTH_DISABLED 0x00 -/* Simultaneous Authenticaction of Equals */ -#define IEEE80211_MESHCONF_AUTH_SAE 0x01 -#define IEEE80211_MESHCONF_FORM_MP 0x01 /* Connected to Portal */ -#define IEEE80211_MESHCONF_FORM_NNEIGH_MASK 0x04 /* Number of Neighbours */ -#define IEEE80211_MESHCONF_CAP_AP 0x01 /* Accepting Peers */ -#define IEEE80211_MESHCONF_CAP_MCCAS 0x02 /* MCCA supported */ -#define IEEE80211_MESHCONF_CAP_MCCAE 0x04 /* MCCA enabled */ -#define IEEE80211_MESHCONF_CAP_FWRD 0x08 /* forwarding enabled */ -#define IEEE80211_MESHCONF_CAP_BTR 0x10 /* Beacon Timing Report Enab */ -#define IEEE80211_MESHCONF_CAP_TBTTA 0x20 /* TBTT Adj. Enabled */ -#define IEEE80211_MESHCONF_CAP_TBTT 0x40 /* TBTT Adjusting */ -#define IEEE80211_MESHCONF_CAP_PSL 0x80 /* Power Save Level */ - -/* Mesh Identifier */ -struct ieee80211_meshid_ie { - uint8_t id_ie; /* IEEE80211_ELEMID_MESHID */ - uint8_t id_len; -} __packed; - -/* Link Metric Report */ -struct ieee80211_meshlmetric_ie { - uint8_t lm_ie; /* IEEE80211_ELEMID_MESHLINK */ - uint8_t lm_len; - uint32_t lm_metric; -#define IEEE80211_MESHLMETRIC_INITIALVAL 0 -} __packed; - -/* Congestion Notification */ -struct ieee80211_meshcngst_ie { - uint8_t cngst_ie; /* IEEE80211_ELEMID_MESHCNGST */ - uint8_t cngst_len; - uint16_t cngst_timer[4]; /* Expiration Timers: AC_BK, - AC_BE, AC_VI, AC_VO */ -} __packed; - -/* Peer Link Management */ -struct ieee80211_meshpeer_ie { - uint8_t peer_ie; /* IEEE80211_ELEMID_MESHPEER */ - uint8_t peer_len; - uint8_t peer_proto[4]; /* Peer Management Protocol */ - uint16_t peer_llinkid; /* Local Link ID */ - uint16_t peer_linkid; /* Peer Link ID */ - uint16_t peer_rcode; -} __packed; - -enum { - IEEE80211_MESH_PEER_LINK_OPEN = 0, - IEEE80211_MESH_PEER_LINK_CONFIRM = 1, - IEEE80211_MESH_PEER_LINK_CLOSE = 2, - /* values 3-255 are reserved */ -}; - -/* Mesh Peering Management Protocol */ -#define IEEE80211_MESH_PEER_PROTO_OUI 0x00, 0x0f, 0xac -#define IEEE80211_MESH_PEER_PROTO_VALUE 0x2a -#define IEEE80211_MESH_PEER_PROTO { IEEE80211_MESH_PEER_PROTO_OUI, \ - IEEE80211_MESH_PEER_PROTO_VALUE } -/* Abbreviated Handshake Protocol */ -#define IEEE80211_MESH_PEER_PROTO_AH_OUI 0x00, 0x0f, 0xac -#define IEEE80211_MESH_PEER_PROTO_AH_VALUE 0x2b -#define IEEE80211_MESH_PEER_PROTO_AH { IEEE80211_MESH_PEER_PROTO_AH_OUI, \ - IEEE80211_MESH_PEER_PROTO_AH_VALUE } -#ifdef notyet -/* Mesh Channel Switch Annoucement */ -struct ieee80211_meshcsa_ie { - uint8_t csa_ie; /* IEEE80211_ELEMID_MESHCSA */ - uint8_t csa_len; - uint8_t csa_mode; - uint8_t csa_newclass; /* New Regulatory Class */ - uint8_t csa_newchan; - uint8_t csa_precvalue; /* Precedence Value */ - uint8_t csa_count; -} __packed; - -/* Mesh TIM */ -/* Equal to the non Mesh version */ - -/* Mesh Awake Window */ -struct ieee80211_meshawakew_ie { - uint8_t awakew_ie; /* IEEE80211_ELEMID_MESHAWAKEW */ - uint8_t awakew_len; - uint8_t awakew_windowlen; /* in TUs */ -} __packed; - -/* Mesh Beacon Timing */ -struct ieee80211_meshbeacont_ie { - uint8_t beacont_ie; /* IEEE80211_ELEMID_MESHBEACONT */ - uint8_t beacont_len; - struct { - uint8_t mp_aid; /* Least Octet of AID */ - uint16_t mp_btime; /* Beacon Time */ - uint16_t mp_bint; /* Beacon Interval */ - } __packed mp[1]; /* NB: variable size */ -} __packed; -#endif - -/* Portal (MP) Annoucement */ -struct ieee80211_meshpann_ie { - uint8_t pann_ie; /* IEEE80211_ELEMID_MESHPANN */ - uint8_t pann_len; - uint8_t pann_flags; - uint8_t pann_hopcount; - uint8_t pann_ttl; - uint8_t pann_addr[IEEE80211_ADDR_LEN]; - uint8_t pann_seq; /* PANN Sequence Number */ -} __packed; - -/* Root (MP) Annoucement */ -struct ieee80211_meshrann_ie { - uint8_t rann_ie; /* IEEE80211_ELEMID_MESHRANN */ - uint8_t rann_len; - uint8_t rann_flags; -#define IEEE80211_MESHRANN_FLAGS_PR 0x01 /* Portal Role */ - uint8_t rann_hopcount; - uint8_t rann_ttl; - uint8_t rann_addr[IEEE80211_ADDR_LEN]; - uint32_t rann_seq; /* HWMP Sequence Number */ - uint32_t rann_metric; -} __packed; - -/* Mesh Path Request */ -struct ieee80211_meshpreq_ie { - uint8_t preq_ie; /* IEEE80211_ELEMID_MESHPREQ */ - uint8_t preq_len; - uint8_t preq_flags; -#define IEEE80211_MESHPREQ_FLAGS_PR 0x01 /* Portal Role */ -#define IEEE80211_MESHPREQ_FLAGS_AM 0x02 /* 0 = ucast / 1 = bcast */ -#define IEEE80211_MESHPREQ_FLAGS_PP 0x04 /* Proactive PREP */ -#define IEEE80211_MESHPREQ_FLAGS_AE 0x40 /* Address Extension */ - uint8_t preq_hopcount; - uint8_t preq_ttl; - uint32_t preq_id; - uint8_t preq_origaddr[IEEE80211_ADDR_LEN]; - uint32_t preq_origseq; /* HWMP Sequence Number */ - /* NB: may have Originator Proxied Address */ - uint32_t preq_lifetime; - uint32_t preq_metric; - uint8_t preq_tcount; /* target count */ - struct { - uint8_t target_flags; -#define IEEE80211_MESHPREQ_TFLAGS_TO 0x01 /* Target Only */ -#define IEEE80211_MESHPREQ_TFLAGS_RF 0x02 /* Reply and Forward */ -#define IEEE80211_MESHPREQ_TFLAGS_USN 0x04 /* Unknown HWMP seq number */ - uint8_t target_addr[IEEE80211_ADDR_LEN]; - uint32_t target_seq; /* HWMP Sequence Number */ - } __packed preq_targets[1]; /* NB: variable size */ -} __packed; - -/* Mesh Path Reply */ -struct ieee80211_meshprep_ie { - uint8_t prep_ie; /* IEEE80211_ELEMID_MESHPREP */ - uint8_t prep_len; - uint8_t prep_flags; - uint8_t prep_hopcount; - uint8_t prep_ttl; - uint8_t prep_targetaddr[IEEE80211_ADDR_LEN]; - uint32_t prep_targetseq; - /* NB: May have Target Proxied Address */ - uint32_t prep_lifetime; - uint32_t prep_metric; - uint8_t prep_origaddr[IEEE80211_ADDR_LEN]; - uint32_t prep_origseq; /* HWMP Sequence Number */ -} __packed; - -/* Mesh Path Error */ -struct ieee80211_meshperr_ie { - uint8_t perr_ie; /* IEEE80211_ELEMID_MESHPERR */ - uint8_t perr_len; - uint8_t perr_ttl; - uint8_t perr_ndests; /* Number of Destinations */ - struct { - uint8_t dest_flags; -#define IEEE80211_MESHPERR_DFLAGS_USN 0x01 -#define IEEE80211_MESHPERR_DFLAGS_RC 0x02 - uint8_t dest_addr[IEEE80211_ADDR_LEN]; - uint32_t dest_seq; /* HWMP Sequence Number */ - uint16_t dest_rcode; - } __packed perr_dests[1]; /* NB: variable size */ -} __packed; - -#ifdef notyet -/* Mesh Proxy Update */ -struct ieee80211_meshpu_ie { - uint8_t pu_ie; /* IEEE80211_ELEMID_MESHPU */ - uint8_t pu_len; - uint8_t pu_flags; -#define IEEE80211_MESHPU_FLAGS_MASK 0x1 -#define IEEE80211_MESHPU_FLAGS_DEL 0x0 -#define IEEE80211_MESHPU_FLAGS_ADD 0x1 - uint8_t pu_seq; /* PU Sequence Number */ - uint8_t pu_addr[IEEE80211_ADDR_LEN]; - uint8_t pu_naddr; /* Number of Proxied Addresses */ - /* NB: proxied address follows */ -} __packed; - -/* Mesh Proxy Update Confirmation */ -struct ieee80211_meshpuc_ie { - uint8_t puc_ie; /* IEEE80211_ELEMID_MESHPUC */ - uint8_t puc_len; - uint8_t puc_flags; - uint8_t puc_seq; /* PU Sequence Number */ - uint8_t puc_daddr[IEEE80211_ADDR_LEN]; -} __packed; -#endif - -/* - * 802.11s Action Frames - */ -#define IEEE80211_ACTION_CAT_MESHPEERING 30 /* XXX Linux */ -#define IEEE80211_ACTION_CAT_MESHLMETRIC 13 -#define IEEE80211_ACTION_CAT_MESHPATH 32 /* XXX Linux */ -#define IEEE80211_ACTION_CAT_INTERWORK 15 -#define IEEE80211_ACTION_CAT_RESOURCE 16 -#define IEEE80211_ACTION_CAT_PROXY 17 - -/* - * Mesh Peering Action codes. - */ -enum { - IEEE80211_ACTION_MESHPEERING_OPEN = 0, - IEEE80211_ACTION_MESHPEERING_CONFIRM = 1, - IEEE80211_ACTION_MESHPEERING_CLOSE = 2, - /* 3-255 reserved */ -}; - -/* - * Mesh Path Selection Action code. - */ -enum { - IEEE80211_ACTION_MESHPATH_SEL = 0, - /* 1-255 reserved */ -}; - -/* - * Mesh Link Metric Action codes. - */ -enum { - IEEE80211_ACTION_MESHLMETRIC_REQ = 0, /* Link Metric Request */ - IEEE80211_ACTION_MESHLMETRIC_REP = 1, /* Link Metric Report */ - /* 2-255 reserved */ -}; - -/* - * Mesh Portal Annoucement Action codes. - */ -enum { - IEEE80211_ACTION_MESHPANN = 0, - /* 1-255 reserved */ -}; - -/* - * Different mesh control structures based on the AE - * (Address Extension) bits. - */ -struct ieee80211_meshcntl { - uint8_t mc_flags; /* Address Extension 00 */ - uint8_t mc_ttl; /* TTL */ - uint8_t mc_seq[4]; /* Sequence No. */ - /* NB: more addresses may follow */ -} __packed; - -struct ieee80211_meshcntl_ae01 { - uint8_t mc_flags; /* Address Extension 01 */ - uint8_t mc_ttl; /* TTL */ - uint8_t mc_seq[4]; /* Sequence No. */ - uint8_t mc_addr4[IEEE80211_ADDR_LEN]; -} __packed; - -struct ieee80211_meshcntl_ae10 { - uint8_t mc_flags; /* Address Extension 10 */ - uint8_t mc_ttl; /* TTL */ - uint8_t mc_seq[4]; /* Sequence No. */ - uint8_t mc_addr4[IEEE80211_ADDR_LEN]; - uint8_t mc_addr5[IEEE80211_ADDR_LEN]; -} __packed; - -struct ieee80211_meshcntl_ae11 { - uint8_t mc_flags; /* Address Extension 11 */ - uint8_t mc_ttl; /* TTL */ - uint8_t mc_seq[4]; /* Sequence No. */ - uint8_t mc_addr4[IEEE80211_ADDR_LEN]; - uint8_t mc_addr5[IEEE80211_ADDR_LEN]; - uint8_t mc_addr6[IEEE80211_ADDR_LEN]; -} __packed; - -#ifdef _KERNEL -struct ieee80211_mesh_route { - TAILQ_ENTRY(ieee80211_mesh_route) rt_next; - int rt_crtime; /* creation time */ - uint8_t rt_dest[IEEE80211_ADDR_LEN]; - uint8_t rt_nexthop[IEEE80211_ADDR_LEN]; - uint32_t rt_metric; /* path metric */ - uint16_t rt_nhops; /* number of hops */ - uint16_t rt_flags; -#define IEEE80211_MESHRT_FLAGS_VALID 0x01 /* patch discovery complete */ -#define IEEE80211_MESHRT_FLAGS_PROXY 0x02 /* proxy entry */ - uint32_t rt_lifetime; - uint32_t rt_lastmseq; /* last seq# seen dest */ - void *rt_priv; /* private data */ -}; -#define IEEE80211_MESH_ROUTE_PRIV(rt, cast) ((cast *)rt->rt_priv) - -#define IEEE80211_MESH_PROTO_DSZ 12 /* description size */ -/* - * Mesh Path Selection Protocol. - */ -enum ieee80211_state; -struct ieee80211_mesh_proto_path { - uint8_t mpp_active; - char mpp_descr[IEEE80211_MESH_PROTO_DSZ]; - uint8_t mpp_ie; - struct ieee80211_node * - (*mpp_discover)(struct ieee80211vap *, - const uint8_t [IEEE80211_ADDR_LEN], - struct mbuf *); - void (*mpp_peerdown)(struct ieee80211_node *); - void (*mpp_vattach)(struct ieee80211vap *); - void (*mpp_vdetach)(struct ieee80211vap *); - int (*mpp_newstate)(struct ieee80211vap *, - enum ieee80211_state, int); - const size_t mpp_privlen; /* size required in the routing table - for private data */ - int mpp_inact; /* inact. timeout for invalid routes - (ticks) */ -}; - -/* - * Mesh Link Metric Report Protocol. - */ -struct ieee80211_mesh_proto_metric { - uint8_t mpm_active; - char mpm_descr[IEEE80211_MESH_PROTO_DSZ]; - uint8_t mpm_ie; - uint32_t (*mpm_metric)(struct ieee80211_node *); -}; - -#ifdef notyet -/* - * Mesh Authentication Protocol. - */ -struct ieee80211_mesh_proto_auth { - uint8_t mpa_ie[4]; -}; - -struct ieee80211_mesh_proto_congestion { -}; - -struct ieee80211_mesh_proto_sync { -}; -#endif - -typedef uint32_t ieee80211_mesh_seq; -#define IEEE80211_MESH_SEQ_LEQ(a, b) ((int32_t)((a)-(b)) <= 0) -#define IEEE80211_MESH_SEQ_GEQ(a, b) ((int32_t)((a)-(b)) >= 0) - -struct ieee80211_mesh_state { - int ms_idlen; - uint8_t ms_id[IEEE80211_MESHID_LEN]; - ieee80211_mesh_seq ms_seq; /* seq no for meshcntl */ - uint16_t ms_neighbors; - uint8_t ms_ttl; /* mesh ttl set in packets */ -#define IEEE80211_MESHFLAGS_AP 0x01 /* accept peers */ -#define IEEE80211_MESHFLAGS_PORTAL 0x02 /* mesh portal role */ -#define IEEE80211_MESHFLAGS_FWD 0x04 /* forward packets */ - uint8_t ms_flags; - struct mtx ms_rt_lock; - struct callout ms_cleantimer; - TAILQ_HEAD(, ieee80211_mesh_route) ms_routes; - struct ieee80211_mesh_proto_metric *ms_pmetric; - struct ieee80211_mesh_proto_path *ms_ppath; -}; -void ieee80211_mesh_attach(struct ieee80211com *); -void ieee80211_mesh_detach(struct ieee80211com *); - -struct ieee80211_mesh_route * - ieee80211_mesh_rt_find(struct ieee80211vap *, - const uint8_t [IEEE80211_ADDR_LEN]); -struct ieee80211_mesh_route * - ieee80211_mesh_rt_add(struct ieee80211vap *, - const uint8_t [IEEE80211_ADDR_LEN]); -void ieee80211_mesh_rt_del(struct ieee80211vap *, - const uint8_t [IEEE80211_ADDR_LEN]); -void ieee80211_mesh_rt_flush(struct ieee80211vap *); -void ieee80211_mesh_rt_flush_peer(struct ieee80211vap *, - const uint8_t [IEEE80211_ADDR_LEN]); -void ieee80211_mesh_proxy_check(struct ieee80211vap *, - const uint8_t [IEEE80211_ADDR_LEN]); - -int ieee80211_mesh_register_proto_path(const - struct ieee80211_mesh_proto_path *); -int ieee80211_mesh_register_proto_metric(const - struct ieee80211_mesh_proto_metric *); - -uint8_t * ieee80211_add_meshid(uint8_t *, struct ieee80211vap *); -uint8_t * ieee80211_add_meshconf(uint8_t *, struct ieee80211vap *); -uint8_t * ieee80211_add_meshpeer(uint8_t *, uint8_t, uint16_t, uint16_t, - uint16_t); -uint8_t * ieee80211_add_meshlmetric(uint8_t *, uint32_t); - -void ieee80211_mesh_node_init(struct ieee80211vap *, - struct ieee80211_node *); -void ieee80211_mesh_node_cleanup(struct ieee80211_node *); -void ieee80211_parse_meshid(struct ieee80211_node *, - const uint8_t *); -struct ieee80211_scanparams; -void ieee80211_mesh_init_neighbor(struct ieee80211_node *, - const struct ieee80211_frame *, - const struct ieee80211_scanparams *); -void ieee80211_mesh_update_beacon(struct ieee80211vap *, - struct ieee80211_beacon_offsets *); - -/* - * Return non-zero if proxy operation is enabled. - */ -static __inline int -ieee80211_mesh_isproxyena(struct ieee80211vap *vap) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - return (ms->ms_flags & - (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_PORTAL)) != 0; -} - -/* - * Process an outbound frame: if a path is known to the - * destination then return a reference to the next hop - * for immediate transmission. Otherwise initiate path - * discovery and, if possible queue the packet to be - * sent when path discovery completes. - */ -static __inline struct ieee80211_node * -ieee80211_mesh_discover(struct ieee80211vap *vap, - const uint8_t dest[IEEE80211_ADDR_LEN], struct mbuf *m) -{ - struct ieee80211_mesh_state *ms = vap->iv_mesh; - return ms->ms_ppath->mpp_discover(vap, dest, m); -} - -#endif /* _KERNEL */ -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_MESH_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_monitor.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_monitor.c deleted file mode 100644 index e32408172f..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_monitor.c +++ /dev/null @@ -1,138 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifdef __FreeBSD__ -__FBSDID("$FreeBSD$"); -#endif - -/* - * IEEE 802.11 Monitor mode support. - */ -#include "opt_inet.h" -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include - -static void monitor_vattach(struct ieee80211vap *); -static int monitor_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int monitor_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int nf); - -void -ieee80211_monitor_attach(struct ieee80211com *ic) -{ - ic->ic_vattach[IEEE80211_M_MONITOR] = monitor_vattach; -} - -void -ieee80211_monitor_detach(struct ieee80211com *ic) -{ -} - -static void -monitor_vdetach(struct ieee80211vap *vap) -{ -} - -static void -monitor_vattach(struct ieee80211vap *vap) -{ - vap->iv_newstate = monitor_newstate; - vap->iv_input = monitor_input; - vap->iv_opdetach = monitor_vdetach; -} - -/* - * IEEE80211_M_MONITOR vap state machine handler. - */ -static int -monitor_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct ieee80211com *ic = vap->iv_ic; - enum ieee80211_state ostate; - - IEEE80211_LOCK_ASSERT(ic); - - ostate = vap->iv_state; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n", - __func__, ieee80211_state_name[ostate], - ieee80211_state_name[nstate], arg); - vap->iv_state = nstate; /* state transition */ - if (nstate == IEEE80211_S_RUN) { - switch (ostate) { - case IEEE80211_S_INIT: - ieee80211_create_ibss(vap, ic->ic_curchan); - break; - default: - break; - } - /* - * NB: this shouldn't be here but many people use - * monitor mode for raw packets; once we switch - * them over to adhoc demo mode remove this. - */ - ieee80211_node_authorize(vap->iv_bss); - } - return 0; -} - -/* - * Process a received frame in monitor mode. - */ -static int -monitor_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ifnet *ifp = vap->iv_ifp; - - ifp->if_ipackets++; - - if (ieee80211_radiotap_active_vap(vap)) - ieee80211_radiotap_rx(vap, m); - m_freem(m); - return -1; -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_monitor.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_monitor.h deleted file mode 100644 index d62154342b..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_monitor.h +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_MONITOR_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_MONITOR_H_ - -/* - * Monitor implementation definitions. - */ -void ieee80211_monitor_attach(struct ieee80211com *); -void ieee80211_monitor_detach(struct ieee80211com *); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_MONITOR_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_node.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_node.c deleted file mode 100644 index 1cbff9618b..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_node.c +++ /dev/null @@ -1,2652 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#ifdef IEEE80211_SUPPORT_SUPERG -#include -#endif -#ifdef IEEE80211_SUPPORT_TDMA -#include -#endif -#include -#include -#include - -#include - -/* - * IEEE80211_NODE_HASHSIZE must be a power of 2. - */ -CTASSERT((IEEE80211_NODE_HASHSIZE & (IEEE80211_NODE_HASHSIZE-1)) == 0); - -/* - * Association id's are managed with a bit vector. - */ -#define IEEE80211_AID_SET(_vap, b) \ - ((_vap)->iv_aid_bitmap[IEEE80211_AID(b) / 32] |= \ - (1 << (IEEE80211_AID(b) % 32))) -#define IEEE80211_AID_CLR(_vap, b) \ - ((_vap)->iv_aid_bitmap[IEEE80211_AID(b) / 32] &= \ - ~(1 << (IEEE80211_AID(b) % 32))) -#define IEEE80211_AID_ISSET(_vap, b) \ - ((_vap)->iv_aid_bitmap[IEEE80211_AID(b) / 32] & (1 << (IEEE80211_AID(b) % 32))) - -#ifdef IEEE80211_DEBUG_REFCNT -#define REFCNT_LOC "%s (%s:%u) %p<%s> refcnt %d\n", __func__, func, line -#else -#define REFCNT_LOC "%s %p<%s> refcnt %d\n", __func__ -#endif - -static int ieee80211_sta_join1(struct ieee80211_node *); - -static struct ieee80211_node *node_alloc(struct ieee80211vap *, - const uint8_t [IEEE80211_ADDR_LEN]); -static void node_cleanup(struct ieee80211_node *); -static void node_free(struct ieee80211_node *); -static void node_age(struct ieee80211_node *); -static int8_t node_getrssi(const struct ieee80211_node *); -static void node_getsignal(const struct ieee80211_node *, int8_t *, int8_t *); -static void node_getmimoinfo(const struct ieee80211_node *, - struct ieee80211_mimo_info *); - -static void _ieee80211_free_node(struct ieee80211_node *); - -static void ieee80211_node_table_init(struct ieee80211com *ic, - struct ieee80211_node_table *nt, const char *name, - int inact, int keymaxix); -static void ieee80211_node_table_reset(struct ieee80211_node_table *, - struct ieee80211vap *); -static void ieee80211_node_table_cleanup(struct ieee80211_node_table *nt); -static void ieee80211_erp_timeout(struct ieee80211com *); - -void -ieee80211_node_attach(struct ieee80211com *ic) -{ - /* XXX really want maxlen enforced per-sta */ - ieee80211_ageq_init(&ic->ic_stageq, ic->ic_max_keyix * 8, - "802.11 staging q"); - ieee80211_node_table_init(ic, &ic->ic_sta, "station", - IEEE80211_INACT_INIT, ic->ic_max_keyix); - callout_init(&ic->ic_inact, CALLOUT_MPSAFE); - callout_reset(&ic->ic_inact, IEEE80211_INACT_WAIT*hz, - ieee80211_node_timeout, ic); - - ic->ic_node_alloc = node_alloc; - ic->ic_node_free = node_free; - ic->ic_node_cleanup = node_cleanup; - ic->ic_node_age = node_age; - ic->ic_node_drain = node_age; /* NB: same as age */ - ic->ic_node_getrssi = node_getrssi; - ic->ic_node_getsignal = node_getsignal; - ic->ic_node_getmimoinfo = node_getmimoinfo; - - /* - * Set flags to be propagated to all vap's; - * these define default behaviour/configuration. - */ - ic->ic_flags_ext |= IEEE80211_FEXT_INACT; /* inactivity processing */ -} - -void -ieee80211_node_detach(struct ieee80211com *ic) -{ - - callout_drain(&ic->ic_inact); - ieee80211_node_table_cleanup(&ic->ic_sta); - ieee80211_ageq_cleanup(&ic->ic_stageq); -} - -void -ieee80211_node_vattach(struct ieee80211vap *vap) -{ - /* NB: driver can override */ - vap->iv_max_aid = IEEE80211_AID_DEF; - - /* default station inactivity timer setings */ - vap->iv_inact_init = IEEE80211_INACT_INIT; - vap->iv_inact_auth = IEEE80211_INACT_AUTH; - vap->iv_inact_run = IEEE80211_INACT_RUN; - vap->iv_inact_probe = IEEE80211_INACT_PROBE; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_INACT, - "%s: init %u auth %u run %u probe %u\n", __func__, - vap->iv_inact_init, vap->iv_inact_auth, - vap->iv_inact_run, vap->iv_inact_probe); -} - -void -ieee80211_node_latevattach(struct ieee80211vap *vap) -{ - if (vap->iv_opmode == IEEE80211_M_HOSTAP) { - /* XXX should we allow max aid to be zero? */ - if (vap->iv_max_aid < IEEE80211_AID_MIN) { - vap->iv_max_aid = IEEE80211_AID_MIN; - if_printf(vap->iv_ifp, - "WARNING: max aid too small, changed to %d\n", - vap->iv_max_aid); - } - vap->iv_aid_bitmap = (uint32_t *) malloc( - howmany(vap->iv_max_aid, 32) * sizeof(uint32_t), - M_80211_NODE, M_NOWAIT | M_ZERO); - if (vap->iv_aid_bitmap == NULL) { - /* XXX no way to recover */ - printf("%s: no memory for AID bitmap, max aid %d!\n", - __func__, vap->iv_max_aid); - vap->iv_max_aid = 0; - } - } - - ieee80211_reset_bss(vap); - - vap->iv_auth = ieee80211_authenticator_get(vap->iv_bss->ni_authmode); -} - -void -ieee80211_node_vdetach(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - - ieee80211_node_table_reset(&ic->ic_sta, vap); - if (vap->iv_bss != NULL) { - ieee80211_free_node(vap->iv_bss); - vap->iv_bss = NULL; - } - if (vap->iv_aid_bitmap != NULL) { - free(vap->iv_aid_bitmap, M_80211_NODE); - vap->iv_aid_bitmap = NULL; - } -} - -/* - * Port authorize/unauthorize interfaces for use by an authenticator. - */ - -void -ieee80211_node_authorize(struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - - ni->ni_flags |= IEEE80211_NODE_AUTH; - ni->ni_inact_reload = vap->iv_inact_run; - ni->ni_inact = ni->ni_inact_reload; - - IEEE80211_NOTE(vap, IEEE80211_MSG_INACT, ni, - "%s: inact_reload %u", __func__, ni->ni_inact_reload); -} - -void -ieee80211_node_unauthorize(struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - - ni->ni_flags &= ~IEEE80211_NODE_AUTH; - ni->ni_inact_reload = vap->iv_inact_auth; - if (ni->ni_inact > ni->ni_inact_reload) - ni->ni_inact = ni->ni_inact_reload; - - IEEE80211_NOTE(vap, IEEE80211_MSG_INACT, ni, - "%s: inact_reload %u inact %u", __func__, - ni->ni_inact_reload, ni->ni_inact); -} - -/* - * Fix tx parameters for a node according to ``association state''. - */ -void -ieee80211_node_setuptxparms(struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - enum ieee80211_phymode mode; - - if (ni->ni_flags & IEEE80211_NODE_HT) { - if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) - mode = IEEE80211_MODE_11NA; - else - mode = IEEE80211_MODE_11NG; - } else { /* legacy rate handling */ - if (IEEE80211_IS_CHAN_ST(ni->ni_chan)) - mode = IEEE80211_MODE_STURBO_A; - else if (IEEE80211_IS_CHAN_HALF(ni->ni_chan)) - mode = IEEE80211_MODE_HALF; - else if (IEEE80211_IS_CHAN_QUARTER(ni->ni_chan)) - mode = IEEE80211_MODE_QUARTER; - /* NB: 108A should be handled as 11a */ - else if (IEEE80211_IS_CHAN_A(ni->ni_chan)) - mode = IEEE80211_MODE_11A; - else if (IEEE80211_IS_CHAN_108G(ni->ni_chan) || - (ni->ni_flags & IEEE80211_NODE_ERP)) - mode = IEEE80211_MODE_11G; - else - mode = IEEE80211_MODE_11B; - } - ni->ni_txparms = &vap->iv_txparms[mode]; -} - -/* - * Set/change the channel. The rate set is also updated as - * to insure a consistent view by drivers. - * XXX should be private but hostap needs it to deal with CSA - */ -void -ieee80211_node_set_chan(struct ieee80211_node *ni, - struct ieee80211_channel *chan) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211vap *vap = ni->ni_vap; - enum ieee80211_phymode mode; - - KASSERT(chan != IEEE80211_CHAN_ANYC, ("no channel")); - - ni->ni_chan = chan; - mode = ieee80211_chan2mode(chan); - if (IEEE80211_IS_CHAN_HT(chan)) { - /* - * We must install the legacy rate est in ni_rates and the - * HT rate set in ni_htrates. - */ - ni->ni_htrates = *ieee80211_get_suphtrates(ic, chan); - /* - * Setup bss tx parameters based on operating mode. We - * use legacy rates when operating in a mixed HT+non-HT bss - * and non-ERP rates in 11g for mixed ERP+non-ERP bss. - */ - if (mode == IEEE80211_MODE_11NA && - (vap->iv_flags_ht & IEEE80211_FHT_PUREN) == 0) - mode = IEEE80211_MODE_11A; - else if (mode == IEEE80211_MODE_11NG && - (vap->iv_flags_ht & IEEE80211_FHT_PUREN) == 0) - mode = IEEE80211_MODE_11G; - if (mode == IEEE80211_MODE_11G && - (vap->iv_flags & IEEE80211_F_PUREG) == 0) - mode = IEEE80211_MODE_11B; - } - ni->ni_txparms = &vap->iv_txparms[mode]; - ni->ni_rates = *ieee80211_get_suprates(ic, chan); -} - -static __inline void -copy_bss(struct ieee80211_node *nbss, const struct ieee80211_node *obss) -{ - /* propagate useful state */ - nbss->ni_authmode = obss->ni_authmode; - nbss->ni_txpower = obss->ni_txpower; - nbss->ni_vlan = obss->ni_vlan; - /* XXX statistics? */ - /* XXX legacy WDS bssid? */ -} - -void -ieee80211_create_ibss(struct ieee80211vap* vap, struct ieee80211_channel *chan) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: creating %s on channel %u\n", __func__, - ieee80211_opmode_name[vap->iv_opmode], - ieee80211_chan2ieee(ic, chan)); - - ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr); - if (ni == NULL) { - /* XXX recovery? */ - return; - } - IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_myaddr); - ni->ni_esslen = vap->iv_des_ssid[0].len; - memcpy(ni->ni_essid, vap->iv_des_ssid[0].ssid, ni->ni_esslen); - if (vap->iv_bss != NULL) - copy_bss(ni, vap->iv_bss); - ni->ni_intval = ic->ic_bintval; - if (vap->iv_flags & IEEE80211_F_PRIVACY) - ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY; - if (ic->ic_phytype == IEEE80211_T_FH) { - ni->ni_fhdwell = 200; /* XXX */ - ni->ni_fhindex = 1; - } - if (vap->iv_opmode == IEEE80211_M_IBSS) { - vap->iv_flags |= IEEE80211_F_SIBSS; - ni->ni_capinfo |= IEEE80211_CAPINFO_IBSS; /* XXX */ - if (vap->iv_flags & IEEE80211_F_DESBSSID) - IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_des_bssid); - else { - get_random_bytes(ni->ni_bssid, IEEE80211_ADDR_LEN); - /* clear group bit, add local bit */ - ni->ni_bssid[0] = (ni->ni_bssid[0] &~ 0x01) | 0x02; - } - } else if (vap->iv_opmode == IEEE80211_M_AHDEMO) { - if (vap->iv_flags & IEEE80211_F_DESBSSID) - IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_des_bssid); - else -#ifdef IEEE80211_SUPPORT_TDMA - if ((vap->iv_caps & IEEE80211_C_TDMA) == 0) -#endif - memset(ni->ni_bssid, 0, IEEE80211_ADDR_LEN); -#ifdef IEEE80211_SUPPORT_MESH - } else if (vap->iv_opmode == IEEE80211_M_MBSS) { - ni->ni_meshidlen = vap->iv_mesh->ms_idlen; - memcpy(ni->ni_meshid, vap->iv_mesh->ms_id, ni->ni_meshidlen); -#endif - } - /* - * Fix the channel and related attributes. - */ - /* clear DFS CAC state on previous channel */ - if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && - ic->ic_bsschan->ic_freq != chan->ic_freq && - IEEE80211_IS_CHAN_CACDONE(ic->ic_bsschan)) - ieee80211_dfs_cac_clear(ic, ic->ic_bsschan); - ic->ic_bsschan = chan; - ieee80211_node_set_chan(ni, chan); - ic->ic_curmode = ieee80211_chan2mode(chan); - /* - * Do mode-specific setup. - */ - if (IEEE80211_IS_CHAN_FULL(chan)) { - if (IEEE80211_IS_CHAN_ANYG(chan)) { - /* - * Use a mixed 11b/11g basic rate set. - */ - ieee80211_setbasicrates(&ni->ni_rates, - IEEE80211_MODE_11G); - if (vap->iv_flags & IEEE80211_F_PUREG) { - /* - * Also mark OFDM rates basic so 11b - * stations do not join (WiFi compliance). - */ - ieee80211_addbasicrates(&ni->ni_rates, - IEEE80211_MODE_11A); - } - } else if (IEEE80211_IS_CHAN_B(chan)) { - /* - * Force pure 11b rate set. - */ - ieee80211_setbasicrates(&ni->ni_rates, - IEEE80211_MODE_11B); - } - } - - (void) ieee80211_sta_join1(ieee80211_ref_node(ni)); -} - -/* - * Reset bss state on transition to the INIT state. - * Clear any stations from the table (they have been - * deauth'd) and reset the bss node (clears key, rate - * etc. state). - */ -void -ieee80211_reset_bss(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni, *obss; - - ieee80211_node_table_reset(&ic->ic_sta, vap); - /* XXX multi-bss: wrong */ - ieee80211_reset_erp(ic); - - ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr); - KASSERT(ni != NULL, ("unable to setup initial BSS node")); - obss = vap->iv_bss; - vap->iv_bss = ieee80211_ref_node(ni); - if (obss != NULL) { - copy_bss(ni, obss); - ni->ni_intval = ic->ic_bintval; - ieee80211_free_node(obss); - } else - IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_myaddr); -} - -static int -match_ssid(const struct ieee80211_node *ni, - int nssid, const struct ieee80211_scan_ssid ssids[]) -{ - int i; - - for (i = 0; i < nssid; i++) { - if (ni->ni_esslen == ssids[i].len && - memcmp(ni->ni_essid, ssids[i].ssid, ni->ni_esslen) == 0) - return 1; - } - return 0; -} - -/* - * Test a node for suitability/compatibility. - */ -static int -check_bss(struct ieee80211vap *vap, struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - uint8_t rate; - - if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ni->ni_chan))) - return 0; - if (vap->iv_opmode == IEEE80211_M_IBSS) { - if ((ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) == 0) - return 0; - } else { - if ((ni->ni_capinfo & IEEE80211_CAPINFO_ESS) == 0) - return 0; - } - if (vap->iv_flags & IEEE80211_F_PRIVACY) { - if ((ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0) - return 0; - } else { - /* XXX does this mean privacy is supported or required? */ - if (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) - return 0; - } - rate = ieee80211_fix_rate(ni, &ni->ni_rates, - IEEE80211_F_JOIN | IEEE80211_F_DONEGO | IEEE80211_F_DOFRATE); - if (rate & IEEE80211_RATE_BASIC) - return 0; - if (vap->iv_des_nssid != 0 && - !match_ssid(ni, vap->iv_des_nssid, vap->iv_des_ssid)) - return 0; - if ((vap->iv_flags & IEEE80211_F_DESBSSID) && - !IEEE80211_ADDR_EQ(vap->iv_des_bssid, ni->ni_bssid)) - return 0; - return 1; -} - -#ifdef IEEE80211_DEBUG -/* - * Display node suitability/compatibility. - */ -static void -check_bss_debug(struct ieee80211vap *vap, struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - uint8_t rate; - int fail; - - fail = 0; - if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ni->ni_chan))) - fail |= 0x01; - if (vap->iv_opmode == IEEE80211_M_IBSS) { - if ((ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) == 0) - fail |= 0x02; - } else { - if ((ni->ni_capinfo & IEEE80211_CAPINFO_ESS) == 0) - fail |= 0x02; - } - if (vap->iv_flags & IEEE80211_F_PRIVACY) { - if ((ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0) - fail |= 0x04; - } else { - /* XXX does this mean privacy is supported or required? */ - if (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) - fail |= 0x04; - } - rate = ieee80211_fix_rate(ni, &ni->ni_rates, - IEEE80211_F_JOIN | IEEE80211_F_DONEGO | IEEE80211_F_DOFRATE); - if (rate & IEEE80211_RATE_BASIC) - fail |= 0x08; - if (vap->iv_des_nssid != 0 && - !match_ssid(ni, vap->iv_des_nssid, vap->iv_des_ssid)) - fail |= 0x10; - if ((vap->iv_flags & IEEE80211_F_DESBSSID) && - !IEEE80211_ADDR_EQ(vap->iv_des_bssid, ni->ni_bssid)) - fail |= 0x20; - - printf(" %c %s", fail ? '-' : '+', ether_sprintf(ni->ni_macaddr)); - printf(" %s%c", ether_sprintf(ni->ni_bssid), fail & 0x20 ? '!' : ' '); - printf(" %3d%c", - ieee80211_chan2ieee(ic, ni->ni_chan), fail & 0x01 ? '!' : ' '); - printf(" %2dM%c", (rate & IEEE80211_RATE_VAL) / 2, - fail & 0x08 ? '!' : ' '); - printf(" %4s%c", - (ni->ni_capinfo & IEEE80211_CAPINFO_ESS) ? "ess" : - (ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" : - "????", - fail & 0x02 ? '!' : ' '); - printf(" %3s%c ", - (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) ? "wep" : "no", - fail & 0x04 ? '!' : ' '); - ieee80211_print_essid(ni->ni_essid, ni->ni_esslen); - printf("%s\n", fail & 0x10 ? "!" : ""); -} -#endif /* IEEE80211_DEBUG */ - -/* - * Handle 802.11 ad hoc network merge. The - * convention, set by the Wireless Ethernet Compatibility Alliance - * (WECA), is that an 802.11 station will change its BSSID to match - * the "oldest" 802.11 ad hoc network, on the same channel, that - * has the station's desired SSID. The "oldest" 802.11 network - * sends beacons with the greatest TSF timestamp. - * - * The caller is assumed to validate TSF's before attempting a merge. - * - * Return !0 if the BSSID changed, 0 otherwise. - */ -int -ieee80211_ibss_merge(struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; -#ifdef IEEE80211_DEBUG - struct ieee80211com *ic = ni->ni_ic; -#endif - - if (ni == vap->iv_bss || - IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) { - /* unchanged, nothing to do */ - return 0; - } - if (!check_bss(vap, ni)) { - /* capabilities mismatch */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC, - "%s: merge failed, capabilities mismatch\n", __func__); -#ifdef IEEE80211_DEBUG - if (ieee80211_msg_assoc(vap)) - check_bss_debug(vap, ni); -#endif - vap->iv_stats.is_ibss_capmismatch++; - return 0; - } - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC, - "%s: new bssid %s: %s preamble, %s slot time%s\n", __func__, - ether_sprintf(ni->ni_bssid), - ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long", - ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long", - ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "" - ); - return ieee80211_sta_join1(ieee80211_ref_node(ni)); -} - -/* - * Calculate HT channel promotion flags for all vaps. - * This assumes ni_chan have been setup for each vap. - */ -static int -gethtadjustflags(struct ieee80211com *ic) -{ - struct ieee80211vap *vap; - int flags; - - flags = 0; - /* XXX locking */ - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - if (vap->iv_state < IEEE80211_S_RUN) - continue; - switch (vap->iv_opmode) { - case IEEE80211_M_WDS: - case IEEE80211_M_STA: - case IEEE80211_M_AHDEMO: - case IEEE80211_M_HOSTAP: - case IEEE80211_M_IBSS: - case IEEE80211_M_MBSS: - flags |= ieee80211_htchanflags(vap->iv_bss->ni_chan); - break; - default: - break; - } - } - return flags; -} - -/* - * Check if the current channel needs to change based on whether - * any vap's are using HT20/HT40. This is used to sync the state - * of ic_curchan after a channel width change on a running vap. - */ -void -ieee80211_sync_curchan(struct ieee80211com *ic) -{ - struct ieee80211_channel *c; - - c = ieee80211_ht_adjust_channel(ic, ic->ic_curchan, gethtadjustflags(ic)); - if (c != ic->ic_curchan) { - ic->ic_curchan = c; - ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan); - ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan); - IEEE80211_UNLOCK(ic); - ic->ic_set_channel(ic); - ieee80211_radiotap_chan_change(ic); - IEEE80211_LOCK(ic); - } -} - -/* - * Setup the current channel. The request channel may be - * promoted if other vap's are operating with HT20/HT40. - */ -void -ieee80211_setupcurchan(struct ieee80211com *ic, struct ieee80211_channel *c) -{ - if (ic->ic_htcaps & IEEE80211_HTC_HT) { - int flags = gethtadjustflags(ic); - /* - * Check for channel promotion required to support the - * set of running vap's. This assumes we are called - * after ni_chan is setup for each vap. - */ - /* NB: this assumes IEEE80211_FHT_USEHT40 > IEEE80211_FHT_HT */ - if (flags > ieee80211_htchanflags(c)) - c = ieee80211_ht_adjust_channel(ic, c, flags); - } - ic->ic_bsschan = ic->ic_curchan = c; - ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan); - ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan); -} - -/* - * Change the current channel. The channel change is guaranteed to have - * happened before the next state change. - */ -void -ieee80211_setcurchan(struct ieee80211com *ic, struct ieee80211_channel *c) -{ - ieee80211_setupcurchan(ic, c); - ieee80211_runtask(ic, &ic->ic_chan_task); -} - -/* - * Join the specified IBSS/BSS network. The node is assumed to - * be passed in with a held reference. - */ -static int -ieee80211_sta_join1(struct ieee80211_node *selbs) -{ - struct ieee80211vap *vap = selbs->ni_vap; - struct ieee80211com *ic = selbs->ni_ic; - struct ieee80211_node *obss; - int canreassoc; - - /* - * Committed to selbs, setup state. - */ - obss = vap->iv_bss; - /* - * Check if old+new node have the same address in which - * case we can reassociate when operating in sta mode. - */ - canreassoc = (obss != NULL && - vap->iv_state == IEEE80211_S_RUN && - IEEE80211_ADDR_EQ(obss->ni_macaddr, selbs->ni_macaddr)); - vap->iv_bss = selbs; /* NB: caller assumed to bump refcnt */ - if (obss != NULL) { - copy_bss(selbs, obss); - ieee80211_node_decref(obss); /* iv_bss reference */ - ieee80211_free_node(obss); /* station table reference */ - obss = NULL; /* NB: guard against later use */ - } - - /* - * Delete unusable rates; we've already checked - * that the negotiated rate set is acceptable. - */ - ieee80211_fix_rate(vap->iv_bss, &vap->iv_bss->ni_rates, - IEEE80211_F_DODEL | IEEE80211_F_JOIN); - - ieee80211_setcurchan(ic, selbs->ni_chan); - /* - * Set the erp state (mostly the slot time) to deal with - * the auto-select case; this should be redundant if the - * mode is locked. - */ - ieee80211_reset_erp(ic); - ieee80211_wme_initparams(vap); - - if (vap->iv_opmode == IEEE80211_M_STA) { - if (canreassoc) { - /* Reassociate */ - ieee80211_new_state(vap, IEEE80211_S_ASSOC, 1); - } else { - /* - * Act as if we received a DEAUTH frame in case we - * are invoked from the RUN state. This will cause - * us to try to re-authenticate if we are operating - * as a station. - */ - ieee80211_new_state(vap, IEEE80211_S_AUTH, - IEEE80211_FC0_SUBTYPE_DEAUTH); - } - } else - ieee80211_new_state(vap, IEEE80211_S_RUN, -1); - return 1; -} - -int -ieee80211_sta_join(struct ieee80211vap *vap, struct ieee80211_channel *chan, - const struct ieee80211_scan_entry *se) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni; - - ni = ieee80211_alloc_node(&ic->ic_sta, vap, se->se_macaddr); - if (ni == NULL) { - /* XXX msg */ - return 0; - } - /* - * Expand scan state into node's format. - * XXX may not need all this stuff - */ - IEEE80211_ADDR_COPY(ni->ni_bssid, se->se_bssid); - ni->ni_esslen = se->se_ssid[1]; - memcpy(ni->ni_essid, se->se_ssid+2, ni->ni_esslen); - ni->ni_tstamp.tsf = se->se_tstamp.tsf; - ni->ni_intval = se->se_intval; - ni->ni_capinfo = se->se_capinfo; - ni->ni_chan = chan; - ni->ni_timoff = se->se_timoff; - ni->ni_fhdwell = se->se_fhdwell; - ni->ni_fhindex = se->se_fhindex; - ni->ni_erp = se->se_erp; - IEEE80211_RSSI_LPF(ni->ni_avgrssi, se->se_rssi); - ni->ni_noise = se->se_noise; - if (vap->iv_opmode == IEEE80211_M_STA) { - /* NB: only infrastructure mode requires an associd */ - ni->ni_flags |= IEEE80211_NODE_ASSOCID; - } - - if (ieee80211_ies_init(&ni->ni_ies, se->se_ies.data, se->se_ies.len)) { - ieee80211_ies_expand(&ni->ni_ies); -#ifdef IEEE80211_SUPPORT_SUPERG - if (ni->ni_ies.ath_ie != NULL) - ieee80211_parse_ath(ni, ni->ni_ies.ath_ie); -#endif - if (ni->ni_ies.htcap_ie != NULL) - ieee80211_parse_htcap(ni, ni->ni_ies.htcap_ie); - if (ni->ni_ies.htinfo_ie != NULL) - ieee80211_parse_htinfo(ni, ni->ni_ies.htinfo_ie); -#ifdef IEEE80211_SUPPORT_MESH - if (ni->ni_ies.meshid_ie != NULL) - ieee80211_parse_meshid(ni, ni->ni_ies.meshid_ie); -#endif -#ifdef IEEE80211_SUPPORT_TDMA - if (ni->ni_ies.tdma_ie != NULL) - ieee80211_parse_tdma(ni, ni->ni_ies.tdma_ie); -#endif - } - - vap->iv_dtim_period = se->se_dtimperiod; - vap->iv_dtim_count = 0; - - /* NB: must be after ni_chan is setup */ - ieee80211_setup_rates(ni, se->se_rates, se->se_xrates, - IEEE80211_F_DOSORT); - if (ieee80211_iserp_rateset(&ni->ni_rates)) - ni->ni_flags |= IEEE80211_NODE_ERP; - ieee80211_node_setuptxparms(ni); - ieee80211_ratectl_node_init(ni); - - return ieee80211_sta_join1(ieee80211_ref_node(ni)); -} - -/* - * Leave the specified IBSS/BSS network. The node is assumed to - * be passed in with a held reference. - */ -void -ieee80211_sta_leave(struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - - ic->ic_node_cleanup(ni); - ieee80211_notify_node_leave(ni); -} - -/* - * Send a deauthenticate frame and drop the station. - */ -void -ieee80211_node_deauth(struct ieee80211_node *ni, int reason) -{ - /* NB: bump the refcnt to be sure temporay nodes are not reclaimed */ - ieee80211_ref_node(ni); - if (ni->ni_associd != 0) - IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DEAUTH, reason); - ieee80211_node_leave(ni); - ieee80211_free_node(ni); -} - -static struct ieee80211_node * -node_alloc(struct ieee80211vap *vap, const uint8_t macaddr[IEEE80211_ADDR_LEN]) -{ - struct ieee80211_node *ni; - - ni = (struct ieee80211_node *) malloc(sizeof(struct ieee80211_node), - M_80211_NODE, M_NOWAIT | M_ZERO); - return ni; -} - -/* - * Initialize an ie blob with the specified data. If previous - * data exists re-use the data block. As a side effect we clear - * all references to specific ie's; the caller is required to - * recalculate them. - */ -int -ieee80211_ies_init(struct ieee80211_ies *ies, const uint8_t *data, int len) -{ - /* NB: assumes data+len are the last fields */ - memset(ies, 0, offsetof(struct ieee80211_ies, data)); - if (ies->data != NULL && ies->len != len) { - /* data size changed */ - free(ies->data, M_80211_NODE_IE); - ies->data = NULL; - } - if (ies->data == NULL) { - ies->data = (uint8_t *) malloc(len, M_80211_NODE_IE, M_NOWAIT); - if (ies->data == NULL) { - ies->len = 0; - /* NB: pointers have already been zero'd above */ - return 0; - } - } - memcpy(ies->data, data, len); - ies->len = len; - return 1; -} - -/* - * Reclaim storage for an ie blob. - */ -void -ieee80211_ies_cleanup(struct ieee80211_ies *ies) -{ - if (ies->data != NULL) - free(ies->data, M_80211_NODE_IE); -} - -/* - * Expand an ie blob data contents and to fillin individual - * ie pointers. The data blob is assumed to be well-formed; - * we don't do any validity checking of ie lengths. - */ -void -ieee80211_ies_expand(struct ieee80211_ies *ies) -{ - uint8_t *ie; - int ielen; - - ie = ies->data; - ielen = ies->len; - while (ielen > 0) { - switch (ie[0]) { - case IEEE80211_ELEMID_VENDOR: - if (iswpaoui(ie)) - ies->wpa_ie = ie; - else if (iswmeoui(ie)) - ies->wme_ie = ie; -#ifdef IEEE80211_SUPPORT_SUPERG - else if (isatherosoui(ie)) - ies->ath_ie = ie; -#endif -#ifdef IEEE80211_SUPPORT_TDMA - else if (istdmaoui(ie)) - ies->tdma_ie = ie; -#endif - break; - case IEEE80211_ELEMID_RSN: - ies->rsn_ie = ie; - break; - case IEEE80211_ELEMID_HTCAP: - ies->htcap_ie = ie; - break; -#ifdef IEEE80211_SUPPORT_MESH - case IEEE80211_ELEMID_MESHID: - ies->meshid_ie = ie; - break; -#endif - } - ielen -= 2 + ie[1]; - ie += 2 + ie[1]; - } -} - -/* - * Reclaim any resources in a node and reset any critical - * state. Typically nodes are free'd immediately after, - * but in some cases the storage may be reused so we need - * to insure consistent state (should probably fix that). - */ -static void -node_cleanup(struct ieee80211_node *ni) -{ -#define N(a) (sizeof(a)/sizeof(a[0])) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - int i; - - /* NB: preserve ni_table */ - if (ni->ni_flags & IEEE80211_NODE_PWR_MGT) { - if (vap->iv_opmode != IEEE80211_M_STA) - vap->iv_ps_sta--; - ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; - IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, - "power save mode off, %u sta's in ps mode", vap->iv_ps_sta); - } - /* - * Cleanup any HT-related state. - */ - if (ni->ni_flags & IEEE80211_NODE_HT) - ieee80211_ht_node_cleanup(ni); -#ifdef IEEE80211_SUPPORT_SUPERG - else if (ni->ni_ath_flags & IEEE80211_NODE_ATH) - ieee80211_ff_node_cleanup(ni); -#endif -#ifdef IEEE80211_SUPPORT_MESH - /* - * Cleanup any mesh-related state. - */ - if (vap->iv_opmode == IEEE80211_M_MBSS) - ieee80211_mesh_node_cleanup(ni); -#endif - /* - * Clear any staging queue entries. - */ - ieee80211_ageq_drain_node(&ic->ic_stageq, ni); - - /* - * Clear AREF flag that marks the authorization refcnt bump - * has happened. This is probably not needed as the node - * should always be removed from the table so not found but - * do it just in case. - * Likewise clear the ASSOCID flag as these flags are intended - * to be managed in tandem. - */ - ni->ni_flags &= ~(IEEE80211_NODE_AREF | IEEE80211_NODE_ASSOCID); - - /* - * Drain power save queue and, if needed, clear TIM. - */ - if (ieee80211_node_psq_drain(ni) != 0 && vap->iv_set_tim != NULL) - vap->iv_set_tim(ni, 0); - - ni->ni_associd = 0; - if (ni->ni_challenge != NULL) { - free(ni->ni_challenge, M_80211_NODE); - ni->ni_challenge = NULL; - } - /* - * Preserve SSID, WPA, and WME ie's so the bss node is - * reusable during a re-auth/re-assoc state transition. - * If we remove these data they will not be recreated - * because they come from a probe-response or beacon frame - * which cannot be expected prior to the association-response. - * This should not be an issue when operating in other modes - * as stations leaving always go through a full state transition - * which will rebuild this state. - * - * XXX does this leave us open to inheriting old state? - */ - for (i = 0; i < N(ni->ni_rxfrag); i++) - if (ni->ni_rxfrag[i] != NULL) { - m_freem(ni->ni_rxfrag[i]); - ni->ni_rxfrag[i] = NULL; - } - /* - * Must be careful here to remove any key map entry w/o a LOR. - */ - ieee80211_node_delucastkey(ni); -#undef N -} - -static void -node_free(struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - - ieee80211_ratectl_node_deinit(ni); - ic->ic_node_cleanup(ni); - ieee80211_ies_cleanup(&ni->ni_ies); - ieee80211_psq_cleanup(&ni->ni_psq); - free(ni, M_80211_NODE); -} - -static void -node_age(struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - - IEEE80211_NODE_LOCK_ASSERT(&vap->iv_ic->ic_sta); - - /* - * Age frames on the power save queue. - */ - if (ieee80211_node_psq_age(ni) != 0 && - ni->ni_psq.psq_len == 0 && vap->iv_set_tim != NULL) - vap->iv_set_tim(ni, 0); - /* - * Age out HT resources (e.g. frames on the - * A-MPDU reorder queues). - */ - if (ni->ni_associd != 0 && (ni->ni_flags & IEEE80211_NODE_HT)) - ieee80211_ht_node_age(ni); -} - -static int8_t -node_getrssi(const struct ieee80211_node *ni) -{ - uint32_t avgrssi = ni->ni_avgrssi; - int32_t rssi; - - if (avgrssi == IEEE80211_RSSI_DUMMY_MARKER) - return 0; - rssi = IEEE80211_RSSI_GET(avgrssi); - return rssi < 0 ? 0 : rssi > 127 ? 127 : rssi; -} - -static void -node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise) -{ - *rssi = node_getrssi(ni); - *noise = ni->ni_noise; -} - -static void -node_getmimoinfo(const struct ieee80211_node *ni, - struct ieee80211_mimo_info *info) -{ - int i; - uint32_t avgrssi; - int32_t rssi; - - bzero(info, sizeof(*info)); - - for (i = 0; i < ni->ni_mimo_chains; i++) { - avgrssi = ni->ni_mimo_rssi_ctl[i]; - if (avgrssi == IEEE80211_RSSI_DUMMY_MARKER) { - info->rssi[i] = 0; - } else { - rssi = IEEE80211_RSSI_GET(avgrssi); - info->rssi[i] = rssi < 0 ? 0 : rssi > 127 ? 127 : rssi; - } - info->noise[i] = ni->ni_mimo_noise_ctl[i]; - } - - /* XXX ext radios? */ - - /* XXX EVM? */ -} - -struct ieee80211_node * -ieee80211_alloc_node(struct ieee80211_node_table *nt, - struct ieee80211vap *vap, const uint8_t macaddr[IEEE80211_ADDR_LEN]) -{ - struct ieee80211com *ic = nt->nt_ic; - struct ieee80211_node *ni; - int hash; - - ni = ic->ic_node_alloc(vap, macaddr); - if (ni == NULL) { - vap->iv_stats.is_rx_nodealloc++; - return NULL; - } - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "%s %p<%s> in %s table\n", __func__, ni, - ether_sprintf(macaddr), nt->nt_name); - - IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr); - hash = IEEE80211_NODE_HASH(ic, macaddr); - ieee80211_node_initref(ni); /* mark referenced */ - ni->ni_chan = IEEE80211_CHAN_ANYC; - ni->ni_authmode = IEEE80211_AUTH_OPEN; - ni->ni_txpower = ic->ic_txpowlimit; /* max power */ - ni->ni_txparms = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; - ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE); - ni->ni_avgrssi = IEEE80211_RSSI_DUMMY_MARKER; - ni->ni_inact_reload = nt->nt_inact_init; - ni->ni_inact = ni->ni_inact_reload; - ni->ni_ath_defkeyix = 0x7fff; - ieee80211_psq_init(&ni->ni_psq, "unknown"); -#ifdef IEEE80211_SUPPORT_MESH - if (vap->iv_opmode == IEEE80211_M_MBSS) - ieee80211_mesh_node_init(vap, ni); -#endif - IEEE80211_NODE_LOCK(nt); - TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list); - LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash); - ni->ni_table = nt; - ni->ni_vap = vap; - ni->ni_ic = ic; - IEEE80211_NODE_UNLOCK(nt); - - IEEE80211_NOTE(vap, IEEE80211_MSG_INACT, ni, - "%s: inact_reload %u", __func__, ni->ni_inact_reload); - - ieee80211_ratectl_node_init(ni); - - return ni; -} - -/* - * Craft a temporary node suitable for sending a management frame - * to the specified station. We craft only as much state as we - * need to do the work since the node will be immediately reclaimed - * once the send completes. - */ -struct ieee80211_node * -ieee80211_tmp_node(struct ieee80211vap *vap, - const uint8_t macaddr[IEEE80211_ADDR_LEN]) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni; - - ni = ic->ic_node_alloc(vap, macaddr); - if (ni != NULL) { - struct ieee80211_node *bss = vap->iv_bss; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "%s %p<%s>\n", __func__, ni, ether_sprintf(macaddr)); - - ni->ni_table = NULL; /* NB: pedantic */ - ni->ni_ic = ic; /* NB: needed to set channel */ - ni->ni_vap = vap; - - IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr); - IEEE80211_ADDR_COPY(ni->ni_bssid, bss->ni_bssid); - ieee80211_node_initref(ni); /* mark referenced */ - /* NB: required by ieee80211_fix_rate */ - ieee80211_node_set_chan(ni, bss->ni_chan); - ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, - IEEE80211_KEYIX_NONE); - ni->ni_txpower = bss->ni_txpower; - /* XXX optimize away */ - ieee80211_psq_init(&ni->ni_psq, "unknown"); - - ieee80211_ratectl_node_init(ni); - } else { - /* XXX msg */ - vap->iv_stats.is_rx_nodealloc++; - } - return ni; -} - -struct ieee80211_node * -ieee80211_dup_bss(struct ieee80211vap *vap, - const uint8_t macaddr[IEEE80211_ADDR_LEN]) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni; - - ni = ieee80211_alloc_node(&ic->ic_sta, vap, macaddr); - if (ni != NULL) { - struct ieee80211_node *bss = vap->iv_bss; - /* - * Inherit from iv_bss. - */ - copy_bss(ni, bss); - IEEE80211_ADDR_COPY(ni->ni_bssid, bss->ni_bssid); - ieee80211_node_set_chan(ni, bss->ni_chan); - } - return ni; -} - -/* - * Create a bss node for a legacy WDS vap. The far end does - * not associate so we just create create a new node and - * simulate an association. The caller is responsible for - * installing the node as the bss node and handling any further - * setup work like authorizing the port. - */ -struct ieee80211_node * -ieee80211_node_create_wds(struct ieee80211vap *vap, - const uint8_t bssid[IEEE80211_ADDR_LEN], struct ieee80211_channel *chan) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni; - - /* XXX check if node already in sta table? */ - ni = ieee80211_alloc_node(&ic->ic_sta, vap, bssid); - if (ni != NULL) { - ni->ni_wdsvap = vap; - IEEE80211_ADDR_COPY(ni->ni_bssid, bssid); - /* - * Inherit any manually configured settings. - */ - copy_bss(ni, vap->iv_bss); - ieee80211_node_set_chan(ni, chan); - /* NB: propagate ssid so available to WPA supplicant */ - ni->ni_esslen = vap->iv_des_ssid[0].len; - memcpy(ni->ni_essid, vap->iv_des_ssid[0].ssid, ni->ni_esslen); - /* NB: no associd for peer */ - /* - * There are no management frames to use to - * discover neighbor capabilities, so blindly - * propagate the local configuration. - */ - if (vap->iv_flags & IEEE80211_F_WME) - ni->ni_flags |= IEEE80211_NODE_QOS; -#ifdef IEEE80211_SUPPORT_SUPERG - if (vap->iv_flags & IEEE80211_F_FF) - ni->ni_flags |= IEEE80211_NODE_FF; -#endif - if ((ic->ic_htcaps & IEEE80211_HTC_HT) && - (vap->iv_flags_ht & IEEE80211_FHT_HT)) { - /* - * Device is HT-capable and HT is enabled for - * the vap; setup HT operation. On return - * ni_chan will be adjusted to an HT channel. - */ - ieee80211_ht_wds_init(ni); - } else { - struct ieee80211_channel *c = ni->ni_chan; - /* - * Force a legacy channel to be used. - */ - c = ieee80211_find_channel(ic, - c->ic_freq, c->ic_flags &~ IEEE80211_CHAN_HT); - KASSERT(c != NULL, ("no legacy channel, %u/%x", - ni->ni_chan->ic_freq, ni->ni_chan->ic_flags)); - ni->ni_chan = c; - } - } - return ni; -} - -struct ieee80211_node * -#ifdef IEEE80211_DEBUG_REFCNT -ieee80211_find_node_locked_debug(struct ieee80211_node_table *nt, - const uint8_t macaddr[IEEE80211_ADDR_LEN], const char *func, int line) -#else -ieee80211_find_node_locked(struct ieee80211_node_table *nt, - const uint8_t macaddr[IEEE80211_ADDR_LEN]) -#endif -{ - struct ieee80211_node *ni; - int hash; - - IEEE80211_NODE_LOCK_ASSERT(nt); - - hash = IEEE80211_NODE_HASH(nt->nt_ic, macaddr); - LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) { - if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) { - ieee80211_ref_node(ni); /* mark referenced */ -#ifdef IEEE80211_DEBUG_REFCNT - IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE, - "%s (%s:%u) %p<%s> refcnt %d\n", __func__, - func, line, - ni, ether_sprintf(ni->ni_macaddr), - ieee80211_node_refcnt(ni)); -#endif - return ni; - } - } - return NULL; -} - -struct ieee80211_node * -#ifdef IEEE80211_DEBUG_REFCNT -ieee80211_find_node_debug(struct ieee80211_node_table *nt, - const uint8_t macaddr[IEEE80211_ADDR_LEN], const char *func, int line) -#else -ieee80211_find_node(struct ieee80211_node_table *nt, - const uint8_t macaddr[IEEE80211_ADDR_LEN]) -#endif -{ - struct ieee80211_node *ni; - - IEEE80211_NODE_LOCK(nt); - ni = ieee80211_find_node_locked(nt, macaddr); - IEEE80211_NODE_UNLOCK(nt); - return ni; -} - -struct ieee80211_node * -#ifdef IEEE80211_DEBUG_REFCNT -ieee80211_find_vap_node_locked_debug(struct ieee80211_node_table *nt, - const struct ieee80211vap *vap, - const uint8_t macaddr[IEEE80211_ADDR_LEN], const char *func, int line) -#else -ieee80211_find_vap_node_locked(struct ieee80211_node_table *nt, - const struct ieee80211vap *vap, - const uint8_t macaddr[IEEE80211_ADDR_LEN]) -#endif -{ - struct ieee80211_node *ni; - int hash; - - IEEE80211_NODE_LOCK_ASSERT(nt); - - hash = IEEE80211_NODE_HASH(nt->nt_ic, macaddr); - LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) { - if (ni->ni_vap == vap && - IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) { - ieee80211_ref_node(ni); /* mark referenced */ -#ifdef IEEE80211_DEBUG_REFCNT - IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE, - "%s (%s:%u) %p<%s> refcnt %d\n", __func__, - func, line, - ni, ether_sprintf(ni->ni_macaddr), - ieee80211_node_refcnt(ni)); -#endif - return ni; - } - } - return NULL; -} - -struct ieee80211_node * -#ifdef IEEE80211_DEBUG_REFCNT -ieee80211_find_vap_node_debug(struct ieee80211_node_table *nt, - const struct ieee80211vap *vap, - const uint8_t macaddr[IEEE80211_ADDR_LEN], const char *func, int line) -#else -ieee80211_find_vap_node(struct ieee80211_node_table *nt, - const struct ieee80211vap *vap, - const uint8_t macaddr[IEEE80211_ADDR_LEN]) -#endif -{ - struct ieee80211_node *ni; - - IEEE80211_NODE_LOCK(nt); - ni = ieee80211_find_vap_node_locked(nt, vap, macaddr); - IEEE80211_NODE_UNLOCK(nt); - return ni; -} - -/* - * Fake up a node; this handles node discovery in adhoc mode. - * Note that for the driver's benefit we we treat this like - * an association so the driver has an opportunity to setup - * it's private state. - */ -struct ieee80211_node * -ieee80211_fakeup_adhoc_node(struct ieee80211vap *vap, - const uint8_t macaddr[IEEE80211_ADDR_LEN]) -{ - struct ieee80211_node *ni; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "%s: mac<%s>\n", __func__, ether_sprintf(macaddr)); - ni = ieee80211_dup_bss(vap, macaddr); - if (ni != NULL) { - struct ieee80211com *ic = vap->iv_ic; - - /* XXX no rate negotiation; just dup */ - ni->ni_rates = vap->iv_bss->ni_rates; - if (ieee80211_iserp_rateset(&ni->ni_rates)) - ni->ni_flags |= IEEE80211_NODE_ERP; - if (vap->iv_opmode == IEEE80211_M_AHDEMO) { - /* - * In adhoc demo mode there are no management - * frames to use to discover neighbor capabilities, - * so blindly propagate the local configuration - * so we can do interesting things (e.g. use - * WME to disable ACK's). - */ - if (vap->iv_flags & IEEE80211_F_WME) - ni->ni_flags |= IEEE80211_NODE_QOS; -#ifdef IEEE80211_SUPPORT_SUPERG - if (vap->iv_flags & IEEE80211_F_FF) - ni->ni_flags |= IEEE80211_NODE_FF; -#endif - } - ieee80211_node_setuptxparms(ni); - ieee80211_ratectl_node_init(ni); - if (ic->ic_newassoc != NULL) - ic->ic_newassoc(ni, 1); - /* XXX not right for 802.1x/WPA */ - ieee80211_node_authorize(ni); - } - return ni; -} - -void -ieee80211_init_neighbor(struct ieee80211_node *ni, - const struct ieee80211_frame *wh, - const struct ieee80211_scanparams *sp) -{ - ni->ni_esslen = sp->ssid[1]; - memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]); - IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); - memcpy(ni->ni_tstamp.data, sp->tstamp, sizeof(ni->ni_tstamp)); - ni->ni_intval = sp->bintval; - ni->ni_capinfo = sp->capinfo; - ni->ni_chan = ni->ni_ic->ic_curchan; - ni->ni_fhdwell = sp->fhdwell; - ni->ni_fhindex = sp->fhindex; - ni->ni_erp = sp->erp; - ni->ni_timoff = sp->timoff; -#ifdef IEEE80211_SUPPORT_MESH - if (ni->ni_vap->iv_opmode == IEEE80211_M_MBSS) - ieee80211_mesh_init_neighbor(ni, wh, sp); -#endif - if (ieee80211_ies_init(&ni->ni_ies, sp->ies, sp->ies_len)) { - ieee80211_ies_expand(&ni->ni_ies); - if (ni->ni_ies.wme_ie != NULL) - ni->ni_flags |= IEEE80211_NODE_QOS; - else - ni->ni_flags &= ~IEEE80211_NODE_QOS; -#ifdef IEEE80211_SUPPORT_SUPERG - if (ni->ni_ies.ath_ie != NULL) - ieee80211_parse_ath(ni, ni->ni_ies.ath_ie); -#endif - } - - /* NB: must be after ni_chan is setup */ - ieee80211_setup_rates(ni, sp->rates, sp->xrates, - IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | - IEEE80211_F_DONEGO | IEEE80211_F_DODEL); -} - -/* - * Do node discovery in adhoc mode on receipt of a beacon - * or probe response frame. Note that for the driver's - * benefit we we treat this like an association so the - * driver has an opportunity to setup it's private state. - */ -struct ieee80211_node * -ieee80211_add_neighbor(struct ieee80211vap *vap, - const struct ieee80211_frame *wh, - const struct ieee80211_scanparams *sp) -{ - struct ieee80211_node *ni; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "%s: mac<%s>\n", __func__, ether_sprintf(wh->i_addr2)); - ni = ieee80211_dup_bss(vap, wh->i_addr2);/* XXX alloc_node? */ - if (ni != NULL) { - struct ieee80211com *ic = vap->iv_ic; - - ieee80211_init_neighbor(ni, wh, sp); - if (ieee80211_iserp_rateset(&ni->ni_rates)) - ni->ni_flags |= IEEE80211_NODE_ERP; - ieee80211_node_setuptxparms(ni); - ieee80211_ratectl_node_init(ni); - if (ic->ic_newassoc != NULL) - ic->ic_newassoc(ni, 1); - /* XXX not right for 802.1x/WPA */ - ieee80211_node_authorize(ni); - } - return ni; -} - -#define IS_PROBEREQ(wh) \ - ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK|IEEE80211_FC0_SUBTYPE_MASK)) \ - == (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ)) -#define IS_BCAST_PROBEREQ(wh) \ - (IS_PROBEREQ(wh) && IEEE80211_IS_MULTICAST( \ - ((const struct ieee80211_frame *)(wh))->i_addr3)) - -static __inline struct ieee80211_node * -_find_rxnode(struct ieee80211_node_table *nt, - const struct ieee80211_frame_min *wh) -{ - if (IS_BCAST_PROBEREQ(wh)) - return NULL; /* spam bcast probe req to all vap's */ - return ieee80211_find_node_locked(nt, wh->i_addr2); -} - -/* - * Locate the node for sender, track state, and then pass the - * (referenced) node up to the 802.11 layer for its use. Note - * we can return NULL if the sender is not in the table. - */ -struct ieee80211_node * -#ifdef IEEE80211_DEBUG_REFCNT -ieee80211_find_rxnode_debug(struct ieee80211com *ic, - const struct ieee80211_frame_min *wh, const char *func, int line) -#else -ieee80211_find_rxnode(struct ieee80211com *ic, - const struct ieee80211_frame_min *wh) -#endif -{ - struct ieee80211_node_table *nt; - struct ieee80211_node *ni; - - nt = &ic->ic_sta; - IEEE80211_NODE_LOCK(nt); - ni = _find_rxnode(nt, wh); - IEEE80211_NODE_UNLOCK(nt); - - return ni; -} - -/* - * Like ieee80211_find_rxnode but use the supplied h/w - * key index as a hint to locate the node in the key - * mapping table. If an entry is present at the key - * index we return it; otherwise do a normal lookup and - * update the mapping table if the station has a unicast - * key assigned to it. - */ -struct ieee80211_node * -#ifdef IEEE80211_DEBUG_REFCNT -ieee80211_find_rxnode_withkey_debug(struct ieee80211com *ic, - const struct ieee80211_frame_min *wh, ieee80211_keyix keyix, - const char *func, int line) -#else -ieee80211_find_rxnode_withkey(struct ieee80211com *ic, - const struct ieee80211_frame_min *wh, ieee80211_keyix keyix) -#endif -{ - struct ieee80211_node_table *nt; - struct ieee80211_node *ni; - - nt = &ic->ic_sta; - IEEE80211_NODE_LOCK(nt); - if (nt->nt_keyixmap != NULL && keyix < nt->nt_keyixmax) - ni = nt->nt_keyixmap[keyix]; - else - ni = NULL; - if (ni == NULL) { - ni = _find_rxnode(nt, wh); - if (ni != NULL && nt->nt_keyixmap != NULL) { - /* - * If the station has a unicast key cache slot - * assigned update the key->node mapping table. - */ - keyix = ni->ni_ucastkey.wk_rxkeyix; - /* XXX can keyixmap[keyix] != NULL? */ - if (keyix < nt->nt_keyixmax && - nt->nt_keyixmap[keyix] == NULL) { - IEEE80211_DPRINTF(ni->ni_vap, - IEEE80211_MSG_NODE, - "%s: add key map entry %p<%s> refcnt %d\n", - __func__, ni, ether_sprintf(ni->ni_macaddr), - ieee80211_node_refcnt(ni)+1); - nt->nt_keyixmap[keyix] = ieee80211_ref_node(ni); - } - } - } else { - if (IS_BCAST_PROBEREQ(wh)) - ni = NULL; /* spam bcast probe req to all vap's */ - else - ieee80211_ref_node(ni); - } - IEEE80211_NODE_UNLOCK(nt); - - return ni; -} -#undef IS_BCAST_PROBEREQ -#undef IS_PROBEREQ - -/* - * Return a reference to the appropriate node for sending - * a data frame. This handles node discovery in adhoc networks. - */ -struct ieee80211_node * -#ifdef IEEE80211_DEBUG_REFCNT -ieee80211_find_txnode_debug(struct ieee80211vap *vap, - const uint8_t macaddr[IEEE80211_ADDR_LEN], - const char *func, int line) -#else -ieee80211_find_txnode(struct ieee80211vap *vap, - const uint8_t macaddr[IEEE80211_ADDR_LEN]) -#endif -{ - struct ieee80211_node_table *nt = &vap->iv_ic->ic_sta; - struct ieee80211_node *ni; - - /* - * The destination address should be in the node table - * unless this is a multicast/broadcast frame. We can - * also optimize station mode operation, all frames go - * to the bss node. - */ - /* XXX can't hold lock across dup_bss 'cuz of recursive locking */ - IEEE80211_NODE_LOCK(nt); - if (vap->iv_opmode == IEEE80211_M_STA || - vap->iv_opmode == IEEE80211_M_WDS || - IEEE80211_IS_MULTICAST(macaddr)) - ni = ieee80211_ref_node(vap->iv_bss); - else - ni = ieee80211_find_node_locked(nt, macaddr); - IEEE80211_NODE_UNLOCK(nt); - - if (ni == NULL) { - if (vap->iv_opmode == IEEE80211_M_IBSS || - vap->iv_opmode == IEEE80211_M_AHDEMO) { - /* - * In adhoc mode cons up a node for the destination. - * Note that we need an additional reference for the - * caller to be consistent with - * ieee80211_find_node_locked. - */ - ni = ieee80211_fakeup_adhoc_node(vap, macaddr); - if (ni != NULL) - (void) ieee80211_ref_node(ni); - } else { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_OUTPUT, macaddr, - "no node, discard frame (%s)", __func__); - vap->iv_stats.is_tx_nonode++; - } - } - return ni; -} - -static void -_ieee80211_free_node(struct ieee80211_node *ni) -{ - struct ieee80211_node_table *nt = ni->ni_table; - - /* - * NB: careful about referencing the vap as it may be - * gone if the last reference was held by a driver. - * We know the com will always be present so it's safe - * to use ni_ic below to reclaim resources. - */ -#if 0 - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "%s %p<%s> in %s table\n", __func__, ni, - ether_sprintf(ni->ni_macaddr), - nt != NULL ? nt->nt_name : ""); -#endif - if (ni->ni_associd != 0) { - struct ieee80211vap *vap = ni->ni_vap; - if (vap->iv_aid_bitmap != NULL) - IEEE80211_AID_CLR(vap, ni->ni_associd); - } - if (nt != NULL) { - TAILQ_REMOVE(&nt->nt_node, ni, ni_list); - LIST_REMOVE(ni, ni_hash); - } - ni->ni_ic->ic_node_free(ni); -} - -void -#ifdef IEEE80211_DEBUG_REFCNT -ieee80211_free_node_debug(struct ieee80211_node *ni, const char *func, int line) -#else -ieee80211_free_node(struct ieee80211_node *ni) -#endif -{ - struct ieee80211_node_table *nt = ni->ni_table; - -#ifdef IEEE80211_DEBUG_REFCNT - IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE, - "%s (%s:%u) %p<%s> refcnt %d\n", __func__, func, line, ni, - ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)-1); -#endif - if (nt != NULL) { - IEEE80211_NODE_LOCK(nt); - if (ieee80211_node_dectestref(ni)) { - /* - * Last reference, reclaim state. - */ - _ieee80211_free_node(ni); - } else if (ieee80211_node_refcnt(ni) == 1 && - nt->nt_keyixmap != NULL) { - ieee80211_keyix keyix; - /* - * Check for a last reference in the key mapping table. - */ - keyix = ni->ni_ucastkey.wk_rxkeyix; - if (keyix < nt->nt_keyixmax && - nt->nt_keyixmap[keyix] == ni) { - IEEE80211_DPRINTF(ni->ni_vap, - IEEE80211_MSG_NODE, - "%s: %p<%s> clear key map entry", __func__, - ni, ether_sprintf(ni->ni_macaddr)); - nt->nt_keyixmap[keyix] = NULL; - ieee80211_node_decref(ni); /* XXX needed? */ - _ieee80211_free_node(ni); - } - } - IEEE80211_NODE_UNLOCK(nt); - } else { - if (ieee80211_node_dectestref(ni)) - _ieee80211_free_node(ni); - } -} - -/* - * Reclaim a unicast key and clear any key cache state. - */ -int -ieee80211_node_delucastkey(struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_node_table *nt = &ic->ic_sta; - struct ieee80211_node *nikey; - ieee80211_keyix keyix; - int isowned, status; - - /* - * NB: We must beware of LOR here; deleting the key - * can cause the crypto layer to block traffic updates - * which can generate a LOR against the node table lock; - * grab it here and stash the key index for our use below. - * - * Must also beware of recursion on the node table lock. - * When called from node_cleanup we may already have - * the node table lock held. Unfortunately there's no - * way to separate out this path so we must do this - * conditionally. - */ - isowned = IEEE80211_NODE_IS_LOCKED(nt); - if (!isowned) - IEEE80211_NODE_LOCK(nt); - nikey = NULL; - status = 1; /* NB: success */ - if (ni->ni_ucastkey.wk_keyix != IEEE80211_KEYIX_NONE) { - keyix = ni->ni_ucastkey.wk_rxkeyix; - status = ieee80211_crypto_delkey(ni->ni_vap, &ni->ni_ucastkey); - if (nt->nt_keyixmap != NULL && keyix < nt->nt_keyixmax) { - nikey = nt->nt_keyixmap[keyix]; - nt->nt_keyixmap[keyix] = NULL; - } - } - if (!isowned) - IEEE80211_NODE_UNLOCK(nt); - - if (nikey != NULL) { - KASSERT(nikey == ni, - ("key map out of sync, ni %p nikey %p", ni, nikey)); - IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE, - "%s: delete key map entry %p<%s> refcnt %d\n", - __func__, ni, ether_sprintf(ni->ni_macaddr), - ieee80211_node_refcnt(ni)-1); - ieee80211_free_node(ni); - } - return status; -} - -/* - * Reclaim a node. If this is the last reference count then - * do the normal free work. Otherwise remove it from the node - * table and mark it gone by clearing the back-reference. - */ -static void -node_reclaim(struct ieee80211_node_table *nt, struct ieee80211_node *ni) -{ - ieee80211_keyix keyix; - - IEEE80211_NODE_LOCK_ASSERT(nt); - - IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE, - "%s: remove %p<%s> from %s table, refcnt %d\n", - __func__, ni, ether_sprintf(ni->ni_macaddr), - nt->nt_name, ieee80211_node_refcnt(ni)-1); - /* - * Clear any entry in the unicast key mapping table. - * We need to do it here so rx lookups don't find it - * in the mapping table even if it's not in the hash - * table. We cannot depend on the mapping table entry - * being cleared because the node may not be free'd. - */ - keyix = ni->ni_ucastkey.wk_rxkeyix; - if (nt->nt_keyixmap != NULL && keyix < nt->nt_keyixmax && - nt->nt_keyixmap[keyix] == ni) { - IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE, - "%s: %p<%s> clear key map entry %u\n", - __func__, ni, ether_sprintf(ni->ni_macaddr), keyix); - nt->nt_keyixmap[keyix] = NULL; - ieee80211_node_decref(ni); /* NB: don't need free */ - } - if (!ieee80211_node_dectestref(ni)) { - /* - * Other references are present, just remove the - * node from the table so it cannot be found. When - * the references are dropped storage will be - * reclaimed. - */ - TAILQ_REMOVE(&nt->nt_node, ni, ni_list); - LIST_REMOVE(ni, ni_hash); - ni->ni_table = NULL; /* clear reference */ - } else - _ieee80211_free_node(ni); -} - -/* - * Node table support. - */ - -static void -ieee80211_node_table_init(struct ieee80211com *ic, - struct ieee80211_node_table *nt, - const char *name, int inact, int keyixmax) -{ - struct ifnet *ifp = ic->ic_ifp; - - nt->nt_ic = ic; - IEEE80211_NODE_LOCK_INIT(nt, ifp->if_xname); - IEEE80211_NODE_ITERATE_LOCK_INIT(nt, ifp->if_xname); - TAILQ_INIT(&nt->nt_node); - nt->nt_name = name; - nt->nt_scangen = 1; - nt->nt_inact_init = inact; - nt->nt_keyixmax = keyixmax; - if (nt->nt_keyixmax > 0) { - nt->nt_keyixmap = (struct ieee80211_node **) malloc( - keyixmax * sizeof(struct ieee80211_node *), - M_80211_NODE, M_NOWAIT | M_ZERO); - if (nt->nt_keyixmap == NULL) - if_printf(ic->ic_ifp, - "Cannot allocate key index map with %u entries\n", - keyixmax); - } else - nt->nt_keyixmap = NULL; -} - -static void -ieee80211_node_table_reset(struct ieee80211_node_table *nt, - struct ieee80211vap *match) -{ - struct ieee80211_node *ni, *next; - - IEEE80211_NODE_LOCK(nt); - TAILQ_FOREACH_SAFE(ni, &nt->nt_node, ni_list, next) { - if (match != NULL && ni->ni_vap != match) - continue; - /* XXX can this happen? if so need's work */ - if (ni->ni_associd != 0) { - struct ieee80211vap *vap = ni->ni_vap; - - if (vap->iv_auth->ia_node_leave != NULL) - vap->iv_auth->ia_node_leave(ni); - if (vap->iv_aid_bitmap != NULL) - IEEE80211_AID_CLR(vap, ni->ni_associd); - } - ni->ni_wdsvap = NULL; /* clear reference */ - node_reclaim(nt, ni); - } - if (match != NULL && match->iv_opmode == IEEE80211_M_WDS) { - /* - * Make a separate pass to clear references to this vap - * held by DWDS entries. They will not be matched above - * because ni_vap will point to the ap vap but we still - * need to clear ni_wdsvap when the WDS vap is destroyed - * and/or reset. - */ - TAILQ_FOREACH_SAFE(ni, &nt->nt_node, ni_list, next) - if (ni->ni_wdsvap == match) - ni->ni_wdsvap = NULL; - } - IEEE80211_NODE_UNLOCK(nt); -} - -static void -ieee80211_node_table_cleanup(struct ieee80211_node_table *nt) -{ - ieee80211_node_table_reset(nt, NULL); - if (nt->nt_keyixmap != NULL) { -#ifdef DIAGNOSTIC - /* XXX verify all entries are NULL */ - int i; - for (i = 0; i < nt->nt_keyixmax; i++) - if (nt->nt_keyixmap[i] != NULL) - printf("%s: %s[%u] still active\n", __func__, - nt->nt_name, i); -#endif - free(nt->nt_keyixmap, M_80211_NODE); - nt->nt_keyixmap = NULL; - } - IEEE80211_NODE_ITERATE_LOCK_DESTROY(nt); - IEEE80211_NODE_LOCK_DESTROY(nt); -} - -/* - * Timeout inactive stations and do related housekeeping. - * Note that we cannot hold the node lock while sending a - * frame as this would lead to a LOR. Instead we use a - * generation number to mark nodes that we've scanned and - * drop the lock and restart a scan if we have to time out - * a node. Since we are single-threaded by virtue of - * controlling the inactivity timer we can be sure this will - * process each node only once. - */ -static void -ieee80211_timeout_stations(struct ieee80211com *ic) -{ - struct ieee80211_node_table *nt = &ic->ic_sta; - struct ieee80211vap *vap; - struct ieee80211_node *ni; - int gen = 0; - - IEEE80211_NODE_ITERATE_LOCK(nt); - gen = ++nt->nt_scangen; -restart: - IEEE80211_NODE_LOCK(nt); - TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { - if (ni->ni_scangen == gen) /* previously handled */ - continue; - ni->ni_scangen = gen; - /* - * Ignore entries for which have yet to receive an - * authentication frame. These are transient and - * will be reclaimed when the last reference to them - * goes away (when frame xmits complete). - */ - vap = ni->ni_vap; - /* - * Only process stations when in RUN state. This - * insures, for example, that we don't timeout an - * inactive station during CAC. Note that CSA state - * is actually handled in ieee80211_node_timeout as - * it applies to more than timeout processing. - */ - if (vap->iv_state != IEEE80211_S_RUN) - continue; - /* XXX can vap be NULL? */ - if ((vap->iv_opmode == IEEE80211_M_HOSTAP || - vap->iv_opmode == IEEE80211_M_STA) && - (ni->ni_flags & IEEE80211_NODE_AREF) == 0) - continue; - /* - * Free fragment if not needed anymore - * (last fragment older than 1s). - * XXX doesn't belong here, move to node_age - */ - if (ni->ni_rxfrag[0] != NULL && - ticks > ni->ni_rxfragstamp + hz) { - m_freem(ni->ni_rxfrag[0]); - ni->ni_rxfrag[0] = NULL; - } - if (ni->ni_inact > 0) { - ni->ni_inact--; - IEEE80211_NOTE(vap, IEEE80211_MSG_INACT, ni, - "%s: inact %u inact_reload %u nrates %u", - __func__, ni->ni_inact, ni->ni_inact_reload, - ni->ni_rates.rs_nrates); - } - /* - * Special case ourself; we may be idle for extended periods - * of time and regardless reclaiming our state is wrong. - * XXX run ic_node_age - */ - if (ni == vap->iv_bss) - continue; - if (ni->ni_associd != 0 || - (vap->iv_opmode == IEEE80211_M_IBSS || - vap->iv_opmode == IEEE80211_M_AHDEMO)) { - /* - * Age/drain resources held by the station. - */ - ic->ic_node_age(ni); - /* - * Probe the station before time it out. We - * send a null data frame which may not be - * universally supported by drivers (need it - * for ps-poll support so it should be...). - * - * XXX don't probe the station unless we've - * received a frame from them (and have - * some idea of the rates they are capable - * of); this will get fixed more properly - * soon with better handling of the rate set. - */ - if ((vap->iv_flags_ext & IEEE80211_FEXT_INACT) && - (0 < ni->ni_inact && - ni->ni_inact <= vap->iv_inact_probe) && - ni->ni_rates.rs_nrates != 0) { - IEEE80211_NOTE(vap, - IEEE80211_MSG_INACT | IEEE80211_MSG_NODE, - ni, "%s", - "probe station due to inactivity"); - /* - * Grab a reference before unlocking the table - * so the node cannot be reclaimed before we - * send the frame. ieee80211_send_nulldata - * understands we've done this and reclaims the - * ref for us as needed. - */ - ieee80211_ref_node(ni); - IEEE80211_NODE_UNLOCK(nt); - ieee80211_send_nulldata(ni); - /* XXX stat? */ - goto restart; - } - } - if ((vap->iv_flags_ext & IEEE80211_FEXT_INACT) && - ni->ni_inact <= 0) { - IEEE80211_NOTE(vap, - IEEE80211_MSG_INACT | IEEE80211_MSG_NODE, ni, - "station timed out due to inactivity " - "(refcnt %u)", ieee80211_node_refcnt(ni)); - /* - * Send a deauthenticate frame and drop the station. - * This is somewhat complicated due to reference counts - * and locking. At this point a station will typically - * have a reference count of 1. ieee80211_node_leave - * will do a "free" of the node which will drop the - * reference count. But in the meantime a reference - * wil be held by the deauth frame. The actual reclaim - * of the node will happen either after the tx is - * completed or by ieee80211_node_leave. - * - * Separately we must drop the node lock before sending - * in case the driver takes a lock, as this can result - * in a LOR between the node lock and the driver lock. - */ - ieee80211_ref_node(ni); - IEEE80211_NODE_UNLOCK(nt); - if (ni->ni_associd != 0) { - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_DEAUTH, - IEEE80211_REASON_AUTH_EXPIRE); - } - ieee80211_node_leave(ni); - ieee80211_free_node(ni); - vap->iv_stats.is_node_timeout++; - goto restart; - } - } - IEEE80211_NODE_UNLOCK(nt); - - IEEE80211_NODE_ITERATE_UNLOCK(nt); -} - -/* - * Aggressively reclaim resources. This should be used - * only in a critical situation to reclaim mbuf resources. - */ -void -ieee80211_drain(struct ieee80211com *ic) -{ - struct ieee80211_node_table *nt = &ic->ic_sta; - struct ieee80211vap *vap; - struct ieee80211_node *ni; - - IEEE80211_NODE_LOCK(nt); - TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { - /* - * Ignore entries for which have yet to receive an - * authentication frame. These are transient and - * will be reclaimed when the last reference to them - * goes away (when frame xmits complete). - */ - vap = ni->ni_vap; - /* - * Only process stations when in RUN state. This - * insures, for example, that we don't timeout an - * inactive station during CAC. Note that CSA state - * is actually handled in ieee80211_node_timeout as - * it applies to more than timeout processing. - */ - if (vap->iv_state != IEEE80211_S_RUN) - continue; - /* XXX can vap be NULL? */ - if ((vap->iv_opmode == IEEE80211_M_HOSTAP || - vap->iv_opmode == IEEE80211_M_STA) && - (ni->ni_flags & IEEE80211_NODE_AREF) == 0) - continue; - /* - * Free fragments. - * XXX doesn't belong here, move to node_drain - */ - if (ni->ni_rxfrag[0] != NULL) { - m_freem(ni->ni_rxfrag[0]); - ni->ni_rxfrag[0] = NULL; - } - /* - * Drain resources held by the station. - */ - ic->ic_node_drain(ni); - } - IEEE80211_NODE_UNLOCK(nt); -} - -/* - * Per-ieee80211com inactivity timer callback. - */ -void -ieee80211_node_timeout(void *arg) -{ - struct ieee80211com *ic = arg; - - /* - * Defer timeout processing if a channel switch is pending. - * We typically need to be mute so not doing things that - * might generate frames is good to handle in one place. - * Supressing the station timeout processing may extend the - * lifetime of inactive stations (by not decrementing their - * idle counters) but this should be ok unless the CSA is - * active for an unusually long time. - */ - if ((ic->ic_flags & IEEE80211_F_CSAPENDING) == 0) { - ieee80211_scan_timeout(ic); - ieee80211_timeout_stations(ic); - ieee80211_ageq_age(&ic->ic_stageq, IEEE80211_INACT_WAIT); - - IEEE80211_LOCK(ic); - ieee80211_erp_timeout(ic); - ieee80211_ht_timeout(ic); - IEEE80211_UNLOCK(ic); - } - callout_reset(&ic->ic_inact, IEEE80211_INACT_WAIT*hz, - ieee80211_node_timeout, ic); -} - -void -ieee80211_iterate_nodes(struct ieee80211_node_table *nt, - ieee80211_iter_func *f, void *arg) -{ - struct ieee80211_node *ni; - u_int gen; - - IEEE80211_NODE_ITERATE_LOCK(nt); - gen = ++nt->nt_scangen; -restart: - IEEE80211_NODE_LOCK(nt); - TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { - if (ni->ni_scangen != gen) { - ni->ni_scangen = gen; - (void) ieee80211_ref_node(ni); - IEEE80211_NODE_UNLOCK(nt); - (*f)(arg, ni); - ieee80211_free_node(ni); - goto restart; - } - } - IEEE80211_NODE_UNLOCK(nt); - - IEEE80211_NODE_ITERATE_UNLOCK(nt); -} - -void -ieee80211_dump_node(struct ieee80211_node_table *nt, struct ieee80211_node *ni) -{ - printf("0x%p: mac %s refcnt %d\n", ni, - ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)); - printf("\tscangen %u authmode %u flags 0x%x\n", - ni->ni_scangen, ni->ni_authmode, ni->ni_flags); - printf("\tassocid 0x%x txpower %u vlan %u\n", - ni->ni_associd, ni->ni_txpower, ni->ni_vlan); - printf("\ttxseq %u rxseq %u fragno %u rxfragstamp %u\n", - ni->ni_txseqs[IEEE80211_NONQOS_TID], - ni->ni_rxseqs[IEEE80211_NONQOS_TID] >> IEEE80211_SEQ_SEQ_SHIFT, - ni->ni_rxseqs[IEEE80211_NONQOS_TID] & IEEE80211_SEQ_FRAG_MASK, - ni->ni_rxfragstamp); - printf("\trssi %d noise %d intval %u capinfo 0x%x\n", - node_getrssi(ni), ni->ni_noise, - ni->ni_intval, ni->ni_capinfo); - printf("\tbssid %s essid \"%.*s\" channel %u:0x%x\n", - ether_sprintf(ni->ni_bssid), - ni->ni_esslen, ni->ni_essid, - ni->ni_chan->ic_freq, ni->ni_chan->ic_flags); - printf("\tinact %u inact_reload %u txrate %u\n", - ni->ni_inact, ni->ni_inact_reload, ni->ni_txrate); - printf("\thtcap %x htparam %x htctlchan %u ht2ndchan %u\n", - ni->ni_htcap, ni->ni_htparam, - ni->ni_htctlchan, ni->ni_ht2ndchan); - printf("\thtopmode %x htstbc %x chw %u\n", - ni->ni_htopmode, ni->ni_htstbc, ni->ni_chw); -} - -void -ieee80211_dump_nodes(struct ieee80211_node_table *nt) -{ - ieee80211_iterate_nodes(nt, - (ieee80211_iter_func *) ieee80211_dump_node, nt); -} - -static void -ieee80211_notify_erp_locked(struct ieee80211com *ic) -{ - struct ieee80211vap *vap; - - IEEE80211_LOCK_ASSERT(ic); - - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if (vap->iv_opmode == IEEE80211_M_HOSTAP) - ieee80211_beacon_notify(vap, IEEE80211_BEACON_ERP); -} - -void -ieee80211_notify_erp(struct ieee80211com *ic) -{ - IEEE80211_LOCK(ic); - ieee80211_notify_erp_locked(ic); - IEEE80211_UNLOCK(ic); -} - -/* - * Handle a station joining an 11g network. - */ -static void -ieee80211_node_join_11g(struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - - IEEE80211_LOCK_ASSERT(ic); - - /* - * Station isn't capable of short slot time. Bump - * the count of long slot time stations and disable - * use of short slot time. Note that the actual switch - * over to long slot time use may not occur until the - * next beacon transmission (per sec. 7.3.1.4 of 11g). - */ - if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) { - ic->ic_longslotsta++; - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ASSOC, ni, - "station needs long slot time, count %d", - ic->ic_longslotsta); - /* XXX vap's w/ conflicting needs won't work */ - if (!IEEE80211_IS_CHAN_108G(ic->ic_bsschan)) { - /* - * Don't force slot time when switched to turbo - * mode as non-ERP stations won't be present; this - * need only be done when on the normal G channel. - */ - ieee80211_set_shortslottime(ic, 0); - } - } - /* - * If the new station is not an ERP station - * then bump the counter and enable protection - * if configured. - */ - if (!ieee80211_iserp_rateset(&ni->ni_rates)) { - ic->ic_nonerpsta++; - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ASSOC, ni, - "station is !ERP, %d non-ERP stations associated", - ic->ic_nonerpsta); - /* - * If station does not support short preamble - * then we must enable use of Barker preamble. - */ - if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) == 0) { - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ASSOC, ni, - "%s", "station needs long preamble"); - ic->ic_flags |= IEEE80211_F_USEBARKER; - ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; - } - /* - * If protection is configured and this is the first - * indication we should use protection, enable it. - */ - if (ic->ic_protmode != IEEE80211_PROT_NONE && - ic->ic_nonerpsta == 1 && - (ic->ic_flags_ext & IEEE80211_FEXT_NONERP_PR) == 0) { - IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_ASSOC, - "%s: enable use of protection\n", __func__); - ic->ic_flags |= IEEE80211_F_USEPROT; - ieee80211_notify_erp_locked(ic); - } - } else - ni->ni_flags |= IEEE80211_NODE_ERP; -} - -void -ieee80211_node_join(struct ieee80211_node *ni, int resp) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211vap *vap = ni->ni_vap; - int newassoc; - - if (ni->ni_associd == 0) { - uint16_t aid; - - KASSERT(vap->iv_aid_bitmap != NULL, ("no aid bitmap")); - /* - * It would be good to search the bitmap - * more efficiently, but this will do for now. - */ - for (aid = 1; aid < vap->iv_max_aid; aid++) { - if (!IEEE80211_AID_ISSET(vap, aid)) - break; - } - if (aid >= vap->iv_max_aid) { - IEEE80211_SEND_MGMT(ni, resp, IEEE80211_STATUS_TOOMANY); - ieee80211_node_leave(ni); - return; - } - ni->ni_associd = aid | 0xc000; - ni->ni_jointime = time_uptime; - IEEE80211_LOCK(ic); - IEEE80211_AID_SET(vap, ni->ni_associd); - vap->iv_sta_assoc++; - ic->ic_sta_assoc++; - - if (IEEE80211_IS_CHAN_HT(ic->ic_bsschan)) - ieee80211_ht_node_join(ni); - if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan) && - IEEE80211_IS_CHAN_FULL(ic->ic_bsschan)) - ieee80211_node_join_11g(ni); - IEEE80211_UNLOCK(ic); - - newassoc = 1; - } else - newassoc = 0; - - IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, ni, - "station associated at aid %d: %s preamble, %s slot time%s%s%s%s%s%s%s%s", - IEEE80211_NODE_AID(ni), - ic->ic_flags & IEEE80211_F_SHPREAMBLE ? "short" : "long", - ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", - ic->ic_flags & IEEE80211_F_USEPROT ? ", protection" : "", - ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "", - ni->ni_flags & IEEE80211_NODE_HT ? - (ni->ni_chw == 40 ? ", HT40" : ", HT20") : "", - ni->ni_flags & IEEE80211_NODE_AMPDU ? " (+AMPDU)" : "", - ni->ni_flags & IEEE80211_NODE_MIMO_RTS ? " (+SMPS-DYN)" : - ni->ni_flags & IEEE80211_NODE_MIMO_PS ? " (+SMPS)" : "", - ni->ni_flags & IEEE80211_NODE_RIFS ? " (+RIFS)" : "", - IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF) ? - ", fast-frames" : "", - IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_TURBOP) ? - ", turbo" : "" - ); - - ieee80211_node_setuptxparms(ni); - ieee80211_ratectl_node_init(ni); - /* give driver a chance to setup state like ni_txrate */ - if (ic->ic_newassoc != NULL) - ic->ic_newassoc(ni, newassoc); - IEEE80211_SEND_MGMT(ni, resp, IEEE80211_STATUS_SUCCESS); - /* tell the authenticator about new station */ - if (vap->iv_auth->ia_node_join != NULL) - vap->iv_auth->ia_node_join(ni); - ieee80211_notify_node_join(ni, - resp == IEEE80211_FC0_SUBTYPE_ASSOC_RESP); -} - -static void -disable_protection(struct ieee80211com *ic) -{ - KASSERT(ic->ic_nonerpsta == 0 && - (ic->ic_flags_ext & IEEE80211_FEXT_NONERP_PR) == 0, - ("%d non ERP stations, flags 0x%x", ic->ic_nonerpsta, - ic->ic_flags_ext)); - - ic->ic_flags &= ~IEEE80211_F_USEPROT; - /* XXX verify mode? */ - if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) { - ic->ic_flags |= IEEE80211_F_SHPREAMBLE; - ic->ic_flags &= ~IEEE80211_F_USEBARKER; - } - ieee80211_notify_erp_locked(ic); -} - -/* - * Handle a station leaving an 11g network. - */ -static void -ieee80211_node_leave_11g(struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - - IEEE80211_LOCK_ASSERT(ic); - - KASSERT(IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan), - ("not in 11g, bss %u:0x%x", ic->ic_bsschan->ic_freq, - ic->ic_bsschan->ic_flags)); - - /* - * If a long slot station do the slot time bookkeeping. - */ - if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) { - KASSERT(ic->ic_longslotsta > 0, - ("bogus long slot station count %d", ic->ic_longslotsta)); - ic->ic_longslotsta--; - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ASSOC, ni, - "long slot time station leaves, count now %d", - ic->ic_longslotsta); - if (ic->ic_longslotsta == 0) { - /* - * Re-enable use of short slot time if supported - * and not operating in IBSS mode (per spec). - */ - if ((ic->ic_caps & IEEE80211_C_SHSLOT) && - ic->ic_opmode != IEEE80211_M_IBSS) { - IEEE80211_DPRINTF(ni->ni_vap, - IEEE80211_MSG_ASSOC, - "%s: re-enable use of short slot time\n", - __func__); - ieee80211_set_shortslottime(ic, 1); - } - } - } - /* - * If a non-ERP station do the protection-related bookkeeping. - */ - if ((ni->ni_flags & IEEE80211_NODE_ERP) == 0) { - KASSERT(ic->ic_nonerpsta > 0, - ("bogus non-ERP station count %d", ic->ic_nonerpsta)); - ic->ic_nonerpsta--; - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ASSOC, ni, - "non-ERP station leaves, count now %d%s", ic->ic_nonerpsta, - (ic->ic_flags_ext & IEEE80211_FEXT_NONERP_PR) ? - " (non-ERP sta present)" : ""); - if (ic->ic_nonerpsta == 0 && - (ic->ic_flags_ext & IEEE80211_FEXT_NONERP_PR) == 0) { - IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_ASSOC, - "%s: disable use of protection\n", __func__); - disable_protection(ic); - } - } -} - -/* - * Time out presence of an overlapping bss with non-ERP - * stations. When operating in hostap mode we listen for - * beacons from other stations and if we identify a non-ERP - * station is present we enable protection. To identify - * when all non-ERP stations are gone we time out this - * condition. - */ -static void -ieee80211_erp_timeout(struct ieee80211com *ic) -{ - - IEEE80211_LOCK_ASSERT(ic); - - if ((ic->ic_flags_ext & IEEE80211_FEXT_NONERP_PR) && - time_after(ticks, ic->ic_lastnonerp + IEEE80211_NONERP_PRESENT_AGE)) { -#if 0 - IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, - "%s", "age out non-ERP sta present on channel"); -#endif - ic->ic_flags_ext &= ~IEEE80211_FEXT_NONERP_PR; - if (ic->ic_nonerpsta == 0) - disable_protection(ic); - } -} - -/* - * Handle bookkeeping for station deauthentication/disassociation - * when operating as an ap. - */ -void -ieee80211_node_leave(struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_node_table *nt = ni->ni_table; - - IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, ni, - "station with aid %d leaves", IEEE80211_NODE_AID(ni)); - - KASSERT(vap->iv_opmode != IEEE80211_M_STA, - ("unexpected operating mode %u", vap->iv_opmode)); - /* - * If node wasn't previously associated all - * we need to do is reclaim the reference. - */ - /* XXX ibss mode bypasses 11g and notification */ - if (ni->ni_associd == 0) - goto done; - /* - * Tell the authenticator the station is leaving. - * Note that we must do this before yanking the - * association id as the authenticator uses the - * associd to locate it's state block. - */ - if (vap->iv_auth->ia_node_leave != NULL) - vap->iv_auth->ia_node_leave(ni); - - IEEE80211_LOCK(ic); - IEEE80211_AID_CLR(vap, ni->ni_associd); - ni->ni_associd = 0; - vap->iv_sta_assoc--; - ic->ic_sta_assoc--; - - if (IEEE80211_IS_CHAN_HT(ic->ic_bsschan)) - ieee80211_ht_node_leave(ni); - if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan) && - IEEE80211_IS_CHAN_FULL(ic->ic_bsschan)) - ieee80211_node_leave_11g(ni); - IEEE80211_UNLOCK(ic); - /* - * Cleanup station state. In particular clear various - * state that might otherwise be reused if the node - * is reused before the reference count goes to zero - * (and memory is reclaimed). - */ - ieee80211_sta_leave(ni); -done: - /* - * Remove the node from any table it's recorded in and - * drop the caller's reference. Removal from the table - * is important to insure the node is not reprocessed - * for inactivity. - */ - if (nt != NULL) { - IEEE80211_NODE_LOCK(nt); - node_reclaim(nt, ni); - IEEE80211_NODE_UNLOCK(nt); - } else - ieee80211_free_node(ni); -} - -struct rssiinfo { - struct ieee80211vap *vap; - int rssi_samples; - uint32_t rssi_total; -}; - -static void -get_hostap_rssi(void *arg, struct ieee80211_node *ni) -{ - struct rssiinfo *info = arg; - struct ieee80211vap *vap = ni->ni_vap; - int8_t rssi; - - if (info->vap != vap) - return; - /* only associated stations */ - if (ni->ni_associd == 0) - return; - rssi = vap->iv_ic->ic_node_getrssi(ni); - if (rssi != 0) { - info->rssi_samples++; - info->rssi_total += rssi; - } -} - -static void -get_adhoc_rssi(void *arg, struct ieee80211_node *ni) -{ - struct rssiinfo *info = arg; - struct ieee80211vap *vap = ni->ni_vap; - int8_t rssi; - - if (info->vap != vap) - return; - /* only neighbors */ - /* XXX check bssid */ - if ((ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) == 0) - return; - rssi = vap->iv_ic->ic_node_getrssi(ni); - if (rssi != 0) { - info->rssi_samples++; - info->rssi_total += rssi; - } -} - -#ifdef IEEE80211_SUPPORT_MESH -static void -get_mesh_rssi(void *arg, struct ieee80211_node *ni) -{ - struct rssiinfo *info = arg; - struct ieee80211vap *vap = ni->ni_vap; - int8_t rssi; - - if (info->vap != vap) - return; - /* only neighbors that peered successfully */ - if (ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) - return; - rssi = vap->iv_ic->ic_node_getrssi(ni); - if (rssi != 0) { - info->rssi_samples++; - info->rssi_total += rssi; - } -} -#endif /* IEEE80211_SUPPORT_MESH */ - -int8_t -ieee80211_getrssi(struct ieee80211vap *vap) -{ -#define NZ(x) ((x) == 0 ? 1 : (x)) - struct ieee80211com *ic = vap->iv_ic; - struct rssiinfo info; - - info.rssi_total = 0; - info.rssi_samples = 0; - info.vap = vap; - switch (vap->iv_opmode) { - case IEEE80211_M_IBSS: /* average of all ibss neighbors */ - case IEEE80211_M_AHDEMO: /* average of all neighbors */ - ieee80211_iterate_nodes(&ic->ic_sta, get_adhoc_rssi, &info); - break; - case IEEE80211_M_HOSTAP: /* average of all associated stations */ - ieee80211_iterate_nodes(&ic->ic_sta, get_hostap_rssi, &info); - break; -#ifdef IEEE80211_SUPPORT_MESH - case IEEE80211_M_MBSS: /* average of all mesh neighbors */ - ieee80211_iterate_nodes(&ic->ic_sta, get_mesh_rssi, &info); - break; -#endif - case IEEE80211_M_MONITOR: /* XXX */ - case IEEE80211_M_STA: /* use stats from associated ap */ - default: - if (vap->iv_bss != NULL) - info.rssi_total = ic->ic_node_getrssi(vap->iv_bss); - info.rssi_samples = 1; - break; - } - return info.rssi_total / NZ(info.rssi_samples); -#undef NZ -} - -void -ieee80211_getsignal(struct ieee80211vap *vap, int8_t *rssi, int8_t *noise) -{ - - if (vap->iv_bss == NULL) /* NB: shouldn't happen */ - return; - vap->iv_ic->ic_node_getsignal(vap->iv_bss, rssi, noise); - /* for non-station mode return avg'd rssi accounting */ - if (vap->iv_opmode != IEEE80211_M_STA) - *rssi = ieee80211_getrssi(vap); -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_node.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_node.h deleted file mode 100644 index 68167a0e05..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_node.h +++ /dev/null @@ -1,461 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_NODE_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_NODE_H_ - -#include /* for ieee80211_nodestats */ -#include /* for aggregation state */ - -/* - * Each ieee80211com instance has a single timer that fires every - * IEEE80211_INACT_WAIT seconds to handle "inactivity processing". - * This is used to do node inactivity processing when operating - * as an AP, adhoc or mesh mode. For inactivity processing each node - * has a timeout set in it's ni_inact field that is decremented - * on each timeout and the node is reclaimed when the counter goes - * to zero. We use different inactivity timeout values depending - * on whether the node is associated and authorized (either by - * 802.1x or open/shared key authentication) or associated but yet - * to be authorized. The latter timeout is shorter to more aggressively - * reclaim nodes that leave part way through the 802.1x exchange. - */ -#define IEEE80211_INACT_WAIT 15 /* inactivity interval (secs) */ -#define IEEE80211_INACT_INIT (30/IEEE80211_INACT_WAIT) /* initial */ -#define IEEE80211_INACT_AUTH (180/IEEE80211_INACT_WAIT) /* associated but not authorized */ -#define IEEE80211_INACT_RUN (300/IEEE80211_INACT_WAIT) /* authorized */ -#define IEEE80211_INACT_PROBE (30/IEEE80211_INACT_WAIT) /* probe */ -#define IEEE80211_INACT_SCAN (300/IEEE80211_INACT_WAIT) /* scanned */ - -#define IEEE80211_TRANS_WAIT 2 /* mgt frame tx timer (secs) */ - -/* threshold for aging overlapping non-ERP bss */ -#define IEEE80211_NONERP_PRESENT_AGE msecs_to_ticks(60*1000) - -#define IEEE80211_NODE_HASHSIZE 32 /* NB: hash size must be pow2 */ -/* simple hash is enough for variation of macaddr */ -#define IEEE80211_NODE_HASH(ic, addr) \ - (((const uint8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % \ - IEEE80211_NODE_HASHSIZE) - -struct ieee80211_node_table; -struct ieee80211com; -struct ieee80211vap; - -/* - * Information element ``blob''. We use this structure - * to capture management frame payloads that need to be - * retained. Information elements within the payload that - * we need to consult have references recorded. - */ -struct ieee80211_ies { - /* the following are either NULL or point within data */ - uint8_t *wpa_ie; /* captured WPA ie */ - uint8_t *rsn_ie; /* captured RSN ie */ - uint8_t *wme_ie; /* captured WME ie */ - uint8_t *ath_ie; /* captured Atheros ie */ - uint8_t *htcap_ie; /* captured HTCAP ie */ - uint8_t *htinfo_ie; /* captured HTINFO ie */ - uint8_t *tdma_ie; /* captured TDMA ie */ - uint8_t *meshid_ie; /* captured MESH ID ie */ - uint8_t *spare[4]; - /* NB: these must be the last members of this structure */ - uint8_t *data; /* frame data > 802.11 header */ - int len; /* data size in bytes */ -}; - -/* - * 802.11s (Mesh) Peer Link FSM state. - */ -enum ieee80211_mesh_mlstate { - IEEE80211_NODE_MESH_IDLE = 0, - IEEE80211_NODE_MESH_OPENSNT = 1, /* open frame sent */ - IEEE80211_NODE_MESH_OPENRCV = 2, /* open frame received */ - IEEE80211_NODE_MESH_CONFIRMRCV = 3, /* confirm frame received */ - IEEE80211_NODE_MESH_ESTABLISHED = 4, /* link established */ - IEEE80211_NODE_MESH_HOLDING = 5, /* link closing */ -}; -#define IEEE80211_MESH_MLSTATE_BITS \ - "\20\1IDLE\2OPENSNT\2OPENRCV\3CONFIRMRCV\4ESTABLISHED\5HOLDING" - -/* - * Node specific information. Note that drivers are expected - * to derive from this structure to add device-specific per-node - * state. This is done by overriding the ic_node_* methods in - * the ieee80211com structure. - */ -struct ieee80211_node { - struct ieee80211vap *ni_vap; /* associated vap */ - struct ieee80211com *ni_ic; /* copy from vap to save deref*/ - struct ieee80211_node_table *ni_table; /* NB: may be NULL */ - TAILQ_ENTRY(ieee80211_node) ni_list; /* list of all nodes */ - LIST_ENTRY(ieee80211_node) ni_hash; /* hash collision list */ - u_int ni_refcnt; /* count of held references */ - u_int ni_scangen; /* gen# for timeout scan */ - u_int ni_flags; -#define IEEE80211_NODE_AUTH 0x000001 /* authorized for data */ -#define IEEE80211_NODE_QOS 0x000002 /* QoS enabled */ -#define IEEE80211_NODE_ERP 0x000004 /* ERP enabled */ -/* NB: this must have the same value as IEEE80211_FC1_PWR_MGT */ -#define IEEE80211_NODE_PWR_MGT 0x000010 /* power save mode enabled */ -#define IEEE80211_NODE_AREF 0x000020 /* authentication ref held */ -#define IEEE80211_NODE_HT 0x000040 /* HT enabled */ -#define IEEE80211_NODE_HTCOMPAT 0x000080 /* HT setup w/ vendor OUI's */ -#define IEEE80211_NODE_WPS 0x000100 /* WPS association */ -#define IEEE80211_NODE_TSN 0x000200 /* TSN association */ -#define IEEE80211_NODE_AMPDU_RX 0x000400 /* AMPDU rx enabled */ -#define IEEE80211_NODE_AMPDU_TX 0x000800 /* AMPDU tx enabled */ -#define IEEE80211_NODE_MIMO_PS 0x001000 /* MIMO power save enabled */ -#define IEEE80211_NODE_MIMO_RTS 0x002000 /* send RTS in MIMO PS */ -#define IEEE80211_NODE_RIFS 0x004000 /* RIFS enabled */ -#define IEEE80211_NODE_SGI20 0x008000 /* Short GI in HT20 enabled */ -#define IEEE80211_NODE_SGI40 0x010000 /* Short GI in HT40 enabled */ -#define IEEE80211_NODE_ASSOCID 0x020000 /* xmit requires associd */ -#define IEEE80211_NODE_AMSDU_RX 0x040000 /* AMSDU rx enabled */ -#define IEEE80211_NODE_AMSDU_TX 0x080000 /* AMSDU tx enabled */ - uint16_t ni_associd; /* association ID */ - uint16_t ni_vlan; /* vlan tag */ - uint16_t ni_txpower; /* current transmit power */ - uint8_t ni_authmode; /* authentication algorithm */ - uint8_t ni_ath_flags; /* Atheros feature flags */ - /* NB: These must have the same values as IEEE80211_ATHC_* */ -#define IEEE80211_NODE_TURBOP 0x0001 /* Turbo prime enable */ -#define IEEE80211_NODE_COMP 0x0002 /* Compresssion enable */ -#define IEEE80211_NODE_FF 0x0004 /* Fast Frame capable */ -#define IEEE80211_NODE_XR 0x0008 /* Atheros WME enable */ -#define IEEE80211_NODE_AR 0x0010 /* AR capable */ -#define IEEE80211_NODE_BOOST 0x0080 /* Dynamic Turbo boosted */ - uint16_t ni_ath_defkeyix;/* Atheros def key index */ - const struct ieee80211_txparam *ni_txparms; - uint32_t ni_jointime; /* time of join (secs) */ - uint32_t *ni_challenge; /* shared-key challenge */ - struct ieee80211_ies ni_ies; /* captured ie's */ - /* tx seq per-tid */ - ieee80211_seq ni_txseqs[IEEE80211_TID_SIZE]; - /* rx seq previous per-tid*/ - ieee80211_seq ni_rxseqs[IEEE80211_TID_SIZE]; - uint32_t ni_rxfragstamp; /* time stamp of last rx frag */ - struct mbuf *ni_rxfrag[3]; /* rx frag reassembly */ - struct ieee80211_key ni_ucastkey; /* unicast key */ - - /* hardware */ - uint32_t ni_avgrssi; /* recv ssi state */ - int8_t ni_noise; /* noise floor */ - - /* mimo statistics */ - uint32_t ni_mimo_rssi_ctl[IEEE80211_MAX_CHAINS]; - uint32_t ni_mimo_rssi_ext[IEEE80211_MAX_CHAINS]; - uint8_t ni_mimo_noise_ctl[IEEE80211_MAX_CHAINS]; - uint8_t ni_mimo_noise_ext[IEEE80211_MAX_CHAINS]; - uint8_t ni_mimo_chains; - - /* header */ - uint8_t ni_macaddr[IEEE80211_ADDR_LEN]; - uint8_t ni_bssid[IEEE80211_ADDR_LEN]; - - /* beacon, probe response */ - union { - uint8_t data[8]; - u_int64_t tsf; - } ni_tstamp; /* from last rcv'd beacon */ - uint16_t ni_intval; /* beacon interval */ - uint16_t ni_capinfo; /* capabilities */ - uint8_t ni_esslen; - uint8_t ni_essid[IEEE80211_NWID_LEN]; - struct ieee80211_rateset ni_rates; /* negotiated rate set */ - struct ieee80211_channel *ni_chan; - uint16_t ni_fhdwell; /* FH only */ - uint8_t ni_fhindex; /* FH only */ - uint16_t ni_erp; /* ERP from beacon/probe resp */ - uint16_t ni_timoff; /* byte offset to TIM ie */ - uint8_t ni_dtim_period; /* DTIM period */ - uint8_t ni_dtim_count; /* DTIM count for last bcn */ - - /* 11s state */ - uint8_t ni_meshidlen; - uint8_t ni_meshid[IEEE80211_MESHID_LEN]; - enum ieee80211_mesh_mlstate ni_mlstate; /* peering management state */ - uint16_t ni_mllid; /* link local ID */ - uint16_t ni_mlpid; /* link peer ID */ - struct callout ni_mltimer; /* link mesh timer */ - uint8_t ni_mlrcnt; /* link mesh retry counter */ - uint8_t ni_mltval; /* link mesh timer value */ - - /* 11n state */ - uint16_t ni_htcap; /* HT capabilities */ - uint8_t ni_htparam; /* HT params */ - uint8_t ni_htctlchan; /* HT control channel */ - uint8_t ni_ht2ndchan; /* HT 2nd channel */ - uint8_t ni_htopmode; /* HT operating mode */ - uint8_t ni_htstbc; /* HT */ - uint8_t ni_chw; /* negotiated channel width */ - struct ieee80211_htrateset ni_htrates; /* negotiated ht rate set */ - struct ieee80211_tx_ampdu ni_tx_ampdu[WME_NUM_AC]; - struct ieee80211_rx_ampdu ni_rx_ampdu[WME_NUM_TID]; - - /* others */ - short ni_inact; /* inactivity mark count */ - short ni_inact_reload;/* inactivity reload value */ - int ni_txrate; /* legacy rate/MCS */ - struct ieee80211_psq ni_psq; /* power save queue */ - struct ieee80211_nodestats ni_stats; /* per-node statistics */ - - struct ieee80211vap *ni_wdsvap; /* associated WDS vap */ - void *ni_rctls; /* private ratectl state */ - uint64_t ni_spare[3]; -}; - -#define IEEE80211_NODE_ATH (IEEE80211_NODE_FF | IEEE80211_NODE_TURBOP) -#define IEEE80211_NODE_AMPDU \ - (IEEE80211_NODE_AMPDU_RX | IEEE80211_NODE_AMPDU_TX) -#define IEEE80211_NODE_AMSDU \ - (IEEE80211_NODE_AMSDU_RX | IEEE80211_NODE_AMSDU_TX) -#define IEEE80211_NODE_HT_ALL \ - (IEEE80211_NODE_HT | IEEE80211_NODE_HTCOMPAT | \ - IEEE80211_NODE_AMPDU | IEEE80211_NODE_AMSDU | \ - IEEE80211_NODE_MIMO_PS | IEEE80211_NODE_MIMO_RTS | \ - IEEE80211_NODE_RIFS | IEEE80211_NODE_SGI20 | IEEE80211_NODE_SGI40) - -#define IEEE80211_NODE_BITS \ - "\20\1AUTH\2QOS\3ERP\5PWR_MGT\6AREF\7HT\10HTCOMPAT\11WPS\12TSN" \ - "\13AMPDU_RX\14AMPDU_TX\15MIMO_PS\16MIMO_RTS\17RIFS\20SGI20\21SGI40" \ - "\22ASSOCID" - -#define IEEE80211_NODE_AID(ni) IEEE80211_AID(ni->ni_associd) - -#define IEEE80211_NODE_STAT(ni,stat) (ni->ni_stats.ns_##stat++) -#define IEEE80211_NODE_STAT_ADD(ni,stat,v) (ni->ni_stats.ns_##stat += v) -#define IEEE80211_NODE_STAT_SET(ni,stat,v) (ni->ni_stats.ns_##stat = v) - -/* - * Filtered rssi calculation support. The receive rssi is maintained - * as an average over the last 10 frames received using a low pass filter - * (all frames for now, possibly need to be more selective). Calculations - * are designed such that a good compiler can optimize them. The avg - * rssi state should be initialized to IEEE80211_RSSI_DUMMY_MARKER and - * each sample incorporated with IEEE80211_RSSI_LPF. Use IEEE80211_RSSI_GET - * to extract the current value. - * - * Note that we assume rssi data are in the range [-127..127] and we - * discard values <-20. This is consistent with assumptions throughout - * net80211 that signal strength data are in .5 dBm units relative to - * the current noise floor (linear, not log). - */ -#define IEEE80211_RSSI_LPF_LEN 10 -#define IEEE80211_RSSI_DUMMY_MARKER 127 -/* NB: pow2 to optimize out * and / */ -#define IEEE80211_RSSI_EP_MULTIPLIER (1<<7) -#define IEEE80211_RSSI_IN(x) ((x) * IEEE80211_RSSI_EP_MULTIPLIER) -#define _IEEE80211_RSSI_LPF(x, y, len) \ - (((x) != IEEE80211_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y)) -#define IEEE80211_RSSI_LPF(x, y) do { \ - if ((y) >= -20) { \ - x = _IEEE80211_RSSI_LPF((x), IEEE80211_RSSI_IN((y)), \ - IEEE80211_RSSI_LPF_LEN); \ - } \ -} while (0) -#define IEEE80211_RSSI_EP_RND(x, mul) \ - ((((x) % (mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) -#define IEEE80211_RSSI_GET(x) \ - IEEE80211_RSSI_EP_RND(x, IEEE80211_RSSI_EP_MULTIPLIER) - -static __inline struct ieee80211_node * -ieee80211_ref_node(struct ieee80211_node *ni) -{ - ieee80211_node_incref(ni); - return ni; -} - -static __inline void -ieee80211_unref_node(struct ieee80211_node **ni) -{ - ieee80211_node_decref(*ni); - *ni = NULL; /* guard against use */ -} - -struct ieee80211com; - -void ieee80211_node_attach(struct ieee80211com *); -void ieee80211_node_lateattach(struct ieee80211com *); -void ieee80211_node_detach(struct ieee80211com *); -void ieee80211_node_vattach(struct ieee80211vap *); -void ieee80211_node_latevattach(struct ieee80211vap *); -void ieee80211_node_vdetach(struct ieee80211vap *); - -static __inline int -ieee80211_node_is_authorized(const struct ieee80211_node *ni) -{ - return (ni->ni_flags & IEEE80211_NODE_AUTH); -} - -void ieee80211_node_authorize(struct ieee80211_node *); -void ieee80211_node_unauthorize(struct ieee80211_node *); - -void ieee80211_node_setuptxparms(struct ieee80211_node *); -void ieee80211_node_set_chan(struct ieee80211_node *, - struct ieee80211_channel *); -void ieee80211_create_ibss(struct ieee80211vap*, struct ieee80211_channel *); -void ieee80211_reset_bss(struct ieee80211vap *); -void ieee80211_sync_curchan(struct ieee80211com *); -void ieee80211_setupcurchan(struct ieee80211com *, - struct ieee80211_channel *); -void ieee80211_setcurchan(struct ieee80211com *, struct ieee80211_channel *); -int ieee80211_ibss_merge(struct ieee80211_node *); -struct ieee80211_scan_entry; -int ieee80211_sta_join(struct ieee80211vap *, struct ieee80211_channel *, - const struct ieee80211_scan_entry *); -void ieee80211_sta_leave(struct ieee80211_node *); -void ieee80211_node_deauth(struct ieee80211_node *, int); - -int ieee80211_ies_init(struct ieee80211_ies *, const uint8_t *, int); -void ieee80211_ies_cleanup(struct ieee80211_ies *); -void ieee80211_ies_expand(struct ieee80211_ies *); -#define ieee80211_ies_setie(_ies, _ie, _off) do { \ - (_ies)._ie = (_ies).data + (_off); \ -} while (0) - -/* - * Table of ieee80211_node instances. Each ieee80211com - * has one that holds association stations (when operating - * as an ap) or neighbors (in ibss mode). - * - * XXX embed this in ieee80211com instead of indirect? - */ -struct ieee80211_node_table { - struct ieee80211com *nt_ic; /* back reference */ - ieee80211_node_lock_t nt_nodelock; /* on node table */ - TAILQ_HEAD(, ieee80211_node) nt_node; /* information of all nodes */ - LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE]; - struct ieee80211_node **nt_keyixmap; /* key ix -> node map */ - int nt_keyixmax; /* keyixmap size */ - const char *nt_name; /* table name for debug msgs */ - ieee80211_scan_lock_t nt_scanlock; /* on nt_scangen */ - u_int nt_scangen; /* gen# for iterators */ - int nt_inact_init; /* initial node inact setting */ -}; - -struct ieee80211_node *ieee80211_alloc_node(struct ieee80211_node_table *, - struct ieee80211vap *, - const uint8_t macaddr[IEEE80211_ADDR_LEN]); -struct ieee80211_node *ieee80211_tmp_node(struct ieee80211vap *, - const uint8_t macaddr[IEEE80211_ADDR_LEN]); -struct ieee80211_node *ieee80211_dup_bss(struct ieee80211vap *, - const uint8_t macaddr[IEEE80211_ADDR_LEN]); -struct ieee80211_node *ieee80211_node_create_wds(struct ieee80211vap *, - const uint8_t bssid[IEEE80211_ADDR_LEN], - struct ieee80211_channel *); -#ifdef IEEE80211_DEBUG_REFCNT -void ieee80211_free_node_debug(struct ieee80211_node *, - const char *func, int line); -struct ieee80211_node *ieee80211_find_node_locked_debug( - struct ieee80211_node_table *, - const uint8_t macaddr[IEEE80211_ADDR_LEN], - const char *func, int line); -struct ieee80211_node *ieee80211_find_node_debug(struct ieee80211_node_table *, - const uint8_t macaddr[IEEE80211_ADDR_LEN], - const char *func, int line); -struct ieee80211_node *ieee80211_find_vap_node_locked_debug( - struct ieee80211_node_table *, - const struct ieee80211vap *vap, - const uint8_t macaddr[IEEE80211_ADDR_LEN], - const char *func, int line); -struct ieee80211_node *ieee80211_find_vap_node_debug( - struct ieee80211_node_table *, - const struct ieee80211vap *vap, - const uint8_t macaddr[IEEE80211_ADDR_LEN], - const char *func, int line); -struct ieee80211_node * ieee80211_find_rxnode_debug(struct ieee80211com *, - const struct ieee80211_frame_min *, - const char *func, int line); -struct ieee80211_node * ieee80211_find_rxnode_withkey_debug( - struct ieee80211com *, - const struct ieee80211_frame_min *, uint16_t keyix, - const char *func, int line); -struct ieee80211_node *ieee80211_find_txnode_debug(struct ieee80211vap *, - const uint8_t *, - const char *func, int line); -#define ieee80211_free_node(ni) \ - ieee80211_free_node_debug(ni, __func__, __LINE__) -#define ieee80211_find_node_locked(nt, mac) \ - ieee80211_find_node_locked_debug(nt, mac, __func__, __LINE__) -#define ieee80211_find_node(nt, mac) \ - ieee80211_find_node_debug(nt, mac, __func__, __LINE__) -#define ieee80211_find_vap_node_locked(nt, vap, mac) \ - ieee80211_find_vap_node_locked_debug(nt, vap, mac, __func__, __LINE__) -#define ieee80211_find_vap_node(nt, vap, mac) \ - ieee80211_find_vap_node_debug(nt, vap, mac, __func__, __LINE__) -#define ieee80211_find_rxnode(ic, wh) \ - ieee80211_find_rxnode_debug(ic, wh, __func__, __LINE__) -#define ieee80211_find_rxnode_withkey(ic, wh, keyix) \ - ieee80211_find_rxnode_withkey_debug(ic, wh, keyix, __func__, __LINE__) -#define ieee80211_find_txnode(vap, mac) \ - ieee80211_find_txnode_debug(vap, mac, __func__, __LINE__) -#else -void ieee80211_free_node(struct ieee80211_node *); -struct ieee80211_node *ieee80211_find_node_locked(struct ieee80211_node_table *, - const uint8_t macaddr[IEEE80211_ADDR_LEN]); -struct ieee80211_node *ieee80211_find_node(struct ieee80211_node_table *, - const uint8_t macaddr[IEEE80211_ADDR_LEN]); -struct ieee80211_node *ieee80211_find_vap_node_locked( - struct ieee80211_node_table *, const struct ieee80211vap *, - const uint8_t macaddr[IEEE80211_ADDR_LEN]); -struct ieee80211_node *ieee80211_find_vap_node( - struct ieee80211_node_table *, const struct ieee80211vap *, - const uint8_t macaddr[IEEE80211_ADDR_LEN]); -struct ieee80211_node * ieee80211_find_rxnode(struct ieee80211com *, - const struct ieee80211_frame_min *); -struct ieee80211_node * ieee80211_find_rxnode_withkey(struct ieee80211com *, - const struct ieee80211_frame_min *, uint16_t keyix); -struct ieee80211_node *ieee80211_find_txnode(struct ieee80211vap *, - const uint8_t macaddr[IEEE80211_ADDR_LEN]); -#endif -int ieee80211_node_delucastkey(struct ieee80211_node *); -void ieee80211_node_timeout(void *arg); - -typedef void ieee80211_iter_func(void *, struct ieee80211_node *); -void ieee80211_iterate_nodes(struct ieee80211_node_table *, - ieee80211_iter_func *, void *); - -void ieee80211_notify_erp(struct ieee80211com *); -void ieee80211_dump_node(struct ieee80211_node_table *, - struct ieee80211_node *); -void ieee80211_dump_nodes(struct ieee80211_node_table *); - -struct ieee80211_node *ieee80211_fakeup_adhoc_node(struct ieee80211vap *, - const uint8_t macaddr[IEEE80211_ADDR_LEN]); -struct ieee80211_scanparams; -void ieee80211_init_neighbor(struct ieee80211_node *, - const struct ieee80211_frame *, - const struct ieee80211_scanparams *); -struct ieee80211_node *ieee80211_add_neighbor(struct ieee80211vap *, - const struct ieee80211_frame *, - const struct ieee80211_scanparams *); -void ieee80211_node_join(struct ieee80211_node *,int); -void ieee80211_node_leave(struct ieee80211_node *); -int8_t ieee80211_getrssi(struct ieee80211vap *); -void ieee80211_getsignal(struct ieee80211vap *, int8_t *, int8_t *); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_NODE_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_output.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_output.c deleted file mode 100644 index eb5ccb309d..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_output.c +++ /dev/null @@ -1,3065 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_inet.h" -#include "opt_inet6.h" -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#ifdef IEEE80211_SUPPORT_SUPERG -#include -#endif -#ifdef IEEE80211_SUPPORT_TDMA -#include -#endif -#include -#include - -#if defined(INET) || defined(INET6) -#include -#endif - -#ifdef INET -#include -#include -#include -#endif -#ifdef INET6 -#include -#endif - -#include - -#define ETHER_HEADER_COPY(dst, src) \ - memcpy(dst, src, sizeof(struct ether_header)) - -/* unalligned little endian access */ -#define LE_WRITE_2(p, v) do { \ - ((uint8_t *)(p))[0] = (v) & 0xff; \ - ((uint8_t *)(p))[1] = ((v) >> 8) & 0xff; \ -} while (0) -#define LE_WRITE_4(p, v) do { \ - ((uint8_t *)(p))[0] = (v) & 0xff; \ - ((uint8_t *)(p))[1] = ((v) >> 8) & 0xff; \ - ((uint8_t *)(p))[2] = ((v) >> 16) & 0xff; \ - ((uint8_t *)(p))[3] = ((v) >> 24) & 0xff; \ -} while (0) - -static int ieee80211_fragment(struct ieee80211vap *, struct mbuf *, - u_int hdrsize, u_int ciphdrsize, u_int mtu); -static void ieee80211_tx_mgt_cb(struct ieee80211_node *, void *, int); - -#ifdef IEEE80211_DEBUG -/* - * Decide if an outbound management frame should be - * printed when debugging is enabled. This filters some - * of the less interesting frames that come frequently - * (e.g. beacons). - */ -static __inline int -doprint(struct ieee80211vap *vap, int subtype) -{ - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - return (vap->iv_opmode == IEEE80211_M_IBSS); - } - return 1; -} -#endif - -/* - * Start method for vap's. All packets from the stack come - * through here. We handle common processing of the packets - * before dispatching them to the underlying device. - */ -void -ieee80211_start(struct ifnet *ifp) -{ -#define IS_DWDS(vap) \ - (vap->iv_opmode == IEEE80211_M_WDS && \ - (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY) == 0) - struct ieee80211vap *vap = ifp->if_softc; - struct ieee80211com *ic = vap->iv_ic; - struct ifnet *parent = ic->ic_ifp; - struct ieee80211_node *ni; - struct mbuf *m; - struct ether_header *eh; - int error; - - /* NB: parent must be up and running */ - if (!IFNET_IS_UP_RUNNING(parent)) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, - "%s: ignore queue, parent %s not up+running\n", - __func__, parent->if_xname); - /* XXX stat */ - return; - } - if (vap->iv_state == IEEE80211_S_SLEEP) { - /* - * In power save, wakeup device for transmit. - */ - ieee80211_new_state(vap, IEEE80211_S_RUN, 0); - return; - } - /* - * No data frames go out unless we're running. - * Note in particular this covers CAC and CSA - * states (though maybe we should check muting - * for CSA). - */ - if (vap->iv_state != IEEE80211_S_RUN) { - IEEE80211_LOCK(ic); - /* re-check under the com lock to avoid races */ - if (vap->iv_state != IEEE80211_S_RUN) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, - "%s: ignore queue, in %s state\n", - __func__, ieee80211_state_name[vap->iv_state]); - vap->iv_stats.is_tx_badstate++; - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - IEEE80211_UNLOCK(ic); - return; - } - IEEE80211_UNLOCK(ic); - } - for (;;) { - IFQ_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - /* - * Sanitize mbuf flags for net80211 use. We cannot - * clear M_PWR_SAV or M_MORE_DATA because these may - * be set for frames that are re-submitted from the - * power save queue. - * - * NB: This must be done before ieee80211_classify as - * it marks EAPOL in frames with M_EAPOL. - */ - m->m_flags &= ~(M_80211_TX - M_PWR_SAV - M_MORE_DATA); - /* - * Cancel any background scan. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) - ieee80211_cancel_anyscan(vap); - /* - * Find the node for the destination so we can do - * things like power save and fast frames aggregation. - * - * NB: past this point various code assumes the first - * mbuf has the 802.3 header present (and contiguous). - */ - ni = NULL; - if (m->m_len < sizeof(struct ether_header) && - (m = m_pullup(m, sizeof(struct ether_header))) == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, - "discard frame, %s\n", "m_pullup failed"); - vap->iv_stats.is_tx_nobuf++; /* XXX */ - ifp->if_oerrors++; - continue; - } - eh = mtod(m, struct ether_header *); - if (ETHER_IS_MULTICAST(eh->ether_dhost)) { - if (IS_DWDS(vap)) { - /* - * Only unicast frames from the above go out - * DWDS vaps; multicast frames are handled by - * dispatching the frame as it comes through - * the AP vap (see below). - */ - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_WDS, - eh->ether_dhost, "mcast", "%s", "on DWDS"); - vap->iv_stats.is_dwds_mcast++; - m_freem(m); - continue; - } - if (vap->iv_opmode == IEEE80211_M_HOSTAP) { - /* - * Spam DWDS vap's w/ multicast traffic. - */ - /* XXX only if dwds in use? */ - ieee80211_dwds_mcast(vap, m); - } - } -#ifdef IEEE80211_SUPPORT_MESH - if (vap->iv_opmode != IEEE80211_M_MBSS) { -#endif - ni = ieee80211_find_txnode(vap, eh->ether_dhost); - if (ni == NULL) { - /* NB: ieee80211_find_txnode does stat+msg */ - ifp->if_oerrors++; - m_freem(m); - continue; - } - if (ni->ni_associd == 0 && - (ni->ni_flags & IEEE80211_NODE_ASSOCID)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_OUTPUT, - eh->ether_dhost, NULL, - "sta not associated (type 0x%04x)", - htons(eh->ether_type)); - vap->iv_stats.is_tx_notassoc++; - ifp->if_oerrors++; - m_freem(m); - ieee80211_free_node(ni); - continue; - } -#ifdef IEEE80211_SUPPORT_MESH - } else { - if (!IEEE80211_ADDR_EQ(eh->ether_shost, vap->iv_myaddr)) { - /* - * Proxy station only if configured. - */ - if (!ieee80211_mesh_isproxyena(vap)) { - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_OUTPUT | - IEEE80211_MSG_MESH, - eh->ether_dhost, NULL, - "%s", "proxy not enabled"); - vap->iv_stats.is_mesh_notproxy++; - ifp->if_oerrors++; - m_freem(m); - continue; - } - ieee80211_mesh_proxy_check(vap, eh->ether_shost); - } - ni = ieee80211_mesh_discover(vap, eh->ether_dhost, m); - if (ni == NULL) { - /* - * NB: ieee80211_mesh_discover holds/disposes - * frame (e.g. queueing on path discovery). - */ - ifp->if_oerrors++; - continue; - } - } -#endif - if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && - (m->m_flags & M_PWR_SAV) == 0) { - /* - * Station in power save mode; pass the frame - * to the 802.11 layer and continue. We'll get - * the frame back when the time is right. - * XXX lose WDS vap linkage? - */ - (void) ieee80211_pwrsave(ni, m); - ieee80211_free_node(ni); - continue; - } - /* calculate priority so drivers can find the tx queue */ - if (ieee80211_classify(ni, m)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_OUTPUT, - eh->ether_dhost, NULL, - "%s", "classification failure"); - vap->iv_stats.is_tx_classify++; - ifp->if_oerrors++; - m_freem(m); - ieee80211_free_node(ni); - continue; - } - /* - * Stash the node pointer. Note that we do this after - * any call to ieee80211_dwds_mcast because that code - * uses any existing value for rcvif to identify the - * interface it (might have been) received on. - */ - m->m_pkthdr.rcvif = (void *)ni; - - BPF_MTAP(ifp, m); /* 802.3 tx */ - - /* - * Check if A-MPDU tx aggregation is setup or if we - * should try to enable it. The sta must be associated - * with HT and A-MPDU enabled for use. When the policy - * routine decides we should enable A-MPDU we issue an - * ADDBA request and wait for a reply. The frame being - * encapsulated will go out w/o using A-MPDU, or possibly - * it might be collected by the driver and held/retransmit. - * The default ic_ampdu_enable routine handles staggering - * ADDBA requests in case the receiver NAK's us or we are - * otherwise unable to establish a BA stream. - */ - if ((ni->ni_flags & IEEE80211_NODE_AMPDU_TX) && - (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_TX) && - (m->m_flags & M_EAPOL) == 0) { - const int ac = M_WME_GETAC(m); - struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[ac]; - - ieee80211_txampdu_count_packet(tap); - if (IEEE80211_AMPDU_RUNNING(tap)) { - /* - * Operational, mark frame for aggregation. - * - * XXX do tx aggregation here - */ - m->m_flags |= M_AMPDU_MPDU; - } else if (!IEEE80211_AMPDU_REQUESTED(tap) && - ic->ic_ampdu_enable(ni, tap)) { - /* - * Not negotiated yet, request service. - */ - ieee80211_ampdu_request(ni, tap); - /* XXX hold frame for reply? */ - } - } -#ifdef IEEE80211_SUPPORT_SUPERG - else if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF)) { - m = ieee80211_ff_check(ni, m); - if (m == NULL) { - /* NB: any ni ref held on stageq */ - continue; - } - } -#endif /* IEEE80211_SUPPORT_SUPERG */ - if (__predict_true((vap->iv_caps & IEEE80211_C_8023ENCAP) == 0)) { - /* - * Encapsulate the packet in prep for transmission. - */ - m = ieee80211_encap(vap, ni, m); - if (m == NULL) { - /* NB: stat+msg handled in ieee80211_encap */ - ieee80211_free_node(ni); - continue; - } - } - - error = parent->if_transmit(parent, m); - if (error != 0) { - /* NB: IFQ_HANDOFF reclaims mbuf */ - ieee80211_free_node(ni); - } else { - ifp->if_opackets++; - } - ic->ic_lastdata = ticks; - } -#undef IS_DWDS -} - -/* - * 802.11 output routine. This is (currently) used only to - * connect bpf write calls to the 802.11 layer for injecting - * raw 802.11 frames. - */ -int -ieee80211_output(struct ifnet *ifp, struct mbuf *m, - struct sockaddr *dst, struct route *ro) -{ -#define senderr(e) do { error = (e); goto bad;} while (0) - struct ieee80211_node *ni = NULL; - struct ieee80211vap *vap; - struct ieee80211_frame *wh; - int error; - - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) { - /* - * Short-circuit requests if the vap is marked OACTIVE - * as this can happen because a packet came down through - * ieee80211_start before the vap entered RUN state in - * which case it's ok to just drop the frame. This - * should not be necessary but callers of if_output don't - * check OACTIVE. - */ - senderr(ENETDOWN); - } - vap = ifp->if_softc; - -#ifdef __HAIKU__ - return vap->iv_output(ifp, m, dst, ro); -#else - /* - * Hand to the 802.3 code if not tagged as - * a raw 802.11 frame. - */ - if (dst->sa_family != AF_IEEE80211) - return vap->iv_output(ifp, m, dst, ro); -#ifdef MAC - error = mac_ifnet_check_transmit(ifp, m); - if (error) - senderr(error); -#endif - if (ifp->if_flags & IFF_MONITOR) - senderr(ENETDOWN); - if (!IFNET_IS_UP_RUNNING(ifp)) - senderr(ENETDOWN); - if (vap->iv_state == IEEE80211_S_CAC) { - IEEE80211_DPRINTF(vap, - IEEE80211_MSG_OUTPUT | IEEE80211_MSG_DOTH, - "block %s frame in CAC state\n", "raw data"); - vap->iv_stats.is_tx_badstate++; - senderr(EIO); /* XXX */ - } else if (vap->iv_state == IEEE80211_S_SCAN) - senderr(EIO); - /* XXX bypass bridge, pfil, carp, etc. */ - - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_ack)) - senderr(EIO); /* XXX */ - wh = mtod(m, struct ieee80211_frame *); - if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != - IEEE80211_FC0_VERSION_0) - senderr(EIO); /* XXX */ - - /* locate destination node */ - switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { - case IEEE80211_FC1_DIR_NODS: - case IEEE80211_FC1_DIR_FROMDS: - ni = ieee80211_find_txnode(vap, wh->i_addr1); - break; - case IEEE80211_FC1_DIR_TODS: - case IEEE80211_FC1_DIR_DSTODS: - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) - senderr(EIO); /* XXX */ - ni = ieee80211_find_txnode(vap, wh->i_addr3); - break; - default: - senderr(EIO); /* XXX */ - } - if (ni == NULL) { - /* - * Permit packets w/ bpf params through regardless - * (see below about sa_len). - */ - if (dst->sa_len == 0) - senderr(EHOSTUNREACH); - ni = ieee80211_ref_node(vap->iv_bss); - } - - /* - * Sanitize mbuf for net80211 flags leaked from above. - * - * NB: This must be done before ieee80211_classify as - * it marks EAPOL in frames with M_EAPOL. - */ - m->m_flags &= ~M_80211_TX; - - /* calculate priority so drivers can find the tx queue */ - /* XXX assumes an 802.3 frame */ - if (ieee80211_classify(ni, m)) - senderr(EIO); /* XXX */ - - ifp->if_opackets++; - IEEE80211_NODE_STAT(ni, tx_data); - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { - IEEE80211_NODE_STAT(ni, tx_mcast); - m->m_flags |= M_MCAST; - } else - IEEE80211_NODE_STAT(ni, tx_ucast); - /* NB: ieee80211_encap does not include 802.11 header */ - IEEE80211_NODE_STAT_ADD(ni, tx_bytes, m->m_pkthdr.len); - - /* - * NB: DLT_IEEE802_11_RADIO identifies the parameters are - * present by setting the sa_len field of the sockaddr (yes, - * this is a hack). - * NB: we assume sa_data is suitably aligned to cast. - */ - return vap->iv_ic->ic_raw_xmit(ni, m, - (const struct ieee80211_bpf_params *)(dst->sa_len ? - dst->sa_data : NULL)); -#endif -bad: - if (m != NULL) - m_freem(m); - if (ni != NULL) - ieee80211_free_node(ni); - ifp->if_oerrors++; - return error; -#undef senderr -} - -/* - * Set the direction field and address fields of an outgoing - * frame. Note this should be called early on in constructing - * a frame as it sets i_fc[1]; other bits can then be or'd in. - */ -void -ieee80211_send_setup( - struct ieee80211_node *ni, - struct mbuf *m, - int type, int tid, - const uint8_t sa[IEEE80211_ADDR_LEN], - const uint8_t da[IEEE80211_ADDR_LEN], - const uint8_t bssid[IEEE80211_ADDR_LEN]) -{ -#define WH4(wh) ((struct ieee80211_frame_addr4 *)wh) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_tx_ampdu *tap; - struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); - ieee80211_seq seqno; - - wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | type; - if ((type & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) { - switch (vap->iv_opmode) { - case IEEE80211_M_STA: - wh->i_fc[1] = IEEE80211_FC1_DIR_TODS; - IEEE80211_ADDR_COPY(wh->i_addr1, bssid); - IEEE80211_ADDR_COPY(wh->i_addr2, sa); - IEEE80211_ADDR_COPY(wh->i_addr3, da); - break; - case IEEE80211_M_IBSS: - case IEEE80211_M_AHDEMO: - wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; - IEEE80211_ADDR_COPY(wh->i_addr1, da); - IEEE80211_ADDR_COPY(wh->i_addr2, sa); - IEEE80211_ADDR_COPY(wh->i_addr3, bssid); - break; - case IEEE80211_M_HOSTAP: - wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS; - IEEE80211_ADDR_COPY(wh->i_addr1, da); - IEEE80211_ADDR_COPY(wh->i_addr2, bssid); - IEEE80211_ADDR_COPY(wh->i_addr3, sa); - break; - case IEEE80211_M_WDS: - wh->i_fc[1] = IEEE80211_FC1_DIR_DSTODS; - IEEE80211_ADDR_COPY(wh->i_addr1, da); - IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr); - IEEE80211_ADDR_COPY(wh->i_addr3, da); - IEEE80211_ADDR_COPY(WH4(wh)->i_addr4, sa); - break; - case IEEE80211_M_MBSS: -#ifdef IEEE80211_SUPPORT_MESH - /* XXX add support for proxied addresses */ - if (IEEE80211_IS_MULTICAST(da)) { - wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS; - /* XXX next hop */ - IEEE80211_ADDR_COPY(wh->i_addr1, da); - IEEE80211_ADDR_COPY(wh->i_addr2, - vap->iv_myaddr); - } else { - wh->i_fc[1] = IEEE80211_FC1_DIR_DSTODS; - IEEE80211_ADDR_COPY(wh->i_addr1, da); - IEEE80211_ADDR_COPY(wh->i_addr2, - vap->iv_myaddr); - IEEE80211_ADDR_COPY(wh->i_addr3, da); - IEEE80211_ADDR_COPY(WH4(wh)->i_addr4, sa); - } -#endif - break; - case IEEE80211_M_MONITOR: /* NB: to quiet compiler */ - break; - } - } else { - wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; - IEEE80211_ADDR_COPY(wh->i_addr1, da); - IEEE80211_ADDR_COPY(wh->i_addr2, sa); -#ifdef IEEE80211_SUPPORT_MESH - if (vap->iv_opmode == IEEE80211_M_MBSS) - IEEE80211_ADDR_COPY(wh->i_addr3, sa); - else -#endif - IEEE80211_ADDR_COPY(wh->i_addr3, bssid); - } - *(uint16_t *)&wh->i_dur[0] = 0; - - tap = &ni->ni_tx_ampdu[TID_TO_WME_AC(tid)]; - if (tid != IEEE80211_NONQOS_TID && IEEE80211_AMPDU_RUNNING(tap)) - m->m_flags |= M_AMPDU_MPDU; - else { - seqno = ni->ni_txseqs[tid]++; - *(uint16_t *)&wh->i_seq[0] = - htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT); - M_SEQNO_SET(m, seqno); - } - - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) - m->m_flags |= M_MCAST; -#undef WH4 -} - -/* - * Send a management frame to the specified node. The node pointer - * must have a reference as the pointer will be passed to the driver - * and potentially held for a long time. If the frame is successfully - * dispatched to the driver, then it is responsible for freeing the - * reference (and potentially free'ing up any associated storage); - * otherwise deal with reclaiming any reference (on error). - */ -int -ieee80211_mgmt_output(struct ieee80211_node *ni, struct mbuf *m, int type, - struct ieee80211_bpf_params *params) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_frame *wh; - - KASSERT(ni != NULL, ("null node")); - - if (vap->iv_state == IEEE80211_S_CAC) { - IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT | IEEE80211_MSG_DOTH, - ni, "block %s frame in CAC state", - ieee80211_mgt_subtype_name[ - (type & IEEE80211_FC0_SUBTYPE_MASK) >> - IEEE80211_FC0_SUBTYPE_SHIFT]); - vap->iv_stats.is_tx_badstate++; - ieee80211_free_node(ni); - m_freem(m); - return EIO; /* XXX */ - } - - M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT); - if (m == NULL) { - ieee80211_free_node(ni); - return ENOMEM; - } - - wh = mtod(m, struct ieee80211_frame *); - ieee80211_send_setup(ni, m, - IEEE80211_FC0_TYPE_MGT | type, IEEE80211_NONQOS_TID, - vap->iv_myaddr, ni->ni_macaddr, ni->ni_bssid); - if (params->ibp_flags & IEEE80211_BPF_CRYPTO) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_AUTH, wh->i_addr1, - "encrypting frame (%s)", __func__); - wh->i_fc[1] |= IEEE80211_FC1_WEP; - } - m->m_flags |= M_ENCAP; /* mark encapsulated */ - - KASSERT(type != IEEE80211_FC0_SUBTYPE_PROBE_RESP, ("probe response?")); - M_WME_SETAC(m, params->ibp_pri); - -#ifdef IEEE80211_DEBUG - /* avoid printing too many frames */ - if ((ieee80211_msg_debug(vap) && doprint(vap, type)) || - ieee80211_msg_dumppkts(vap)) { - printf("[%s] send %s on channel %u\n", - ether_sprintf(wh->i_addr1), - ieee80211_mgt_subtype_name[ - (type & IEEE80211_FC0_SUBTYPE_MASK) >> - IEEE80211_FC0_SUBTYPE_SHIFT], - ieee80211_chan2ieee(ic, ic->ic_curchan)); - } -#endif - IEEE80211_NODE_STAT(ni, tx_mgmt); - - return ic->ic_raw_xmit(ni, m, params); -} - -/* - * Send a null data frame to the specified node. If the station - * is setup for QoS then a QoS Null Data frame is constructed. - * If this is a WDS station then a 4-address frame is constructed. - * - * NB: the caller is assumed to have setup a node reference - * for use; this is necessary to deal with a race condition - * when probing for inactive stations. Like ieee80211_mgmt_output - * we must cleanup any node reference on error; however we - * can safely just unref it as we know it will never be the - * last reference to the node. - */ -int -ieee80211_send_nulldata(struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct mbuf *m; - struct ieee80211_frame *wh; - int hdrlen; - uint8_t *frm; - - if (vap->iv_state == IEEE80211_S_CAC) { - IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT | IEEE80211_MSG_DOTH, - ni, "block %s frame in CAC state", "null data"); - ieee80211_unref_node(&ni); - vap->iv_stats.is_tx_badstate++; - return EIO; /* XXX */ - } - - if (ni->ni_flags & (IEEE80211_NODE_QOS|IEEE80211_NODE_HT)) - hdrlen = sizeof(struct ieee80211_qosframe); - else - hdrlen = sizeof(struct ieee80211_frame); - /* NB: only WDS vap's get 4-address frames */ - if (vap->iv_opmode == IEEE80211_M_WDS) - hdrlen += IEEE80211_ADDR_LEN; - if (ic->ic_flags & IEEE80211_F_DATAPAD) - hdrlen = roundup(hdrlen, sizeof(uint32_t)); - - m = ieee80211_getmgtframe(&frm, ic->ic_headroom + hdrlen, 0); - if (m == NULL) { - /* XXX debug msg */ - ieee80211_unref_node(&ni); - vap->iv_stats.is_tx_nobuf++; - return ENOMEM; - } - KASSERT(M_LEADINGSPACE(m) >= hdrlen, - ("leading space %zd", M_LEADINGSPACE(m))); - M_PREPEND(m, hdrlen, M_DONTWAIT); - if (m == NULL) { - /* NB: cannot happen */ - ieee80211_free_node(ni); - return ENOMEM; - } - - wh = mtod(m, struct ieee80211_frame *); /* NB: a little lie */ - if (ni->ni_flags & IEEE80211_NODE_QOS) { - const int tid = WME_AC_TO_TID(WME_AC_BE); - uint8_t *qos; - - ieee80211_send_setup(ni, m, - IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS_NULL, - tid, vap->iv_myaddr, ni->ni_macaddr, ni->ni_bssid); - - if (vap->iv_opmode == IEEE80211_M_WDS) - qos = ((struct ieee80211_qosframe_addr4 *) wh)->i_qos; - else - qos = ((struct ieee80211_qosframe *) wh)->i_qos; - qos[0] = tid & IEEE80211_QOS_TID; - if (ic->ic_wme.wme_wmeChanParams.cap_wmeParams[WME_AC_BE].wmep_noackPolicy) - qos[0] |= IEEE80211_QOS_ACKPOLICY_NOACK; - qos[1] = 0; - } else { - ieee80211_send_setup(ni, m, - IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_NODATA, - IEEE80211_NONQOS_TID, - vap->iv_myaddr, ni->ni_macaddr, ni->ni_bssid); - } - if (vap->iv_opmode != IEEE80211_M_WDS) { - /* NB: power management bit is never sent by an AP */ - if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && - vap->iv_opmode != IEEE80211_M_HOSTAP) - wh->i_fc[1] |= IEEE80211_FC1_PWR_MGT; - } - m->m_len = m->m_pkthdr.len = hdrlen; - m->m_flags |= M_ENCAP; /* mark encapsulated */ - - M_WME_SETAC(m, WME_AC_BE); - - IEEE80211_NODE_STAT(ni, tx_data); - - IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_DUMPPKTS, ni, - "send %snull data frame on channel %u, pwr mgt %s", - ni->ni_flags & IEEE80211_NODE_QOS ? "QoS " : "", - ieee80211_chan2ieee(ic, ic->ic_curchan), - wh->i_fc[1] & IEEE80211_FC1_PWR_MGT ? "ena" : "dis"); - - return ic->ic_raw_xmit(ni, m, NULL); -} - -/* - * Assign priority to a frame based on any vlan tag assigned - * to the station and/or any Diffserv setting in an IP header. - * Finally, if an ACM policy is setup (in station mode) it's - * applied. - */ -int -ieee80211_classify(struct ieee80211_node *ni, struct mbuf *m) -{ - const struct ether_header *eh = mtod(m, struct ether_header *); - int v_wme_ac, d_wme_ac, ac; - - /* - * Always promote PAE/EAPOL frames to high priority. - */ - if (eh->ether_type == htons(ETHERTYPE_PAE)) { - /* NB: mark so others don't need to check header */ - m->m_flags |= M_EAPOL; - ac = WME_AC_VO; - goto done; - } - /* - * Non-qos traffic goes to BE. - */ - if ((ni->ni_flags & IEEE80211_NODE_QOS) == 0) { - ac = WME_AC_BE; - goto done; - } - - /* - * If node has a vlan tag then all traffic - * to it must have a matching tag. - */ - v_wme_ac = 0; - if (ni->ni_vlan != 0) { - if ((m->m_flags & M_VLANTAG) == 0) { - IEEE80211_NODE_STAT(ni, tx_novlantag); - return 1; - } - if (EVL_VLANOFTAG(m->m_pkthdr.ether_vtag) != - EVL_VLANOFTAG(ni->ni_vlan)) { - IEEE80211_NODE_STAT(ni, tx_vlanmismatch); - return 1; - } - /* map vlan priority to AC */ - v_wme_ac = TID_TO_WME_AC(EVL_PRIOFTAG(ni->ni_vlan)); - } - - /* XXX m_copydata may be too slow for fast path */ -#ifdef INET - if (eh->ether_type == htons(ETHERTYPE_IP)) { - uint8_t tos; - /* - * IP frame, map the DSCP bits from the TOS field. - */ - /* NB: ip header may not be in first mbuf */ - m_copydata(m, sizeof(struct ether_header) + - offsetof(struct ip, ip_tos), sizeof(tos), &tos); - tos >>= 5; /* NB: ECN + low 3 bits of DSCP */ - d_wme_ac = TID_TO_WME_AC(tos); - } else { -#endif /* INET */ -#ifdef INET6 - if (eh->ether_type == htons(ETHERTYPE_IPV6)) { - uint32_t flow; - uint8_t tos; - /* - * IPv6 frame, map the DSCP bits from the TOS field. - */ - m_copydata(m, sizeof(struct ether_header) + - offsetof(struct ip6_hdr, ip6_flow), sizeof(flow), - (caddr_t) &flow); - tos = (uint8_t)(ntohl(flow) >> 20); - tos >>= 5; /* NB: ECN + low 3 bits of DSCP */ - d_wme_ac = TID_TO_WME_AC(tos); - } else { -#endif /* INET6 */ - d_wme_ac = WME_AC_BE; -#ifdef INET6 - } -#endif -#ifdef INET - } -#endif - /* - * Use highest priority AC. - */ - if (v_wme_ac > d_wme_ac) - ac = v_wme_ac; - else - ac = d_wme_ac; - - /* - * Apply ACM policy. - */ - if (ni->ni_vap->iv_opmode == IEEE80211_M_STA) { - static const int acmap[4] = { - WME_AC_BK, /* WME_AC_BE */ - WME_AC_BK, /* WME_AC_BK */ - WME_AC_BE, /* WME_AC_VI */ - WME_AC_VI, /* WME_AC_VO */ - }; - struct ieee80211com *ic = ni->ni_ic; - - while (ac != WME_AC_BK && - ic->ic_wme.wme_wmeBssChanParams.cap_wmeParams[ac].wmep_acm) - ac = acmap[ac]; - } -done: - M_WME_SETAC(m, ac); - return 0; -} - -/* - * Insure there is sufficient contiguous space to encapsulate the - * 802.11 data frame. If room isn't already there, arrange for it. - * Drivers and cipher modules assume we have done the necessary work - * and fail rudely if they don't find the space they need. - */ -struct mbuf * -ieee80211_mbuf_adjust(struct ieee80211vap *vap, int hdrsize, - struct ieee80211_key *key, struct mbuf *m) -{ -#define TO_BE_RECLAIMED (sizeof(struct ether_header) - sizeof(struct llc)) - int needed_space = vap->iv_ic->ic_headroom + hdrsize; - - if (key != NULL) { - /* XXX belongs in crypto code? */ - needed_space += key->wk_cipher->ic_header; - /* XXX frags */ - /* - * When crypto is being done in the host we must insure - * the data are writable for the cipher routines; clone - * a writable mbuf chain. - * XXX handle SWMIC specially - */ - if (key->wk_flags & (IEEE80211_KEY_SWENCRYPT|IEEE80211_KEY_SWENMIC)) { - m = m_unshare(m, M_NOWAIT); - if (m == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, - "%s: cannot get writable mbuf\n", __func__); - vap->iv_stats.is_tx_nobuf++; /* XXX new stat */ - return NULL; - } - } - } - /* - * We know we are called just before stripping an Ethernet - * header and prepending an LLC header. This means we know - * there will be - * sizeof(struct ether_header) - sizeof(struct llc) - * bytes recovered to which we need additional space for the - * 802.11 header and any crypto header. - */ - /* XXX check trailing space and copy instead? */ - if (M_LEADINGSPACE(m) < needed_space - TO_BE_RECLAIMED) { - struct mbuf *n = m_gethdr(M_NOWAIT, m->m_type); - if (n == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, - "%s: cannot expand storage\n", __func__); - vap->iv_stats.is_tx_nobuf++; - m_freem(m); - return NULL; - } - KASSERT(needed_space <= MHLEN, - ("not enough room, need %u got %zu\n", needed_space, MHLEN)); - /* - * Setup new mbuf to have leading space to prepend the - * 802.11 header and any crypto header bits that are - * required (the latter are added when the driver calls - * back to ieee80211_crypto_encap to do crypto encapsulation). - */ - /* NB: must be first 'cuz it clobbers m_data */ - m_move_pkthdr(n, m); - n->m_len = 0; /* NB: m_gethdr does not set */ - n->m_data += needed_space; - /* - * Pull up Ethernet header to create the expected layout. - * We could use m_pullup but that's overkill (i.e. we don't - * need the actual data) and it cannot fail so do it inline - * for speed. - */ - /* NB: struct ether_header is known to be contiguous */ - n->m_len += sizeof(struct ether_header); - m->m_len -= sizeof(struct ether_header); - m->m_data += sizeof(struct ether_header); - /* - * Replace the head of the chain. - */ - n->m_next = m; - m = n; - } - return m; -#undef TO_BE_RECLAIMED -} - -/* - * Return the transmit key to use in sending a unicast frame. - * If a unicast key is set we use that. When no unicast key is set - * we fall back to the default transmit key. - */ -static __inline struct ieee80211_key * -ieee80211_crypto_getucastkey(struct ieee80211vap *vap, - struct ieee80211_node *ni) -{ - if (IEEE80211_KEY_UNDEFINED(&ni->ni_ucastkey)) { - if (vap->iv_def_txkey == IEEE80211_KEYIX_NONE || - IEEE80211_KEY_UNDEFINED(&vap->iv_nw_keys[vap->iv_def_txkey])) - return NULL; - return &vap->iv_nw_keys[vap->iv_def_txkey]; - } else { - return &ni->ni_ucastkey; - } -} - -/* - * Return the transmit key to use in sending a multicast frame. - * Multicast traffic always uses the group key which is installed as - * the default tx key. - */ -static __inline struct ieee80211_key * -ieee80211_crypto_getmcastkey(struct ieee80211vap *vap, - struct ieee80211_node *ni) -{ - if (vap->iv_def_txkey == IEEE80211_KEYIX_NONE || - IEEE80211_KEY_UNDEFINED(&vap->iv_nw_keys[vap->iv_def_txkey])) - return NULL; - return &vap->iv_nw_keys[vap->iv_def_txkey]; -} - -/* - * Encapsulate an outbound data frame. The mbuf chain is updated. - * If an error is encountered NULL is returned. The caller is required - * to provide a node reference and pullup the ethernet header in the - * first mbuf. - * - * NB: Packet is assumed to be processed by ieee80211_classify which - * marked EAPOL frames w/ M_EAPOL. - */ -struct mbuf * -ieee80211_encap(struct ieee80211vap *vap, struct ieee80211_node *ni, - struct mbuf *m) -{ -#define WH4(wh) ((struct ieee80211_frame_addr4 *)(wh)) - struct ieee80211com *ic = ni->ni_ic; -#ifdef IEEE80211_SUPPORT_MESH - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct ieee80211_meshcntl_ae10 *mc; -#endif - struct ether_header eh; - struct ieee80211_frame *wh; - struct ieee80211_key *key; - struct llc *llc; - int hdrsize, hdrspace, datalen, addqos, txfrag, is4addr; - ieee80211_seq seqno; - int meshhdrsize, meshae; - uint8_t *qos; - - /* - * Copy existing Ethernet header to a safe place. The - * rest of the code assumes it's ok to strip it when - * reorganizing state for the final encapsulation. - */ - KASSERT(m->m_len >= sizeof(eh), ("no ethernet header!")); - ETHER_HEADER_COPY(&eh, mtod(m, caddr_t)); - - /* - * Insure space for additional headers. First identify - * transmit key to use in calculating any buffer adjustments - * required. This is also used below to do privacy - * encapsulation work. Then calculate the 802.11 header - * size and any padding required by the driver. - * - * Note key may be NULL if we fall back to the default - * transmit key and that is not set. In that case the - * buffer may not be expanded as needed by the cipher - * routines, but they will/should discard it. - */ - if (vap->iv_flags & IEEE80211_F_PRIVACY) { - if (vap->iv_opmode == IEEE80211_M_STA || - !IEEE80211_IS_MULTICAST(eh.ether_dhost) || - (vap->iv_opmode == IEEE80211_M_WDS && - (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY))) - key = ieee80211_crypto_getucastkey(vap, ni); - else - key = ieee80211_crypto_getmcastkey(vap, ni); - if (key == NULL && (m->m_flags & M_EAPOL) == 0) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, - eh.ether_dhost, - "no default transmit key (%s) deftxkey %u", - __func__, vap->iv_def_txkey); - vap->iv_stats.is_tx_nodefkey++; - goto bad; - } - } else - key = NULL; - /* - * XXX Some ap's don't handle QoS-encapsulated EAPOL - * frames so suppress use. This may be an issue if other - * ap's require all data frames to be QoS-encapsulated - * once negotiated in which case we'll need to make this - * configurable. - */ - addqos = (ni->ni_flags & (IEEE80211_NODE_QOS|IEEE80211_NODE_HT)) && - (m->m_flags & M_EAPOL) == 0; - if (addqos) - hdrsize = sizeof(struct ieee80211_qosframe); - else - hdrsize = sizeof(struct ieee80211_frame); -#ifdef IEEE80211_SUPPORT_MESH - if (vap->iv_opmode == IEEE80211_M_MBSS) { - /* - * Mesh data frames are encapsulated according to the - * rules of Section 11B.8.5 (p.139 of D3.0 spec). - * o Group Addressed data (aka multicast) originating - * at the local sta are sent w/ 3-address format and - * address extension mode 00 - * o Individually Addressed data (aka unicast) originating - * at the local sta are sent w/ 4-address format and - * address extension mode 00 - * o Group Addressed data forwarded from a non-mesh sta are - * sent w/ 3-address format and address extension mode 01 - * o Individually Address data from another sta are sent - * w/ 4-address format and address extension mode 10 - */ - is4addr = 0; /* NB: don't use, disable */ - if (!IEEE80211_IS_MULTICAST(eh.ether_dhost)) - hdrsize += IEEE80211_ADDR_LEN; /* unicast are 4-addr */ - meshhdrsize = sizeof(struct ieee80211_meshcntl); - /* XXX defines for AE modes */ - if (IEEE80211_ADDR_EQ(eh.ether_shost, vap->iv_myaddr)) { - if (!IEEE80211_IS_MULTICAST(eh.ether_dhost)) - meshae = 0; - else - meshae = 4; /* NB: pseudo */ - } else if (IEEE80211_IS_MULTICAST(eh.ether_dhost)) { - meshae = 1; - meshhdrsize += 1*IEEE80211_ADDR_LEN; - } else { - meshae = 2; - meshhdrsize += 2*IEEE80211_ADDR_LEN; - } - } else { -#endif - /* - * 4-address frames need to be generated for: - * o packets sent through a WDS vap (IEEE80211_M_WDS) - * o packets sent through a vap marked for relaying - * (e.g. a station operating with dynamic WDS) - */ - is4addr = vap->iv_opmode == IEEE80211_M_WDS || - ((vap->iv_flags_ext & IEEE80211_FEXT_4ADDR) && - !IEEE80211_ADDR_EQ(eh.ether_shost, vap->iv_myaddr)); - if (is4addr) - hdrsize += IEEE80211_ADDR_LEN; - meshhdrsize = meshae = 0; -#ifdef IEEE80211_SUPPORT_MESH - } -#endif - /* - * Honor driver DATAPAD requirement. - */ - if (ic->ic_flags & IEEE80211_F_DATAPAD) - hdrspace = roundup(hdrsize, sizeof(uint32_t)); - else - hdrspace = hdrsize; - - if (__predict_true((m->m_flags & M_FF) == 0)) { - /* - * Normal frame. - */ - m = ieee80211_mbuf_adjust(vap, hdrspace + meshhdrsize, key, m); - if (m == NULL) { - /* NB: ieee80211_mbuf_adjust handles msgs+statistics */ - goto bad; - } - /* NB: this could be optimized 'cuz of ieee80211_mbuf_adjust */ - m_adj(m, sizeof(struct ether_header) - sizeof(struct llc)); - llc = mtod(m, struct llc *); - llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; - llc->llc_control = LLC_UI; - llc->llc_snap.org_code[0] = 0; - llc->llc_snap.org_code[1] = 0; - llc->llc_snap.org_code[2] = 0; - llc->llc_snap.ether_type = eh.ether_type; - } else { -#ifdef IEEE80211_SUPPORT_SUPERG - /* - * Aggregated frame. - */ - m = ieee80211_ff_encap(vap, m, hdrspace + meshhdrsize, key); - if (m == NULL) -#endif - goto bad; - } - datalen = m->m_pkthdr.len; /* NB: w/o 802.11 header */ - - M_PREPEND(m, hdrspace + meshhdrsize, M_DONTWAIT); - if (m == NULL) { - vap->iv_stats.is_tx_nobuf++; - goto bad; - } - wh = mtod(m, struct ieee80211_frame *); - wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA; - *(uint16_t *)wh->i_dur = 0; - qos = NULL; /* NB: quiet compiler */ - if (is4addr) { - wh->i_fc[1] = IEEE80211_FC1_DIR_DSTODS; - IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr); - IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr); - IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost); - IEEE80211_ADDR_COPY(WH4(wh)->i_addr4, eh.ether_shost); - } else switch (vap->iv_opmode) { - case IEEE80211_M_STA: - wh->i_fc[1] = IEEE80211_FC1_DIR_TODS; - IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_bssid); - IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost); - IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost); - break; - case IEEE80211_M_IBSS: - case IEEE80211_M_AHDEMO: - wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; - IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost); - IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost); - /* - * NB: always use the bssid from iv_bss as the - * neighbor's may be stale after an ibss merge - */ - IEEE80211_ADDR_COPY(wh->i_addr3, vap->iv_bss->ni_bssid); - break; - case IEEE80211_M_HOSTAP: - wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS; - IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost); - IEEE80211_ADDR_COPY(wh->i_addr2, ni->ni_bssid); - IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost); - break; -#ifdef IEEE80211_SUPPORT_MESH - case IEEE80211_M_MBSS: - /* NB: offset by hdrspace to deal with DATAPAD */ - mc = (struct ieee80211_meshcntl_ae10 *) - (mtod(m, uint8_t *) + hdrspace); - switch (meshae) { - case 0: /* ucast, no proxy */ - wh->i_fc[1] = IEEE80211_FC1_DIR_DSTODS; - IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr); - IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr); - IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost); - IEEE80211_ADDR_COPY(WH4(wh)->i_addr4, eh.ether_shost); - mc->mc_flags = 0; - qos = ((struct ieee80211_qosframe_addr4 *) wh)->i_qos; - break; - case 4: /* mcast, no proxy */ - wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS; - IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost); - IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr); - IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost); - mc->mc_flags = 0; /* NB: AE is really 0 */ - qos = ((struct ieee80211_qosframe *) wh)->i_qos; - break; - case 1: /* mcast, proxy */ - wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS; - IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost); - IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr); - IEEE80211_ADDR_COPY(wh->i_addr3, vap->iv_myaddr); - mc->mc_flags = 1; - IEEE80211_ADDR_COPY(mc->mc_addr4, eh.ether_shost); - qos = ((struct ieee80211_qosframe *) wh)->i_qos; - break; - case 2: /* ucast, proxy */ - wh->i_fc[1] = IEEE80211_FC1_DIR_DSTODS; - IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr); - IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr); - /* XXX not right, need MeshDA */ - IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost); - /* XXX assume are MeshSA */ - IEEE80211_ADDR_COPY(WH4(wh)->i_addr4, vap->iv_myaddr); - mc->mc_flags = 2; - IEEE80211_ADDR_COPY(mc->mc_addr4, eh.ether_dhost); - IEEE80211_ADDR_COPY(mc->mc_addr5, eh.ether_shost); - qos = ((struct ieee80211_qosframe_addr4 *) wh)->i_qos; - break; - default: - KASSERT(0, ("meshae %d", meshae)); - break; - } - mc->mc_ttl = ms->ms_ttl; - ms->ms_seq++; - LE_WRITE_4(mc->mc_seq, ms->ms_seq); - break; -#endif - case IEEE80211_M_WDS: /* NB: is4addr should always be true */ - default: - goto bad; - } - if (m->m_flags & M_MORE_DATA) - wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; - if (addqos) { - int ac, tid; - - if (is4addr) { - qos = ((struct ieee80211_qosframe_addr4 *) wh)->i_qos; - /* NB: mesh case handled earlier */ - } else if (vap->iv_opmode != IEEE80211_M_MBSS) - qos = ((struct ieee80211_qosframe *) wh)->i_qos; - ac = M_WME_GETAC(m); - /* map from access class/queue to 11e header priorty value */ - tid = WME_AC_TO_TID(ac); - qos[0] = tid & IEEE80211_QOS_TID; - if (ic->ic_wme.wme_wmeChanParams.cap_wmeParams[ac].wmep_noackPolicy) - qos[0] |= IEEE80211_QOS_ACKPOLICY_NOACK; - qos[1] = 0; - wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_QOS; - - if ((m->m_flags & M_AMPDU_MPDU) == 0) { - /* - * NB: don't assign a sequence # to potential - * aggregates; we expect this happens at the - * point the frame comes off any aggregation q - * as otherwise we may introduce holes in the - * BA sequence space and/or make window accouting - * more difficult. - * - * XXX may want to control this with a driver - * capability; this may also change when we pull - * aggregation up into net80211 - */ - seqno = ni->ni_txseqs[tid]++; - *(uint16_t *)wh->i_seq = - htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT); - M_SEQNO_SET(m, seqno); - } - } else { - seqno = ni->ni_txseqs[IEEE80211_NONQOS_TID]++; - *(uint16_t *)wh->i_seq = - htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT); - M_SEQNO_SET(m, seqno); - } - - - /* check if xmit fragmentation is required */ - txfrag = (m->m_pkthdr.len > vap->iv_fragthreshold && - !IEEE80211_IS_MULTICAST(wh->i_addr1) && - (vap->iv_caps & IEEE80211_C_TXFRAG) && - (m->m_flags & (M_FF | M_AMPDU_MPDU)) == 0); - if (key != NULL) { - /* - * IEEE 802.1X: send EAPOL frames always in the clear. - * WPA/WPA2: encrypt EAPOL keys when pairwise keys are set. - */ - if ((m->m_flags & M_EAPOL) == 0 || - ((vap->iv_flags & IEEE80211_F_WPA) && - (vap->iv_opmode == IEEE80211_M_STA ? - !IEEE80211_KEY_UNDEFINED(key) : - !IEEE80211_KEY_UNDEFINED(&ni->ni_ucastkey)))) { - wh->i_fc[1] |= IEEE80211_FC1_WEP; - if (!ieee80211_crypto_enmic(vap, key, m, txfrag)) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_OUTPUT, - eh.ether_dhost, - "%s", "enmic failed, discard frame"); - vap->iv_stats.is_crypto_enmicfail++; - goto bad; - } - } - } - if (txfrag && !ieee80211_fragment(vap, m, hdrsize, - key != NULL ? key->wk_cipher->ic_header : 0, vap->iv_fragthreshold)) - goto bad; - - m->m_flags |= M_ENCAP; /* mark encapsulated */ - - IEEE80211_NODE_STAT(ni, tx_data); - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { - IEEE80211_NODE_STAT(ni, tx_mcast); - m->m_flags |= M_MCAST; - } else - IEEE80211_NODE_STAT(ni, tx_ucast); - IEEE80211_NODE_STAT_ADD(ni, tx_bytes, datalen); - - return m; -bad: - if (m != NULL) - m_freem(m); - return NULL; -#undef WH4 -} - -/* - * Fragment the frame according to the specified mtu. - * The size of the 802.11 header (w/o padding) is provided - * so we don't need to recalculate it. We create a new - * mbuf for each fragment and chain it through m_nextpkt; - * we might be able to optimize this by reusing the original - * packet's mbufs but that is significantly more complicated. - */ -static int -ieee80211_fragment(struct ieee80211vap *vap, struct mbuf *m0, - u_int hdrsize, u_int ciphdrsize, u_int mtu) -{ - struct ieee80211_frame *wh, *whf; - struct mbuf *m, *prev, *next; - u_int totalhdrsize, fragno, fragsize, off, remainder, payload; - - KASSERT(m0->m_nextpkt == NULL, ("mbuf already chained?")); - KASSERT(m0->m_pkthdr.len > mtu, - ("pktlen %u mtu %u", m0->m_pkthdr.len, mtu)); - - wh = mtod(m0, struct ieee80211_frame *); - /* NB: mark the first frag; it will be propagated below */ - wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG; - totalhdrsize = hdrsize + ciphdrsize; - fragno = 1; - off = mtu - ciphdrsize; - remainder = m0->m_pkthdr.len - off; - prev = m0; - do { - fragsize = totalhdrsize + remainder; - if (fragsize > mtu) - fragsize = mtu; - /* XXX fragsize can be >2048! */ - KASSERT(fragsize < MCLBYTES, - ("fragment size %u too big!", fragsize)); - if (fragsize > MHLEN) - m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - else - m = m_gethdr(M_DONTWAIT, MT_DATA); - if (m == NULL) - goto bad; - /* leave room to prepend any cipher header */ - m_align(m, fragsize - ciphdrsize); - - /* - * Form the header in the fragment. Note that since - * we mark the first fragment with the MORE_FRAG bit - * it automatically is propagated to each fragment; we - * need only clear it on the last fragment (done below). - */ - whf = mtod(m, struct ieee80211_frame *); - memcpy(whf, wh, hdrsize); - *(uint16_t *)&whf->i_seq[0] |= htole16( - (fragno & IEEE80211_SEQ_FRAG_MASK) << - IEEE80211_SEQ_FRAG_SHIFT); - fragno++; - - payload = fragsize - totalhdrsize; - /* NB: destination is known to be contiguous */ - m_copydata(m0, off, payload, mtod(m, uint8_t *) + hdrsize); - m->m_len = hdrsize + payload; - m->m_pkthdr.len = hdrsize + payload; - m->m_flags |= M_FRAG; - - /* chain up the fragment */ - prev->m_nextpkt = m; - prev = m; - - /* deduct fragment just formed */ - remainder -= payload; - off += payload; - } while (remainder != 0); - - /* set the last fragment */ - m->m_flags |= M_LASTFRAG; - whf->i_fc[1] &= ~IEEE80211_FC1_MORE_FRAG; - - /* strip first mbuf now that everything has been copied */ - m_adj(m0, -(m0->m_pkthdr.len - (mtu - ciphdrsize))); - m0->m_flags |= M_FIRSTFRAG | M_FRAG; - - vap->iv_stats.is_tx_fragframes++; - vap->iv_stats.is_tx_frags += fragno-1; - - return 1; -bad: - /* reclaim fragments but leave original frame for caller to free */ - for (m = m0->m_nextpkt; m != NULL; m = next) { - next = m->m_nextpkt; - m->m_nextpkt = NULL; /* XXX paranoid */ - m_freem(m); - } - m0->m_nextpkt = NULL; - return 0; -} - -/* - * Add a supported rates element id to a frame. - */ -uint8_t * -ieee80211_add_rates(uint8_t *frm, const struct ieee80211_rateset *rs) -{ - int nrates; - - *frm++ = IEEE80211_ELEMID_RATES; - nrates = rs->rs_nrates; - if (nrates > IEEE80211_RATE_SIZE) - nrates = IEEE80211_RATE_SIZE; - *frm++ = nrates; - memcpy(frm, rs->rs_rates, nrates); - return frm + nrates; -} - -/* - * Add an extended supported rates element id to a frame. - */ -uint8_t * -ieee80211_add_xrates(uint8_t *frm, const struct ieee80211_rateset *rs) -{ - /* - * Add an extended supported rates element if operating in 11g mode. - */ - if (rs->rs_nrates > IEEE80211_RATE_SIZE) { - int nrates = rs->rs_nrates - IEEE80211_RATE_SIZE; - *frm++ = IEEE80211_ELEMID_XRATES; - *frm++ = nrates; - memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates); - frm += nrates; - } - return frm; -} - -/* - * Add an ssid element to a frame. - */ -static uint8_t * -ieee80211_add_ssid(uint8_t *frm, const uint8_t *ssid, u_int len) -{ - *frm++ = IEEE80211_ELEMID_SSID; - *frm++ = len; - memcpy(frm, ssid, len); - return frm + len; -} - -/* - * Add an erp element to a frame. - */ -static uint8_t * -ieee80211_add_erp(uint8_t *frm, struct ieee80211com *ic) -{ - uint8_t erp; - - *frm++ = IEEE80211_ELEMID_ERP; - *frm++ = 1; - erp = 0; - if (ic->ic_nonerpsta != 0) - erp |= IEEE80211_ERP_NON_ERP_PRESENT; - if (ic->ic_flags & IEEE80211_F_USEPROT) - erp |= IEEE80211_ERP_USE_PROTECTION; - if (ic->ic_flags & IEEE80211_F_USEBARKER) - erp |= IEEE80211_ERP_LONG_PREAMBLE; - *frm++ = erp; - return frm; -} - -/* - * Add a CFParams element to a frame. - */ -static uint8_t * -ieee80211_add_cfparms(uint8_t *frm, struct ieee80211com *ic) -{ -#define ADDSHORT(frm, v) do { \ - LE_WRITE_2(frm, v); \ - frm += 2; \ -} while (0) - *frm++ = IEEE80211_ELEMID_CFPARMS; - *frm++ = 6; - *frm++ = 0; /* CFP count */ - *frm++ = 2; /* CFP period */ - ADDSHORT(frm, 0); /* CFP MaxDuration (TU) */ - ADDSHORT(frm, 0); /* CFP CurRemaining (TU) */ - return frm; -#undef ADDSHORT -} - -static __inline uint8_t * -add_appie(uint8_t *frm, const struct ieee80211_appie *ie) -{ - memcpy(frm, ie->ie_data, ie->ie_len); - return frm + ie->ie_len; -} - -static __inline uint8_t * -add_ie(uint8_t *frm, const uint8_t *ie) -{ - memcpy(frm, ie, 2 + ie[1]); - return frm + 2 + ie[1]; -} - -#define WME_OUI_BYTES 0x00, 0x50, 0xf2 -/* - * Add a WME information element to a frame. - */ -static uint8_t * -ieee80211_add_wme_info(uint8_t *frm, struct ieee80211_wme_state *wme) -{ - static const struct ieee80211_wme_info info = { - .wme_id = IEEE80211_ELEMID_VENDOR, - .wme_len = sizeof(struct ieee80211_wme_info) - 2, - .wme_oui = { WME_OUI_BYTES }, - .wme_type = WME_OUI_TYPE, - .wme_subtype = WME_INFO_OUI_SUBTYPE, - .wme_version = WME_VERSION, - .wme_info = 0, - }; - memcpy(frm, &info, sizeof(info)); - return frm + sizeof(info); -} - -/* - * Add a WME parameters element to a frame. - */ -static uint8_t * -ieee80211_add_wme_param(uint8_t *frm, struct ieee80211_wme_state *wme) -{ -#define SM(_v, _f) (((_v) << _f##_S) & _f) -#define ADDSHORT(frm, v) do { \ - LE_WRITE_2(frm, v); \ - frm += 2; \ -} while (0) - /* NB: this works 'cuz a param has an info at the front */ - static const struct ieee80211_wme_info param = { - .wme_id = IEEE80211_ELEMID_VENDOR, - .wme_len = sizeof(struct ieee80211_wme_param) - 2, - .wme_oui = { WME_OUI_BYTES }, - .wme_type = WME_OUI_TYPE, - .wme_subtype = WME_PARAM_OUI_SUBTYPE, - .wme_version = WME_VERSION, - }; - int i; - - memcpy(frm, ¶m, sizeof(param)); - frm += __offsetof(struct ieee80211_wme_info, wme_info); - *frm++ = wme->wme_bssChanParams.cap_info; /* AC info */ - *frm++ = 0; /* reserved field */ - for (i = 0; i < WME_NUM_AC; i++) { - const struct wmeParams *ac = - &wme->wme_bssChanParams.cap_wmeParams[i]; - *frm++ = SM(i, WME_PARAM_ACI) - | SM(ac->wmep_acm, WME_PARAM_ACM) - | SM(ac->wmep_aifsn, WME_PARAM_AIFSN) - ; - *frm++ = SM(ac->wmep_logcwmax, WME_PARAM_LOGCWMAX) - | SM(ac->wmep_logcwmin, WME_PARAM_LOGCWMIN) - ; - ADDSHORT(frm, ac->wmep_txopLimit); - } - return frm; -#undef SM -#undef ADDSHORT -} -#undef WME_OUI_BYTES - -/* - * Add an 11h Power Constraint element to a frame. - */ -static uint8_t * -ieee80211_add_powerconstraint(uint8_t *frm, struct ieee80211vap *vap) -{ - const struct ieee80211_channel *c = vap->iv_bss->ni_chan; - /* XXX per-vap tx power limit? */ - int8_t limit = vap->iv_ic->ic_txpowlimit / 2; - - frm[0] = IEEE80211_ELEMID_PWRCNSTR; - frm[1] = 1; - frm[2] = c->ic_maxregpower > limit ? c->ic_maxregpower - limit : 0; - return frm + 3; -} - -/* - * Add an 11h Power Capability element to a frame. - */ -static uint8_t * -ieee80211_add_powercapability(uint8_t *frm, const struct ieee80211_channel *c) -{ - frm[0] = IEEE80211_ELEMID_PWRCAP; - frm[1] = 2; - frm[2] = c->ic_minpower; - frm[3] = c->ic_maxpower; - return frm + 4; -} - -/* - * Add an 11h Supported Channels element to a frame. - */ -static uint8_t * -ieee80211_add_supportedchannels(uint8_t *frm, struct ieee80211com *ic) -{ - static const int ielen = 26; - - frm[0] = IEEE80211_ELEMID_SUPPCHAN; - frm[1] = ielen; - /* XXX not correct */ - memcpy(frm+2, ic->ic_chan_avail, ielen); - return frm + 2 + ielen; -} - -/* - * Add an 11h Channel Switch Announcement element to a frame. - * Note that we use the per-vap CSA count to adjust the global - * counter so we can use this routine to form probe response - * frames and get the current count. - */ -static uint8_t * -ieee80211_add_csa(uint8_t *frm, struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_csa_ie *csa = (struct ieee80211_csa_ie *) frm; - - csa->csa_ie = IEEE80211_ELEMID_CSA; - csa->csa_len = 3; - csa->csa_mode = 1; /* XXX force quiet on channel */ - csa->csa_newchan = ieee80211_chan2ieee(ic, ic->ic_csa_newchan); - csa->csa_count = ic->ic_csa_count - vap->iv_csa_count; - return frm + sizeof(*csa); -} - -/* - * Add an 11h country information element to a frame. - */ -static uint8_t * -ieee80211_add_countryie(uint8_t *frm, struct ieee80211com *ic) -{ - - if (ic->ic_countryie == NULL || - ic->ic_countryie_chan != ic->ic_bsschan) { - /* - * Handle lazy construction of ie. This is done on - * first use and after a channel change that requires - * re-calculation. - */ - if (ic->ic_countryie != NULL) - free(ic->ic_countryie, M_80211_NODE_IE); - ic->ic_countryie = ieee80211_alloc_countryie(ic); - if (ic->ic_countryie == NULL) - return frm; - ic->ic_countryie_chan = ic->ic_bsschan; - } - return add_appie(frm, ic->ic_countryie); -} - -/* - * Send a probe request frame with the specified ssid - * and any optional information element data. - */ -int -ieee80211_send_probereq(struct ieee80211_node *ni, - const uint8_t sa[IEEE80211_ADDR_LEN], - const uint8_t da[IEEE80211_ADDR_LEN], - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t *ssid, size_t ssidlen) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - const struct ieee80211_txparam *tp; - struct ieee80211_bpf_params params; - struct ieee80211_frame *wh; - const struct ieee80211_rateset *rs; - struct mbuf *m; - uint8_t *frm; - - if (vap->iv_state == IEEE80211_S_CAC) { - IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, ni, - "block %s frame in CAC state", "probe request"); - vap->iv_stats.is_tx_badstate++; - return EIO; /* XXX */ - } - - /* - * Hold a reference on the node so it doesn't go away until after - * the xmit is complete all the way in the driver. On error we - * will remove our reference. - */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", - __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), - ieee80211_node_refcnt(ni)+1); - ieee80211_ref_node(ni); - - /* - * prreq frame format - * [tlv] ssid - * [tlv] supported rates - * [tlv] RSN (optional) - * [tlv] extended supported rates - * [tlv] WPA (optional) - * [tlv] user-specified ie's - */ - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - 2 + IEEE80211_NWID_LEN - + 2 + IEEE80211_RATE_SIZE - + sizeof(struct ieee80211_ie_wpa) - + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) - + sizeof(struct ieee80211_ie_wpa) - + (vap->iv_appie_probereq != NULL ? - vap->iv_appie_probereq->ie_len : 0) - ); - if (m == NULL) { - vap->iv_stats.is_tx_nobuf++; - ieee80211_free_node(ni); - return ENOMEM; - } - - frm = ieee80211_add_ssid(frm, ssid, ssidlen); - rs = ieee80211_get_suprates(ic, ic->ic_curchan); - frm = ieee80211_add_rates(frm, rs); - if (vap->iv_flags & IEEE80211_F_WPA2) { - if (vap->iv_rsn_ie != NULL) - frm = add_ie(frm, vap->iv_rsn_ie); - /* XXX else complain? */ - } - frm = ieee80211_add_xrates(frm, rs); - if (vap->iv_flags & IEEE80211_F_WPA1) { - if (vap->iv_wpa_ie != NULL) - frm = add_ie(frm, vap->iv_wpa_ie); - /* XXX else complain? */ - } - if (vap->iv_appie_probereq != NULL) - frm = add_appie(frm, vap->iv_appie_probereq); - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - - KASSERT(M_LEADINGSPACE(m) >= sizeof(struct ieee80211_frame), - ("leading space %zd", M_LEADINGSPACE(m))); - M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT); - if (m == NULL) { - /* NB: cannot happen */ - ieee80211_free_node(ni); - return ENOMEM; - } - - wh = mtod(m, struct ieee80211_frame *); - ieee80211_send_setup(ni, m, - IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ, - IEEE80211_NONQOS_TID, sa, da, bssid); - /* XXX power management? */ - m->m_flags |= M_ENCAP; /* mark encapsulated */ - - M_WME_SETAC(m, WME_AC_BE); - - IEEE80211_NODE_STAT(ni, tx_probereq); - IEEE80211_NODE_STAT(ni, tx_mgmt); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_DUMPPKTS, - "send probe req on channel %u bssid %s ssid \"%.*s\"\n", - ieee80211_chan2ieee(ic, ic->ic_curchan), ether_sprintf(bssid), - ssidlen, ssid); - - memset(¶ms, 0, sizeof(params)); - params.ibp_pri = M_WME_GETAC(m); - tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; - params.ibp_rate0 = tp->mgmtrate; - if (IEEE80211_IS_MULTICAST(da)) { - params.ibp_flags |= IEEE80211_BPF_NOACK; - params.ibp_try0 = 1; - } else - params.ibp_try0 = tp->maxretry; - params.ibp_power = ni->ni_txpower; - return ic->ic_raw_xmit(ni, m, ¶ms); -} - -/* - * Calculate capability information for mgt frames. - */ -uint16_t -ieee80211_getcapinfo(struct ieee80211vap *vap, struct ieee80211_channel *chan) -{ - struct ieee80211com *ic = vap->iv_ic; - uint16_t capinfo; - - KASSERT(vap->iv_opmode != IEEE80211_M_STA, ("station mode")); - - if (vap->iv_opmode == IEEE80211_M_HOSTAP) - capinfo = IEEE80211_CAPINFO_ESS; - else if (vap->iv_opmode == IEEE80211_M_IBSS) - capinfo = IEEE80211_CAPINFO_IBSS; - else - capinfo = 0; - if (vap->iv_flags & IEEE80211_F_PRIVACY) - capinfo |= IEEE80211_CAPINFO_PRIVACY; - if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && - IEEE80211_IS_CHAN_2GHZ(chan)) - capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE; - if (ic->ic_flags & IEEE80211_F_SHSLOT) - capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME; - if (IEEE80211_IS_CHAN_5GHZ(chan) && (vap->iv_flags & IEEE80211_F_DOTH)) - capinfo |= IEEE80211_CAPINFO_SPECTRUM_MGMT; - return capinfo; -} - -/* - * Send a management frame. The node is for the destination (or ic_bss - * when in station mode). Nodes other than ic_bss have their reference - * count bumped to reflect our use for an indeterminant time. - */ -int -ieee80211_send_mgmt(struct ieee80211_node *ni, int type, int arg) -{ -#define HTFLAGS (IEEE80211_NODE_HT | IEEE80211_NODE_HTCOMPAT) -#define senderr(_x, _v) do { vap->iv_stats._v++; ret = _x; goto bad; } while (0) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_node *bss = vap->iv_bss; - struct ieee80211_bpf_params params; - struct mbuf *m; - uint8_t *frm; - uint16_t capinfo; - int has_challenge, is_shared_key, ret, status; - - KASSERT(ni != NULL, ("null node")); - - /* - * Hold a reference on the node so it doesn't go away until after - * the xmit is complete all the way in the driver. On error we - * will remove our reference. - */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", - __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), - ieee80211_node_refcnt(ni)+1); - ieee80211_ref_node(ni); - - memset(¶ms, 0, sizeof(params)); - switch (type) { - - case IEEE80211_FC0_SUBTYPE_AUTH: - status = arg >> 16; - arg &= 0xffff; - has_challenge = ((arg == IEEE80211_AUTH_SHARED_CHALLENGE || - arg == IEEE80211_AUTH_SHARED_RESPONSE) && - ni->ni_challenge != NULL); - - /* - * Deduce whether we're doing open authentication or - * shared key authentication. We do the latter if - * we're in the middle of a shared key authentication - * handshake or if we're initiating an authentication - * request and configured to use shared key. - */ - is_shared_key = has_challenge || - arg >= IEEE80211_AUTH_SHARED_RESPONSE || - (arg == IEEE80211_AUTH_SHARED_REQUEST && - bss->ni_authmode == IEEE80211_AUTH_SHARED); - - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - 3 * sizeof(uint16_t) - + (has_challenge && status == IEEE80211_STATUS_SUCCESS ? - sizeof(uint16_t)+IEEE80211_CHALLENGE_LEN : 0) - ); - if (m == NULL) - senderr(ENOMEM, is_tx_nobuf); - - ((uint16_t *)frm)[0] = - (is_shared_key) ? htole16(IEEE80211_AUTH_ALG_SHARED) - : htole16(IEEE80211_AUTH_ALG_OPEN); - ((uint16_t *)frm)[1] = htole16(arg); /* sequence number */ - ((uint16_t *)frm)[2] = htole16(status);/* status */ - - if (has_challenge && status == IEEE80211_STATUS_SUCCESS) { - ((uint16_t *)frm)[3] = - htole16((IEEE80211_CHALLENGE_LEN << 8) | - IEEE80211_ELEMID_CHALLENGE); - memcpy(&((uint16_t *)frm)[4], ni->ni_challenge, - IEEE80211_CHALLENGE_LEN); - m->m_pkthdr.len = m->m_len = - 4 * sizeof(uint16_t) + IEEE80211_CHALLENGE_LEN; - if (arg == IEEE80211_AUTH_SHARED_RESPONSE) { - IEEE80211_NOTE(vap, IEEE80211_MSG_AUTH, ni, - "request encrypt frame (%s)", __func__); - /* mark frame for encryption */ - params.ibp_flags |= IEEE80211_BPF_CRYPTO; - } - } else - m->m_pkthdr.len = m->m_len = 3 * sizeof(uint16_t); - - /* XXX not right for shared key */ - if (status == IEEE80211_STATUS_SUCCESS) - IEEE80211_NODE_STAT(ni, tx_auth); - else - IEEE80211_NODE_STAT(ni, tx_auth_fail); - - if (vap->iv_opmode == IEEE80211_M_STA) - ieee80211_add_callback(m, ieee80211_tx_mgt_cb, - (void *) vap->iv_state); - break; - - case IEEE80211_FC0_SUBTYPE_DEAUTH: - IEEE80211_NOTE(vap, IEEE80211_MSG_AUTH, ni, - "send station deauthenticate (reason %d)", arg); - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t)); - if (m == NULL) - senderr(ENOMEM, is_tx_nobuf); - *(uint16_t *)frm = htole16(arg); /* reason */ - m->m_pkthdr.len = m->m_len = sizeof(uint16_t); - - IEEE80211_NODE_STAT(ni, tx_deauth); - IEEE80211_NODE_STAT_SET(ni, tx_deauth_code, arg); - - ieee80211_node_unauthorize(ni); /* port closed */ - break; - - case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: - /* - * asreq frame format - * [2] capability information - * [2] listen interval - * [6*] current AP address (reassoc only) - * [tlv] ssid - * [tlv] supported rates - * [tlv] extended supported rates - * [4] power capability (optional) - * [28] supported channels (optional) - * [tlv] HT capabilities - * [tlv] WME (optional) - * [tlv] Vendor OUI HT capabilities (optional) - * [tlv] Atheros capabilities (if negotiated) - * [tlv] AppIE's (optional) - */ - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t) - + sizeof(uint16_t) - + IEEE80211_ADDR_LEN - + 2 + IEEE80211_NWID_LEN - + 2 + IEEE80211_RATE_SIZE - + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) - + 4 - + 2 + 26 - + sizeof(struct ieee80211_wme_info) - + sizeof(struct ieee80211_ie_htcap) - + 4 + sizeof(struct ieee80211_ie_htcap) -#ifdef IEEE80211_SUPPORT_SUPERG - + sizeof(struct ieee80211_ath_ie) -#endif - + (vap->iv_appie_wpa != NULL ? - vap->iv_appie_wpa->ie_len : 0) - + (vap->iv_appie_assocreq != NULL ? - vap->iv_appie_assocreq->ie_len : 0) - ); - if (m == NULL) - senderr(ENOMEM, is_tx_nobuf); - - KASSERT(vap->iv_opmode == IEEE80211_M_STA, - ("wrong mode %u", vap->iv_opmode)); - capinfo = IEEE80211_CAPINFO_ESS; - if (vap->iv_flags & IEEE80211_F_PRIVACY) - capinfo |= IEEE80211_CAPINFO_PRIVACY; - /* - * NB: Some 11a AP's reject the request when - * short premable is set. - */ - if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && - IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) - capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE; - if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) && - (ic->ic_caps & IEEE80211_C_SHSLOT)) - capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME; - if ((ni->ni_capinfo & IEEE80211_CAPINFO_SPECTRUM_MGMT) && - (vap->iv_flags & IEEE80211_F_DOTH)) - capinfo |= IEEE80211_CAPINFO_SPECTRUM_MGMT; - *(uint16_t *)frm = htole16(capinfo); - frm += 2; - - KASSERT(bss->ni_intval != 0, ("beacon interval is zero!")); - *(uint16_t *)frm = htole16(howmany(ic->ic_lintval, - bss->ni_intval)); - frm += 2; - - if (type == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) { - IEEE80211_ADDR_COPY(frm, bss->ni_bssid); - frm += IEEE80211_ADDR_LEN; - } - - frm = ieee80211_add_ssid(frm, ni->ni_essid, ni->ni_esslen); - frm = ieee80211_add_rates(frm, &ni->ni_rates); - if (vap->iv_flags & IEEE80211_F_WPA2) { - if (vap->iv_rsn_ie != NULL) - frm = add_ie(frm, vap->iv_rsn_ie); - /* XXX else complain? */ - } - frm = ieee80211_add_xrates(frm, &ni->ni_rates); - if (capinfo & IEEE80211_CAPINFO_SPECTRUM_MGMT) { - frm = ieee80211_add_powercapability(frm, - ic->ic_curchan); - frm = ieee80211_add_supportedchannels(frm, ic); - } - if ((vap->iv_flags_ht & IEEE80211_FHT_HT) && - ni->ni_ies.htcap_ie != NULL && - ni->ni_ies.htcap_ie[0] == IEEE80211_ELEMID_HTCAP) - frm = ieee80211_add_htcap(frm, ni); - if (vap->iv_flags & IEEE80211_F_WPA1) { - if (vap->iv_wpa_ie != NULL) - frm = add_ie(frm, vap->iv_wpa_ie); - /* XXX else complain */ - } - if ((ic->ic_flags & IEEE80211_F_WME) && - ni->ni_ies.wme_ie != NULL) - frm = ieee80211_add_wme_info(frm, &ic->ic_wme); - if ((vap->iv_flags_ht & IEEE80211_FHT_HT) && - ni->ni_ies.htcap_ie != NULL && - ni->ni_ies.htcap_ie[0] == IEEE80211_ELEMID_VENDOR) - frm = ieee80211_add_htcap_vendor(frm, ni); -#ifdef IEEE80211_SUPPORT_SUPERG - if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS)) { - frm = ieee80211_add_ath(frm, - IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS), - ((vap->iv_flags & IEEE80211_F_WPA) == 0 && - ni->ni_authmode != IEEE80211_AUTH_8021X) ? - vap->iv_def_txkey : IEEE80211_KEYIX_NONE); - } -#endif /* IEEE80211_SUPPORT_SUPERG */ - if (vap->iv_appie_assocreq != NULL) - frm = add_appie(frm, vap->iv_appie_assocreq); - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - - ieee80211_add_callback(m, ieee80211_tx_mgt_cb, - (void *) vap->iv_state); - break; - - case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: - /* - * asresp frame format - * [2] capability information - * [2] status - * [2] association ID - * [tlv] supported rates - * [tlv] extended supported rates - * [tlv] HT capabilities (standard, if STA enabled) - * [tlv] HT information (standard, if STA enabled) - * [tlv] WME (if configured and STA enabled) - * [tlv] HT capabilities (vendor OUI, if STA enabled) - * [tlv] HT information (vendor OUI, if STA enabled) - * [tlv] Atheros capabilities (if STA enabled) - * [tlv] AppIE's (optional) - */ - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t) - + sizeof(uint16_t) - + sizeof(uint16_t) - + 2 + IEEE80211_RATE_SIZE - + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) - + sizeof(struct ieee80211_ie_htcap) + 4 - + sizeof(struct ieee80211_ie_htinfo) + 4 - + sizeof(struct ieee80211_wme_param) -#ifdef IEEE80211_SUPPORT_SUPERG - + sizeof(struct ieee80211_ath_ie) -#endif - + (vap->iv_appie_assocresp != NULL ? - vap->iv_appie_assocresp->ie_len : 0) - ); - if (m == NULL) - senderr(ENOMEM, is_tx_nobuf); - - capinfo = ieee80211_getcapinfo(vap, bss->ni_chan); - *(uint16_t *)frm = htole16(capinfo); - frm += 2; - - *(uint16_t *)frm = htole16(arg); /* status */ - frm += 2; - - if (arg == IEEE80211_STATUS_SUCCESS) { - *(uint16_t *)frm = htole16(ni->ni_associd); - IEEE80211_NODE_STAT(ni, tx_assoc); - } else - IEEE80211_NODE_STAT(ni, tx_assoc_fail); - frm += 2; - - frm = ieee80211_add_rates(frm, &ni->ni_rates); - frm = ieee80211_add_xrates(frm, &ni->ni_rates); - /* NB: respond according to what we received */ - if ((ni->ni_flags & HTFLAGS) == IEEE80211_NODE_HT) { - frm = ieee80211_add_htcap(frm, ni); - frm = ieee80211_add_htinfo(frm, ni); - } - if ((vap->iv_flags & IEEE80211_F_WME) && - ni->ni_ies.wme_ie != NULL) - frm = ieee80211_add_wme_param(frm, &ic->ic_wme); - if ((ni->ni_flags & HTFLAGS) == HTFLAGS) { - frm = ieee80211_add_htcap_vendor(frm, ni); - frm = ieee80211_add_htinfo_vendor(frm, ni); - } -#ifdef IEEE80211_SUPPORT_SUPERG - if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS)) - frm = ieee80211_add_ath(frm, - IEEE80211_ATH_CAP(vap, ni, IEEE80211_F_ATHEROS), - ((vap->iv_flags & IEEE80211_F_WPA) == 0 && - ni->ni_authmode != IEEE80211_AUTH_8021X) ? - vap->iv_def_txkey : IEEE80211_KEYIX_NONE); -#endif /* IEEE80211_SUPPORT_SUPERG */ - if (vap->iv_appie_assocresp != NULL) - frm = add_appie(frm, vap->iv_appie_assocresp); - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - break; - - case IEEE80211_FC0_SUBTYPE_DISASSOC: - IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, - "send station disassociate (reason %d)", arg); - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - sizeof(uint16_t)); - if (m == NULL) - senderr(ENOMEM, is_tx_nobuf); - *(uint16_t *)frm = htole16(arg); /* reason */ - m->m_pkthdr.len = m->m_len = sizeof(uint16_t); - - IEEE80211_NODE_STAT(ni, tx_disassoc); - IEEE80211_NODE_STAT_SET(ni, tx_disassoc_code, arg); - break; - - default: - IEEE80211_NOTE(vap, IEEE80211_MSG_ANY, ni, - "invalid mgmt frame type %u", type); - senderr(EINVAL, is_tx_unknownmgt); - /* NOTREACHED */ - } - - /* NB: force non-ProbeResp frames to the highest queue */ - params.ibp_pri = WME_AC_VO; - params.ibp_rate0 = bss->ni_txparms->mgmtrate; - /* NB: we know all frames are unicast */ - params.ibp_try0 = bss->ni_txparms->maxretry; - params.ibp_power = bss->ni_txpower; - return ieee80211_mgmt_output(ni, m, type, ¶ms); -bad: - ieee80211_free_node(ni); - return ret; -#undef senderr -#undef HTFLAGS -} - -/* - * Return an mbuf with a probe response frame in it. - * Space is left to prepend and 802.11 header at the - * front but it's left to the caller to fill in. - */ -struct mbuf * -ieee80211_alloc_proberesp(struct ieee80211_node *bss, int legacy) -{ - struct ieee80211vap *vap = bss->ni_vap; - struct ieee80211com *ic = bss->ni_ic; - const struct ieee80211_rateset *rs; - struct mbuf *m; - uint16_t capinfo; - uint8_t *frm; - - /* - * probe response frame format - * [8] time stamp - * [2] beacon interval - * [2] cabability information - * [tlv] ssid - * [tlv] supported rates - * [tlv] parameter set (FH/DS) - * [tlv] parameter set (IBSS) - * [tlv] country (optional) - * [3] power control (optional) - * [5] channel switch announcement (CSA) (optional) - * [tlv] extended rate phy (ERP) - * [tlv] extended supported rates - * [tlv] RSN (optional) - * [tlv] HT capabilities - * [tlv] HT information - * [tlv] WPA (optional) - * [tlv] WME (optional) - * [tlv] Vendor OUI HT capabilities (optional) - * [tlv] Vendor OUI HT information (optional) - * [tlv] Atheros capabilities - * [tlv] AppIE's (optional) - * [tlv] Mesh ID (MBSS) - * [tlv] Mesh Conf (MBSS) - */ - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - 8 - + sizeof(uint16_t) - + sizeof(uint16_t) - + 2 + IEEE80211_NWID_LEN - + 2 + IEEE80211_RATE_SIZE - + 7 /* max(7,3) */ - + IEEE80211_COUNTRY_MAX_SIZE - + 3 - + sizeof(struct ieee80211_csa_ie) - + 3 - + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) - + sizeof(struct ieee80211_ie_wpa) - + sizeof(struct ieee80211_ie_htcap) - + sizeof(struct ieee80211_ie_htinfo) - + sizeof(struct ieee80211_ie_wpa) - + sizeof(struct ieee80211_wme_param) - + 4 + sizeof(struct ieee80211_ie_htcap) - + 4 + sizeof(struct ieee80211_ie_htinfo) -#ifdef IEEE80211_SUPPORT_SUPERG - + sizeof(struct ieee80211_ath_ie) -#endif -#ifdef IEEE80211_SUPPORT_MESH - + 2 + IEEE80211_MESHID_LEN - + sizeof(struct ieee80211_meshconf_ie) -#endif - + (vap->iv_appie_proberesp != NULL ? - vap->iv_appie_proberesp->ie_len : 0) - ); - if (m == NULL) { - vap->iv_stats.is_tx_nobuf++; - return NULL; - } - - memset(frm, 0, 8); /* timestamp should be filled later */ - frm += 8; - *(uint16_t *)frm = htole16(bss->ni_intval); - frm += 2; - capinfo = ieee80211_getcapinfo(vap, bss->ni_chan); - *(uint16_t *)frm = htole16(capinfo); - frm += 2; - - frm = ieee80211_add_ssid(frm, bss->ni_essid, bss->ni_esslen); - rs = ieee80211_get_suprates(ic, bss->ni_chan); - frm = ieee80211_add_rates(frm, rs); - - if (IEEE80211_IS_CHAN_FHSS(bss->ni_chan)) { - *frm++ = IEEE80211_ELEMID_FHPARMS; - *frm++ = 5; - *frm++ = bss->ni_fhdwell & 0x00ff; - *frm++ = (bss->ni_fhdwell >> 8) & 0x00ff; - *frm++ = IEEE80211_FH_CHANSET( - ieee80211_chan2ieee(ic, bss->ni_chan)); - *frm++ = IEEE80211_FH_CHANPAT( - ieee80211_chan2ieee(ic, bss->ni_chan)); - *frm++ = bss->ni_fhindex; - } else { - *frm++ = IEEE80211_ELEMID_DSPARMS; - *frm++ = 1; - *frm++ = ieee80211_chan2ieee(ic, bss->ni_chan); - } - - if (vap->iv_opmode == IEEE80211_M_IBSS) { - *frm++ = IEEE80211_ELEMID_IBSSPARMS; - *frm++ = 2; - *frm++ = 0; *frm++ = 0; /* TODO: ATIM window */ - } - if ((vap->iv_flags & IEEE80211_F_DOTH) || - (vap->iv_flags_ext & IEEE80211_FEXT_DOTD)) - frm = ieee80211_add_countryie(frm, ic); - if (vap->iv_flags & IEEE80211_F_DOTH) { - if (IEEE80211_IS_CHAN_5GHZ(bss->ni_chan)) - frm = ieee80211_add_powerconstraint(frm, vap); - if (ic->ic_flags & IEEE80211_F_CSAPENDING) - frm = ieee80211_add_csa(frm, vap); - } - if (IEEE80211_IS_CHAN_ANYG(bss->ni_chan)) - frm = ieee80211_add_erp(frm, ic); - frm = ieee80211_add_xrates(frm, rs); - if (vap->iv_flags & IEEE80211_F_WPA2) { - if (vap->iv_rsn_ie != NULL) - frm = add_ie(frm, vap->iv_rsn_ie); - /* XXX else complain? */ - } - /* - * NB: legacy 11b clients do not get certain ie's. - * The caller identifies such clients by passing - * a token in legacy to us. Could expand this to be - * any legacy client for stuff like HT ie's. - */ - if (IEEE80211_IS_CHAN_HT(bss->ni_chan) && - legacy != IEEE80211_SEND_LEGACY_11B) { - frm = ieee80211_add_htcap(frm, bss); - frm = ieee80211_add_htinfo(frm, bss); - } - if (vap->iv_flags & IEEE80211_F_WPA1) { - if (vap->iv_wpa_ie != NULL) - frm = add_ie(frm, vap->iv_wpa_ie); - /* XXX else complain? */ - } - if (vap->iv_flags & IEEE80211_F_WME) - frm = ieee80211_add_wme_param(frm, &ic->ic_wme); - if (IEEE80211_IS_CHAN_HT(bss->ni_chan) && - (vap->iv_flags_ht & IEEE80211_FHT_HTCOMPAT) && - legacy != IEEE80211_SEND_LEGACY_11B) { - frm = ieee80211_add_htcap_vendor(frm, bss); - frm = ieee80211_add_htinfo_vendor(frm, bss); - } -#ifdef IEEE80211_SUPPORT_SUPERG - if ((vap->iv_flags & IEEE80211_F_ATHEROS) && - legacy != IEEE80211_SEND_LEGACY_11B) - frm = ieee80211_add_athcaps(frm, bss); -#endif - if (vap->iv_appie_proberesp != NULL) - frm = add_appie(frm, vap->iv_appie_proberesp); -#ifdef IEEE80211_SUPPORT_MESH - if (vap->iv_opmode == IEEE80211_M_MBSS) { - frm = ieee80211_add_meshid(frm, vap); - frm = ieee80211_add_meshconf(frm, vap); - } -#endif - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - - return m; -} - -/* - * Send a probe response frame to the specified mac address. - * This does not go through the normal mgt frame api so we - * can specify the destination address and re-use the bss node - * for the sta reference. - */ -int -ieee80211_send_proberesp(struct ieee80211vap *vap, - const uint8_t da[IEEE80211_ADDR_LEN], int legacy) -{ - struct ieee80211_node *bss = vap->iv_bss; - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_frame *wh; - struct mbuf *m; - - if (vap->iv_state == IEEE80211_S_CAC) { - IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, bss, - "block %s frame in CAC state", "probe response"); - vap->iv_stats.is_tx_badstate++; - return EIO; /* XXX */ - } - - /* - * Hold a reference on the node so it doesn't go away until after - * the xmit is complete all the way in the driver. On error we - * will remove our reference. - */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", - __func__, __LINE__, bss, ether_sprintf(bss->ni_macaddr), - ieee80211_node_refcnt(bss)+1); - ieee80211_ref_node(bss); - - m = ieee80211_alloc_proberesp(bss, legacy); - if (m == NULL) { - ieee80211_free_node(bss); - return ENOMEM; - } - - M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT); - KASSERT(m != NULL, ("no room for header")); - - wh = mtod(m, struct ieee80211_frame *); - ieee80211_send_setup(bss, m, - IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP, - IEEE80211_NONQOS_TID, vap->iv_myaddr, da, bss->ni_bssid); - /* XXX power management? */ - m->m_flags |= M_ENCAP; /* mark encapsulated */ - - M_WME_SETAC(m, WME_AC_BE); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_DUMPPKTS, - "send probe resp on channel %u to %s%s\n", - ieee80211_chan2ieee(ic, ic->ic_curchan), ether_sprintf(da), - legacy ? " " : ""); - IEEE80211_NODE_STAT(bss, tx_mgmt); - - return ic->ic_raw_xmit(bss, m, NULL); -} - -/* - * Allocate and build a RTS (Request To Send) control frame. - */ -struct mbuf * -ieee80211_alloc_rts(struct ieee80211com *ic, - const uint8_t ra[IEEE80211_ADDR_LEN], - const uint8_t ta[IEEE80211_ADDR_LEN], - uint16_t dur) -{ - struct ieee80211_frame_rts *rts; - struct mbuf *m; - - /* XXX honor ic_headroom */ - m = m_gethdr(M_DONTWAIT, MT_DATA); - if (m != NULL) { - rts = mtod(m, struct ieee80211_frame_rts *); - rts->i_fc[0] = IEEE80211_FC0_VERSION_0 | - IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_RTS; - rts->i_fc[1] = IEEE80211_FC1_DIR_NODS; - *(u_int16_t *)rts->i_dur = htole16(dur); - IEEE80211_ADDR_COPY(rts->i_ra, ra); - IEEE80211_ADDR_COPY(rts->i_ta, ta); - - m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame_rts); - } - return m; -} - -/* - * Allocate and build a CTS (Clear To Send) control frame. - */ -struct mbuf * -ieee80211_alloc_cts(struct ieee80211com *ic, - const uint8_t ra[IEEE80211_ADDR_LEN], uint16_t dur) -{ - struct ieee80211_frame_cts *cts; - struct mbuf *m; - - /* XXX honor ic_headroom */ - m = m_gethdr(M_DONTWAIT, MT_DATA); - if (m != NULL) { - cts = mtod(m, struct ieee80211_frame_cts *); - cts->i_fc[0] = IEEE80211_FC0_VERSION_0 | - IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_CTS; - cts->i_fc[1] = IEEE80211_FC1_DIR_NODS; - *(u_int16_t *)cts->i_dur = htole16(dur); - IEEE80211_ADDR_COPY(cts->i_ra, ra); - - m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame_cts); - } - return m; -} - -static void -ieee80211_tx_mgt_timeout(void *arg) -{ - struct ieee80211_node *ni = arg; - struct ieee80211vap *vap = ni->ni_vap; - - if (vap->iv_state != IEEE80211_S_INIT && - (vap->iv_ic->ic_flags & IEEE80211_F_SCAN) == 0) { - /* - * NB: it's safe to specify a timeout as the reason here; - * it'll only be used in the right state. - */ - ieee80211_new_state(vap, IEEE80211_S_SCAN, - IEEE80211_SCAN_FAIL_TIMEOUT); - } -} - -static void -ieee80211_tx_mgt_cb(struct ieee80211_node *ni, void *arg, int status) -{ - struct ieee80211vap *vap = ni->ni_vap; - enum ieee80211_state ostate = (enum ieee80211_state) arg; - - /* - * Frame transmit completed; arrange timer callback. If - * transmit was successfuly we wait for response. Otherwise - * we arrange an immediate callback instead of doing the - * callback directly since we don't know what state the driver - * is in (e.g. what locks it is holding). This work should - * not be too time-critical and not happen too often so the - * added overhead is acceptable. - * - * XXX what happens if !acked but response shows up before callback? - */ - if (vap->iv_state == ostate) - callout_reset(&vap->iv_mgtsend, - status == 0 ? IEEE80211_TRANS_WAIT*hz : 0, - ieee80211_tx_mgt_timeout, ni); -} - -static void -ieee80211_beacon_construct(struct mbuf *m, uint8_t *frm, - struct ieee80211_beacon_offsets *bo, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_rateset *rs = &ni->ni_rates; - uint16_t capinfo; - - /* - * beacon frame format - * [8] time stamp - * [2] beacon interval - * [2] cabability information - * [tlv] ssid - * [tlv] supported rates - * [3] parameter set (DS) - * [8] CF parameter set (optional) - * [tlv] parameter set (IBSS/TIM) - * [tlv] country (optional) - * [3] power control (optional) - * [5] channel switch announcement (CSA) (optional) - * [tlv] extended rate phy (ERP) - * [tlv] extended supported rates - * [tlv] RSN parameters - * [tlv] HT capabilities - * [tlv] HT information - * XXX Vendor-specific OIDs (e.g. Atheros) - * [tlv] WPA parameters - * [tlv] WME parameters - * [tlv] Vendor OUI HT capabilities (optional) - * [tlv] Vendor OUI HT information (optional) - * [tlv] Atheros capabilities (optional) - * [tlv] TDMA parameters (optional) - * [tlv] Mesh ID (MBSS) - * [tlv] Mesh Conf (MBSS) - * [tlv] application data (optional) - */ - - memset(bo, 0, sizeof(*bo)); - - memset(frm, 0, 8); /* XXX timestamp is set by hardware/driver */ - frm += 8; - *(uint16_t *)frm = htole16(ni->ni_intval); - frm += 2; - capinfo = ieee80211_getcapinfo(vap, ni->ni_chan); - bo->bo_caps = (uint16_t *)frm; - *(uint16_t *)frm = htole16(capinfo); - frm += 2; - *frm++ = IEEE80211_ELEMID_SSID; - if ((vap->iv_flags & IEEE80211_F_HIDESSID) == 0) { - *frm++ = ni->ni_esslen; - memcpy(frm, ni->ni_essid, ni->ni_esslen); - frm += ni->ni_esslen; - } else - *frm++ = 0; - frm = ieee80211_add_rates(frm, rs); - if (!IEEE80211_IS_CHAN_FHSS(ni->ni_chan)) { - *frm++ = IEEE80211_ELEMID_DSPARMS; - *frm++ = 1; - *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan); - } - if (ic->ic_flags & IEEE80211_F_PCF) { - bo->bo_cfp = frm; - frm = ieee80211_add_cfparms(frm, ic); - } - bo->bo_tim = frm; - if (vap->iv_opmode == IEEE80211_M_IBSS) { - *frm++ = IEEE80211_ELEMID_IBSSPARMS; - *frm++ = 2; - *frm++ = 0; *frm++ = 0; /* TODO: ATIM window */ - bo->bo_tim_len = 0; - } else if (vap->iv_opmode == IEEE80211_M_HOSTAP || - vap->iv_opmode == IEEE80211_M_MBSS) { - /* TIM IE is the same for Mesh and Hostap */ - struct ieee80211_tim_ie *tie = (struct ieee80211_tim_ie *) frm; - - tie->tim_ie = IEEE80211_ELEMID_TIM; - tie->tim_len = 4; /* length */ - tie->tim_count = 0; /* DTIM count */ - tie->tim_period = vap->iv_dtim_period; /* DTIM period */ - tie->tim_bitctl = 0; /* bitmap control */ - tie->tim_bitmap[0] = 0; /* Partial Virtual Bitmap */ - frm += sizeof(struct ieee80211_tim_ie); - bo->bo_tim_len = 1; - } - bo->bo_tim_trailer = frm; - if ((vap->iv_flags & IEEE80211_F_DOTH) || - (vap->iv_flags_ext & IEEE80211_FEXT_DOTD)) - frm = ieee80211_add_countryie(frm, ic); - if (vap->iv_flags & IEEE80211_F_DOTH) { - if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) - frm = ieee80211_add_powerconstraint(frm, vap); - bo->bo_csa = frm; - if (ic->ic_flags & IEEE80211_F_CSAPENDING) - frm = ieee80211_add_csa(frm, vap); - } else - bo->bo_csa = frm; - if (IEEE80211_IS_CHAN_ANYG(ni->ni_chan)) { - bo->bo_erp = frm; - frm = ieee80211_add_erp(frm, ic); - } - frm = ieee80211_add_xrates(frm, rs); - if (vap->iv_flags & IEEE80211_F_WPA2) { - if (vap->iv_rsn_ie != NULL) - frm = add_ie(frm, vap->iv_rsn_ie); - /* XXX else complain */ - } - if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) { - frm = ieee80211_add_htcap(frm, ni); - bo->bo_htinfo = frm; - frm = ieee80211_add_htinfo(frm, ni); - } - if (vap->iv_flags & IEEE80211_F_WPA1) { - if (vap->iv_wpa_ie != NULL) - frm = add_ie(frm, vap->iv_wpa_ie); - /* XXX else complain */ - } - if (vap->iv_flags & IEEE80211_F_WME) { - bo->bo_wme = frm; - frm = ieee80211_add_wme_param(frm, &ic->ic_wme); - } - if (IEEE80211_IS_CHAN_HT(ni->ni_chan) && - (vap->iv_flags_ht & IEEE80211_FHT_HTCOMPAT)) { - frm = ieee80211_add_htcap_vendor(frm, ni); - frm = ieee80211_add_htinfo_vendor(frm, ni); - } -#ifdef IEEE80211_SUPPORT_SUPERG - if (vap->iv_flags & IEEE80211_F_ATHEROS) { - bo->bo_ath = frm; - frm = ieee80211_add_athcaps(frm, ni); - } -#endif -#ifdef IEEE80211_SUPPORT_TDMA - if (vap->iv_caps & IEEE80211_C_TDMA) { - bo->bo_tdma = frm; - frm = ieee80211_add_tdma(frm, vap); - } -#endif - if (vap->iv_appie_beacon != NULL) { - bo->bo_appie = frm; - bo->bo_appie_len = vap->iv_appie_beacon->ie_len; - frm = add_appie(frm, vap->iv_appie_beacon); - } -#ifdef IEEE80211_SUPPORT_MESH - if (vap->iv_opmode == IEEE80211_M_MBSS) { - frm = ieee80211_add_meshid(frm, vap); - bo->bo_meshconf = frm; - frm = ieee80211_add_meshconf(frm, vap); - } -#endif - bo->bo_tim_trailer_len = frm - bo->bo_tim_trailer; - bo->bo_csa_trailer_len = frm - bo->bo_csa; - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); -} - -/* - * Allocate a beacon frame and fillin the appropriate bits. - */ -struct mbuf * -ieee80211_beacon_alloc(struct ieee80211_node *ni, - struct ieee80211_beacon_offsets *bo) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = vap->iv_ifp; - struct ieee80211_frame *wh; - struct mbuf *m; - int pktlen; - uint8_t *frm; - - /* - * beacon frame format - * [8] time stamp - * [2] beacon interval - * [2] cabability information - * [tlv] ssid - * [tlv] supported rates - * [3] parameter set (DS) - * [8] CF parameter set (optional) - * [tlv] parameter set (IBSS/TIM) - * [tlv] country (optional) - * [3] power control (optional) - * [5] channel switch announcement (CSA) (optional) - * [tlv] extended rate phy (ERP) - * [tlv] extended supported rates - * [tlv] RSN parameters - * [tlv] HT capabilities - * [tlv] HT information - * [tlv] Vendor OUI HT capabilities (optional) - * [tlv] Vendor OUI HT information (optional) - * XXX Vendor-specific OIDs (e.g. Atheros) - * [tlv] WPA parameters - * [tlv] WME parameters - * [tlv] TDMA parameters (optional) - * [tlv] Mesh ID (MBSS) - * [tlv] Mesh Conf (MBSS) - * [tlv] application data (optional) - * NB: we allocate the max space required for the TIM bitmap. - * XXX how big is this? - */ - pktlen = 8 /* time stamp */ - + sizeof(uint16_t) /* beacon interval */ - + sizeof(uint16_t) /* capabilities */ - + 2 + ni->ni_esslen /* ssid */ - + 2 + IEEE80211_RATE_SIZE /* supported rates */ - + 2 + 1 /* DS parameters */ - + 2 + 6 /* CF parameters */ - + 2 + 4 + vap->iv_tim_len /* DTIM/IBSSPARMS */ - + IEEE80211_COUNTRY_MAX_SIZE /* country */ - + 2 + 1 /* power control */ - + sizeof(struct ieee80211_csa_ie) /* CSA */ - + 2 + 1 /* ERP */ - + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) - + (vap->iv_caps & IEEE80211_C_WPA ? /* WPA 1+2 */ - 2*sizeof(struct ieee80211_ie_wpa) : 0) - /* XXX conditional? */ - + 4+2*sizeof(struct ieee80211_ie_htcap)/* HT caps */ - + 4+2*sizeof(struct ieee80211_ie_htinfo)/* HT info */ - + (vap->iv_caps & IEEE80211_C_WME ? /* WME */ - sizeof(struct ieee80211_wme_param) : 0) -#ifdef IEEE80211_SUPPORT_SUPERG - + sizeof(struct ieee80211_ath_ie) /* ATH */ -#endif -#ifdef IEEE80211_SUPPORT_TDMA - + (vap->iv_caps & IEEE80211_C_TDMA ? /* TDMA */ - sizeof(struct ieee80211_tdma_param) : 0) -#endif -#ifdef IEEE80211_SUPPORT_MESH - + 2 + ni->ni_meshidlen - + sizeof(struct ieee80211_meshconf_ie) -#endif - + IEEE80211_MAX_APPIE - ; - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), pktlen); - if (m == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ANY, - "%s: cannot get buf; size %u\n", __func__, pktlen); - vap->iv_stats.is_tx_nobuf++; - return NULL; - } - ieee80211_beacon_construct(m, frm, bo, ni); - - M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT); - KASSERT(m != NULL, ("no space for 802.11 header?")); - wh = mtod(m, struct ieee80211_frame *); - wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | - IEEE80211_FC0_SUBTYPE_BEACON; - wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; - *(uint16_t *)wh->i_dur = 0; - IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr); - IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr); - IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid); - *(uint16_t *)wh->i_seq = 0; - - return m; -} - -/* - * Update the dynamic parts of a beacon frame based on the current state. - */ -int -ieee80211_beacon_update(struct ieee80211_node *ni, - struct ieee80211_beacon_offsets *bo, struct mbuf *m, int mcast) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - int len_changed = 0; - uint16_t capinfo; - struct ieee80211_frame *wh; - ieee80211_seq seqno; - - IEEE80211_LOCK(ic); - /* - * Handle 11h channel change when we've reached the count. - * We must recalculate the beacon frame contents to account - * for the new channel. Note we do this only for the first - * vap that reaches this point; subsequent vaps just update - * their beacon state to reflect the recalculated channel. - */ - if (isset(bo->bo_flags, IEEE80211_BEACON_CSA) && - vap->iv_csa_count == ic->ic_csa_count) { - vap->iv_csa_count = 0; - /* - * Effect channel change before reconstructing the beacon - * frame contents as many places reference ni_chan. - */ - if (ic->ic_csa_newchan != NULL) - ieee80211_csa_completeswitch(ic); - /* - * NB: ieee80211_beacon_construct clears all pending - * updates in bo_flags so we don't need to explicitly - * clear IEEE80211_BEACON_CSA. - */ - ieee80211_beacon_construct(m, - mtod(m, uint8_t*) + sizeof(struct ieee80211_frame), bo, ni); - - /* XXX do WME aggressive mode processing? */ - IEEE80211_UNLOCK(ic); - return 1; /* just assume length changed */ - } - - wh = mtod(m, struct ieee80211_frame *); - seqno = ni->ni_txseqs[IEEE80211_NONQOS_TID]++; - *(uint16_t *)&wh->i_seq[0] = - htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT); - M_SEQNO_SET(m, seqno); - - /* XXX faster to recalculate entirely or just changes? */ - capinfo = ieee80211_getcapinfo(vap, ni->ni_chan); - *bo->bo_caps = htole16(capinfo); - - if (vap->iv_flags & IEEE80211_F_WME) { - struct ieee80211_wme_state *wme = &ic->ic_wme; - - /* - * Check for agressive mode change. When there is - * significant high priority traffic in the BSS - * throttle back BE traffic by using conservative - * parameters. Otherwise BE uses agressive params - * to optimize performance of legacy/non-QoS traffic. - */ - if (wme->wme_flags & WME_F_AGGRMODE) { - if (wme->wme_hipri_traffic > - wme->wme_hipri_switch_thresh) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME, - "%s: traffic %u, disable aggressive mode\n", - __func__, wme->wme_hipri_traffic); - wme->wme_flags &= ~WME_F_AGGRMODE; - ieee80211_wme_updateparams_locked(vap); - wme->wme_hipri_traffic = - wme->wme_hipri_switch_hysteresis; - } else - wme->wme_hipri_traffic = 0; - } else { - if (wme->wme_hipri_traffic <= - wme->wme_hipri_switch_thresh) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME, - "%s: traffic %u, enable aggressive mode\n", - __func__, wme->wme_hipri_traffic); - wme->wme_flags |= WME_F_AGGRMODE; - ieee80211_wme_updateparams_locked(vap); - wme->wme_hipri_traffic = 0; - } else - wme->wme_hipri_traffic = - wme->wme_hipri_switch_hysteresis; - } - if (isset(bo->bo_flags, IEEE80211_BEACON_WME)) { - (void) ieee80211_add_wme_param(bo->bo_wme, wme); - clrbit(bo->bo_flags, IEEE80211_BEACON_WME); - } - } - - if (isset(bo->bo_flags, IEEE80211_BEACON_HTINFO)) { - ieee80211_ht_update_beacon(vap, bo); - clrbit(bo->bo_flags, IEEE80211_BEACON_HTINFO); - } -#ifdef IEEE80211_SUPPORT_TDMA - if (vap->iv_caps & IEEE80211_C_TDMA) { - /* - * NB: the beacon is potentially updated every TBTT. - */ - ieee80211_tdma_update_beacon(vap, bo); - } -#endif -#ifdef IEEE80211_SUPPORT_MESH - if (vap->iv_opmode == IEEE80211_M_MBSS) - ieee80211_mesh_update_beacon(vap, bo); -#endif - - if (vap->iv_opmode == IEEE80211_M_HOSTAP || - vap->iv_opmode == IEEE80211_M_MBSS) { /* NB: no IBSS support*/ - struct ieee80211_tim_ie *tie = - (struct ieee80211_tim_ie *) bo->bo_tim; - if (isset(bo->bo_flags, IEEE80211_BEACON_TIM)) { - u_int timlen, timoff, i; - /* - * ATIM/DTIM needs updating. If it fits in the - * current space allocated then just copy in the - * new bits. Otherwise we need to move any trailing - * data to make room. Note that we know there is - * contiguous space because ieee80211_beacon_allocate - * insures there is space in the mbuf to write a - * maximal-size virtual bitmap (based on iv_max_aid). - */ - /* - * Calculate the bitmap size and offset, copy any - * trailer out of the way, and then copy in the - * new bitmap and update the information element. - * Note that the tim bitmap must contain at least - * one byte and any offset must be even. - */ - if (vap->iv_ps_pending != 0) { - timoff = 128; /* impossibly large */ - for (i = 0; i < vap->iv_tim_len; i++) - if (vap->iv_tim_bitmap[i]) { - timoff = i &~ 1; - break; - } - KASSERT(timoff != 128, ("tim bitmap empty!")); - for (i = vap->iv_tim_len-1; i >= timoff; i--) - if (vap->iv_tim_bitmap[i]) - break; - timlen = 1 + (i - timoff); - } else { - timoff = 0; - timlen = 1; - } - if (timlen != bo->bo_tim_len) { - /* copy up/down trailer */ - int adjust = tie->tim_bitmap+timlen - - bo->bo_tim_trailer; - ovbcopy(bo->bo_tim_trailer, - bo->bo_tim_trailer+adjust, - bo->bo_tim_trailer_len); - bo->bo_tim_trailer += adjust; - bo->bo_erp += adjust; - bo->bo_htinfo += adjust; -#ifdef IEEE80211_SUPPORT_SUPERG - bo->bo_ath += adjust; -#endif -#ifdef IEEE80211_SUPPORT_TDMA - bo->bo_tdma += adjust; -#endif -#ifdef IEEE80211_SUPPORT_MESH - bo->bo_meshconf += adjust; -#endif - bo->bo_appie += adjust; - bo->bo_wme += adjust; - bo->bo_csa += adjust; - bo->bo_tim_len = timlen; - - /* update information element */ - tie->tim_len = 3 + timlen; - tie->tim_bitctl = timoff; - len_changed = 1; - } - memcpy(tie->tim_bitmap, vap->iv_tim_bitmap + timoff, - bo->bo_tim_len); - - clrbit(bo->bo_flags, IEEE80211_BEACON_TIM); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER, - "%s: TIM updated, pending %u, off %u, len %u\n", - __func__, vap->iv_ps_pending, timoff, timlen); - } - /* count down DTIM period */ - if (tie->tim_count == 0) - tie->tim_count = tie->tim_period - 1; - else - tie->tim_count--; - /* update state for buffered multicast frames on DTIM */ - if (mcast && tie->tim_count == 0) - tie->tim_bitctl |= 1; - else - tie->tim_bitctl &= ~1; - if (isset(bo->bo_flags, IEEE80211_BEACON_CSA)) { - struct ieee80211_csa_ie *csa = - (struct ieee80211_csa_ie *) bo->bo_csa; - - /* - * Insert or update CSA ie. If we're just starting - * to count down to the channel switch then we need - * to insert the CSA ie. Otherwise we just need to - * drop the count. The actual change happens above - * when the vap's count reaches the target count. - */ - if (vap->iv_csa_count == 0) { - memmove(&csa[1], csa, bo->bo_csa_trailer_len); - bo->bo_erp += sizeof(*csa); - bo->bo_htinfo += sizeof(*csa); - bo->bo_wme += sizeof(*csa); -#ifdef IEEE80211_SUPPORT_SUPERG - bo->bo_ath += sizeof(*csa); -#endif -#ifdef IEEE80211_SUPPORT_TDMA - bo->bo_tdma += sizeof(*csa); -#endif -#ifdef IEEE80211_SUPPORT_MESH - bo->bo_meshconf += sizeof(*csa); -#endif - bo->bo_appie += sizeof(*csa); - bo->bo_csa_trailer_len += sizeof(*csa); - bo->bo_tim_trailer_len += sizeof(*csa); - m->m_len += sizeof(*csa); - m->m_pkthdr.len += sizeof(*csa); - - ieee80211_add_csa(bo->bo_csa, vap); - } else - csa->csa_count--; - vap->iv_csa_count++; - /* NB: don't clear IEEE80211_BEACON_CSA */ - } - if (isset(bo->bo_flags, IEEE80211_BEACON_ERP)) { - /* - * ERP element needs updating. - */ - (void) ieee80211_add_erp(bo->bo_erp, ic); - clrbit(bo->bo_flags, IEEE80211_BEACON_ERP); - } -#ifdef IEEE80211_SUPPORT_SUPERG - if (isset(bo->bo_flags, IEEE80211_BEACON_ATH)) { - ieee80211_add_athcaps(bo->bo_ath, ni); - clrbit(bo->bo_flags, IEEE80211_BEACON_ATH); - } -#endif - } - if (isset(bo->bo_flags, IEEE80211_BEACON_APPIE)) { - const struct ieee80211_appie *aie = vap->iv_appie_beacon; - int aielen; - uint8_t *frm; - - aielen = 0; - if (aie != NULL) - aielen += aie->ie_len; - if (aielen != bo->bo_appie_len) { - /* copy up/down trailer */ - int adjust = aielen - bo->bo_appie_len; - ovbcopy(bo->bo_tim_trailer, bo->bo_tim_trailer+adjust, - bo->bo_tim_trailer_len); - bo->bo_tim_trailer += adjust; - bo->bo_appie += adjust; - bo->bo_appie_len = aielen; - - len_changed = 1; - } - frm = bo->bo_appie; - if (aie != NULL) - frm = add_appie(frm, aie); - clrbit(bo->bo_flags, IEEE80211_BEACON_APPIE); - } - IEEE80211_UNLOCK(ic); - - return len_changed; -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_phy.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_phy.c deleted file mode 100644 index cd99ce837b..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_phy.c +++ /dev/null @@ -1,465 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 PHY-related support. - */ - -#include "opt_inet.h" - -#include -#include -#include - -#include - -#include -#include - -#include -#include - -#ifdef notyet -struct ieee80211_ds_plcp_hdr { - uint8_t i_signal; - uint8_t i_service; - uint16_t i_length; - uint16_t i_crc; -} __packed; - -#endif /* notyet */ - -/* shorthands to compact tables for readability */ -#define OFDM IEEE80211_T_OFDM -#define CCK IEEE80211_T_CCK -#define TURBO IEEE80211_T_TURBO -#define HALF IEEE80211_T_OFDM_HALF -#define QUART IEEE80211_T_OFDM_QUARTER -#define PBCC (IEEE80211_T_OFDM_QUARTER+1) /* XXX */ -#define B(r) (0x80 | r) -#define Mb(x) (x*1000) - -static struct ieee80211_rate_table ieee80211_11b_table = { - .rateCount = 4, /* XXX no PBCC */ - .info = { -/* short ctrl */ -/* Preamble dot11Rate Rate */ - [0] = { .phy = CCK, 1000, 0x00, B(2), 0 },/* 1 Mb */ - [1] = { .phy = CCK, 2000, 0x04, B(4), 1 },/* 2 Mb */ - [2] = { .phy = CCK, 5500, 0x04, B(11), 1 },/* 5.5 Mb */ - [3] = { .phy = CCK, 11000, 0x04, B(22), 1 },/* 11 Mb */ - [4] = { .phy = PBCC, 22000, 0x04, 44, 3 } /* 22 Mb */ - }, -}; - -static struct ieee80211_rate_table ieee80211_11g_table = { - .rateCount = 12, - .info = { -/* short ctrl */ -/* Preamble dot11Rate Rate */ - [0] = { .phy = CCK, 1000, 0x00, B(2), 0 }, - [1] = { .phy = CCK, 2000, 0x04, B(4), 1 }, - [2] = { .phy = CCK, 5500, 0x04, B(11), 2 }, - [3] = { .phy = CCK, 11000, 0x04, B(22), 3 }, - [4] = { .phy = OFDM, 6000, 0x00, 12, 4 }, - [5] = { .phy = OFDM, 9000, 0x00, 18, 4 }, - [6] = { .phy = OFDM, 12000, 0x00, 24, 6 }, - [7] = { .phy = OFDM, 18000, 0x00, 36, 6 }, - [8] = { .phy = OFDM, 24000, 0x00, 48, 8 }, - [9] = { .phy = OFDM, 36000, 0x00, 72, 8 }, - [10] = { .phy = OFDM, 48000, 0x00, 96, 8 }, - [11] = { .phy = OFDM, 54000, 0x00, 108, 8 } - }, -}; - -static struct ieee80211_rate_table ieee80211_11a_table = { - .rateCount = 8, - .info = { -/* short ctrl */ -/* Preamble dot11Rate Rate */ - [0] = { .phy = OFDM, 6000, 0x00, B(12), 0 }, - [1] = { .phy = OFDM, 9000, 0x00, 18, 0 }, - [2] = { .phy = OFDM, 12000, 0x00, B(24), 2 }, - [3] = { .phy = OFDM, 18000, 0x00, 36, 2 }, - [4] = { .phy = OFDM, 24000, 0x00, B(48), 4 }, - [5] = { .phy = OFDM, 36000, 0x00, 72, 4 }, - [6] = { .phy = OFDM, 48000, 0x00, 96, 4 }, - [7] = { .phy = OFDM, 54000, 0x00, 108, 4 } - }, -}; - -static struct ieee80211_rate_table ieee80211_half_table = { - .rateCount = 8, - .info = { -/* short ctrl */ -/* Preamble dot11Rate Rate */ - [0] = { .phy = HALF, 3000, 0x00, B(6), 0 }, - [1] = { .phy = HALF, 4500, 0x00, 9, 0 }, - [2] = { .phy = HALF, 6000, 0x00, B(12), 2 }, - [3] = { .phy = HALF, 9000, 0x00, 18, 2 }, - [4] = { .phy = HALF, 12000, 0x00, B(24), 4 }, - [5] = { .phy = HALF, 18000, 0x00, 36, 4 }, - [6] = { .phy = HALF, 24000, 0x00, 48, 4 }, - [7] = { .phy = HALF, 27000, 0x00, 54, 4 } - }, -}; - -static struct ieee80211_rate_table ieee80211_quarter_table = { - .rateCount = 8, - .info = { -/* short ctrl */ -/* Preamble dot11Rate Rate */ - [0] = { .phy = QUART, 1500, 0x00, B(3), 0 }, - [1] = { .phy = QUART, 2250, 0x00, 4, 0 }, - [2] = { .phy = QUART, 3000, 0x00, B(9), 2 }, - [3] = { .phy = QUART, 4500, 0x00, 9, 2 }, - [4] = { .phy = QUART, 6000, 0x00, B(12), 4 }, - [5] = { .phy = QUART, 9000, 0x00, 18, 4 }, - [6] = { .phy = QUART, 12000, 0x00, 24, 4 }, - [7] = { .phy = QUART, 13500, 0x00, 27, 4 } - }, -}; - -static struct ieee80211_rate_table ieee80211_turbog_table = { - .rateCount = 7, - .info = { -/* short ctrl */ -/* Preamble dot11Rate Rate */ - [0] = { .phy = TURBO, 12000, 0x00, B(12), 0 }, - [1] = { .phy = TURBO, 24000, 0x00, B(24), 1 }, - [2] = { .phy = TURBO, 36000, 0x00, 36, 1 }, - [3] = { .phy = TURBO, 48000, 0x00, B(48), 3 }, - [4] = { .phy = TURBO, 72000, 0x00, 72, 3 }, - [5] = { .phy = TURBO, 96000, 0x00, 96, 3 }, - [6] = { .phy = TURBO, 108000, 0x00, 108, 3 } - }, -}; - -static struct ieee80211_rate_table ieee80211_turboa_table = { - .rateCount = 8, - .info = { -/* short ctrl */ -/* Preamble dot11Rate Rate */ - [0] = { .phy = TURBO, 12000, 0x00, B(12), 0 }, - [1] = { .phy = TURBO, 18000, 0x00, 18, 0 }, - [2] = { .phy = TURBO, 24000, 0x00, B(24), 2 }, - [3] = { .phy = TURBO, 36000, 0x00, 36, 2 }, - [4] = { .phy = TURBO, 48000, 0x00, B(48), 4 }, - [5] = { .phy = TURBO, 72000, 0x00, 72, 4 }, - [6] = { .phy = TURBO, 96000, 0x00, 96, 4 }, - [7] = { .phy = TURBO, 108000, 0x00, 108, 4 } - }, -}; - -#undef Mb -#undef B -#undef OFDM -#undef HALF -#undef QUART -#undef CCK -#undef TURBO -#undef XR - -/* - * Setup a rate table's reverse lookup table and fill in - * ack durations. The reverse lookup tables are assumed - * to be initialized to zero (or at least the first entry). - * We use this as a key that indicates whether or not - * we've previously setup the reverse lookup table. - * - * XXX not reentrant, but shouldn't matter - */ -static void -ieee80211_setup_ratetable(struct ieee80211_rate_table *rt) -{ -#define N(a) (sizeof(a)/sizeof(a[0])) -#define WLAN_CTRL_FRAME_SIZE \ - (sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN) - - int i; - - for (i = 0; i < N(rt->rateCodeToIndex); i++) - rt->rateCodeToIndex[i] = (uint8_t) -1; - for (i = 0; i < rt->rateCount; i++) { - uint8_t code = rt->info[i].dot11Rate; - uint8_t cix = rt->info[i].ctlRateIndex; - uint8_t ctl_rate = rt->info[cix].dot11Rate; - - rt->rateCodeToIndex[code] = i; - if (code & IEEE80211_RATE_BASIC) { - /* - * Map w/o basic rate bit too. - */ - code &= IEEE80211_RATE_VAL; - rt->rateCodeToIndex[code] = i; - } - - /* - * XXX for 11g the control rate to use for 5.5 and 11 Mb/s - * depends on whether they are marked as basic rates; - * the static tables are setup with an 11b-compatible - * 2Mb/s rate which will work but is suboptimal - * - * NB: Control rate is always less than or equal to the - * current rate, so control rate's reverse lookup entry - * has been installed and following call is safe. - */ - rt->info[i].lpAckDuration = ieee80211_compute_duration(rt, - WLAN_CTRL_FRAME_SIZE, ctl_rate, 0); - rt->info[i].spAckDuration = ieee80211_compute_duration(rt, - WLAN_CTRL_FRAME_SIZE, ctl_rate, IEEE80211_F_SHPREAMBLE); - } - -#undef WLAN_CTRL_FRAME_SIZE -#undef N -} - -/* Setup all rate tables */ -void -ieee80211_phy_init(void) -{ -#define N(arr) (int)(sizeof(arr) / sizeof(arr[0])) - static struct ieee80211_rate_table * const ratetables[] = { - &ieee80211_half_table, - &ieee80211_quarter_table, - &ieee80211_11a_table, - &ieee80211_11g_table, - &ieee80211_turbog_table, - &ieee80211_turboa_table, - &ieee80211_turboa_table, - &ieee80211_11a_table, - &ieee80211_11g_table, - &ieee80211_11b_table - }; - int i; - - for (i = 0; i < N(ratetables); ++i) - ieee80211_setup_ratetable(ratetables[i]); - -#undef N -} -SYSINIT(wlan_phy, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_phy_init, NULL); - -const struct ieee80211_rate_table * -ieee80211_get_ratetable(struct ieee80211_channel *c) -{ - const struct ieee80211_rate_table *rt; - - /* XXX HT */ - if (IEEE80211_IS_CHAN_HALF(c)) - rt = &ieee80211_half_table; - else if (IEEE80211_IS_CHAN_QUARTER(c)) - rt = &ieee80211_quarter_table; - else if (IEEE80211_IS_CHAN_HTA(c)) - rt = &ieee80211_11a_table; /* XXX */ - else if (IEEE80211_IS_CHAN_HTG(c)) - rt = &ieee80211_11g_table; /* XXX */ - else if (IEEE80211_IS_CHAN_108G(c)) - rt = &ieee80211_turbog_table; - else if (IEEE80211_IS_CHAN_ST(c)) - rt = &ieee80211_turboa_table; - else if (IEEE80211_IS_CHAN_TURBO(c)) - rt = &ieee80211_turboa_table; - else if (IEEE80211_IS_CHAN_A(c)) - rt = &ieee80211_11a_table; - else if (IEEE80211_IS_CHAN_ANYG(c)) - rt = &ieee80211_11g_table; - else if (IEEE80211_IS_CHAN_B(c)) - rt = &ieee80211_11b_table; - else { - /* NB: should not get here */ - panic("%s: no rate table for channel; freq %u flags 0x%x\n", - __func__, c->ic_freq, c->ic_flags); - } - return rt; -} - -/* - * Convert PLCP signal/rate field to 802.11 rate (.5Mbits/s) - * - * Note we do no parameter checking; this routine is mainly - * used to derive an 802.11 rate for constructing radiotap - * header data for rx frames. - * - * XXX might be a candidate for inline - */ -uint8_t -ieee80211_plcp2rate(uint8_t plcp, enum ieee80211_phytype type) -{ - if (type == IEEE80211_T_OFDM) { - static const uint8_t ofdm_plcp2rate[16] = { - [0xb] = 12, - [0xf] = 18, - [0xa] = 24, - [0xe] = 36, - [0x9] = 48, - [0xd] = 72, - [0x8] = 96, - [0xc] = 108 - }; - return ofdm_plcp2rate[plcp & 0xf]; - } - if (type == IEEE80211_T_CCK) { - static const uint8_t cck_plcp2rate[16] = { - [0xa] = 2, /* 0x0a */ - [0x4] = 4, /* 0x14 */ - [0x7] = 11, /* 0x37 */ - [0xe] = 22, /* 0x6e */ - [0xc] = 44, /* 0xdc , actually PBCC */ - }; - return cck_plcp2rate[plcp & 0xf]; - } - return 0; -} - -/* - * Covert 802.11 rate to PLCP signal. - */ -uint8_t -ieee80211_rate2plcp(int rate, enum ieee80211_phytype type) -{ - /* XXX ignore type for now since rates are unique */ - switch (rate) { - /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ - case 12: return 0xb; - case 18: return 0xf; - case 24: return 0xa; - case 36: return 0xe; - case 48: return 0x9; - case 72: return 0xd; - case 96: return 0x8; - case 108: return 0xc; - /* CCK rates (IEEE Std 802.11b-1999 page 15, subclause 18.2.3.3) */ - case 2: return 10; - case 4: return 20; - case 11: return 55; - case 22: return 110; - /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ - case 44: return 220; - } - return 0; /* XXX unsupported/unknown rate */ -} - -#define CCK_SIFS_TIME 10 -#define CCK_PREAMBLE_BITS 144 -#define CCK_PLCP_BITS 48 - -#define OFDM_SIFS_TIME 16 -#define OFDM_PREAMBLE_TIME 20 -#define OFDM_PLCP_BITS 22 -#define OFDM_SYMBOL_TIME 4 - -#define OFDM_HALF_SIFS_TIME 32 -#define OFDM_HALF_PREAMBLE_TIME 40 -#define OFDM_HALF_PLCP_BITS 22 -#define OFDM_HALF_SYMBOL_TIME 8 - -#define OFDM_QUARTER_SIFS_TIME 64 -#define OFDM_QUARTER_PREAMBLE_TIME 80 -#define OFDM_QUARTER_PLCP_BITS 22 -#define OFDM_QUARTER_SYMBOL_TIME 16 - -#define TURBO_SIFS_TIME 8 -#define TURBO_PREAMBLE_TIME 14 -#define TURBO_PLCP_BITS 22 -#define TURBO_SYMBOL_TIME 4 - -/* - * Compute the time to transmit a frame of length frameLen bytes - * using the specified rate, phy, and short preamble setting. - * SIFS is included. - */ -uint16_t -ieee80211_compute_duration(const struct ieee80211_rate_table *rt, - uint32_t frameLen, uint16_t rate, int isShortPreamble) -{ - uint8_t rix = rt->rateCodeToIndex[rate]; - uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime; - uint32_t kbps; - - KASSERT(rix != (uint8_t)-1, ("rate %d has no info", rate)); - kbps = rt->info[rix].rateKbps; - if (kbps == 0) /* XXX bandaid for channel changes */ - return 0; - - switch (rt->info[rix].phy) { - case IEEE80211_T_CCK: - phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; - if (isShortPreamble && rt->info[rix].shortPreamble) - phyTime >>= 1; - numBits = frameLen << 3; - txTime = CCK_SIFS_TIME + phyTime - + ((numBits * 1000)/kbps); - break; - case IEEE80211_T_OFDM: - bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000; - KASSERT(bitsPerSymbol != 0, ("full rate bps")); - - numBits = OFDM_PLCP_BITS + (frameLen << 3); - numSymbols = howmany(numBits, bitsPerSymbol); - txTime = OFDM_SIFS_TIME - + OFDM_PREAMBLE_TIME - + (numSymbols * OFDM_SYMBOL_TIME); - break; - case IEEE80211_T_OFDM_HALF: - bitsPerSymbol = (kbps * OFDM_HALF_SYMBOL_TIME) / 1000; - KASSERT(bitsPerSymbol != 0, ("1/4 rate bps")); - - numBits = OFDM_PLCP_BITS + (frameLen << 3); - numSymbols = howmany(numBits, bitsPerSymbol); - txTime = OFDM_HALF_SIFS_TIME - + OFDM_HALF_PREAMBLE_TIME - + (numSymbols * OFDM_HALF_SYMBOL_TIME); - break; - case IEEE80211_T_OFDM_QUARTER: - bitsPerSymbol = (kbps * OFDM_QUARTER_SYMBOL_TIME) / 1000; - KASSERT(bitsPerSymbol != 0, ("1/2 rate bps")); - - numBits = OFDM_PLCP_BITS + (frameLen << 3); - numSymbols = howmany(numBits, bitsPerSymbol); - txTime = OFDM_QUARTER_SIFS_TIME - + OFDM_QUARTER_PREAMBLE_TIME - + (numSymbols * OFDM_QUARTER_SYMBOL_TIME); - break; - case IEEE80211_T_TURBO: - /* we still save OFDM rates in kbps - so double them */ - bitsPerSymbol = ((kbps << 1) * TURBO_SYMBOL_TIME) / 1000; - KASSERT(bitsPerSymbol != 0, ("turbo bps")); - - numBits = TURBO_PLCP_BITS + (frameLen << 3); - numSymbols = howmany(numBits, bitsPerSymbol); - txTime = TURBO_SIFS_TIME + TURBO_PREAMBLE_TIME - + (numSymbols * TURBO_SYMBOL_TIME); - break; - default: - panic("%s: unknown phy %u (rate %u)\n", __func__, - rt->info[rix].phy, rate); - break; - } - return txTime; -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_phy.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_phy.h deleted file mode 100644 index 7508fe2f6a..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_phy.h +++ /dev/null @@ -1,157 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_PHY_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_PHY_H_ - -#ifdef _KERNEL -/* - * IEEE 802.11 PHY-related definitions. - */ - -void ieee80211_phy_init(void); - -/* - * Contention window (slots). - */ -#define IEEE80211_CW_MAX 1023 /* aCWmax */ -#define IEEE80211_CW_MIN_0 31 /* DS/CCK aCWmin, ERP aCWmin(0) */ -#define IEEE80211_CW_MIN_1 15 /* OFDM aCWmin, ERP aCWmin(1) */ - -/* - * SIFS (microseconds). - */ -#define IEEE80211_DUR_SIFS 10 /* DS/CCK/ERP SIFS */ -#define IEEE80211_DUR_OFDM_SIFS 16 /* OFDM SIFS */ - -/* - * Slot time (microseconds). - */ -#define IEEE80211_DUR_SLOT 20 /* DS/CCK slottime, ERP long slottime */ -#define IEEE80211_DUR_SHSLOT 9 /* ERP short slottime */ -#define IEEE80211_DUR_OFDM_SLOT 9 /* OFDM slottime */ - -/* - * DIFS (microseconds). - */ -#define IEEE80211_DUR_DIFS(sifs, slot) ((sifs) + 2 * (slot)) - -struct ieee80211_channel; - -struct ieee80211_rate_table { - int rateCount; /* NB: for proper padding */ - uint8_t rateCodeToIndex[256]; /* back mapping */ - struct { - uint8_t phy; /* CCK/OFDM/TURBO */ - uint32_t rateKbps; /* transfer rate in kbs */ - uint8_t shortPreamble; /* mask for enabling short - * preamble in CCK rate code */ - uint8_t dot11Rate; /* value for supported rates - * info element of MLME */ - uint8_t ctlRateIndex; /* index of next lower basic - * rate; used for dur. calcs */ - uint16_t lpAckDuration; /* long preamble ACK dur. */ - uint16_t spAckDuration; /* short preamble ACK dur. */ - } info[32]; -}; - -const struct ieee80211_rate_table *ieee80211_get_ratetable( - struct ieee80211_channel *); - -static __inline__ uint8_t -ieee80211_ack_rate(const struct ieee80211_rate_table *rt, uint8_t rate) -{ - uint8_t cix = rt->info[rt->rateCodeToIndex[rate]].ctlRateIndex; - KASSERT(cix != (uint8_t)-1, ("rate %d has no info", rate)); - return rt->info[cix].dot11Rate; -} - -static __inline__ uint8_t -ieee80211_ctl_rate(const struct ieee80211_rate_table *rt, uint8_t rate) -{ - uint8_t cix = rt->info[rt->rateCodeToIndex[rate]].ctlRateIndex; - KASSERT(cix != (uint8_t)-1, ("rate %d has no info", rate)); - return rt->info[cix].dot11Rate; -} - -static __inline__ enum ieee80211_phytype -ieee80211_rate2phytype(const struct ieee80211_rate_table *rt, uint8_t rate) -{ - uint8_t rix = rt->rateCodeToIndex[rate]; - KASSERT(rix != (uint8_t)-1, ("rate %d has no info", rate)); - return (enum ieee80211_phytype)rt->info[rix].phy; -} - -static __inline__ int -ieee80211_isratevalid(const struct ieee80211_rate_table *rt, uint8_t rate) -{ - return rt->rateCodeToIndex[rate] != (uint8_t)-1; -} - -/* - * Calculate ACK field for - * o non-fragment data frames - * o management frames - * sent using rate, phy and short preamble setting. - */ -static __inline__ uint16_t -ieee80211_ack_duration(const struct ieee80211_rate_table *rt, - uint8_t rate, int isShortPreamble) -{ - uint8_t rix = rt->rateCodeToIndex[rate]; - - KASSERT(rix != (uint8_t)-1, ("rate %d has no info", rate)); - if (isShortPreamble) { - KASSERT(rt->info[rix].spAckDuration != 0, - ("shpreamble ack dur is not computed!\n")); - return rt->info[rix].spAckDuration; - } else { - KASSERT(rt->info[rix].lpAckDuration != 0, - ("lgpreamble ack dur is not computed!\n")); - return rt->info[rix].lpAckDuration; - } -} - -/* - * Compute the time to transmit a frame of length frameLen bytes - * using the specified 802.11 rate code, phy, and short preamble - * setting. - * - * NB: SIFS is included. - */ -uint16_t ieee80211_compute_duration(const struct ieee80211_rate_table *, - uint32_t frameLen, uint16_t rate, int isShortPreamble); -/* - * Convert PLCP signal/rate field to 802.11 rate code (.5Mbits/s) - */ -uint8_t ieee80211_plcp2rate(uint8_t, enum ieee80211_phytype); -/* - * Convert 802.11 rate code to PLCP signal. - */ -uint8_t ieee80211_rate2plcp(int, enum ieee80211_phytype); -#endif /* _KERNEL */ -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_PHY_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_power.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_power.c deleted file mode 100644 index 2b68f9022f..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_power.c +++ /dev/null @@ -1,525 +0,0 @@ -/*- - * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 power save support. - */ -#include "opt_wlan.h" - -#include -#include -#include - -#include - -#include -#include -#include - -#include - -#include - -static void ieee80211_update_ps(struct ieee80211vap *, int); -static int ieee80211_set_tim(struct ieee80211_node *, int); - -void -ieee80211_power_attach(struct ieee80211com *ic) -{ -} - -void -ieee80211_power_detach(struct ieee80211com *ic) -{ -} - -void -ieee80211_power_vattach(struct ieee80211vap *vap) -{ - if (vap->iv_opmode == IEEE80211_M_HOSTAP || - vap->iv_opmode == IEEE80211_M_IBSS) { - /* NB: driver should override */ - vap->iv_update_ps = ieee80211_update_ps; - vap->iv_set_tim = ieee80211_set_tim; - } -} - -void -ieee80211_power_latevattach(struct ieee80211vap *vap) -{ - /* - * Allocate these only if needed. Beware that we - * know adhoc mode doesn't support ATIM yet... - */ - if (vap->iv_opmode == IEEE80211_M_HOSTAP) { - vap->iv_tim_len = howmany(vap->iv_max_aid,8) * sizeof(uint8_t); - vap->iv_tim_bitmap = (uint8_t *) malloc(vap->iv_tim_len, - M_80211_POWER, M_NOWAIT | M_ZERO); - if (vap->iv_tim_bitmap == NULL) { - printf("%s: no memory for TIM bitmap!\n", __func__); - /* XXX good enough to keep from crashing? */ - vap->iv_tim_len = 0; - } - } -} - -void -ieee80211_power_vdetach(struct ieee80211vap *vap) -{ - if (vap->iv_tim_bitmap != NULL) { - free(vap->iv_tim_bitmap, M_80211_POWER); - vap->iv_tim_bitmap = NULL; - } -} - -void -ieee80211_psq_init(struct ieee80211_psq *psq, const char *name) -{ - memset(psq, 0, sizeof(*psq)); - psq->psq_maxlen = IEEE80211_PS_MAX_QUEUE; - IEEE80211_PSQ_INIT(psq, name); /* OS-dependent setup */ -} - -void -ieee80211_psq_cleanup(struct ieee80211_psq *psq) -{ -#if 0 - psq_drain(psq); /* XXX should not be needed? */ -#else - KASSERT(psq->psq_len == 0, ("%d frames on ps q", psq->psq_len)); -#endif - IEEE80211_PSQ_DESTROY(psq); /* OS-dependent cleanup */ -} - -/* - * Return the highest priority frame in the ps queue. - */ -struct mbuf * -ieee80211_node_psq_dequeue(struct ieee80211_node *ni, int *qlen) -{ - struct ieee80211_psq *psq = &ni->ni_psq; - struct ieee80211_psq_head *qhead; - struct mbuf *m; - - IEEE80211_PSQ_LOCK(psq); - qhead = &psq->psq_head[0]; -again: - if ((m = qhead->head) != NULL) { - if ((qhead->head = m->m_nextpkt) == NULL) - qhead->tail = NULL; - KASSERT(qhead->len > 0, ("qhead len %d", qhead->len)); - qhead->len--; - KASSERT(psq->psq_len > 0, ("psq len %d", psq->psq_len)); - psq->psq_len--; - m->m_nextpkt = NULL; - } - if (m == NULL && qhead == &psq->psq_head[0]) { - /* Algol-68 style for loop */ - qhead = &psq->psq_head[1]; - goto again; - } - if (qlen != NULL) - *qlen = psq->psq_len; - IEEE80211_PSQ_UNLOCK(psq); - return m; -} - -/* - * Reclaim an mbuf from the ps q. If marked with M_ENCAP - * we assume there is a node reference that must be relcaimed. - */ -static void -psq_mfree(struct mbuf *m) -{ - if (m->m_flags & M_ENCAP) { - struct ieee80211_node *ni = (void *) m->m_pkthdr.rcvif; - ieee80211_free_node(ni); - } - m->m_nextpkt = NULL; - m_freem(m); -} - -/* - * Clear any frames queued in the power save queue. - * The number of frames that were present is returned. - */ -static int -psq_drain(struct ieee80211_psq *psq) -{ - struct ieee80211_psq_head *qhead; - struct mbuf *m; - int qlen; - - IEEE80211_PSQ_LOCK(psq); - qlen = psq->psq_len; - qhead = &psq->psq_head[0]; -again: - while ((m = qhead->head) != NULL) { - qhead->head = m->m_nextpkt; - psq_mfree(m); - } - qhead->tail = NULL; - qhead->len = 0; - if (qhead == &psq->psq_head[0]) { /* Algol-68 style for loop */ - qhead = &psq->psq_head[1]; - goto again; - } - psq->psq_len = 0; - IEEE80211_PSQ_UNLOCK(psq); - - return qlen; -} - -/* - * Clear any frames queued in the power save queue. - * The number of frames that were present is returned. - */ -int -ieee80211_node_psq_drain(struct ieee80211_node *ni) -{ - return psq_drain(&ni->ni_psq); -} - -/* - * Age frames on the power save queue. The aging interval is - * 4 times the listen interval specified by the station. This - * number is factored into the age calculations when the frame - * is placed on the queue. We store ages as time differences - * so we can check and/or adjust only the head of the list. - * If a frame's age exceeds the threshold then discard it. - * The number of frames discarded is returned so the caller - * can check if it needs to adjust the tim. - */ -int -ieee80211_node_psq_age(struct ieee80211_node *ni) -{ - struct ieee80211_psq *psq = &ni->ni_psq; - int discard = 0; - - if (psq->psq_len != 0) { -#ifdef IEEE80211_DEBUG - struct ieee80211vap *vap = ni->ni_vap; -#endif - struct ieee80211_psq_head *qhead; - struct mbuf *m; - - IEEE80211_PSQ_LOCK(psq); - qhead = &psq->psq_head[0]; - again: - while ((m = qhead->head) != NULL && - M_AGE_GET(m) < IEEE80211_INACT_WAIT) { - IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, - "discard frame, age %u", M_AGE_GET(m)); - if ((qhead->head = m->m_nextpkt) == NULL) - qhead->tail = NULL; - KASSERT(qhead->len > 0, ("qhead len %d", qhead->len)); - qhead->len--; - KASSERT(psq->psq_len > 0, ("psq len %d", psq->psq_len)); - psq->psq_len--; - psq_mfree(m); - discard++; - } - if (qhead == &psq->psq_head[0]) { /* Algol-68 style for loop */ - qhead = &psq->psq_head[1]; - goto again; - } - if (m != NULL) - M_AGE_SUB(m, IEEE80211_INACT_WAIT); - IEEE80211_PSQ_UNLOCK(psq); - - IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, - "discard %u frames for age", discard); - IEEE80211_NODE_STAT_ADD(ni, ps_discard, discard); - } - return discard; -} - -/* - * Handle a change in the PS station occupancy. - */ -static void -ieee80211_update_ps(struct ieee80211vap *vap, int nsta) -{ - - KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP || - vap->iv_opmode == IEEE80211_M_IBSS, - ("operating mode %u", vap->iv_opmode)); -} - -/* - * Indicate whether there are frames queued for a station in power-save mode. - */ -static int -ieee80211_set_tim(struct ieee80211_node *ni, int set) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - uint16_t aid; - int changed; - - KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP || - vap->iv_opmode == IEEE80211_M_IBSS, - ("operating mode %u", vap->iv_opmode)); - - aid = IEEE80211_AID(ni->ni_associd); - KASSERT(aid < vap->iv_max_aid, - ("bogus aid %u, max %u", aid, vap->iv_max_aid)); - - IEEE80211_LOCK(ic); - changed = (set != (isset(vap->iv_tim_bitmap, aid) != 0)); - if (changed) { - if (set) { - setbit(vap->iv_tim_bitmap, aid); - vap->iv_ps_pending++; - } else { - clrbit(vap->iv_tim_bitmap, aid); - vap->iv_ps_pending--; - } - /* NB: we know vap is in RUN state so no need to check */ - vap->iv_update_beacon(vap, IEEE80211_BEACON_TIM); - } - IEEE80211_UNLOCK(ic); - - return changed; -} - -/* - * Save an outbound packet for a node in power-save sleep state. - * The new packet is placed on the node's saved queue, and the TIM - * is changed, if necessary. - */ -int -ieee80211_pwrsave(struct ieee80211_node *ni, struct mbuf *m) -{ - struct ieee80211_psq *psq = &ni->ni_psq; - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_psq_head *qhead; - int qlen, age; - - IEEE80211_PSQ_LOCK(psq); - if (psq->psq_len >= psq->psq_maxlen) { - psq->psq_drops++; - IEEE80211_PSQ_UNLOCK(psq); - IEEE80211_NOTE(vap, IEEE80211_MSG_ANY, ni, - "pwr save q overflow, drops %d (size %d)", - psq->psq_drops, psq->psq_len); -#ifdef IEEE80211_DEBUG - if (ieee80211_msg_dumppkts(vap)) - ieee80211_dump_pkt(ni->ni_ic, mtod(m, caddr_t), - m->m_len, -1, -1); -#endif - psq_mfree(m); - return ENOSPC; - } - /* - * Tag the frame with it's expiry time and insert it in - * the appropriate queue. The aging interval is 4 times - * the listen interval specified by the station. Frames - * that sit around too long are reclaimed using this - * information. - */ - /* TU -> secs. XXX handle overflow? */ - age = IEEE80211_TU_TO_MS((ni->ni_intval * ic->ic_bintval) << 2) / 1000; - /* - * Encapsulated frames go on the high priority queue, - * other stuff goes on the low priority queue. We use - * this to order frames returned out of the driver - * ahead of frames we collect in ieee80211_start. - */ - if (m->m_flags & M_ENCAP) - qhead = &psq->psq_head[0]; - else - qhead = &psq->psq_head[1]; - if (qhead->tail == NULL) { - struct mbuf *mh; - - qhead->head = m; - /* - * Take care to adjust age when inserting the first - * frame of a queue and the other queue already has - * frames. We need to preserve the age difference - * relationship so ieee80211_node_psq_age works. - */ - if (qhead == &psq->psq_head[1]) { - mh = psq->psq_head[0].head; - if (mh != NULL) - age-= M_AGE_GET(mh); - } else { - mh = psq->psq_head[1].head; - if (mh != NULL) { - int nage = M_AGE_GET(mh) - age; - /* XXX is clamping to zero good 'nuf? */ - M_AGE_SET(mh, nage < 0 ? 0 : nage); - } - } - } else { - qhead->tail->m_nextpkt = m; - age -= M_AGE_GET(qhead->head); - } - KASSERT(age >= 0, ("age %d", age)); - M_AGE_SET(m, age); - m->m_nextpkt = NULL; - qhead->tail = m; - qhead->len++; - qlen = ++(psq->psq_len); - IEEE80211_PSQ_UNLOCK(psq); - - IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, - "save frame with age %d, %u now queued", age, qlen); - - if (qlen == 1 && vap->iv_set_tim != NULL) - vap->iv_set_tim(ni, 1); - - return 0; -} - -/* - * Move frames from the ps q to the vap's send queue - * and/or the driver's send queue; and kick the start - * method for each, as appropriate. Note we're careful - * to preserve packet ordering here. - */ -static void -pwrsave_flushq(struct ieee80211_node *ni) -{ - struct ieee80211_psq *psq = &ni->ni_psq; - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_psq_head *qhead; - struct ifnet *parent, *ifp; - - IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, - "flush ps queue, %u packets queued", psq->psq_len); - - IEEE80211_PSQ_LOCK(psq); - qhead = &psq->psq_head[0]; /* 802.11 frames */ - if (qhead->head != NULL) { - /* XXX could dispatch through vap and check M_ENCAP */ - parent = vap->iv_ic->ic_ifp; - /* XXX need different driver interface */ - /* XXX bypasses q max and OACTIVE */ - IF_PREPEND_LIST(&parent->if_snd, qhead->head, qhead->tail, - qhead->len); - qhead->head = qhead->tail = NULL; - qhead->len = 0; - } else - parent = NULL; - - qhead = &psq->psq_head[1]; /* 802.3 frames */ - if (qhead->head != NULL) { - ifp = vap->iv_ifp; - /* XXX need different driver interface */ - /* XXX bypasses q max and OACTIVE */ - IF_PREPEND_LIST(&ifp->if_snd, qhead->head, qhead->tail, - qhead->len); - qhead->head = qhead->tail = NULL; - qhead->len = 0; - } else - ifp = NULL; - psq->psq_len = 0; - IEEE80211_PSQ_UNLOCK(psq); - - /* NB: do this outside the psq lock */ - /* XXX packets might get reordered if parent is OACTIVE */ - if (parent != NULL) - if_start(parent); - if (ifp != NULL) - if_start(ifp); -} - -/* - * Handle station power-save state change. - */ -void -ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable) -{ - struct ieee80211vap *vap = ni->ni_vap; - int update; - - update = 0; - if (enable) { - if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) { - vap->iv_ps_sta++; - update = 1; - } - ni->ni_flags |= IEEE80211_NODE_PWR_MGT; - IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, - "power save mode on, %u sta's in ps mode", vap->iv_ps_sta); - - if (update) - vap->iv_update_ps(vap, vap->iv_ps_sta); - } else { - if (ni->ni_flags & IEEE80211_NODE_PWR_MGT) { - vap->iv_ps_sta--; - update = 1; - } - ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; - IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, - "power save mode off, %u sta's in ps mode", vap->iv_ps_sta); - - /* NB: order here is intentional so TIM is clear before flush */ - if (vap->iv_set_tim != NULL) - vap->iv_set_tim(ni, 0); - if (update) { - /* NB if no sta's in ps, driver should flush mc q */ - vap->iv_update_ps(vap, vap->iv_ps_sta); - } - if (ni->ni_psq.psq_len != 0) - pwrsave_flushq(ni); - } -} - -/* - * Handle power-save state change in station mode. - */ -void -ieee80211_sta_pwrsave(struct ieee80211vap *vap, int enable) -{ - struct ieee80211_node *ni = vap->iv_bss; - - if (!((enable != 0) ^ ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) != 0))) - return; - - IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, - "sta power save mode %s", enable ? "on" : "off"); - if (!enable) { - ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; - ieee80211_send_nulldata(ieee80211_ref_node(ni)); - /* - * Flush any queued frames; we can do this immediately - * because we know they'll be queued behind the null - * data frame we send the ap. - * XXX can we use a data frame to take us out of ps? - */ - if (ni->ni_psq.psq_len != 0) - pwrsave_flushq(ni); - } else { - ni->ni_flags |= IEEE80211_NODE_PWR_MGT; - ieee80211_send_nulldata(ieee80211_ref_node(ni)); - } -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_power.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_power.h deleted file mode 100644 index 29f04da473..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_power.h +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_POWER_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_POWER_H_ - -struct ieee80211com; -struct ieee80211vap; -struct ieee80211_node; -struct mbuf; - -/* - * Power save packet queues. There are two queues, one - * for frames coming from the net80211 layer and the other - * for frames that come from the driver. Frames from the - * driver are expected to have M_ENCAP marked to indicate - * they have already been encapsulated and are treated as - * higher priority: they are sent first when flushing the - * queue on a power save state change or in response to a - * ps-poll frame. - * - * Note that frames sent from the high priority queue are - * fed directly to the driver without going through - * ieee80211_start again; drivers that send up encap'd - * frames are required to handle them when they come back. - */ -struct ieee80211_psq { - ieee80211_psq_lock_t psq_lock; - int psq_len; - int psq_maxlen; - int psq_drops; - struct ieee80211_psq_head { - struct mbuf *head; - struct mbuf *tail; - int len; - } psq_head[2]; /* 2 priorities */ -}; - -void ieee80211_psq_init(struct ieee80211_psq *, const char *); -void ieee80211_psq_cleanup(struct ieee80211_psq *); - -void ieee80211_power_attach(struct ieee80211com *); -void ieee80211_power_detach(struct ieee80211com *); -void ieee80211_power_vattach(struct ieee80211vap *); -void ieee80211_power_vdetach(struct ieee80211vap *); -void ieee80211_power_latevattach(struct ieee80211vap *); - -struct mbuf *ieee80211_node_psq_dequeue(struct ieee80211_node *ni, int *qlen); -int ieee80211_node_psq_drain(struct ieee80211_node *); -int ieee80211_node_psq_age(struct ieee80211_node *); -int ieee80211_pwrsave(struct ieee80211_node *, struct mbuf *); -void ieee80211_node_pwrsave(struct ieee80211_node *, int enable); -void ieee80211_sta_pwrsave(struct ieee80211vap *, int enable); - -void ieee80211_power_poll(struct ieee80211com *); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_POWER_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_proto.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_proto.c deleted file mode 100644 index f44c594111..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_proto.c +++ /dev/null @@ -1,1930 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 protocol support. - */ - -#include "opt_inet.h" -#include "opt_wlan.h" - -#include -#include -#include - -#include -#include - -#include -#include -#include /* XXX for ether_sprintf */ - -#include -#include -#include -#include -#include -#ifdef IEEE80211_SUPPORT_MESH -#include -#endif -#include -#include - -/* XXX tunables */ -#define AGGRESSIVE_MODE_SWITCH_HYSTERESIS 3 /* pkts / 100ms */ -#define HIGH_PRI_SWITCH_THRESH 10 /* pkts / 100ms */ - -const char *ieee80211_mgt_subtype_name[] = { - "assoc_req", "assoc_resp", "reassoc_req", "reassoc_resp", - "probe_req", "probe_resp", "reserved#6", "reserved#7", - "beacon", "atim", "disassoc", "auth", - "deauth", "action", "action_noack", "reserved#15" -}; -const char *ieee80211_ctl_subtype_name[] = { - "reserved#0", "reserved#1", "reserved#2", "reserved#3", - "reserved#3", "reserved#5", "reserved#6", "reserved#7", - "reserved#8", "reserved#9", "ps_poll", "rts", - "cts", "ack", "cf_end", "cf_end_ack" -}; -const char *ieee80211_opmode_name[IEEE80211_OPMODE_MAX] = { - "IBSS", /* IEEE80211_M_IBSS */ - "STA", /* IEEE80211_M_STA */ - "WDS", /* IEEE80211_M_WDS */ - "AHDEMO", /* IEEE80211_M_AHDEMO */ - "HOSTAP", /* IEEE80211_M_HOSTAP */ - "MONITOR", /* IEEE80211_M_MONITOR */ - "MBSS" /* IEEE80211_M_MBSS */ -}; -const char *ieee80211_state_name[IEEE80211_S_MAX] = { - "INIT", /* IEEE80211_S_INIT */ - "SCAN", /* IEEE80211_S_SCAN */ - "AUTH", /* IEEE80211_S_AUTH */ - "ASSOC", /* IEEE80211_S_ASSOC */ - "CAC", /* IEEE80211_S_CAC */ - "RUN", /* IEEE80211_S_RUN */ - "CSA", /* IEEE80211_S_CSA */ - "SLEEP", /* IEEE80211_S_SLEEP */ -}; -const char *ieee80211_wme_acnames[] = { - "WME_AC_BE", - "WME_AC_BK", - "WME_AC_VI", - "WME_AC_VO", - "WME_UPSD", -}; - -static void beacon_miss(void *, int); -static void beacon_swmiss(void *, int); -static void parent_updown(void *, int); -static void update_mcast(void *, int); -static void update_promisc(void *, int); -static void update_channel(void *, int); -static void ieee80211_newstate_cb(void *, int); -static int ieee80211_new_state_locked(struct ieee80211vap *, - enum ieee80211_state, int); - -static int -null_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, - const struct ieee80211_bpf_params *params) -{ - struct ifnet *ifp = ni->ni_ic->ic_ifp; - - if_printf(ifp, "missing ic_raw_xmit callback, drop frame\n"); - m_freem(m); - return ENETDOWN; -} - -void -ieee80211_proto_attach(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - - /* override the 802.3 setting */ - ifp->if_hdrlen = ic->ic_headroom - + sizeof(struct ieee80211_qosframe_addr4) - + IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN - + IEEE80211_WEP_EXTIVLEN; - /* XXX no way to recalculate on ifdetach */ - if (ALIGN(ifp->if_hdrlen) > max_linkhdr) { - /* XXX sanity check... */ - max_linkhdr = ALIGN(ifp->if_hdrlen); - max_hdr = max_linkhdr + max_protohdr; - max_datalen = MHLEN - max_hdr; - } - ic->ic_protmode = IEEE80211_PROT_CTSONLY; - - TASK_INIT(&ic->ic_parent_task, 0, parent_updown, ifp); - TASK_INIT(&ic->ic_mcast_task, 0, update_mcast, ic); - TASK_INIT(&ic->ic_promisc_task, 0, update_promisc, ic); - TASK_INIT(&ic->ic_chan_task, 0, update_channel, ic); - TASK_INIT(&ic->ic_bmiss_task, 0, beacon_miss, ic); - - ic->ic_wme.wme_hipri_switch_hysteresis = - AGGRESSIVE_MODE_SWITCH_HYSTERESIS; - - /* initialize management frame handlers */ - ic->ic_send_mgmt = ieee80211_send_mgmt; - ic->ic_raw_xmit = null_raw_xmit; - - ieee80211_adhoc_attach(ic); - ieee80211_sta_attach(ic); - ieee80211_wds_attach(ic); - ieee80211_hostap_attach(ic); -#ifdef IEEE80211_SUPPORT_MESH - ieee80211_mesh_attach(ic); -#endif - ieee80211_monitor_attach(ic); -} - -void -ieee80211_proto_detach(struct ieee80211com *ic) -{ - ieee80211_monitor_detach(ic); -#ifdef IEEE80211_SUPPORT_MESH - ieee80211_mesh_detach(ic); -#endif - ieee80211_hostap_detach(ic); - ieee80211_wds_detach(ic); - ieee80211_adhoc_detach(ic); - ieee80211_sta_detach(ic); -} - -static void -null_update_beacon(struct ieee80211vap *vap, int item) -{ -} - -void -ieee80211_proto_vattach(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = vap->iv_ifp; - int i; - - /* override the 802.3 setting */ - ifp->if_hdrlen = ic->ic_ifp->if_hdrlen; - - vap->iv_rtsthreshold = IEEE80211_RTS_DEFAULT; - vap->iv_fragthreshold = IEEE80211_FRAG_DEFAULT; - vap->iv_bmiss_max = IEEE80211_BMISS_MAX; - callout_init(&vap->iv_swbmiss, CALLOUT_MPSAFE); - callout_init(&vap->iv_mgtsend, CALLOUT_MPSAFE); - TASK_INIT(&vap->iv_nstate_task, 0, ieee80211_newstate_cb, vap); - TASK_INIT(&vap->iv_swbmiss_task, 0, beacon_swmiss, vap); - /* - * Install default tx rate handling: no fixed rate, lowest - * supported rate for mgmt and multicast frames. Default - * max retry count. These settings can be changed by the - * driver and/or user applications. - */ - for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_MAX; i++) { - const struct ieee80211_rateset *rs = &ic->ic_sup_rates[i]; - - vap->iv_txparms[i].ucastrate = IEEE80211_FIXED_RATE_NONE; - - /* - * Setting the management rate to MCS 0 assumes that the - * BSS Basic rate set is empty and the BSS Basic MCS set - * is not. - * - * Since we're not checking this, default to the lowest - * defined rate for this mode. - * - * At least one 11n AP (DLINK DIR-825) is reported to drop - * some MCS management traffic (eg BA response frames.) - * - * See also: 9.6.0 of the 802.11n-2009 specification. - */ -#ifdef NOTYET - if (i == IEEE80211_MODE_11NA || i == IEEE80211_MODE_11NG) { - vap->iv_txparms[i].mgmtrate = 0 | IEEE80211_RATE_MCS; - vap->iv_txparms[i].mcastrate = 0 | IEEE80211_RATE_MCS; - } else { - vap->iv_txparms[i].mgmtrate = - rs->rs_rates[0] & IEEE80211_RATE_VAL; - vap->iv_txparms[i].mcastrate = - rs->rs_rates[0] & IEEE80211_RATE_VAL; - } -#endif - vap->iv_txparms[i].mgmtrate = rs->rs_rates[0] & IEEE80211_RATE_VAL; - vap->iv_txparms[i].mcastrate = rs->rs_rates[0] & IEEE80211_RATE_VAL; - vap->iv_txparms[i].maxretry = IEEE80211_TXMAX_DEFAULT; - } - vap->iv_roaming = IEEE80211_ROAMING_AUTO; - - vap->iv_update_beacon = null_update_beacon; - vap->iv_deliver_data = ieee80211_deliver_data; - - /* attach support for operating mode */ - ic->ic_vattach[vap->iv_opmode](vap); -} - -void -ieee80211_proto_vdetach(struct ieee80211vap *vap) -{ -#define FREEAPPIE(ie) do { \ - if (ie != NULL) \ - free(ie, M_80211_NODE_IE); \ -} while (0) - /* - * Detach operating mode module. - */ - if (vap->iv_opdetach != NULL) - vap->iv_opdetach(vap); - /* - * This should not be needed as we detach when reseting - * the state but be conservative here since the - * authenticator may do things like spawn kernel threads. - */ - if (vap->iv_auth->ia_detach != NULL) - vap->iv_auth->ia_detach(vap); - /* - * Detach any ACL'ator. - */ - if (vap->iv_acl != NULL) - vap->iv_acl->iac_detach(vap); - - FREEAPPIE(vap->iv_appie_beacon); - FREEAPPIE(vap->iv_appie_probereq); - FREEAPPIE(vap->iv_appie_proberesp); - FREEAPPIE(vap->iv_appie_assocreq); - FREEAPPIE(vap->iv_appie_assocresp); - FREEAPPIE(vap->iv_appie_wpa); -#undef FREEAPPIE -} - -/* - * Simple-minded authenticator module support. - */ - -#define IEEE80211_AUTH_MAX (IEEE80211_AUTH_WPA+1) -/* XXX well-known names */ -static const char *auth_modnames[IEEE80211_AUTH_MAX] = { - "wlan_internal", /* IEEE80211_AUTH_NONE */ - "wlan_internal", /* IEEE80211_AUTH_OPEN */ - "wlan_internal", /* IEEE80211_AUTH_SHARED */ - "wlan_xauth", /* IEEE80211_AUTH_8021X */ - "wlan_internal", /* IEEE80211_AUTH_AUTO */ - "wlan_xauth", /* IEEE80211_AUTH_WPA */ -}; -static const struct ieee80211_authenticator *authenticators[IEEE80211_AUTH_MAX]; - -static const struct ieee80211_authenticator auth_internal = { - .ia_name = "wlan_internal", - .ia_attach = NULL, - .ia_detach = NULL, - .ia_node_join = NULL, - .ia_node_leave = NULL, -}; - -/* - * Setup internal authenticators once; they are never unregistered. - */ -void -ieee80211_auth_setup(void) -{ - ieee80211_authenticator_register(IEEE80211_AUTH_OPEN, &auth_internal); - ieee80211_authenticator_register(IEEE80211_AUTH_SHARED, &auth_internal); - ieee80211_authenticator_register(IEEE80211_AUTH_AUTO, &auth_internal); -} -SYSINIT(wlan_auth, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_auth_setup, NULL); - -const struct ieee80211_authenticator * -ieee80211_authenticator_get(int auth) -{ - if (auth >= IEEE80211_AUTH_MAX) - return NULL; - if (authenticators[auth] == NULL) - ieee80211_load_module(auth_modnames[auth]); - return authenticators[auth]; -} - -void -ieee80211_authenticator_register(int type, - const struct ieee80211_authenticator *auth) -{ - if (type >= IEEE80211_AUTH_MAX) - return; - authenticators[type] = auth; -} - -void -ieee80211_authenticator_unregister(int type) -{ - - if (type >= IEEE80211_AUTH_MAX) - return; - authenticators[type] = NULL; -} - -/* - * Very simple-minded ACL module support. - */ -/* XXX just one for now */ -static const struct ieee80211_aclator *acl = NULL; - -void -ieee80211_aclator_register(const struct ieee80211_aclator *iac) -{ - printf("wlan: %s acl policy registered\n", iac->iac_name); - acl = iac; -} - -void -ieee80211_aclator_unregister(const struct ieee80211_aclator *iac) -{ - if (acl == iac) - acl = NULL; - printf("wlan: %s acl policy unregistered\n", iac->iac_name); -} - -const struct ieee80211_aclator * -ieee80211_aclator_get(const char *name) -{ - if (acl == NULL) - ieee80211_load_module("wlan_acl"); - return acl != NULL && strcmp(acl->iac_name, name) == 0 ? acl : NULL; -} - -void -ieee80211_print_essid(const uint8_t *essid, int len) -{ - const uint8_t *p; - int i; - - if (len > IEEE80211_NWID_LEN) - len = IEEE80211_NWID_LEN; - /* determine printable or not */ - for (i = 0, p = essid; i < len; i++, p++) { - if (*p < ' ' || *p > 0x7e) - break; - } - if (i == len) { - printf("\""); - for (i = 0, p = essid; i < len; i++, p++) - printf("%c", *p); - printf("\""); - } else { - printf("0x"); - for (i = 0, p = essid; i < len; i++, p++) - printf("%02x", *p); - } -} - -void -ieee80211_dump_pkt(struct ieee80211com *ic, - const uint8_t *buf, int len, int rate, int rssi) -{ - const struct ieee80211_frame *wh; - int i; - - wh = (const struct ieee80211_frame *)buf; - switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { - case IEEE80211_FC1_DIR_NODS: - printf("NODS %s", ether_sprintf(wh->i_addr2)); - printf("->%s", ether_sprintf(wh->i_addr1)); - printf("(%s)", ether_sprintf(wh->i_addr3)); - break; - case IEEE80211_FC1_DIR_TODS: - printf("TODS %s", ether_sprintf(wh->i_addr2)); - printf("->%s", ether_sprintf(wh->i_addr3)); - printf("(%s)", ether_sprintf(wh->i_addr1)); - break; - case IEEE80211_FC1_DIR_FROMDS: - printf("FRDS %s", ether_sprintf(wh->i_addr3)); - printf("->%s", ether_sprintf(wh->i_addr1)); - printf("(%s)", ether_sprintf(wh->i_addr2)); - break; - case IEEE80211_FC1_DIR_DSTODS: - printf("DSDS %s", ether_sprintf((const uint8_t *)&wh[1])); - printf("->%s", ether_sprintf(wh->i_addr3)); - printf("(%s", ether_sprintf(wh->i_addr2)); - printf("->%s)", ether_sprintf(wh->i_addr1)); - break; - } - switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { - case IEEE80211_FC0_TYPE_DATA: - printf(" data"); - break; - case IEEE80211_FC0_TYPE_MGT: - printf(" %s", ieee80211_mgt_subtype_name[ - (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) - >> IEEE80211_FC0_SUBTYPE_SHIFT]); - break; - default: - printf(" type#%d", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK); - break; - } - if (IEEE80211_QOS_HAS_SEQ(wh)) { - const struct ieee80211_qosframe *qwh = - (const struct ieee80211_qosframe *)buf; - printf(" QoS [TID %u%s]", qwh->i_qos[0] & IEEE80211_QOS_TID, - qwh->i_qos[0] & IEEE80211_QOS_ACKPOLICY ? " ACM" : ""); - } - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - int off; - - off = ieee80211_anyhdrspace(ic, wh); - printf(" WEP [IV %.02x %.02x %.02x", - buf[off+0], buf[off+1], buf[off+2]); - if (buf[off+IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) - printf(" %.02x %.02x %.02x", - buf[off+4], buf[off+5], buf[off+6]); - printf(" KID %u]", buf[off+IEEE80211_WEP_IVLEN] >> 6); - } - if (rate >= 0) - printf(" %dM", rate / 2); - if (rssi >= 0) - printf(" +%d", rssi); - printf("\n"); - if (len > 0) { - for (i = 0; i < len; i++) { - if ((i & 1) == 0) - printf(" "); - printf("%02x", buf[i]); - } - printf("\n"); - } -} - -static __inline int -findrix(const struct ieee80211_rateset *rs, int r) -{ - int i; - - for (i = 0; i < rs->rs_nrates; i++) - if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == r) - return i; - return -1; -} - -int -ieee80211_fix_rate(struct ieee80211_node *ni, - struct ieee80211_rateset *nrs, int flags) -{ -#define RV(v) ((v) & IEEE80211_RATE_VAL) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - int i, j, rix, error; - int okrate, badrate, fixedrate, ucastrate; - const struct ieee80211_rateset *srs; - uint8_t r; - - error = 0; - okrate = badrate = 0; - ucastrate = vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)].ucastrate; - if (ucastrate != IEEE80211_FIXED_RATE_NONE) { - /* - * Workaround awkwardness with fixed rate. We are called - * to check both the legacy rate set and the HT rate set - * but we must apply any legacy fixed rate check only to the - * legacy rate set and vice versa. We cannot tell what type - * of rate set we've been given (legacy or HT) but we can - * distinguish the fixed rate type (MCS have 0x80 set). - * So to deal with this the caller communicates whether to - * check MCS or legacy rate using the flags and we use the - * type of any fixed rate to avoid applying an MCS to a - * legacy rate and vice versa. - */ - if (ucastrate & 0x80) { - if (flags & IEEE80211_F_DOFRATE) - flags &= ~IEEE80211_F_DOFRATE; - } else if ((ucastrate & 0x80) == 0) { - if (flags & IEEE80211_F_DOFMCS) - flags &= ~IEEE80211_F_DOFMCS; - } - /* NB: required to make MCS match below work */ - ucastrate &= IEEE80211_RATE_VAL; - } - fixedrate = IEEE80211_FIXED_RATE_NONE; - /* - * XXX we are called to process both MCS and legacy rates; - * we must use the appropriate basic rate set or chaos will - * ensue; for now callers that want MCS must supply - * IEEE80211_F_DOBRS; at some point we'll need to split this - * function so there are two variants, one for MCS and one - * for legacy rates. - */ - if (flags & IEEE80211_F_DOBRS) - srs = (const struct ieee80211_rateset *) - ieee80211_get_suphtrates(ic, ni->ni_chan); - else - srs = ieee80211_get_suprates(ic, ni->ni_chan); - for (i = 0; i < nrs->rs_nrates; ) { - if (flags & IEEE80211_F_DOSORT) { - /* - * Sort rates. - */ - for (j = i + 1; j < nrs->rs_nrates; j++) { - if (RV(nrs->rs_rates[i]) > RV(nrs->rs_rates[j])) { - r = nrs->rs_rates[i]; - nrs->rs_rates[i] = nrs->rs_rates[j]; - nrs->rs_rates[j] = r; - } - } - } - r = nrs->rs_rates[i] & IEEE80211_RATE_VAL; - badrate = r; - /* - * Check for fixed rate. - */ - if (r == ucastrate) - fixedrate = r; - /* - * Check against supported rates. - */ - rix = findrix(srs, r); - if (flags & IEEE80211_F_DONEGO) { - if (rix < 0) { - /* - * A rate in the node's rate set is not - * supported. If this is a basic rate and we - * are operating as a STA then this is an error. - * Otherwise we just discard/ignore the rate. - */ - if ((flags & IEEE80211_F_JOIN) && - (nrs->rs_rates[i] & IEEE80211_RATE_BASIC)) - error++; - } else if ((flags & IEEE80211_F_JOIN) == 0) { - /* - * Overwrite with the supported rate - * value so any basic rate bit is set. - */ - nrs->rs_rates[i] = srs->rs_rates[rix]; - } - } - if ((flags & IEEE80211_F_DODEL) && rix < 0) { - /* - * Delete unacceptable rates. - */ - nrs->rs_nrates--; - for (j = i; j < nrs->rs_nrates; j++) - nrs->rs_rates[j] = nrs->rs_rates[j + 1]; - nrs->rs_rates[j] = 0; - continue; - } - if (rix >= 0) - okrate = nrs->rs_rates[i]; - i++; - } - if (okrate == 0 || error != 0 || - ((flags & (IEEE80211_F_DOFRATE|IEEE80211_F_DOFMCS)) && - fixedrate != ucastrate)) { - IEEE80211_NOTE(vap, IEEE80211_MSG_XRATE | IEEE80211_MSG_11N, ni, - "%s: flags 0x%x okrate %d error %d fixedrate 0x%x " - "ucastrate %x\n", __func__, fixedrate, ucastrate, flags); - return badrate | IEEE80211_RATE_BASIC; - } else - return RV(okrate); -#undef RV -} - -/* - * Reset 11g-related state. - */ -void -ieee80211_reset_erp(struct ieee80211com *ic) -{ - ic->ic_flags &= ~IEEE80211_F_USEPROT; - ic->ic_nonerpsta = 0; - ic->ic_longslotsta = 0; - /* - * Short slot time is enabled only when operating in 11g - * and not in an IBSS. We must also honor whether or not - * the driver is capable of doing it. - */ - ieee80211_set_shortslottime(ic, - IEEE80211_IS_CHAN_A(ic->ic_curchan) || - IEEE80211_IS_CHAN_HT(ic->ic_curchan) || - (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) && - ic->ic_opmode == IEEE80211_M_HOSTAP && - (ic->ic_caps & IEEE80211_C_SHSLOT))); - /* - * Set short preamble and ERP barker-preamble flags. - */ - if (IEEE80211_IS_CHAN_A(ic->ic_curchan) || - (ic->ic_caps & IEEE80211_C_SHPREAMBLE)) { - ic->ic_flags |= IEEE80211_F_SHPREAMBLE; - ic->ic_flags &= ~IEEE80211_F_USEBARKER; - } else { - ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; - ic->ic_flags |= IEEE80211_F_USEBARKER; - } -} - -/* - * Set the short slot time state and notify the driver. - */ -void -ieee80211_set_shortslottime(struct ieee80211com *ic, int onoff) -{ - if (onoff) - ic->ic_flags |= IEEE80211_F_SHSLOT; - else - ic->ic_flags &= ~IEEE80211_F_SHSLOT; - /* notify driver */ - if (ic->ic_updateslot != NULL) - ic->ic_updateslot(ic->ic_ifp); -} - -/* - * Check if the specified rate set supports ERP. - * NB: the rate set is assumed to be sorted. - */ -int -ieee80211_iserp_rateset(const struct ieee80211_rateset *rs) -{ -#define N(a) (sizeof(a) / sizeof(a[0])) - static const int rates[] = { 2, 4, 11, 22, 12, 24, 48 }; - int i, j; - - if (rs->rs_nrates < N(rates)) - return 0; - for (i = 0; i < N(rates); i++) { - for (j = 0; j < rs->rs_nrates; j++) { - int r = rs->rs_rates[j] & IEEE80211_RATE_VAL; - if (rates[i] == r) - goto next; - if (r > rates[i]) - return 0; - } - return 0; - next: - ; - } - return 1; -#undef N -} - -/* - * Mark the basic rates for the rate table based on the - * operating mode. For real 11g we mark all the 11b rates - * and 6, 12, and 24 OFDM. For 11b compatibility we mark only - * 11b rates. There's also a pseudo 11a-mode used to mark only - * the basic OFDM rates. - */ -static void -setbasicrates(struct ieee80211_rateset *rs, - enum ieee80211_phymode mode, int add) -{ - static const struct ieee80211_rateset basic[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_11A] = { 3, { 12, 24, 48 } }, - [IEEE80211_MODE_11B] = { 2, { 2, 4 } }, - /* NB: mixed b/g */ - [IEEE80211_MODE_11G] = { 4, { 2, 4, 11, 22 } }, - [IEEE80211_MODE_TURBO_A] = { 3, { 12, 24, 48 } }, - [IEEE80211_MODE_TURBO_G] = { 4, { 2, 4, 11, 22 } }, - [IEEE80211_MODE_STURBO_A] = { 3, { 12, 24, 48 } }, - [IEEE80211_MODE_HALF] = { 3, { 6, 12, 24 } }, - [IEEE80211_MODE_QUARTER] = { 3, { 3, 6, 12 } }, - [IEEE80211_MODE_11NA] = { 3, { 12, 24, 48 } }, - /* NB: mixed b/g */ - [IEEE80211_MODE_11NG] = { 4, { 2, 4, 11, 22 } }, - }; - int i, j; - - for (i = 0; i < rs->rs_nrates; i++) { - if (!add) - rs->rs_rates[i] &= IEEE80211_RATE_VAL; - for (j = 0; j < basic[mode].rs_nrates; j++) - if (basic[mode].rs_rates[j] == rs->rs_rates[i]) { - rs->rs_rates[i] |= IEEE80211_RATE_BASIC; - break; - } - } -} - -/* - * Set the basic rates in a rate set. - */ -void -ieee80211_setbasicrates(struct ieee80211_rateset *rs, - enum ieee80211_phymode mode) -{ - setbasicrates(rs, mode, 0); -} - -/* - * Add basic rates to a rate set. - */ -void -ieee80211_addbasicrates(struct ieee80211_rateset *rs, - enum ieee80211_phymode mode) -{ - setbasicrates(rs, mode, 1); -} - -/* - * WME protocol support. - * - * The default 11a/b/g/n parameters come from the WiFi Alliance WMM - * System Interopability Test Plan (v1.4, Appendix F) and the 802.11n - * Draft 2.0 Test Plan (Appendix D). - * - * Static/Dynamic Turbo mode settings come from Atheros. - */ -typedef struct phyParamType { - uint8_t aifsn; - uint8_t logcwmin; - uint8_t logcwmax; - uint16_t txopLimit; - uint8_t acm; -} paramType; - -static const struct phyParamType phyParamForAC_BE[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = { 3, 4, 6, 0, 0 }, - [IEEE80211_MODE_11A] = { 3, 4, 6, 0, 0 }, - [IEEE80211_MODE_11B] = { 3, 4, 6, 0, 0 }, - [IEEE80211_MODE_11G] = { 3, 4, 6, 0, 0 }, - [IEEE80211_MODE_FH] = { 3, 4, 6, 0, 0 }, - [IEEE80211_MODE_TURBO_A]= { 2, 3, 5, 0, 0 }, - [IEEE80211_MODE_TURBO_G]= { 2, 3, 5, 0, 0 }, - [IEEE80211_MODE_STURBO_A]={ 2, 3, 5, 0, 0 }, - [IEEE80211_MODE_HALF] = { 3, 4, 6, 0, 0 }, - [IEEE80211_MODE_QUARTER]= { 3, 4, 6, 0, 0 }, - [IEEE80211_MODE_11NA] = { 3, 4, 6, 0, 0 }, - [IEEE80211_MODE_11NG] = { 3, 4, 6, 0, 0 }, -}; -static const struct phyParamType phyParamForAC_BK[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = { 7, 4, 10, 0, 0 }, - [IEEE80211_MODE_11A] = { 7, 4, 10, 0, 0 }, - [IEEE80211_MODE_11B] = { 7, 4, 10, 0, 0 }, - [IEEE80211_MODE_11G] = { 7, 4, 10, 0, 0 }, - [IEEE80211_MODE_FH] = { 7, 4, 10, 0, 0 }, - [IEEE80211_MODE_TURBO_A]= { 7, 3, 10, 0, 0 }, - [IEEE80211_MODE_TURBO_G]= { 7, 3, 10, 0, 0 }, - [IEEE80211_MODE_STURBO_A]={ 7, 3, 10, 0, 0 }, - [IEEE80211_MODE_HALF] = { 7, 4, 10, 0, 0 }, - [IEEE80211_MODE_QUARTER]= { 7, 4, 10, 0, 0 }, - [IEEE80211_MODE_11NA] = { 7, 4, 10, 0, 0 }, - [IEEE80211_MODE_11NG] = { 7, 4, 10, 0, 0 }, -}; -static const struct phyParamType phyParamForAC_VI[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = { 1, 3, 4, 94, 0 }, - [IEEE80211_MODE_11A] = { 1, 3, 4, 94, 0 }, - [IEEE80211_MODE_11B] = { 1, 3, 4, 188, 0 }, - [IEEE80211_MODE_11G] = { 1, 3, 4, 94, 0 }, - [IEEE80211_MODE_FH] = { 1, 3, 4, 188, 0 }, - [IEEE80211_MODE_TURBO_A]= { 1, 2, 3, 94, 0 }, - [IEEE80211_MODE_TURBO_G]= { 1, 2, 3, 94, 0 }, - [IEEE80211_MODE_STURBO_A]={ 1, 2, 3, 94, 0 }, - [IEEE80211_MODE_HALF] = { 1, 3, 4, 94, 0 }, - [IEEE80211_MODE_QUARTER]= { 1, 3, 4, 94, 0 }, - [IEEE80211_MODE_11NA] = { 1, 3, 4, 94, 0 }, - [IEEE80211_MODE_11NG] = { 1, 3, 4, 94, 0 }, -}; -static const struct phyParamType phyParamForAC_VO[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = { 1, 2, 3, 47, 0 }, - [IEEE80211_MODE_11A] = { 1, 2, 3, 47, 0 }, - [IEEE80211_MODE_11B] = { 1, 2, 3, 102, 0 }, - [IEEE80211_MODE_11G] = { 1, 2, 3, 47, 0 }, - [IEEE80211_MODE_FH] = { 1, 2, 3, 102, 0 }, - [IEEE80211_MODE_TURBO_A]= { 1, 2, 2, 47, 0 }, - [IEEE80211_MODE_TURBO_G]= { 1, 2, 2, 47, 0 }, - [IEEE80211_MODE_STURBO_A]={ 1, 2, 2, 47, 0 }, - [IEEE80211_MODE_HALF] = { 1, 2, 3, 47, 0 }, - [IEEE80211_MODE_QUARTER]= { 1, 2, 3, 47, 0 }, - [IEEE80211_MODE_11NA] = { 1, 2, 3, 47, 0 }, - [IEEE80211_MODE_11NG] = { 1, 2, 3, 47, 0 }, -}; - -static const struct phyParamType bssPhyParamForAC_BE[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = { 3, 4, 10, 0, 0 }, - [IEEE80211_MODE_11A] = { 3, 4, 10, 0, 0 }, - [IEEE80211_MODE_11B] = { 3, 4, 10, 0, 0 }, - [IEEE80211_MODE_11G] = { 3, 4, 10, 0, 0 }, - [IEEE80211_MODE_FH] = { 3, 4, 10, 0, 0 }, - [IEEE80211_MODE_TURBO_A]= { 2, 3, 10, 0, 0 }, - [IEEE80211_MODE_TURBO_G]= { 2, 3, 10, 0, 0 }, - [IEEE80211_MODE_STURBO_A]={ 2, 3, 10, 0, 0 }, - [IEEE80211_MODE_HALF] = { 3, 4, 10, 0, 0 }, - [IEEE80211_MODE_QUARTER]= { 3, 4, 10, 0, 0 }, - [IEEE80211_MODE_11NA] = { 3, 4, 10, 0, 0 }, - [IEEE80211_MODE_11NG] = { 3, 4, 10, 0, 0 }, -}; -static const struct phyParamType bssPhyParamForAC_VI[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = { 2, 3, 4, 94, 0 }, - [IEEE80211_MODE_11A] = { 2, 3, 4, 94, 0 }, - [IEEE80211_MODE_11B] = { 2, 3, 4, 188, 0 }, - [IEEE80211_MODE_11G] = { 2, 3, 4, 94, 0 }, - [IEEE80211_MODE_FH] = { 2, 3, 4, 188, 0 }, - [IEEE80211_MODE_TURBO_A]= { 2, 2, 3, 94, 0 }, - [IEEE80211_MODE_TURBO_G]= { 2, 2, 3, 94, 0 }, - [IEEE80211_MODE_STURBO_A]={ 2, 2, 3, 94, 0 }, - [IEEE80211_MODE_HALF] = { 2, 3, 4, 94, 0 }, - [IEEE80211_MODE_QUARTER]= { 2, 3, 4, 94, 0 }, - [IEEE80211_MODE_11NA] = { 2, 3, 4, 94, 0 }, - [IEEE80211_MODE_11NG] = { 2, 3, 4, 94, 0 }, -}; -static const struct phyParamType bssPhyParamForAC_VO[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = { 2, 2, 3, 47, 0 }, - [IEEE80211_MODE_11A] = { 2, 2, 3, 47, 0 }, - [IEEE80211_MODE_11B] = { 2, 2, 3, 102, 0 }, - [IEEE80211_MODE_11G] = { 2, 2, 3, 47, 0 }, - [IEEE80211_MODE_FH] = { 2, 2, 3, 102, 0 }, - [IEEE80211_MODE_TURBO_A]= { 1, 2, 2, 47, 0 }, - [IEEE80211_MODE_TURBO_G]= { 1, 2, 2, 47, 0 }, - [IEEE80211_MODE_STURBO_A]={ 1, 2, 2, 47, 0 }, - [IEEE80211_MODE_HALF] = { 2, 2, 3, 47, 0 }, - [IEEE80211_MODE_QUARTER]= { 2, 2, 3, 47, 0 }, - [IEEE80211_MODE_11NA] = { 2, 2, 3, 47, 0 }, - [IEEE80211_MODE_11NG] = { 2, 2, 3, 47, 0 }, -}; - -static void -_setifsparams(struct wmeParams *wmep, const paramType *phy) -{ - wmep->wmep_aifsn = phy->aifsn; - wmep->wmep_logcwmin = phy->logcwmin; - wmep->wmep_logcwmax = phy->logcwmax; - wmep->wmep_txopLimit = phy->txopLimit; -} - -static void -setwmeparams(struct ieee80211vap *vap, const char *type, int ac, - struct wmeParams *wmep, const paramType *phy) -{ - wmep->wmep_acm = phy->acm; - _setifsparams(wmep, phy); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME, - "set %s (%s) [acm %u aifsn %u logcwmin %u logcwmax %u txop %u]\n", - ieee80211_wme_acnames[ac], type, - wmep->wmep_acm, wmep->wmep_aifsn, wmep->wmep_logcwmin, - wmep->wmep_logcwmax, wmep->wmep_txopLimit); -} - -static void -ieee80211_wme_initparams_locked(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_wme_state *wme = &ic->ic_wme; - const paramType *pPhyParam, *pBssPhyParam; - struct wmeParams *wmep; - enum ieee80211_phymode mode; - int i; - - IEEE80211_LOCK_ASSERT(ic); - - if ((ic->ic_caps & IEEE80211_C_WME) == 0 || ic->ic_nrunning > 1) - return; - - /* - * Clear the wme cap_info field so a qoscount from a previous - * vap doesn't confuse later code which only parses the beacon - * field and updates hardware when said field changes. - * Otherwise the hardware is programmed with defaults, not what - * the beacon actually announces. - */ - wme->wme_wmeChanParams.cap_info = 0; - - /* - * Select mode; we can be called early in which case we - * always use auto mode. We know we'll be called when - * entering the RUN state with bsschan setup properly - * so state will eventually get set correctly - */ - if (ic->ic_bsschan != IEEE80211_CHAN_ANYC) - mode = ieee80211_chan2mode(ic->ic_bsschan); - else - mode = IEEE80211_MODE_AUTO; - for (i = 0; i < WME_NUM_AC; i++) { - switch (i) { - case WME_AC_BK: - pPhyParam = &phyParamForAC_BK[mode]; - pBssPhyParam = &phyParamForAC_BK[mode]; - break; - case WME_AC_VI: - pPhyParam = &phyParamForAC_VI[mode]; - pBssPhyParam = &bssPhyParamForAC_VI[mode]; - break; - case WME_AC_VO: - pPhyParam = &phyParamForAC_VO[mode]; - pBssPhyParam = &bssPhyParamForAC_VO[mode]; - break; - case WME_AC_BE: - default: - pPhyParam = &phyParamForAC_BE[mode]; - pBssPhyParam = &bssPhyParamForAC_BE[mode]; - break; - } - wmep = &wme->wme_wmeChanParams.cap_wmeParams[i]; - if (ic->ic_opmode == IEEE80211_M_HOSTAP) { - setwmeparams(vap, "chan", i, wmep, pPhyParam); - } else { - setwmeparams(vap, "chan", i, wmep, pBssPhyParam); - } - wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i]; - setwmeparams(vap, "bss ", i, wmep, pBssPhyParam); - } - /* NB: check ic_bss to avoid NULL deref on initial attach */ - if (vap->iv_bss != NULL) { - /* - * Calculate agressive mode switching threshold based - * on beacon interval. This doesn't need locking since - * we're only called before entering the RUN state at - * which point we start sending beacon frames. - */ - wme->wme_hipri_switch_thresh = - (HIGH_PRI_SWITCH_THRESH * vap->iv_bss->ni_intval) / 100; - wme->wme_flags &= ~WME_F_AGGRMODE; - ieee80211_wme_updateparams(vap); - } -} - -void -ieee80211_wme_initparams(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - - IEEE80211_LOCK(ic); - ieee80211_wme_initparams_locked(vap); - IEEE80211_UNLOCK(ic); -} - -/* - * Update WME parameters for ourself and the BSS. - */ -void -ieee80211_wme_updateparams_locked(struct ieee80211vap *vap) -{ - static const paramType aggrParam[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = { 2, 4, 10, 64, 0 }, - [IEEE80211_MODE_11A] = { 2, 4, 10, 64, 0 }, - [IEEE80211_MODE_11B] = { 2, 5, 10, 64, 0 }, - [IEEE80211_MODE_11G] = { 2, 4, 10, 64, 0 }, - [IEEE80211_MODE_FH] = { 2, 5, 10, 64, 0 }, - [IEEE80211_MODE_TURBO_A] = { 1, 3, 10, 64, 0 }, - [IEEE80211_MODE_TURBO_G] = { 1, 3, 10, 64, 0 }, - [IEEE80211_MODE_STURBO_A] = { 1, 3, 10, 64, 0 }, - [IEEE80211_MODE_HALF] = { 2, 4, 10, 64, 0 }, - [IEEE80211_MODE_QUARTER] = { 2, 4, 10, 64, 0 }, - [IEEE80211_MODE_11NA] = { 2, 4, 10, 64, 0 }, /* XXXcheck*/ - [IEEE80211_MODE_11NG] = { 2, 4, 10, 64, 0 }, /* XXXcheck*/ - }; - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_wme_state *wme = &ic->ic_wme; - const struct wmeParams *wmep; - struct wmeParams *chanp, *bssp; - enum ieee80211_phymode mode; - int i; - - /* - * Set up the channel access parameters for the physical - * device. First populate the configured settings. - */ - for (i = 0; i < WME_NUM_AC; i++) { - chanp = &wme->wme_chanParams.cap_wmeParams[i]; - wmep = &wme->wme_wmeChanParams.cap_wmeParams[i]; - chanp->wmep_aifsn = wmep->wmep_aifsn; - chanp->wmep_logcwmin = wmep->wmep_logcwmin; - chanp->wmep_logcwmax = wmep->wmep_logcwmax; - chanp->wmep_txopLimit = wmep->wmep_txopLimit; - - chanp = &wme->wme_bssChanParams.cap_wmeParams[i]; - wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i]; - chanp->wmep_aifsn = wmep->wmep_aifsn; - chanp->wmep_logcwmin = wmep->wmep_logcwmin; - chanp->wmep_logcwmax = wmep->wmep_logcwmax; - chanp->wmep_txopLimit = wmep->wmep_txopLimit; - } - - /* - * Select mode; we can be called early in which case we - * always use auto mode. We know we'll be called when - * entering the RUN state with bsschan setup properly - * so state will eventually get set correctly - */ - if (ic->ic_bsschan != IEEE80211_CHAN_ANYC) - mode = ieee80211_chan2mode(ic->ic_bsschan); - else - mode = IEEE80211_MODE_AUTO; - - /* - * This implements agressive mode as found in certain - * vendors' AP's. When there is significant high - * priority (VI/VO) traffic in the BSS throttle back BE - * traffic by using conservative parameters. Otherwise - * BE uses agressive params to optimize performance of - * legacy/non-QoS traffic. - */ - if ((vap->iv_opmode == IEEE80211_M_HOSTAP && - (wme->wme_flags & WME_F_AGGRMODE) != 0) || - (vap->iv_opmode == IEEE80211_M_STA && - (vap->iv_bss->ni_flags & IEEE80211_NODE_QOS) == 0) || - (vap->iv_flags & IEEE80211_F_WME) == 0) { - chanp = &wme->wme_chanParams.cap_wmeParams[WME_AC_BE]; - bssp = &wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE]; - - chanp->wmep_aifsn = bssp->wmep_aifsn = aggrParam[mode].aifsn; - chanp->wmep_logcwmin = bssp->wmep_logcwmin = - aggrParam[mode].logcwmin; - chanp->wmep_logcwmax = bssp->wmep_logcwmax = - aggrParam[mode].logcwmax; - chanp->wmep_txopLimit = bssp->wmep_txopLimit = - (vap->iv_flags & IEEE80211_F_BURST) ? - aggrParam[mode].txopLimit : 0; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME, - "update %s (chan+bss) [acm %u aifsn %u logcwmin %u " - "logcwmax %u txop %u]\n", ieee80211_wme_acnames[WME_AC_BE], - chanp->wmep_acm, chanp->wmep_aifsn, chanp->wmep_logcwmin, - chanp->wmep_logcwmax, chanp->wmep_txopLimit); - } - - if (vap->iv_opmode == IEEE80211_M_HOSTAP && - ic->ic_sta_assoc < 2 && (wme->wme_flags & WME_F_AGGRMODE) != 0) { - static const uint8_t logCwMin[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = 3, - [IEEE80211_MODE_11A] = 3, - [IEEE80211_MODE_11B] = 4, - [IEEE80211_MODE_11G] = 3, - [IEEE80211_MODE_FH] = 4, - [IEEE80211_MODE_TURBO_A] = 3, - [IEEE80211_MODE_TURBO_G] = 3, - [IEEE80211_MODE_STURBO_A] = 3, - [IEEE80211_MODE_HALF] = 3, - [IEEE80211_MODE_QUARTER] = 3, - [IEEE80211_MODE_11NA] = 3, - [IEEE80211_MODE_11NG] = 3, - }; - chanp = &wme->wme_chanParams.cap_wmeParams[WME_AC_BE]; - bssp = &wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE]; - - chanp->wmep_logcwmin = bssp->wmep_logcwmin = logCwMin[mode]; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME, - "update %s (chan+bss) logcwmin %u\n", - ieee80211_wme_acnames[WME_AC_BE], chanp->wmep_logcwmin); - } - if (vap->iv_opmode == IEEE80211_M_HOSTAP) { /* XXX ibss? */ - /* - * Arrange for a beacon update and bump the parameter - * set number so associated stations load the new values. - */ - wme->wme_bssChanParams.cap_info = - (wme->wme_bssChanParams.cap_info+1) & WME_QOSINFO_COUNT; - ieee80211_beacon_notify(vap, IEEE80211_BEACON_WME); - } - - wme->wme_update(ic); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME, - "%s: WME params updated, cap_info 0x%x\n", __func__, - vap->iv_opmode == IEEE80211_M_STA ? - wme->wme_wmeChanParams.cap_info : - wme->wme_bssChanParams.cap_info); -} - -void -ieee80211_wme_updateparams(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - - if (ic->ic_caps & IEEE80211_C_WME) { - IEEE80211_LOCK(ic); - ieee80211_wme_updateparams_locked(vap); - IEEE80211_UNLOCK(ic); - } -} - -static void -parent_updown(void *arg, int npending) -{ - struct ifnet *parent = arg; - - parent->if_ioctl(parent, SIOCSIFFLAGS, NULL); -} - -static void -update_mcast(void *arg, int npending) -{ - struct ieee80211com *ic = arg; - struct ifnet *parent = ic->ic_ifp; - - ic->ic_update_mcast(parent); -} - -static void -update_promisc(void *arg, int npending) -{ - struct ieee80211com *ic = arg; - struct ifnet *parent = ic->ic_ifp; - - ic->ic_update_promisc(parent); -} - -static void -update_channel(void *arg, int npending) -{ - struct ieee80211com *ic = arg; - - ic->ic_set_channel(ic); - ieee80211_radiotap_chan_change(ic); -} - -/* - * Block until the parent is in a known state. This is - * used after any operations that dispatch a task (e.g. - * to auto-configure the parent device up/down). - */ -void -ieee80211_waitfor_parent(struct ieee80211com *ic) -{ - taskqueue_block(ic->ic_tq); - ieee80211_draintask(ic, &ic->ic_parent_task); - ieee80211_draintask(ic, &ic->ic_mcast_task); - ieee80211_draintask(ic, &ic->ic_promisc_task); - ieee80211_draintask(ic, &ic->ic_chan_task); - ieee80211_draintask(ic, &ic->ic_bmiss_task); - taskqueue_unblock(ic->ic_tq); -} - -/* - * Start a vap running. If this is the first vap to be - * set running on the underlying device then we - * automatically bring the device up. - */ -void -ieee80211_start_locked(struct ieee80211vap *vap) -{ - struct ifnet *ifp = vap->iv_ifp; - struct ieee80211com *ic = vap->iv_ic; - struct ifnet *parent = ic->ic_ifp; - - IEEE80211_LOCK_ASSERT(ic); - - IEEE80211_DPRINTF(vap, - IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, - "start running, %d vaps running\n", ic->ic_nrunning); - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - /* - * Mark us running. Note that it's ok to do this first; - * if we need to bring the parent device up we defer that - * to avoid dropping the com lock. We expect the device - * to respond to being marked up by calling back into us - * through ieee80211_start_all at which point we'll come - * back in here and complete the work. - */ - ifp->if_drv_flags |= IFF_DRV_RUNNING; - /* - * We are not running; if this we are the first vap - * to be brought up auto-up the parent if necessary. - */ - if (ic->ic_nrunning++ == 0 && - (parent->if_drv_flags & IFF_DRV_RUNNING) == 0) { - IEEE80211_DPRINTF(vap, - IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, - "%s: up parent %s\n", __func__, parent->if_xname); - parent->if_flags |= IFF_UP; - ieee80211_runtask(ic, &ic->ic_parent_task); - return; - } - } - /* - * If the parent is up and running, then kick the - * 802.11 state machine as appropriate. - */ - if ((parent->if_drv_flags & IFF_DRV_RUNNING) && - vap->iv_roaming != IEEE80211_ROAMING_MANUAL) { - if (vap->iv_opmode == IEEE80211_M_STA) { -#if 0 - /* XXX bypasses scan too easily; disable for now */ - /* - * Try to be intelligent about clocking the state - * machine. If we're currently in RUN state then - * we should be able to apply any new state/parameters - * simply by re-associating. Otherwise we need to - * re-scan to select an appropriate ap. - */ - if (vap->iv_state >= IEEE80211_S_RUN) - ieee80211_new_state_locked(vap, - IEEE80211_S_ASSOC, 1); - else -#endif - ieee80211_new_state_locked(vap, - IEEE80211_S_SCAN, 0); - } else { - /* - * For monitor+wds mode there's nothing to do but - * start running. Otherwise if this is the first - * vap to be brought up, start a scan which may be - * preempted if the station is locked to a particular - * channel. - */ - vap->iv_flags_ext |= IEEE80211_FEXT_REINIT; - if (vap->iv_opmode == IEEE80211_M_MONITOR || - vap->iv_opmode == IEEE80211_M_WDS) - ieee80211_new_state_locked(vap, - IEEE80211_S_RUN, -1); - else - ieee80211_new_state_locked(vap, - IEEE80211_S_SCAN, 0); - } - } -} - -/* - * Start a single vap. - */ -void -ieee80211_init(void *arg) -{ - struct ieee80211vap *vap = arg; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, - "%s\n", __func__); - - IEEE80211_LOCK(vap->iv_ic); - ieee80211_start_locked(vap); - IEEE80211_UNLOCK(vap->iv_ic); -} - -/* - * Start all runnable vap's on a device. - */ -void -ieee80211_start_all(struct ieee80211com *ic) -{ - struct ieee80211vap *vap; - - IEEE80211_LOCK(ic); - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - struct ifnet *ifp = vap->iv_ifp; - if (IFNET_IS_UP_RUNNING(ifp)) /* NB: avoid recursion */ - ieee80211_start_locked(vap); - } - IEEE80211_UNLOCK(ic); -} - -/* - * Stop a vap. We force it down using the state machine - * then mark it's ifnet not running. If this is the last - * vap running on the underlying device then we close it - * too to insure it will be properly initialized when the - * next vap is brought up. - */ -void -ieee80211_stop_locked(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = vap->iv_ifp; - struct ifnet *parent = ic->ic_ifp; - - IEEE80211_LOCK_ASSERT(ic); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, - "stop running, %d vaps running\n", ic->ic_nrunning); - - ieee80211_new_state_locked(vap, IEEE80211_S_INIT, -1); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; /* mark us stopped */ - if (--ic->ic_nrunning == 0 && - (parent->if_drv_flags & IFF_DRV_RUNNING)) { - IEEE80211_DPRINTF(vap, - IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, - "down parent %s\n", parent->if_xname); - parent->if_flags &= ~IFF_UP; - ieee80211_runtask(ic, &ic->ic_parent_task); - } - } -} - -void -ieee80211_stop(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - - IEEE80211_LOCK(ic); - ieee80211_stop_locked(vap); - IEEE80211_UNLOCK(ic); -} - -/* - * Stop all vap's running on a device. - */ -void -ieee80211_stop_all(struct ieee80211com *ic) -{ - struct ieee80211vap *vap; - - IEEE80211_LOCK(ic); - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - struct ifnet *ifp = vap->iv_ifp; - if (IFNET_IS_UP_RUNNING(ifp)) /* NB: avoid recursion */ - ieee80211_stop_locked(vap); - } - IEEE80211_UNLOCK(ic); - - ieee80211_waitfor_parent(ic); -} - -/* - * Stop all vap's running on a device and arrange - * for those that were running to be resumed. - */ -void -ieee80211_suspend_all(struct ieee80211com *ic) -{ - struct ieee80211vap *vap; - - IEEE80211_LOCK(ic); - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - struct ifnet *ifp = vap->iv_ifp; - if (IFNET_IS_UP_RUNNING(ifp)) { /* NB: avoid recursion */ - vap->iv_flags_ext |= IEEE80211_FEXT_RESUME; - ieee80211_stop_locked(vap); - } - } - IEEE80211_UNLOCK(ic); - - ieee80211_waitfor_parent(ic); -} - -/* - * Start all vap's marked for resume. - */ -void -ieee80211_resume_all(struct ieee80211com *ic) -{ - struct ieee80211vap *vap; - - IEEE80211_LOCK(ic); - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - struct ifnet *ifp = vap->iv_ifp; - if (!IFNET_IS_UP_RUNNING(ifp) && - (vap->iv_flags_ext & IEEE80211_FEXT_RESUME)) { - vap->iv_flags_ext &= ~IEEE80211_FEXT_RESUME; - ieee80211_start_locked(vap); - } - } - IEEE80211_UNLOCK(ic); -} - -void -ieee80211_beacon_miss(struct ieee80211com *ic) -{ - IEEE80211_LOCK(ic); - if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { - /* Process in a taskq, the handler may reenter the driver */ - ieee80211_runtask(ic, &ic->ic_bmiss_task); - } - IEEE80211_UNLOCK(ic); -} - -static void -beacon_miss(void *arg, int npending) -{ - struct ieee80211com *ic = arg; - struct ieee80211vap *vap; - - /* XXX locking */ - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - /* - * We only pass events through for sta vap's in RUN state; - * may be too restrictive but for now this saves all the - * handlers duplicating these checks. - */ - if (vap->iv_opmode == IEEE80211_M_STA && - vap->iv_state >= IEEE80211_S_RUN && - vap->iv_bmiss != NULL) - vap->iv_bmiss(vap); - } -} - -static void -beacon_swmiss(void *arg, int npending) -{ - struct ieee80211vap *vap = arg; - - if (vap->iv_state != IEEE80211_S_RUN) - return; - - /* XXX Call multiple times if npending > zero? */ - vap->iv_bmiss(vap); -} - -/* - * Software beacon miss handling. Check if any beacons - * were received in the last period. If not post a - * beacon miss; otherwise reset the counter. - */ -void -ieee80211_swbmiss(void *arg) -{ - struct ieee80211vap *vap = arg; - struct ieee80211com *ic = vap->iv_ic; - - /* XXX sleep state? */ - KASSERT(vap->iv_state == IEEE80211_S_RUN, - ("wrong state %d", vap->iv_state)); - - if (ic->ic_flags & IEEE80211_F_SCAN) { - /* - * If scanning just ignore and reset state. If we get a - * bmiss after coming out of scan because we haven't had - * time to receive a beacon then we should probe the AP - * before posting a real bmiss (unless iv_bmiss_max has - * been artifiically lowered). A cleaner solution might - * be to disable the timer on scan start/end but to handle - * case of multiple sta vap's we'd need to disable the - * timers of all affected vap's. - */ - vap->iv_swbmiss_count = 0; - } else if (vap->iv_swbmiss_count == 0) { - if (vap->iv_bmiss != NULL) - ieee80211_runtask(ic, &vap->iv_swbmiss_task); - } else - vap->iv_swbmiss_count = 0; - callout_reset(&vap->iv_swbmiss, vap->iv_swbmiss_period, - ieee80211_swbmiss, vap); -} - -/* - * Start an 802.11h channel switch. We record the parameters, - * mark the operation pending, notify each vap through the - * beacon update mechanism so it can update the beacon frame - * contents, and then switch vap's to CSA state to block outbound - * traffic. Devices that handle CSA directly can use the state - * switch to do the right thing so long as they call - * ieee80211_csa_completeswitch when it's time to complete the - * channel change. Devices that depend on the net80211 layer can - * use ieee80211_beacon_update to handle the countdown and the - * channel switch. - */ -void -ieee80211_csa_startswitch(struct ieee80211com *ic, - struct ieee80211_channel *c, int mode, int count) -{ - struct ieee80211vap *vap; - - IEEE80211_LOCK_ASSERT(ic); - - ic->ic_csa_newchan = c; - ic->ic_csa_mode = mode; - ic->ic_csa_count = count; - ic->ic_flags |= IEEE80211_F_CSAPENDING; - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - if (vap->iv_opmode == IEEE80211_M_HOSTAP || - vap->iv_opmode == IEEE80211_M_IBSS || - vap->iv_opmode == IEEE80211_M_MBSS) - ieee80211_beacon_notify(vap, IEEE80211_BEACON_CSA); - /* switch to CSA state to block outbound traffic */ - if (vap->iv_state == IEEE80211_S_RUN) - ieee80211_new_state_locked(vap, IEEE80211_S_CSA, 0); - } - ieee80211_notify_csa(ic, c, mode, count); -} - -/* - * Complete the channel switch by transitioning all CSA VAPs to RUN. - * This is called by both the completion and cancellation functions - * so each VAP is placed back in the RUN state and can thus transmit. - */ -static void -csa_completeswitch(struct ieee80211com *ic) -{ - struct ieee80211vap *vap; - - ic->ic_csa_newchan = NULL; - ic->ic_flags &= ~IEEE80211_F_CSAPENDING; - - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if (vap->iv_state == IEEE80211_S_CSA) - ieee80211_new_state_locked(vap, IEEE80211_S_RUN, 0); -} - -/* - * Complete an 802.11h channel switch started by ieee80211_csa_startswitch. - * We clear state and move all vap's in CSA state to RUN state - * so they can again transmit. - * - * Although this may not be completely correct, update the BSS channel - * for each VAP to the newly configured channel. The setcurchan sets - * the current operating channel for the interface (so the radio does - * switch over) but the VAP BSS isn't updated, leading to incorrectly - * reported information via ioctl. - */ -void -ieee80211_csa_completeswitch(struct ieee80211com *ic) -{ - struct ieee80211vap *vap; - - IEEE80211_LOCK_ASSERT(ic); - - KASSERT(ic->ic_flags & IEEE80211_F_CSAPENDING, ("csa not pending")); - - ieee80211_setcurchan(ic, ic->ic_csa_newchan); - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if (vap->iv_state == IEEE80211_S_CSA) - vap->iv_bss->ni_chan = ic->ic_curchan; - - csa_completeswitch(ic); -} - -/* - * Cancel an 802.11h channel switch started by ieee80211_csa_startswitch. - * We clear state and move all vap's in CSA state to RUN state - * so they can again transmit. - */ -void -ieee80211_csa_cancelswitch(struct ieee80211com *ic) -{ - IEEE80211_LOCK_ASSERT(ic); - - csa_completeswitch(ic); -} - -/* - * Complete a DFS CAC started by ieee80211_dfs_cac_start. - * We clear state and move all vap's in CAC state to RUN state. - */ -void -ieee80211_cac_completeswitch(struct ieee80211vap *vap0) -{ - struct ieee80211com *ic = vap0->iv_ic; - struct ieee80211vap *vap; - - IEEE80211_LOCK(ic); - /* - * Complete CAC state change for lead vap first; then - * clock all the other vap's waiting. - */ - KASSERT(vap0->iv_state == IEEE80211_S_CAC, - ("wrong state %d", vap0->iv_state)); - ieee80211_new_state_locked(vap0, IEEE80211_S_RUN, 0); - - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if (vap->iv_state == IEEE80211_S_CAC) - ieee80211_new_state_locked(vap, IEEE80211_S_RUN, 0); - IEEE80211_UNLOCK(ic); -} - -/* - * Force all vap's other than the specified vap to the INIT state - * and mark them as waiting for a scan to complete. These vaps - * will be brought up when the scan completes and the scanning vap - * reaches RUN state by wakeupwaiting. - */ -static void -markwaiting(struct ieee80211vap *vap0) -{ - struct ieee80211com *ic = vap0->iv_ic; - struct ieee80211vap *vap; - - IEEE80211_LOCK_ASSERT(ic); - - /* - * A vap list entry can not disappear since we are running on the - * taskqueue and a vap destroy will queue and drain another state - * change task. - */ - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - if (vap == vap0) - continue; - if (vap->iv_state != IEEE80211_S_INIT) { - /* NB: iv_newstate may drop the lock */ - vap->iv_newstate(vap, IEEE80211_S_INIT, 0); - vap->iv_flags_ext |= IEEE80211_FEXT_SCANWAIT; - } - } -} - -/* - * Wakeup all vap's waiting for a scan to complete. This is the - * companion to markwaiting (above) and is used to coordinate - * multiple vaps scanning. - * This is called from the state taskqueue. - */ -static void -wakeupwaiting(struct ieee80211vap *vap0) -{ - struct ieee80211com *ic = vap0->iv_ic; - struct ieee80211vap *vap; - - IEEE80211_LOCK_ASSERT(ic); - - /* - * A vap list entry can not disappear since we are running on the - * taskqueue and a vap destroy will queue and drain another state - * change task. - */ - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - if (vap == vap0) - continue; - if (vap->iv_flags_ext & IEEE80211_FEXT_SCANWAIT) { - vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANWAIT; - /* NB: sta's cannot go INIT->RUN */ - /* NB: iv_newstate may drop the lock */ - vap->iv_newstate(vap, - vap->iv_opmode == IEEE80211_M_STA ? - IEEE80211_S_SCAN : IEEE80211_S_RUN, 0); - } - } -} - -/* - * Handle post state change work common to all operating modes. - */ -static void -ieee80211_newstate_cb(void *xvap, int npending) -{ - struct ieee80211vap *vap = xvap; - struct ieee80211com *ic = vap->iv_ic; - enum ieee80211_state nstate, ostate; - int arg, rc; - - IEEE80211_LOCK(ic); - nstate = vap->iv_nstate; - arg = vap->iv_nstate_arg; - - if (vap->iv_flags_ext & IEEE80211_FEXT_REINIT) { - /* - * We have been requested to drop back to the INIT before - * proceeding to the new state. - */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, - "%s: %s -> %s arg %d\n", __func__, - ieee80211_state_name[vap->iv_state], - ieee80211_state_name[IEEE80211_S_INIT], arg); - vap->iv_newstate(vap, IEEE80211_S_INIT, arg); - vap->iv_flags_ext &= ~IEEE80211_FEXT_REINIT; - } - - ostate = vap->iv_state; - if (nstate == IEEE80211_S_SCAN && ostate != IEEE80211_S_INIT) { - /* - * SCAN was forced; e.g. on beacon miss. Force other running - * vap's to INIT state and mark them as waiting for the scan to - * complete. This insures they don't interfere with our - * scanning. Since we are single threaded the vaps can not - * transition again while we are executing. - * - * XXX not always right, assumes ap follows sta - */ - markwaiting(vap); - } - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, - "%s: %s -> %s arg %d\n", __func__, - ieee80211_state_name[ostate], ieee80211_state_name[nstate], arg); - - rc = vap->iv_newstate(vap, nstate, arg); - vap->iv_flags_ext &= ~IEEE80211_FEXT_STATEWAIT; - if (rc != 0) { - /* State transition failed */ - KASSERT(rc != EINPROGRESS, ("iv_newstate was deferred")); - KASSERT(nstate != IEEE80211_S_INIT, - ("INIT state change failed")); - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, - "%s: %s returned error %d\n", __func__, - ieee80211_state_name[nstate], rc); - goto done; - } - - /* No actual transition, skip post processing */ - if (ostate == nstate) - goto done; - - if (nstate == IEEE80211_S_RUN) { - /* - * OACTIVE may be set on the vap if the upper layer - * tried to transmit (e.g. IPv6 NDP) before we reach - * RUN state. Clear it and restart xmit. - * - * Note this can also happen as a result of SLEEP->RUN - * (i.e. coming out of power save mode). - */ - vap->iv_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - if_start(vap->iv_ifp); - - /* bring up any vaps waiting on us */ - wakeupwaiting(vap); - } else if (nstate == IEEE80211_S_INIT) { - /* - * Flush the scan cache if we did the last scan (XXX?) - * and flush any frames on send queues from this vap. - * Note the mgt q is used only for legacy drivers and - * will go away shortly. - */ - ieee80211_scan_flush(vap); - - /* XXX NB: cast for altq */ - ieee80211_flush_ifq((struct ifqueue *)&ic->ic_ifp->if_snd, vap); - } -done: - IEEE80211_UNLOCK(ic); -} - -/* - * Public interface for initiating a state machine change. - * This routine single-threads the request and coordinates - * the scheduling of multiple vaps for the purpose of selecting - * an operating channel. Specifically the following scenarios - * are handled: - * o only one vap can be selecting a channel so on transition to - * SCAN state if another vap is already scanning then - * mark the caller for later processing and return without - * doing anything (XXX? expectations by caller of synchronous operation) - * o only one vap can be doing CAC of a channel so on transition to - * CAC state if another vap is already scanning for radar then - * mark the caller for later processing and return without - * doing anything (XXX? expectations by caller of synchronous operation) - * o if another vap is already running when a request is made - * to SCAN then an operating channel has been chosen; bypass - * the scan and just join the channel - * - * Note that the state change call is done through the iv_newstate - * method pointer so any driver routine gets invoked. The driver - * will normally call back into operating mode-specific - * ieee80211_newstate routines (below) unless it needs to completely - * bypass the state machine (e.g. because the firmware has it's - * own idea how things should work). Bypassing the net80211 layer - * is usually a mistake and indicates lack of proper integration - * with the net80211 layer. - */ -static int -ieee80211_new_state_locked(struct ieee80211vap *vap, - enum ieee80211_state nstate, int arg) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211vap *vp; - enum ieee80211_state ostate; - int nrunning, nscanning; - - IEEE80211_LOCK_ASSERT(ic); - - if (vap->iv_flags_ext & IEEE80211_FEXT_STATEWAIT) { - if (vap->iv_nstate == IEEE80211_S_INIT) { - /* - * XXX The vap is being stopped, do no allow any other - * state changes until this is completed. - */ - return -1; - } else if (vap->iv_state != vap->iv_nstate) { -#if 0 - /* Warn if the previous state hasn't completed. */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, - "%s: pending %s -> %s transition lost\n", __func__, - ieee80211_state_name[vap->iv_state], - ieee80211_state_name[vap->iv_nstate]); -#else - /* XXX temporarily enable to identify issues */ - if_printf(vap->iv_ifp, - "%s: pending %s -> %s transition lost\n", - __func__, ieee80211_state_name[vap->iv_state], - ieee80211_state_name[vap->iv_nstate]); -#endif - } - } - - nrunning = nscanning = 0; - /* XXX can track this state instead of calculating */ - TAILQ_FOREACH(vp, &ic->ic_vaps, iv_next) { - if (vp != vap) { - if (vp->iv_state >= IEEE80211_S_RUN) - nrunning++; - /* XXX doesn't handle bg scan */ - /* NB: CAC+AUTH+ASSOC treated like SCAN */ - else if (vp->iv_state > IEEE80211_S_INIT) - nscanning++; - } - } - ostate = vap->iv_state; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, - "%s: %s -> %s (nrunning %d nscanning %d)\n", __func__, - ieee80211_state_name[ostate], ieee80211_state_name[nstate], - nrunning, nscanning); - switch (nstate) { - case IEEE80211_S_SCAN: - if (ostate == IEEE80211_S_INIT) { - /* - * INIT -> SCAN happens on initial bringup. - */ - KASSERT(!(nscanning && nrunning), - ("%d scanning and %d running", nscanning, nrunning)); - if (nscanning) { - /* - * Someone is scanning, defer our state - * change until the work has completed. - */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, - "%s: defer %s -> %s\n", - __func__, ieee80211_state_name[ostate], - ieee80211_state_name[nstate]); - vap->iv_flags_ext |= IEEE80211_FEXT_SCANWAIT; - return 0; - } - if (nrunning) { - /* - * Someone is operating; just join the channel - * they have chosen. - */ - /* XXX kill arg? */ - /* XXX check each opmode, adhoc? */ - if (vap->iv_opmode == IEEE80211_M_STA) - nstate = IEEE80211_S_SCAN; - else - nstate = IEEE80211_S_RUN; -#ifdef IEEE80211_DEBUG - if (nstate != IEEE80211_S_SCAN) { - IEEE80211_DPRINTF(vap, - IEEE80211_MSG_STATE, - "%s: override, now %s -> %s\n", - __func__, - ieee80211_state_name[ostate], - ieee80211_state_name[nstate]); - } -#endif - } - } - break; - case IEEE80211_S_RUN: - if (vap->iv_opmode == IEEE80211_M_WDS && - (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY) && - nscanning) { - /* - * Legacy WDS with someone else scanning; don't - * go online until that completes as we should - * follow the other vap to the channel they choose. - */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, - "%s: defer %s -> %s (legacy WDS)\n", __func__, - ieee80211_state_name[ostate], - ieee80211_state_name[nstate]); - vap->iv_flags_ext |= IEEE80211_FEXT_SCANWAIT; - return 0; - } - if (vap->iv_opmode == IEEE80211_M_HOSTAP && - IEEE80211_IS_CHAN_DFS(ic->ic_bsschan) && - (vap->iv_flags_ext & IEEE80211_FEXT_DFS) && - !IEEE80211_IS_CHAN_CACDONE(ic->ic_bsschan)) { - /* - * This is a DFS channel, transition to CAC state - * instead of RUN. This allows us to initiate - * Channel Availability Check (CAC) as specified - * by 11h/DFS. - */ - nstate = IEEE80211_S_CAC; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, - "%s: override %s -> %s (DFS)\n", __func__, - ieee80211_state_name[ostate], - ieee80211_state_name[nstate]); - } - break; - case IEEE80211_S_INIT: - /* cancel any scan in progress */ - ieee80211_cancel_scan(vap); - if (ostate == IEEE80211_S_INIT ) { - /* XXX don't believe this */ - /* INIT -> INIT. nothing to do */ - vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANWAIT; - } - /* fall thru... */ - default: - break; - } - /* defer the state change to a thread */ - vap->iv_nstate = nstate; - vap->iv_nstate_arg = arg; - vap->iv_flags_ext |= IEEE80211_FEXT_STATEWAIT; - ieee80211_runtask(ic, &vap->iv_nstate_task); - return EINPROGRESS; -} - -int -ieee80211_new_state(struct ieee80211vap *vap, - enum ieee80211_state nstate, int arg) -{ - struct ieee80211com *ic = vap->iv_ic; - int rc; - - IEEE80211_LOCK(ic); - rc = ieee80211_new_state_locked(vap, nstate, arg); - IEEE80211_UNLOCK(ic); - return rc; -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_proto.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_proto.h deleted file mode 100644 index 2b325576ef..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_proto.h +++ /dev/null @@ -1,416 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_PROTO_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_PROTO_H_ - -/* - * 802.11 protocol implementation definitions. - */ - -void ieee80211_auth_setup(void); - -enum ieee80211_state { - IEEE80211_S_INIT = 0, /* default state */ - IEEE80211_S_SCAN = 1, /* scanning */ - IEEE80211_S_AUTH = 2, /* try to authenticate */ - IEEE80211_S_ASSOC = 3, /* try to assoc */ - IEEE80211_S_CAC = 4, /* doing channel availability check */ - IEEE80211_S_RUN = 5, /* operational (e.g. associated) */ - IEEE80211_S_CSA = 6, /* channel switch announce pending */ - IEEE80211_S_SLEEP = 7, /* power save */ -}; -#define IEEE80211_S_MAX (IEEE80211_S_SLEEP+1) - -#define IEEE80211_SEND_MGMT(_ni,_type,_arg) \ - ((*(_ni)->ni_ic->ic_send_mgmt)(_ni, _type, _arg)) - -extern const char *ieee80211_mgt_subtype_name[]; -extern const char *ieee80211_phymode_name[IEEE80211_MODE_MAX]; -extern const int ieee80211_opcap[IEEE80211_OPMODE_MAX]; - -void ieee80211_proto_attach(struct ieee80211com *); -void ieee80211_proto_detach(struct ieee80211com *); -void ieee80211_proto_vattach(struct ieee80211vap *); -void ieee80211_proto_vdetach(struct ieee80211vap *); - -void ieee80211_syncifflag_locked(struct ieee80211com *, int flag); -void ieee80211_syncflag(struct ieee80211vap *, int flag); -void ieee80211_syncflag_ht(struct ieee80211vap *, int flag); -void ieee80211_syncflag_ext(struct ieee80211vap *, int flag); - -#define IEEE80211_R_NF 0x0000001 /* global NF value valid */ -#define IEEE80211_R_RSSI 0x0000002 /* global RSSI value valid */ -#define IEEE80211_R_C_CHAIN 0x0000004 /* RX chain count valid */ -#define IEEE80211_R_C_NF 0x0000008 /* per-chain NF value valid */ -#define IEEE80211_R_C_RSSI 0x0000010 /* per-chain RSSI value valid */ -#define IEEE80211_R_C_EVM 0x0000020 /* per-chain EVM valid */ -#define IEEE80211_R_C_HT40 0x0000040 /* RX'ed packet is 40mhz, pilots 4,5 valid */ - -struct ieee80211_rx_stats { - uint32_t r_flags; /* IEEE80211_R_* flags */ - uint8_t c_chain; /* number of RX chains involved */ - int16_t c_nf_ctl[IEEE80211_MAX_CHAINS]; /* per-chain NF */ - int16_t c_nf_ext[IEEE80211_MAX_CHAINS]; /* per-chain NF */ - int16_t c_rssi_ctl[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */ - int16_t c_rssi_ext[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */ - uint8_t nf; /* global NF */ - uint8_t rssi; /* global RSSI */ - uint8_t evm[IEEE80211_MAX_CHAINS][IEEE80211_MAX_EVM_PILOTS]; - /* per-chain, per-pilot EVM values */ -}; - -#define ieee80211_input(ni, m, rssi, nf) \ - ((ni)->ni_vap->iv_input(ni, m, rssi, nf)) -int ieee80211_input_all(struct ieee80211com *, struct mbuf *, int, int); - -int ieee80211_input_mimo(struct ieee80211_node *, struct mbuf *, - struct ieee80211_rx_stats *); -int ieee80211_input_mimo_all(struct ieee80211com *, struct mbuf *, - struct ieee80211_rx_stats *); - -struct ieee80211_bpf_params; -int ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int, - struct ieee80211_bpf_params *); -int ieee80211_raw_xmit(struct ieee80211_node *, struct mbuf *, - const struct ieee80211_bpf_params *); -int ieee80211_output(struct ifnet *, struct mbuf *, - struct sockaddr *, struct route *ro); -void ieee80211_send_setup(struct ieee80211_node *, struct mbuf *, int, int, - const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN], - const uint8_t [IEEE80211_ADDR_LEN]); -void ieee80211_start(struct ifnet *); -int ieee80211_send_nulldata(struct ieee80211_node *); -int ieee80211_classify(struct ieee80211_node *, struct mbuf *m); -struct mbuf *ieee80211_mbuf_adjust(struct ieee80211vap *, int, - struct ieee80211_key *, struct mbuf *); -struct mbuf *ieee80211_encap(struct ieee80211vap *, struct ieee80211_node *, - struct mbuf *); -int ieee80211_send_mgmt(struct ieee80211_node *, int, int); -struct ieee80211_appie; -int ieee80211_send_probereq(struct ieee80211_node *ni, - const uint8_t sa[IEEE80211_ADDR_LEN], - const uint8_t da[IEEE80211_ADDR_LEN], - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t *ssid, size_t ssidlen); -/* - * The formation of ProbeResponse frames requires guidance to - * deal with legacy clients. When the client is identified as - * "legacy 11b" ieee80211_send_proberesp is passed this token. - */ -#define IEEE80211_SEND_LEGACY_11B 0x1 /* legacy 11b client */ -#define IEEE80211_SEND_LEGACY_11 0x2 /* other legacy client */ -#define IEEE80211_SEND_LEGACY 0x3 /* any legacy client */ -struct mbuf *ieee80211_alloc_proberesp(struct ieee80211_node *, int); -int ieee80211_send_proberesp(struct ieee80211vap *, - const uint8_t da[IEEE80211_ADDR_LEN], int); -struct mbuf *ieee80211_alloc_rts(struct ieee80211com *ic, - const uint8_t [IEEE80211_ADDR_LEN], - const uint8_t [IEEE80211_ADDR_LEN], uint16_t); -struct mbuf *ieee80211_alloc_cts(struct ieee80211com *, - const uint8_t [IEEE80211_ADDR_LEN], uint16_t); - -uint8_t *ieee80211_add_rates(uint8_t *, const struct ieee80211_rateset *); -uint8_t *ieee80211_add_xrates(uint8_t *, const struct ieee80211_rateset *); -uint16_t ieee80211_getcapinfo(struct ieee80211vap *, - struct ieee80211_channel *); - -void ieee80211_reset_erp(struct ieee80211com *); -void ieee80211_set_shortslottime(struct ieee80211com *, int onoff); -int ieee80211_iserp_rateset(const struct ieee80211_rateset *); -void ieee80211_setbasicrates(struct ieee80211_rateset *, - enum ieee80211_phymode); -void ieee80211_addbasicrates(struct ieee80211_rateset *, - enum ieee80211_phymode); - -/* - * Return the size of the 802.11 header for a management or data frame. - */ -static __inline int -ieee80211_hdrsize(const void *data) -{ - const struct ieee80211_frame *wh = (const struct ieee80211_frame *)data; - int size = sizeof(struct ieee80211_frame); - - /* NB: we don't handle control frames */ - KASSERT((wh->i_fc[0]&IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL, - ("%s: control frame", __func__)); - if (IEEE80211_IS_DSTODS(wh)) - size += IEEE80211_ADDR_LEN; - if (IEEE80211_QOS_HAS_SEQ(wh)) - size += sizeof(uint16_t); - return size; -} - -/* - * Like ieee80211_hdrsize, but handles any type of frame. - */ -static __inline int -ieee80211_anyhdrsize(const void *data) -{ - const struct ieee80211_frame *wh = (const struct ieee80211_frame *)data; - - if ((wh->i_fc[0]&IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) { - switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) { - case IEEE80211_FC0_SUBTYPE_CTS: - case IEEE80211_FC0_SUBTYPE_ACK: - return sizeof(struct ieee80211_frame_ack); - case IEEE80211_FC0_SUBTYPE_BAR: - return sizeof(struct ieee80211_frame_bar); - } - return sizeof(struct ieee80211_frame_min); - } else - return ieee80211_hdrsize(data); -} - -/* - * Template for an in-kernel authenticator. Authenticators - * register with the protocol code and are typically loaded - * as separate modules as needed. One special authenticator - * is xauth; it intercepts requests so that protocols like - * WPA can be handled in user space. - */ -struct ieee80211_authenticator { - const char *ia_name; /* printable name */ - int (*ia_attach)(struct ieee80211vap *); - void (*ia_detach)(struct ieee80211vap *); - void (*ia_node_join)(struct ieee80211_node *); - void (*ia_node_leave)(struct ieee80211_node *); -}; -void ieee80211_authenticator_register(int type, - const struct ieee80211_authenticator *); -void ieee80211_authenticator_unregister(int type); -const struct ieee80211_authenticator *ieee80211_authenticator_get(int auth); - -struct ieee80211req; -/* - * Template for an MAC ACL policy module. Such modules - * register with the protocol code and are passed the sender's - * address of each received auth frame for validation. - */ -struct ieee80211_aclator { - const char *iac_name; /* printable name */ - int (*iac_attach)(struct ieee80211vap *); - void (*iac_detach)(struct ieee80211vap *); - int (*iac_check)(struct ieee80211vap *, - const uint8_t mac[IEEE80211_ADDR_LEN]); - int (*iac_add)(struct ieee80211vap *, - const uint8_t mac[IEEE80211_ADDR_LEN]); - int (*iac_remove)(struct ieee80211vap *, - const uint8_t mac[IEEE80211_ADDR_LEN]); - int (*iac_flush)(struct ieee80211vap *); - int (*iac_setpolicy)(struct ieee80211vap *, int); - int (*iac_getpolicy)(struct ieee80211vap *); - int (*iac_setioctl)(struct ieee80211vap *, struct ieee80211req *); - int (*iac_getioctl)(struct ieee80211vap *, struct ieee80211req *); -}; -void ieee80211_aclator_register(const struct ieee80211_aclator *); -void ieee80211_aclator_unregister(const struct ieee80211_aclator *); -const struct ieee80211_aclator *ieee80211_aclator_get(const char *name); - -/* flags for ieee80211_fix_rate() */ -#define IEEE80211_F_DOSORT 0x00000001 /* sort rate list */ -#define IEEE80211_F_DOFRATE 0x00000002 /* use fixed legacy rate */ -#define IEEE80211_F_DONEGO 0x00000004 /* calc negotiated rate */ -#define IEEE80211_F_DODEL 0x00000008 /* delete ignore rate */ -#define IEEE80211_F_DOBRS 0x00000010 /* check basic rate set */ -#define IEEE80211_F_JOIN 0x00000020 /* sta joining our bss */ -#define IEEE80211_F_DOFMCS 0x00000040 /* use fixed HT rate */ -int ieee80211_fix_rate(struct ieee80211_node *, - struct ieee80211_rateset *, int); - -/* - * WME/WMM support. - */ -struct wmeParams { - uint8_t wmep_acm; - uint8_t wmep_aifsn; - uint8_t wmep_logcwmin; /* log2(cwmin) */ - uint8_t wmep_logcwmax; /* log2(cwmax) */ - uint8_t wmep_txopLimit; - uint8_t wmep_noackPolicy; /* 0 (ack), 1 (no ack) */ -}; -#define IEEE80211_TXOP_TO_US(_txop) ((_txop)<<5) -#define IEEE80211_US_TO_TXOP(_us) ((_us)>>5) - -struct chanAccParams { - uint8_t cap_info; /* version of the current set */ - struct wmeParams cap_wmeParams[WME_NUM_AC]; -}; - -struct ieee80211_wme_state { - u_int wme_flags; -#define WME_F_AGGRMODE 0x00000001 /* STATUS: WME agressive mode */ - u_int wme_hipri_traffic; /* VI/VO frames in beacon interval */ - u_int wme_hipri_switch_thresh;/* agressive mode switch thresh */ - u_int wme_hipri_switch_hysteresis;/* agressive mode switch hysteresis */ - - struct wmeParams wme_params[4]; /* from assoc resp for each AC*/ - struct chanAccParams wme_wmeChanParams; /* WME params applied to self */ - struct chanAccParams wme_wmeBssChanParams;/* WME params bcast to stations */ - struct chanAccParams wme_chanParams; /* params applied to self */ - struct chanAccParams wme_bssChanParams; /* params bcast to stations */ - - int (*wme_update)(struct ieee80211com *); -}; - -void ieee80211_wme_initparams(struct ieee80211vap *); -void ieee80211_wme_updateparams(struct ieee80211vap *); -void ieee80211_wme_updateparams_locked(struct ieee80211vap *); - -/* - * Return the WME TID from a QoS frame. If no TID - * is present return the index for the "non-QoS" entry. - */ -static __inline uint8_t -ieee80211_gettid(const struct ieee80211_frame *wh) -{ - uint8_t tid; - - if (IEEE80211_QOS_HAS_SEQ(wh)) { - if (IEEE80211_IS_DSTODS(wh)) - tid = ((const struct ieee80211_qosframe_addr4 *)wh)-> - i_qos[0]; - else - tid = ((const struct ieee80211_qosframe *)wh)->i_qos[0]; - tid &= IEEE80211_QOS_TID; - } else - tid = IEEE80211_NONQOS_TID; - return tid; -} - -void ieee80211_waitfor_parent(struct ieee80211com *); -void ieee80211_start_locked(struct ieee80211vap *); -void ieee80211_init(void *); -void ieee80211_start_all(struct ieee80211com *); -void ieee80211_stop_locked(struct ieee80211vap *); -void ieee80211_stop(struct ieee80211vap *); -void ieee80211_stop_all(struct ieee80211com *); -void ieee80211_suspend_all(struct ieee80211com *); -void ieee80211_resume_all(struct ieee80211com *); -void ieee80211_dturbo_switch(struct ieee80211vap *, int newflags); -void ieee80211_swbmiss(void *arg); -void ieee80211_beacon_miss(struct ieee80211com *); -int ieee80211_new_state(struct ieee80211vap *, enum ieee80211_state, int); -void ieee80211_print_essid(const uint8_t *, int); -void ieee80211_dump_pkt(struct ieee80211com *, - const uint8_t *, int, int, int); - -extern const char *ieee80211_opmode_name[]; -extern const char *ieee80211_state_name[IEEE80211_S_MAX]; -extern const char *ieee80211_wme_acnames[]; - -/* - * Beacon frames constructed by ieee80211_beacon_alloc - * have the following structure filled in so drivers - * can update the frame later w/ minimal overhead. - */ -struct ieee80211_beacon_offsets { - uint8_t bo_flags[4]; /* update/state flags */ - uint16_t *bo_caps; /* capabilities */ - uint8_t *bo_cfp; /* start of CFParms element */ - uint8_t *bo_tim; /* start of atim/dtim */ - uint8_t *bo_wme; /* start of WME parameters */ - uint8_t *bo_tdma; /* start of TDMA parameters */ - uint8_t *bo_tim_trailer;/* start of fixed-size trailer */ - uint16_t bo_tim_len; /* atim/dtim length in bytes */ - uint16_t bo_tim_trailer_len;/* tim trailer length in bytes */ - uint8_t *bo_erp; /* start of ERP element */ - uint8_t *bo_htinfo; /* start of HT info element */ - uint8_t *bo_ath; /* start of ATH parameters */ - uint8_t *bo_appie; /* start of AppIE element */ - uint16_t bo_appie_len; /* AppIE length in bytes */ - uint16_t bo_csa_trailer_len; - uint8_t *bo_csa; /* start of CSA element */ - uint8_t *bo_meshconf; /* start of MESHCONF element */ - uint8_t *bo_spare[3]; -}; -struct mbuf *ieee80211_beacon_alloc(struct ieee80211_node *, - struct ieee80211_beacon_offsets *); - -/* - * Beacon frame updates are signaled through calls to iv_update_beacon - * with one of the IEEE80211_BEACON_* tokens defined below. For devices - * that construct beacon frames on the host this can trigger a rebuild - * or defer the processing. For devices that offload beacon frame - * handling this callback can be used to signal a rebuild. The bo_flags - * array in the ieee80211_beacon_offsets structure is intended to record - * deferred processing requirements; ieee80211_beacon_update uses the - * state to optimize work. Since this structure is owned by the driver - * and not visible to the 802.11 layer drivers must supply an iv_update_beacon - * callback that marks the flag bits and schedules (as necessary) an update. - */ -enum { - IEEE80211_BEACON_CAPS = 0, /* capabilities */ - IEEE80211_BEACON_TIM = 1, /* DTIM/ATIM */ - IEEE80211_BEACON_WME = 2, - IEEE80211_BEACON_ERP = 3, /* Extended Rate Phy */ - IEEE80211_BEACON_HTINFO = 4, /* HT Information */ - IEEE80211_BEACON_APPIE = 5, /* Application IE's */ - IEEE80211_BEACON_CFP = 6, /* CFParms */ - IEEE80211_BEACON_CSA = 7, /* Channel Switch Announcement */ - IEEE80211_BEACON_TDMA = 9, /* TDMA Info */ - IEEE80211_BEACON_ATH = 10, /* ATH parameters */ - IEEE80211_BEACON_MESHCONF = 11, /* Mesh Configuration */ -}; -int ieee80211_beacon_update(struct ieee80211_node *, - struct ieee80211_beacon_offsets *, struct mbuf *, int mcast); - -void ieee80211_csa_startswitch(struct ieee80211com *, - struct ieee80211_channel *, int mode, int count); -void ieee80211_csa_completeswitch(struct ieee80211com *); -void ieee80211_csa_cancelswitch(struct ieee80211com *); -void ieee80211_cac_completeswitch(struct ieee80211vap *); - -/* - * Notification methods called from the 802.11 state machine. - * Note that while these are defined here, their implementation - * is OS-specific. - */ -void ieee80211_notify_node_join(struct ieee80211_node *, int newassoc); -void ieee80211_notify_node_leave(struct ieee80211_node *); -void ieee80211_notify_scan_done(struct ieee80211vap *); -void ieee80211_notify_wds_discover(struct ieee80211_node *); -void ieee80211_notify_csa(struct ieee80211com *, - const struct ieee80211_channel *, int mode, int count); -void ieee80211_notify_radar(struct ieee80211com *, - const struct ieee80211_channel *); -enum ieee80211_notify_cac_event { - IEEE80211_NOTIFY_CAC_START = 0, /* CAC timer started */ - IEEE80211_NOTIFY_CAC_STOP = 1, /* CAC intentionally stopped */ - IEEE80211_NOTIFY_CAC_RADAR = 2, /* CAC stopped due to radar detectio */ - IEEE80211_NOTIFY_CAC_EXPIRE = 3, /* CAC expired w/o radar */ -}; -void ieee80211_notify_cac(struct ieee80211com *, - const struct ieee80211_channel *, - enum ieee80211_notify_cac_event); -void ieee80211_notify_node_deauth(struct ieee80211_node *); -void ieee80211_notify_node_auth(struct ieee80211_node *); -void ieee80211_notify_country(struct ieee80211vap *, const uint8_t [], - const uint8_t cc[2]); -void ieee80211_notify_radio(struct ieee80211com *, int); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_PROTO_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_radiotap.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_radiotap.c deleted file mode 100644 index fc3dbdc312..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_radiotap.c +++ /dev/null @@ -1,355 +0,0 @@ -/*- - * Copyright (c) 2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 radiotap support. - */ -#include "opt_wlan.h" - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include - -static int radiotap_offset(struct ieee80211_radiotap_header *, int); - -void -ieee80211_radiotap_attach(struct ieee80211com *ic, - struct ieee80211_radiotap_header *th, int tlen, uint32_t tx_radiotap, - struct ieee80211_radiotap_header *rh, int rlen, uint32_t rx_radiotap) -{ -#define B(_v) (1<<(_v)) - int off; - - th->it_len = htole16(roundup2(tlen, sizeof(uint32_t))); - th->it_present = htole32(tx_radiotap); - ic->ic_th = th; - /* calculate offset to channel data */ - off = -1; - if (tx_radiotap & B(IEEE80211_RADIOTAP_CHANNEL)) - off = radiotap_offset(th, IEEE80211_RADIOTAP_CHANNEL); - else if (tx_radiotap & B(IEEE80211_RADIOTAP_XCHANNEL)) - off = radiotap_offset(th, IEEE80211_RADIOTAP_XCHANNEL); - if (off == -1) { - if_printf(ic->ic_ifp, "%s: no tx channel, radiotap 0x%x", - __func__, tx_radiotap); - /* NB: we handle this case but data will have no chan spec */ - } else - ic->ic_txchan = ((uint8_t *) th) + off; - - rh->it_len = htole16(roundup2(rlen, sizeof(uint32_t))); - rh->it_present = htole32(rx_radiotap); - ic->ic_rh = rh; - /* calculate offset to channel data */ - off = -1; - if (rx_radiotap & B(IEEE80211_RADIOTAP_CHANNEL)) - off = radiotap_offset(rh, IEEE80211_RADIOTAP_CHANNEL); - else if (rx_radiotap & B(IEEE80211_RADIOTAP_XCHANNEL)) - off = radiotap_offset(rh, IEEE80211_RADIOTAP_XCHANNEL); - if (off == -1) { - if_printf(ic->ic_ifp, "%s: no rx channel, radiotap 0x%x", - __func__, rx_radiotap); - /* NB: we handle this case but data will have no chan spec */ - } else - ic->ic_rxchan = ((uint8_t *) rh) + off; -#undef B -} - -void -ieee80211_radiotap_detach(struct ieee80211com *ic) -{ -} - -void -ieee80211_radiotap_vattach(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_radiotap_header *th = ic->ic_th; - - if (th != NULL && ic->ic_rh != NULL) { - /* radiotap DLT for raw 802.11 frames */ - bpfattach2(vap->iv_ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + le16toh(th->it_len), - &vap->iv_rawbpf); - } -} - -void -ieee80211_radiotap_vdetach(struct ieee80211vap *vap) -{ - /* NB: bpfattach is called by ether_ifdetach and claims all taps */ -} - -static void -set_channel(void *p, const struct ieee80211_channel *c) -{ - struct { - uint16_t freq; - uint16_t flags; - } *rc = p; - - rc->freq = htole16(c->ic_freq); - rc->flags = htole16(c->ic_flags); -} - -static void -set_xchannel(void *p, const struct ieee80211_channel *c) -{ - struct { - uint32_t flags; - uint16_t freq; - uint8_t ieee; - uint8_t maxpow; - } *rc = p; - - rc->flags = htole32(c->ic_flags); - rc->freq = htole16(c->ic_freq); - rc->ieee = c->ic_ieee; - rc->maxpow = c->ic_maxregpower; -} - -/* - * Update radiotap state on channel change. - */ -void -ieee80211_radiotap_chan_change(struct ieee80211com *ic) -{ - if (ic->ic_rxchan != NULL) { - struct ieee80211_radiotap_header *rh = ic->ic_rh; - - if (rh->it_present & htole32(1<ic_rxchan, ic->ic_curchan); - else if (rh->it_present & htole32(1<ic_rxchan, ic->ic_curchan); - } - if (ic->ic_txchan != NULL) { - struct ieee80211_radiotap_header *th = ic->ic_th; - - if (th->it_present & htole32(1<ic_txchan, ic->ic_curchan); - else if (th->it_present & htole32(1<ic_txchan, ic->ic_curchan); - } -} - -/* - * Distribute radiotap data (+packet) to all monitor mode - * vaps with an active tap other than vap0. - */ -static void -spam_vaps(struct ieee80211vap *vap0, struct mbuf *m, - struct ieee80211_radiotap_header *rh, int len) -{ - struct ieee80211com *ic = vap0->iv_ic; - struct ieee80211vap *vap; - - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - if (vap != vap0 && - vap->iv_opmode == IEEE80211_M_MONITOR && - (vap->iv_flags_ext & IEEE80211_FEXT_BPF) && - vap->iv_state != IEEE80211_S_INIT) - bpf_mtap2(vap->iv_rawbpf, rh, len, m); - } -} - -/* - * Dispatch radiotap data for transmitted packet. - */ -void -ieee80211_radiotap_tx(struct ieee80211vap *vap0, struct mbuf *m) -{ - struct ieee80211com *ic = vap0->iv_ic; - struct ieee80211_radiotap_header *th = ic->ic_th; - int len; - - KASSERT(th != NULL, ("no tx radiotap header")); - len = le16toh(th->it_len); - - if (vap0->iv_flags_ext & IEEE80211_FEXT_BPF) - bpf_mtap2(vap0->iv_rawbpf, th, len, m); - /* - * Spam monitor mode vaps. - */ - if (ic->ic_montaps != 0) - spam_vaps(vap0, m, th, len); -} - -/* - * Dispatch radiotap data for received packet. - */ -void -ieee80211_radiotap_rx(struct ieee80211vap *vap0, struct mbuf *m) -{ - struct ieee80211com *ic = vap0->iv_ic; - struct ieee80211_radiotap_header *rh = ic->ic_rh; - int len; - - KASSERT(rh != NULL, ("no rx radiotap header")); - len = le16toh(rh->it_len); - - if (vap0->iv_flags_ext & IEEE80211_FEXT_BPF) - bpf_mtap2(vap0->iv_rawbpf, rh, len, m); - /* - * Spam monitor mode vaps with unicast frames. Multicast - * frames are handled by passing through ieee80211_input_all - * which distributes copies to the monitor mode vaps. - */ - if (ic->ic_montaps != 0 && (m->m_flags & M_BCAST) == 0) - spam_vaps(vap0, m, rh, len); -} - -/* - * Dispatch radiotap data for a packet received outside the normal - * rx processing path; this is used, for example, to handle frames - * received with errors that would otherwise be dropped. - */ -void -ieee80211_radiotap_rx_all(struct ieee80211com *ic, struct mbuf *m) -{ - struct ieee80211_radiotap_header *rh = ic->ic_rh; - int len = le16toh(rh->it_len); - struct ieee80211vap *vap; - - /* XXX locking? */ - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - if (ieee80211_radiotap_active_vap(vap) && - vap->iv_state != IEEE80211_S_INIT) - bpf_mtap2(vap->iv_rawbpf, rh, len, m); - } -} - -/* - * Return the offset of the specified item in the radiotap - * header description. If the item is not present or is not - * known -1 is returned. - */ -static int -radiotap_offset(struct ieee80211_radiotap_header *rh, int item) -{ - static const struct { - size_t align, width; - } items[] = { - [IEEE80211_RADIOTAP_TSFT] = { - .align = sizeof(uint64_t), - .width = sizeof(uint64_t), - }, - [IEEE80211_RADIOTAP_FLAGS] = { - .align = sizeof(uint8_t), - .width = sizeof(uint8_t), - }, - [IEEE80211_RADIOTAP_RATE] = { - .align = sizeof(uint8_t), - .width = sizeof(uint8_t), - }, - [IEEE80211_RADIOTAP_CHANNEL] = { - .align = sizeof(uint16_t), - .width = 2*sizeof(uint16_t), - }, - [IEEE80211_RADIOTAP_FHSS] = { - .align = sizeof(uint16_t), - .width = sizeof(uint16_t), - }, - [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = { - .align = sizeof(uint8_t), - .width = sizeof(uint8_t), - }, - [IEEE80211_RADIOTAP_DBM_ANTNOISE] = { - .align = sizeof(uint8_t), - .width = sizeof(uint8_t), - }, - [IEEE80211_RADIOTAP_LOCK_QUALITY] = { - .align = sizeof(uint16_t), - .width = sizeof(uint16_t), - }, - [IEEE80211_RADIOTAP_TX_ATTENUATION] = { - .align = sizeof(uint16_t), - .width = sizeof(uint16_t), - }, - [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = { - .align = sizeof(uint16_t), - .width = sizeof(uint16_t), - }, - [IEEE80211_RADIOTAP_DBM_TX_POWER] = { - .align = sizeof(uint8_t), - .width = sizeof(uint8_t), - }, - [IEEE80211_RADIOTAP_ANTENNA] = { - .align = sizeof(uint8_t), - .width = sizeof(uint8_t), - }, - [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = { - .align = sizeof(uint8_t), - .width = sizeof(uint8_t), - }, - [IEEE80211_RADIOTAP_DB_ANTNOISE] = { - .align = sizeof(uint8_t), - .width = sizeof(uint8_t), - }, - [IEEE80211_RADIOTAP_XCHANNEL] = { - .align = sizeof(uint32_t), - .width = 2*sizeof(uint32_t), - }, - }; - uint32_t present = le32toh(rh->it_present); - int off, i; - - off = sizeof(struct ieee80211_radiotap_header); - for (i = 0; i < IEEE80211_RADIOTAP_EXT; i++) { - if ((present & (1< le16toh(rh->it_len)) { - /* NB: item does not fit in header data */ - printf("%s: item %d not in header data, " - "off %d width %zu len %d\n", __func__, i, - off, items[i].width, le16toh(rh->it_len)); - return -1; - } - return off; - } - off += items[i].width; - } - return -1; -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_radiotap.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_radiotap.h deleted file mode 100644 index f7ef147c77..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_radiotap.h +++ /dev/null @@ -1,234 +0,0 @@ -/* $FreeBSD$ */ -/* $NetBSD: ieee80211_radiotap.h,v 1.16 2007/01/06 05:51:15 dyoung Exp $ */ - -/*- - * Copyright (c) 2003, 2004 David Young. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of David Young may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID - * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_RADIOTAP_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_RADIOTAP_H_ - -/* A generic radio capture format is desirable. It must be - * rigidly defined (e.g., units for fields should be given), - * and easily extensible. - * - * The following is an extensible radio capture format. It is - * based on a bitmap indicating which fields are present. - * - * I am trying to describe precisely what the application programmer - * should expect in the following, and for that reason I tell the - * units and origin of each measurement (where it applies), or else I - * use sufficiently weaselly language ("is a monotonically nondecreasing - * function of...") that I cannot set false expectations for lawyerly - * readers. - */ -#if defined(__KERNEL__) || defined(_KERNEL) -#ifndef DLT_IEEE802_11_RADIO -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus WLAN header */ -#endif -#endif /* defined(__KERNEL__) || defined(_KERNEL) */ - -#define IEEE80211_RADIOTAP_HDRLEN 64 /* XXX deprecated */ - -/* - * The radio capture header precedes the 802.11 header. - * - * Note well: all radiotap fields are little-endian. - */ -struct ieee80211_radiotap_header { - uint8_t it_version; /* Version 0. Only increases - * for drastic changes, - * introduction of compatible - * new fields does not count. - */ - uint8_t it_pad; - uint16_t it_len; /* length of the whole - * header in bytes, including - * it_version, it_pad, - * it_len, and data fields. - */ - uint32_t it_present; /* A bitmap telling which - * fields are present. Set bit 31 - * (0x80000000) to extend the - * bitmap by another 32 bits. - * Additional extensions are made - * by setting bit 31. - */ -} __packed; - -/* - * Name Data type Units - * ---- --------- ----- - * - * IEEE80211_RADIOTAP_TSFT uint64_t microseconds - * - * Value in microseconds of the MAC's 64-bit 802.11 Time - * Synchronization Function timer when the first bit of the - * MPDU arrived at the MAC. For received frames, only. - * - * IEEE80211_RADIOTAP_CHANNEL 2 x uint16_t MHz, bitmap - * - * Tx/Rx frequency in MHz, followed by flags (see below). - * - * IEEE80211_RADIOTAP_FHSS uint16_t see below - * - * For frequency-hopping radios, the hop set (first byte) - * and pattern (second byte). - * - * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s or index - * - * Tx/Rx data rate. If bit 0x80 is set then it represents an - * an MCS index and not an IEEE rate. - * - * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from - * one milliwatt (dBm) - * - * RF signal power at the antenna, decibel difference from - * one milliwatt. - * - * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from - * one milliwatt (dBm) - * - * RF noise power at the antenna, decibel difference from one - * milliwatt. - * - * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB) - * - * RF signal power at the antenna, decibel difference from an - * arbitrary, fixed reference. - * - * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB) - * - * RF noise power at the antenna, decibel difference from an - * arbitrary, fixed reference point. - * - * IEEE80211_RADIOTAP_LOCK_QUALITY uint16_t unitless - * - * Quality of Barker code lock. Unitless. Monotonically - * nondecreasing with "better" lock strength. Called "Signal - * Quality" in datasheets. (Is there a standard way to measure - * this?) - * - * IEEE80211_RADIOTAP_TX_ATTENUATION uint16_t unitless - * - * Transmit power expressed as unitless distance from max - * power set at factory calibration. 0 is max power. - * Monotonically nondecreasing with lower power levels. - * - * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t decibels (dB) - * - * Transmit power expressed as decibel distance from max power - * set at factory calibration. 0 is max power. Monotonically - * nondecreasing with lower power levels. - * - * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from - * one milliwatt (dBm) - * - * Transmit power expressed as dBm (decibels from a 1 milliwatt - * reference). This is the absolute power level measured at - * the antenna port. - * - * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap - * - * Properties of transmitted and received frames. See flags - * defined below. - * - * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index - * - * Unitless indication of the Rx/Tx antenna for this packet. - * The first antenna is antenna 0. - * - * IEEE80211_RADIOTAP_XCHANNEL uint32_t bitmap - * uint16_t MHz - * uint8_t channel number - * int8_t .5 dBm - * - * Extended channel specification: flags (see below) followed by - * frequency in MHz, the corresponding IEEE channel number, and - * finally the maximum regulatory transmit power cap in .5 dBm - * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL - * and only one of the two should be present. - */ -enum ieee80211_radiotap_type { - IEEE80211_RADIOTAP_TSFT = 0, - IEEE80211_RADIOTAP_FLAGS = 1, - IEEE80211_RADIOTAP_RATE = 2, - IEEE80211_RADIOTAP_CHANNEL = 3, - IEEE80211_RADIOTAP_FHSS = 4, - IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, - IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, - IEEE80211_RADIOTAP_LOCK_QUALITY = 7, - IEEE80211_RADIOTAP_TX_ATTENUATION = 8, - IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, - IEEE80211_RADIOTAP_DBM_TX_POWER = 10, - IEEE80211_RADIOTAP_ANTENNA = 11, - IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, - IEEE80211_RADIOTAP_DB_ANTNOISE = 13, - /* NB: gap for netbsd definitions */ - IEEE80211_RADIOTAP_XCHANNEL = 18, - IEEE80211_RADIOTAP_EXT = 31, -}; - -#ifndef _KERNEL -/* channel attributes */ -#define IEEE80211_CHAN_TURBO 0x00000010 /* Turbo channel */ -#define IEEE80211_CHAN_CCK 0x00000020 /* CCK channel */ -#define IEEE80211_CHAN_OFDM 0x00000040 /* OFDM channel */ -#define IEEE80211_CHAN_2GHZ 0x00000080 /* 2 GHz spectrum channel. */ -#define IEEE80211_CHAN_5GHZ 0x00000100 /* 5 GHz spectrum channel */ -#define IEEE80211_CHAN_PASSIVE 0x00000200 /* Only passive scan allowed */ -#define IEEE80211_CHAN_DYN 0x00000400 /* Dynamic CCK-OFDM channel */ -#define IEEE80211_CHAN_GFSK 0x00000800 /* GFSK channel (FHSS PHY) */ -#define IEEE80211_CHAN_GSM 0x00001000 /* 900 MHz spectrum channel */ -#define IEEE80211_CHAN_STURBO 0x00002000 /* 11a static turbo channel only */ -#define IEEE80211_CHAN_HALF 0x00004000 /* Half rate channel */ -#define IEEE80211_CHAN_QUARTER 0x00008000 /* Quarter rate channel */ -#endif /* !_KERNEL */ - -/* For IEEE80211_RADIOTAP_FLAGS */ -#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received - * during CFP - */ -#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received - * with short - * preamble - */ -#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received - * with WEP encryption - */ -#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received - * with fragmentation - */ -#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ -#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between - * 802.11 header and payload - * (to 32-bit boundary) - */ -#define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */ -#define IEEE80211_RADIOTAP_F_SHORTGI 0x80 /* HT short GI */ - -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_RADIOTAP_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ratectl.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_ratectl.c deleted file mode 100644 index 3e7fa19354..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ratectl.c +++ /dev/null @@ -1,117 +0,0 @@ -/*- - * Copyright (c) 2010 Rui Paulo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include - -#include -#include - -#include -#include - -static const struct ieee80211_ratectl *ratectls[IEEE80211_RATECTL_MAX]; - -static const char *ratectl_modnames[IEEE80211_RATECTL_MAX] = { - [IEEE80211_RATECTL_AMRR] = "wlan_amrr", - [IEEE80211_RATECTL_RSSADAPT] = "wlan_rssadapt", - [IEEE80211_RATECTL_ONOE] = "wlan_onoe", - [IEEE80211_RATECTL_SAMPLE] = "wlan_sample", - [IEEE80211_RATECTL_NONE] = "wlan_none", -}; - -MALLOC_DEFINE(M_80211_RATECTL, "80211ratectl", "802.11 rate control"); - - -#if defined(__HAIKU__) -/* - * Setup ratectl support for a device/shared instance. - */ -void -ieee80211_ratectl_attach(struct ieee80211com *ic) -{ - ieee80211_ratectl_none_load(); - ieee80211_ratectl_amrr_load(); - ieee80211_ratectl_rssadapt_load(); -} - -/* - * Teardown ratectl support. - */ -void -ieee80211_ratectl_detach(struct ieee80211com *ic) -{ - ieee80211_ratectl_none_unload(); - ieee80211_ratectl_amrr_unload(); - ieee80211_ratectl_rssadapt_unload(); -} -#endif - -void -ieee80211_ratectl_register(int type, const struct ieee80211_ratectl *ratectl) -{ - if (type >= IEEE80211_RATECTL_MAX) - return; - ratectls[type] = ratectl; -} - -void -ieee80211_ratectl_unregister(int type) -{ - if (type >= IEEE80211_RATECTL_MAX) - return; - ratectls[type] = NULL; -} - -void -ieee80211_ratectl_init(struct ieee80211vap *vap) -{ - if (vap->iv_rate == ratectls[IEEE80211_RATECTL_NONE]) - ieee80211_ratectl_set(vap, IEEE80211_RATECTL_AMRR); - vap->iv_rate->ir_init(vap); -} - -void -ieee80211_ratectl_set(struct ieee80211vap *vap, int type) -{ - if (type >= IEEE80211_RATECTL_MAX) - return; - if (ratectls[type] == NULL) { - ieee80211_load_module(ratectl_modnames[type]); - if (ratectls[type] == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_RATECTL, - "%s: unable to load algo %u, module %s\n", - __func__, type, ratectl_modnames[type]); - vap->iv_rate = ratectls[IEEE80211_RATECTL_NONE]; - return; - } - } - vap->iv_rate = ratectls[type]; -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ratectl.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_ratectl.h deleted file mode 100644 index a39efb47c5..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ratectl.h +++ /dev/null @@ -1,128 +0,0 @@ -/*- - * Copyright (c) 2010 Rui Paulo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -enum ieee80211_ratealgs { - IEEE80211_RATECTL_AMRR = 0, - IEEE80211_RATECTL_RSSADAPT = 1, - IEEE80211_RATECTL_ONOE = 2, - IEEE80211_RATECTL_SAMPLE = 3, - IEEE80211_RATECTL_NONE = 4, - IEEE80211_RATECTL_MAX -}; - -#define IEEE80211_RATECTL_TX_SUCCESS 1 -#define IEEE80211_RATECTL_TX_FAILURE 0 - -struct ieee80211_ratectl { - const char *ir_name; - int (*ir_attach)(const struct ieee80211vap *); - void (*ir_detach)(const struct ieee80211vap *); - void (*ir_init)(struct ieee80211vap *); - void (*ir_deinit)(struct ieee80211vap *); - void (*ir_node_init)(struct ieee80211_node *); - void (*ir_node_deinit)(struct ieee80211_node *); - int (*ir_rate)(struct ieee80211_node *, void *, uint32_t); - void (*ir_tx_complete)(const struct ieee80211vap *, - const struct ieee80211_node *, int, - void *, void *); - void (*ir_tx_update)(const struct ieee80211vap *, - const struct ieee80211_node *, - void *, void *, void *); - void (*ir_setinterval)(const struct ieee80211vap *, int); -}; - -void ieee80211_ratectl_register(int, const struct ieee80211_ratectl *); -void ieee80211_ratectl_unregister(int); -void ieee80211_ratectl_init(struct ieee80211vap *); -void ieee80211_ratectl_set(struct ieee80211vap *, int); - -#if defined (__HAIKU__) -void ieee80211_ratectl_attach(struct ieee80211com *ic); -void ieee80211_ratectl_detach(struct ieee80211com *ic); -void ieee80211_ratectl_none_load(void); -void ieee80211_ratectl_none_unload(void); -void ieee80211_ratectl_amrr_load(void); -void ieee80211_ratectl_amrr_unload(void); -void ieee80211_ratectl_rssadapt_load(void); -void ieee80211_ratectl_rssadapt_unload(void); -#endif - -MALLOC_DECLARE(M_80211_RATECTL); - -static void __inline -ieee80211_ratectl_deinit(struct ieee80211vap *vap) -{ - vap->iv_rate->ir_deinit(vap); -} - -static void __inline -ieee80211_ratectl_node_init(struct ieee80211_node *ni) -{ - const struct ieee80211vap *vap = ni->ni_vap; - - vap->iv_rate->ir_node_init(ni); -} - -static void __inline -ieee80211_ratectl_node_deinit(struct ieee80211_node *ni) -{ - const struct ieee80211vap *vap = ni->ni_vap; - - vap->iv_rate->ir_node_deinit(ni); -} - -static int __inline -ieee80211_ratectl_rate(struct ieee80211_node *ni, void *arg, uint32_t iarg) -{ - const struct ieee80211vap *vap = ni->ni_vap; - - return vap->iv_rate->ir_rate(ni, arg, iarg); -} - -static void __inline -ieee80211_ratectl_tx_complete(const struct ieee80211vap *vap, - const struct ieee80211_node *ni, int status, void *arg1, void *arg2) -{ - vap->iv_rate->ir_tx_complete(vap, ni, status, arg1, arg2); -} - -static void __inline -ieee80211_ratectl_tx_update(const struct ieee80211vap *vap, - const struct ieee80211_node *ni, void *arg1, void *arg2, void *arg3) -{ - if (vap->iv_rate->ir_tx_update == NULL) - return; - vap->iv_rate->ir_tx_update(vap, ni, arg1, arg2, arg3); -} - -static void __inline -ieee80211_ratectl_setinterval(const struct ieee80211vap *vap, int msecs) -{ - if (vap->iv_rate->ir_setinterval == NULL) - return; - vap->iv_rate->ir_setinterval(vap, msecs); -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ratectl_none.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_ratectl_none.c deleted file mode 100644 index 0edec449ec..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ratectl_none.c +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * Copyright (c) 2010 Bernhard Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include -#include - -#ifdef INET -#include -#include -#endif - -#include -#include - -static void -none_init(struct ieee80211vap *vap) -{ -} - -static void -none_deinit(struct ieee80211vap *vap) -{ - free(vap->iv_rs, M_80211_RATECTL); -} - -static void -none_node_init(struct ieee80211_node *ni) -{ - ni->ni_txrate = ni->ni_rates.rs_rates[0] & IEEE80211_RATE_VAL; -} - -static void -none_node_deinit(struct ieee80211_node *ni) -{ -} - -static int -none_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg __unused) -{ - int rix = 0; - - ni->ni_txrate = ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL; - return rix; -} - -static void -none_tx_complete(const struct ieee80211vap *vap, - const struct ieee80211_node *ni, int ok, - void *arg1, void *arg2 __unused) -{ -} - -static void -none_tx_update(const struct ieee80211vap *vap, const struct ieee80211_node *ni, - void *arg1, void *arg2, void *arg3) -{ -} - -static void -none_setinterval(const struct ieee80211vap *vap, int msecs) -{ -} - -/* number of references from net80211 layer */ -static int nrefs = 0; - -static const struct ieee80211_ratectl none = { - .ir_name = "none", - .ir_attach = NULL, - .ir_detach = NULL, - .ir_init = none_init, - .ir_deinit = none_deinit, - .ir_node_init = none_node_init, - .ir_node_deinit = none_node_deinit, - .ir_rate = none_rate, - .ir_tx_complete = none_tx_complete, - .ir_tx_update = none_tx_update, - .ir_setinterval = none_setinterval, -}; -IEEE80211_RATECTL_MODULE(ratectl_none, 1); -IEEE80211_RATECTL_ALG(none, IEEE80211_RATECTL_NONE, none); diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_regdomain.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_regdomain.c deleted file mode 100644 index c1d617335a..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_regdomain.c +++ /dev/null @@ -1,448 +0,0 @@ -/*- - * Copyright (c) 2005-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 regdomain support. - */ -#include "opt_wlan.h" - -#include -#include -#include - -#include - -#include -#include - -#include -#include - -static void -null_getradiocaps(struct ieee80211com *ic, int maxchan, - int *n, struct ieee80211_channel *c) -{ - /* just feed back the current channel list */ - if (maxchan > ic->ic_nchans) - maxchan = ic->ic_nchans; - memcpy(c, ic->ic_channels, maxchan*sizeof(struct ieee80211_channel)); - *n = maxchan; -} - -static int -null_setregdomain(struct ieee80211com *ic, - struct ieee80211_regdomain *rd, - int nchans, struct ieee80211_channel chans[]) -{ - return 0; /* accept anything */ -} - -void -ieee80211_regdomain_attach(struct ieee80211com *ic) -{ - if (ic->ic_regdomain.regdomain == 0 && - ic->ic_regdomain.country == CTRY_DEFAULT) { - ic->ic_regdomain.country = CTRY_UNITED_STATES; /* XXX */ - ic->ic_regdomain.location = ' '; /* both */ - ic->ic_regdomain.isocc[0] = 'U'; /* XXX */ - ic->ic_regdomain.isocc[1] = 'S'; /* XXX */ - /* NB: driver calls ieee80211_init_channels or similar */ - } - ic->ic_getradiocaps = null_getradiocaps; - ic->ic_setregdomain = null_setregdomain; -} - -void -ieee80211_regdomain_detach(struct ieee80211com *ic) -{ - if (ic->ic_countryie != NULL) { - free(ic->ic_countryie, M_80211_NODE_IE); - ic->ic_countryie = NULL; - } -} - -void -ieee80211_regdomain_vattach(struct ieee80211vap *vap) -{ -} - -void -ieee80211_regdomain_vdetach(struct ieee80211vap *vap) -{ -} - -static void -addchan(struct ieee80211com *ic, int ieee, int flags) -{ - struct ieee80211_channel *c; - - c = &ic->ic_channels[ic->ic_nchans++]; - c->ic_freq = ieee80211_ieee2mhz(ieee, flags); - c->ic_ieee = ieee; - c->ic_flags = flags; - c->ic_extieee = 0; -} - -/* - * Setup the channel list for the specified regulatory domain, - * country code, and operating modes. This interface is used - * when a driver does not obtain the channel list from another - * source (such as firmware). - */ -int -ieee80211_init_channels(struct ieee80211com *ic, - const struct ieee80211_regdomain *rd, const uint8_t bands[]) -{ - int i; - - /* XXX just do something for now */ - ic->ic_nchans = 0; - if (isset(bands, IEEE80211_MODE_11B) || - isset(bands, IEEE80211_MODE_11G)) { - int maxchan = 11; - if (rd != NULL && rd->ecm) - maxchan = 14; - for (i = 1; i <= maxchan; i++) { - if (isset(bands, IEEE80211_MODE_11B)) - addchan(ic, i, IEEE80211_CHAN_B); - if (isset(bands, IEEE80211_MODE_11G)) - addchan(ic, i, IEEE80211_CHAN_G); - } - } - if (isset(bands, IEEE80211_MODE_11A)) { - for (i = 36; i <= 64; i += 4) - addchan(ic, i, IEEE80211_CHAN_A); - for (i = 100; i <= 140; i += 4) - addchan(ic, i, IEEE80211_CHAN_A); - for (i = 149; i <= 161; i += 4) - addchan(ic, i, IEEE80211_CHAN_A); - } - if (rd != NULL) - ic->ic_regdomain = *rd; - - return 0; -} - -static __inline int -chancompar(const void *a, const void *b) -{ - const struct ieee80211_channel *ca = a; - const struct ieee80211_channel *cb = b; - - return (ca->ic_freq == cb->ic_freq) ? - (ca->ic_flags & IEEE80211_CHAN_ALL) - - (cb->ic_flags & IEEE80211_CHAN_ALL) : - ca->ic_freq - cb->ic_freq; -} - -/* - * Insertion sort. - */ -#define swap(_a, _b, _size) { \ - uint8_t *s = _b; \ - int i = _size; \ - do { \ - uint8_t tmp = *_a; \ - *_a++ = *s; \ - *s++ = tmp; \ - } while (--i); \ - _a -= _size; \ -} - -static void -sort_channels(void *a, size_t n, size_t size) -{ - uint8_t *aa = a; - uint8_t *ai, *t; - - KASSERT(n > 0, ("no channels")); - for (ai = aa+size; --n >= 1; ai += size) - for (t = ai; t > aa; t -= size) { - uint8_t *u = t - size; - if (chancompar(u, t) <= 0) - break; - swap(u, t, size); - } -} -#undef swap - -/* - * Order channels w/ the same frequency so that - * b < g < htg and a < hta. This is used to optimize - * channel table lookups and some user applications - * may also depend on it (though they should not). - */ -void -ieee80211_sort_channels(struct ieee80211_channel chans[], int nchans) -{ - if (nchans > 0) - sort_channels(chans, nchans, sizeof(struct ieee80211_channel)); -} - -/* - * Allocate and construct a Country Information IE. - */ -struct ieee80211_appie * -ieee80211_alloc_countryie(struct ieee80211com *ic) -{ -#define CHAN_UNINTERESTING \ - (IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO | \ - IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER) - /* XXX what about auto? */ - /* flag set of channels to be excluded (band added below) */ - static const int skipflags[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = CHAN_UNINTERESTING, - [IEEE80211_MODE_11A] = CHAN_UNINTERESTING, - [IEEE80211_MODE_11B] = CHAN_UNINTERESTING, - [IEEE80211_MODE_11G] = CHAN_UNINTERESTING, - [IEEE80211_MODE_FH] = CHAN_UNINTERESTING - | IEEE80211_CHAN_OFDM - | IEEE80211_CHAN_CCK - | IEEE80211_CHAN_DYN, - [IEEE80211_MODE_TURBO_A] = CHAN_UNINTERESTING, - [IEEE80211_MODE_TURBO_G] = CHAN_UNINTERESTING, - [IEEE80211_MODE_STURBO_A] = CHAN_UNINTERESTING, - [IEEE80211_MODE_HALF] = IEEE80211_CHAN_TURBO - | IEEE80211_CHAN_STURBO, - [IEEE80211_MODE_QUARTER] = IEEE80211_CHAN_TURBO - | IEEE80211_CHAN_STURBO, - [IEEE80211_MODE_11NA] = CHAN_UNINTERESTING, - [IEEE80211_MODE_11NG] = CHAN_UNINTERESTING, - }; - const struct ieee80211_regdomain *rd = &ic->ic_regdomain; - uint8_t nextchan, chans[IEEE80211_CHAN_BYTES], *frm; - struct ieee80211_appie *aie; - struct ieee80211_country_ie *ie; - int i, skip, nruns; - - aie = malloc(IEEE80211_COUNTRY_MAX_SIZE, M_80211_NODE_IE, - M_NOWAIT | M_ZERO); - if (aie == NULL) { - if_printf(ic->ic_ifp, - "%s: unable to allocate memory for country ie\n", __func__); - /* XXX stat */ - return NULL; - } - ie = (struct ieee80211_country_ie *) aie->ie_data; - ie->ie = IEEE80211_ELEMID_COUNTRY; - if (rd->isocc[0] == '\0') { - if_printf(ic->ic_ifp, "no ISO country string for cc %d; " - "using blanks\n", rd->country); - ie->cc[0] = ie->cc[1] = ' '; - } else { - ie->cc[0] = rd->isocc[0]; - ie->cc[1] = rd->isocc[1]; - } - /* - * Indoor/Outdoor portion of country string: - * 'I' indoor only - * 'O' outdoor only - * ' ' all enviroments - */ - ie->cc[2] = (rd->location == 'I' ? 'I' : - rd->location == 'O' ? 'O' : ' '); - /* - * Run-length encoded channel+max tx power info. - */ - frm = (uint8_t *)&ie->band[0]; - nextchan = 0; /* NB: impossible channel # */ - nruns = 0; - memset(chans, 0, sizeof(chans)); - skip = skipflags[ieee80211_chan2mode(ic->ic_bsschan)]; - if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) - skip |= IEEE80211_CHAN_2GHZ; - else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_bsschan)) - skip |= IEEE80211_CHAN_5GHZ; - for (i = 0; i < ic->ic_nchans; i++) { - const struct ieee80211_channel *c = &ic->ic_channels[i]; - - if (isset(chans, c->ic_ieee)) /* suppress dup's */ - continue; - if (c->ic_flags & skip) /* skip band, etc. */ - continue; - setbit(chans, c->ic_ieee); - if (c->ic_ieee != nextchan || - c->ic_maxregpower != frm[-1]) { /* new run */ - if (nruns == IEEE80211_COUNTRY_MAX_BANDS) { - if_printf(ic->ic_ifp, "%s: country ie too big, " - "runs > max %d, truncating\n", - __func__, IEEE80211_COUNTRY_MAX_BANDS); - /* XXX stat? fail? */ - break; - } - frm[0] = c->ic_ieee; /* starting channel # */ - frm[1] = 1; /* # channels in run */ - frm[2] = c->ic_maxregpower; /* tx power cap */ - frm += 3; - nextchan = c->ic_ieee + 1; /* overflow? */ - nruns++; - } else { /* extend run */ - frm[-2]++; - nextchan++; - } - } - ie->len = frm - ie->cc; - if (ie->len & 1) { /* Zero pad to multiple of 2 */ - ie->len++; - *frm++ = 0; - } - aie->ie_len = frm - aie->ie_data; - - return aie; -#undef CHAN_UNINTERESTING -} - -static int -allvapsdown(struct ieee80211com *ic) -{ - struct ieee80211vap *vap; - - IEEE80211_LOCK_ASSERT(ic); - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if (vap->iv_state != IEEE80211_S_INIT) - return 0; - return 1; -} - -int -ieee80211_setregdomain(struct ieee80211vap *vap, - struct ieee80211_regdomain_req *reg) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_channel *c; - int desfreq = 0, desflags = 0; /* XXX silence gcc complaint */ - int error, i; - - if (reg->rd.location != 'I' && reg->rd.location != 'O' && - reg->rd.location != ' ') { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL, - "%s: invalid location 0x%x\n", __func__, reg->rd.location); - return EINVAL; - } - if (reg->rd.isocc[0] == '\0' || reg->rd.isocc[1] == '\0') { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL, - "%s: invalid iso cc 0x%x:0x%x\n", __func__, - reg->rd.isocc[0], reg->rd.isocc[1]); - return EINVAL; - } - if (reg->chaninfo.ic_nchans > IEEE80211_CHAN_MAX) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL, - "%s: too many channels %u, max %u\n", __func__, - reg->chaninfo.ic_nchans, IEEE80211_CHAN_MAX); - return EINVAL; - } - /* - * Calculate freq<->IEEE mapping and default max tx power - * for channels not setup. The driver can override these - * setting to reflect device properties/requirements. - */ - for (i = 0; i < reg->chaninfo.ic_nchans; i++) { - c = ®->chaninfo.ic_chans[i]; - if (c->ic_freq == 0 || c->ic_flags == 0) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL, - "%s: invalid channel spec at [%u]\n", __func__, i); - return EINVAL; - } - if (c->ic_maxregpower == 0) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL, - "%s: invalid channel spec, zero maxregpower, " - "freq %u flags 0x%x\n", __func__, - c->ic_freq, c->ic_flags); - return EINVAL; - } - if (c->ic_ieee == 0) - c->ic_ieee = ieee80211_mhz2ieee(c->ic_freq,c->ic_flags); - if (IEEE80211_IS_CHAN_HT40(c) && c->ic_extieee == 0) - c->ic_extieee = ieee80211_mhz2ieee(c->ic_freq + - (IEEE80211_IS_CHAN_HT40U(c) ? 20 : -20), - c->ic_flags); - if (c->ic_maxpower == 0) - c->ic_maxpower = 2*c->ic_maxregpower; - } - IEEE80211_LOCK(ic); - /* XXX bandaid; a running vap will likely crash */ - if (!allvapsdown(ic)) { - IEEE80211_UNLOCK(ic); - IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL, - "%s: reject: vaps are running\n", __func__); - return EBUSY; - } - error = ic->ic_setregdomain(ic, ®->rd, - reg->chaninfo.ic_nchans, reg->chaninfo.ic_chans); - if (error != 0) { - IEEE80211_UNLOCK(ic); - IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL, - "%s: driver rejected request, error %u\n", __func__, error); - return error; - } - /* - * Commit: copy in new channel table and reset media state. - * On return the state machines will be clocked so all vaps - * will reset their state. - * - * XXX ic_bsschan is marked undefined, must have vap's in - * INIT state or we blow up forcing stations off - */ - /* - * Save any desired channel for restore below. Note this - * needs to be done for all vaps but for now we only do - * the one where the ioctl is issued. - */ - if (vap->iv_des_chan != IEEE80211_CHAN_ANYC) { - desfreq = vap->iv_des_chan->ic_freq; - desflags = vap->iv_des_chan->ic_flags; - } - /* regdomain parameters */ - memcpy(&ic->ic_regdomain, ®->rd, sizeof(reg->rd)); - /* channel table */ - memcpy(ic->ic_channels, reg->chaninfo.ic_chans, - reg->chaninfo.ic_nchans * sizeof(struct ieee80211_channel)); - ic->ic_nchans = reg->chaninfo.ic_nchans; - memset(&ic->ic_channels[ic->ic_nchans], 0, - (IEEE80211_CHAN_MAX - ic->ic_nchans) * - sizeof(struct ieee80211_channel)); - ieee80211_media_init(ic); - - /* - * Invalidate channel-related state. - */ - if (ic->ic_countryie != NULL) { - free(ic->ic_countryie, M_80211_NODE_IE); - ic->ic_countryie = NULL; - } - ieee80211_scan_flush(vap); - ieee80211_dfs_reset(ic); - if (vap->iv_des_chan != IEEE80211_CHAN_ANYC) { - c = ieee80211_find_channel(ic, desfreq, desflags); - /* NB: may be NULL if not present in new channel list */ - vap->iv_des_chan = (c != NULL) ? c : IEEE80211_CHAN_ANYC; - } - IEEE80211_UNLOCK(ic); - - return 0; -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_regdomain.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_regdomain.h deleted file mode 100644 index 93f228af03..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_regdomain.h +++ /dev/null @@ -1,282 +0,0 @@ -/*- - * Copyright (c) 2005-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_REGDOMAIN_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_REGDOMAIN_H_ - -/* - * 802.11 regulatory domain definitions. - */ - -/* - * ISO 3166 Country/Region Codes - * http://ftp.ics.uci.edu/pub/ietf/http/related/iso3166.txt - */ -enum ISOCountryCode { - CTRY_AFGHANISTAN = 4, - CTRY_ALBANIA = 8, /* Albania */ - CTRY_ALGERIA = 12, /* Algeria */ - CTRY_AMERICAN_SAMOA = 16, - CTRY_ANDORRA = 20, - CTRY_ANGOLA = 24, - CTRY_ANGUILLA = 660, - CTRY_ANTARTICA = 10, - CTRY_ANTIGUA = 28, /* Antigua and Barbuda */ - CTRY_ARGENTINA = 32, /* Argentina */ - CTRY_ARMENIA = 51, /* Armenia */ - CTRY_ARUBA = 533, /* Aruba */ - CTRY_AUSTRALIA = 36, /* Australia */ - CTRY_AUSTRIA = 40, /* Austria */ - CTRY_AZERBAIJAN = 31, /* Azerbaijan */ - CTRY_BAHAMAS = 44, /* Bahamas */ - CTRY_BAHRAIN = 48, /* Bahrain */ - CTRY_BANGLADESH = 50, /* Bangladesh */ - CTRY_BARBADOS = 52, - CTRY_BELARUS = 112, /* Belarus */ - CTRY_BELGIUM = 56, /* Belgium */ - CTRY_BELIZE = 84, - CTRY_BENIN = 204, - CTRY_BERMUDA = 60, - CTRY_BHUTAN = 64, - CTRY_BOLIVIA = 68, /* Bolivia */ - CTRY_BOSNIA_AND_HERZEGOWINA = 70, - CTRY_BOTSWANA = 72, - CTRY_BOUVET_ISLAND = 74, - CTRY_BRAZIL = 76, /* Brazil */ - CTRY_BRITISH_INDIAN_OCEAN_TERRITORY = 86, - CTRY_BRUNEI_DARUSSALAM = 96, /* Brunei Darussalam */ - CTRY_BULGARIA = 100, /* Bulgaria */ - CTRY_BURKINA_FASO = 854, - CTRY_BURUNDI = 108, - CTRY_CAMBODIA = 116, - CTRY_CAMEROON = 120, - CTRY_CANADA = 124, /* Canada */ - CTRY_CAPE_VERDE = 132, - CTRY_CAYMAN_ISLANDS = 136, - CTRY_CENTRAL_AFRICAN_REPUBLIC = 140, - CTRY_CHAD = 148, - CTRY_CHILE = 152, /* Chile */ - CTRY_CHINA = 156, /* People's Republic of China */ - CTRY_CHRISTMAS_ISLAND = 162, - CTRY_COCOS_ISLANDS = 166, - CTRY_COLOMBIA = 170, /* Colombia */ - CTRY_COMOROS = 174, - CTRY_CONGO = 178, - CTRY_COOK_ISLANDS = 184, - CTRY_COSTA_RICA = 188, /* Costa Rica */ - CTRY_COTE_DIVOIRE = 384, - CTRY_CROATIA = 191, /* Croatia (local name: Hrvatska) */ - CTRY_CYPRUS = 196, /* Cyprus */ - CTRY_CZECH = 203, /* Czech Republic */ - CTRY_DENMARK = 208, /* Denmark */ - CTRY_DJIBOUTI = 262, - CTRY_DOMINICA = 212, - CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */ - CTRY_EAST_TIMOR = 626, - CTRY_ECUADOR = 218, /* Ecuador */ - CTRY_EGYPT = 818, /* Egypt */ - CTRY_EL_SALVADOR = 222, /* El Salvador */ - CTRY_EQUATORIAL_GUINEA = 226, - CTRY_ERITREA = 232, - CTRY_ESTONIA = 233, /* Estonia */ - CTRY_ETHIOPIA = 210, - CTRY_FALKLAND_ISLANDS = 238, /* (Malvinas) */ - CTRY_FAEROE_ISLANDS = 234, /* Faeroe Islands */ - CTRY_FIJI = 242, - CTRY_FINLAND = 246, /* Finland */ - CTRY_FRANCE = 250, /* France */ - CTRY_FRANCE2 = 255, /* France (Metropolitan) */ - CTRY_FRENCH_GUIANA = 254, - CTRY_FRENCH_POLYNESIA = 258, - CTRY_FRENCH_SOUTHERN_TERRITORIES = 260, - CTRY_GABON = 266, - CTRY_GAMBIA = 270, - CTRY_GEORGIA = 268, /* Georgia */ - CTRY_GERMANY = 276, /* Germany */ - CTRY_GHANA = 288, - CTRY_GIBRALTAR = 292, - CTRY_GREECE = 300, /* Greece */ - CTRY_GREENLAND = 304, - CTRY_GRENADA = 308, - CTRY_GUADELOUPE = 312, - CTRY_GUAM = 316, - CTRY_GUATEMALA = 320, /* Guatemala */ - CTRY_GUINEA = 324, - CTRY_GUINEA_BISSAU = 624, - CTRY_GUYANA = 328, - /* XXX correct remainder */ - CTRY_HAITI = 332, - CTRY_HONDURAS = 340, /* Honduras */ - CTRY_HONG_KONG = 344, /* Hong Kong S.A.R., P.R.C. */ - CTRY_HUNGARY = 348, /* Hungary */ - CTRY_ICELAND = 352, /* Iceland */ - CTRY_INDIA = 356, /* India */ - CTRY_INDONESIA = 360, /* Indonesia */ - CTRY_IRAN = 364, /* Iran */ - CTRY_IRAQ = 368, /* Iraq */ - CTRY_IRELAND = 372, /* Ireland */ - CTRY_ISRAEL = 376, /* Israel */ - CTRY_ITALY = 380, /* Italy */ - CTRY_JAMAICA = 388, /* Jamaica */ - CTRY_JAPAN = 392, /* Japan */ - CTRY_JORDAN = 400, /* Jordan */ - CTRY_KAZAKHSTAN = 398, /* Kazakhstan */ - CTRY_KENYA = 404, /* Kenya */ - CTRY_KOREA_NORTH = 408, /* North Korea */ - CTRY_KOREA_ROC = 410, /* South Korea */ - CTRY_KOREA_ROC2 = 411, /* South Korea */ - CTRY_KUWAIT = 414, /* Kuwait */ - CTRY_LATVIA = 428, /* Latvia */ - CTRY_LEBANON = 422, /* Lebanon */ - CTRY_LIBYA = 434, /* Libya */ - CTRY_LIECHTENSTEIN = 438, /* Liechtenstein */ - CTRY_LITHUANIA = 440, /* Lithuania */ - CTRY_LUXEMBOURG = 442, /* Luxembourg */ - CTRY_MACAU = 446, /* Macau */ - CTRY_MACEDONIA = 807, /* the Former Yugoslav Republic of Macedonia */ - CTRY_MALAYSIA = 458, /* Malaysia */ - CTRY_MALTA = 470, /* Malta */ - CTRY_MEXICO = 484, /* Mexico */ - CTRY_MONACO = 492, /* Principality of Monaco */ - CTRY_MOROCCO = 504, /* Morocco */ - CTRY_NEPAL = 524, /* Nepal */ - CTRY_NETHERLANDS = 528, /* Netherlands */ - CTRY_NEW_ZEALAND = 554, /* New Zealand */ - CTRY_NICARAGUA = 558, /* Nicaragua */ - CTRY_NORWAY = 578, /* Norway */ - CTRY_OMAN = 512, /* Oman */ - CTRY_PAKISTAN = 586, /* Islamic Republic of Pakistan */ - CTRY_PANAMA = 591, /* Panama */ - CTRY_PARAGUAY = 600, /* Paraguay */ - CTRY_PERU = 604, /* Peru */ - CTRY_PHILIPPINES = 608, /* Republic of the Philippines */ - CTRY_POLAND = 616, /* Poland */ - CTRY_PORTUGAL = 620, /* Portugal */ - CTRY_PUERTO_RICO = 630, /* Puerto Rico */ - CTRY_QATAR = 634, /* Qatar */ - CTRY_ROMANIA = 642, /* Romania */ - CTRY_RUSSIA = 643, /* Russia */ - CTRY_SAUDI_ARABIA = 682, /* Saudi Arabia */ - CTRY_SINGAPORE = 702, /* Singapore */ - CTRY_SLOVAKIA = 703, /* Slovak Republic */ - CTRY_SLOVENIA = 705, /* Slovenia */ - CTRY_SOUTH_AFRICA = 710, /* South Africa */ - CTRY_SPAIN = 724, /* Spain */ - CTRY_SRILANKA = 144, /* Sri Lanka */ - CTRY_SWEDEN = 752, /* Sweden */ - CTRY_SWITZERLAND = 756, /* Switzerland */ - CTRY_SYRIA = 760, /* Syria */ - CTRY_TAIWAN = 158, /* Taiwan */ - CTRY_THAILAND = 764, /* Thailand */ - CTRY_TRINIDAD_Y_TOBAGO = 780, /* Trinidad y Tobago */ - CTRY_TUNISIA = 788, /* Tunisia */ - CTRY_TURKEY = 792, /* Turkey */ - CTRY_UAE = 784, /* U.A.E. */ - CTRY_UKRAINE = 804, /* Ukraine */ - CTRY_UNITED_KINGDOM = 826, /* United Kingdom */ - CTRY_UNITED_STATES = 840, /* United States */ - CTRY_URUGUAY = 858, /* Uruguay */ - CTRY_UZBEKISTAN = 860, /* Uzbekistan */ - CTRY_VENEZUELA = 862, /* Venezuela */ - CTRY_VIET_NAM = 704, /* Viet Nam */ - CTRY_YEMEN = 887, /* Yemen */ - CTRY_ZIMBABWE = 716, /* Zimbabwe */ - - /* NB: from here down not listed in 3166; they come from Atheros */ - CTRY_DEBUG = 0x1ff, /* debug */ - CTRY_DEFAULT = 0, /* default */ - - CTRY_UNITED_STATES_FCC49 = 842, /* United States (Public Safety)*/ - CTRY_KOREA_ROC3 = 412, /* South Korea */ - - CTRY_JAPAN1 = 393, /* Japan (JP1) */ - CTRY_JAPAN2 = 394, /* Japan (JP0) */ - CTRY_JAPAN3 = 395, /* Japan (JP1-1) */ - CTRY_JAPAN4 = 396, /* Japan (JE1) */ - CTRY_JAPAN5 = 397, /* Japan (JE2) */ - CTRY_JAPAN6 = 399, /* Japan (JP6) */ - CTRY_JAPAN7 = 4007, /* Japan (J7) */ - CTRY_JAPAN8 = 4008, /* Japan (J8) */ - CTRY_JAPAN9 = 4009, /* Japan (J9) */ - CTRY_JAPAN10 = 4010, /* Japan (J10) */ - CTRY_JAPAN11 = 4011, /* Japan (J11) */ - CTRY_JAPAN12 = 4012, /* Japan (J12) */ - CTRY_JAPAN13 = 4013, /* Japan (J13) */ - CTRY_JAPAN14 = 4014, /* Japan (J14) */ - CTRY_JAPAN15 = 4015, /* Japan (J15) */ - CTRY_JAPAN16 = 4016, /* Japan (J16) */ - CTRY_JAPAN17 = 4017, /* Japan (J17) */ - CTRY_JAPAN18 = 4018, /* Japan (J18) */ - CTRY_JAPAN19 = 4019, /* Japan (J19) */ - CTRY_JAPAN20 = 4020, /* Japan (J20) */ - CTRY_JAPAN21 = 4021, /* Japan (J21) */ - CTRY_JAPAN22 = 4022, /* Japan (J22) */ - CTRY_JAPAN23 = 4023, /* Japan (J23) */ - CTRY_JAPAN24 = 4024, /* Japan (J24) */ -}; - -enum RegdomainCode { - SKU_FCC = 0x10, /* FCC, aka United States */ - SKU_CA = 0x20, /* North America, aka Canada */ - SKU_ETSI = 0x30, /* Europe */ - SKU_ETSI2 = 0x32, /* Europe w/o HT40 in 5GHz */ - SKU_ETSI3 = 0x33, /* Europe - channel 36 */ - SKU_FCC3 = 0x3a, /* FCC w/5470 band, 11h, DFS */ - SKU_JAPAN = 0x40, - SKU_KOREA = 0x45, - SKU_APAC = 0x50, /* Asia Pacific */ - SKU_APAC2 = 0x51, /* Asia Pacific w/ DFS on mid-band */ - SKU_APAC3 = 0x5d, /* Asia Pacific w/o ISM band */ - SKU_ROW = 0x81, /* China/Taiwan/Rest of World */ - SKU_NONE = 0xf0, /* "Region Free" */ - SKU_DEBUG = 0x1ff, - - /* NB: from here down private */ - SKU_SR9 = 0x0298, /* Ubiquiti SR9 (900MHz/GSM) */ - SKU_XR9 = 0x0299, /* Ubiquiti XR9 (900MHz/GSM) */ - SKU_GZ901 = 0x029a, /* Zcomax GZ-901 (900MHz/GSM) */ -}; - -#if defined(__KERNEL__) || defined(_KERNEL) -struct ieee80211com; -void ieee80211_regdomain_attach(struct ieee80211com *); -void ieee80211_regdomain_detach(struct ieee80211com *); -struct ieee80211vap; -void ieee80211_regdomain_vattach(struct ieee80211vap *); -void ieee80211_regdomain_vdetach(struct ieee80211vap *); - -struct ieee80211_regdomain; -int ieee80211_init_channels(struct ieee80211com *, - const struct ieee80211_regdomain *, const uint8_t bands[]); -struct ieee80211_channel; -void ieee80211_sort_channels(struct ieee80211_channel *chans, int nchans); -struct ieee80211_appie; -struct ieee80211_appie *ieee80211_alloc_countryie(struct ieee80211com *); -struct ieee80211_regdomain_req; -int ieee80211_setregdomain(struct ieee80211vap *, - struct ieee80211_regdomain_req *); -#endif /* defined(__KERNEL__) || defined(_KERNEL) */ -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_REGDOMAIN_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_rssadapt.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_rssadapt.c deleted file mode 100644 index aaf4057a77..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_rssadapt.c +++ /dev/null @@ -1,349 +0,0 @@ -/* $FreeBSD$ */ -/* $NetBSD: ieee80211_rssadapt.c,v 1.9 2005/02/26 22:45:09 perry Exp $ */ -/*- - * Copyright (c) 2010 Rui Paulo - * Copyright (c) 2003, 2004 David Young. All rights reserved. - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * 3. The name of David Young may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David - * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -struct rssadapt_expavgctl { - /* RSS threshold decay. */ - u_int rc_decay_denom; - u_int rc_decay_old; - /* RSS threshold update. */ - u_int rc_thresh_denom; - u_int rc_thresh_old; - /* RSS average update. */ - u_int rc_avgrssi_denom; - u_int rc_avgrssi_old; -}; - -static struct rssadapt_expavgctl master_expavgctl = { - .rc_decay_denom = 16, - .rc_decay_old = 15, - .rc_thresh_denom = 8, - .rc_thresh_old = 4, - .rc_avgrssi_denom = 8, - .rc_avgrssi_old = 4 -}; - -#ifdef interpolate -#undef interpolate -#endif -#define interpolate(parm, old, new) ((parm##_old * (old) + \ - (parm##_denom - parm##_old) * (new)) / \ - parm##_denom) - -static void rssadapt_setinterval(const struct ieee80211vap *, int); -static void rssadapt_init(struct ieee80211vap *); -static void rssadapt_deinit(struct ieee80211vap *); -static void rssadapt_updatestats(struct ieee80211_rssadapt_node *); -static void rssadapt_node_init(struct ieee80211_node *); -static void rssadapt_node_deinit(struct ieee80211_node *); -static int rssadapt_rate(struct ieee80211_node *, void *, uint32_t); -static void rssadapt_lower_rate(struct ieee80211_rssadapt_node *, int, int); -static void rssadapt_raise_rate(struct ieee80211_rssadapt_node *, - int, int); -static void rssadapt_tx_complete(const struct ieee80211vap *, - const struct ieee80211_node *, int, - void *, void *); -static void rssadapt_sysctlattach(struct ieee80211vap *, - struct sysctl_ctx_list *, struct sysctl_oid *); - -/* number of references from net80211 layer */ -static int nrefs = 0; - -static const struct ieee80211_ratectl rssadapt = { - .ir_name = "rssadapt", - .ir_attach = NULL, - .ir_detach = NULL, - .ir_init = rssadapt_init, - .ir_deinit = rssadapt_deinit, - .ir_node_init = rssadapt_node_init, - .ir_node_deinit = rssadapt_node_deinit, - .ir_rate = rssadapt_rate, - .ir_tx_complete = rssadapt_tx_complete, - .ir_tx_update = NULL, - .ir_setinterval = rssadapt_setinterval, -}; -IEEE80211_RATECTL_MODULE(rssadapt, 1); -IEEE80211_RATECTL_ALG(rssadapt, IEEE80211_RATECTL_RSSADAPT, rssadapt); - -static void -rssadapt_setinterval(const struct ieee80211vap *vap, int msecs) -{ - struct ieee80211_rssadapt *rs = vap->iv_rs; - int t; - - if (msecs < 100) - msecs = 100; - t = msecs_to_ticks(msecs); - rs->interval = (t < 1) ? 1 : t; -} - -static void -rssadapt_init(struct ieee80211vap *vap) -{ - struct ieee80211_rssadapt *rs; - - KASSERT(vap->iv_rs == NULL, ("%s: iv_rs already initialized", - __func__)); - - vap->iv_rs = rs = malloc(sizeof(struct ieee80211_rssadapt), - M_80211_RATECTL, M_NOWAIT|M_ZERO); - if (rs == NULL) { - if_printf(vap->iv_ifp, "couldn't alloc ratectl structure\n"); - return; - } - rs->vap = vap; - rssadapt_setinterval(vap, 500 /* msecs */); - rssadapt_sysctlattach(vap, vap->iv_sysctl, vap->iv_oid); -} - -static void -rssadapt_deinit(struct ieee80211vap *vap) -{ - free(vap->iv_rs, M_80211_RATECTL); -} - -static void -rssadapt_updatestats(struct ieee80211_rssadapt_node *ra) -{ - long interval; - - ra->ra_pktrate = (ra->ra_pktrate + 10*(ra->ra_nfail + ra->ra_nok))/2; - ra->ra_nfail = ra->ra_nok = 0; - - /* - * A node is eligible for its rate to be raised every 1/10 to 10 - * seconds, more eligible in proportion to recent packet rates. - */ - interval = MAX(10*1000, 10*1000 / MAX(1, 10 * ra->ra_pktrate)); - ra->ra_raise_interval = msecs_to_ticks(interval); -} - -static void -rssadapt_node_init(struct ieee80211_node *ni) -{ - struct ieee80211_rssadapt_node *ra; - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_rssadapt *rsa = vap->iv_rs; - const struct ieee80211_rateset *rs = &ni->ni_rates; - - if (ni->ni_rctls == NULL) { - ni->ni_rctls = ra = - malloc(sizeof(struct ieee80211_rssadapt_node), - M_80211_RATECTL, M_NOWAIT|M_ZERO); - if (ra == NULL) { - if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl " - "structure\n"); - return; - } - } else - ra = ni->ni_rctls; - ra->ra_rs = rsa; - ra->ra_rates = *rs; - rssadapt_updatestats(ra); - - /* pick initial rate */ - for (ra->ra_rix = rs->rs_nrates - 1; - ra->ra_rix > 0 && (rs->rs_rates[ra->ra_rix] & IEEE80211_RATE_VAL) > 72; - ra->ra_rix--) - ; - ni->ni_txrate = rs->rs_rates[ra->ra_rix] & IEEE80211_RATE_VAL; - ra->ra_ticks = ticks; - - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, - "RSSADAPT initial rate %d", ni->ni_txrate); -} - -static void -rssadapt_node_deinit(struct ieee80211_node *ni) -{ - - free(ni->ni_rctls, M_80211_RATECTL); -} - -static __inline int -bucket(int pktlen) -{ - int i, top, thridx; - - for (i = 0, top = IEEE80211_RSSADAPT_BKT0; - i < IEEE80211_RSSADAPT_BKTS; - i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) { - thridx = i; - if (pktlen <= top) - break; - } - return thridx; -} - -static int -rssadapt_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg) -{ - struct ieee80211_rssadapt_node *ra = ni->ni_rctls; - u_int pktlen = iarg; - const struct ieee80211_rateset *rs = &ra->ra_rates; - uint16_t (*thrs)[IEEE80211_RATE_SIZE]; - int rix, rssi; - - if ((ticks - ra->ra_ticks) > ra->ra_rs->interval) { - rssadapt_updatestats(ra); - ra->ra_ticks = ticks; - } - - thrs = &ra->ra_rate_thresh[bucket(pktlen)]; - - /* XXX this is average rssi, should be using last value */ - rssi = ni->ni_ic->ic_node_getrssi(ni); - for (rix = rs->rs_nrates-1; rix >= 0; rix--) - if ((*thrs)[rix] < (rssi << 8)) - break; - if (rix != ra->ra_rix) { - /* update public rate */ - ni->ni_txrate = ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL; - ra->ra_rix = rix; - - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, - "RSSADAPT new rate %d (pktlen %d rssi %d)", - ni->ni_txrate, pktlen, rssi); - } - return rix; -} - -/* - * Adapt the data rate to suit the conditions. When a transmitted - * packet is dropped after RAL_RSSADAPT_RETRY_LIMIT retransmissions, - * raise the RSS threshold for transmitting packets of similar length at - * the same data rate. - */ -static void -rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra, int pktlen, int rssi) -{ - uint16_t last_thr; - uint16_t (*thrs)[IEEE80211_RATE_SIZE]; - u_int rix; - - thrs = &ra->ra_rate_thresh[bucket(pktlen)]; - - rix = ra->ra_rix; - last_thr = (*thrs)[rix]; - (*thrs)[rix] = interpolate(master_expavgctl.rc_thresh, - last_thr, (rssi << 8)); - - IEEE80211_DPRINTF(ra->ra_rs->vap, IEEE80211_MSG_RATECTL, - "RSSADAPT lower threshold for rate %d (last_thr %d new thr %d rssi %d)\n", - ra->ra_rates.rs_rates[rix + 1] & IEEE80211_RATE_VAL, - last_thr, (*thrs)[rix], rssi); -} - -static void -rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra, int pktlen, int rssi) -{ - uint16_t (*thrs)[IEEE80211_RATE_SIZE]; - uint16_t newthr, oldthr; - int rix; - - thrs = &ra->ra_rate_thresh[bucket(pktlen)]; - - rix = ra->ra_rix; - if ((*thrs)[rix + 1] > (*thrs)[rix]) { - oldthr = (*thrs)[rix + 1]; - if ((*thrs)[rix] == 0) - newthr = (rssi << 8); - else - newthr = (*thrs)[rix]; - (*thrs)[rix + 1] = interpolate(master_expavgctl.rc_decay, - oldthr, newthr); - - IEEE80211_DPRINTF(ra->ra_rs->vap, IEEE80211_MSG_RATECTL, - "RSSADAPT raise threshold for rate %d (oldthr %d newthr %d rssi %d)\n", - ra->ra_rates.rs_rates[rix + 1] & IEEE80211_RATE_VAL, - oldthr, newthr, rssi); - - ra->ra_last_raise = ticks; - } -} - -static void -rssadapt_tx_complete(const struct ieee80211vap *vap, - const struct ieee80211_node *ni, int success, void *arg1, void *arg2) -{ - struct ieee80211_rssadapt_node *ra = ni->ni_rctls; - int pktlen = *(int *)arg1, rssi = *(int *)arg2; - - if (success) { - ra->ra_nok++; - if ((ra->ra_rix + 1) < ra->ra_rates.rs_nrates && - (ticks - ra->ra_last_raise) >= ra->ra_raise_interval) - rssadapt_raise_rate(ra, pktlen, rssi); - } else { - ra->ra_nfail++; - rssadapt_lower_rate(ra, pktlen, rssi); - } -} - -static int -rssadapt_sysctl_interval(SYSCTL_HANDLER_ARGS) -{ - struct ieee80211vap *vap = arg1; - struct ieee80211_rssadapt *rs = vap->iv_rs; - int msecs = ticks_to_msecs(rs->interval); - int error; - - error = sysctl_handle_int(oidp, &msecs, 0, req); - if (error || !req->newptr) - return error; - rssadapt_setinterval(vap, msecs); - return 0; -} - -static void -rssadapt_sysctlattach(struct ieee80211vap *vap, - struct sysctl_ctx_list *ctx, struct sysctl_oid *tree) -{ - - SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "rssadapt_rate_interval", CTLTYPE_INT | CTLFLAG_RW, vap, - 0, rssadapt_sysctl_interval, "I", "rssadapt operation interval (ms)"); -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_rssadapt.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_rssadapt.h deleted file mode 100644 index d3bc711760..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_rssadapt.h +++ /dev/null @@ -1,71 +0,0 @@ -/* $FreeBSD$ */ -/* $NetBSD: ieee80211_rssadapt.h,v 1.4 2005/02/26 22:45:09 perry Exp $ */ -/*- - * Copyright (c) 2003, 2004 David Young. All rights reserved. - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * 3. The name of David Young may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David - * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_RSSADAPT_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_RSSADAPT_H_ - -/* Data-rate adaptation loosely based on "Link Adaptation Strategy - * for IEEE 802.11 WLAN via Received Signal Strength Measurement" - * by Javier del Prado Pavon and Sunghyun Choi. - */ - -/* Buckets for frames 0-128 bytes long, 129-1024, 1025-maximum. */ -#define IEEE80211_RSSADAPT_BKTS 3 -#define IEEE80211_RSSADAPT_BKT0 128 -#define IEEE80211_RSSADAPT_BKTPOWER 3 /* 2**_BKTPOWER */ - -struct ieee80211_rssadapt { - const struct ieee80211vap *vap; - int interval; /* update interval (ticks) */ -}; - -struct ieee80211_rssadapt_node { - struct ieee80211_rssadapt *ra_rs; /* backpointer */ - struct ieee80211_rateset ra_rates; /* negotiated rates */ - int ra_rix; /* current rate index */ - int ra_ticks; /* time of last update */ - int ra_last_raise; /* time of last rate raise */ - int ra_raise_interval; /* rate raise time threshold */ - - /* Tx failures in this update interval */ - uint32_t ra_nfail; - /* Tx successes in this update interval */ - uint32_t ra_nok; - /* exponential average packets/second */ - uint32_t ra_pktrate; - /* RSSI threshold for each Tx rate */ - uint16_t ra_rate_thresh[IEEE80211_RSSADAPT_BKTS] - [IEEE80211_RATE_SIZE]; -}; - -#define IEEE80211_RSSADAPT_SUCCESS 1 -#define IEEE80211_RSSADAPT_FAILURE 0 -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_RSSADAPT_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_scan.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_scan.c deleted file mode 100644 index 9fbeb91f31..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_scan.c +++ /dev/null @@ -1,1258 +0,0 @@ -/*- - * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 scanning support. - */ -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include - -#include - -struct scan_state { - struct ieee80211_scan_state base; /* public state */ - - u_int ss_iflags; /* flags used internally */ -#define ISCAN_MINDWELL 0x0001 /* min dwell time reached */ -#define ISCAN_DISCARD 0x0002 /* discard rx'd frames */ -#define ISCAN_CANCEL 0x0004 /* cancel current scan */ -#define ISCAN_ABORT 0x0008 /* end the scan immediately */ - unsigned long ss_chanmindwell; /* min dwell on curchan */ - unsigned long ss_scanend; /* time scan must stop */ - u_int ss_duration; /* duration for next scan */ - struct task ss_scan_task; /* scan execution */ - struct cv ss_scan_cv; /* scan signal */ - struct callout ss_scan_timer; /* scan timer */ -}; -#define SCAN_PRIVATE(ss) ((struct scan_state *) ss) - -/* - * Amount of time to go off-channel during a background - * scan. This value should be large enough to catch most - * ap's but short enough that we can return on-channel - * before our listen interval expires. - * - * XXX tunable - * XXX check against configured listen interval - */ -#define IEEE80211_SCAN_OFFCHANNEL msecs_to_ticks(150) - -/* - * Roaming-related defaults. RSSI thresholds are as returned by the - * driver (.5dBm). Transmit rate thresholds are IEEE rate codes (i.e - * .5M units) or MCS. - */ -/* rssi thresholds */ -#define ROAM_RSSI_11A_DEFAULT 14 /* 11a bss */ -#define ROAM_RSSI_11B_DEFAULT 14 /* 11b bss */ -#define ROAM_RSSI_11BONLY_DEFAULT 14 /* 11b-only bss */ -/* transmit rate thresholds */ -#define ROAM_RATE_11A_DEFAULT 2*12 /* 11a bss */ -#define ROAM_RATE_11B_DEFAULT 2*5 /* 11b bss */ -#define ROAM_RATE_11BONLY_DEFAULT 2*1 /* 11b-only bss */ -#define ROAM_RATE_HALF_DEFAULT 2*6 /* half-width 11a/g bss */ -#define ROAM_RATE_QUARTER_DEFAULT 2*3 /* quarter-width 11a/g bss */ -#define ROAM_MCS_11N_DEFAULT (1 | IEEE80211_RATE_MCS) /* 11n bss */ - -static void scan_curchan(struct ieee80211_scan_state *, unsigned long); -static void scan_mindwell(struct ieee80211_scan_state *); -static void scan_signal(void *); -static void scan_task(void *, int); - -void -ieee80211_scan_attach(struct ieee80211com *ic) -{ - struct scan_state *ss; - - ss = (struct scan_state *) malloc(sizeof(struct scan_state), - M_80211_SCAN, M_NOWAIT | M_ZERO); - if (ss == NULL) { - ic->ic_scan = NULL; - return; - } - callout_init_mtx(&ss->ss_scan_timer, IEEE80211_LOCK_OBJ(ic), 0); - cv_init(&ss->ss_scan_cv, "scan"); - TASK_INIT(&ss->ss_scan_task, 0, scan_task, ss); - ic->ic_scan = &ss->base; - ss->base.ss_ic = ic; - - ic->ic_scan_curchan = scan_curchan; - ic->ic_scan_mindwell = scan_mindwell; - -#if defined(__HAIKU__) - ieee80211_scan_sta_init(); -#endif -} - -void -ieee80211_scan_detach(struct ieee80211com *ic) -{ - struct ieee80211_scan_state *ss = ic->ic_scan; - - if (ss != NULL) { - IEEE80211_LOCK(ic); - SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_ABORT; - scan_signal(ss); - IEEE80211_UNLOCK(ic); - ieee80211_draintask(ic, &SCAN_PRIVATE(ss)->ss_scan_task); - callout_drain(&SCAN_PRIVATE(ss)->ss_scan_timer); - KASSERT((ic->ic_flags & IEEE80211_F_SCAN) == 0, - ("scan still running")); - if (ss->ss_ops != NULL) { - ss->ss_ops->scan_detach(ss); - ss->ss_ops = NULL; - } - ic->ic_scan = NULL; - free(SCAN_PRIVATE(ss), M_80211_SCAN); - } - - -#if defined(__HAIKU__) - ieee80211_scan_sta_uninit(); -#endif -} - -static const struct ieee80211_roamparam defroam[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_11A] = { .rssi = ROAM_RSSI_11A_DEFAULT, - .rate = ROAM_RATE_11A_DEFAULT }, - [IEEE80211_MODE_11G] = { .rssi = ROAM_RSSI_11B_DEFAULT, - .rate = ROAM_RATE_11B_DEFAULT }, - [IEEE80211_MODE_11B] = { .rssi = ROAM_RSSI_11BONLY_DEFAULT, - .rate = ROAM_RATE_11BONLY_DEFAULT }, - [IEEE80211_MODE_TURBO_A]= { .rssi = ROAM_RSSI_11A_DEFAULT, - .rate = ROAM_RATE_11A_DEFAULT }, - [IEEE80211_MODE_TURBO_G]= { .rssi = ROAM_RSSI_11A_DEFAULT, - .rate = ROAM_RATE_11A_DEFAULT }, - [IEEE80211_MODE_STURBO_A]={ .rssi = ROAM_RSSI_11A_DEFAULT, - .rate = ROAM_RATE_11A_DEFAULT }, - [IEEE80211_MODE_HALF] = { .rssi = ROAM_RSSI_11A_DEFAULT, - .rate = ROAM_RATE_HALF_DEFAULT }, - [IEEE80211_MODE_QUARTER]= { .rssi = ROAM_RSSI_11A_DEFAULT, - .rate = ROAM_RATE_QUARTER_DEFAULT }, - [IEEE80211_MODE_11NA] = { .rssi = ROAM_RSSI_11A_DEFAULT, - .rate = ROAM_MCS_11N_DEFAULT }, - [IEEE80211_MODE_11NG] = { .rssi = ROAM_RSSI_11B_DEFAULT, - .rate = ROAM_MCS_11N_DEFAULT }, -}; - -void -ieee80211_scan_vattach(struct ieee80211vap *vap) -{ - vap->iv_bgscanidle = (IEEE80211_BGSCAN_IDLE_DEFAULT*1000)/hz; - vap->iv_bgscanintvl = IEEE80211_BGSCAN_INTVAL_DEFAULT*hz; - vap->iv_scanvalid = IEEE80211_SCAN_VALID_DEFAULT*hz; - - vap->iv_roaming = IEEE80211_ROAMING_AUTO; - memcpy(vap->iv_roamparms, defroam, sizeof(defroam)); - -} - -void -ieee80211_scan_vdetach(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_state *ss; - - IEEE80211_LOCK(ic); - ss = ic->ic_scan; - if (ss != NULL && ss->ss_vap == vap) { - if (ic->ic_flags & IEEE80211_F_SCAN) { - SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_ABORT; - scan_signal(ss); - } - if (ss->ss_ops != NULL) { - ss->ss_ops->scan_detach(ss); - ss->ss_ops = NULL; - } - ss->ss_vap = NULL; - } - IEEE80211_UNLOCK(ic); -} - -/* - * Simple-minded scanner module support. - */ -static const char *scan_modnames[IEEE80211_OPMODE_MAX] = { - "wlan_scan_sta", /* IEEE80211_M_IBSS */ - "wlan_scan_sta", /* IEEE80211_M_STA */ - "wlan_scan_wds", /* IEEE80211_M_WDS */ - "wlan_scan_sta", /* IEEE80211_M_AHDEMO */ - "wlan_scan_ap", /* IEEE80211_M_HOSTAP */ - "wlan_scan_monitor", /* IEEE80211_M_MONITOR */ - "wlan_scan_sta", /* IEEE80211_M_MBSS */ -}; -static const struct ieee80211_scanner *scanners[IEEE80211_OPMODE_MAX]; - -const struct ieee80211_scanner * -ieee80211_scanner_get(enum ieee80211_opmode mode) -{ - if (mode >= IEEE80211_OPMODE_MAX) - return NULL; - if (scanners[mode] == NULL) - ieee80211_load_module(scan_modnames[mode]); - return scanners[mode]; -} - -void -ieee80211_scanner_register(enum ieee80211_opmode mode, - const struct ieee80211_scanner *scan) -{ - if (mode >= IEEE80211_OPMODE_MAX) - return; - scanners[mode] = scan; -} - -void -ieee80211_scanner_unregister(enum ieee80211_opmode mode, - const struct ieee80211_scanner *scan) -{ - if (mode >= IEEE80211_OPMODE_MAX) - return; - if (scanners[mode] == scan) - scanners[mode] = NULL; -} - -void -ieee80211_scanner_unregister_all(const struct ieee80211_scanner *scan) -{ - int m; - - for (m = 0; m < IEEE80211_OPMODE_MAX; m++) - if (scanners[m] == scan) - scanners[m] = NULL; -} - -/* - * Update common scanner state to reflect the current - * operating mode. This is called when the state machine - * is transitioned to RUN state w/o scanning--e.g. when - * operating in monitor mode. The purpose of this is to - * ensure later callbacks find ss_ops set to properly - * reflect current operating mode. - */ -static void -scan_update_locked(struct ieee80211vap *vap, - const struct ieee80211_scanner *scan) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_state *ss = ic->ic_scan; - - IEEE80211_LOCK_ASSERT(ic); - -#ifdef IEEE80211_DEBUG - if (ss->ss_vap != vap || ss->ss_ops != scan) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: current scanner is <%s:%s>, switch to <%s:%s>\n", - __func__, - ss->ss_vap != NULL ? - ss->ss_vap->iv_ifp->if_xname : "none", - ss->ss_vap != NULL ? - ieee80211_opmode_name[ss->ss_vap->iv_opmode] : "none", - vap->iv_ifp->if_xname, - ieee80211_opmode_name[vap->iv_opmode]); - } -#endif - ss->ss_vap = vap; - if (ss->ss_ops != scan) { - /* - * Switch scanners; detach old, attach new. Special - * case where a single scan module implements multiple - * policies by using different scan ops but a common - * core. We assume if the old and new attach methods - * are identical then it's ok to just change ss_ops - * and not flush the internal state of the module. - */ - if (scan == NULL || ss->ss_ops == NULL || - ss->ss_ops->scan_attach != scan->scan_attach) { - if (ss->ss_ops != NULL) - ss->ss_ops->scan_detach(ss); - if (scan != NULL && !scan->scan_attach(ss)) { - /* XXX attach failure */ - /* XXX stat+msg */ - scan = NULL; - } - } - ss->ss_ops = scan; - } -} - -static char -channel_type(const struct ieee80211_channel *c) -{ - if (IEEE80211_IS_CHAN_ST(c)) - return 'S'; - if (IEEE80211_IS_CHAN_108A(c)) - return 'T'; - if (IEEE80211_IS_CHAN_108G(c)) - return 'G'; - if (IEEE80211_IS_CHAN_HT(c)) - return 'n'; - if (IEEE80211_IS_CHAN_A(c)) - return 'a'; - if (IEEE80211_IS_CHAN_ANYG(c)) - return 'g'; - if (IEEE80211_IS_CHAN_B(c)) - return 'b'; - return 'f'; -} - -void -ieee80211_scan_dump_channels(const struct ieee80211_scan_state *ss) -{ - struct ieee80211com *ic = ss->ss_ic; - const char *sep; - int i; - - sep = ""; - for (i = ss->ss_next; i < ss->ss_last; i++) { - const struct ieee80211_channel *c = ss->ss_chans[i]; - - printf("%s%u%c", sep, ieee80211_chan2ieee(ic, c), - channel_type(c)); - sep = ", "; - } -} - -#ifdef IEEE80211_DEBUG -static void -scan_dump(struct ieee80211_scan_state *ss) -{ - struct ieee80211vap *vap = ss->ss_vap; - - if_printf(vap->iv_ifp, "scan set "); - ieee80211_scan_dump_channels(ss); - printf(" dwell min %lums max %lums\n", - ticks_to_msecs(ss->ss_mindwell), ticks_to_msecs(ss->ss_maxdwell)); -} -#endif /* IEEE80211_DEBUG */ - -static void -copy_ssid(struct ieee80211vap *vap, struct ieee80211_scan_state *ss, - int nssid, const struct ieee80211_scan_ssid ssids[]) -{ - if (nssid > IEEE80211_SCAN_MAX_SSID) { - /* XXX printf */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: too many ssid %d, ignoring all of them\n", - __func__, nssid); - return; - } - memcpy(ss->ss_ssid, ssids, nssid * sizeof(ssids[0])); - ss->ss_nssid = nssid; -} - -/* - * Start a scan unless one is already going. - */ -static int -start_scan_locked(const struct ieee80211_scanner *scan, - struct ieee80211vap *vap, int flags, u_int duration, - u_int mindwell, u_int maxdwell, - u_int nssid, const struct ieee80211_scan_ssid ssids[]) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_state *ss = ic->ic_scan; - - IEEE80211_LOCK_ASSERT(ic); - - if (ic->ic_flags & IEEE80211_F_CSAPENDING) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: scan inhibited by pending channel change\n", __func__); - } else if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: %s scan, duration %u mindwell %u maxdwell %u, desired mode %s, %s%s%s%s%s%s\n" - , __func__ - , flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive" - , duration, mindwell, maxdwell - , ieee80211_phymode_name[vap->iv_des_mode] - , flags & IEEE80211_SCAN_FLUSH ? "flush" : "append" - , flags & IEEE80211_SCAN_NOPICK ? ", nopick" : "" - , flags & IEEE80211_SCAN_NOJOIN ? ", nojoin" : "" - , flags & IEEE80211_SCAN_NOBCAST ? ", nobcast" : "" - , flags & IEEE80211_SCAN_PICK1ST ? ", pick1st" : "" - , flags & IEEE80211_SCAN_ONCE ? ", once" : "" - ); - -#ifdef __HAIKU__ - /* We never want to join if not explicitly looking for an SSID */ - if (nssid == 0 && (flags & IEEE80211_SCAN_NOJOIN) == 0) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: setting nojoin due to no configured ssid\n", __func__); - flags |= IEEE80211_SCAN_NOJOIN; - } -#endif - - scan_update_locked(vap, scan); - if (ss->ss_ops != NULL) { - if ((flags & IEEE80211_SCAN_NOSSID) == 0) - copy_ssid(vap, ss, nssid, ssids); - - /* NB: top 4 bits for internal use */ - ss->ss_flags = flags & 0xfff; - if (ss->ss_flags & IEEE80211_SCAN_ACTIVE) - vap->iv_stats.is_scan_active++; - else - vap->iv_stats.is_scan_passive++; - if (flags & IEEE80211_SCAN_FLUSH) - ss->ss_ops->scan_flush(ss); - if (flags & IEEE80211_SCAN_BGSCAN) - ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN; - - /* NB: flush frames rx'd before 1st channel change */ - SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_DISCARD; - SCAN_PRIVATE(ss)->ss_duration = duration; - ss->ss_next = 0; - ss->ss_mindwell = mindwell; - ss->ss_maxdwell = maxdwell; - /* NB: scan_start must be before the scan runtask */ - ss->ss_ops->scan_start(ss, vap); -#ifdef IEEE80211_DEBUG - if (ieee80211_msg_scan(vap)) - scan_dump(ss); -#endif /* IEEE80211_DEBUG */ - ic->ic_flags |= IEEE80211_F_SCAN; - ieee80211_runtask(ic, &SCAN_PRIVATE(ss)->ss_scan_task); - } - return 1; - } else { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: %s scan already in progress\n", __func__, - ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive"); - } - return 0; -} - -/* - * Start a scan unless one is already going. - */ -int -ieee80211_start_scan(struct ieee80211vap *vap, int flags, - u_int duration, u_int mindwell, u_int maxdwell, - u_int nssid, const struct ieee80211_scan_ssid ssids[]) -{ - struct ieee80211com *ic = vap->iv_ic; - const struct ieee80211_scanner *scan; - int result; - - scan = ieee80211_scanner_get(vap->iv_opmode); - if (scan == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: no scanner support for %s mode\n", - __func__, ieee80211_opmode_name[vap->iv_opmode]); - /* XXX stat */ - return 0; - } - - IEEE80211_LOCK(ic); - result = start_scan_locked(scan, vap, flags, duration, - mindwell, maxdwell, nssid, ssids); - IEEE80211_UNLOCK(ic); - - return result; -} - -/* - * Check the scan cache for an ap/channel to use; if that - * fails then kick off a new scan. - */ -int -ieee80211_check_scan(struct ieee80211vap *vap, int flags, - u_int duration, u_int mindwell, u_int maxdwell, - u_int nssid, const struct ieee80211_scan_ssid ssids[]) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_state *ss = ic->ic_scan; - const struct ieee80211_scanner *scan; - int result; - - scan = ieee80211_scanner_get(vap->iv_opmode); - if (scan == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: no scanner support for %s mode\n", - __func__, vap->iv_opmode); - /* XXX stat */ - return 0; - } - - /* - * Check if there's a list of scan candidates already. - * XXX want more than the ap we're currently associated with - */ - - IEEE80211_LOCK(ic); - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: %s scan, %s%s%s%s%s\n" - , __func__ - , flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive" - , flags & IEEE80211_SCAN_FLUSH ? "flush" : "append" - , flags & IEEE80211_SCAN_NOPICK ? ", nopick" : "" - , flags & IEEE80211_SCAN_NOJOIN ? ", nojoin" : "" - , flags & IEEE80211_SCAN_PICK1ST ? ", pick1st" : "" - , flags & IEEE80211_SCAN_ONCE ? ", once" : "" - ); - - if (ss->ss_ops != scan) { - /* XXX re-use cache contents? e.g. adhoc<->sta */ - flags |= IEEE80211_SCAN_FLUSH; - } - scan_update_locked(vap, scan); - if (ss->ss_ops != NULL) { - /* XXX verify ss_ops matches vap->iv_opmode */ - if ((flags & IEEE80211_SCAN_NOSSID) == 0) { - /* - * Update the ssid list and mark flags so if - * we call start_scan it doesn't duplicate work. - */ - copy_ssid(vap, ss, nssid, ssids); - flags |= IEEE80211_SCAN_NOSSID; - } - if ((ic->ic_flags & IEEE80211_F_SCAN) == 0 && - (flags & IEEE80211_SCAN_FLUSH) == 0 && - time_before(ticks, ic->ic_lastscan + vap->iv_scanvalid)) { - /* - * We're not currently scanning and the cache is - * deemed hot enough to consult. Lock out others - * by marking IEEE80211_F_SCAN while we decide if - * something is already in the scan cache we can - * use. Also discard any frames that might come - * in while temporarily marked as scanning. - */ - SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_DISCARD; - ic->ic_flags |= IEEE80211_F_SCAN; - - /* NB: need to use supplied flags in check */ - ss->ss_flags = flags & 0xff; - result = ss->ss_ops->scan_end(ss, vap); - - ic->ic_flags &= ~IEEE80211_F_SCAN; - SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_DISCARD; - if (result) { - ieee80211_notify_scan_done(vap); - IEEE80211_UNLOCK(ic); - return 1; - } - } - } - result = start_scan_locked(scan, vap, flags, duration, - mindwell, maxdwell, nssid, ssids); - IEEE80211_UNLOCK(ic); - - return result; -} - -/* - * Check the scan cache for an ap/channel to use; if that fails - * then kick off a scan using the current settings. - */ -int -ieee80211_check_scan_current(struct ieee80211vap *vap) -{ - return ieee80211_check_scan(vap, - IEEE80211_SCAN_ACTIVE, - IEEE80211_SCAN_FOREVER, 0, 0, - vap->iv_des_nssid, vap->iv_des_ssid); -} - -/* - * Restart a previous scan. If the previous scan completed - * then we start again using the existing channel list. - */ -int -ieee80211_bg_scan(struct ieee80211vap *vap, int flags) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_state *ss = ic->ic_scan; - const struct ieee80211_scanner *scan; - - scan = ieee80211_scanner_get(vap->iv_opmode); - if (scan == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: no scanner support for %s mode\n", - __func__, vap->iv_opmode); - /* XXX stat */ - return 0; - } - - IEEE80211_LOCK(ic); - if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { - u_int duration; - /* - * Go off-channel for a fixed interval that is large - * enough to catch most ap's but short enough that - * we can return on-channel before our listen interval - * expires. - */ - duration = IEEE80211_SCAN_OFFCHANNEL; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: %s scan, ticks %u duration %lu\n", __func__, - ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive", - ticks, duration); - - scan_update_locked(vap, scan); - if (ss->ss_ops != NULL) { - ss->ss_vap = vap; - /* - * A background scan does not select a new sta; it - * just refreshes the scan cache. Also, indicate - * the scan logic should follow the beacon schedule: - * we go off-channel and scan for a while, then - * return to the bss channel to receive a beacon, - * then go off-channel again. All during this time - * we notify the ap we're in power save mode. When - * the scan is complete we leave power save mode. - * If any beacon indicates there are frames pending - * for us then we drop out of power save mode - * (and background scan) automatically by way of the - * usual sta power save logic. - */ - ss->ss_flags |= IEEE80211_SCAN_NOPICK - | IEEE80211_SCAN_BGSCAN - | flags - ; - /* if previous scan completed, restart */ - if (ss->ss_next >= ss->ss_last) { - if (ss->ss_flags & IEEE80211_SCAN_ACTIVE) - vap->iv_stats.is_scan_active++; - else - vap->iv_stats.is_scan_passive++; - /* - * NB: beware of the scan cache being flushed; - * if the channel list is empty use the - * scan_start method to populate it. - */ - ss->ss_next = 0; - if (ss->ss_last != 0) - ss->ss_ops->scan_restart(ss, vap); - else { - ss->ss_ops->scan_start(ss, vap); -#ifdef IEEE80211_DEBUG - if (ieee80211_msg_scan(vap)) - scan_dump(ss); -#endif /* IEEE80211_DEBUG */ - } - } - /* NB: flush frames rx'd before 1st channel change */ - SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_DISCARD; - SCAN_PRIVATE(ss)->ss_duration = duration; - ss->ss_maxdwell = duration; - ic->ic_flags |= IEEE80211_F_SCAN; - ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN; - ieee80211_runtask(ic, &SCAN_PRIVATE(ss)->ss_scan_task); - } else { - /* XXX msg+stat */ - } - } else { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: %s scan already in progress\n", __func__, - ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive"); - } - IEEE80211_UNLOCK(ic); - - /* NB: racey, does it matter? */ - return (ic->ic_flags & IEEE80211_F_SCAN); -} - -/* - * Cancel any scan currently going on for the specified vap. - */ -void -ieee80211_cancel_scan(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_state *ss = ic->ic_scan; - - IEEE80211_LOCK(ic); - if ((ic->ic_flags & IEEE80211_F_SCAN) && - ss->ss_vap == vap && - (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) == 0) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: cancel %s scan\n", __func__, - ss->ss_flags & IEEE80211_SCAN_ACTIVE ? - "active" : "passive"); - - /* clear bg scan NOPICK and mark cancel request */ - ss->ss_flags &= ~IEEE80211_SCAN_NOPICK; - SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL; - /* wake up the scan task */ - scan_signal(ss); - } - IEEE80211_UNLOCK(ic); -} - -/* - * Cancel any scan currently going on. - */ -void -ieee80211_cancel_anyscan(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_state *ss = ic->ic_scan; - - IEEE80211_LOCK(ic); - if ((ic->ic_flags & IEEE80211_F_SCAN) && - (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) == 0) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: cancel %s scan\n", __func__, - ss->ss_flags & IEEE80211_SCAN_ACTIVE ? - "active" : "passive"); - - /* clear bg scan NOPICK and mark cancel request */ - ss->ss_flags &= ~IEEE80211_SCAN_NOPICK; - SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL; - /* wake up the scan task */ - scan_signal(ss); - } - IEEE80211_UNLOCK(ic); -} - -/* - * Public access to scan_next for drivers that manage - * scanning themselves (e.g. for firmware-based devices). - */ -void -ieee80211_scan_next(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_state *ss = ic->ic_scan; - - /* wake up the scan task */ - IEEE80211_LOCK(ic); - scan_signal(ss); - IEEE80211_UNLOCK(ic); -} - -/* - * Public access to scan_next for drivers that are not able to scan single - * channels (e.g. for firmware-based devices). - */ -void -ieee80211_scan_done(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_state *ss; - - IEEE80211_LOCK(ic); - ss = ic->ic_scan; - ss->ss_next = ss->ss_last; /* all channels are complete */ - scan_signal(ss); - IEEE80211_UNLOCK(ic); -} - -/* - * Probe the curent channel, if allowed, while scanning. - * If the channel is not marked passive-only then send - * a probe request immediately. Otherwise mark state and - * listen for beacons on the channel; if we receive something - * then we'll transmit a probe request. - */ -void -ieee80211_probe_curchan(struct ieee80211vap *vap, int force) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_state *ss = ic->ic_scan; - struct ifnet *ifp = vap->iv_ifp; - int i; - - if ((ic->ic_curchan->ic_flags & IEEE80211_CHAN_PASSIVE) && !force) { - ic->ic_flags_ext |= IEEE80211_FEXT_PROBECHAN; - return; - } - /* - * Send directed probe requests followed by any - * broadcast probe request. - * XXX remove dependence on ic/vap->iv_bss - */ - for (i = 0; i < ss->ss_nssid; i++) - ieee80211_send_probereq(vap->iv_bss, - vap->iv_myaddr, ifp->if_broadcastaddr, - ifp->if_broadcastaddr, - ss->ss_ssid[i].ssid, ss->ss_ssid[i].len); - if ((ss->ss_flags & IEEE80211_SCAN_NOBCAST) == 0) - ieee80211_send_probereq(vap->iv_bss, - vap->iv_myaddr, ifp->if_broadcastaddr, - ifp->if_broadcastaddr, - "", 0); -} - -/* - * Scan curchan. If this is an active scan and the channel - * is not marked passive then send probe request frame(s). - * Arrange for the channel change after maxdwell ticks. - */ -static void -scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) -{ - struct ieee80211vap *vap = ss->ss_vap; - - IEEE80211_LOCK(vap->iv_ic); - if (ss->ss_flags & IEEE80211_SCAN_ACTIVE) - ieee80211_probe_curchan(vap, 0); - callout_reset(&SCAN_PRIVATE(ss)->ss_scan_timer, - maxdwell, scan_signal, ss); - IEEE80211_UNLOCK(vap->iv_ic); -} - -static void -scan_signal(void *arg) -{ - struct ieee80211_scan_state *ss = (struct ieee80211_scan_state *) arg; - - IEEE80211_LOCK_ASSERT(ss->ss_ic); - - cv_signal(&SCAN_PRIVATE(ss)->ss_scan_cv); -} - -/* - * Handle mindwell requirements completed; initiate a channel - * change to the next channel asap. - */ -static void -scan_mindwell(struct ieee80211_scan_state *ss) -{ - struct ieee80211com *ic = ss->ss_ic; - - IEEE80211_LOCK(ic); - scan_signal(ss); - IEEE80211_UNLOCK(ic); -} - -static void -scan_task(void *arg, int pending) -{ -#define ISCAN_REP (ISCAN_MINDWELL | ISCAN_DISCARD) - struct ieee80211_scan_state *ss = (struct ieee80211_scan_state *) arg; - struct ieee80211vap *vap = ss->ss_vap; - struct ieee80211com *ic = ss->ss_ic; - struct ieee80211_channel *chan; - unsigned long maxdwell, scanend; - int scandone = 0; - - IEEE80211_LOCK(ic); - if (vap == NULL || (ic->ic_flags & IEEE80211_F_SCAN) == 0 || - (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_ABORT)) { - /* Cancelled before we started */ - goto done; - } - - if (ss->ss_next == ss->ss_last) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: no channels to scan\n", __func__); - goto done; - } - - if (vap->iv_opmode == IEEE80211_M_STA && - vap->iv_state == IEEE80211_S_RUN) { - if ((vap->iv_bss->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) { - /* Enable station power save mode */ - ieee80211_sta_pwrsave(vap, 1); - /* - * Use an 1ms delay so the null data frame has a chance - * to go out. - * XXX Should use M_TXCB mechanism to eliminate this. - */ - cv_timedwait(&SCAN_PRIVATE(ss)->ss_scan_cv, - IEEE80211_LOCK_OBJ(ic), hz / 1000); - if (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_ABORT) - goto done; - } - } - - scanend = ticks + SCAN_PRIVATE(ss)->ss_duration; - IEEE80211_UNLOCK(ic); - ic->ic_scan_start(ic); /* notify driver */ - IEEE80211_LOCK(ic); - - for (;;) { - scandone = (ss->ss_next >= ss->ss_last) || - (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) != 0; - if (scandone || (ss->ss_flags & IEEE80211_SCAN_GOTPICK) || - (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_ABORT) || - time_after(ticks + ss->ss_mindwell, scanend)) - break; - - chan = ss->ss_chans[ss->ss_next++]; - - /* - * Watch for truncation due to the scan end time. - */ - if (time_after(ticks + ss->ss_maxdwell, scanend)) - maxdwell = scanend - ticks; - else - maxdwell = ss->ss_maxdwell; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: chan %3d%c -> %3d%c [%s, dwell min %lums max %lums]\n", - __func__, - ieee80211_chan2ieee(ic, ic->ic_curchan), - channel_type(ic->ic_curchan), - ieee80211_chan2ieee(ic, chan), channel_type(chan), - (ss->ss_flags & IEEE80211_SCAN_ACTIVE) && - (chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0 ? - "active" : "passive", - ticks_to_msecs(ss->ss_mindwell), ticks_to_msecs(maxdwell)); - - /* - * Potentially change channel and phy mode. - */ - ic->ic_curchan = chan; - ic->ic_rt = ieee80211_get_ratetable(chan); - IEEE80211_UNLOCK(ic); - /* - * Perform the channel change and scan unlocked so the driver - * may sleep. Once set_channel returns the hardware has - * completed the channel change. - */ - ic->ic_set_channel(ic); - ieee80211_radiotap_chan_change(ic); - - /* - * Scan curchan. Drivers for "intelligent hardware" - * override ic_scan_curchan to tell the device to do - * the work. Otherwise we manage the work outselves; - * sending a probe request (as needed), and arming the - * timeout to switch channels after maxdwell ticks. - * - * scan_curchan should only pause for the time required to - * prepare/initiate the hardware for the scan (if at all), the - * below condvar is used to sleep for the channels dwell time - * and allows it to be signalled for abort. - */ - ic->ic_scan_curchan(ss, maxdwell); - IEEE80211_LOCK(ic); - - SCAN_PRIVATE(ss)->ss_chanmindwell = ticks + ss->ss_mindwell; - /* clear mindwell lock and initial channel change flush */ - SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_REP; - - if ((SCAN_PRIVATE(ss)->ss_iflags & (ISCAN_CANCEL|ISCAN_ABORT))) - continue; - - /* Wait to be signalled to scan the next channel */ - cv_wait(&SCAN_PRIVATE(ss)->ss_scan_cv, IEEE80211_LOCK_OBJ(ic)); - } - if (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_ABORT) - goto done; - - IEEE80211_UNLOCK(ic); - ic->ic_scan_end(ic); /* notify driver */ - IEEE80211_LOCK(ic); - - /* - * Record scan complete time. Note that we also do - * this when canceled so any background scan will - * not be restarted for a while. - */ - if (scandone) - ic->ic_lastscan = ticks; - /* return to the bss channel */ - if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && - ic->ic_curchan != ic->ic_bsschan) { - ieee80211_setupcurchan(ic, ic->ic_bsschan); - IEEE80211_UNLOCK(ic); - ic->ic_set_channel(ic); - ieee80211_radiotap_chan_change(ic); - IEEE80211_LOCK(ic); - } - /* clear internal flags and any indication of a pick */ - SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_REP; - ss->ss_flags &= ~IEEE80211_SCAN_GOTPICK; - - /* - * If not canceled and scan completed, do post-processing. - * If the callback function returns 0, then it wants to - * continue/restart scanning. Unfortunately we needed to - * notify the driver to end the scan above to avoid having - * rx frames alter the scan candidate list. - */ - if ((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) == 0 && - !ss->ss_ops->scan_end(ss, vap) && - (ss->ss_flags & IEEE80211_SCAN_ONCE) == 0 && - time_before(ticks + ss->ss_mindwell, scanend)) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: done, restart " - "[ticks %u, dwell min %lu scanend %lu]\n", - __func__, - ticks, ss->ss_mindwell, scanend); - ss->ss_next = 0; /* reset to begining */ - if (ss->ss_flags & IEEE80211_SCAN_ACTIVE) - vap->iv_stats.is_scan_active++; - else - vap->iv_stats.is_scan_passive++; - - ss->ss_ops->scan_restart(ss, vap); /* XXX? */ - ieee80211_runtask(ic, &SCAN_PRIVATE(ss)->ss_scan_task); - IEEE80211_UNLOCK(ic); - return; - } - - /* past here, scandone is ``true'' if not in bg mode */ - if ((ss->ss_flags & IEEE80211_SCAN_BGSCAN) == 0) - scandone = 1; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: %s, [ticks %u, dwell min %lu scanend %lu]\n", - __func__, scandone ? "done" : "stopped", - ticks, ss->ss_mindwell, scanend); - - /* - * Clear the SCAN bit first in case frames are - * pending on the station power save queue. If - * we defer this then the dispatch of the frames - * may generate a request to cancel scanning. - */ -done: - ic->ic_flags &= ~IEEE80211_F_SCAN; - /* - * Drop out of power save mode when a scan has - * completed. If this scan was prematurely terminated - * because it is a background scan then don't notify - * the ap; we'll either return to scanning after we - * receive the beacon frame or we'll drop out of power - * save mode because the beacon indicates we have frames - * waiting for us. - */ - if (scandone) { - ieee80211_sta_pwrsave(vap, 0); - if (ss->ss_next >= ss->ss_last) { - ieee80211_notify_scan_done(vap); - ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN; - } - } - SCAN_PRIVATE(ss)->ss_iflags &= ~(ISCAN_CANCEL|ISCAN_ABORT); - ss->ss_flags &= ~(IEEE80211_SCAN_ONCE | IEEE80211_SCAN_PICK1ST); - IEEE80211_UNLOCK(ic); -#undef ISCAN_REP -} - -#ifdef IEEE80211_DEBUG -static void -dump_country(const uint8_t *ie) -{ - const struct ieee80211_country_ie *cie = - (const struct ieee80211_country_ie *) ie; - int i, nbands, schan, nchan; - - if (cie->len < 3) { - printf(" ", cie->len); - return; - } - printf(" country [%c%c%c", cie->cc[0], cie->cc[1], cie->cc[2]); - nbands = (cie->len - 3) / sizeof(cie->band[0]); - for (i = 0; i < nbands; i++) { - schan = cie->band[i].schan; - nchan = cie->band[i].nchan; - if (nchan != 1) - printf(" %u-%u,%u", schan, schan + nchan-1, - cie->band[i].maxtxpwr); - else - printf(" %u,%u", schan, cie->band[i].maxtxpwr); - } - printf("]"); -} - -static void -dump_probe_beacon(uint8_t subtype, int isnew, - const uint8_t mac[IEEE80211_ADDR_LEN], - const struct ieee80211_scanparams *sp, int rssi) -{ - - printf("[%s] %s%s on chan %u (bss chan %u) ", - ether_sprintf(mac), isnew ? "new " : "", - ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT], - sp->chan, sp->bchan); - ieee80211_print_essid(sp->ssid + 2, sp->ssid[1]); - printf(" rssi %d\n", rssi); - - if (isnew) { - printf("[%s] caps 0x%x bintval %u erp 0x%x", - ether_sprintf(mac), sp->capinfo, sp->bintval, sp->erp); - if (sp->country != NULL) - dump_country(sp->country); - printf("\n"); - } -} -#endif /* IEEE80211_DEBUG */ - -/* - * Process a beacon or probe response frame. - */ -void -ieee80211_add_scan(struct ieee80211vap *vap, - const struct ieee80211_scanparams *sp, - const struct ieee80211_frame *wh, - int subtype, int rssi, int noise) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_state *ss = ic->ic_scan; - - /* XXX locking */ - /* - * Frames received during startup are discarded to avoid - * using scan state setup on the initial entry to the timer - * callback. This can occur because the device may enable - * rx prior to our doing the initial channel change in the - * timer routine. - */ - if (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_DISCARD) - return; -#ifdef IEEE80211_DEBUG - if (ieee80211_msg_scan(vap) && (ic->ic_flags & IEEE80211_F_SCAN)) - dump_probe_beacon(subtype, 1, wh->i_addr2, sp, rssi); -#endif - if (ss->ss_ops != NULL && - ss->ss_ops->scan_add(ss, sp, wh, subtype, rssi, noise)) { - /* - * If we've reached the min dwell time terminate - * the timer so we'll switch to the next channel. - */ - if ((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_MINDWELL) == 0 && - time_after_eq(ticks, SCAN_PRIVATE(ss)->ss_chanmindwell)) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: chan %3d%c min dwell met (%u > %lu)\n", - __func__, - ieee80211_chan2ieee(ic, ic->ic_curchan), - channel_type(ic->ic_curchan), - ticks, SCAN_PRIVATE(ss)->ss_chanmindwell); - SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_MINDWELL; - /* - * NB: trigger at next clock tick or wait for the - * hardware. - */ - ic->ic_scan_mindwell(ss); - } - } -} - -/* - * Timeout/age scan cache entries; called from sta timeout - * timer (XXX should be self-contained). - */ -void -ieee80211_scan_timeout(struct ieee80211com *ic) -{ - struct ieee80211_scan_state *ss = ic->ic_scan; - - if (ss->ss_ops != NULL) - ss->ss_ops->scan_age(ss); -} - -/* - * Mark a scan cache entry after a successful associate. - */ -void -ieee80211_scan_assoc_success(struct ieee80211vap *vap, const uint8_t mac[]) -{ - struct ieee80211_scan_state *ss = vap->iv_ic->ic_scan; - - if (ss->ss_ops != NULL) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_SCAN, - mac, "%s", __func__); - ss->ss_ops->scan_assoc_success(ss, mac); - } -} - -/* - * Demerit a scan cache entry after failing to associate. - */ -void -ieee80211_scan_assoc_fail(struct ieee80211vap *vap, - const uint8_t mac[], int reason) -{ - struct ieee80211_scan_state *ss = vap->iv_ic->ic_scan; - - if (ss->ss_ops != NULL) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_SCAN, mac, - "%s: reason %u", __func__, reason); - ss->ss_ops->scan_assoc_fail(ss, mac, reason); - } -} - -/* - * Iterate over the contents of the scan cache. - */ -void -ieee80211_scan_iterate(struct ieee80211vap *vap, - ieee80211_scan_iter_func *f, void *arg) -{ - struct ieee80211_scan_state *ss = vap->iv_ic->ic_scan; - - if (ss->ss_ops != NULL) - ss->ss_ops->scan_iterate(ss, f, arg); -} - -/* - * Flush the contents of the scan cache. - */ -void -ieee80211_scan_flush(struct ieee80211vap *vap) -{ - struct ieee80211_scan_state *ss = vap->iv_ic->ic_scan; - - if (ss->ss_ops != NULL && ss->ss_vap == vap) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s\n", __func__); - ss->ss_ops->scan_flush(ss); - } -} - -/* - * Check the scan cache for an ap/channel to use; if that - * fails then kick off a new scan. - */ -struct ieee80211_channel * -ieee80211_scan_pickchannel(struct ieee80211com *ic, int flags) -{ - struct ieee80211_scan_state *ss = ic->ic_scan; - - IEEE80211_LOCK_ASSERT(ic); - - if (ss == NULL || ss->ss_ops == NULL || ss->ss_vap == NULL) { - /* XXX printf? */ - return NULL; - } - if (ss->ss_ops->scan_pickchan == NULL) { - IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN, - "%s: scan module does not support picking a channel, " - "opmode %s\n", __func__, ss->ss_vap->iv_opmode); - return NULL; - } - return ss->ss_ops->scan_pickchan(ss, flags); -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_scan.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_scan.h deleted file mode 100644 index 55df7a9d02..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_scan.h +++ /dev/null @@ -1,300 +0,0 @@ -/*- - * Copyright (c) 2005-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_SCAN_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_SCAN_H_ - -/* - * 802.11 scanning support. - * - * Scanning is the procedure by which a station locates a bss to join - * (infrastructure/ibss mode), or a channel to use (when operating as - * an ap or ibss master). Scans are either "active" or "passive". An - * active scan causes one or more probe request frames to be sent on - * visiting each channel. A passive request causes each channel in the - * scan set to be visited but no frames to be transmitted; the station - * only listens for traffic. Note that active scanning may still need - * to listen for traffic before sending probe request frames depending - * on regulatory constraints; the 802.11 layer handles this by generating - * a callback when scanning on a ``passive channel'' when the - * IEEE80211_FEXT_PROBECHAN flag is set. - * - * A scan operation involves constructing a set of channels to inspect - * (the scan set), visiting each channel and collecting information - * (e.g. what bss are present), and then analyzing the results to make - * decisions like which bss to join. This process needs to be as fast - * as possible so we do things like intelligently construct scan sets - * and dwell on a channel only as long as necessary. The scan code also - * maintains a cache of recent scan results and uses it to bypass scanning - * whenever possible. The scan cache is also used to enable roaming - * between access points when operating in infrastructure mode. - * - * Scanning is handled with pluggable modules that implement "policy" - * per-operating mode. The core scanning support provides an - * instrastructure to support these modules and exports a common api - * to the rest of the 802.11 layer. Policy modules decide what - * channels to visit, what state to record to make decisions (e.g. ap - * mode scanning for auto channel selection keeps significantly less - * state than sta mode scanning for an ap to associate to), and selects - * the final station/channel to return as the result of a scan. - * - * Scanning is done synchronously when initially bringing a vap to an - * operational state and optionally in the background to maintain the - * scan cache for doing roaming and rogue ap monitoring. Scanning is - * not tied to the 802.11 state machine that governs vaps though there - * is linkage to the IEEE80211_SCAN state. Only one vap at a time may - * be scanning; this scheduling policy is handled in ieee80211_new_state - * and is invisible to the scanning code. -*/ -#define IEEE80211_SCAN_MAX IEEE80211_CHAN_MAX - -struct ieee80211_scanner; /* scan policy state */ - -struct ieee80211_scan_ssid { - int len; /* length in bytes */ - uint8_t ssid[IEEE80211_NWID_LEN]; /* ssid contents */ -}; -#define IEEE80211_SCAN_MAX_SSID 1 /* max # ssid's to probe */ - -/* - * Scan state visible to the 802.11 layer. Scan parameters and - * results are stored in this data structure. The ieee80211_scan_state - * structure is extended with space that is maintained private to - * the core scanning support. We allocate one instance and link it - * to the ieee80211com structure; then share it between all associated - * vaps. We could allocate multiple of these, e.g. to hold multiple - * scan results, but this is sufficient for current needs. - */ -struct ieee80211_scan_state { - struct ieee80211vap *ss_vap; - struct ieee80211com *ss_ic; - const struct ieee80211_scanner *ss_ops; /* policy hookup, see below */ - void *ss_priv; /* scanner private state */ - uint16_t ss_flags; -#define IEEE80211_SCAN_NOPICK 0x0001 /* scan only, no selection */ -#define IEEE80211_SCAN_ACTIVE 0x0002 /* active scan (probe req) */ -#define IEEE80211_SCAN_PICK1ST 0x0004 /* ``hey sailor'' mode */ -#define IEEE80211_SCAN_BGSCAN 0x0008 /* bg scan, exit ps at end */ -#define IEEE80211_SCAN_ONCE 0x0010 /* do one complete pass */ -#define IEEE80211_SCAN_NOBCAST 0x0020 /* no broadcast probe req */ -#define IEEE80211_SCAN_NOJOIN 0x0040 /* no auto-sequencing */ -#define IEEE80211_SCAN_GOTPICK 0x1000 /* got candidate, can stop */ - uint8_t ss_nssid; /* # ssid's to probe/match */ - struct ieee80211_scan_ssid ss_ssid[IEEE80211_SCAN_MAX_SSID]; - /* ssid's to probe/match */ - /* ordered channel set */ - struct ieee80211_channel *ss_chans[IEEE80211_SCAN_MAX]; - uint16_t ss_next; /* ix of next chan to scan */ - uint16_t ss_last; /* ix+1 of last chan to scan */ - unsigned long ss_mindwell; /* min dwell on channel */ - unsigned long ss_maxdwell; /* max dwell on channel */ -}; - -/* - * The upper 16 bits of the flags word is used to communicate - * information to the scanning code that is NOT recorded in - * ss_flags. It might be better to split this stuff out into - * a separate variable to avoid confusion. - */ -#define IEEE80211_SCAN_FLUSH 0x00010000 /* flush candidate table */ -#define IEEE80211_SCAN_NOSSID 0x80000000 /* don't update ssid list */ - -struct ieee80211com; -void ieee80211_scan_attach(struct ieee80211com *); -void ieee80211_scan_detach(struct ieee80211com *); -void ieee80211_scan_vattach(struct ieee80211vap *); -void ieee80211_scan_vdetach(struct ieee80211vap *); - -void ieee80211_scan_dump_channels(const struct ieee80211_scan_state *); - -#define IEEE80211_SCAN_FOREVER 0x7fffffff -int ieee80211_start_scan(struct ieee80211vap *, int flags, - u_int duration, u_int mindwell, u_int maxdwell, - u_int nssid, const struct ieee80211_scan_ssid ssids[]); -int ieee80211_check_scan(struct ieee80211vap *, int flags, - u_int duration, u_int mindwell, u_int maxdwell, - u_int nssid, const struct ieee80211_scan_ssid ssids[]); -int ieee80211_check_scan_current(struct ieee80211vap *); -int ieee80211_bg_scan(struct ieee80211vap *, int); -void ieee80211_cancel_scan(struct ieee80211vap *); -void ieee80211_cancel_anyscan(struct ieee80211vap *); -void ieee80211_scan_next(struct ieee80211vap *); -void ieee80211_scan_done(struct ieee80211vap *); -void ieee80211_probe_curchan(struct ieee80211vap *, int); -struct ieee80211_channel *ieee80211_scan_pickchannel(struct ieee80211com *, int); - -struct ieee80211_scanparams; -void ieee80211_add_scan(struct ieee80211vap *, - const struct ieee80211_scanparams *, - const struct ieee80211_frame *, - int subtype, int rssi, int noise); -void ieee80211_scan_timeout(struct ieee80211com *); - -void ieee80211_scan_assoc_success(struct ieee80211vap *, - const uint8_t mac[IEEE80211_ADDR_LEN]); -enum { - IEEE80211_SCAN_FAIL_TIMEOUT = 1, /* no response to mgmt frame */ - IEEE80211_SCAN_FAIL_STATUS = 2 /* negative response to " " */ -}; -void ieee80211_scan_assoc_fail(struct ieee80211vap *, - const uint8_t mac[IEEE80211_ADDR_LEN], int reason); -void ieee80211_scan_flush(struct ieee80211vap *); - -struct ieee80211_scan_entry; -typedef void ieee80211_scan_iter_func(void *, - const struct ieee80211_scan_entry *); -void ieee80211_scan_iterate(struct ieee80211vap *, - ieee80211_scan_iter_func, void *); -enum { - IEEE80211_BPARSE_BADIELEN = 0x01, /* ie len past end of frame */ - IEEE80211_BPARSE_RATES_INVALID = 0x02, /* invalid RATES ie */ - IEEE80211_BPARSE_XRATES_INVALID = 0x04, /* invalid XRATES ie */ - IEEE80211_BPARSE_SSID_INVALID = 0x08, /* invalid SSID ie */ - IEEE80211_BPARSE_CHAN_INVALID = 0x10, /* invalid FH/DSPARMS chan */ - IEEE80211_BPARSE_OFFCHAN = 0x20, /* DSPARMS chan != curchan */ - IEEE80211_BPARSE_BINTVAL_INVALID= 0x40, /* invalid beacon interval */ - IEEE80211_BPARSE_CSA_INVALID = 0x80, /* invalid CSA ie */ -}; - -/* - * Parameters supplied when adding/updating an entry in a - * scan cache. Pointer variables should be set to NULL - * if no data is available. Pointer references can be to - * local data; any information that is saved will be copied. - * All multi-byte values must be in host byte order. - */ -struct ieee80211_scanparams { - uint8_t status; /* bitmask of IEEE80211_BPARSE_* */ - uint8_t chan; /* channel # from FH/DSPARMS */ - uint8_t bchan; /* curchan's channel # */ - uint8_t fhindex; - uint16_t fhdwell; /* FHSS dwell interval */ - uint16_t capinfo; /* 802.11 capabilities */ - uint16_t erp; /* NB: 0x100 indicates ie present */ - uint16_t bintval; - uint8_t timoff; - uint8_t *ies; /* all captured ies */ - size_t ies_len; /* length of all captured ies */ - uint8_t *tim; - uint8_t *tstamp; - uint8_t *country; - uint8_t *ssid; - uint8_t *rates; - uint8_t *xrates; - uint8_t *doth; - uint8_t *wpa; - uint8_t *rsn; - uint8_t *wme; - uint8_t *htcap; - uint8_t *htinfo; - uint8_t *ath; - uint8_t *tdma; - uint8_t *csa; - uint8_t *meshid; - uint8_t *meshconf; - uint8_t *spare[3]; -}; - -/* - * Scan cache entry format used when exporting data from a policy - * module; this data may be represented some other way internally. - */ -struct ieee80211_scan_entry { - uint8_t se_macaddr[IEEE80211_ADDR_LEN]; - uint8_t se_bssid[IEEE80211_ADDR_LEN]; - /* XXX can point inside se_ies */ - uint8_t se_ssid[2+IEEE80211_NWID_LEN]; - uint8_t se_rates[2+IEEE80211_RATE_MAXSIZE]; - uint8_t se_xrates[2+IEEE80211_RATE_MAXSIZE]; - union { - uint8_t data[8]; - u_int64_t tsf; - } se_tstamp; /* from last rcv'd beacon */ - uint16_t se_intval; /* beacon interval (host byte order) */ - uint16_t se_capinfo; /* capabilities (host byte order) */ - struct ieee80211_channel *se_chan;/* channel where sta found */ - uint16_t se_timoff; /* byte offset to TIM ie */ - uint16_t se_fhdwell; /* FH only (host byte order) */ - uint8_t se_fhindex; /* FH only */ - uint8_t se_dtimperiod; /* DTIM period */ - uint16_t se_erp; /* ERP from beacon/probe resp */ - int8_t se_rssi; /* avg'd recv ssi */ - int8_t se_noise; /* noise floor */ - uint8_t se_cc[2]; /* captured country code */ - uint8_t se_meshid[2+IEEE80211_MESHID_LEN]; - struct ieee80211_ies se_ies; /* captured ie's */ - u_int se_age; /* age of entry (0 on create) */ -}; - -/* - * Template for an in-kernel scan policy module. - * Modules register with the scanning code and are - * typically loaded as needed. - */ -struct ieee80211_scanner { - const char *scan_name; /* printable name */ - int (*scan_attach)(struct ieee80211_scan_state *); - int (*scan_detach)(struct ieee80211_scan_state *); - int (*scan_start)(struct ieee80211_scan_state *, - struct ieee80211vap *); - int (*scan_restart)(struct ieee80211_scan_state *, - struct ieee80211vap *); - int (*scan_cancel)(struct ieee80211_scan_state *, - struct ieee80211vap *); - int (*scan_end)(struct ieee80211_scan_state *, - struct ieee80211vap *); - int (*scan_flush)(struct ieee80211_scan_state *); - struct ieee80211_channel *(*scan_pickchan)( - struct ieee80211_scan_state *, int); - /* add an entry to the cache */ - int (*scan_add)(struct ieee80211_scan_state *, - const struct ieee80211_scanparams *, - const struct ieee80211_frame *, - int subtype, int rssi, int noise); - /* age and/or purge entries in the cache */ - void (*scan_age)(struct ieee80211_scan_state *); - /* note that association failed for an entry */ - void (*scan_assoc_fail)(struct ieee80211_scan_state *, - const uint8_t macaddr[IEEE80211_ADDR_LEN], - int reason); - /* note that association succeed for an entry */ - void (*scan_assoc_success)(struct ieee80211_scan_state *, - const uint8_t macaddr[IEEE80211_ADDR_LEN]); - /* iterate over entries in the scan cache */ - void (*scan_iterate)(struct ieee80211_scan_state *, - ieee80211_scan_iter_func *, void *); - void (*scan_spare0)(void); - void (*scan_spare1)(void); - void (*scan_spare2)(void); - void (*scan_spare4)(void); -}; -void ieee80211_scanner_register(enum ieee80211_opmode, - const struct ieee80211_scanner *); -void ieee80211_scanner_unregister(enum ieee80211_opmode, - const struct ieee80211_scanner *); -void ieee80211_scanner_unregister_all(const struct ieee80211_scanner *); -const struct ieee80211_scanner *ieee80211_scanner_get(enum ieee80211_opmode); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_SCAN_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_scan_sta.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_scan_sta.c deleted file mode 100644 index 11bd3f56c0..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_scan_sta.c +++ /dev/null @@ -1,1961 +0,0 @@ -/*- - * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * IEEE 802.11 station scanning support. - */ -#include "opt_wlan.h" - -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#ifdef IEEE80211_SUPPORT_TDMA -#include -#endif -#ifdef IEEE80211_SUPPORT_MESH -#include -#endif - -#include - -/* - * Parameters for managing cache entries: - * - * o a station with STA_FAILS_MAX failures is not considered - * when picking a candidate - * o a station that hasn't had an update in STA_PURGE_SCANS - * (background) scans is discarded - * o after STA_FAILS_AGE seconds we clear the failure count - */ -#define STA_FAILS_MAX 2 /* assoc failures before ignored */ -#define STA_FAILS_AGE (2*60) /* time before clearing fails (secs) */ -#define STA_PURGE_SCANS 2 /* age for purging entries (scans) */ - -/* XXX tunable */ -#define STA_RSSI_MIN 8 /* min acceptable rssi */ -#define STA_RSSI_MAX 40 /* max rssi for comparison */ - -struct sta_entry { - struct ieee80211_scan_entry base; - TAILQ_ENTRY(sta_entry) se_list; - LIST_ENTRY(sta_entry) se_hash; - uint8_t se_fails; /* failure to associate count */ - uint8_t se_seen; /* seen during current scan */ - uint8_t se_notseen; /* not seen in previous scans */ - uint8_t se_flags; -#define STA_DEMOTE11B 0x01 /* match w/ demoted 11b chan */ - uint32_t se_avgrssi; /* LPF rssi state */ - unsigned long se_lastupdate; /* time of last update */ - unsigned long se_lastfail; /* time of last failure */ - unsigned long se_lastassoc; /* time of last association */ - u_int se_scangen; /* iterator scan gen# */ - u_int se_countrygen; /* gen# of last cc notify */ -}; - -#define STA_HASHSIZE 32 -/* simple hash is enough for variation of macaddr */ -#define STA_HASH(addr) \ - (((const uint8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % STA_HASHSIZE) - -#define MAX_IEEE_CHAN 256 /* max acceptable IEEE chan # */ -CTASSERT(MAX_IEEE_CHAN >= 256); - -struct sta_table { - ieee80211_scan_table_lock_t st_lock; /* on scan table */ - TAILQ_HEAD(, sta_entry) st_entry; /* all entries */ - LIST_HEAD(, sta_entry) st_hash[STA_HASHSIZE]; - struct mtx st_scanlock; /* on st_scaniter */ - u_int st_scaniter; /* gen# for iterator */ - u_int st_scangen; /* scan generation # */ - int st_newscan; - /* ap-related state */ - int st_maxrssi[MAX_IEEE_CHAN]; -}; - -static void sta_flush_table(struct sta_table *); -/* - * match_bss returns a bitmask describing if an entry is suitable - * for use. If non-zero the entry was deemed not suitable and it's - * contents explains why. The following flags are or'd to to this - * mask and can be used to figure out why the entry was rejected. - */ -#define MATCH_CHANNEL 0x00001 /* channel mismatch */ -#define MATCH_CAPINFO 0x00002 /* capabilities mismatch, e.g. no ess */ -#define MATCH_PRIVACY 0x00004 /* privacy mismatch */ -#define MATCH_RATE 0x00008 /* rate set mismatch */ -#define MATCH_SSID 0x00010 /* ssid mismatch */ -#define MATCH_BSSID 0x00020 /* bssid mismatch */ -#define MATCH_FAILS 0x00040 /* too many failed auth attempts */ -#define MATCH_NOTSEEN 0x00080 /* not seen in recent scans */ -#define MATCH_RSSI 0x00100 /* rssi deemed too low to use */ -#define MATCH_CC 0x00200 /* country code mismatch */ -#define MATCH_TDMA_NOIE 0x00400 /* no TDMA ie */ -#define MATCH_TDMA_NOTMASTER 0x00800 /* not TDMA master */ -#define MATCH_TDMA_NOSLOT 0x01000 /* all TDMA slots occupied */ -#define MATCH_TDMA_LOCAL 0x02000 /* local address */ -#define MATCH_TDMA_VERSION 0x04000 /* protocol version mismatch */ -#define MATCH_MESH_NOID 0x10000 /* no MESHID ie */ -#define MATCH_MESHID 0x20000 /* meshid mismatch */ -static int match_bss(struct ieee80211vap *, - const struct ieee80211_scan_state *, struct sta_entry *, int); -static void adhoc_age(struct ieee80211_scan_state *); - -static __inline int -isocmp(const uint8_t cc1[], const uint8_t cc2[]) -{ - return (cc1[0] == cc2[0] && cc1[1] == cc2[1]); -} - -/* number of references from net80211 layer */ -static int nrefs = 0; -/* - * Module glue. - */ -IEEE80211_SCANNER_MODULE(sta, 1); - -/* - * Attach prior to any scanning work. - */ -static int -sta_attach(struct ieee80211_scan_state *ss) -{ - struct sta_table *st; - - st = (struct sta_table *) malloc(sizeof(struct sta_table), - M_80211_SCAN, M_NOWAIT | M_ZERO); - if (st == NULL) - return 0; - IEEE80211_SCAN_TABLE_LOCK_INIT(st, "scantable"); - mtx_init(&st->st_scanlock, "scangen", "802.11 scangen", MTX_DEF); - TAILQ_INIT(&st->st_entry); - ss->ss_priv = st; - nrefs++; /* NB: we assume caller locking */ - return 1; -} - -/* - * Cleanup any private state. - */ -static int -sta_detach(struct ieee80211_scan_state *ss) -{ - struct sta_table *st = ss->ss_priv; - - if (st != NULL) { - sta_flush_table(st); - IEEE80211_SCAN_TABLE_LOCK_DESTROY(st); - mtx_destroy(&st->st_scanlock); - free(st, M_80211_SCAN); - KASSERT(nrefs > 0, ("imbalanced attach/detach")); - nrefs--; /* NB: we assume caller locking */ - } - return 1; -} - -/* - * Flush all per-scan state. - */ -static int -sta_flush(struct ieee80211_scan_state *ss) -{ - struct sta_table *st = ss->ss_priv; - - IEEE80211_SCAN_TABLE_LOCK(st); - sta_flush_table(st); - IEEE80211_SCAN_TABLE_UNLOCK(st); - ss->ss_last = 0; - return 0; -} - -/* - * Flush all entries in the scan cache. - */ -static void -sta_flush_table(struct sta_table *st) -{ - struct sta_entry *se, *next; - - TAILQ_FOREACH_SAFE(se, &st->st_entry, se_list, next) { - TAILQ_REMOVE(&st->st_entry, se, se_list); - LIST_REMOVE(se, se_hash); - ieee80211_ies_cleanup(&se->base.se_ies); - free(se, M_80211_SCAN); - } - memset(st->st_maxrssi, 0, sizeof(st->st_maxrssi)); -} - -/* - * Process a beacon or probe response frame; create an - * entry in the scan cache or update any previous entry. - */ -static int -sta_add(struct ieee80211_scan_state *ss, - const struct ieee80211_scanparams *sp, - const struct ieee80211_frame *wh, - int subtype, int rssi, int noise) -{ -#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) -#define PICK1ST(_ss) \ - ((ss->ss_flags & (IEEE80211_SCAN_PICK1ST | IEEE80211_SCAN_GOTPICK)) == \ - IEEE80211_SCAN_PICK1ST) - struct sta_table *st = ss->ss_priv; - const uint8_t *macaddr = wh->i_addr2; - struct ieee80211vap *vap = ss->ss_vap; - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_channel *c; - struct sta_entry *se; - struct ieee80211_scan_entry *ise; - int hash; - - hash = STA_HASH(macaddr); - - IEEE80211_SCAN_TABLE_LOCK(st); - LIST_FOREACH(se, &st->st_hash[hash], se_hash) - if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr)) - goto found; - se = (struct sta_entry *) malloc(sizeof(struct sta_entry), - M_80211_SCAN, M_NOWAIT | M_ZERO); - if (se == NULL) { - IEEE80211_SCAN_TABLE_UNLOCK(st); - return 0; - } - se->se_scangen = st->st_scaniter-1; - se->se_avgrssi = IEEE80211_RSSI_DUMMY_MARKER; - IEEE80211_ADDR_COPY(se->base.se_macaddr, macaddr); - TAILQ_INSERT_TAIL(&st->st_entry, se, se_list); - LIST_INSERT_HEAD(&st->st_hash[hash], se, se_hash); -found: - ise = &se->base; - /* XXX ap beaconing multiple ssid w/ same bssid */ - if (sp->ssid[1] != 0 && - (ISPROBE(subtype) || ise->se_ssid[1] == 0)) - memcpy(ise->se_ssid, sp->ssid, 2+sp->ssid[1]); - KASSERT(sp->rates[1] <= IEEE80211_RATE_MAXSIZE, - ("rate set too large: %u", sp->rates[1])); - memcpy(ise->se_rates, sp->rates, 2+sp->rates[1]); - if (sp->xrates != NULL) { - /* XXX validate xrates[1] */ - KASSERT(sp->xrates[1] <= IEEE80211_RATE_MAXSIZE, - ("xrate set too large: %u", sp->xrates[1])); - memcpy(ise->se_xrates, sp->xrates, 2+sp->xrates[1]); - } else - ise->se_xrates[1] = 0; - IEEE80211_ADDR_COPY(ise->se_bssid, wh->i_addr3); - if ((sp->status & IEEE80211_BPARSE_OFFCHAN) == 0) { - /* - * Record rssi data using extended precision LPF filter. - * - * NB: use only on-channel data to insure we get a good - * estimate of the signal we'll see when associated. - */ - IEEE80211_RSSI_LPF(se->se_avgrssi, rssi); - ise->se_rssi = IEEE80211_RSSI_GET(se->se_avgrssi); - ise->se_noise = noise; - } - memcpy(ise->se_tstamp.data, sp->tstamp, sizeof(ise->se_tstamp)); - ise->se_intval = sp->bintval; - ise->se_capinfo = sp->capinfo; -#ifdef IEEE80211_SUPPORT_MESH - if (sp->meshid != NULL && sp->meshid[1] != 0) - memcpy(ise->se_meshid, sp->meshid, 2+sp->meshid[1]); -#endif - /* - * Beware of overriding se_chan for frames seen - * off-channel; this can cause us to attempt an - * association on the wrong channel. - */ - if (sp->status & IEEE80211_BPARSE_OFFCHAN) { - /* - * Off-channel, locate the home/bss channel for the sta - * using the value broadcast in the DSPARMS ie. We know - * sp->chan has this value because it's used to calculate - * IEEE80211_BPARSE_OFFCHAN. - */ - c = ieee80211_find_channel_byieee(ic, sp->chan, - ic->ic_curchan->ic_flags); - if (c != NULL) { - ise->se_chan = c; - } else if (ise->se_chan == NULL) { - /* should not happen, pick something */ - ise->se_chan = ic->ic_curchan; - } - } else - ise->se_chan = ic->ic_curchan; - if (IEEE80211_IS_CHAN_HT(ise->se_chan) && sp->htcap == NULL) { - /* Demote legacy networks to a non-HT channel. */ - c = ieee80211_find_channel(ic, ise->se_chan->ic_freq, - ise->se_chan->ic_flags & ~IEEE80211_CHAN_HT); - KASSERT(c != NULL, - ("no legacy channel %u", ise->se_chan->ic_ieee)); - ise->se_chan = c; - } - ise->se_fhdwell = sp->fhdwell; - ise->se_fhindex = sp->fhindex; - ise->se_erp = sp->erp; - ise->se_timoff = sp->timoff; - if (sp->tim != NULL) { - const struct ieee80211_tim_ie *tim = - (const struct ieee80211_tim_ie *) sp->tim; - ise->se_dtimperiod = tim->tim_period; - } - if (sp->country != NULL) { - const struct ieee80211_country_ie *cie = - (const struct ieee80211_country_ie *) sp->country; - /* - * If 11d is enabled and we're attempting to join a bss - * that advertises it's country code then compare our - * current settings to what we fetched from the country ie. - * If our country code is unspecified or different then - * dispatch an event to user space that identifies the - * country code so our regdomain config can be changed. - */ - /* XXX only for STA mode? */ - if ((IEEE80211_IS_CHAN_11D(ise->se_chan) || - (vap->iv_flags_ext & IEEE80211_FEXT_DOTD)) && - (ic->ic_regdomain.country == CTRY_DEFAULT || - !isocmp(cie->cc, ic->ic_regdomain.isocc))) { - /* only issue one notify event per scan */ - if (se->se_countrygen != st->st_scangen) { - ieee80211_notify_country(vap, ise->se_bssid, - cie->cc); - se->se_countrygen = st->st_scangen; - } - } - ise->se_cc[0] = cie->cc[0]; - ise->se_cc[1] = cie->cc[1]; - } - /* NB: no need to setup ie ptrs; they are not (currently) used */ - (void) ieee80211_ies_init(&ise->se_ies, sp->ies, sp->ies_len); - - /* clear failure count after STA_FAIL_AGE passes */ - if (se->se_fails && (ticks - se->se_lastfail) > STA_FAILS_AGE*hz) { - se->se_fails = 0; - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_SCAN, macaddr, - "%s: fails %u", __func__, se->se_fails); - } - - se->se_lastupdate = ticks; /* update time */ - se->se_seen = 1; - se->se_notseen = 0; - - KASSERT(sizeof(sp->bchan) == 1, ("bchan size")); - if (rssi > st->st_maxrssi[sp->bchan]) - st->st_maxrssi[sp->bchan] = rssi; - - IEEE80211_SCAN_TABLE_UNLOCK(st); - - /* - * If looking for a quick choice and nothing's - * been found check here. - */ - if (PICK1ST(ss) && match_bss(vap, ss, se, IEEE80211_MSG_SCAN) == 0) - ss->ss_flags |= IEEE80211_SCAN_GOTPICK; - - return 1; -#undef PICK1ST -#undef ISPROBE -} - -/* - * Check if a channel is excluded by user request. - */ -static int -isexcluded(struct ieee80211vap *vap, const struct ieee80211_channel *c) -{ - return (isclr(vap->iv_ic->ic_chan_active, c->ic_ieee) || - (vap->iv_des_chan != IEEE80211_CHAN_ANYC && - c->ic_freq != vap->iv_des_chan->ic_freq)); -} - -static struct ieee80211_channel * -find11gchannel(struct ieee80211com *ic, int i, int freq) -{ - struct ieee80211_channel *c; - int j; - - /* - * The normal ordering in the channel list is b channel - * immediately followed by g so optimize the search for - * this. We'll still do a full search just in case. - */ - for (j = i+1; j < ic->ic_nchans; j++) { - c = &ic->ic_channels[j]; - if (c->ic_freq == freq && IEEE80211_IS_CHAN_G(c)) - return c; - } - for (j = 0; j < i; j++) { - c = &ic->ic_channels[j]; - if (c->ic_freq == freq && IEEE80211_IS_CHAN_G(c)) - return c; - } - return NULL; -} - -static const u_int chanflags[IEEE80211_MODE_MAX] = { - [IEEE80211_MODE_AUTO] = IEEE80211_CHAN_B, - [IEEE80211_MODE_11A] = IEEE80211_CHAN_A, - [IEEE80211_MODE_11B] = IEEE80211_CHAN_B, - [IEEE80211_MODE_11G] = IEEE80211_CHAN_G, - [IEEE80211_MODE_FH] = IEEE80211_CHAN_FHSS, - /* check base channel */ - [IEEE80211_MODE_TURBO_A] = IEEE80211_CHAN_A, - [IEEE80211_MODE_TURBO_G] = IEEE80211_CHAN_G, - [IEEE80211_MODE_STURBO_A] = IEEE80211_CHAN_ST, - [IEEE80211_MODE_HALF] = IEEE80211_CHAN_HALF, - [IEEE80211_MODE_QUARTER] = IEEE80211_CHAN_QUARTER, - /* check legacy */ - [IEEE80211_MODE_11NA] = IEEE80211_CHAN_A, - [IEEE80211_MODE_11NG] = IEEE80211_CHAN_G, -}; - -static void -add_channels(struct ieee80211vap *vap, - struct ieee80211_scan_state *ss, - enum ieee80211_phymode mode, const uint16_t freq[], int nfreq) -{ -#define N(a) (sizeof(a) / sizeof(a[0])) - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_channel *c, *cg; - u_int modeflags; - int i; - - KASSERT(mode < N(chanflags), ("Unexpected mode %u", mode)); - modeflags = chanflags[mode]; - for (i = 0; i < nfreq; i++) { - if (ss->ss_last >= IEEE80211_SCAN_MAX) - break; - - c = ieee80211_find_channel(ic, freq[i], modeflags); - if (c == NULL || isexcluded(vap, c)) - continue; - if (mode == IEEE80211_MODE_AUTO) { - /* - * XXX special-case 11b/g channels so we select - * the g channel if both are present. - */ - if (IEEE80211_IS_CHAN_B(c) && - (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) - c = cg; - } - ss->ss_chans[ss->ss_last++] = c; - } -#undef N -} - -struct scanlist { - uint16_t mode; - uint16_t count; - const uint16_t *list; -}; - -static int -checktable(const struct scanlist *scan, const struct ieee80211_channel *c) -{ - int i; - - for (; scan->list != NULL; scan++) { - for (i = 0; i < scan->count; i++) - if (scan->list[i] == c->ic_freq) - return 1; - } - return 0; -} - -static int -onscanlist(const struct ieee80211_scan_state *ss, - const struct ieee80211_channel *c) -{ - int i; - - for (i = 0; i < ss->ss_last; i++) - if (ss->ss_chans[i] == c) - return 1; - return 0; -} - -static void -sweepchannels(struct ieee80211_scan_state *ss, struct ieee80211vap *vap, - const struct scanlist table[]) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_channel *c; - int i; - - for (i = 0; i < ic->ic_nchans; i++) { - if (ss->ss_last >= IEEE80211_SCAN_MAX) - break; - - c = &ic->ic_channels[i]; - /* - * Ignore dynamic turbo channels; we scan them - * in normal mode (i.e. not boosted). Likewise - * for HT channels, they get scanned using - * legacy rates. - */ - if (IEEE80211_IS_CHAN_DTURBO(c) || IEEE80211_IS_CHAN_HT(c)) - continue; - - /* - * If a desired mode was specified, scan only - * channels that satisfy that constraint. - */ - if (vap->iv_des_mode != IEEE80211_MODE_AUTO && - vap->iv_des_mode != ieee80211_chan2mode(c)) - continue; - - /* - * Skip channels excluded by user request. - */ - if (isexcluded(vap, c)) - continue; - - /* - * Add the channel unless it is listed in the - * fixed scan order tables. This insures we - * don't sweep back in channels we filtered out - * above. - */ - if (checktable(table, c)) - continue; - - /* Add channel to scanning list. */ - ss->ss_chans[ss->ss_last++] = c; - } - /* - * Explicitly add any desired channel if: - * - not already on the scan list - * - allowed by any desired mode constraint - * - there is space in the scan list - * This allows the channel to be used when the filtering - * mechanisms would otherwise elide it (e.g HT, turbo). - */ - c = vap->iv_des_chan; - if (c != IEEE80211_CHAN_ANYC && - !onscanlist(ss, c) && - (vap->iv_des_mode == IEEE80211_MODE_AUTO || - vap->iv_des_mode == ieee80211_chan2mode(c)) && - ss->ss_last < IEEE80211_SCAN_MAX) - ss->ss_chans[ss->ss_last++] = c; -} - -static void -makescanlist(struct ieee80211_scan_state *ss, struct ieee80211vap *vap, - const struct scanlist table[]) -{ - const struct scanlist *scan; - enum ieee80211_phymode mode; - - ss->ss_last = 0; - /* - * Use the table of ordered channels to construct the list - * of channels for scanning. Any channels in the ordered - * list not in the master list will be discarded. - */ - for (scan = table; scan->list != NULL; scan++) { - mode = scan->mode; - if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { - /* - * If a desired mode was specified, scan only - * channels that satisfy that constraint. - */ - if (vap->iv_des_mode != mode) { - /* - * The scan table marks 2.4Ghz channels as b - * so if the desired mode is 11g, then use - * the 11b channel list but upgrade the mode. - */ - if (vap->iv_des_mode != IEEE80211_MODE_11G || - mode != IEEE80211_MODE_11B) - continue; - mode = IEEE80211_MODE_11G; /* upgrade */ - } - } else { - /* - * This lets add_channels upgrade an 11b channel - * to 11g if available. - */ - if (mode == IEEE80211_MODE_11B) - mode = IEEE80211_MODE_AUTO; - } -#ifdef IEEE80211_F_XR - /* XR does not operate on turbo channels */ - if ((vap->iv_flags & IEEE80211_F_XR) && - (mode == IEEE80211_MODE_TURBO_A || - mode == IEEE80211_MODE_TURBO_G || - mode == IEEE80211_MODE_STURBO_A)) - continue; -#endif - /* - * Add the list of the channels; any that are not - * in the master channel list will be discarded. - */ - add_channels(vap, ss, mode, scan->list, scan->count); - } - - /* - * Add the channels from the ic that are not present - * in the table. - */ - sweepchannels(ss, vap, table); -} - -static const uint16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64, 36, 40, 44, 48 */ -{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 }; -static const uint16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */ -{ 5170, 5190, 5210, 5230 }; -static const uint16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */ -{ 2412, 2437, 2462, 2442, 2472 }; -static const uint16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */ -{ 5745, 5765, 5785, 5805, 5825 }; -static const uint16_t rcl7[] = /* 11 ETSI channel: 100,104,108,112,116,120,124,128,132,136,140 */ -{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 }; -static const uint16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */ -{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 }; -static const uint16_t rcl9[] = /* 2.4Ghz ch: 14 */ -{ 2484 }; -static const uint16_t rcl10[] = /* Added Korean channels 2312-2372 */ -{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 }; -static const uint16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */ -{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 }; -#ifdef ATH_TURBO_SCAN -static const uint16_t rcl5[] = /* 3 static turbo channels */ -{ 5210, 5250, 5290 }; -static const uint16_t rcl6[] = /* 2 static turbo channels */ -{ 5760, 5800 }; -static const uint16_t rcl6x[] = /* 4 FCC3 turbo channels */ -{ 5540, 5580, 5620, 5660 }; -static const uint16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */ -{ 2437 }; -static const uint16_t rcl13[] = /* dynamic Turbo channels */ -{ 5200, 5240, 5280, 5765, 5805 }; -#endif /* ATH_TURBO_SCAN */ - -#define X(a) .count = sizeof(a)/sizeof(a[0]), .list = a - -static const struct scanlist staScanTable[] = { - { IEEE80211_MODE_11B, X(rcl3) }, - { IEEE80211_MODE_11A, X(rcl1) }, - { IEEE80211_MODE_11A, X(rcl2) }, - { IEEE80211_MODE_11B, X(rcl8) }, - { IEEE80211_MODE_11B, X(rcl9) }, - { IEEE80211_MODE_11A, X(rcl4) }, -#ifdef ATH_TURBO_SCAN - { IEEE80211_MODE_STURBO_A, X(rcl5) }, - { IEEE80211_MODE_STURBO_A, X(rcl6) }, - { IEEE80211_MODE_TURBO_A, X(rcl6x) }, - { IEEE80211_MODE_TURBO_A, X(rcl13) }, -#endif /* ATH_TURBO_SCAN */ - { IEEE80211_MODE_11A, X(rcl7) }, - { IEEE80211_MODE_11B, X(rcl10) }, - { IEEE80211_MODE_11A, X(rcl11) }, -#ifdef ATH_TURBO_SCAN - { IEEE80211_MODE_TURBO_G, X(rcl12) }, -#endif /* ATH_TURBO_SCAN */ - { .list = NULL } -}; - -/* - * Start a station-mode scan by populating the channel list. - */ -static int -sta_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) -{ - struct sta_table *st = ss->ss_priv; - - makescanlist(ss, vap, staScanTable); - - if (ss->ss_mindwell == 0) - ss->ss_mindwell = msecs_to_ticks(20); /* 20ms */ - if (ss->ss_maxdwell == 0) - ss->ss_maxdwell = msecs_to_ticks(200); /* 200ms */ - - st->st_scangen++; - st->st_newscan = 1; - - return 0; -} - -/* - * Restart a scan, typically a bg scan but can - * also be a fg scan that came up empty. - */ -static int -sta_restart(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) -{ - struct sta_table *st = ss->ss_priv; - - st->st_newscan = 1; - return 0; -} - -/* - * Cancel an ongoing scan. - */ -static int -sta_cancel(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) -{ - return 0; -} - -/* unalligned little endian access */ -#define LE_READ_2(p) \ - ((uint16_t) \ - ((((const uint8_t *)(p))[0] ) | \ - (((const uint8_t *)(p))[1] << 8))) - -/* - * Demote any supplied 11g channel to 11b. There should - * always be an 11b channel but we check anyway... - */ -static struct ieee80211_channel * -demote11b(struct ieee80211vap *vap, struct ieee80211_channel *chan) -{ - struct ieee80211_channel *c; - - if (IEEE80211_IS_CHAN_ANYG(chan) && - vap->iv_des_mode == IEEE80211_MODE_AUTO) { - c = ieee80211_find_channel(vap->iv_ic, chan->ic_freq, - (chan->ic_flags &~ (IEEE80211_CHAN_PUREG | IEEE80211_CHAN_G)) | - IEEE80211_CHAN_B); - if (c != NULL) - chan = c; - } - return chan; -} - -static int -maxrate(const struct ieee80211_scan_entry *se) -{ - const struct ieee80211_ie_htcap *htcap = - (const struct ieee80211_ie_htcap *) se->se_ies.htcap_ie; - int rmax, r, i, txstream; - uint16_t caps; - uint8_t txparams; - - rmax = 0; - if (htcap != NULL) { - /* - * HT station; inspect supported MCS and then adjust - * rate by channel width. - */ - txparams = htcap->hc_mcsset[12]; - if (txparams & 0x3) { - /* - * TX MCS parameters defined and not equal to RX, - * extract the number of spartial streams and - * map it to the highest MCS rate. - */ - txstream = ((txparams & 0xc) >> 2) + 1; - i = txstream * 8 - 1; - } else - for (i = 31; i >= 0 && isclr(htcap->hc_mcsset, i); i--); - if (i >= 0) { - caps = LE_READ_2(&htcap->hc_cap); - if ((caps & IEEE80211_HTCAP_CHWIDTH40) && - (caps & IEEE80211_HTCAP_SHORTGI40)) - rmax = ieee80211_htrates[i].ht40_rate_400ns; - else if (caps & IEEE80211_HTCAP_CHWIDTH40) - rmax = ieee80211_htrates[i].ht40_rate_800ns; - else if (caps & IEEE80211_HTCAP_SHORTGI20) - rmax = ieee80211_htrates[i].ht20_rate_400ns; - else - rmax = ieee80211_htrates[i].ht20_rate_800ns; - } - } - for (i = 0; i < se->se_rates[1]; i++) { - r = se->se_rates[2+i] & IEEE80211_RATE_VAL; - if (r > rmax) - rmax = r; - } - for (i = 0; i < se->se_xrates[1]; i++) { - r = se->se_xrates[2+i] & IEEE80211_RATE_VAL; - if (r > rmax) - rmax = r; - } - return rmax; -} - -/* - * Compare the capabilities of two entries and decide which is - * more desirable (return >0 if a is considered better). Note - * that we assume compatibility/usability has already been checked - * so we don't need to (e.g. validate whether privacy is supported). - * Used to select the best scan candidate for association in a BSS. - */ -static int -sta_compare(const struct sta_entry *a, const struct sta_entry *b) -{ -#define PREFER(_a,_b,_what) do { \ - if (((_a) ^ (_b)) & (_what)) \ - return ((_a) & (_what)) ? 1 : -1; \ -} while (0) - int maxa, maxb; - int8_t rssia, rssib; - int weight; - - /* privacy support */ - PREFER(a->base.se_capinfo, b->base.se_capinfo, - IEEE80211_CAPINFO_PRIVACY); - - /* compare count of previous failures */ - weight = b->se_fails - a->se_fails; - if (abs(weight) > 1) - return weight; - - /* - * Compare rssi. If the two are considered equivalent - * then fallback to other criteria. We threshold the - * comparisons to avoid selecting an ap purely by rssi - * when both values may be good but one ap is otherwise - * more desirable (e.g. an 11b-only ap with stronger - * signal than an 11g ap). - */ - rssia = MIN(a->base.se_rssi, STA_RSSI_MAX); - rssib = MIN(b->base.se_rssi, STA_RSSI_MAX); - if (abs(rssib - rssia) < 5) { - /* best/max rate preferred if signal level close enough XXX */ - maxa = maxrate(&a->base); - maxb = maxrate(&b->base); - if (maxa != maxb) - return maxa - maxb; - /* XXX use freq for channel preference */ - /* for now just prefer 5Ghz band to all other bands */ - PREFER(IEEE80211_IS_CHAN_5GHZ(a->base.se_chan), - IEEE80211_IS_CHAN_5GHZ(b->base.se_chan), 1); - } - /* all things being equal, use signal level */ - return a->base.se_rssi - b->base.se_rssi; -#undef PREFER -} - -/* - * Check rate set suitability and return the best supported rate. - * XXX inspect MCS for HT - */ -static int -check_rate(struct ieee80211vap *vap, const struct ieee80211_channel *chan, - const struct ieee80211_scan_entry *se) -{ -#define RV(v) ((v) & IEEE80211_RATE_VAL) - const struct ieee80211_rateset *srs; - int i, j, nrs, r, okrate, badrate, fixedrate, ucastrate; - const uint8_t *rs; - - okrate = badrate = 0; - - srs = ieee80211_get_suprates(vap->iv_ic, chan); - nrs = se->se_rates[1]; - rs = se->se_rates+2; - /* XXX MCS */ - ucastrate = vap->iv_txparms[ieee80211_chan2mode(chan)].ucastrate; - fixedrate = IEEE80211_FIXED_RATE_NONE; -again: - for (i = 0; i < nrs; i++) { - r = RV(rs[i]); - badrate = r; - /* - * Check any fixed rate is included. - */ - if (r == ucastrate) - fixedrate = r; - /* - * Check against our supported rates. - */ - for (j = 0; j < srs->rs_nrates; j++) - if (r == RV(srs->rs_rates[j])) { - if (r > okrate) /* NB: track max */ - okrate = r; - break; - } - - if (j == srs->rs_nrates && (rs[i] & IEEE80211_RATE_BASIC)) { - /* - * Don't try joining a BSS, if we don't support - * one of its basic rates. - */ - okrate = 0; - goto back; - } - } - if (rs == se->se_rates+2) { - /* scan xrates too; sort of an algol68-style for loop */ - nrs = se->se_xrates[1]; - rs = se->se_xrates+2; - goto again; - } - -back: - if (okrate == 0 || ucastrate != fixedrate) - return badrate | IEEE80211_RATE_BASIC; - else - return RV(okrate); -#undef RV -} - -static __inline int -match_id(const uint8_t *ie, const uint8_t *val, int len) -{ - return (ie[1] == len && memcmp(ie+2, val, len) == 0); -} - -static int -match_ssid(const uint8_t *ie, - int nssid, const struct ieee80211_scan_ssid ssids[]) -{ - int i; - - for (i = 0; i < nssid; i++) { - if (match_id(ie, ssids[i].ssid, ssids[i].len)) - return 1; - } - return 0; -} - -#ifdef IEEE80211_SUPPORT_TDMA -static int -tdma_isfull(const struct ieee80211_tdma_param *tdma) -{ - int slot, slotcnt; - - slotcnt = tdma->tdma_slotcnt; - for (slot = slotcnt-1; slot >= 0; slot--) - if (isclr(tdma->tdma_inuse, slot)) - return 0; - return 1; -} -#endif /* IEEE80211_SUPPORT_TDMA */ - -/* - * Test a scan candidate for suitability/compatibility. - */ -static int -match_bss(struct ieee80211vap *vap, - const struct ieee80211_scan_state *ss, struct sta_entry *se0, - int debug) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_scan_entry *se = &se0->base; - uint8_t rate; - int fail; - - fail = 0; - if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, se->se_chan))) - fail |= MATCH_CHANNEL; - /* - * NB: normally the desired mode is used to construct - * the channel list, but it's possible for the scan - * cache to include entries for stations outside this - * list so we check the desired mode here to weed them - * out. - */ - if (vap->iv_des_mode != IEEE80211_MODE_AUTO && - (se->se_chan->ic_flags & IEEE80211_CHAN_ALLTURBO) != - chanflags[vap->iv_des_mode]) - fail |= MATCH_CHANNEL; - if (vap->iv_opmode == IEEE80211_M_IBSS) { - if ((se->se_capinfo & IEEE80211_CAPINFO_IBSS) == 0) - fail |= MATCH_CAPINFO; -#ifdef IEEE80211_SUPPORT_TDMA - } else if (vap->iv_opmode == IEEE80211_M_AHDEMO) { - /* - * Adhoc demo network setup shouldn't really be scanning - * but just in case skip stations operating in IBSS or - * BSS mode. - */ - if (se->se_capinfo & (IEEE80211_CAPINFO_IBSS|IEEE80211_CAPINFO_ESS)) - fail |= MATCH_CAPINFO; - /* - * TDMA operation cannot coexist with a normal 802.11 network; - * skip if IBSS or ESS capabilities are marked and require - * the beacon have a TDMA ie present. - */ - if (vap->iv_caps & IEEE80211_C_TDMA) { - const struct ieee80211_tdma_param *tdma = - (const struct ieee80211_tdma_param *)se->se_ies.tdma_ie; - const struct ieee80211_tdma_state *ts = vap->iv_tdma; - - if (tdma == NULL) - fail |= MATCH_TDMA_NOIE; - else if (tdma->tdma_version != ts->tdma_version) - fail |= MATCH_TDMA_VERSION; - else if (tdma->tdma_slot != 0) - fail |= MATCH_TDMA_NOTMASTER; - else if (tdma_isfull(tdma)) - fail |= MATCH_TDMA_NOSLOT; -#if 0 - else if (ieee80211_local_address(se->se_macaddr)) - fail |= MATCH_TDMA_LOCAL; -#endif - } -#endif /* IEEE80211_SUPPORT_TDMA */ -#ifdef IEEE80211_SUPPORT_MESH - } else if (vap->iv_opmode == IEEE80211_M_MBSS) { - const struct ieee80211_mesh_state *ms = vap->iv_mesh; - /* - * Mesh nodes have IBSS & ESS bits in capinfo turned off - * and two special ie's that must be present. - */ - if (se->se_capinfo & (IEEE80211_CAPINFO_IBSS|IEEE80211_CAPINFO_ESS)) - fail |= MATCH_CAPINFO; - else if (se->se_meshid[0] != IEEE80211_ELEMID_MESHID) - fail |= MATCH_MESH_NOID; - else if (ms->ms_idlen != 0 && - match_id(se->se_meshid, ms->ms_id, ms->ms_idlen)) - fail |= MATCH_MESHID; -#endif - } else { - if ((se->se_capinfo & IEEE80211_CAPINFO_ESS) == 0) - fail |= MATCH_CAPINFO; - /* - * If 11d is enabled and we're attempting to join a bss - * that advertises it's country code then compare our - * current settings to what we fetched from the country ie. - * If our country code is unspecified or different then do - * not attempt to join the bss. We should have already - * dispatched an event to user space that identifies the - * new country code so our regdomain config should match. - */ - if ((IEEE80211_IS_CHAN_11D(se->se_chan) || - (vap->iv_flags_ext & IEEE80211_FEXT_DOTD)) && - se->se_cc[0] != 0 && - (ic->ic_regdomain.country == CTRY_DEFAULT || - !isocmp(se->se_cc, ic->ic_regdomain.isocc))) - fail |= MATCH_CC; - } - if (vap->iv_flags & IEEE80211_F_PRIVACY) { - if ((se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0) - fail |= MATCH_PRIVACY; - } else { - /* XXX does this mean privacy is supported or required? */ - if (se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) - fail |= MATCH_PRIVACY; - } - se0->se_flags &= ~STA_DEMOTE11B; - rate = check_rate(vap, se->se_chan, se); - if (rate & IEEE80211_RATE_BASIC) { - fail |= MATCH_RATE; - /* - * An 11b-only ap will give a rate mismatch if there is an - * OFDM fixed tx rate for 11g. Try downgrading the channel - * in the scan list to 11b and retry the rate check. - */ - if (IEEE80211_IS_CHAN_ANYG(se->se_chan)) { - rate = check_rate(vap, demote11b(vap, se->se_chan), se); - if ((rate & IEEE80211_RATE_BASIC) == 0) { - fail &= ~MATCH_RATE; - se0->se_flags |= STA_DEMOTE11B; - } - } - } else if (rate < 2*24) { - /* - * This is an 11b-only ap. Check the desired mode in - * case that needs to be honored (mode 11g filters out - * 11b-only ap's). Otherwise force any 11g channel used - * in scanning to be demoted. - * - * NB: we cheat a bit here by looking at the max rate; - * we could/should check the rates. - */ - if (!(vap->iv_des_mode == IEEE80211_MODE_AUTO || - vap->iv_des_mode == IEEE80211_MODE_11B)) - fail |= MATCH_RATE; - else - se0->se_flags |= STA_DEMOTE11B; - } - if (ss->ss_nssid != 0 && - !match_ssid(se->se_ssid, ss->ss_nssid, ss->ss_ssid)) - fail |= MATCH_SSID; - if ((vap->iv_flags & IEEE80211_F_DESBSSID) && - !IEEE80211_ADDR_EQ(vap->iv_des_bssid, se->se_bssid)) - fail |= MATCH_BSSID; - if (se0->se_fails >= STA_FAILS_MAX) - fail |= MATCH_FAILS; - if (se0->se_notseen >= STA_PURGE_SCANS) - fail |= MATCH_NOTSEEN; - if (se->se_rssi < STA_RSSI_MIN) - fail |= MATCH_RSSI; -#ifdef IEEE80211_DEBUG - if (ieee80211_msg(vap, debug)) { - printf(" %c %s", - fail & MATCH_FAILS ? '=' : - fail & MATCH_NOTSEEN ? '^' : - fail & MATCH_CC ? '$' : -#ifdef IEEE80211_SUPPORT_TDMA - fail & MATCH_TDMA_NOIE ? '&' : - fail & MATCH_TDMA_VERSION ? 'v' : - fail & MATCH_TDMA_NOTMASTER ? 's' : - fail & MATCH_TDMA_NOSLOT ? 'f' : - fail & MATCH_TDMA_LOCAL ? 'l' : -#endif - fail & MATCH_MESH_NOID ? 'm' : - fail ? '-' : '+', ether_sprintf(se->se_macaddr)); - printf(" %s%c", ether_sprintf(se->se_bssid), - fail & MATCH_BSSID ? '!' : ' '); - printf(" %3d%c", ieee80211_chan2ieee(ic, se->se_chan), - fail & MATCH_CHANNEL ? '!' : ' '); - printf(" %+4d%c", se->se_rssi, fail & MATCH_RSSI ? '!' : ' '); - printf(" %2dM%c", (rate & IEEE80211_RATE_VAL) / 2, - fail & MATCH_RATE ? '!' : ' '); - printf(" %4s%c", - (se->se_capinfo & IEEE80211_CAPINFO_ESS) ? "ess" : - (se->se_capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" : "", - fail & MATCH_CAPINFO ? '!' : ' '); - printf(" %3s%c ", - (se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) ? - "wep" : "no", - fail & MATCH_PRIVACY ? '!' : ' '); - ieee80211_print_essid(se->se_ssid+2, se->se_ssid[1]); - printf("%s\n", fail & (MATCH_SSID | MATCH_MESHID) ? "!" : ""); - } -#endif - return fail; -} - -static void -sta_update_notseen(struct sta_table *st) -{ - struct sta_entry *se; - - IEEE80211_SCAN_TABLE_LOCK(st); - TAILQ_FOREACH(se, &st->st_entry, se_list) { - /* - * If seen the reset and don't bump the count; - * otherwise bump the ``not seen'' count. Note - * that this insures that stations for which we - * see frames while not scanning but not during - * this scan will not be penalized. - */ - if (se->se_seen) - se->se_seen = 0; - else - se->se_notseen++; - } - IEEE80211_SCAN_TABLE_UNLOCK(st); -} - -static void -sta_dec_fails(struct sta_table *st) -{ - struct sta_entry *se; - - IEEE80211_SCAN_TABLE_LOCK(st); - TAILQ_FOREACH(se, &st->st_entry, se_list) - if (se->se_fails) - se->se_fails--; - IEEE80211_SCAN_TABLE_UNLOCK(st); -} - -static struct sta_entry * -select_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap, int debug) -{ - struct sta_table *st = ss->ss_priv; - struct sta_entry *se, *selbs = NULL; - - IEEE80211_DPRINTF(vap, debug, " %s\n", - "macaddr bssid chan rssi rate flag wep essid"); - IEEE80211_SCAN_TABLE_LOCK(st); - TAILQ_FOREACH(se, &st->st_entry, se_list) { - ieee80211_ies_expand(&se->base.se_ies); - if (match_bss(vap, ss, se, debug) == 0) { - if (selbs == NULL) - selbs = se; - else if (sta_compare(se, selbs) > 0) - selbs = se; - } - } - IEEE80211_SCAN_TABLE_UNLOCK(st); - - return selbs; -} - -/* - * Pick an ap or ibss network to join or find a channel - * to use to start an ibss network. - */ -static int -sta_pick_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) -{ - struct sta_table *st = ss->ss_priv; - struct sta_entry *selbs; - struct ieee80211_channel *chan; - - KASSERT(vap->iv_opmode == IEEE80211_M_STA, - ("wrong mode %u", vap->iv_opmode)); - - if (st->st_newscan) { - sta_update_notseen(st); - st->st_newscan = 0; - } - if (ss->ss_flags & IEEE80211_SCAN_NOPICK) { - /* - * Manual/background scan, don't select+join the - * bss, just return. The scanning framework will - * handle notification that this has completed. - */ - ss->ss_flags &= ~IEEE80211_SCAN_NOPICK; - return 1; - } - /* - * Automatic sequencing; look for a candidate and - * if found join the network. - */ - /* NB: unlocked read should be ok */ - if (TAILQ_FIRST(&st->st_entry) == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: no scan candidate\n", __func__); - if (ss->ss_flags & IEEE80211_SCAN_NOJOIN) - return 0; -notfound: - /* - * If nothing suitable was found decrement - * the failure counts so entries will be - * reconsidered the next time around. We - * really want to do this only for sta's - * where we've previously had some success. - */ - sta_dec_fails(st); - st->st_newscan = 1; - return 0; /* restart scan */ - } - selbs = select_bss(ss, vap, IEEE80211_MSG_SCAN); - if (ss->ss_flags & IEEE80211_SCAN_NOJOIN) - return (selbs != NULL); - if (selbs == NULL) - goto notfound; - chan = selbs->base.se_chan; - if (selbs->se_flags & STA_DEMOTE11B) - chan = demote11b(vap, chan); - if (!ieee80211_sta_join(vap, chan, &selbs->base)) - goto notfound; - return 1; /* terminate scan */ -} - -/* - * Lookup an entry in the scan cache. We assume we're - * called from the bottom half or such that we don't need - * to block the bottom half so that it's safe to return - * a reference to an entry w/o holding the lock on the table. - */ -static struct sta_entry * -sta_lookup(struct sta_table *st, const uint8_t macaddr[IEEE80211_ADDR_LEN]) -{ - struct sta_entry *se; - int hash = STA_HASH(macaddr); - - IEEE80211_SCAN_TABLE_LOCK(st); - LIST_FOREACH(se, &st->st_hash[hash], se_hash) - if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr)) - break; - IEEE80211_SCAN_TABLE_UNLOCK(st); - - return se; /* NB: unlocked */ -} - -static void -sta_roam_check(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni = vap->iv_bss; - struct sta_table *st = ss->ss_priv; - enum ieee80211_phymode mode; - struct sta_entry *se, *selbs; - uint8_t roamRate, curRate, ucastRate; - int8_t roamRssi, curRssi; - - se = sta_lookup(st, ni->ni_macaddr); - if (se == NULL) { - /* XXX something is wrong */ - return; - } - - mode = ieee80211_chan2mode(ic->ic_bsschan); - roamRate = vap->iv_roamparms[mode].rate; - roamRssi = vap->iv_roamparms[mode].rssi; - ucastRate = vap->iv_txparms[mode].ucastrate; - /* NB: the most up to date rssi is in the node, not the scan cache */ - curRssi = ic->ic_node_getrssi(ni); - if (ucastRate == IEEE80211_FIXED_RATE_NONE) { - curRate = ni->ni_txrate; - roamRate &= IEEE80211_RATE_VAL; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ROAM, - "%s: currssi %d currate %u roamrssi %d roamrate %u\n", - __func__, curRssi, curRate, roamRssi, roamRate); - } else { - curRate = roamRate; /* NB: insure compare below fails */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ROAM, - "%s: currssi %d roamrssi %d\n", __func__, curRssi, roamRssi); - } - /* - * Check if a new ap should be used and switch. - * XXX deauth current ap - */ - if (curRate < roamRate || curRssi < roamRssi) { - if (time_after(ticks, ic->ic_lastscan + vap->iv_scanvalid)) { - /* - * Scan cache contents are too old; force a scan now - * if possible so we have current state to make a - * decision with. We don't kick off a bg scan if - * we're using dynamic turbo and boosted or if the - * channel is busy. - * XXX force immediate switch on scan complete - */ - if (!IEEE80211_IS_CHAN_DTURBO(ic->ic_curchan) && - time_after(ticks, ic->ic_lastdata + vap->iv_bgscanidle)) - ieee80211_bg_scan(vap, 0); - return; - } - se->base.se_rssi = curRssi; - selbs = select_bss(ss, vap, IEEE80211_MSG_ROAM); - if (selbs != NULL && selbs != se) { - struct ieee80211_channel *chan; - - IEEE80211_DPRINTF(vap, - IEEE80211_MSG_ROAM | IEEE80211_MSG_DEBUG, - "%s: ROAM: curRate %u, roamRate %u, " - "curRssi %d, roamRssi %d\n", __func__, - curRate, roamRate, curRssi, roamRssi); - - chan = selbs->base.se_chan; - if (selbs->se_flags & STA_DEMOTE11B) - chan = demote11b(vap, chan); - (void) ieee80211_sta_join(vap, chan, &selbs->base); - } - } -} - -/* - * Age entries in the scan cache. - * XXX also do roaming since it's convenient - */ -static void -sta_age(struct ieee80211_scan_state *ss) -{ - struct ieee80211vap *vap = ss->ss_vap; - - adhoc_age(ss); - /* - * If rate control is enabled check periodically to see if - * we should roam from our current connection to one that - * might be better. This only applies when we're operating - * in sta mode and automatic roaming is set. - * XXX defer if busy - * XXX repeater station - * XXX do when !bgscan? - */ - KASSERT(vap->iv_opmode == IEEE80211_M_STA, - ("wrong mode %u", vap->iv_opmode)); - if (vap->iv_roaming == IEEE80211_ROAMING_AUTO && - (vap->iv_flags & IEEE80211_F_BGSCAN) && - vap->iv_state >= IEEE80211_S_RUN) - /* XXX vap is implicit */ - sta_roam_check(ss, vap); -} - -/* - * Iterate over the entries in the scan cache, invoking - * the callback function on each one. - */ -static void -sta_iterate(struct ieee80211_scan_state *ss, - ieee80211_scan_iter_func *f, void *arg) -{ - struct sta_table *st = ss->ss_priv; - struct sta_entry *se; - u_int gen; - - mtx_lock(&st->st_scanlock); - gen = st->st_scaniter++; -restart: - IEEE80211_SCAN_TABLE_LOCK(st); - TAILQ_FOREACH(se, &st->st_entry, se_list) { - if (se->se_scangen != gen) { - se->se_scangen = gen; - /* update public state */ - se->base.se_age = ticks - se->se_lastupdate; - IEEE80211_SCAN_TABLE_UNLOCK(st); - (*f)(arg, &se->base); - goto restart; - } - } - IEEE80211_SCAN_TABLE_UNLOCK(st); - - mtx_unlock(&st->st_scanlock); -} - -static void -sta_assoc_fail(struct ieee80211_scan_state *ss, - const uint8_t macaddr[IEEE80211_ADDR_LEN], int reason) -{ - struct sta_table *st = ss->ss_priv; - struct sta_entry *se; - - se = sta_lookup(st, macaddr); - if (se != NULL) { - se->se_fails++; - se->se_lastfail = ticks; - IEEE80211_NOTE_MAC(ss->ss_vap, IEEE80211_MSG_SCAN, - macaddr, "%s: reason %u fails %u", - __func__, reason, se->se_fails); - } -} - -static void -sta_assoc_success(struct ieee80211_scan_state *ss, - const uint8_t macaddr[IEEE80211_ADDR_LEN]) -{ - struct sta_table *st = ss->ss_priv; - struct sta_entry *se; - - se = sta_lookup(st, macaddr); - if (se != NULL) { -#if 0 - se->se_fails = 0; - IEEE80211_NOTE_MAC(ss->ss_vap, IEEE80211_MSG_SCAN, - macaddr, "%s: fails %u", - __func__, se->se_fails); -#endif - se->se_lastassoc = ticks; - } -} - -static const struct ieee80211_scanner sta_default = { - .scan_name = "default", - .scan_attach = sta_attach, - .scan_detach = sta_detach, - .scan_start = sta_start, - .scan_restart = sta_restart, - .scan_cancel = sta_cancel, - .scan_end = sta_pick_bss, - .scan_flush = sta_flush, - .scan_add = sta_add, - .scan_age = sta_age, - .scan_iterate = sta_iterate, - .scan_assoc_fail = sta_assoc_fail, - .scan_assoc_success = sta_assoc_success, -}; - -/* - * Adhoc mode-specific support. - */ - -static const uint16_t adhocWorld[] = /* 36, 40, 44, 48 */ -{ 5180, 5200, 5220, 5240 }; -static const uint16_t adhocFcc3[] = /* 36, 40, 44, 48 145, 149, 153, 157, 161, 165 */ -{ 5180, 5200, 5220, 5240, 5725, 5745, 5765, 5785, 5805, 5825 }; -static const uint16_t adhocMkk[] = /* 34, 38, 42, 46 */ -{ 5170, 5190, 5210, 5230 }; -static const uint16_t adhoc11b[] = /* 10, 11 */ -{ 2457, 2462 }; - -static const struct scanlist adhocScanTable[] = { - { IEEE80211_MODE_11B, X(adhoc11b) }, - { IEEE80211_MODE_11A, X(adhocWorld) }, - { IEEE80211_MODE_11A, X(adhocFcc3) }, - { IEEE80211_MODE_11B, X(adhocMkk) }, - { .list = NULL } -}; -#undef X - -/* - * Start an adhoc-mode scan by populating the channel list. - */ -static int -adhoc_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) -{ - struct sta_table *st = ss->ss_priv; - - makescanlist(ss, vap, adhocScanTable); - - if (ss->ss_mindwell == 0) - ss->ss_mindwell = msecs_to_ticks(200); /* 200ms */ - if (ss->ss_maxdwell == 0) - ss->ss_maxdwell = msecs_to_ticks(200); /* 200ms */ - - st->st_scangen++; - st->st_newscan = 1; - - return 0; -} - -/* - * Select a channel to start an adhoc network on. - * The channel list was populated with appropriate - * channels so select one that looks least occupied. - */ -static struct ieee80211_channel * -adhoc_pick_channel(struct ieee80211_scan_state *ss, int flags) -{ - struct sta_table *st = ss->ss_priv; - struct sta_entry *se; - struct ieee80211_channel *c, *bestchan; - int i, bestrssi, maxrssi; - - bestchan = NULL; - bestrssi = -1; - - IEEE80211_SCAN_TABLE_LOCK(st); - for (i = 0; i < ss->ss_last; i++) { - c = ss->ss_chans[i]; - /* never consider a channel with radar */ - if (IEEE80211_IS_CHAN_RADAR(c)) - continue; - /* skip channels disallowed by regulatory settings */ - if (IEEE80211_IS_CHAN_NOADHOC(c)) - continue; - /* check channel attributes for band compatibility */ - if (flags != 0 && (c->ic_flags & flags) != flags) - continue; - maxrssi = 0; - TAILQ_FOREACH(se, &st->st_entry, se_list) { - if (se->base.se_chan != c) - continue; - if (se->base.se_rssi > maxrssi) - maxrssi = se->base.se_rssi; - } - if (bestchan == NULL || maxrssi < bestrssi) - bestchan = c; - } - IEEE80211_SCAN_TABLE_UNLOCK(st); - - return bestchan; -} - -/* - * Pick an ibss network to join or find a channel - * to use to start an ibss network. - */ -static int -adhoc_pick_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) -{ - struct sta_table *st = ss->ss_priv; - struct sta_entry *selbs; - struct ieee80211_channel *chan; - - KASSERT(vap->iv_opmode == IEEE80211_M_IBSS || - vap->iv_opmode == IEEE80211_M_AHDEMO || - vap->iv_opmode == IEEE80211_M_MBSS, - ("wrong opmode %u", vap->iv_opmode)); - - if (st->st_newscan) { - sta_update_notseen(st); - st->st_newscan = 0; - } - if (ss->ss_flags & IEEE80211_SCAN_NOPICK) { - /* - * Manual/background scan, don't select+join the - * bss, just return. The scanning framework will - * handle notification that this has completed. - */ - ss->ss_flags &= ~IEEE80211_SCAN_NOPICK; - return 1; - } - /* - * Automatic sequencing; look for a candidate and - * if found join the network. - */ - /* NB: unlocked read should be ok */ - if (TAILQ_FIRST(&st->st_entry) == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: no scan candidate\n", __func__); - if (ss->ss_flags & IEEE80211_SCAN_NOJOIN) - return 0; -notfound: - /* NB: never auto-start a tdma network for slot !0 */ -#ifdef IEEE80211_SUPPORT_TDMA - if (vap->iv_des_nssid && - ((vap->iv_caps & IEEE80211_C_TDMA) == 0 || - ieee80211_tdma_getslot(vap) == 0)) { -#else - if (vap->iv_des_nssid) { -#endif - /* - * No existing adhoc network to join and we have - * an ssid; start one up. If no channel was - * specified, try to select a channel. - */ - if (vap->iv_des_chan == IEEE80211_CHAN_ANYC || - IEEE80211_IS_CHAN_RADAR(vap->iv_des_chan)) { - struct ieee80211com *ic = vap->iv_ic; - - chan = adhoc_pick_channel(ss, 0); - if (chan != NULL) - chan = ieee80211_ht_adjust_channel(ic, - chan, vap->iv_flags_ht); - } else - chan = vap->iv_des_chan; - if (chan != NULL) { - ieee80211_create_ibss(vap, chan); - return 1; - } - } - /* - * If nothing suitable was found decrement - * the failure counts so entries will be - * reconsidered the next time around. We - * really want to do this only for sta's - * where we've previously had some success. - */ - sta_dec_fails(st); - st->st_newscan = 1; - return 0; /* restart scan */ - } - selbs = select_bss(ss, vap, IEEE80211_MSG_SCAN); - if (ss->ss_flags & IEEE80211_SCAN_NOJOIN) - return (selbs != NULL); - if (selbs == NULL) - goto notfound; - chan = selbs->base.se_chan; - if (selbs->se_flags & STA_DEMOTE11B) - chan = demote11b(vap, chan); - if (!ieee80211_sta_join(vap, chan, &selbs->base)) - goto notfound; - return 1; /* terminate scan */ -} - -/* - * Age entries in the scan cache. - */ -static void -adhoc_age(struct ieee80211_scan_state *ss) -{ - struct sta_table *st = ss->ss_priv; - struct sta_entry *se, *next; - - IEEE80211_SCAN_TABLE_LOCK(st); - TAILQ_FOREACH_SAFE(se, &st->st_entry, se_list, next) { - if (se->se_notseen > STA_PURGE_SCANS) { - TAILQ_REMOVE(&st->st_entry, se, se_list); - LIST_REMOVE(se, se_hash); - ieee80211_ies_cleanup(&se->base.se_ies); - free(se, M_80211_SCAN); - } - } - IEEE80211_SCAN_TABLE_UNLOCK(st); -} - -static const struct ieee80211_scanner adhoc_default = { - .scan_name = "default", - .scan_attach = sta_attach, - .scan_detach = sta_detach, - .scan_start = adhoc_start, - .scan_restart = sta_restart, - .scan_cancel = sta_cancel, - .scan_end = adhoc_pick_bss, - .scan_flush = sta_flush, - .scan_pickchan = adhoc_pick_channel, - .scan_add = sta_add, - .scan_age = adhoc_age, - .scan_iterate = sta_iterate, - .scan_assoc_fail = sta_assoc_fail, - .scan_assoc_success = sta_assoc_success, -}; -IEEE80211_SCANNER_ALG(ibss, IEEE80211_M_IBSS, adhoc_default); -IEEE80211_SCANNER_ALG(ahdemo, IEEE80211_M_AHDEMO, adhoc_default); - -static void -ap_force_promisc(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - - IEEE80211_LOCK(ic); - /* set interface into promiscuous mode */ - ifp->if_flags |= IFF_PROMISC; - ieee80211_runtask(ic, &ic->ic_promisc_task); - IEEE80211_UNLOCK(ic); -} - -static void -ap_reset_promisc(struct ieee80211com *ic) -{ - IEEE80211_LOCK(ic); - ieee80211_syncifflag_locked(ic, IFF_PROMISC); - IEEE80211_UNLOCK(ic); -} - -static int -ap_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) -{ - struct sta_table *st = ss->ss_priv; - - makescanlist(ss, vap, staScanTable); - - if (ss->ss_mindwell == 0) - ss->ss_mindwell = msecs_to_ticks(200); /* 200ms */ - if (ss->ss_maxdwell == 0) - ss->ss_maxdwell = msecs_to_ticks(200); /* 200ms */ - - st->st_scangen++; - st->st_newscan = 1; - - ap_force_promisc(vap->iv_ic); - return 0; -} - -/* - * Cancel an ongoing scan. - */ -static int -ap_cancel(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) -{ - ap_reset_promisc(vap->iv_ic); - return 0; -} - -/* - * Pick a quiet channel to use for ap operation. - */ -static struct ieee80211_channel * -ap_pick_channel(struct ieee80211_scan_state *ss, int flags) -{ - struct sta_table *st = ss->ss_priv; - struct ieee80211_channel *bestchan = NULL; - int i; - - /* XXX select channel more intelligently, e.g. channel spread, power */ - /* NB: use scan list order to preserve channel preference */ - for (i = 0; i < ss->ss_last; i++) { - struct ieee80211_channel *chan = ss->ss_chans[i]; - /* - * If the channel is unoccupied the max rssi - * should be zero; just take it. Otherwise - * track the channel with the lowest rssi and - * use that when all channels appear occupied. - */ - if (IEEE80211_IS_CHAN_RADAR(chan)) - continue; - if (IEEE80211_IS_CHAN_NOHOSTAP(chan)) - continue; - /* check channel attributes for band compatibility */ - if (flags != 0 && (chan->ic_flags & flags) != flags) - continue; - KASSERT(sizeof(chan->ic_ieee) == 1, ("ic_chan size")); - /* XXX channel have interference */ - if (st->st_maxrssi[chan->ic_ieee] == 0) { - /* XXX use other considerations */ - return chan; - } - if (bestchan == NULL || - st->st_maxrssi[chan->ic_ieee] < st->st_maxrssi[bestchan->ic_ieee]) - bestchan = chan; - } - return bestchan; -} - -/* - * Pick a quiet channel to use for ap operation. - */ -static int -ap_end(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_channel *bestchan; - - KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP, - ("wrong opmode %u", vap->iv_opmode)); - bestchan = ap_pick_channel(ss, 0); - if (bestchan == NULL) { - /* no suitable channel, should not happen */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: no suitable channel! (should not happen)\n", __func__); - /* XXX print something? */ - return 0; /* restart scan */ - } - /* - * If this is a dynamic turbo channel, start with the unboosted one. - */ - if (IEEE80211_IS_CHAN_TURBO(bestchan)) { - bestchan = ieee80211_find_channel(ic, bestchan->ic_freq, - bestchan->ic_flags & ~IEEE80211_CHAN_TURBO); - if (bestchan == NULL) { - /* should never happen ?? */ - return 0; - } - } - ap_reset_promisc(ic); - if (ss->ss_flags & (IEEE80211_SCAN_NOPICK | IEEE80211_SCAN_NOJOIN)) { - /* - * Manual/background scan, don't select+join the - * bss, just return. The scanning framework will - * handle notification that this has completed. - */ - ss->ss_flags &= ~IEEE80211_SCAN_NOPICK; - return 1; - } - ieee80211_create_ibss(vap, - ieee80211_ht_adjust_channel(ic, bestchan, vap->iv_flags_ht)); - return 1; -} - -static const struct ieee80211_scanner ap_default = { - .scan_name = "default", - .scan_attach = sta_attach, - .scan_detach = sta_detach, - .scan_start = ap_start, - .scan_restart = sta_restart, - .scan_cancel = ap_cancel, - .scan_end = ap_end, - .scan_flush = sta_flush, - .scan_pickchan = ap_pick_channel, - .scan_add = sta_add, - .scan_age = adhoc_age, - .scan_iterate = sta_iterate, - .scan_assoc_success = sta_assoc_success, - .scan_assoc_fail = sta_assoc_fail, -}; -IEEE80211_SCANNER_ALG(ap, IEEE80211_M_HOSTAP, ap_default); - -#ifdef IEEE80211_SUPPORT_MESH -/* - * Pick an mbss network to join or find a channel - * to use to start an mbss network. - */ -static int -mesh_pick_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) -{ - struct sta_table *st = ss->ss_priv; - struct ieee80211_mesh_state *ms = vap->iv_mesh; - struct sta_entry *selbs; - struct ieee80211_channel *chan; - - KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, - ("wrong opmode %u", vap->iv_opmode)); - - if (st->st_newscan) { - sta_update_notseen(st); - st->st_newscan = 0; - } - if (ss->ss_flags & IEEE80211_SCAN_NOPICK) { - /* - * Manual/background scan, don't select+join the - * bss, just return. The scanning framework will - * handle notification that this has completed. - */ - ss->ss_flags &= ~IEEE80211_SCAN_NOPICK; - return 1; - } - /* - * Automatic sequencing; look for a candidate and - * if found join the network. - */ - /* NB: unlocked read should be ok */ - if (TAILQ_FIRST(&st->st_entry) == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, - "%s: no scan candidate\n", __func__); - if (ss->ss_flags & IEEE80211_SCAN_NOJOIN) - return 0; -notfound: - if (ms->ms_idlen != 0) { - /* - * No existing mbss network to join and we have - * a meshid; start one up. If no channel was - * specified, try to select a channel. - */ - if (vap->iv_des_chan == IEEE80211_CHAN_ANYC || - IEEE80211_IS_CHAN_RADAR(vap->iv_des_chan)) { - struct ieee80211com *ic = vap->iv_ic; - - chan = adhoc_pick_channel(ss, 0); - if (chan != NULL) - chan = ieee80211_ht_adjust_channel(ic, - chan, vap->iv_flags_ht); - } else - chan = vap->iv_des_chan; - if (chan != NULL) { - ieee80211_create_ibss(vap, chan); - return 1; - } - } - /* - * If nothing suitable was found decrement - * the failure counts so entries will be - * reconsidered the next time around. We - * really want to do this only for sta's - * where we've previously had some success. - */ - sta_dec_fails(st); - st->st_newscan = 1; - return 0; /* restart scan */ - } - selbs = select_bss(ss, vap, IEEE80211_MSG_SCAN); - if (ss->ss_flags & IEEE80211_SCAN_NOJOIN) - return (selbs != NULL); - if (selbs == NULL) - goto notfound; - chan = selbs->base.se_chan; - if (selbs->se_flags & STA_DEMOTE11B) - chan = demote11b(vap, chan); - if (!ieee80211_sta_join(vap, chan, &selbs->base)) - goto notfound; - return 1; /* terminate scan */ -} - -static const struct ieee80211_scanner mesh_default = { - .scan_name = "default", - .scan_attach = sta_attach, - .scan_detach = sta_detach, - .scan_start = adhoc_start, - .scan_restart = sta_restart, - .scan_cancel = sta_cancel, - .scan_end = mesh_pick_bss, - .scan_flush = sta_flush, - .scan_pickchan = adhoc_pick_channel, - .scan_add = sta_add, - .scan_age = adhoc_age, - .scan_iterate = sta_iterate, - .scan_assoc_fail = sta_assoc_fail, - .scan_assoc_success = sta_assoc_success, -}; -IEEE80211_SCANNER_ALG(mesh, IEEE80211_M_MBSS, mesh_default); -#endif /* IEEE80211_SUPPORT_MESH */ - -#if defined(__HAIKU__) -void -ieee80211_scan_sta_init() -{ - ieee80211_scanner_register(IEEE80211_M_STA, &sta_default); - ieee80211_scanner_register(IEEE80211_M_IBSS, &adhoc_default); -} - -void -ieee80211_scan_sta_uninit() -{ - ieee80211_scanner_unregister(IEEE80211_M_STA, &sta_default); - ieee80211_scanner_unregister(IEEE80211_M_IBSS, &adhoc_default); -} -#endif /* __HAIKU__ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_sta.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_sta.c deleted file mode 100644 index 5444459a15..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_sta.c +++ /dev/null @@ -1,1761 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifdef __FreeBSD__ -__FBSDID("$FreeBSD$"); -#endif - -/* - * IEEE 802.11 Station mode support. - */ -#include "opt_inet.h" -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#ifdef IEEE80211_SUPPORT_SUPERG -#include -#endif -#include - -#define IEEE80211_RATE2MBS(r) (((r) & IEEE80211_RATE_VAL) / 2) - -static void sta_vattach(struct ieee80211vap *); -static void sta_beacon_miss(struct ieee80211vap *); -static int sta_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int sta_input(struct ieee80211_node *, struct mbuf *, int, int); -static void sta_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int nf); -static void sta_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype); - -void -ieee80211_sta_attach(struct ieee80211com *ic) -{ - ic->ic_vattach[IEEE80211_M_STA] = sta_vattach; -} - -void -ieee80211_sta_detach(struct ieee80211com *ic) -{ -} - -static void -sta_vdetach(struct ieee80211vap *vap) -{ -} - -static void -sta_vattach(struct ieee80211vap *vap) -{ - vap->iv_newstate = sta_newstate; - vap->iv_input = sta_input; - vap->iv_recv_mgmt = sta_recv_mgmt; - vap->iv_recv_ctl = sta_recv_ctl; - vap->iv_opdetach = sta_vdetach; - vap->iv_bmiss = sta_beacon_miss; -} - -/* - * Handle a beacon miss event. The common code filters out - * spurious events that can happen when scanning and/or before - * reaching RUN state. - */ -static void -sta_beacon_miss(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - - KASSERT((ic->ic_flags & IEEE80211_F_SCAN) == 0, ("scanning")); - KASSERT(vap->iv_state >= IEEE80211_S_RUN, - ("wrong state %s", ieee80211_state_name[vap->iv_state])); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, - "beacon miss, mode %s state %s\n", - ieee80211_opmode_name[vap->iv_opmode], - ieee80211_state_name[vap->iv_state]); - - if (vap->iv_state == IEEE80211_S_CSA) { - /* - * A Channel Switch is pending; assume we missed the - * beacon that would've completed the process and just - * force the switch. If we made a mistake we'll not - * find the AP on the new channel and fall back to a - * normal scan. - */ - ieee80211_csa_completeswitch(ic); - return; - } - if (++vap->iv_bmiss_count < vap->iv_bmiss_max) { - /* - * Send a directed probe req before falling back to a - * scan; if we receive a response ic_bmiss_count will - * be reset. Some cards mistakenly report beacon miss - * so this avoids the expensive scan if the ap is - * still there. - */ - ieee80211_send_probereq(vap->iv_bss, vap->iv_myaddr, - vap->iv_bss->ni_bssid, vap->iv_bss->ni_bssid, - vap->iv_bss->ni_essid, vap->iv_bss->ni_esslen); - return; - } - - callout_stop(&vap->iv_swbmiss); - vap->iv_bmiss_count = 0; - vap->iv_stats.is_beacon_miss++; - if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) { -#ifdef IEEE80211_SUPPORT_SUPERG - struct ieee80211com *ic = vap->iv_ic; - - /* - * If we receive a beacon miss interrupt when using - * dynamic turbo, attempt to switch modes before - * reassociating. - */ - if (IEEE80211_ATH_CAP(vap, vap->iv_bss, IEEE80211_NODE_TURBOP)) - ieee80211_dturbo_switch(vap, - ic->ic_bsschan->ic_flags ^ IEEE80211_CHAN_TURBO); -#endif - /* - * Try to reassociate before scanning for a new ap. - */ - ieee80211_new_state(vap, IEEE80211_S_ASSOC, 1); - } else { - /* - * Somebody else is controlling state changes (e.g. - * a user-mode app) don't do anything that would - * confuse them; just drop into scan mode so they'll - * notified of the state change and given control. - */ - ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); - } -} - -/* - * Handle deauth with reason. We retry only for - * the cases where we might succeed. Otherwise - * we downgrade the ap and scan. - */ -static void -sta_authretry(struct ieee80211vap *vap, struct ieee80211_node *ni, int reason) -{ - switch (reason) { - case IEEE80211_STATUS_SUCCESS: /* NB: MLME assoc */ - case IEEE80211_STATUS_TIMEOUT: - case IEEE80211_REASON_ASSOC_EXPIRE: - case IEEE80211_REASON_NOT_AUTHED: - case IEEE80211_REASON_NOT_ASSOCED: - case IEEE80211_REASON_ASSOC_LEAVE: - case IEEE80211_REASON_ASSOC_NOT_AUTHED: - IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_AUTH, 1); - break; - default: - ieee80211_scan_assoc_fail(vap, vap->iv_bss->ni_macaddr, reason); - if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) - ieee80211_check_scan_current(vap); - break; - } -} - -/* - * IEEE80211_M_STA vap state machine handler. - * This routine handles the main states in the 802.11 protocol. - */ -static int -sta_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni; - enum ieee80211_state ostate; - - IEEE80211_LOCK_ASSERT(ic); - - ostate = vap->iv_state; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n", - __func__, ieee80211_state_name[ostate], - ieee80211_state_name[nstate], arg); - vap->iv_state = nstate; /* state transition */ - callout_stop(&vap->iv_mgtsend); /* XXX callout_drain */ - if (ostate != IEEE80211_S_SCAN) - ieee80211_cancel_scan(vap); /* background scan */ - ni = vap->iv_bss; /* NB: no reference held */ - if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) - callout_stop(&vap->iv_swbmiss); - switch (nstate) { - case IEEE80211_S_INIT: - switch (ostate) { - case IEEE80211_S_SLEEP: - /* XXX wakeup */ - case IEEE80211_S_RUN: - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_DISASSOC, - IEEE80211_REASON_ASSOC_LEAVE); - ieee80211_sta_leave(ni); - break; - case IEEE80211_S_ASSOC: - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_DEAUTH, - IEEE80211_REASON_AUTH_LEAVE); - break; - case IEEE80211_S_SCAN: - ieee80211_cancel_scan(vap); - break; - default: - goto invalid; - } - if (ostate != IEEE80211_S_INIT) { - /* NB: optimize INIT -> INIT case */ - ieee80211_reset_bss(vap); - } - if (vap->iv_auth->ia_detach != NULL) - vap->iv_auth->ia_detach(vap); - break; - case IEEE80211_S_SCAN: - switch (ostate) { - case IEEE80211_S_INIT: - /* - * Initiate a scan. We can come here as a result - * of an IEEE80211_IOC_SCAN_REQ too in which case - * the vap will be marked with IEEE80211_FEXT_SCANREQ - * and the scan request parameters will be present - * in iv_scanreq. Otherwise we do the default. - */ - if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) { - ieee80211_check_scan(vap, - vap->iv_scanreq_flags, - vap->iv_scanreq_duration, - vap->iv_scanreq_mindwell, - vap->iv_scanreq_maxdwell, - vap->iv_scanreq_nssid, vap->iv_scanreq_ssid); - vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; - } else - ieee80211_check_scan_current(vap); - break; - case IEEE80211_S_SCAN: - case IEEE80211_S_AUTH: - case IEEE80211_S_ASSOC: - /* - * These can happen either because of a timeout - * on an assoc/auth response or because of a - * change in state that requires a reset. For - * the former we're called with a non-zero arg - * that is the cause for the failure; pass this - * to the scan code so it can update state. - * Otherwise trigger a new scan unless we're in - * manual roaming mode in which case an application - * must issue an explicit scan request. - */ - if (arg != 0) - ieee80211_scan_assoc_fail(vap, - vap->iv_bss->ni_macaddr, arg); - if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) - ieee80211_check_scan_current(vap); - break; - case IEEE80211_S_RUN: /* beacon miss */ - /* - * Beacon miss. Notify user space and if not - * under control of a user application (roaming - * manual) kick off a scan to re-connect. - */ - ieee80211_sta_leave(ni); - if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) - ieee80211_check_scan_current(vap); - break; - default: - goto invalid; - } - break; - case IEEE80211_S_AUTH: - switch (ostate) { - case IEEE80211_S_INIT: - case IEEE80211_S_SCAN: - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_AUTH, 1); - break; - case IEEE80211_S_AUTH: - case IEEE80211_S_ASSOC: - switch (arg & 0xff) { - case IEEE80211_FC0_SUBTYPE_AUTH: - /* ??? */ - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_AUTH, 2); - break; - case IEEE80211_FC0_SUBTYPE_DEAUTH: - sta_authretry(vap, ni, arg>>8); - break; - } - break; - case IEEE80211_S_RUN: - switch (arg & 0xff) { - case IEEE80211_FC0_SUBTYPE_AUTH: - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_AUTH, 2); - vap->iv_state = ostate; /* stay RUN */ - break; - case IEEE80211_FC0_SUBTYPE_DEAUTH: - ieee80211_sta_leave(ni); - if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) { - /* try to reauth */ - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_AUTH, 1); - } - break; - } - break; - default: - goto invalid; - } - break; - case IEEE80211_S_ASSOC: - switch (ostate) { - case IEEE80211_S_AUTH: - case IEEE80211_S_ASSOC: - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0); - break; - case IEEE80211_S_SLEEP: /* cannot happen */ - case IEEE80211_S_RUN: - ieee80211_sta_leave(ni); - if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) { - IEEE80211_SEND_MGMT(ni, arg ? - IEEE80211_FC0_SUBTYPE_REASSOC_REQ : - IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0); - } - break; - default: - goto invalid; - } - break; - case IEEE80211_S_RUN: - if (vap->iv_flags & IEEE80211_F_WPA) { - /* XXX validate prerequisites */ - } - switch (ostate) { - case IEEE80211_S_RUN: - case IEEE80211_S_CSA: - break; - case IEEE80211_S_AUTH: /* when join is done in fw */ - case IEEE80211_S_ASSOC: -#ifdef IEEE80211_DEBUG - if (ieee80211_msg_debug(vap)) { - ieee80211_note(vap, "%s with %s ssid ", - (vap->iv_opmode == IEEE80211_M_STA ? - "associated" : "synchronized"), - ether_sprintf(ni->ni_bssid)); - ieee80211_print_essid(vap->iv_bss->ni_essid, - ni->ni_esslen); - /* XXX MCS/HT */ - printf(" channel %d start %uMb\n", - ieee80211_chan2ieee(ic, ic->ic_curchan), - IEEE80211_RATE2MBS(ni->ni_txrate)); - } -#endif - ieee80211_scan_assoc_success(vap, ni->ni_macaddr); - ieee80211_notify_node_join(ni, - arg == IEEE80211_FC0_SUBTYPE_ASSOC_RESP); - break; - case IEEE80211_S_SLEEP: - ieee80211_sta_pwrsave(vap, 0); - break; - default: - goto invalid; - } - ieee80211_sync_curchan(ic); - if (ostate != IEEE80211_S_RUN && - (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) { - /* - * Start s/w beacon miss timer for devices w/o - * hardware support. We fudge a bit here since - * we're doing this in software. - */ - vap->iv_swbmiss_period = IEEE80211_TU_TO_TICKS( - 2 * vap->iv_bmissthreshold * ni->ni_intval); - vap->iv_swbmiss_count = 0; - callout_reset(&vap->iv_swbmiss, vap->iv_swbmiss_period, - ieee80211_swbmiss, vap); - } - /* - * When 802.1x is not in use mark the port authorized - * at this point so traffic can flow. - */ - if (ni->ni_authmode != IEEE80211_AUTH_8021X) - ieee80211_node_authorize(ni); - /* - * Fake association when joining an existing bss. - */ - if (ic->ic_newassoc != NULL) - ic->ic_newassoc(vap->iv_bss, ostate != IEEE80211_S_RUN); - break; - case IEEE80211_S_CSA: - if (ostate != IEEE80211_S_RUN) - goto invalid; - break; - case IEEE80211_S_SLEEP: - ieee80211_sta_pwrsave(vap, 1); - break; - default: - invalid: - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, - "%s: unexpected state transition %s -> %s\n", __func__, - ieee80211_state_name[ostate], ieee80211_state_name[nstate]); - break; - } - return 0; -} - -/* - * Return non-zero if the frame is an echo of a multicast - * frame sent by ourself. The dir is known to be DSTODS. - */ -static __inline int -isdstods_mcastecho(struct ieee80211vap *vap, const struct ieee80211_frame *wh) -{ -#define QWH4(wh) ((const struct ieee80211_qosframe_addr4 *)wh) -#define WH4(wh) ((const struct ieee80211_frame_addr4 *)wh) - const uint8_t *sa; - - KASSERT(vap->iv_opmode == IEEE80211_M_STA, ("wrong mode")); - - if (!IEEE80211_IS_MULTICAST(wh->i_addr3)) - return 0; - sa = IEEE80211_QOS_HAS_SEQ(wh) ? QWH4(wh)->i_addr4 : WH4(wh)->i_addr4; - return IEEE80211_ADDR_EQ(sa, vap->iv_myaddr); -#undef WH4 -#undef QWH4 -} - -/* - * Return non-zero if the frame is an echo of a multicast - * frame sent by ourself. The dir is known to be FROMDS. - */ -static __inline int -isfromds_mcastecho(struct ieee80211vap *vap, const struct ieee80211_frame *wh) -{ - KASSERT(vap->iv_opmode == IEEE80211_M_STA, ("wrong mode")); - - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) - return 0; - return IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_myaddr); -} - -/* - * Decide if a received management frame should be - * printed when debugging is enabled. This filters some - * of the less interesting frames that come frequently - * (e.g. beacons). - */ -static __inline int -doprint(struct ieee80211vap *vap, int subtype) -{ - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_BEACON: - return (vap->iv_ic->ic_flags & IEEE80211_F_SCAN); - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - return 0; - } - return 1; -} - -/* - * Process a received frame. The node associated with the sender - * should be supplied. If nothing was found in the node table then - * the caller is assumed to supply a reference to iv_bss instead. - * The RSSI and a timestamp are also supplied. The RSSI data is used - * during AP scanning to select a AP to associate with; it can have - * any units so long as values have consistent units and higher values - * mean ``better signal''. The receive timestamp is currently not used - * by the 802.11 layer. - */ -static int -sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) -{ -#define HAS_SEQ(type) ((type & 0x4) == 0) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = vap->iv_ifp; - struct ieee80211_frame *wh; - struct ieee80211_key *key; - struct ether_header *eh; - int hdrspace, need_tap = 1; /* mbuf need to be tapped. */ - uint8_t dir, type, subtype, qos; - uint8_t *bssid; - uint16_t rxseq; - - if (m->m_flags & M_AMPDU_MPDU) { - /* - * Fastpath for A-MPDU reorder q resubmission. Frames - * w/ M_AMPDU_MPDU marked have already passed through - * here but were received out of order and been held on - * the reorder queue. When resubmitted they are marked - * with the M_AMPDU_MPDU flag and we can bypass most of - * the normal processing. - */ - wh = mtod(m, struct ieee80211_frame *); - type = IEEE80211_FC0_TYPE_DATA; - dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; - subtype = IEEE80211_FC0_SUBTYPE_QOS; - hdrspace = ieee80211_hdrspace(ic, wh); /* XXX optimize? */ - goto resubmit_ampdu; - } - - KASSERT(ni != NULL, ("null node")); - ni->ni_inact = ni->ni_inact_reload; - - type = -1; /* undefined */ - - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, - "too short (1): len %u", m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } - /* - * Bit of a cheat here, we use a pointer for a 3-address - * frame format but don't reference fields past outside - * ieee80211_frame_min w/o first validating the data is - * present. - */ - wh = mtod(m, struct ieee80211_frame *); - - if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != - IEEE80211_FC0_VERSION_0) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, "wrong version, fc %02x:%02x", - wh->i_fc[0], wh->i_fc[1]); - vap->iv_stats.is_rx_badversion++; - goto err; - } - - dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; - type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; - subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { - bssid = wh->i_addr2; - if (!IEEE80211_ADDR_EQ(bssid, ni->ni_bssid)) { - /* not interested in */ - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - bssid, NULL, "%s", "not to bss"); - vap->iv_stats.is_rx_wrongbss++; - goto out; - } - IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = nf; - if (HAS_SEQ(type) && !IEEE80211_IS_MULTICAST(wh->i_addr1)) { - uint8_t tid = ieee80211_gettid(wh); - if (IEEE80211_QOS_HAS_SEQ(wh) && - TID_TO_WME_AC(tid) >= WME_AC_VI) - ic->ic_wme.wme_hipri_traffic++; - rxseq = le16toh(*(uint16_t *)wh->i_seq); - if (! ieee80211_check_rxseq(ni, wh)) { - /* duplicate, discard */ - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - bssid, "duplicate", - "seqno <%u,%u> fragno <%u,%u> tid %u", - rxseq >> IEEE80211_SEQ_SEQ_SHIFT, - ni->ni_rxseqs[tid] >> - IEEE80211_SEQ_SEQ_SHIFT, - rxseq & IEEE80211_SEQ_FRAG_MASK, - ni->ni_rxseqs[tid] & - IEEE80211_SEQ_FRAG_MASK, - tid); - vap->iv_stats.is_rx_dup++; - IEEE80211_NODE_STAT(ni, rx_dup); - goto out; - } - ni->ni_rxseqs[tid] = rxseq; - } - } - - switch (type) { - case IEEE80211_FC0_TYPE_DATA: - hdrspace = ieee80211_hdrspace(ic, wh); - if (m->m_len < hdrspace && - (m = m_pullup(m, hdrspace)) == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, - "data too short: expecting %u", hdrspace); - vap->iv_stats.is_rx_tooshort++; - goto out; /* XXX */ - } - /* - * Handle A-MPDU re-ordering. If the frame is to be - * processed directly then ieee80211_ampdu_reorder - * will return 0; otherwise it has consumed the mbuf - * and we should do nothing more with it. - */ - if ((m->m_flags & M_AMPDU) && - (dir == IEEE80211_FC1_DIR_FROMDS || - dir == IEEE80211_FC1_DIR_DSTODS) && - ieee80211_ampdu_reorder(ni, m) != 0) { - m = NULL; - goto out; - } - resubmit_ampdu: - if (dir == IEEE80211_FC1_DIR_FROMDS) { - if ((ifp->if_flags & IFF_SIMPLEX) && - isfromds_mcastecho(vap, wh)) { - /* - * In IEEE802.11 network, multicast - * packets sent from "me" are broadcast - * from the AP; silently discard for - * SIMPLEX interface. - */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "data", "%s", "multicast echo"); - vap->iv_stats.is_rx_mcastecho++; - goto out; - } - if ((vap->iv_flags & IEEE80211_F_DWDS) && - IEEE80211_IS_MULTICAST(wh->i_addr1)) { - /* - * DWDS sta's must drop 3-address mcast frames - * as they will be sent separately as a 4-addr - * frame. Accepting the 3-addr frame will - * confuse the bridge into thinking the sending - * sta is located at the end of WDS link. - */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, wh, - "3-address data", "%s", "DWDS enabled"); - vap->iv_stats.is_rx_mcastecho++; - goto out; - } - } else if (dir == IEEE80211_FC1_DIR_DSTODS) { - if ((vap->iv_flags & IEEE80211_F_DWDS) == 0) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_INPUT, wh, "4-address data", - "%s", "DWDS not enabled"); - vap->iv_stats.is_rx_wrongdir++; - goto out; - } - if ((ifp->if_flags & IFF_SIMPLEX) && - isdstods_mcastecho(vap, wh)) { - /* - * In IEEE802.11 network, multicast - * packets sent from "me" are broadcast - * from the AP; silently discard for - * SIMPLEX interface. - */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, wh, - "4-address data", "%s", "multicast echo"); - vap->iv_stats.is_rx_mcastecho++; - goto out; - } - } else { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, wh, - "data", "incorrect dir 0x%x", dir); - vap->iv_stats.is_rx_wrongdir++; - goto out; - } - - /* - * Handle privacy requirements. Note that we - * must not be preempted from here until after - * we (potentially) call ieee80211_crypto_demic; - * otherwise we may violate assumptions in the - * crypto cipher modules used to do delayed update - * of replay sequence numbers. - */ - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { - /* - * Discard encrypted frames when privacy is off. - */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "WEP", "%s", "PRIVACY off"); - vap->iv_stats.is_rx_noprivacy++; - IEEE80211_NODE_STAT(ni, rx_noprivacy); - goto out; - } - key = ieee80211_crypto_decap(ni, m, hdrspace); - if (key == NULL) { - /* NB: stats+msgs handled in crypto_decap */ - IEEE80211_NODE_STAT(ni, rx_wepfail); - goto out; - } - wh = mtod(m, struct ieee80211_frame *); - wh->i_fc[1] &= ~IEEE80211_FC1_WEP; - } else { - /* XXX M_WEP and IEEE80211_F_PRIVACY */ - key = NULL; - } - - /* - * Save QoS bits for use below--before we strip the header. - */ - if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { - qos = (dir == IEEE80211_FC1_DIR_DSTODS) ? - ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] : - ((struct ieee80211_qosframe *)wh)->i_qos[0]; - } else - qos = 0; - - /* - * Next up, any fragmentation. - */ - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - m = ieee80211_defrag(ni, m, hdrspace); - if (m == NULL) { - /* Fragment dropped or frame not complete yet */ - goto out; - } - } - wh = NULL; /* no longer valid, catch any uses */ - - /* - * Next strip any MSDU crypto bits. - */ - if (key != NULL && !ieee80211_crypto_demic(vap, key, m, 0)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - ni->ni_macaddr, "data", "%s", "demic error"); - vap->iv_stats.is_rx_demicfail++; - IEEE80211_NODE_STAT(ni, rx_demicfail); - goto out; - } - - /* copy to listener after decrypt */ - if (ieee80211_radiotap_active_vap(vap)) - ieee80211_radiotap_rx(vap, m); - need_tap = 0; - - /* - * Finally, strip the 802.11 header. - */ - m = ieee80211_decap(vap, m, hdrspace); - if (m == NULL) { - /* XXX mask bit to check for both */ - /* don't count Null data frames as errors */ - if (subtype == IEEE80211_FC0_SUBTYPE_NODATA || - subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL) - goto out; - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - ni->ni_macaddr, "data", "%s", "decap error"); - vap->iv_stats.is_rx_decap++; - IEEE80211_NODE_STAT(ni, rx_decap); - goto err; - } - eh = mtod(m, struct ether_header *); - if (!ieee80211_node_is_authorized(ni)) { - /* - * Deny any non-PAE frames received prior to - * authorization. For open/shared-key - * authentication the port is mark authorized - * after authentication completes. For 802.1x - * the port is not marked authorized by the - * authenticator until the handshake has completed. - */ - if (eh->ether_type != htons(ETHERTYPE_PAE)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - eh->ether_shost, "data", - "unauthorized port: ether type 0x%x len %u", - eh->ether_type, m->m_pkthdr.len); - vap->iv_stats.is_rx_unauth++; - IEEE80211_NODE_STAT(ni, rx_unauth); - goto err; - } - } else { - /* - * When denying unencrypted frames, discard - * any non-PAE frames received without encryption. - */ - if ((vap->iv_flags & IEEE80211_F_DROPUNENC) && - (key == NULL && (m->m_flags & M_WEP) == 0) && - eh->ether_type != htons(ETHERTYPE_PAE)) { - /* - * Drop unencrypted frames. - */ - vap->iv_stats.is_rx_unencrypted++; - IEEE80211_NODE_STAT(ni, rx_unencrypted); - goto out; - } - } - /* XXX require HT? */ - if (qos & IEEE80211_QOS_AMSDU) { - m = ieee80211_decap_amsdu(ni, m); - if (m == NULL) - return IEEE80211_FC0_TYPE_DATA; - } else { -#ifdef IEEE80211_SUPPORT_SUPERG - m = ieee80211_decap_fastframe(vap, ni, m); - if (m == NULL) - return IEEE80211_FC0_TYPE_DATA; -#endif - } - ieee80211_deliver_data(vap, ni, m); - return IEEE80211_FC0_TYPE_DATA; - - case IEEE80211_FC0_TYPE_MGT: - vap->iv_stats.is_rx_mgmt++; - IEEE80211_NODE_STAT(ni, rx_mgmt); - if (dir != IEEE80211_FC1_DIR_NODS) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "data", "incorrect dir 0x%x", dir); - vap->iv_stats.is_rx_wrongdir++; - goto err; - } - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, "mgt", "too short: len %u", - m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } -#ifdef IEEE80211_DEBUG - if ((ieee80211_msg_debug(vap) && doprint(vap, subtype)) || - ieee80211_msg_dumppkts(vap)) { - if_printf(ifp, "received %s from %s rssi %d\n", - ieee80211_mgt_subtype_name[subtype >> - IEEE80211_FC0_SUBTYPE_SHIFT], - ether_sprintf(wh->i_addr2), rssi); - } -#endif - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - if (subtype != IEEE80211_FC0_SUBTYPE_AUTH) { - /* - * Only shared key auth frames with a challenge - * should be encrypted, discard all others. - */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, ieee80211_mgt_subtype_name[subtype >> - IEEE80211_FC0_SUBTYPE_SHIFT], - "%s", "WEP set but not permitted"); - vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ - goto out; - } - if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { - /* - * Discard encrypted frames when privacy is off. - */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "mgt", "%s", "WEP set but PRIVACY off"); - vap->iv_stats.is_rx_noprivacy++; - goto out; - } - hdrspace = ieee80211_hdrspace(ic, wh); - key = ieee80211_crypto_decap(ni, m, hdrspace); - if (key == NULL) { - /* NB: stats+msgs handled in crypto_decap */ - goto out; - } - wh = mtod(m, struct ieee80211_frame *); - wh->i_fc[1] &= ~IEEE80211_FC1_WEP; - } - vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); - goto out; - - case IEEE80211_FC0_TYPE_CTL: - vap->iv_stats.is_rx_ctl++; - IEEE80211_NODE_STAT(ni, rx_ctrl); - vap->iv_recv_ctl(ni, m, subtype); - goto out; - - default: - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, NULL, "bad frame type 0x%x", type); - /* should not come here */ - break; - } -err: - ifp->if_ierrors++; -out: - if (m != NULL) { - if (need_tap && ieee80211_radiotap_active_vap(vap)) - ieee80211_radiotap_rx(vap, m); - m_freem(m); - } - return type; -} - -static void -sta_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh, - int rssi, int nf, uint16_t seq, uint16_t status) -{ - struct ieee80211vap *vap = ni->ni_vap; - - if (ni->ni_authmode == IEEE80211_AUTH_SHARED) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "open auth", - "bad sta auth mode %u", ni->ni_authmode); - vap->iv_stats.is_rx_bad_auth++; /* XXX */ - return; - } - if (vap->iv_state != IEEE80211_S_AUTH || - seq != IEEE80211_AUTH_OPEN_RESPONSE) { - vap->iv_stats.is_rx_bad_auth++; - return; - } - if (status != 0) { - IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, - ni, "open auth failed (reason %d)", status); - vap->iv_stats.is_rx_auth_fail++; - vap->iv_stats.is_rx_authfail_code = status; - ieee80211_new_state(vap, IEEE80211_S_SCAN, - IEEE80211_SCAN_FAIL_STATUS); - } else - ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0); -} - -static void -sta_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh, - uint8_t *frm, uint8_t *efrm, int rssi, int nf, - uint16_t seq, uint16_t status) -{ - struct ieee80211vap *vap = ni->ni_vap; - uint8_t *challenge; - int estatus; - - /* - * NB: this can happen as we allow pre-shared key - * authentication to be enabled w/o wep being turned - * on so that configuration of these can be done - * in any order. It may be better to enforce the - * ordering in which case this check would just be - * for sanity/consistency. - */ - if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key auth", - "%s", " PRIVACY is disabled"); - estatus = IEEE80211_STATUS_ALG; - goto bad; - } - /* - * Pre-shared key authentication is evil; accept - * it only if explicitly configured (it is supported - * mainly for compatibility with clients like OS X). - */ - if (ni->ni_authmode != IEEE80211_AUTH_AUTO && - ni->ni_authmode != IEEE80211_AUTH_SHARED) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key auth", - "bad sta auth mode %u", ni->ni_authmode); - vap->iv_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */ - estatus = IEEE80211_STATUS_ALG; - goto bad; - } - - challenge = NULL; - if (frm + 1 < efrm) { - if ((frm[1] + 2) > (efrm - frm)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key auth", - "ie %d/%d too long", - frm[0], (frm[1] + 2) - (efrm - frm)); - vap->iv_stats.is_rx_bad_auth++; - estatus = IEEE80211_STATUS_CHALLENGE; - goto bad; - } - if (*frm == IEEE80211_ELEMID_CHALLENGE) - challenge = frm; - frm += frm[1] + 2; - } - switch (seq) { - case IEEE80211_AUTH_SHARED_CHALLENGE: - case IEEE80211_AUTH_SHARED_RESPONSE: - if (challenge == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key auth", - "%s", "no challenge"); - vap->iv_stats.is_rx_bad_auth++; - estatus = IEEE80211_STATUS_CHALLENGE; - goto bad; - } - if (challenge[1] != IEEE80211_CHALLENGE_LEN) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, - ni->ni_macaddr, "shared key auth", - "bad challenge len %d", challenge[1]); - vap->iv_stats.is_rx_bad_auth++; - estatus = IEEE80211_STATUS_CHALLENGE; - goto bad; - } - default: - break; - } - if (vap->iv_state != IEEE80211_S_AUTH) - return; - switch (seq) { - case IEEE80211_AUTH_SHARED_PASS: - if (ni->ni_challenge != NULL) { - free(ni->ni_challenge, M_80211_NODE); - ni->ni_challenge = NULL; - } - if (status != 0) { - IEEE80211_NOTE_FRAME(vap, - IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, wh, - "shared key auth failed (reason %d)", status); - vap->iv_stats.is_rx_auth_fail++; - vap->iv_stats.is_rx_authfail_code = status; - return; - } - ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0); - break; - case IEEE80211_AUTH_SHARED_CHALLENGE: - if (!ieee80211_alloc_challenge(ni)) - return; - /* XXX could optimize by passing recvd challenge */ - memcpy(ni->ni_challenge, &challenge[2], challenge[1]); - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); - break; - default: - IEEE80211_DISCARD(vap, IEEE80211_MSG_AUTH, - wh, "shared key auth", "bad seq %d", seq); - vap->iv_stats.is_rx_bad_auth++; - return; - } - return; -bad: - /* - * Kick the state machine. This short-circuits - * using the mgt frame timeout to trigger the - * state transition. - */ - if (vap->iv_state == IEEE80211_S_AUTH) - ieee80211_new_state(vap, IEEE80211_S_SCAN, - IEEE80211_SCAN_FAIL_STATUS); -} - -static int -ieee80211_parse_wmeparams(struct ieee80211vap *vap, uint8_t *frm, - const struct ieee80211_frame *wh) -{ -#define MS(_v, _f) (((_v) & _f) >> _f##_S) - struct ieee80211_wme_state *wme = &vap->iv_ic->ic_wme; - u_int len = frm[1], qosinfo; - int i; - - if (len < sizeof(struct ieee80211_wme_param)-2) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_WME, - wh, "WME", "too short, len %u", len); - return -1; - } - qosinfo = frm[__offsetof(struct ieee80211_wme_param, param_qosInfo)]; - qosinfo &= WME_QOSINFO_COUNT; - /* XXX do proper check for wraparound */ - if (qosinfo == wme->wme_wmeChanParams.cap_info) - return 0; - frm += __offsetof(struct ieee80211_wme_param, params_acParams); - for (i = 0; i < WME_NUM_AC; i++) { - struct wmeParams *wmep = - &wme->wme_wmeChanParams.cap_wmeParams[i]; - /* NB: ACI not used */ - wmep->wmep_acm = MS(frm[0], WME_PARAM_ACM); - wmep->wmep_aifsn = MS(frm[0], WME_PARAM_AIFSN); - wmep->wmep_logcwmin = MS(frm[1], WME_PARAM_LOGCWMIN); - wmep->wmep_logcwmax = MS(frm[1], WME_PARAM_LOGCWMAX); - wmep->wmep_txopLimit = LE_READ_2(frm+2); - frm += 4; - } - wme->wme_wmeChanParams.cap_info = qosinfo; - return 1; -#undef MS -} - -/* - * Process 11h Channel Switch Announcement (CSA) ie. If this - * is the first CSA then initiate the switch. Otherwise we - * track state and trigger completion and/or cancel of the switch. - * XXX should be public for IBSS use - */ -static void -ieee80211_parse_csaparams(struct ieee80211vap *vap, uint8_t *frm, - const struct ieee80211_frame *wh) -{ - struct ieee80211com *ic = vap->iv_ic; - const struct ieee80211_csa_ie *csa = - (const struct ieee80211_csa_ie *) frm; - - KASSERT(vap->iv_state >= IEEE80211_S_RUN, - ("state %s", ieee80211_state_name[vap->iv_state])); - - if (csa->csa_mode > 1) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_DOTH, - wh, "CSA", "invalid mode %u", csa->csa_mode); - return; - } - IEEE80211_LOCK(ic); - if ((ic->ic_flags & IEEE80211_F_CSAPENDING) == 0) { - /* - * Convert the channel number to a channel reference. We - * try first to preserve turbo attribute of the current - * channel then fallback. Note this will not work if the - * CSA specifies a channel that requires a band switch (e.g. - * 11a => 11g). This is intentional as 11h is defined only - * for 5GHz/11a and because the switch does not involve a - * reassociation, protocol state (capabilities, negotated - * rates, etc) may/will be wrong. - */ - struct ieee80211_channel *c = - ieee80211_find_channel_byieee(ic, csa->csa_newchan, - (ic->ic_bsschan->ic_flags & IEEE80211_CHAN_ALLTURBO)); - if (c == NULL) { - c = ieee80211_find_channel_byieee(ic, - csa->csa_newchan, - (ic->ic_bsschan->ic_flags & IEEE80211_CHAN_ALL)); - if (c == NULL) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_DOTH, - wh, "CSA", "invalid channel %u", - csa->csa_newchan); - goto done; - } - } -#if IEEE80211_CSA_COUNT_MIN > 0 - if (csa->csa_count < IEEE80211_CSA_COUNT_MIN) { - /* - * Require at least IEEE80211_CSA_COUNT_MIN count to - * reduce the risk of being redirected by a fabricated - * CSA. If a valid CSA is dropped we'll still get a - * beacon miss when the AP leaves the channel so we'll - * eventually follow to the new channel. - * - * NOTE: this violates the 11h spec that states that - * count may be any value and if 0 then a switch - * should happen asap. - */ - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_DOTH, - wh, "CSA", "count %u too small, must be >= %u", - csa->csa_count, IEEE80211_CSA_COUNT_MIN); - goto done; - } -#endif - ieee80211_csa_startswitch(ic, c, csa->csa_mode, csa->csa_count); - } else { - /* - * Validate this ie against the initial CSA. We require - * mode and channel not change and the count must be - * monotonically decreasing. This may be pointless and - * canceling the switch as a result may be too paranoid but - * in the worst case if we drop out of CSA because of this - * and the AP does move then we'll just end up taking a - * beacon miss and scan to find the AP. - * - * XXX may want <= on count as we also process ProbeResp - * frames and those may come in w/ the same count as the - * previous beacon; but doing so leaves us open to a stuck - * count until we add a dead-man timer - */ - if (!(csa->csa_count < ic->ic_csa_count && - csa->csa_mode == ic->ic_csa_mode && - csa->csa_newchan == ieee80211_chan2ieee(ic, ic->ic_csa_newchan))) { - IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_DOTH, wh, - "CSA ie mismatch, initial ie <%d,%d,%d>, " - "this ie <%d,%d,%d>", ic->ic_csa_mode, - ic->ic_csa_newchan, ic->ic_csa_count, - csa->csa_mode, csa->csa_newchan, csa->csa_count); - ieee80211_csa_cancelswitch(ic); - } else { - if (csa->csa_count <= 1) - ieee80211_csa_completeswitch(ic); - else - ic->ic_csa_count = csa->csa_count; - } - } -done: - IEEE80211_UNLOCK(ic); -} - -/* - * Return non-zero if a background scan may be continued: - * o bg scan is active - * o no channel switch is pending - * o there has not been any traffic recently - * - * Note we do not check if there is an administrative enable; - * this is only done to start the scan. We assume that any - * change in state will be accompanied by a request to cancel - * active scans which will otherwise cause this test to fail. - */ -static __inline int -contbgscan(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - - return ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) && - (ic->ic_flags & IEEE80211_F_CSAPENDING) == 0 && - vap->iv_state == IEEE80211_S_RUN && /* XXX? */ - time_after(ticks, ic->ic_lastdata + vap->iv_bgscanidle)); -} - -/* - * Return non-zero if a backgrond scan may be started: - * o bg scanning is administratively enabled - * o no channel switch is pending - * o we are not boosted on a dynamic turbo channel - * o there has not been a scan recently - * o there has not been any traffic recently - */ -static __inline int -startbgscan(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - - return ((vap->iv_flags & IEEE80211_F_BGSCAN) && - (ic->ic_flags & IEEE80211_F_CSAPENDING) == 0 && -#ifdef IEEE80211_SUPPORT_SUPERG - !IEEE80211_IS_CHAN_DTURBO(ic->ic_curchan) && -#endif - time_after(ticks, ic->ic_lastscan + vap->iv_bgscanintvl) && - time_after(ticks, ic->ic_lastdata + vap->iv_bgscanidle)); -} - -static void -sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int nf) -{ -#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) -#define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_frame *wh; - uint8_t *frm, *efrm; - uint8_t *rates, *xrates, *wme, *htcap, *htinfo; - uint8_t rate; - - wh = mtod(m0, struct ieee80211_frame *); - frm = (uint8_t *)&wh[1]; - efrm = mtod(m0, uint8_t *) + m0->m_len; - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - case IEEE80211_FC0_SUBTYPE_BEACON: { - struct ieee80211_scanparams scan; - /* - * We process beacon/probe response frames: - * o when scanning, or - * o station mode when associated (to collect state - * updates such as 802.11g slot time) - * Frames otherwise received are discarded. - */ - if (!((ic->ic_flags & IEEE80211_F_SCAN) || ni->ni_associd)) { - vap->iv_stats.is_rx_mgtdiscard++; - return; - } - /* XXX probe response in sta mode when !scanning? */ - if (ieee80211_parse_beacon(ni, m0, &scan) != 0) - return; - /* - * Count frame now that we know it's to be processed. - */ - if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) { - vap->iv_stats.is_rx_beacon++; /* XXX remove */ - IEEE80211_NODE_STAT(ni, rx_beacons); - } else - IEEE80211_NODE_STAT(ni, rx_proberesp); - /* - * When operating in station mode, check for state updates. - * Be careful to ignore beacons received while doing a - * background scan. We consider only 11g/WMM stuff right now. - */ - if (ni->ni_associd != 0 && - ((ic->ic_flags & IEEE80211_F_SCAN) == 0 || - IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))) { - /* record tsf of last beacon */ - memcpy(ni->ni_tstamp.data, scan.tstamp, - sizeof(ni->ni_tstamp)); - /* count beacon frame for s/w bmiss handling */ - vap->iv_swbmiss_count++; - vap->iv_bmiss_count = 0; - if (ni->ni_erp != scan.erp) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC, - wh->i_addr2, - "erp change: was 0x%x, now 0x%x", - ni->ni_erp, scan.erp); - if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) && - (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION)) - ic->ic_flags |= IEEE80211_F_USEPROT; - else - ic->ic_flags &= ~IEEE80211_F_USEPROT; - ni->ni_erp = scan.erp; - /* XXX statistic */ - /* XXX driver notification */ - } - if ((ni->ni_capinfo ^ scan.capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC, - wh->i_addr2, - "capabilities change: was 0x%x, now 0x%x", - ni->ni_capinfo, scan.capinfo); - /* - * NB: we assume short preamble doesn't - * change dynamically - */ - ieee80211_set_shortslottime(ic, - IEEE80211_IS_CHAN_A(ic->ic_bsschan) || - (scan.capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)); - ni->ni_capinfo = (ni->ni_capinfo &~ IEEE80211_CAPINFO_SHORT_SLOTTIME) - | (scan.capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME); - /* XXX statistic */ - } - if (scan.wme != NULL && - (ni->ni_flags & IEEE80211_NODE_QOS) && - ieee80211_parse_wmeparams(vap, scan.wme, wh) > 0) - ieee80211_wme_updateparams(vap); -#ifdef IEEE80211_SUPPORT_SUPERG - if (scan.ath != NULL) - ieee80211_parse_athparams(ni, scan.ath, wh); -#endif - if (scan.htcap != NULL && scan.htinfo != NULL && - (vap->iv_flags_ht & IEEE80211_FHT_HT)) { - ieee80211_ht_updateparams(ni, - scan.htcap, scan.htinfo); - /* XXX state changes? */ - } - if (scan.tim != NULL) { - struct ieee80211_tim_ie *tim = - (struct ieee80211_tim_ie *) scan.tim; -#if 0 - int aid = IEEE80211_AID(ni->ni_associd); - int ix = aid / NBBY; - int min = tim->tim_bitctl &~ 1; - int max = tim->tim_len + min - 4; - if ((tim->tim_bitctl&1) || - (min <= ix && ix <= max && - isset(tim->tim_bitmap - min, aid))) { - /* - * XXX Do not let bg scan kick off - * we are expecting data. - */ - ic->ic_lastdata = ticks; - ieee80211_sta_pwrsave(vap, 0); - } -#endif - ni->ni_dtim_count = tim->tim_count; - ni->ni_dtim_period = tim->tim_period; - } - if (scan.csa != NULL && - (vap->iv_flags & IEEE80211_F_DOTH)) - ieee80211_parse_csaparams(vap, scan.csa, wh); - else if (ic->ic_flags & IEEE80211_F_CSAPENDING) { - /* - * No CSA ie or 11h disabled, but a channel - * switch is pending; drop out so we aren't - * stuck in CSA state. If the AP really is - * moving we'll get a beacon miss and scan. - */ - IEEE80211_LOCK(ic); - ieee80211_csa_cancelswitch(ic); - IEEE80211_UNLOCK(ic); - } - /* - * If scanning, pass the info to the scan module. - * Otherwise, check if it's the right time to do - * a background scan. Background scanning must - * be enabled and we must not be operating in the - * turbo phase of dynamic turbo mode. Then, - * it's been a while since the last background - * scan and if no data frames have come through - * recently, kick off a scan. Note that this - * is the mechanism by which a background scan - * is started _and_ continued each time we - * return on-channel to receive a beacon from - * our ap. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) { - ieee80211_add_scan(vap, &scan, wh, - subtype, rssi, nf); - } else if (contbgscan(vap)) { - ieee80211_bg_scan(vap, 0); - } else if (startbgscan(vap)) { - vap->iv_stats.is_scan_bg++; -#if 0 - /* wakeup if we are sleeing */ - ieee80211_set_pwrsave(vap, 0); -#endif - ieee80211_bg_scan(vap, 0); - } - return; - } - /* - * If scanning, just pass information to the scan module. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) { - if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) { - /* - * Actively scanning a channel marked passive; - * send a probe request now that we know there - * is 802.11 traffic present. - * - * XXX check if the beacon we recv'd gives - * us what we need and suppress the probe req - */ - ieee80211_probe_curchan(vap, 1); - ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; - } - ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf); - return; - } - break; - } - - case IEEE80211_FC0_SUBTYPE_AUTH: { - uint16_t algo, seq, status; - /* - * auth frame format - * [2] algorithm - * [2] sequence - * [2] status - * [tlv*] challenge - */ - IEEE80211_VERIFY_LENGTH(efrm - frm, 6, return); - algo = le16toh(*(uint16_t *)frm); - seq = le16toh(*(uint16_t *)(frm + 2)); - status = le16toh(*(uint16_t *)(frm + 4)); - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_AUTH, wh->i_addr2, - "recv auth frame with algorithm %d seq %d", algo, seq); - - if (vap->iv_flags & IEEE80211_F_COUNTERM) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_AUTH | IEEE80211_MSG_CRYPTO, - wh, "auth", "%s", "TKIP countermeasures enabled"); - vap->iv_stats.is_rx_auth_countermeasures++; - if (vap->iv_opmode == IEEE80211_M_HOSTAP) { - ieee80211_send_error(ni, wh->i_addr2, - IEEE80211_FC0_SUBTYPE_AUTH, - IEEE80211_REASON_MIC_FAILURE); - } - return; - } - if (algo == IEEE80211_AUTH_ALG_SHARED) - sta_auth_shared(ni, wh, frm + 6, efrm, rssi, nf, - seq, status); - else if (algo == IEEE80211_AUTH_ALG_OPEN) - sta_auth_open(ni, wh, rssi, nf, seq, status); - else { - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "auth", "unsupported alg %d", algo); - vap->iv_stats.is_rx_auth_unsupported++; - return; - } - break; - } - - case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: { - uint16_t capinfo, associd; - uint16_t status; - - if (vap->iv_state != IEEE80211_S_ASSOC) { - vap->iv_stats.is_rx_mgtdiscard++; - return; - } - - /* - * asresp frame format - * [2] capability information - * [2] status - * [2] association ID - * [tlv] supported rates - * [tlv] extended supported rates - * [tlv] WME - * [tlv] HT capabilities - * [tlv] HT info - */ - IEEE80211_VERIFY_LENGTH(efrm - frm, 6, return); - ni = vap->iv_bss; - capinfo = le16toh(*(uint16_t *)frm); - frm += 2; - status = le16toh(*(uint16_t *)frm); - frm += 2; - if (status != 0) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC, - wh->i_addr2, "%sassoc failed (reason %d)", - ISREASSOC(subtype) ? "re" : "", status); - vap->iv_stats.is_rx_auth_fail++; /* XXX */ - return; - } - associd = le16toh(*(uint16_t *)frm); - frm += 2; - - rates = xrates = wme = htcap = htinfo = NULL; - while (efrm - frm > 1) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); - switch (*frm) { - case IEEE80211_ELEMID_RATES: - rates = frm; - break; - case IEEE80211_ELEMID_XRATES: - xrates = frm; - break; - case IEEE80211_ELEMID_HTCAP: - htcap = frm; - break; - case IEEE80211_ELEMID_HTINFO: - htinfo = frm; - break; - case IEEE80211_ELEMID_VENDOR: - if (iswmeoui(frm)) - wme = frm; - else if (vap->iv_flags_ht & IEEE80211_FHT_HTCOMPAT) { - /* - * Accept pre-draft HT ie's if the - * standard ones have not been seen. - */ - if (ishtcapoui(frm)) { - if (htcap == NULL) - htcap = frm; - } else if (ishtinfooui(frm)) { - if (htinfo == NULL) - htinfo = frm; - } - } - /* XXX Atheros OUI support */ - break; - } - frm += frm[1] + 2; - } - - IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return); - if (xrates != NULL) - IEEE80211_VERIFY_ELEMENT(xrates, - IEEE80211_RATE_MAXSIZE - rates[1], return); - rate = ieee80211_setup_rates(ni, rates, xrates, - IEEE80211_F_JOIN | - IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | - IEEE80211_F_DONEGO | IEEE80211_F_DODEL); - if (rate & IEEE80211_RATE_BASIC) { - IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC, - wh->i_addr2, - "%sassoc failed (rate set mismatch)", - ISREASSOC(subtype) ? "re" : ""); - vap->iv_stats.is_rx_assoc_norate++; - ieee80211_new_state(vap, IEEE80211_S_SCAN, - IEEE80211_SCAN_FAIL_STATUS); - return; - } - - ni->ni_capinfo = capinfo; - ni->ni_associd = associd; - if (ni->ni_jointime == 0) - ni->ni_jointime = time_uptime; - if (wme != NULL && - ieee80211_parse_wmeparams(vap, wme, wh) >= 0) { - ni->ni_flags |= IEEE80211_NODE_QOS; - ieee80211_wme_updateparams(vap); - } else - ni->ni_flags &= ~IEEE80211_NODE_QOS; - /* - * Setup HT state according to the negotiation. - * - * NB: shouldn't need to check if HT use is enabled but some - * ap's send back HT ie's even when we don't indicate we - * are HT capable in our AssocReq. - */ - if (htcap != NULL && htinfo != NULL && - (vap->iv_flags_ht & IEEE80211_FHT_HT)) { - ieee80211_ht_node_init(ni); - ieee80211_ht_updateparams(ni, htcap, htinfo); - ieee80211_setup_htrates(ni, htcap, - IEEE80211_F_JOIN | IEEE80211_F_DOBRS); - ieee80211_setup_basic_htrates(ni, htinfo); - ieee80211_node_setuptxparms(ni); - ieee80211_ratectl_node_init(ni); - } else { -#ifdef IEEE80211_SUPPORT_SUPERG - if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_ATH)) - ieee80211_ff_node_init(ni); -#endif - } - /* - * Configure state now that we are associated. - * - * XXX may need different/additional driver callbacks? - */ - if (IEEE80211_IS_CHAN_A(ic->ic_curchan) || - (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) { - ic->ic_flags |= IEEE80211_F_SHPREAMBLE; - ic->ic_flags &= ~IEEE80211_F_USEBARKER; - } else { - ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; - ic->ic_flags |= IEEE80211_F_USEBARKER; - } - ieee80211_set_shortslottime(ic, - IEEE80211_IS_CHAN_A(ic->ic_curchan) || - (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)); - /* - * Honor ERP protection. - * - * NB: ni_erp should zero for non-11g operation. - */ - if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) && - (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION)) - ic->ic_flags |= IEEE80211_F_USEPROT; - else - ic->ic_flags &= ~IEEE80211_F_USEPROT; - IEEE80211_NOTE_MAC(vap, - IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, wh->i_addr2, - "%sassoc success at aid %d: %s preamble, %s slot time%s%s%s%s%s%s%s%s", - ISREASSOC(subtype) ? "re" : "", - IEEE80211_NODE_AID(ni), - ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long", - ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long", - ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "", - ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "", - ni->ni_flags & IEEE80211_NODE_HT ? - (ni->ni_chw == 40 ? ", HT40" : ", HT20") : "", - ni->ni_flags & IEEE80211_NODE_AMPDU ? " (+AMPDU)" : "", - ni->ni_flags & IEEE80211_NODE_MIMO_RTS ? " (+SMPS-DYN)" : - ni->ni_flags & IEEE80211_NODE_MIMO_PS ? " (+SMPS)" : "", - ni->ni_flags & IEEE80211_NODE_RIFS ? " (+RIFS)" : "", - IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF) ? - ", fast-frames" : "", - IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_TURBOP) ? - ", turbo" : "" - ); - ieee80211_new_state(vap, IEEE80211_S_RUN, subtype); - break; - } - - case IEEE80211_FC0_SUBTYPE_DEAUTH: { - uint16_t reason; - - if (vap->iv_state == IEEE80211_S_SCAN) { - vap->iv_stats.is_rx_mgtdiscard++; - return; - } - if (!IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr)) { - /* NB: can happen when in promiscuous mode */ - vap->iv_stats.is_rx_mgtdiscard++; - break; - } - - /* - * deauth frame format - * [2] reason - */ - IEEE80211_VERIFY_LENGTH(efrm - frm, 2, return); - reason = le16toh(*(uint16_t *)frm); - - vap->iv_stats.is_rx_deauth++; - vap->iv_stats.is_rx_deauth_code = reason; - IEEE80211_NODE_STAT(ni, rx_deauth); - - IEEE80211_NOTE(vap, IEEE80211_MSG_AUTH, ni, - "recv deauthenticate (reason %d)", reason); - ieee80211_new_state(vap, IEEE80211_S_AUTH, - (reason << 8) | IEEE80211_FC0_SUBTYPE_DEAUTH); - break; - } - - case IEEE80211_FC0_SUBTYPE_DISASSOC: { - uint16_t reason; - - if (vap->iv_state != IEEE80211_S_RUN && - vap->iv_state != IEEE80211_S_ASSOC && - vap->iv_state != IEEE80211_S_AUTH) { - vap->iv_stats.is_rx_mgtdiscard++; - return; - } - if (!IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr)) { - /* NB: can happen when in promiscuous mode */ - vap->iv_stats.is_rx_mgtdiscard++; - break; - } - - /* - * disassoc frame format - * [2] reason - */ - IEEE80211_VERIFY_LENGTH(efrm - frm, 2, return); - reason = le16toh(*(uint16_t *)frm); - - vap->iv_stats.is_rx_disassoc++; - vap->iv_stats.is_rx_disassoc_code = reason; - IEEE80211_NODE_STAT(ni, rx_disassoc); - - IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, - "recv disassociate (reason %d)", reason); - ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0); - break; - } - - case IEEE80211_FC0_SUBTYPE_ACTION: - case IEEE80211_FC0_SUBTYPE_ACTION_NOACK: - if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) && - !IEEE80211_IS_MULTICAST(wh->i_addr1)) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not for us"); - vap->iv_stats.is_rx_mgtdiscard++; - } else if (vap->iv_state != IEEE80211_S_RUN) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "wrong state %s", - ieee80211_state_name[vap->iv_state]); - vap->iv_stats.is_rx_mgtdiscard++; - } else { - if (ieee80211_parse_action(ni, m0) == 0) - (void)ic->ic_recv_action(ni, wh, frm, efrm); - } - break; - - case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - case IEEE80211_FC0_SUBTYPE_ATIM: - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not handled"); - vap->iv_stats.is_rx_mgtdiscard++; - break; - - default: - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "mgt", "subtype 0x%x not handled", subtype); - vap->iv_stats.is_rx_badsubtype++; - break; - } -#undef ISREASSOC -#undef ISPROBE -} - -static void -sta_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype) -{ - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_BAR: - ieee80211_recv_bar(ni, m); - break; - } -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_sta.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_sta.h deleted file mode 100644 index d701600ad9..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_sta.h +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_STA_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_STA_H_ - -/* - * Station-mode implementation definitions. - */ -void ieee80211_sta_attach(struct ieee80211com *); -void ieee80211_sta_detach(struct ieee80211com *); -void ieee80211_sta_vattach(struct ieee80211vap *); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_STA_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_superg.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_superg.c deleted file mode 100644 index dfe6f192f8..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_superg.c +++ /dev/null @@ -1,900 +0,0 @@ -/*- - * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* - * Atheros fast-frame encapsulation format. - * FF max payload: - * 802.2 + FFHDR + HPAD + 802.3 + 802.2 + 1500 + SPAD + 802.3 + 802.2 + 1500: - * 8 + 4 + 4 + 14 + 8 + 1500 + 6 + 14 + 8 + 1500 - * = 3066 - */ -/* fast frame header is 32-bits */ -#define ATH_FF_PROTO 0x0000003f /* protocol */ -#define ATH_FF_PROTO_S 0 -#define ATH_FF_FTYPE 0x000000c0 /* frame type */ -#define ATH_FF_FTYPE_S 6 -#define ATH_FF_HLEN32 0x00000300 /* optional hdr length */ -#define ATH_FF_HLEN32_S 8 -#define ATH_FF_SEQNUM 0x001ffc00 /* sequence number */ -#define ATH_FF_SEQNUM_S 10 -#define ATH_FF_OFFSET 0xffe00000 /* offset to 2nd payload */ -#define ATH_FF_OFFSET_S 21 - -#define ATH_FF_MAX_HDR_PAD 4 -#define ATH_FF_MAX_SEP_PAD 6 -#define ATH_FF_MAX_HDR 30 - -#define ATH_FF_PROTO_L2TUNNEL 0 /* L2 tunnel protocol */ -#define ATH_FF_ETH_TYPE 0x88bd /* Ether type for encapsulated frames */ -#define ATH_FF_SNAP_ORGCODE_0 0x00 -#define ATH_FF_SNAP_ORGCODE_1 0x03 -#define ATH_FF_SNAP_ORGCODE_2 0x7f - -#define ATH_FF_TXQMIN 2 /* min txq depth for staging */ -#define ATH_FF_TXQMAX 50 /* maximum # of queued frames allowed */ -#define ATH_FF_STAGEMAX 5 /* max waiting period for staged frame*/ - -#define ETHER_HEADER_COPY(dst, src) \ - memcpy(dst, src, sizeof(struct ether_header)) - -static int ieee80211_ffppsmin = 2; /* pps threshold for ff aggregation */ -SYSCTL_INT(_net_wlan, OID_AUTO, ffppsmin, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_ffppsmin, 0, "min packet rate before fast-frame staging"); -static int ieee80211_ffagemax = -1; /* max time frames held on stage q */ -SYSCTL_PROC(_net_wlan, OID_AUTO, ffagemax, CTLTYPE_INT | CTLFLAG_RW, - &ieee80211_ffagemax, 0, ieee80211_sysctl_msecs_ticks, "I", - "max hold time for fast-frame staging (ms)"); - -void -ieee80211_superg_attach(struct ieee80211com *ic) -{ - struct ieee80211_superg *sg; - - if (ic->ic_caps & IEEE80211_C_FF) { - sg = (struct ieee80211_superg *) malloc( - sizeof(struct ieee80211_superg), M_80211_VAP, - M_NOWAIT | M_ZERO); - if (sg == NULL) { - printf("%s: cannot allocate SuperG state block\n", - __func__); - return; - } - ic->ic_superg = sg; - } - ieee80211_ffagemax = msecs_to_ticks(150); -} - -void -ieee80211_superg_detach(struct ieee80211com *ic) -{ - if (ic->ic_superg != NULL) { - free(ic->ic_superg, M_80211_VAP); - ic->ic_superg = NULL; - } -} - -void -ieee80211_superg_vattach(struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - - if (ic->ic_superg == NULL) /* NB: can't do fast-frames w/o state */ - vap->iv_caps &= ~IEEE80211_C_FF; - if (vap->iv_caps & IEEE80211_C_FF) - vap->iv_flags |= IEEE80211_F_FF; - /* NB: we only implement sta mode */ - if (vap->iv_opmode == IEEE80211_M_STA && - (vap->iv_caps & IEEE80211_C_TURBOP)) - vap->iv_flags |= IEEE80211_F_TURBOP; -} - -void -ieee80211_superg_vdetach(struct ieee80211vap *vap) -{ -} - -#define ATH_OUI_BYTES 0x00, 0x03, 0x7f -/* - * Add a WME information element to a frame. - */ -uint8_t * -ieee80211_add_ath(uint8_t *frm, uint8_t caps, ieee80211_keyix defkeyix) -{ - static const struct ieee80211_ath_ie info = { - .ath_id = IEEE80211_ELEMID_VENDOR, - .ath_len = sizeof(struct ieee80211_ath_ie) - 2, - .ath_oui = { ATH_OUI_BYTES }, - .ath_oui_type = ATH_OUI_TYPE, - .ath_oui_subtype= ATH_OUI_SUBTYPE, - .ath_version = ATH_OUI_VERSION, - }; - struct ieee80211_ath_ie *ath = (struct ieee80211_ath_ie *) frm; - - memcpy(frm, &info, sizeof(info)); - ath->ath_capability = caps; - if (defkeyix != IEEE80211_KEYIX_NONE) { - ath->ath_defkeyix[0] = (defkeyix & 0xff); - ath->ath_defkeyix[1] = ((defkeyix >> 8) & 0xff); - } else { - ath->ath_defkeyix[0] = 0xff; - ath->ath_defkeyix[1] = 0x7f; - } - return frm + sizeof(info); -} -#undef ATH_OUI_BYTES - -uint8_t * -ieee80211_add_athcaps(uint8_t *frm, const struct ieee80211_node *bss) -{ - const struct ieee80211vap *vap = bss->ni_vap; - - return ieee80211_add_ath(frm, - vap->iv_flags & IEEE80211_F_ATHEROS, - ((vap->iv_flags & IEEE80211_F_WPA) == 0 && - bss->ni_authmode != IEEE80211_AUTH_8021X) ? - vap->iv_def_txkey : IEEE80211_KEYIX_NONE); -} - -void -ieee80211_parse_ath(struct ieee80211_node *ni, uint8_t *ie) -{ - const struct ieee80211_ath_ie *ath = - (const struct ieee80211_ath_ie *) ie; - - ni->ni_ath_flags = ath->ath_capability; - ni->ni_ath_defkeyix = LE_READ_2(&ath->ath_defkeyix); -} - -int -ieee80211_parse_athparams(struct ieee80211_node *ni, uint8_t *frm, - const struct ieee80211_frame *wh) -{ - struct ieee80211vap *vap = ni->ni_vap; - const struct ieee80211_ath_ie *ath; - u_int len = frm[1]; - int capschanged; - uint16_t defkeyix; - - if (len < sizeof(struct ieee80211_ath_ie)-2) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_SUPERG, - wh, "Atheros", "too short, len %u", len); - return -1; - } - ath = (const struct ieee80211_ath_ie *)frm; - capschanged = (ni->ni_ath_flags != ath->ath_capability); - defkeyix = LE_READ_2(ath->ath_defkeyix); - if (capschanged || defkeyix != ni->ni_ath_defkeyix) { - ni->ni_ath_flags = ath->ath_capability; - ni->ni_ath_defkeyix = defkeyix; - IEEE80211_NOTE(vap, IEEE80211_MSG_SUPERG, ni, - "ath ie change: new caps 0x%x defkeyix 0x%x", - ni->ni_ath_flags, ni->ni_ath_defkeyix); - } - if (IEEE80211_ATH_CAP(vap, ni, ATHEROS_CAP_TURBO_PRIME)) { - uint16_t curflags, newflags; - - /* - * Check for turbo mode switch. Calculate flags - * for the new mode and effect the switch. - */ - newflags = curflags = vap->iv_ic->ic_bsschan->ic_flags; - /* NB: BOOST is not in ic_flags, so get it from the ie */ - if (ath->ath_capability & ATHEROS_CAP_BOOST) - newflags |= IEEE80211_CHAN_TURBO; - else - newflags &= ~IEEE80211_CHAN_TURBO; - if (newflags != curflags) - ieee80211_dturbo_switch(vap, newflags); - } - return capschanged; -} - -/* - * Decap the encapsulated frame pair and dispatch the first - * for delivery. The second frame is returned for delivery - * via the normal path. - */ -struct mbuf * -ieee80211_ff_decap(struct ieee80211_node *ni, struct mbuf *m) -{ -#define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc)) -#define MS(x,f) (((x) & f) >> f##_S) - struct ieee80211vap *vap = ni->ni_vap; - struct llc *llc; - uint32_t ath; - struct mbuf *n; - int framelen; - - /* NB: we assume caller does this check for us */ - KASSERT(IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF), - ("ff not negotiated")); - /* - * Check for fast-frame tunnel encapsulation. - */ - if (m->m_pkthdr.len < 3*FF_LLC_SIZE) - return m; - if (m->m_len < FF_LLC_SIZE && - (m = m_pullup(m, FF_LLC_SIZE)) == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, "fast-frame", - "%s", "m_pullup(llc) failed"); - vap->iv_stats.is_rx_tooshort++; - return NULL; - } - llc = (struct llc *)(mtod(m, uint8_t *) + - sizeof(struct ether_header)); - if (llc->llc_snap.ether_type != htons(ATH_FF_ETH_TYPE)) - return m; - m_adj(m, FF_LLC_SIZE); - m_copydata(m, 0, sizeof(uint32_t), (caddr_t) &ath); - if (MS(ath, ATH_FF_PROTO) != ATH_FF_PROTO_L2TUNNEL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, "fast-frame", - "unsupport tunnel protocol, header 0x%x", ath); - vap->iv_stats.is_ff_badhdr++; - m_freem(m); - return NULL; - } - /* NB: skip header and alignment padding */ - m_adj(m, roundup(sizeof(uint32_t) - 2, 4) + 2); - - vap->iv_stats.is_ff_decap++; - - /* - * Decap the first frame, bust it apart from the - * second and deliver; then decap the second frame - * and return it to the caller for normal delivery. - */ - m = ieee80211_decap1(m, &framelen); - if (m == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, "fast-frame", "%s", "first decap failed"); - vap->iv_stats.is_ff_tooshort++; - return NULL; - } - n = m_split(m, framelen, M_NOWAIT); - if (n == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, "fast-frame", - "%s", "unable to split encapsulated frames"); - vap->iv_stats.is_ff_split++; - m_freem(m); /* NB: must reclaim */ - return NULL; - } - /* XXX not right for WDS */ - vap->iv_deliver_data(vap, ni, m); /* 1st of pair */ - - /* - * Decap second frame. - */ - m_adj(n, roundup2(framelen, 4) - framelen); /* padding */ - n = ieee80211_decap1(n, &framelen); - if (n == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, "fast-frame", "%s", "second decap failed"); - vap->iv_stats.is_ff_tooshort++; - } - /* XXX verify framelen against mbuf contents */ - return n; /* 2nd delivered by caller */ -#undef MS -#undef FF_LLC_SIZE -} - -/* - * Do Ethernet-LLC encapsulation for each payload in a fast frame - * tunnel encapsulation. The frame is assumed to have an Ethernet - * header at the front that must be stripped before prepending the - * LLC followed by the Ethernet header passed in (with an Ethernet - * type that specifies the payload size). - */ -static struct mbuf * -ff_encap1(struct ieee80211vap *vap, struct mbuf *m, - const struct ether_header *eh) -{ - struct llc *llc; - uint16_t payload; - - /* XXX optimize by combining m_adj+M_PREPEND */ - m_adj(m, sizeof(struct ether_header) - sizeof(struct llc)); - llc = mtod(m, struct llc *); - llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; - llc->llc_control = LLC_UI; - llc->llc_snap.org_code[0] = 0; - llc->llc_snap.org_code[1] = 0; - llc->llc_snap.org_code[2] = 0; - llc->llc_snap.ether_type = eh->ether_type; - payload = m->m_pkthdr.len; /* NB: w/o Ethernet header */ - - M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT); - if (m == NULL) { /* XXX cannot happen */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG, - "%s: no space for ether_header\n", __func__); - vap->iv_stats.is_tx_nobuf++; - return NULL; - } - ETHER_HEADER_COPY(mtod(m, void *), eh); - mtod(m, struct ether_header *)->ether_type = htons(payload); - return m; -} - -/* - * Fast frame encapsulation. There must be two packets - * chained with m_nextpkt. We do header adjustment for - * each, add the tunnel encapsulation, and then concatenate - * the mbuf chains to form a single frame for transmission. - */ -struct mbuf * -ieee80211_ff_encap(struct ieee80211vap *vap, struct mbuf *m1, int hdrspace, - struct ieee80211_key *key) -{ - struct mbuf *m2; - struct ether_header eh1, eh2; - struct llc *llc; - struct mbuf *m; - int pad; - - m2 = m1->m_nextpkt; - if (m2 == NULL) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG, - "%s: only one frame\n", __func__); - goto bad; - } - m1->m_nextpkt = NULL; - /* - * Include fast frame headers in adjusting header layout. - */ - KASSERT(m1->m_len >= sizeof(eh1), ("no ethernet header!")); - ETHER_HEADER_COPY(&eh1, mtod(m1, caddr_t)); - m1 = ieee80211_mbuf_adjust(vap, - hdrspace + sizeof(struct llc) + sizeof(uint32_t) + 2 + - sizeof(struct ether_header), - key, m1); - if (m1 == NULL) { - /* NB: ieee80211_mbuf_adjust handles msgs+statistics */ - m_freem(m2); - goto bad; - } - - /* - * Copy second frame's Ethernet header out of line - * and adjust for encapsulation headers. Note that - * we make room for padding in case there isn't room - * at the end of first frame. - */ - KASSERT(m2->m_len >= sizeof(eh2), ("no ethernet header!")); - ETHER_HEADER_COPY(&eh2, mtod(m2, caddr_t)); - m2 = ieee80211_mbuf_adjust(vap, - ATH_FF_MAX_HDR_PAD + sizeof(struct ether_header), - NULL, m2); - if (m2 == NULL) { - /* NB: ieee80211_mbuf_adjust handles msgs+statistics */ - goto bad; - } - - /* - * Now do tunnel encapsulation. First, each - * frame gets a standard encapsulation. - */ - m1 = ff_encap1(vap, m1, &eh1); - if (m1 == NULL) - goto bad; - m2 = ff_encap1(vap, m2, &eh2); - if (m2 == NULL) - goto bad; - - /* - * Pad leading frame to a 4-byte boundary. If there - * is space at the end of the first frame, put it - * there; otherwise prepend to the front of the second - * frame. We know doing the second will always work - * because we reserve space above. We prefer appending - * as this typically has better DMA alignment properties. - */ - for (m = m1; m->m_next != NULL; m = m->m_next) - ; - pad = roundup2(m1->m_pkthdr.len, 4) - m1->m_pkthdr.len; - if (pad) { - if (M_TRAILINGSPACE(m) < pad) { /* prepend to second */ - m2->m_data -= pad; - m2->m_len += pad; - m2->m_pkthdr.len += pad; - } else { /* append to first */ - m->m_len += pad; - m1->m_pkthdr.len += pad; - } - } - - /* - * Now, stick 'em together and prepend the tunnel headers; - * first the Atheros tunnel header (all zero for now) and - * then a special fast frame LLC. - * - * XXX optimize by prepending together - */ - m->m_next = m2; /* NB: last mbuf from above */ - m1->m_pkthdr.len += m2->m_pkthdr.len; - M_PREPEND(m1, sizeof(uint32_t)+2, M_DONTWAIT); - if (m1 == NULL) { /* XXX cannot happen */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG, - "%s: no space for tunnel header\n", __func__); - vap->iv_stats.is_tx_nobuf++; - return NULL; - } - memset(mtod(m1, void *), 0, sizeof(uint32_t)+2); - - M_PREPEND(m1, sizeof(struct llc), M_DONTWAIT); - if (m1 == NULL) { /* XXX cannot happen */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG, - "%s: no space for llc header\n", __func__); - vap->iv_stats.is_tx_nobuf++; - return NULL; - } - llc = mtod(m1, struct llc *); - llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; - llc->llc_control = LLC_UI; - llc->llc_snap.org_code[0] = ATH_FF_SNAP_ORGCODE_0; - llc->llc_snap.org_code[1] = ATH_FF_SNAP_ORGCODE_1; - llc->llc_snap.org_code[2] = ATH_FF_SNAP_ORGCODE_2; - llc->llc_snap.ether_type = htons(ATH_FF_ETH_TYPE); - - vap->iv_stats.is_ff_encap++; - - return m1; -bad: - if (m1 != NULL) - m_freem(m1); - if (m2 != NULL) - m_freem(m2); - return NULL; -} - -static void -ff_transmit(struct ieee80211_node *ni, struct mbuf *m) -{ - struct ieee80211vap *vap = ni->ni_vap; - int error; - - /* encap and xmit */ - m = ieee80211_encap(vap, ni, m); - if (m != NULL) { - struct ifnet *ifp = vap->iv_ifp; - struct ifnet *parent = ni->ni_ic->ic_ifp; - - error = parent->if_transmit(parent, m); - if (error != 0) { - /* NB: IFQ_HANDOFF reclaims mbuf */ - ieee80211_free_node(ni); - } else { - ifp->if_opackets++; - } - } else - ieee80211_free_node(ni); -} - -/* - * Flush frames to device; note we re-use the linked list - * the frames were stored on and use the sentinel (unchanged) - * which may be non-NULL. - */ -static void -ff_flush(struct mbuf *head, struct mbuf *last) -{ - struct mbuf *m, *next; - struct ieee80211_node *ni; - struct ieee80211vap *vap; - - for (m = head; m != last; m = next) { - next = m->m_nextpkt; - m->m_nextpkt = NULL; - - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - vap = ni->ni_vap; - - IEEE80211_NOTE(vap, IEEE80211_MSG_SUPERG, ni, - "%s: flush frame, age %u", __func__, M_AGE_GET(m)); - vap->iv_stats.is_ff_flush++; - - ff_transmit(ni, m); - } -} - -/* - * Age frames on the staging queue. - */ -void -ieee80211_ff_age(struct ieee80211com *ic, struct ieee80211_stageq *sq, - int quanta) -{ - struct ieee80211_superg *sg = ic->ic_superg; - struct mbuf *m, *head; - struct ieee80211_node *ni; - struct ieee80211_tx_ampdu *tap; - - KASSERT(sq->head != NULL, ("stageq empty")); - - IEEE80211_LOCK(ic); - head = sq->head; - while ((m = sq->head) != NULL && M_AGE_GET(m) < quanta) { - /* clear tap ref to frame */ - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - tap = &ni->ni_tx_ampdu[M_WME_GETAC(m)]; - KASSERT(tap->txa_private == m, ("staging queue empty")); - tap->txa_private = NULL; - - sq->head = m->m_nextpkt; - sq->depth--; - sg->ff_stageqdepth--; - } - if (m == NULL) - sq->tail = NULL; - else - M_AGE_SUB(m, quanta); - IEEE80211_UNLOCK(ic); - - ff_flush(head, m); -} - -static void -stageq_add(struct ieee80211_stageq *sq, struct mbuf *m) -{ - int age = ieee80211_ffagemax; - if (sq->tail != NULL) { - sq->tail->m_nextpkt = m; - age -= M_AGE_GET(sq->head); - } else - sq->head = m; - KASSERT(age >= 0, ("age %d", age)); - M_AGE_SET(m, age); - m->m_nextpkt = NULL; - sq->tail = m; - sq->depth++; -} - -static void -stageq_remove(struct ieee80211_stageq *sq, struct mbuf *mstaged) -{ - struct mbuf *m, *mprev; - - mprev = NULL; - for (m = sq->head; m != NULL; m = m->m_nextpkt) { - if (m == mstaged) { - if (mprev == NULL) - sq->head = m->m_nextpkt; - else - mprev->m_nextpkt = m->m_nextpkt; - if (sq->tail == m) - sq->tail = mprev; - sq->depth--; - return; - } - mprev = m; - } - printf("%s: packet not found\n", __func__); -} - -static uint32_t -ff_approx_txtime(struct ieee80211_node *ni, - const struct mbuf *m1, const struct mbuf *m2) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211vap *vap = ni->ni_vap; - uint32_t framelen; - - /* - * Approximate the frame length to be transmitted. A swag to add - * the following maximal values to the skb payload: - * - 32: 802.11 encap + CRC - * - 24: encryption overhead (if wep bit) - * - 4 + 6: fast-frame header and padding - * - 16: 2 LLC FF tunnel headers - * - 14: 1 802.3 FF tunnel header (mbuf already accounts for 2nd) - */ - framelen = m1->m_pkthdr.len + 32 + - ATH_FF_MAX_HDR_PAD + ATH_FF_MAX_SEP_PAD + ATH_FF_MAX_HDR; - if (vap->iv_flags & IEEE80211_F_PRIVACY) - framelen += 24; - if (m2 != NULL) - framelen += m2->m_pkthdr.len; - return ieee80211_compute_duration(ic->ic_rt, framelen, ni->ni_txrate, 0); -} - -/* - * Check if the supplied frame can be partnered with an existing - * or pending frame. Return a reference to any frame that should be - * sent on return; otherwise return NULL. - */ -struct mbuf * -ieee80211_ff_check(struct ieee80211_node *ni, struct mbuf *m) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_superg *sg = ic->ic_superg; - const int pri = M_WME_GETAC(m); - struct ieee80211_stageq *sq; - struct ieee80211_tx_ampdu *tap; - struct mbuf *mstaged; - uint32_t txtime, limit; - - /* - * Check if the supplied frame can be aggregated. - * - * NB: we allow EAPOL frames to be aggregated with other ucast traffic. - * Do 802.1x EAPOL frames proceed in the clear? Then they couldn't - * be aggregated with other types of frames when encryption is on? - */ - IEEE80211_LOCK(ic); - tap = &ni->ni_tx_ampdu[pri]; - mstaged = tap->txa_private; /* NB: we reuse AMPDU state */ - ieee80211_txampdu_count_packet(tap); - - /* - * When not in station mode never aggregate a multicast - * frame; this insures, for example, that a combined frame - * does not require multiple encryption keys. - */ - if (vap->iv_opmode != IEEE80211_M_STA && - ETHER_IS_MULTICAST(mtod(m, struct ether_header *)->ether_dhost)) { - /* XXX flush staged frame? */ - IEEE80211_UNLOCK(ic); - return m; - } - /* - * If there is no frame to combine with and the pps is - * too low; then do not attempt to aggregate this frame. - */ - if (mstaged == NULL && - ieee80211_txampdu_getpps(tap) < ieee80211_ffppsmin) { - IEEE80211_UNLOCK(ic); - return m; - } - sq = &sg->ff_stageq[pri]; - /* - * Check the txop limit to insure the aggregate fits. - */ - limit = IEEE80211_TXOP_TO_US( - ic->ic_wme.wme_chanParams.cap_wmeParams[pri].wmep_txopLimit); - if (limit != 0 && - (txtime = ff_approx_txtime(ni, m, mstaged)) > limit) { - /* - * Aggregate too long, return to the caller for direct - * transmission. In addition, flush any pending frame - * before sending this one. - */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG, - "%s: txtime %u exceeds txop limit %u\n", - __func__, txtime, limit); - - tap->txa_private = NULL; - if (mstaged != NULL) - stageq_remove(sq, mstaged); - IEEE80211_UNLOCK(ic); - - if (mstaged != NULL) { - IEEE80211_NOTE(vap, IEEE80211_MSG_SUPERG, ni, - "%s: flush staged frame", __func__); - /* encap and xmit */ - ff_transmit(ni, mstaged); - } - return m; /* NB: original frame */ - } - /* - * An aggregation candidate. If there's a frame to partner - * with then combine and return for processing. Otherwise - * save this frame and wait for a partner to show up (or - * the frame to be flushed). Note that staged frames also - * hold their node reference. - */ - if (mstaged != NULL) { - tap->txa_private = NULL; - stageq_remove(sq, mstaged); - IEEE80211_UNLOCK(ic); - - IEEE80211_NOTE(vap, IEEE80211_MSG_SUPERG, ni, - "%s: aggregate fast-frame", __func__); - /* - * Release the node reference; we only need - * the one already in mstaged. - */ - KASSERT(mstaged->m_pkthdr.rcvif == (void *)ni, - ("rcvif %p ni %p", mstaged->m_pkthdr.rcvif, ni)); - ieee80211_free_node(ni); - - m->m_nextpkt = NULL; - mstaged->m_nextpkt = m; - mstaged->m_flags |= M_FF; /* NB: mark for encap work */ - } else { - KASSERT(tap->txa_private == NULL, - ("txa_private %p", tap->txa_private)); - tap->txa_private = m; - - stageq_add(sq, m); - sg->ff_stageqdepth++; - IEEE80211_UNLOCK(ic); - - IEEE80211_NOTE(vap, IEEE80211_MSG_SUPERG, ni, - "%s: stage frame, %u queued", __func__, sq->depth); - /* NB: mstaged is NULL */ - } - return mstaged; -} - -void -ieee80211_ff_node_init(struct ieee80211_node *ni) -{ - /* - * Clean FF state on re-associate. This handles the case - * where a station leaves w/o notifying us and then returns - * before node is reaped for inactivity. - */ - ieee80211_ff_node_cleanup(ni); -} - -void -ieee80211_ff_node_cleanup(struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_superg *sg = ic->ic_superg; - struct ieee80211_tx_ampdu *tap; - struct mbuf *m, *head; - int ac; - - IEEE80211_LOCK(ic); - head = NULL; - for (ac = 0; ac < WME_NUM_AC; ac++) { - tap = &ni->ni_tx_ampdu[ac]; - m = tap->txa_private; - if (m != NULL) { - tap->txa_private = NULL; - stageq_remove(&sg->ff_stageq[ac], m); - m->m_nextpkt = head; - head = m; - } - } - IEEE80211_UNLOCK(ic); - - for (m = head; m != NULL; m = m->m_nextpkt) { - m_freem(m); - ieee80211_free_node(ni); - } -} - -/* - * Switch between turbo and non-turbo operating modes. - * Use the specified channel flags to locate the new - * channel, update 802.11 state, and then call back into - * the driver to effect the change. - */ -void -ieee80211_dturbo_switch(struct ieee80211vap *vap, int newflags) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_channel *chan; - - chan = ieee80211_find_channel(ic, ic->ic_bsschan->ic_freq, newflags); - if (chan == NULL) { /* XXX should not happen */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG, - "%s: no channel with freq %u flags 0x%x\n", - __func__, ic->ic_bsschan->ic_freq, newflags); - return; - } - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG, - "%s: %s -> %s (freq %u flags 0x%x)\n", __func__, - ieee80211_phymode_name[ieee80211_chan2mode(ic->ic_bsschan)], - ieee80211_phymode_name[ieee80211_chan2mode(chan)], - chan->ic_freq, chan->ic_flags); - - ic->ic_bsschan = chan; - ic->ic_prevchan = ic->ic_curchan; - ic->ic_curchan = chan; - ic->ic_rt = ieee80211_get_ratetable(chan); - ic->ic_set_channel(ic); - ieee80211_radiotap_chan_change(ic); - /* NB: do not need to reset ERP state 'cuz we're in sta mode */ -} - -/* - * Return the current ``state'' of an Atheros capbility. - * If associated in station mode report the negotiated - * setting. Otherwise report the current setting. - */ -static int -getathcap(struct ieee80211vap *vap, int cap) -{ - if (vap->iv_opmode == IEEE80211_M_STA && - vap->iv_state == IEEE80211_S_RUN) - return IEEE80211_ATH_CAP(vap, vap->iv_bss, cap) != 0; - else - return (vap->iv_flags & cap) != 0; -} - -static int -superg_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - switch (ireq->i_type) { - case IEEE80211_IOC_FF: - ireq->i_val = getathcap(vap, IEEE80211_F_FF); - break; - case IEEE80211_IOC_TURBOP: - ireq->i_val = getathcap(vap, IEEE80211_F_TURBOP); - break; - default: - return ENOSYS; - } - return 0; -} -IEEE80211_IOCTL_GET(superg, superg_ioctl_get80211); - -static int -superg_ioctl_set80211(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - switch (ireq->i_type) { - case IEEE80211_IOC_FF: - if (ireq->i_val) { - if ((vap->iv_caps & IEEE80211_C_FF) == 0) - return EOPNOTSUPP; - vap->iv_flags |= IEEE80211_F_FF; - } else - vap->iv_flags &= ~IEEE80211_F_FF; - return ENETRESET; - case IEEE80211_IOC_TURBOP: - if (ireq->i_val) { - if ((vap->iv_caps & IEEE80211_C_TURBOP) == 0) - return EOPNOTSUPP; - vap->iv_flags |= IEEE80211_F_TURBOP; - } else - vap->iv_flags &= ~IEEE80211_F_TURBOP; - return ENETRESET; - default: - return ENOSYS; - } - return 0; -} -IEEE80211_IOCTL_SET(superg, superg_ioctl_set80211); diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_superg.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_superg.h deleted file mode 100644 index 7872da80ee..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_superg.h +++ /dev/null @@ -1,129 +0,0 @@ -/*- - * Copyright (c) 2009 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_SUPERG_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_SUPERG_H_ - -/* - * Atheros' 802.11 SuperG protocol support. - */ - -/* - * Atheros advanced capability information element. - */ -struct ieee80211_ath_ie { - uint8_t ath_id; /* IEEE80211_ELEMID_VENDOR */ - uint8_t ath_len; /* length in bytes */ - uint8_t ath_oui[3]; /* ATH_OUI */ - uint8_t ath_oui_type; /* ATH_OUI_TYPE */ - uint8_t ath_oui_subtype; /* ATH_OUI_SUBTYPE */ - uint8_t ath_version; /* spec revision */ - uint8_t ath_capability; /* capability info */ -#define ATHEROS_CAP_TURBO_PRIME 0x01 /* dynamic turbo--aka Turbo' */ -#define ATHEROS_CAP_COMPRESSION 0x02 /* data compression */ -#define ATHEROS_CAP_FAST_FRAME 0x04 /* fast (jumbo) frames */ -#define ATHEROS_CAP_XR 0x08 /* Xtended Range support */ -#define ATHEROS_CAP_AR 0x10 /* Advanded Radar support */ -#define ATHEROS_CAP_BURST 0x20 /* Bursting - not negotiated */ -#define ATHEROS_CAP_WME 0x40 /* CWMin tuning */ -#define ATHEROS_CAP_BOOST 0x80 /* use turbo/!turbo mode */ - uint8_t ath_defkeyix[2]; -} __packed; - -#define ATH_OUI_VERSION 0x00 -#define ATH_OUI_SUBTYPE 0x01 - -#ifdef _KERNEL -struct ieee80211_stageq { - struct mbuf *head; /* frames linked w/ m_nextpkt */ - struct mbuf *tail; /* last frame in queue */ - int depth; /* # items on head */ -}; - -struct ieee80211_superg { - /* fast-frames staging q */ - struct ieee80211_stageq ff_stageq[WME_NUM_AC]; - int ff_stageqdepth; /* cumulative depth */ -}; - -void ieee80211_superg_attach(struct ieee80211com *); -void ieee80211_superg_detach(struct ieee80211com *); -void ieee80211_superg_vattach(struct ieee80211vap *); -void ieee80211_superg_vdetach(struct ieee80211vap *); - -uint8_t *ieee80211_add_ath(uint8_t *, uint8_t, ieee80211_keyix); -uint8_t *ieee80211_add_athcaps(uint8_t *, const struct ieee80211_node *); -void ieee80211_parse_ath(struct ieee80211_node *, uint8_t *); -int ieee80211_parse_athparams(struct ieee80211_node *, uint8_t *, - const struct ieee80211_frame *); - -void ieee80211_ff_node_init(struct ieee80211_node *); -void ieee80211_ff_node_cleanup(struct ieee80211_node *); - -struct mbuf *ieee80211_ff_check(struct ieee80211_node *, struct mbuf *); -void ieee80211_ff_age(struct ieee80211com *, struct ieee80211_stageq *, - int quanta); - -static __inline void -ieee80211_ff_flush(struct ieee80211com *ic, int ac) -{ - struct ieee80211_superg *sg = ic->ic_superg; - - if (sg != NULL && sg->ff_stageq[ac].depth) - ieee80211_ff_age(ic, &sg->ff_stageq[ac], 0x7fffffff); -} - -static __inline void -ieee80211_ff_age_all(struct ieee80211com *ic, int quanta) -{ - struct ieee80211_superg *sg = ic->ic_superg; - - if (sg != NULL && sg->ff_stageqdepth) { - if (sg->ff_stageq[WME_AC_VO].depth) - ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_VO], quanta); - if (sg->ff_stageq[WME_AC_VI].depth) - ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_VI], quanta); - if (sg->ff_stageq[WME_AC_BE].depth) - ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_BE], quanta); - if (sg->ff_stageq[WME_AC_BK].depth) - ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_BK], quanta); - } -} - -struct mbuf *ieee80211_ff_encap(struct ieee80211vap *, struct mbuf *, - int, struct ieee80211_key *); - -struct mbuf *ieee80211_ff_decap(struct ieee80211_node *, struct mbuf *); - -static __inline struct mbuf * -ieee80211_decap_fastframe(struct ieee80211vap *vap, struct ieee80211_node *ni, - struct mbuf *m) -{ - return IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF) ? - ieee80211_ff_decap(ni, m) : m; -} -#endif /* _KERNEL */ -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_SUPERG_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_tdma.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_tdma.c deleted file mode 100644 index 8c191ab92b..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_tdma.c +++ /dev/null @@ -1,820 +0,0 @@ -/*- - * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting - * Copyright (c) 2007-2009 Intel Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifdef __FreeBSD__ -__FBSDID("$FreeBSD$"); -#endif - -/* - * IEEE 802.11 TDMA mode support. - */ -#include "opt_inet.h" -#include "opt_tdma.h" -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include - -#ifndef TDMA_SLOTLEN_DEFAULT -#define TDMA_SLOTLEN_DEFAULT 10*1000 /* 10ms */ -#endif -#ifndef TDMA_SLOTCNT_DEFAULT -#define TDMA_SLOTCNT_DEFAULT 2 /* 2x (pt-to-pt) */ -#endif -#ifndef TDMA_BINTVAL_DEFAULT -#define TDMA_BINTVAL_DEFAULT 5 /* 5x ~= 100TU beacon intvl */ -#endif -#ifndef TDMA_TXRATE_11B_DEFAULT -#define TDMA_TXRATE_11B_DEFAULT 2*11 -#endif -#ifndef TDMA_TXRATE_11G_DEFAULT -#define TDMA_TXRATE_11G_DEFAULT 2*24 -#endif -#ifndef TDMA_TXRATE_11A_DEFAULT -#define TDMA_TXRATE_11A_DEFAULT 2*24 -#endif -#ifndef TDMA_TXRATE_TURBO_DEFAULT -#define TDMA_TXRATE_TURBO_DEFAULT 2*24 -#endif -#ifndef TDMA_TXRATE_HALF_DEFAULT -#define TDMA_TXRATE_HALF_DEFAULT 2*12 -#endif -#ifndef TDMA_TXRATE_QUARTER_DEFAULT -#define TDMA_TXRATE_QUARTER_DEFAULT 2*6 -#endif -#ifndef TDMA_TXRATE_11NA_DEFAULT -#define TDMA_TXRATE_11NA_DEFAULT (4 | IEEE80211_RATE_MCS) -#endif -#ifndef TDMA_TXRATE_11NG_DEFAULT -#define TDMA_TXRATE_11NG_DEFAULT (4 | IEEE80211_RATE_MCS) -#endif - -#define TDMA_VERSION_VALID(_version) \ - (TDMA_VERSION_V2 <= (_version) && (_version) <= TDMA_VERSION) -#define TDMA_SLOTCNT_VALID(_slotcnt) \ - (2 <= (_slotcnt) && (_slotcnt) <= TDMA_MAXSLOTS) -/* XXX magic constants */ -#define TDMA_SLOTLEN_VALID(_slotlen) \ - (2*100 <= (_slotlen) && (unsigned)(_slotlen) <= 0xfffff) -/* XXX probably should set a max */ -#define TDMA_BINTVAL_VALID(_bintval) (1 <= (_bintval)) - -/* - * This code is not prepared to handle more than 2 slots. - */ -CTASSERT(TDMA_MAXSLOTS == 2); - -static void tdma_vdetach(struct ieee80211vap *vap); -static int tdma_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static void tdma_beacon_miss(struct ieee80211vap *vap); -static void tdma_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int nf); -static int tdma_update(struct ieee80211vap *vap, - const struct ieee80211_tdma_param *tdma, struct ieee80211_node *ni, - int pickslot); -static int tdma_process_params(struct ieee80211_node *ni, - const u_int8_t *ie, int rssi, int nf, const struct ieee80211_frame *wh); - -static void -settxparms(struct ieee80211vap *vap, enum ieee80211_phymode mode, int rate) -{ - vap->iv_txparms[mode].ucastrate = rate; - vap->iv_txparms[mode].mcastrate = rate; -} - -static void -setackpolicy(struct ieee80211com *ic, int noack) -{ - struct ieee80211_wme_state *wme = &ic->ic_wme; - int ac; - - for (ac = 0; ac < WME_NUM_AC; ac++) { - wme->wme_chanParams.cap_wmeParams[ac].wmep_noackPolicy = noack; - wme->wme_wmeChanParams.cap_wmeParams[ac].wmep_noackPolicy = noack; - } -} - -void -ieee80211_tdma_vattach(struct ieee80211vap *vap) -{ - struct ieee80211_tdma_state *ts; - - KASSERT(vap->iv_caps & IEEE80211_C_TDMA, - ("not a tdma vap, caps 0x%x", vap->iv_caps)); - - ts = (struct ieee80211_tdma_state *) malloc( - sizeof(struct ieee80211_tdma_state), M_80211_VAP, M_NOWAIT | M_ZERO); - if (ts == NULL) { - printf("%s: cannot allocate TDMA state block\n", __func__); - /* NB: fall back to adhdemo mode */ - vap->iv_caps &= ~IEEE80211_C_TDMA; - return; - } - /* NB: default configuration is passive so no beacons */ - ts->tdma_version = TDMA_VERSION; - ts->tdma_slotlen = TDMA_SLOTLEN_DEFAULT; - ts->tdma_slotcnt = TDMA_SLOTCNT_DEFAULT; - ts->tdma_bintval = TDMA_BINTVAL_DEFAULT; - ts->tdma_slot = 1; /* passive operation */ - - /* setup default fixed rates */ - settxparms(vap, IEEE80211_MODE_11A, TDMA_TXRATE_11A_DEFAULT); - settxparms(vap, IEEE80211_MODE_11B, TDMA_TXRATE_11B_DEFAULT); - settxparms(vap, IEEE80211_MODE_11G, TDMA_TXRATE_11G_DEFAULT); - settxparms(vap, IEEE80211_MODE_TURBO_A, TDMA_TXRATE_TURBO_DEFAULT); - settxparms(vap, IEEE80211_MODE_TURBO_G, TDMA_TXRATE_TURBO_DEFAULT); - settxparms(vap, IEEE80211_MODE_STURBO_A, TDMA_TXRATE_TURBO_DEFAULT); - settxparms(vap, IEEE80211_MODE_11NA, TDMA_TXRATE_11NA_DEFAULT); - settxparms(vap, IEEE80211_MODE_11NG, TDMA_TXRATE_11NG_DEFAULT); - settxparms(vap, IEEE80211_MODE_HALF, TDMA_TXRATE_HALF_DEFAULT); - settxparms(vap, IEEE80211_MODE_QUARTER, TDMA_TXRATE_QUARTER_DEFAULT); - - setackpolicy(vap->iv_ic, 1); /* disable ACK's */ - - ts->tdma_opdetach = vap->iv_opdetach; - vap->iv_opdetach = tdma_vdetach; - ts->tdma_newstate = vap->iv_newstate; - vap->iv_newstate = tdma_newstate; - vap->iv_bmiss = tdma_beacon_miss; - ts->tdma_recv_mgmt = vap->iv_recv_mgmt; - vap->iv_recv_mgmt = tdma_recv_mgmt; - - vap->iv_tdma = ts; -} - -static void -tdma_vdetach(struct ieee80211vap *vap) -{ - struct ieee80211_tdma_state *ts = vap->iv_tdma; - - if (ts == NULL) { - /* NB: should not have touched any ic state */ - return; - } - ts->tdma_opdetach(vap); - free(vap->iv_tdma, M_80211_VAP); - vap->iv_tdma = NULL; - - setackpolicy(vap->iv_ic, 0); /* enable ACK's */ -} - -static void -sta_leave(void *arg, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = arg; - - if (ni->ni_vap == vap && ni != vap->iv_bss) - ieee80211_node_leave(ni); -} - -/* - * TDMA state machine handler. - */ -static int -tdma_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct ieee80211_tdma_state *ts = vap->iv_tdma; - struct ieee80211com *ic = vap->iv_ic; - enum ieee80211_state ostate; - int status; - - IEEE80211_LOCK_ASSERT(ic); - - ostate = vap->iv_state; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n", - __func__, ieee80211_state_name[ostate], - ieee80211_state_name[nstate], arg); - - if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) - callout_stop(&vap->iv_swbmiss); - if (nstate == IEEE80211_S_SCAN && - (ostate == IEEE80211_S_INIT || ostate == IEEE80211_S_RUN) && - ts->tdma_slot != 0) { - /* - * Override adhoc behaviour when operating as a slave; - * we need to scan even if the channel is locked. - */ - vap->iv_state = nstate; /* state transition */ - ieee80211_cancel_scan(vap); /* background scan */ - if (ostate == IEEE80211_S_RUN) { - /* purge station table; entries are stale */ - ieee80211_iterate_nodes(&ic->ic_sta, sta_leave, vap); - } - if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) { - ieee80211_check_scan(vap, - vap->iv_scanreq_flags, - vap->iv_scanreq_duration, - vap->iv_scanreq_mindwell, - vap->iv_scanreq_maxdwell, - vap->iv_scanreq_nssid, vap->iv_scanreq_ssid); - vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; - } else - ieee80211_check_scan_current(vap); - status = 0; - } else { - status = ts->tdma_newstate(vap, nstate, arg); - } - if (status == 0 && - nstate == IEEE80211_S_RUN && ostate != IEEE80211_S_RUN && - (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) && - ts->tdma_slot != 0 && - vap->iv_des_chan == IEEE80211_CHAN_ANYC) { - /* - * Start s/w beacon miss timer for slave devices w/o - * hardware support. Note we do this only if we're - * not locked to a channel (i.e. roam to follow the - * master). The 2x is a fudge for our doing this in - * software. - */ - vap->iv_swbmiss_period = IEEE80211_TU_TO_TICKS( - 2 * vap->iv_bmissthreshold * ts->tdma_bintval * - ((ts->tdma_slotcnt * ts->tdma_slotlen) / 1024)); - vap->iv_swbmiss_count = 0; - callout_reset(&vap->iv_swbmiss, vap->iv_swbmiss_period, - ieee80211_swbmiss, vap); - } - return status; -} - -static void -tdma_beacon_miss(struct ieee80211vap *vap) -{ - struct ieee80211_tdma_state *ts = vap->iv_tdma; - - KASSERT((vap->iv_ic->ic_flags & IEEE80211_F_SCAN) == 0, ("scanning")); - KASSERT(vap->iv_state == IEEE80211_S_RUN, - ("wrong state %d", vap->iv_state)); - - IEEE80211_DPRINTF(vap, - IEEE80211_MSG_STATE | IEEE80211_MSG_TDMA | IEEE80211_MSG_DEBUG, - "beacon miss, mode %u state %s\n", - vap->iv_opmode, ieee80211_state_name[vap->iv_state]); - - callout_stop(&vap->iv_swbmiss); - - if (ts->tdma_peer != NULL) { /* XXX? can this be null? */ - ieee80211_notify_node_leave(vap->iv_bss); - ts->tdma_peer = NULL; - /* - * Treat beacon miss like an associate failure wrt the - * scan policy; this forces the entry in the scan cache - * to be ignored after several tries. - */ - ieee80211_scan_assoc_fail(vap, vap->iv_bss->ni_macaddr, - IEEE80211_STATUS_TIMEOUT); - } -#if 0 - ts->tdma_inuse = 0; /* clear slot usage */ -#endif - ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); -} - -static void -tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int nf) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_tdma_state *ts = vap->iv_tdma; - - if (subtype == IEEE80211_FC0_SUBTYPE_BEACON && - (ic->ic_flags & IEEE80211_F_SCAN) == 0) { - struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *); - struct ieee80211_scanparams scan; - - if (ieee80211_parse_beacon(ni, m0, &scan) != 0) - return; - if (scan.tdma == NULL) { - /* - * TDMA stations must beacon a TDMA ie; ignore - * any other station. - * XXX detect overlapping bss and change channel - */ - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT, - wh, ieee80211_mgt_subtype_name[subtype >> - IEEE80211_FC0_SUBTYPE_SHIFT], - "%s", "no TDMA ie"); - vap->iv_stats.is_rx_mgtdiscard++; - return; - } - if (ni == vap->iv_bss && - !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { - /* - * Fake up a node for this newly - * discovered member of the IBSS. - */ - ni = ieee80211_add_neighbor(vap, wh, &scan); - if (ni == NULL) { - /* NB: stat kept for alloc failure */ - return; - } - } - /* - * Check for state updates. - */ - if (IEEE80211_ADDR_EQ(wh->i_addr3, ni->ni_bssid)) { - /* - * Count frame now that we know it's to be processed. - */ - vap->iv_stats.is_rx_beacon++; - IEEE80211_NODE_STAT(ni, rx_beacons); - /* - * Record tsf of last beacon. NB: this must be - * done before calling tdma_process_params - * as deeper routines reference it. - */ - memcpy(&ni->ni_tstamp.data, scan.tstamp, - sizeof(ni->ni_tstamp.data)); - /* - * Count beacon frame for s/w bmiss handling. - */ - vap->iv_swbmiss_count++; - /* - * Process tdma ie. The contents are used to sync - * the slot timing, reconfigure the bss, etc. - */ - (void) tdma_process_params(ni, scan.tdma, rssi, nf, wh); - return; - } - /* - * NB: defer remaining work to the adhoc code; this causes - * 2x parsing of the frame but should happen infrequently - */ - } - ts->tdma_recv_mgmt(ni, m0, subtype, rssi, nf); -} - -/* - * Update TDMA state on receipt of a beacon frame with - * a TDMA information element. The sender's identity - * is provided so we can track who our peer is. If pickslot - * is non-zero we scan the slot allocation state in the ie - * to locate a free slot for our use. - */ -static int -tdma_update(struct ieee80211vap *vap, const struct ieee80211_tdma_param *tdma, - struct ieee80211_node *ni, int pickslot) -{ - struct ieee80211_tdma_state *ts = vap->iv_tdma; - int slot, slotlen, update; - - KASSERT(vap->iv_caps & IEEE80211_C_TDMA, - ("not a tdma vap, caps 0x%x", vap->iv_caps)); - - update = 0; - if (tdma->tdma_slotcnt != ts->tdma_slotcnt) { - if (!TDMA_SLOTCNT_VALID(tdma->tdma_slotcnt)) { - if (ppsratecheck(&ts->tdma_lastprint, &ts->tdma_fails, 1)) - printf("%s: bad slot cnt %u\n", - __func__, tdma->tdma_slotcnt); - return 0; - } - update |= TDMA_UPDATE_SLOTCNT; - } - slotlen = le16toh(tdma->tdma_slotlen) * 100; - if (slotlen != ts->tdma_slotlen) { - if (!TDMA_SLOTLEN_VALID(slotlen)) { - if (ppsratecheck(&ts->tdma_lastprint, &ts->tdma_fails, 1)) - printf("%s: bad slot len %u\n", - __func__, slotlen); - return 0; - } - update |= TDMA_UPDATE_SLOTLEN; - } - if (tdma->tdma_bintval != ts->tdma_bintval) { - if (!TDMA_BINTVAL_VALID(tdma->tdma_bintval)) { - if (ppsratecheck(&ts->tdma_lastprint, &ts->tdma_fails, 1)) - printf("%s: bad beacon interval %u\n", - __func__, tdma->tdma_bintval); - return 0; - } - update |= TDMA_UPDATE_BINTVAL; - } - slot = ts->tdma_slot; - if (pickslot) { - /* - * Pick unoccupied slot. Note we never choose slot 0. - */ - for (slot = tdma->tdma_slotcnt-1; slot > 0; slot--) - if (isclr(tdma->tdma_inuse, slot)) - break; - if (slot <= 0) { - printf("%s: no free slot, slotcnt %u inuse: 0x%x\n", - __func__, tdma->tdma_slotcnt, - tdma->tdma_inuse[0]); - /* XXX need to do something better */ - return 0; - } - if (slot != ts->tdma_slot) - update |= TDMA_UPDATE_SLOT; - } - if (ni != ts->tdma_peer) { - /* update everything */ - update = TDMA_UPDATE_SLOT - | TDMA_UPDATE_SLOTCNT - | TDMA_UPDATE_SLOTLEN - | TDMA_UPDATE_BINTVAL; - } - - if (update) { - /* - * New/changed parameters; update runtime state. - */ - /* XXX overwrites user parameters */ - if (update & TDMA_UPDATE_SLOTCNT) - ts->tdma_slotcnt = tdma->tdma_slotcnt; - if (update & TDMA_UPDATE_SLOTLEN) - ts->tdma_slotlen = slotlen; - if (update & TDMA_UPDATE_SLOT) - ts->tdma_slot = slot; - if (update & TDMA_UPDATE_BINTVAL) - ts->tdma_bintval = tdma->tdma_bintval; - /* mark beacon to be updated before next xmit */ - ieee80211_beacon_notify(vap, IEEE80211_BEACON_TDMA); - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_TDMA, - "%s: slot %u slotcnt %u slotlen %u us bintval %u\n", - __func__, ts->tdma_slot, ts->tdma_slotcnt, - ts->tdma_slotlen, ts->tdma_bintval); - } - /* - * Notify driver. Note we can be called before - * entering RUN state if we scanned and are - * joining an existing bss. In that case do not - * call the driver because not all necessary state - * has been setup. The next beacon will dtrt. - */ - if (vap->iv_state == IEEE80211_S_RUN) - vap->iv_ic->ic_tdma_update(ni, tdma, update); - /* - * Dispatch join event on first beacon from new master. - */ - if (ts->tdma_peer != ni) { - if (ts->tdma_peer != NULL) - ieee80211_notify_node_leave(vap->iv_bss); - ieee80211_notify_node_join(ni, 1); - /* NB: no reference, we just use the address */ - ts->tdma_peer = ni; - } - return 1; -} - -/* - * Process received TDMA parameters. - */ -static int -tdma_process_params(struct ieee80211_node *ni, const u_int8_t *ie, - int rssi, int nf, const struct ieee80211_frame *wh) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_tdma_state *ts = vap->iv_tdma; - const struct ieee80211_tdma_param *tdma = - (const struct ieee80211_tdma_param *) ie; - u_int len = ie[1]; - - KASSERT(vap->iv_caps & IEEE80211_C_TDMA, - ("not a tdma vap, caps 0x%x", vap->iv_caps)); - - if (len < sizeof(*tdma) - 2) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_TDMA, - wh, "tdma", "too short, len %u", len); - return IEEE80211_REASON_IE_INVALID; - } - if (tdma->tdma_version != ts->tdma_version) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_TDMA, - wh, "tdma", "bad version %u (ours %u)", - tdma->tdma_version, ts->tdma_version); - return IEEE80211_REASON_IE_INVALID; - } - /* - * NB: ideally we'd check against tdma_slotcnt, but that - * would require extra effort so do this easy check that - * covers the work below; more stringent checks are done - * before we make more extensive use of the ie contents. - */ - if (tdma->tdma_slot >= TDMA_MAXSLOTS) { - IEEE80211_DISCARD_IE(vap, - IEEE80211_MSG_ELEMID | IEEE80211_MSG_TDMA, - wh, "tdma", "invalid slot %u", tdma->tdma_slot); - return IEEE80211_REASON_IE_INVALID; - } - /* - * Can reach here while scanning, update - * operational state only in RUN state. - */ - if (vap->iv_state == IEEE80211_S_RUN) { - if (tdma->tdma_slot != ts->tdma_slot && - isclr(ts->tdma_inuse, tdma->tdma_slot)) { - IEEE80211_NOTE(vap, IEEE80211_MSG_TDMA, ni, - "discovered in slot %u", tdma->tdma_slot); - setbit(ts->tdma_inuse, tdma->tdma_slot); - /* XXX dispatch event only when operating as master */ - if (ts->tdma_slot == 0) - ieee80211_notify_node_join(ni, 1); - } - setbit(ts->tdma_active, tdma->tdma_slot); - if (tdma->tdma_slot == ts->tdma_slot-1) { - /* - * Slave tsf synchronization to station - * just before us in the schedule. The driver - * is responsible for copying the timestamp - * of the received beacon into our beacon - * frame so the sender can calculate round - * trip time. We cannot do that here because - * we don't know how to update our beacon frame. - */ - (void) tdma_update(vap, tdma, ni, 0); - /* XXX reschedule swbmiss timer on parameter change */ - } else if (tdma->tdma_slot == ts->tdma_slot+1) { - uint64_t tstamp; -#if 0 - uint32_t rstamp = (uint32_t) le64toh(rs->tsf); - int32_t rtt; -#endif - /* - * Use returned timstamp to calculate the - * roundtrip time. - */ - memcpy(&tstamp, tdma->tdma_tstamp, 8); -#if 0 - /* XXX use only 15 bits of rstamp */ - rtt = rstamp - (le64toh(tstamp) & 0x7fff); - if (rtt < 0) - rtt += 0x7fff; - /* XXX hack to quiet normal use */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOT1X, - "tdma rtt %5u [rstamp %5u tstamp %llu]\n", - rtt, rstamp, - (unsigned long long) le64toh(tstamp)); -#endif - } else if (tdma->tdma_slot == ts->tdma_slot && - le64toh(ni->ni_tstamp.tsf) > vap->iv_bss->ni_tstamp.tsf) { - /* - * Station using the same slot as us and has - * been around longer than us; we must move. - * Note this can happen if stations do not - * see each other while scanning. - */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_TDMA, - "slot %u collision rxtsf %llu tsf %llu\n", - tdma->tdma_slot, - (unsigned long long) le64toh(ni->ni_tstamp.tsf), - vap->iv_bss->ni_tstamp.tsf); - setbit(ts->tdma_inuse, tdma->tdma_slot); - - (void) tdma_update(vap, tdma, ni, 1); - } - } - return 0; -} - -int -ieee80211_tdma_getslot(struct ieee80211vap *vap) -{ - struct ieee80211_tdma_state *ts = vap->iv_tdma; - - KASSERT(vap->iv_caps & IEEE80211_C_TDMA, - ("not a tdma vap, caps 0x%x", vap->iv_caps)); - return ts->tdma_slot; -} - -/* - * Parse a TDMA ie on station join and use it to setup node state. - */ -void -ieee80211_parse_tdma(struct ieee80211_node *ni, const uint8_t *ie) -{ - struct ieee80211vap *vap = ni->ni_vap; - - if (vap->iv_caps & IEEE80211_C_TDMA) { - const struct ieee80211_tdma_param *tdma = - (const struct ieee80211_tdma_param *)ie; - struct ieee80211_tdma_state *ts = vap->iv_tdma; - /* - * Adopt TDMA configuration when joining an - * existing network. - */ - setbit(ts->tdma_inuse, tdma->tdma_slot); - (void) tdma_update(vap, tdma, ni, 1); - /* - * Propagate capabilities based on the local - * configuration and the remote station's advertised - * capabilities. In particular this permits us to - * enable use of QoS to disable ACK's. - */ - if ((vap->iv_flags & IEEE80211_F_WME) && - ni->ni_ies.wme_ie != NULL) - ni->ni_flags |= IEEE80211_NODE_QOS; - } -} - -#define TDMA_OUI_BYTES 0x00, 0x03, 0x7f -/* - * Add a TDMA parameters element to a frame. - */ -uint8_t * -ieee80211_add_tdma(uint8_t *frm, struct ieee80211vap *vap) -{ -#define ADDSHORT(frm, v) do { \ - frm[0] = (v) & 0xff; \ - frm[1] = (v) >> 8; \ - frm += 2; \ -} while (0) - static const struct ieee80211_tdma_param param = { - .tdma_id = IEEE80211_ELEMID_VENDOR, - .tdma_len = sizeof(struct ieee80211_tdma_param) - 2, - .tdma_oui = { TDMA_OUI_BYTES }, - .tdma_type = TDMA_OUI_TYPE, - .tdma_subtype = TDMA_SUBTYPE_PARAM, - .tdma_version = TDMA_VERSION, - }; - const struct ieee80211_tdma_state *ts = vap->iv_tdma; - uint16_t slotlen; - - KASSERT(vap->iv_caps & IEEE80211_C_TDMA, - ("not a tdma vap, caps 0x%x", vap->iv_caps)); - - memcpy(frm, ¶m, sizeof(param)); - frm += __offsetof(struct ieee80211_tdma_param, tdma_slot); - *frm++ = ts->tdma_slot; - *frm++ = ts->tdma_slotcnt; - /* NB: convert units to fit in 16-bits */ - slotlen = ts->tdma_slotlen / 100; /* 100us units */ - ADDSHORT(frm, slotlen); - *frm++ = ts->tdma_bintval; - *frm++ = ts->tdma_inuse[0]; - frm += 10; /* pad+timestamp */ - return frm; -#undef ADDSHORT -} -#undef TDMA_OUI_BYTES - -/* - * Update TDMA state at TBTT. - */ -void -ieee80211_tdma_update_beacon(struct ieee80211vap *vap, - struct ieee80211_beacon_offsets *bo) -{ - struct ieee80211_tdma_state *ts = vap->iv_tdma; - - KASSERT(vap->iv_caps & IEEE80211_C_TDMA, - ("not a tdma vap, caps 0x%x", vap->iv_caps)); - - if (isset(bo->bo_flags, IEEE80211_BEACON_TDMA)) { - (void) ieee80211_add_tdma(bo->bo_tdma, vap); - clrbit(bo->bo_flags, IEEE80211_BEACON_TDMA); - } - if (ts->tdma_slot != 0) /* only on master */ - return; - if (ts->tdma_count <= 0) { - /* - * Time to update the mask of active/inuse stations. - * We track stations that we've received a beacon - * frame from and update this mask periodically. - * This allows us to miss a few beacons before marking - * a slot free for re-use. - */ - ts->tdma_inuse[0] = ts->tdma_active[0]; - ts->tdma_active[0] = 0x01; - /* update next time 'round */ - /* XXX use notify framework */ - setbit(bo->bo_flags, IEEE80211_BEACON_TDMA); - /* NB: use s/w beacon miss threshold; may be too high */ - ts->tdma_count = vap->iv_bmissthreshold-1; - } else - ts->tdma_count--; -} - -static int -tdma_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211_tdma_state *ts = vap->iv_tdma; - - if ((vap->iv_caps & IEEE80211_C_TDMA) == 0) - return EOPNOTSUPP; - - switch (ireq->i_type) { - case IEEE80211_IOC_TDMA_SLOT: - ireq->i_val = ts->tdma_slot; - break; - case IEEE80211_IOC_TDMA_SLOTCNT: - ireq->i_val = ts->tdma_slotcnt; - break; - case IEEE80211_IOC_TDMA_SLOTLEN: - ireq->i_val = ts->tdma_slotlen; - break; - case IEEE80211_IOC_TDMA_BINTERVAL: - ireq->i_val = ts->tdma_bintval; - break; - default: - return ENOSYS; - } - return 0; -} -IEEE80211_IOCTL_GET(tdma, tdma_ioctl_get80211); - -static int -tdma_ioctl_set80211(struct ieee80211vap *vap, struct ieee80211req *ireq) -{ - struct ieee80211_tdma_state *ts = vap->iv_tdma; - - if ((vap->iv_caps & IEEE80211_C_TDMA) == 0) - return EOPNOTSUPP; - - switch (ireq->i_type) { - case IEEE80211_IOC_TDMA_SLOT: - if (!(0 <= ireq->i_val && ireq->i_val <= ts->tdma_slotcnt)) - return EINVAL; - if (ireq->i_val != ts->tdma_slot) { - ts->tdma_slot = ireq->i_val; - goto restart; - } - break; - case IEEE80211_IOC_TDMA_SLOTCNT: - if (!TDMA_SLOTCNT_VALID(ireq->i_val)) - return EINVAL; - if (ireq->i_val != ts->tdma_slotcnt) { - ts->tdma_slotcnt = ireq->i_val; - goto restart; - } - break; - case IEEE80211_IOC_TDMA_SLOTLEN: - /* - * XXX - * 150 insures at least 1/8 TU - * 0xfffff is the max duration for bursting - * (implict by way of 16-bit data type for i_val) - */ - if (!TDMA_SLOTLEN_VALID(ireq->i_val)) - return EINVAL; - if (ireq->i_val != ts->tdma_slotlen) { - ts->tdma_slotlen = ireq->i_val; - goto restart; - } - break; - case IEEE80211_IOC_TDMA_BINTERVAL: - if (!TDMA_BINTVAL_VALID(ireq->i_val)) - return EINVAL; - if (ireq->i_val != ts->tdma_bintval) { - ts->tdma_bintval = ireq->i_val; - goto restart; - } - break; - default: - return ENOSYS; - } - return 0; -restart: - ieee80211_beacon_notify(vap, IEEE80211_BEACON_TDMA); - return ERESTART; -} -IEEE80211_IOCTL_SET(tdma, tdma_ioctl_set80211); diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_tdma.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_tdma.h deleted file mode 100644 index 35acf0349f..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_tdma.h +++ /dev/null @@ -1,102 +0,0 @@ -/*- - * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting - * Copyright (c) 2007-2009 Intel Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_TDMA_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_TDMA_H_ - -/* - * TDMA-mode implementation definitions. - */ - -#define TDMA_SUBTYPE_PARAM 0x01 -#define TDMA_VERSION_V2 2 -#define TDMA_VERSION TDMA_VERSION_V2 - -/* NB: we only support 2 right now but protocol handles up to 8 */ -#define TDMA_MAXSLOTS 2 /* max slots/sta's */ - -#define TDMA_PARAM_LEN_V2 sizeof(struct ieee80211_tdma_param) - -/* - * TDMA information element. - */ -struct ieee80211_tdma_param { - u_int8_t tdma_id; /* IEEE80211_ELEMID_VENDOR */ - u_int8_t tdma_len; - u_int8_t tdma_oui[3]; /* TDMA_OUI */ - u_int8_t tdma_type; /* TDMA_OUI_TYPE */ - u_int8_t tdma_subtype; /* TDMA_SUBTYPE_PARAM */ - u_int8_t tdma_version; /* spec revision */ - u_int8_t tdma_slot; /* station slot # [0..7] */ - u_int8_t tdma_slotcnt; /* bss slot count [1..8] */ - u_int16_t tdma_slotlen; /* bss slot len (100us) */ - u_int8_t tdma_bintval; /* beacon interval (superframes) */ - u_int8_t tdma_inuse[1]; /* slot occupancy map */ - u_int8_t tdma_pad[2]; - u_int8_t tdma_tstamp[8]; /* timestamp from last beacon */ -} __packed; - -#ifdef _KERNEL -/* - * Implementation state. - */ -struct ieee80211_tdma_state { - u_int tdma_slotlen; /* bss slot length (us) */ - uint8_t tdma_version; /* protocol version to use */ - uint8_t tdma_slotcnt; /* bss slot count */ - uint8_t tdma_bintval; /* beacon interval (slots) */ - uint8_t tdma_slot; /* station slot # */ - uint8_t tdma_inuse[1]; /* mask of slots in use */ - uint8_t tdma_active[1]; /* mask of active slots */ - int tdma_count; /* active/inuse countdown */ - void *tdma_peer; /* peer station cookie */ - struct timeval tdma_lastprint; /* time of last rate-limited printf */ - int tdma_fails; /* fail count for rate-limiting */ - - /* parent method pointers */ - int (*tdma_newstate)(struct ieee80211vap *, enum ieee80211_state, - int arg); - void (*tdma_recv_mgmt)(struct ieee80211_node *, - struct mbuf *, int, int, int); - void (*tdma_opdetach)(struct ieee80211vap *); -}; - -#define TDMA_UPDATE_SLOT 0x0001 /* tdma_slot changed */ -#define TDMA_UPDATE_SLOTCNT 0x0002 /* tdma_slotcnt changed */ -#define TDMA_UPDATE_SLOTLEN 0x0004 /* tdma_slotlen changed */ -#define TDMA_UPDATE_BINTVAL 0x0008 /* tdma_bintval changed */ - -void ieee80211_tdma_vattach(struct ieee80211vap *); - -int ieee80211_tdma_getslot(struct ieee80211vap *vap); -void ieee80211_parse_tdma(struct ieee80211_node *ni, const uint8_t *ie); -uint8_t *ieee80211_add_tdma(uint8_t *frm, struct ieee80211vap *vap); -struct ieee80211_beacon_offsets; -void ieee80211_tdma_update_beacon(struct ieee80211vap *vap, - struct ieee80211_beacon_offsets *bo); -#endif /* _KERNEL */ -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_TDMA_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_var.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_var.h deleted file mode 100644 index de24cbd4cc..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_var.h +++ /dev/null @@ -1,928 +0,0 @@ -/*- - * Copyright (c) 2001 Atsushi Onoe - * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting - * Copyright (c) 2009 Colin Günther, coling@gmx.de - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_VAR_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_VAR_H_ - -/* - * Definitions for IEEE 802.11 drivers. - */ -/* NB: portability glue must go first */ -#if defined(__NetBSD__) -#include -#elif defined(__FreeBSD__) -#include -#elif defined(__linux__) -#include -#elif __HAIKU__ -#include -#else -#error "No support for your operating system!" -#endif - -#include -#include -#include -#include -#include -#include /* for ieee80211_stats */ -#include -#include -#include -#include -#include -#include - -#define IEEE80211_TXPOWER_MAX 100 /* .5 dbM (XXX units?) */ -#define IEEE80211_TXPOWER_MIN 0 /* kill radio */ - -#define IEEE80211_DTIM_DEFAULT 1 /* default DTIM period */ -#define IEEE80211_BINTVAL_DEFAULT 100 /* default beacon interval (TU's) */ - -#define IEEE80211_BMISS_MAX 2 /* maximum consecutive bmiss allowed */ -#define IEEE80211_HWBMISS_DEFAULT 7 /* h/w bmiss threshold (beacons) */ - -#define IEEE80211_BGSCAN_INTVAL_MIN 15 /* min bg scan intvl (secs) */ -#define IEEE80211_BGSCAN_INTVAL_DEFAULT (5*60) /* default bg scan intvl */ - -#define IEEE80211_BGSCAN_IDLE_MIN 100 /* min idle time (ms) */ -#define IEEE80211_BGSCAN_IDLE_DEFAULT 250 /* default idle time (ms) */ - -#define IEEE80211_SCAN_VALID_MIN 10 /* min scan valid time (secs) */ -#define IEEE80211_SCAN_VALID_DEFAULT 60 /* default scan valid time */ - -#define IEEE80211_PS_SLEEP 0x1 /* STA is in power saving mode */ -#define IEEE80211_PS_MAX_QUEUE 50 /* maximum saved packets */ - -#define IEEE80211_FIXED_RATE_NONE 0xff -#define IEEE80211_TXMAX_DEFAULT 6 /* default ucast max retries */ - -#define IEEE80211_RTS_DEFAULT IEEE80211_RTS_MAX -#define IEEE80211_FRAG_DEFAULT IEEE80211_FRAG_MAX - -#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) -#define IEEE80211_TU_TO_MS(x) (((x) * 1024) / 1000) -#define IEEE80211_TU_TO_TICKS(x)(((x) * 1024 * hz) / (1000 * 1000)) - -/* - * 802.11 control state is split into a common portion that maps - * 1-1 to a physical device and one or more "Virtual AP's" (VAP) - * that are bound to an ieee80211com instance and share a single - * underlying device. Each VAP has a corresponding OS device - * entity through which traffic flows and that applications use - * for issuing ioctls, etc. - */ - -/* - * Data common to one or more virtual AP's. State shared by - * the underlying device and the net80211 layer is exposed here; - * e.g. device-specific callbacks. - */ -struct ieee80211vap; -typedef void (*ieee80211vap_attach)(struct ieee80211vap *); - -struct ieee80211_appie { - uint16_t ie_len; /* size of ie_data */ - uint8_t ie_data[0]; /* user-specified IE's */ -}; - -struct ieee80211_tdma_param; -struct ieee80211_rate_table; -struct ieee80211_tx_ampdu; -struct ieee80211_rx_ampdu; -struct ieee80211_superg; -struct ieee80211_frame; - -struct ieee80211com { - struct ifnet *ic_ifp; /* associated device */ - ieee80211_com_lock_t ic_comlock; /* state update lock */ - TAILQ_HEAD(, ieee80211vap) ic_vaps; /* list of vap instances */ - int ic_headroom; /* driver tx headroom needs */ - enum ieee80211_phytype ic_phytype; /* XXX wrong for multi-mode */ - enum ieee80211_opmode ic_opmode; /* operation mode */ - struct ifmedia ic_media; /* interface media config */ - struct callout ic_inact; /* inactivity processing */ - struct taskqueue *ic_tq; /* deferred state thread */ - struct task ic_parent_task; /* deferred parent processing */ - struct task ic_promisc_task;/* deferred promisc update */ - struct task ic_mcast_task; /* deferred mcast update */ - struct task ic_chan_task; /* deferred channel change */ - struct task ic_bmiss_task; /* deferred beacon miss hndlr */ - - uint32_t ic_flags; /* state flags */ - uint32_t ic_flags_ext; /* extended state flags */ - uint32_t ic_flags_ht; /* HT state flags */ - uint32_t ic_flags_ven; /* vendor state flags */ - uint32_t ic_caps; /* capabilities */ - uint32_t ic_htcaps; /* HT capabilities */ - uint32_t ic_htextcaps; /* HT extended capabilities */ - uint32_t ic_cryptocaps; /* crypto capabilities */ - uint8_t ic_modecaps[2]; /* set of mode capabilities */ - uint8_t ic_promisc; /* vap's needing promisc mode */ - uint8_t ic_allmulti; /* vap's needing all multicast*/ - uint8_t ic_nrunning; /* vap's marked running */ - uint8_t ic_curmode; /* current mode */ - uint16_t ic_bintval; /* beacon interval */ - uint16_t ic_lintval; /* listen interval */ - uint16_t ic_holdover; /* PM hold over duration */ - uint16_t ic_txpowlimit; /* global tx power limit */ - struct ieee80211_rateset ic_sup_rates[IEEE80211_MODE_MAX]; - - /* - * Channel state: - * - * ic_channels is the set of available channels for the device; - * it is setup by the driver - * ic_nchans is the number of valid entries in ic_channels - * ic_chan_avail is a bit vector of these channels used to check - * whether a channel is available w/o searching the channel table. - * ic_chan_active is a (potentially) constrained subset of - * ic_chan_avail that reflects any mode setting or user-specified - * limit on the set of channels to use/scan - * ic_curchan is the current channel the device is set to; it may - * be different from ic_bsschan when we are off-channel scanning - * or otherwise doing background work - * ic_bsschan is the channel selected for operation; it may - * be undefined (IEEE80211_CHAN_ANYC) - * ic_prevchan is a cached ``previous channel'' used to optimize - * lookups when switching back+forth between two channels - * (e.g. for dynamic turbo) - */ - int ic_nchans; /* # entries in ic_channels */ - struct ieee80211_channel ic_channels[IEEE80211_CHAN_MAX]; - uint8_t ic_chan_avail[IEEE80211_CHAN_BYTES]; - uint8_t ic_chan_active[IEEE80211_CHAN_BYTES]; - uint8_t ic_chan_scan[IEEE80211_CHAN_BYTES]; - struct ieee80211_channel *ic_curchan; /* current channel */ - const struct ieee80211_rate_table *ic_rt; /* table for ic_curchan */ - struct ieee80211_channel *ic_bsschan; /* bss channel */ - struct ieee80211_channel *ic_prevchan; /* previous channel */ - struct ieee80211_regdomain ic_regdomain;/* regulatory data */ - struct ieee80211_appie *ic_countryie; /* calculated country ie */ - struct ieee80211_channel *ic_countryie_chan; - - /* 802.11h/DFS state */ - struct ieee80211_channel *ic_csa_newchan;/* channel for doing CSA */ - short ic_csa_mode; /* mode for doing CSA */ - short ic_csa_count; /* count for doing CSA */ - struct ieee80211_dfs_state ic_dfs; /* DFS state */ - - struct ieee80211_scan_state *ic_scan; /* scan state */ - int ic_lastdata; /* time of last data frame */ - int ic_lastscan; /* time last scan completed */ - - /* NB: this is the union of all vap stations/neighbors */ - int ic_max_keyix; /* max h/w key index */ - struct ieee80211_node_table ic_sta; /* stations/neighbors */ - struct ieee80211_ageq ic_stageq; /* frame staging queue */ - uint32_t ic_hash_key; /* random key for mac hash */ - - /* XXX multi-bss: split out common/vap parts */ - struct ieee80211_wme_state ic_wme; /* WME/WMM state */ - - /* XXX multi-bss: can per-vap be done/make sense? */ - enum ieee80211_protmode ic_protmode; /* 802.11g protection mode */ - uint16_t ic_nonerpsta; /* # non-ERP stations */ - uint16_t ic_longslotsta; /* # long slot time stations */ - uint16_t ic_sta_assoc; /* stations associated */ - uint16_t ic_ht_sta_assoc;/* HT stations associated */ - uint16_t ic_ht40_sta_assoc;/* HT40 stations associated */ - uint8_t ic_curhtprotmode;/* HTINFO bss state */ - enum ieee80211_protmode ic_htprotmode; /* HT protection mode */ - int ic_lastnonerp; /* last time non-ERP sta noted*/ - int ic_lastnonht; /* last time non-HT sta noted */ - uint8_t ic_rxstream; /* # RX streams */ - uint8_t ic_txstream; /* # TX streams */ - - /* optional state for Atheros SuperG protocol extensions */ - struct ieee80211_superg *ic_superg; - - /* radiotap handling */ - struct ieee80211_radiotap_header *ic_th;/* tx radiotap headers */ - void *ic_txchan; /* channel state in ic_th */ - struct ieee80211_radiotap_header *ic_rh;/* rx radiotap headers */ - void *ic_rxchan; /* channel state in ic_rh */ - int ic_montaps; /* active monitor mode taps */ - - /* virtual ap create/delete */ - struct ieee80211vap* (*ic_vap_create)(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, - enum ieee80211_opmode opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t macaddr[IEEE80211_ADDR_LEN]); - void (*ic_vap_delete)(struct ieee80211vap *); - /* operating mode attachment */ - ieee80211vap_attach ic_vattach[IEEE80211_OPMODE_MAX]; - /* return hardware/radio capabilities */ - void (*ic_getradiocaps)(struct ieee80211com *, - int, int *, struct ieee80211_channel []); - /* check and/or prepare regdomain state change */ - int (*ic_setregdomain)(struct ieee80211com *, - struct ieee80211_regdomain *, - int, struct ieee80211_channel []); - /* send/recv 802.11 management frame */ - int (*ic_send_mgmt)(struct ieee80211_node *, - int, int); - /* send raw 802.11 frame */ - int (*ic_raw_xmit)(struct ieee80211_node *, - struct mbuf *, - const struct ieee80211_bpf_params *); - /* update device state for 802.11 slot time change */ - void (*ic_updateslot)(struct ifnet *); - /* handle multicast state changes */ - void (*ic_update_mcast)(struct ifnet *); - /* handle promiscuous mode changes */ - void (*ic_update_promisc)(struct ifnet *); - /* new station association callback/notification */ - void (*ic_newassoc)(struct ieee80211_node *, int); - /* TDMA update notification */ - void (*ic_tdma_update)(struct ieee80211_node *, - const struct ieee80211_tdma_param *, int); - /* node state management */ - struct ieee80211_node* (*ic_node_alloc)(struct ieee80211vap *, - const uint8_t [IEEE80211_ADDR_LEN]); - void (*ic_node_free)(struct ieee80211_node *); - void (*ic_node_cleanup)(struct ieee80211_node *); - void (*ic_node_age)(struct ieee80211_node *); - void (*ic_node_drain)(struct ieee80211_node *); - int8_t (*ic_node_getrssi)(const struct ieee80211_node*); - void (*ic_node_getsignal)(const struct ieee80211_node*, - int8_t *, int8_t *); - void (*ic_node_getmimoinfo)( - const struct ieee80211_node*, - struct ieee80211_mimo_info *); - /* scanning support */ - void (*ic_scan_start)(struct ieee80211com *); - void (*ic_scan_end)(struct ieee80211com *); - void (*ic_set_channel)(struct ieee80211com *); - void (*ic_scan_curchan)(struct ieee80211_scan_state *, - unsigned long); - void (*ic_scan_mindwell)(struct ieee80211_scan_state *); - - /* - * 802.11n ADDBA support. A simple/generic implementation - * of A-MPDU tx aggregation is provided; the driver may - * override these methods to provide their own support. - * A-MPDU rx re-ordering happens automatically if the - * driver passes out-of-order frames to ieee80211_input - * from an assocated HT station. - */ - int (*ic_recv_action)(struct ieee80211_node *, - const struct ieee80211_frame *, - const uint8_t *frm, const uint8_t *efrm); - int (*ic_send_action)(struct ieee80211_node *, - int category, int action, void *); - /* check if A-MPDU should be enabled this station+ac */ - int (*ic_ampdu_enable)(struct ieee80211_node *, - struct ieee80211_tx_ampdu *); - /* start/stop doing A-MPDU tx aggregation for a station */ - int (*ic_addba_request)(struct ieee80211_node *, - struct ieee80211_tx_ampdu *, - int dialogtoken, int baparamset, - int batimeout); - int (*ic_addba_response)(struct ieee80211_node *, - struct ieee80211_tx_ampdu *, - int status, int baparamset, int batimeout); - void (*ic_addba_stop)(struct ieee80211_node *, - struct ieee80211_tx_ampdu *); - void (*ic_addba_response_timeout)(struct ieee80211_node *, - struct ieee80211_tx_ampdu *); - /* BAR response received */ - void (*ic_bar_response)(struct ieee80211_node *, - struct ieee80211_tx_ampdu *, int status); - /* start/stop doing A-MPDU rx processing for a station */ - int (*ic_ampdu_rx_start)(struct ieee80211_node *, - struct ieee80211_rx_ampdu *, int baparamset, - int batimeout, int baseqctl); - void (*ic_ampdu_rx_stop)(struct ieee80211_node *, - struct ieee80211_rx_ampdu *); - uint64_t ic_spare[7]; -}; - -struct ieee80211_aclator; -struct ieee80211_tdma_state; -struct ieee80211_mesh_state; -struct ieee80211_hwmp_state; - -struct ieee80211vap { - struct ifmedia iv_media; /* interface media config */ - struct ifnet *iv_ifp; /* associated device */ - struct bpf_if *iv_rawbpf; /* packet filter structure */ - struct sysctl_ctx_list *iv_sysctl; /* dynamic sysctl context */ - struct sysctl_oid *iv_oid; /* net.wlan.X sysctl oid */ - - TAILQ_ENTRY(ieee80211vap) iv_next; /* list of vap instances */ - struct ieee80211com *iv_ic; /* back ptr to common state */ - uint32_t iv_debug; /* debug msg flags */ - struct ieee80211_stats iv_stats; /* statistics */ - - uint8_t iv_myaddr[IEEE80211_ADDR_LEN]; - uint32_t iv_flags; /* state flags */ - uint32_t iv_flags_ext; /* extended state flags */ - uint32_t iv_flags_ht; /* HT state flags */ - uint32_t iv_flags_ven; /* vendor state flags */ - uint32_t iv_caps; /* capabilities */ - uint32_t iv_htcaps; /* HT capabilities */ - uint32_t iv_htextcaps; /* HT extended capabilities */ - enum ieee80211_opmode iv_opmode; /* operation mode */ - enum ieee80211_state iv_state; /* state machine state */ - enum ieee80211_state iv_nstate; /* pending state */ - int iv_nstate_arg; /* pending state arg */ - struct task iv_nstate_task; /* deferred state processing */ - struct task iv_swbmiss_task;/* deferred iv_bmiss call */ - struct callout iv_mgtsend; /* mgmt frame response timer */ - /* inactivity timer settings */ - int iv_inact_init; /* setting for new station */ - int iv_inact_auth; /* auth but not assoc setting */ - int iv_inact_run; /* authorized setting */ - int iv_inact_probe; /* inactive probe time */ - - int iv_des_nssid; /* # desired ssids */ - struct ieee80211_scan_ssid iv_des_ssid[1];/* desired ssid table */ - uint8_t iv_des_bssid[IEEE80211_ADDR_LEN]; - struct ieee80211_channel *iv_des_chan; /* desired channel */ - uint16_t iv_des_mode; /* desired mode */ - int iv_nicknamelen; /* XXX junk */ - uint8_t iv_nickname[IEEE80211_NWID_LEN]; - u_int iv_bgscanidle; /* bg scan idle threshold */ - u_int iv_bgscanintvl; /* bg scan min interval */ - u_int iv_scanvalid; /* scan cache valid threshold */ - u_int iv_scanreq_duration; - u_int iv_scanreq_mindwell; - u_int iv_scanreq_maxdwell; - uint16_t iv_scanreq_flags;/* held scan request params */ - uint8_t iv_scanreq_nssid; - struct ieee80211_scan_ssid iv_scanreq_ssid[IEEE80211_SCAN_MAX_SSID]; - /* sta-mode roaming state */ - enum ieee80211_roamingmode iv_roaming; /* roaming mode */ - struct ieee80211_roamparam iv_roamparms[IEEE80211_MODE_MAX]; - - uint8_t iv_bmissthreshold; - uint8_t iv_bmiss_count; /* current beacon miss count */ - int iv_bmiss_max; /* max bmiss before scan */ - uint16_t iv_swbmiss_count;/* beacons in last period */ - uint16_t iv_swbmiss_period;/* s/w bmiss period */ - struct callout iv_swbmiss; /* s/w beacon miss timer */ - - int iv_ampdu_rxmax; /* A-MPDU rx limit (bytes) */ - int iv_ampdu_density;/* A-MPDU density */ - int iv_ampdu_limit; /* A-MPDU tx limit (bytes) */ - int iv_amsdu_limit; /* A-MSDU tx limit (bytes) */ - u_int iv_ampdu_mintraffic[WME_NUM_AC]; - - uint32_t *iv_aid_bitmap; /* association id map */ - uint16_t iv_max_aid; - uint16_t iv_sta_assoc; /* stations associated */ - uint16_t iv_ps_sta; /* stations in power save */ - uint16_t iv_ps_pending; /* ps sta's w/ pending frames */ - uint16_t iv_txseq; /* mcast xmit seq# space */ - uint16_t iv_tim_len; /* ic_tim_bitmap size (bytes) */ - uint8_t *iv_tim_bitmap; /* power-save stations w/ data*/ - uint8_t iv_dtim_period; /* DTIM period */ - uint8_t iv_dtim_count; /* DTIM count from last bcn */ - /* set/unset aid pwrsav state */ - int iv_csa_count; /* count for doing CSA */ - - struct ieee80211_node *iv_bss; /* information for this node */ - struct ieee80211_txparam iv_txparms[IEEE80211_MODE_MAX]; - uint16_t iv_rtsthreshold; - uint16_t iv_fragthreshold; - int iv_inact_timer; /* inactivity timer wait */ - /* application-specified IE's to attach to mgt frames */ - struct ieee80211_appie *iv_appie_beacon; - struct ieee80211_appie *iv_appie_probereq; - struct ieee80211_appie *iv_appie_proberesp; - struct ieee80211_appie *iv_appie_assocreq; - struct ieee80211_appie *iv_appie_assocresp; - struct ieee80211_appie *iv_appie_wpa; - uint8_t *iv_wpa_ie; - uint8_t *iv_rsn_ie; - uint16_t iv_max_keyix; /* max h/w key index */ - ieee80211_keyix iv_def_txkey; /* default/group tx key index */ - struct ieee80211_key iv_nw_keys[IEEE80211_WEP_NKID]; - int (*iv_key_alloc)(struct ieee80211vap *, - struct ieee80211_key *, - ieee80211_keyix *, ieee80211_keyix *); - int (*iv_key_delete)(struct ieee80211vap *, - const struct ieee80211_key *); - int (*iv_key_set)(struct ieee80211vap *, - const struct ieee80211_key *, - const uint8_t mac[IEEE80211_ADDR_LEN]); - void (*iv_key_update_begin)(struct ieee80211vap *); - void (*iv_key_update_end)(struct ieee80211vap *); - - const struct ieee80211_authenticator *iv_auth; /* authenticator glue */ - void *iv_ec; /* private auth state */ - - const struct ieee80211_aclator *iv_acl; /* acl glue */ - void *iv_as; /* private aclator state */ - - const struct ieee80211_ratectl *iv_rate; - void *iv_rs; /* private ratectl state */ - - struct ieee80211_tdma_state *iv_tdma; /* tdma state */ - struct ieee80211_mesh_state *iv_mesh; /* MBSS state */ - struct ieee80211_hwmp_state *iv_hwmp; /* HWMP state */ - - /* operate-mode detach hook */ - void (*iv_opdetach)(struct ieee80211vap *); - /* receive processing */ - int (*iv_input)(struct ieee80211_node *, - struct mbuf *, int, int); - void (*iv_recv_mgmt)(struct ieee80211_node *, - struct mbuf *, int, int, int); - void (*iv_recv_ctl)(struct ieee80211_node *, - struct mbuf *, int); - void (*iv_deliver_data)(struct ieee80211vap *, - struct ieee80211_node *, struct mbuf *); -#if 0 - /* send processing */ - int (*iv_send_mgmt)(struct ieee80211_node *, - int, int); -#endif - /* beacon miss processing */ - void (*iv_bmiss)(struct ieee80211vap *); - /* reset device state after 802.11 parameter/state change */ - int (*iv_reset)(struct ieee80211vap *, u_long); - /* [schedule] beacon frame update */ - void (*iv_update_beacon)(struct ieee80211vap *, int); - /* power save handling */ - void (*iv_update_ps)(struct ieee80211vap *, int); - int (*iv_set_tim)(struct ieee80211_node *, int); - /* state machine processing */ - int (*iv_newstate)(struct ieee80211vap *, - enum ieee80211_state, int); - /* 802.3 output method for raw frame xmit */ - int (*iv_output)(struct ifnet *, struct mbuf *, - struct sockaddr *, struct route *); - uint64_t iv_spare[6]; -}; - -#define IEEE80211_ADDR_EQ(a1,a2) (memcmp(a1,a2,IEEE80211_ADDR_LEN) == 0) -#define IEEE80211_ADDR_COPY(dst,src) memcpy(dst,src,IEEE80211_ADDR_LEN) - -/* ic_flags/iv_flags */ -#define IEEE80211_F_TURBOP 0x00000001 /* CONF: ATH Turbo enabled*/ -#define IEEE80211_F_COMP 0x00000002 /* CONF: ATH comp enabled */ -#define IEEE80211_F_FF 0x00000004 /* CONF: ATH FF enabled */ -#define IEEE80211_F_BURST 0x00000008 /* CONF: bursting enabled */ -/* NB: this is intentionally setup to be IEEE80211_CAPINFO_PRIVACY */ -#define IEEE80211_F_PRIVACY 0x00000010 /* CONF: privacy enabled */ -#define IEEE80211_F_PUREG 0x00000020 /* CONF: 11g w/o 11b sta's */ -#define IEEE80211_F_SCAN 0x00000080 /* STATUS: scanning */ -#define IEEE80211_F_ASCAN 0x00000100 /* STATUS: active scan */ -#define IEEE80211_F_SIBSS 0x00000200 /* STATUS: start IBSS */ -/* NB: this is intentionally setup to be IEEE80211_CAPINFO_SHORT_SLOTTIME */ -#define IEEE80211_F_SHSLOT 0x00000400 /* STATUS: use short slot time*/ -#define IEEE80211_F_PMGTON 0x00000800 /* CONF: Power mgmt enable */ -#define IEEE80211_F_DESBSSID 0x00001000 /* CONF: des_bssid is set */ -#define IEEE80211_F_WME 0x00002000 /* CONF: enable WME use */ -#define IEEE80211_F_BGSCAN 0x00004000 /* CONF: bg scan enabled (???)*/ -#define IEEE80211_F_SWRETRY 0x00008000 /* CONF: sw tx retry enabled */ -#define IEEE80211_F_TXPOW_FIXED 0x00010000 /* TX Power: fixed rate */ -#define IEEE80211_F_IBSSON 0x00020000 /* CONF: IBSS creation enable */ -#define IEEE80211_F_SHPREAMBLE 0x00040000 /* STATUS: use short preamble */ -#define IEEE80211_F_DATAPAD 0x00080000 /* CONF: do alignment pad */ -#define IEEE80211_F_USEPROT 0x00100000 /* STATUS: protection enabled */ -#define IEEE80211_F_USEBARKER 0x00200000 /* STATUS: use barker preamble*/ -#define IEEE80211_F_CSAPENDING 0x00400000 /* STATUS: chan switch pending*/ -#define IEEE80211_F_WPA1 0x00800000 /* CONF: WPA enabled */ -#define IEEE80211_F_WPA2 0x01000000 /* CONF: WPA2 enabled */ -#define IEEE80211_F_WPA 0x01800000 /* CONF: WPA/WPA2 enabled */ -#define IEEE80211_F_DROPUNENC 0x02000000 /* CONF: drop unencrypted */ -#define IEEE80211_F_COUNTERM 0x04000000 /* CONF: TKIP countermeasures */ -#define IEEE80211_F_HIDESSID 0x08000000 /* CONF: hide SSID in beacon */ -#define IEEE80211_F_NOBRIDGE 0x10000000 /* CONF: dis. internal bridge */ -#define IEEE80211_F_PCF 0x20000000 /* CONF: PCF enabled */ -#define IEEE80211_F_DOTH 0x40000000 /* CONF: 11h enabled */ -#define IEEE80211_F_DWDS 0x80000000 /* CONF: Dynamic WDS enabled */ - -#define IEEE80211_F_BITS \ - "\20\1TURBOP\2COMP\3FF\4BURST\5PRIVACY\6PUREG\10SCAN\11ASCAN\12SIBSS" \ - "\13SHSLOT\14PMGTON\15DESBSSID\16WME\17BGSCAN\20SWRETRY\21TXPOW_FIXED" \ - "\22IBSSON\23SHPREAMBLE\24DATAPAD\25USEPROT\26USERBARKER\27CSAPENDING" \ - "\30WPA1\31WPA2\32DROPUNENC\33COUNTERM\34HIDESSID\35NOBRIDG\36PCF" \ - "\37DOTH\40DWDS" - -/* Atheros protocol-specific flags */ -#define IEEE80211_F_ATHEROS \ - (IEEE80211_F_FF | IEEE80211_F_COMP | IEEE80211_F_TURBOP) -/* Check if an Atheros capability was negotiated for use */ -#define IEEE80211_ATH_CAP(vap, ni, bit) \ - ((vap)->iv_flags & (ni)->ni_ath_flags & (bit)) - -/* ic_flags_ext/iv_flags_ext */ -#define IEEE80211_FEXT_INACT 0x00000002 /* CONF: sta inact handling */ -#define IEEE80211_FEXT_SCANWAIT 0x00000004 /* STATUS: awaiting scan */ -/* 0x00000006 reserved */ -#define IEEE80211_FEXT_BGSCAN 0x00000008 /* STATUS: complete bgscan */ -#define IEEE80211_FEXT_WPS 0x00000010 /* CONF: WPS enabled */ -#define IEEE80211_FEXT_TSN 0x00000020 /* CONF: TSN enabled */ -#define IEEE80211_FEXT_SCANREQ 0x00000040 /* STATUS: scan req params */ -#define IEEE80211_FEXT_RESUME 0x00000080 /* STATUS: start on resume */ -#define IEEE80211_FEXT_4ADDR 0x00000100 /* CONF: apply 4-addr encap */ -#define IEEE80211_FEXT_NONERP_PR 0x00000200 /* STATUS: non-ERP sta present*/ -#define IEEE80211_FEXT_SWBMISS 0x00000400 /* CONF: do bmiss in s/w */ -#define IEEE80211_FEXT_DFS 0x00000800 /* CONF: DFS enabled */ -#define IEEE80211_FEXT_DOTD 0x00001000 /* CONF: 11d enabled */ -#define IEEE80211_FEXT_STATEWAIT 0x00002000 /* STATUS: awaiting state chg */ -#define IEEE80211_FEXT_REINIT 0x00004000 /* STATUS: INIT state first */ -#define IEEE80211_FEXT_BPF 0x00008000 /* STATUS: BPF tap present */ -/* NB: immutable: should be set only when creating a vap */ -#define IEEE80211_FEXT_WDSLEGACY 0x00010000 /* CONF: legacy WDS operation */ -#define IEEE80211_FEXT_PROBECHAN 0x00020000 /* CONF: probe passive channel*/ -#define IEEE80211_FEXT_UNIQMAC 0x00040000 /* CONF: user or computed mac */ - -#define IEEE80211_FEXT_BITS \ - "\20\2INACT\3SCANWAIT\4BGSCAN\5WPS\6TSN\7SCANREQ\10RESUME" \ - "\0114ADDR\12NONEPR_PR\13SWBMISS\14DFS\15DOTD\16STATEWAIT\17REINIT" \ - "\20BPF\21WDSLEGACY\22PROBECHAN\23UNIQMAC" - -/* ic_flags_ht/iv_flags_ht */ -#define IEEE80211_FHT_NONHT_PR 0x00000001 /* STATUS: non-HT sta present */ -#define IEEE80211_FHT_GF 0x00040000 /* CONF: Greenfield enabled */ -#define IEEE80211_FHT_HT 0x00080000 /* CONF: HT supported */ -#define IEEE80211_FHT_AMPDU_TX 0x00100000 /* CONF: A-MPDU tx supported */ -#define IEEE80211_FHT_AMPDU_RX 0x00200000 /* CONF: A-MPDU rx supported */ -#define IEEE80211_FHT_AMSDU_TX 0x00400000 /* CONF: A-MSDU tx supported */ -#define IEEE80211_FHT_AMSDU_RX 0x00800000 /* CONF: A-MSDU rx supported */ -#define IEEE80211_FHT_USEHT40 0x01000000 /* CONF: 20/40 use enabled */ -#define IEEE80211_FHT_PUREN 0x02000000 /* CONF: 11n w/o legacy sta's */ -#define IEEE80211_FHT_SHORTGI20 0x04000000 /* CONF: short GI in HT20 */ -#define IEEE80211_FHT_SHORTGI40 0x08000000 /* CONF: short GI in HT40 */ -#define IEEE80211_FHT_HTCOMPAT 0x10000000 /* CONF: HT vendor OUI's */ -#define IEEE80211_FHT_RIFS 0x20000000 /* CONF: RIFS enabled */ -#define IEEE80211_FHT_STBC_TX 0x40000000 /* CONF: STBC tx enabled */ -#define IEEE80211_FHT_STBC_RX 0x80000000 /* CONF: STBC rx enabled */ - -#define IEEE80211_FHT_BITS \ - "\20\1NONHT_PR" \ - "\23GF\24HT\25AMPDU_TX\26AMPDU_TX" \ - "\27AMSDU_TX\30AMSDU_RX\31USEHT40\32PUREN\33SHORTGI20\34SHORTGI40" \ - "\35HTCOMPAT\36RIFS\37STBC_TX\40STBC_RX" - -#define IEEE80211_FVEN_BITS "\20" - -/* ic_caps/iv_caps: device driver capabilities */ -/* 0x2e available */ -#define IEEE80211_C_STA 0x00000001 /* CAPABILITY: STA available */ -#define IEEE80211_C_8023ENCAP 0x00000002 /* CAPABILITY: 802.3 encap */ -#define IEEE80211_C_FF 0x00000040 /* CAPABILITY: ATH FF avail */ -#define IEEE80211_C_TURBOP 0x00000080 /* CAPABILITY: ATH Turbo avail*/ -#define IEEE80211_C_IBSS 0x00000100 /* CAPABILITY: IBSS available */ -#define IEEE80211_C_PMGT 0x00000200 /* CAPABILITY: Power mgmt */ -#define IEEE80211_C_HOSTAP 0x00000400 /* CAPABILITY: HOSTAP avail */ -#define IEEE80211_C_AHDEMO 0x00000800 /* CAPABILITY: Old Adhoc Demo */ -#define IEEE80211_C_SWRETRY 0x00001000 /* CAPABILITY: sw tx retry */ -#define IEEE80211_C_TXPMGT 0x00002000 /* CAPABILITY: tx power mgmt */ -#define IEEE80211_C_SHSLOT 0x00004000 /* CAPABILITY: short slottime */ -#define IEEE80211_C_SHPREAMBLE 0x00008000 /* CAPABILITY: short preamble */ -#define IEEE80211_C_MONITOR 0x00010000 /* CAPABILITY: monitor mode */ -#define IEEE80211_C_DFS 0x00020000 /* CAPABILITY: DFS/radar avail*/ -#define IEEE80211_C_MBSS 0x00040000 /* CAPABILITY: MBSS available */ -/* 0x7c0000 available */ -#define IEEE80211_C_WPA1 0x00800000 /* CAPABILITY: WPA1 avail */ -#define IEEE80211_C_WPA2 0x01000000 /* CAPABILITY: WPA2 avail */ -#define IEEE80211_C_WPA 0x01800000 /* CAPABILITY: WPA1+WPA2 avail*/ -#define IEEE80211_C_BURST 0x02000000 /* CAPABILITY: frame bursting */ -#define IEEE80211_C_WME 0x04000000 /* CAPABILITY: WME avail */ -#define IEEE80211_C_WDS 0x08000000 /* CAPABILITY: 4-addr support */ -/* 0x10000000 reserved */ -#define IEEE80211_C_BGSCAN 0x20000000 /* CAPABILITY: bg scanning */ -#define IEEE80211_C_TXFRAG 0x40000000 /* CAPABILITY: tx fragments */ -#define IEEE80211_C_TDMA 0x80000000 /* CAPABILITY: TDMA avail */ -/* XXX protection/barker? */ - -#define IEEE80211_C_OPMODE \ - (IEEE80211_C_STA | IEEE80211_C_IBSS | IEEE80211_C_HOSTAP | \ - IEEE80211_C_AHDEMO | IEEE80211_C_MONITOR | IEEE80211_C_WDS | \ - IEEE80211_C_TDMA | IEEE80211_C_MBSS) - -#define IEEE80211_C_BITS \ - "\20\1STA\002803ENCAP\7FF\10TURBOP\11IBSS\12PMGT" \ - "\13HOSTAP\14AHDEMO\15SWRETRY\16TXPMGT\17SHSLOT\20SHPREAMBLE" \ - "\21MONITOR\22DFS\23MBSS\30WPA1\31WPA2\32BURST\33WME\34WDS\36BGSCAN" \ - "\37TXFRAG\40TDMA" - -/* - * ic_htcaps/iv_htcaps: HT-specific device/driver capabilities - * - * NB: the low 16-bits are the 802.11 definitions, the upper - * 16-bits are used to define s/w/driver capabilities. - */ -#define IEEE80211_HTC_AMPDU 0x00010000 /* CAPABILITY: A-MPDU tx */ -#define IEEE80211_HTC_AMSDU 0x00020000 /* CAPABILITY: A-MSDU tx */ -/* NB: HT40 is implied by IEEE80211_HTCAP_CHWIDTH40 */ -#define IEEE80211_HTC_HT 0x00040000 /* CAPABILITY: HT operation */ -#define IEEE80211_HTC_SMPS 0x00080000 /* CAPABILITY: MIMO power save*/ -#define IEEE80211_HTC_RIFS 0x00100000 /* CAPABILITY: RIFS support */ -#define IEEE80211_HTC_RXUNEQUAL 0x00200000 /* CAPABILITY: RX unequal MCS */ -#define IEEE80211_HTC_RXMCS32 0x00400000 /* CAPABILITY: MCS32 support */ -#define IEEE80211_HTC_TXUNEQUAL 0x00800000 /* CAPABILITY: TX unequal MCS */ -#define IEEE80211_HTC_TXMCS32 0x01000000 /* CAPABILITY: MCS32 suport */ - -#define IEEE80211_C_HTCAP_BITS \ - "\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \ - "\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS" - -void ieee80211_ifattach(struct ieee80211com *, - const uint8_t macaddr[IEEE80211_ADDR_LEN]); -void ieee80211_ifdetach(struct ieee80211com *); -int ieee80211_vap_setup(struct ieee80211com *, struct ieee80211vap *, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t macaddr[IEEE80211_ADDR_LEN]); -int ieee80211_vap_attach(struct ieee80211vap *, - ifm_change_cb_t, ifm_stat_cb_t); -void ieee80211_vap_detach(struct ieee80211vap *); -const struct ieee80211_rateset *ieee80211_get_suprates(struct ieee80211com *ic, - const struct ieee80211_channel *); -void ieee80211_announce(struct ieee80211com *); -void ieee80211_announce_channels(struct ieee80211com *); -void ieee80211_drain(struct ieee80211com *); -void ieee80211_media_init(struct ieee80211com *); -struct ieee80211com *ieee80211_find_vap(const uint8_t mac[IEEE80211_ADDR_LEN]); -int ieee80211_media_change(struct ifnet *); -void ieee80211_media_status(struct ifnet *, struct ifmediareq *); -int ieee80211_ioctl(struct ifnet *, u_long, caddr_t); -int ieee80211_rate2media(struct ieee80211com *, int, - enum ieee80211_phymode); -int ieee80211_media2rate(int); -int ieee80211_mhz2ieee(u_int, u_int); -int ieee80211_chan2ieee(struct ieee80211com *, - const struct ieee80211_channel *); -u_int ieee80211_ieee2mhz(u_int, u_int); -struct ieee80211_channel *ieee80211_find_channel(struct ieee80211com *, - int freq, int flags); -struct ieee80211_channel *ieee80211_find_channel_byieee(struct ieee80211com *, - int ieee, int flags); -int ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode); -enum ieee80211_phymode ieee80211_chan2mode(const struct ieee80211_channel *); -uint32_t ieee80211_mac_hash(const struct ieee80211com *, - const uint8_t addr[IEEE80211_ADDR_LEN]); - -void ieee80211_radiotap_attach(struct ieee80211com *, - struct ieee80211_radiotap_header *th, int tlen, - uint32_t tx_radiotap, - struct ieee80211_radiotap_header *rh, int rlen, - uint32_t rx_radiotap); -void ieee80211_radiotap_detach(struct ieee80211com *); -void ieee80211_radiotap_vattach(struct ieee80211vap *); -void ieee80211_radiotap_vdetach(struct ieee80211vap *); -void ieee80211_radiotap_chan_change(struct ieee80211com *); -void ieee80211_radiotap_tx(struct ieee80211vap *, struct mbuf *); -void ieee80211_radiotap_rx(struct ieee80211vap *, struct mbuf *); -void ieee80211_radiotap_rx_all(struct ieee80211com *, struct mbuf *); - -static __inline int -ieee80211_radiotap_active(const struct ieee80211com *ic) -{ - return (ic->ic_flags_ext & IEEE80211_FEXT_BPF) != 0; -} - -static __inline int -ieee80211_radiotap_active_vap(const struct ieee80211vap *vap) -{ - return (vap->iv_flags_ext & IEEE80211_FEXT_BPF) || - vap->iv_ic->ic_montaps != 0; -} - -/* - * Enqueue a task on the state thread. - */ -static __inline void -ieee80211_runtask(struct ieee80211com *ic, struct task *task) -{ - taskqueue_enqueue(ic->ic_tq, task); -} - -/* - * Wait for a queued task to complete. - */ -static __inline void -ieee80211_draintask(struct ieee80211com *ic, struct task *task) -{ - taskqueue_drain(ic->ic_tq, task); -} - -/* - * Key update synchronization methods. XXX should not be visible. - */ -static __inline void -ieee80211_key_update_begin(struct ieee80211vap *vap) -{ - vap->iv_key_update_begin(vap); -} -static __inline void -ieee80211_key_update_end(struct ieee80211vap *vap) -{ - vap->iv_key_update_end(vap); -} - -/* - * XXX these need to be here for IEEE80211_F_DATAPAD - */ - -/* - * Return the space occupied by the 802.11 header and any - * padding required by the driver. This works for a - * management or data frame. - */ -static __inline int -ieee80211_hdrspace(struct ieee80211com *ic, const void *data) -{ - int size = ieee80211_hdrsize(data); - if (ic->ic_flags & IEEE80211_F_DATAPAD) - size = roundup(size, sizeof(uint32_t)); - return size; -} - -/* - * Like ieee80211_hdrspace, but handles any type of frame. - */ -static __inline int -ieee80211_anyhdrspace(struct ieee80211com *ic, const void *data) -{ - int size = ieee80211_anyhdrsize(data); - if (ic->ic_flags & IEEE80211_F_DATAPAD) - size = roundup(size, sizeof(uint32_t)); - return size; -} - -/* - * Notify a vap that beacon state has been updated. - */ -static __inline void -ieee80211_beacon_notify(struct ieee80211vap *vap, int what) -{ - if (vap->iv_state == IEEE80211_S_RUN) - vap->iv_update_beacon(vap, what); -} - -/* - * Calculate HT channel promotion flags for a channel. - * XXX belongs in ieee80211_ht.h but needs IEEE80211_FHT_* - */ -static __inline int -ieee80211_htchanflags(const struct ieee80211_channel *c) -{ - return IEEE80211_IS_CHAN_HT40(c) ? - IEEE80211_FHT_HT | IEEE80211_FHT_USEHT40 : - IEEE80211_IS_CHAN_HT(c) ? IEEE80211_FHT_HT : 0; -} - -/* - * Debugging facilities compiled in when IEEE80211_DEBUG is defined. - * - * The intent is that any problem in the net80211 layer can be - * diagnosed by inspecting the statistics (dumped by the wlanstats - * program) and/or the msgs generated by net80211. Messages are - * broken into functional classes and can be controlled with the - * wlandebug program. Certain of these msg groups are for facilities - * that are no longer part of net80211 (e.g. IEEE80211_MSG_DOT1XSM). - */ -#define IEEE80211_MSG_11N 0x80000000 /* 11n mode debug */ -#define IEEE80211_MSG_DEBUG 0x40000000 /* IFF_DEBUG equivalent */ -#define IEEE80211_MSG_DUMPPKTS 0x20000000 /* IFF_LINK2 equivalant */ -#define IEEE80211_MSG_CRYPTO 0x10000000 /* crypto work */ -#define IEEE80211_MSG_INPUT 0x08000000 /* input handling */ -#define IEEE80211_MSG_XRATE 0x04000000 /* rate set handling */ -#define IEEE80211_MSG_ELEMID 0x02000000 /* element id parsing */ -#define IEEE80211_MSG_NODE 0x01000000 /* node handling */ -#define IEEE80211_MSG_ASSOC 0x00800000 /* association handling */ -#define IEEE80211_MSG_AUTH 0x00400000 /* authentication handling */ -#define IEEE80211_MSG_SCAN 0x00200000 /* scanning */ -#define IEEE80211_MSG_OUTPUT 0x00100000 /* output handling */ -#define IEEE80211_MSG_STATE 0x00080000 /* state machine */ -#define IEEE80211_MSG_POWER 0x00040000 /* power save handling */ -#define IEEE80211_MSG_HWMP 0x00020000 /* hybrid mesh protocol */ -#define IEEE80211_MSG_DOT1XSM 0x00010000 /* 802.1x state machine */ -#define IEEE80211_MSG_RADIUS 0x00008000 /* 802.1x radius client */ -#define IEEE80211_MSG_RADDUMP 0x00004000 /* dump 802.1x radius packets */ -#define IEEE80211_MSG_MESH 0x00002000 /* mesh networking */ -#define IEEE80211_MSG_WPA 0x00001000 /* WPA/RSN protocol */ -#define IEEE80211_MSG_ACL 0x00000800 /* ACL handling */ -#define IEEE80211_MSG_WME 0x00000400 /* WME protocol */ -#define IEEE80211_MSG_SUPERG 0x00000200 /* Atheros SuperG protocol */ -#define IEEE80211_MSG_DOTH 0x00000100 /* 802.11h support */ -#define IEEE80211_MSG_INACT 0x00000080 /* inactivity handling */ -#define IEEE80211_MSG_ROAM 0x00000040 /* sta-mode roaming */ -#define IEEE80211_MSG_RATECTL 0x00000020 /* tx rate control */ -#define IEEE80211_MSG_ACTION 0x00000010 /* action frame handling */ -#define IEEE80211_MSG_WDS 0x00000008 /* WDS handling */ -#define IEEE80211_MSG_IOCTL 0x00000004 /* ioctl handling */ -#define IEEE80211_MSG_TDMA 0x00000002 /* TDMA handling */ - -#define IEEE80211_MSG_ANY 0xffffffff /* anything */ - -#define IEEE80211_MSG_BITS \ - "\20\2TDMA\3IOCTL\4WDS\5ACTION\6RATECTL\7ROAM\10INACT\11DOTH\12SUPERG" \ - "\13WME\14ACL\15WPA\16RADKEYS\17RADDUMP\20RADIUS\21DOT1XSM\22HWMP" \ - "\23POWER\24STATE\25OUTPUT\26SCAN\27AUTH\30ASSOC\31NODE\32ELEMID" \ - "\33XRATE\34INPUT\35CRYPTO\36DUPMPKTS\37DEBUG\04011N" - -#ifdef IEEE80211_DEBUG -#define ieee80211_msg(_vap, _m) ((_vap)->iv_debug & (_m)) -#define IEEE80211_DPRINTF(_vap, _m, _fmt, ...) do { \ - if (ieee80211_msg(_vap, _m)) \ - ieee80211_note(_vap, _fmt, __VA_ARGS__); \ -} while (0) -#define IEEE80211_NOTE(_vap, _m, _ni, _fmt, ...) do { \ - if (ieee80211_msg(_vap, _m)) \ - ieee80211_note_mac(_vap, (_ni)->ni_macaddr, _fmt, __VA_ARGS__);\ -} while (0) -#define IEEE80211_NOTE_MAC(_vap, _m, _mac, _fmt, ...) do { \ - if (ieee80211_msg(_vap, _m)) \ - ieee80211_note_mac(_vap, _mac, _fmt, __VA_ARGS__); \ -} while (0) -#define IEEE80211_NOTE_FRAME(_vap, _m, _wh, _fmt, ...) do { \ - if (ieee80211_msg(_vap, _m)) \ - ieee80211_note_frame(_vap, _wh, _fmt, __VA_ARGS__); \ -} while (0) -void ieee80211_note(const struct ieee80211vap *, const char *, ...); -void ieee80211_note_mac(const struct ieee80211vap *, - const uint8_t mac[IEEE80211_ADDR_LEN], const char *, ...); -void ieee80211_note_frame(const struct ieee80211vap *, - const struct ieee80211_frame *, const char *, ...); -#define ieee80211_msg_debug(_vap) \ - ((_vap)->iv_debug & IEEE80211_MSG_DEBUG) -#define ieee80211_msg_dumppkts(_vap) \ - ((_vap)->iv_debug & IEEE80211_MSG_DUMPPKTS) -#define ieee80211_msg_input(_vap) \ - ((_vap)->iv_debug & IEEE80211_MSG_INPUT) -#define ieee80211_msg_radius(_vap) \ - ((_vap)->iv_debug & IEEE80211_MSG_RADIUS) -#define ieee80211_msg_dumpradius(_vap) \ - ((_vap)->iv_debug & IEEE80211_MSG_RADDUMP) -#define ieee80211_msg_dumpradkeys(_vap) \ - ((_vap)->iv_debug & IEEE80211_MSG_RADKEYS) -#define ieee80211_msg_scan(_vap) \ - ((_vap)->iv_debug & IEEE80211_MSG_SCAN) -#define ieee80211_msg_assoc(_vap) \ - ((_vap)->iv_debug & IEEE80211_MSG_ASSOC) - -/* - * Emit a debug message about discarding a frame or information - * element. One format is for extracting the mac address from - * the frame header; the other is for when a header is not - * available or otherwise appropriate. - */ -#define IEEE80211_DISCARD(_vap, _m, _wh, _type, _fmt, ...) do { \ - if ((_vap)->iv_debug & (_m)) \ - ieee80211_discard_frame(_vap, _wh, _type, _fmt, __VA_ARGS__);\ -} while (0) -#define IEEE80211_DISCARD_IE(_vap, _m, _wh, _type, _fmt, ...) do { \ - if ((_vap)->iv_debug & (_m)) \ - ieee80211_discard_ie(_vap, _wh, _type, _fmt, __VA_ARGS__);\ -} while (0) -#define IEEE80211_DISCARD_MAC(_vap, _m, _mac, _type, _fmt, ...) do { \ - if ((_vap)->iv_debug & (_m)) \ - ieee80211_discard_mac(_vap, _mac, _type, _fmt, __VA_ARGS__);\ -} while (0) - -void ieee80211_discard_frame(const struct ieee80211vap *, - const struct ieee80211_frame *, const char *type, const char *fmt, ...); -void ieee80211_discard_ie(const struct ieee80211vap *, - const struct ieee80211_frame *, const char *type, const char *fmt, ...); -void ieee80211_discard_mac(const struct ieee80211vap *, - const uint8_t mac[IEEE80211_ADDR_LEN], const char *type, - const char *fmt, ...); -#else -#define IEEE80211_DPRINTF(_vap, _m, _fmt, ...) -#define IEEE80211_NOTE(_vap, _m, _ni, _fmt, ...) -#define IEEE80211_NOTE_FRAME(_vap, _m, _wh, _fmt, ...) -#define IEEE80211_NOTE_MAC(_vap, _m, _mac, _fmt, ...) -#define ieee80211_msg_dumppkts(_vap) 0 -#define ieee80211_msg(_vap, _m) 0 - -#define IEEE80211_DISCARD(_vap, _m, _wh, _type, _fmt, ...) -#define IEEE80211_DISCARD_IE(_vap, _m, _wh, _type, _fmt, ...) -#define IEEE80211_DISCARD_MAC(_vap, _m, _mac, _type, _fmt, ...) -#endif - -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_VAR_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_wds.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_wds.c deleted file mode 100644 index ed82fac1c0..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_wds.c +++ /dev/null @@ -1,800 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifdef __FreeBSD__ -__FBSDID("$FreeBSD$"); -#endif - -/* - * IEEE 802.11 WDS mode support. - */ -#include "opt_inet.h" -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#ifdef IEEE80211_SUPPORT_SUPERG -#include -#endif - -static void wds_vattach(struct ieee80211vap *); -static int wds_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int wds_input(struct ieee80211_node *ni, struct mbuf *m, int, int); -static void wds_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int, int); - -void -ieee80211_wds_attach(struct ieee80211com *ic) -{ - ic->ic_vattach[IEEE80211_M_WDS] = wds_vattach; -} - -void -ieee80211_wds_detach(struct ieee80211com *ic) -{ -} - -static void -wds_vdetach(struct ieee80211vap *vap) -{ - if (vap->iv_bss != NULL) { - /* XXX locking? */ - if (vap->iv_bss->ni_wdsvap == vap) - vap->iv_bss->ni_wdsvap = NULL; - } -} - -static void -wds_vattach(struct ieee80211vap *vap) -{ - vap->iv_newstate = wds_newstate; - vap->iv_input = wds_input; - vap->iv_recv_mgmt = wds_recv_mgmt; - vap->iv_opdetach = wds_vdetach; -} - -static void -wds_flush(struct ieee80211_node *ni) -{ - struct ieee80211com *ic = ni->ni_ic; - struct mbuf *m, *next; - int8_t rssi, nf; - - m = ieee80211_ageq_remove(&ic->ic_stageq, - (void *)(uintptr_t) ieee80211_mac_hash(ic, ni->ni_macaddr)); - if (m == NULL) - return; - - IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_WDS, ni, - "%s", "flush wds queue"); - ic->ic_node_getsignal(ni, &rssi, &nf); - for (; m != NULL; m = next) { - next = m->m_nextpkt; - m->m_nextpkt = NULL; - ieee80211_input(ni, m, rssi, nf); - } -} - -static int -ieee80211_create_wds(struct ieee80211vap *vap, struct ieee80211_channel *chan) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node_table *nt = &ic->ic_sta; - struct ieee80211_node *ni, *obss; - - IEEE80211_DPRINTF(vap, IEEE80211_MSG_WDS, - "%s: creating link to %s on channel %u\n", __func__, - ether_sprintf(vap->iv_des_bssid), ieee80211_chan2ieee(ic, chan)); - - /* NB: vap create must specify the bssid for the link */ - KASSERT(vap->iv_flags & IEEE80211_F_DESBSSID, ("no bssid")); - /* NB: we should only be called on RUN transition */ - KASSERT(vap->iv_state == IEEE80211_S_RUN, ("!RUN state")); - - if ((vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY) == 0) { - /* - * Dynamic/non-legacy WDS. Reference the associated - * station specified by the desired bssid setup at vap - * create. Point ni_wdsvap at the WDS vap so 4-address - * frames received through the associated AP vap will - * be dispatched upward (e.g. to a bridge) as though - * they arrived on the WDS vap. - */ - IEEE80211_NODE_LOCK(nt); - obss = NULL; - ni = ieee80211_find_node_locked(&ic->ic_sta, vap->iv_des_bssid); - if (ni == NULL) { - /* - * Node went away before we could hookup. This - * should be ok; no traffic will flow and a leave - * event will be dispatched that should cause - * the vap to be destroyed. - */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_WDS, - "%s: station %s went away\n", - __func__, ether_sprintf(vap->iv_des_bssid)); - /* XXX stat? */ - } else if (ni->ni_wdsvap != NULL) { - /* - * Node already setup with a WDS vap; we cannot - * allow multiple references so disallow. If - * ni_wdsvap points at us that's ok; we should - * do nothing anyway. - */ - /* XXX printf instead? */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_WDS, - "%s: station %s in use with %s\n", - __func__, ether_sprintf(vap->iv_des_bssid), - ni->ni_wdsvap->iv_ifp->if_xname); - /* XXX stat? */ - } else { - /* - * Committed to new node, setup state. - */ - obss = vap->iv_bss; - vap->iv_bss = ni; - ni->ni_wdsvap = vap; - } - IEEE80211_NODE_UNLOCK(nt); - if (obss != NULL) { - /* NB: deferred to avoid recursive lock */ - ieee80211_free_node(obss); - } - } else { - /* - * Legacy WDS vap setup. - */ - /* - * The far end does not associate so we just create - * create a new node and install it as the vap's - * bss node. We must simulate an association and - * authorize the port for traffic to flow. - * XXX check if node already in sta table? - */ - ni = ieee80211_node_create_wds(vap, vap->iv_des_bssid, chan); - if (ni != NULL) { - obss = vap->iv_bss; - vap->iv_bss = ieee80211_ref_node(ni); - ni->ni_flags |= IEEE80211_NODE_AREF; - if (obss != NULL) - ieee80211_free_node(obss); - /* give driver a chance to setup state like ni_txrate */ - if (ic->ic_newassoc != NULL) - ic->ic_newassoc(ni, 1); - /* tell the authenticator about new station */ - if (vap->iv_auth->ia_node_join != NULL) - vap->iv_auth->ia_node_join(ni); - if (ni->ni_authmode != IEEE80211_AUTH_8021X) - ieee80211_node_authorize(ni); - - ieee80211_notify_node_join(ni, 1 /*newassoc*/); - /* XXX inject l2uf frame */ - } - } - - /* - * Flush any pending frames now that were setup. - */ - if (ni != NULL) - wds_flush(ni); - return (ni == NULL ? ENOENT : 0); -} - -/* - * Propagate multicast frames of an ap vap to all DWDS links. - * The caller is assumed to have verified this frame is multicast. - */ -void -ieee80211_dwds_mcast(struct ieee80211vap *vap0, struct mbuf *m) -{ - struct ieee80211com *ic = vap0->iv_ic; - struct ifnet *parent = ic->ic_ifp; - const struct ether_header *eh = mtod(m, const struct ether_header *); - struct ieee80211_node *ni; - struct ieee80211vap *vap; - struct ifnet *ifp; - struct mbuf *mcopy; - int err; - - KASSERT(ETHER_IS_MULTICAST(eh->ether_dhost), - ("%s not mcast", ether_sprintf(eh->ether_dhost))); - - /* XXX locking */ - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - /* only DWDS vaps are interesting */ - if (vap->iv_opmode != IEEE80211_M_WDS || - (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY)) - continue; - /* if it came in this interface, don't send it back out */ - ifp = vap->iv_ifp; - if (ifp == m->m_pkthdr.rcvif) - continue; - /* - * Duplicate the frame and send it. - */ - mcopy = m_copypacket(m, M_DONTWAIT); - if (mcopy == NULL) { - ifp->if_oerrors++; - /* XXX stat + msg */ - continue; - } - ni = ieee80211_find_txnode(vap, eh->ether_dhost); - if (ni == NULL) { - /* NB: ieee80211_find_txnode does stat+msg */ - ifp->if_oerrors++; - m_freem(mcopy); - continue; - } - /* calculate priority so drivers can find the tx queue */ - if (ieee80211_classify(ni, mcopy)) { - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_OUTPUT | IEEE80211_MSG_WDS, - eh->ether_dhost, NULL, - "%s", "classification failure"); - vap->iv_stats.is_tx_classify++; - ifp->if_oerrors++; - m_freem(mcopy); - ieee80211_free_node(ni); - continue; - } - - BPF_MTAP(ifp, m); /* 802.3 tx */ - - /* - * Encapsulate the packet in prep for transmission. - */ - mcopy = ieee80211_encap(vap, ni, mcopy); - if (mcopy == NULL) { - /* NB: stat+msg handled in ieee80211_encap */ - ieee80211_free_node(ni); - continue; - } - mcopy->m_flags |= M_MCAST; - mcopy->m_pkthdr.rcvif = (void *) ni; - - err = parent->if_transmit(parent, mcopy); - if (err) { - /* NB: IFQ_HANDOFF reclaims mbuf */ - ifp->if_oerrors++; - ieee80211_free_node(ni); - } else - ifp->if_opackets++; - } -} - -/* - * Handle DWDS discovery on receipt of a 4-address frame in - * ap mode. Queue the frame and post an event for someone - * to plumb the necessary WDS vap for this station. Frames - * received prior to the vap set running will then be reprocessed - * as if they were just received. - */ -void -ieee80211_dwds_discover(struct ieee80211_node *ni, struct mbuf *m) -{ - struct ieee80211com *ic = ni->ni_ic; - - /* - * Save the frame with an aging interval 4 times - * the listen interval specified by the station. - * Frames that sit around too long are reclaimed - * using this information. - * XXX handle overflow? - * XXX per/vap beacon interval? - */ - m->m_pkthdr.rcvif = (void *)(uintptr_t) - ieee80211_mac_hash(ic, ni->ni_macaddr); - (void) ieee80211_ageq_append(&ic->ic_stageq, m, - ((ni->ni_intval * ic->ic_lintval) << 2) / 1024); - ieee80211_notify_wds_discover(ni); -} - -/* - * IEEE80211_M_WDS vap state machine handler. - */ -static int -wds_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni; - enum ieee80211_state ostate; - int error; - - IEEE80211_LOCK_ASSERT(ic); - - ostate = vap->iv_state; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s\n", __func__, - ieee80211_state_name[ostate], ieee80211_state_name[nstate]); - vap->iv_state = nstate; /* state transition */ - callout_stop(&vap->iv_mgtsend); /* XXX callout_drain */ - if (ostate != IEEE80211_S_SCAN) - ieee80211_cancel_scan(vap); /* background scan */ - ni = vap->iv_bss; /* NB: no reference held */ - error = 0; - switch (nstate) { - case IEEE80211_S_INIT: - switch (ostate) { - case IEEE80211_S_SCAN: - ieee80211_cancel_scan(vap); - break; - default: - break; - } - if (ostate != IEEE80211_S_INIT) { - /* NB: optimize INIT -> INIT case */ - ieee80211_reset_bss(vap); - } - break; - case IEEE80211_S_SCAN: - switch (ostate) { - case IEEE80211_S_INIT: - ieee80211_check_scan_current(vap); - break; - default: - break; - } - break; - case IEEE80211_S_RUN: - if (ostate == IEEE80211_S_INIT) { - /* - * Already have a channel; bypass the scan - * and startup immediately. - */ - error = ieee80211_create_wds(vap, ic->ic_curchan); - } - break; - default: - break; - } - return error; -} - -/* - * Process a received frame. The node associated with the sender - * should be supplied. If nothing was found in the node table then - * the caller is assumed to supply a reference to iv_bss instead. - * The RSSI and a timestamp are also supplied. The RSSI data is used - * during AP scanning to select a AP to associate with; it can have - * any units so long as values have consistent units and higher values - * mean ``better signal''. The receive timestamp is currently not used - * by the 802.11 layer. - */ -static int -wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) -{ -#define HAS_SEQ(type) ((type & 0x4) == 0) - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = vap->iv_ifp; - struct ieee80211_frame *wh; - struct ieee80211_key *key; - struct ether_header *eh; - int hdrspace, need_tap = 1; /* mbuf need to be tapped. */ - uint8_t dir, type, subtype, qos; - uint16_t rxseq; - - if (m->m_flags & M_AMPDU_MPDU) { - /* - * Fastpath for A-MPDU reorder q resubmission. Frames - * w/ M_AMPDU_MPDU marked have already passed through - * here but were received out of order and been held on - * the reorder queue. When resubmitted they are marked - * with the M_AMPDU_MPDU flag and we can bypass most of - * the normal processing. - */ - wh = mtod(m, struct ieee80211_frame *); - type = IEEE80211_FC0_TYPE_DATA; - dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; - subtype = IEEE80211_FC0_SUBTYPE_QOS; - hdrspace = ieee80211_hdrspace(ic, wh); /* XXX optimize? */ - goto resubmit_ampdu; - } - - KASSERT(ni != NULL, ("null node")); - - type = -1; /* undefined */ - - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, - "too short (1): len %u", m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } - /* - * Bit of a cheat here, we use a pointer for a 3-address - * frame format but don't reference fields past outside - * ieee80211_frame_min w/o first validating the data is - * present. - */ - wh = mtod(m, struct ieee80211_frame *); - - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) - ni->ni_inact = ni->ni_inact_reload; - - if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != - IEEE80211_FC0_VERSION_0) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, "wrong version, fc %02x:%02x", - wh->i_fc[0], wh->i_fc[1]); - vap->iv_stats.is_rx_badversion++; - goto err; - } - - dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; - type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; - subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - - /* NB: WDS vap's do not scan */ - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_addr4)) { - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_ANY, ni->ni_macaddr, NULL, - "too short (3): len %u", m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } - /* NB: the TA is implicitly verified by finding the wds peer node */ - if (!IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr) && - !IEEE80211_ADDR_EQ(wh->i_addr1, ifp->if_broadcastaddr)) { - /* not interested in */ - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - wh->i_addr1, NULL, "%s", "not to bss"); - vap->iv_stats.is_rx_wrongbss++; - goto out; - } - IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = nf; - if (HAS_SEQ(type)) { - uint8_t tid = ieee80211_gettid(wh); - if (IEEE80211_QOS_HAS_SEQ(wh) && - TID_TO_WME_AC(tid) >= WME_AC_VI) - ic->ic_wme.wme_hipri_traffic++; - rxseq = le16toh(*(uint16_t *)wh->i_seq); - if (! ieee80211_check_rxseq(ni, wh)) { - /* duplicate, discard */ - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - wh->i_addr1, "duplicate", - "seqno <%u,%u> fragno <%u,%u> tid %u", - rxseq >> IEEE80211_SEQ_SEQ_SHIFT, - ni->ni_rxseqs[tid] >> IEEE80211_SEQ_SEQ_SHIFT, - rxseq & IEEE80211_SEQ_FRAG_MASK, - ni->ni_rxseqs[tid] & IEEE80211_SEQ_FRAG_MASK, - tid); - vap->iv_stats.is_rx_dup++; - IEEE80211_NODE_STAT(ni, rx_dup); - goto out; - } - ni->ni_rxseqs[tid] = rxseq; - } - switch (type) { - case IEEE80211_FC0_TYPE_DATA: - hdrspace = ieee80211_hdrspace(ic, wh); - if (m->m_len < hdrspace && - (m = m_pullup(m, hdrspace)) == NULL) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, NULL, - "data too short: expecting %u", hdrspace); - vap->iv_stats.is_rx_tooshort++; - goto out; /* XXX */ - } - if (dir != IEEE80211_FC1_DIR_DSTODS) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "data", "incorrect dir 0x%x", dir); - vap->iv_stats.is_rx_wrongdir++; - goto out; - } - /* - * Only legacy WDS traffic should take this path. - */ - if ((vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY) == 0) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "data", "%s", "not legacy wds"); - vap->iv_stats.is_rx_wrongdir++;/*XXX*/ - goto out; - } - /* - * Handle A-MPDU re-ordering. If the frame is to be - * processed directly then ieee80211_ampdu_reorder - * will return 0; otherwise it has consumed the mbuf - * and we should do nothing more with it. - */ - if ((m->m_flags & M_AMPDU) && - ieee80211_ampdu_reorder(ni, m) != 0) { - m = NULL; - goto out; - } - resubmit_ampdu: - - /* - * Handle privacy requirements. Note that we - * must not be preempted from here until after - * we (potentially) call ieee80211_crypto_demic; - * otherwise we may violate assumptions in the - * crypto cipher modules used to do delayed update - * of replay sequence numbers. - */ - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { - /* - * Discard encrypted frames when privacy is off. - */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "WEP", "%s", "PRIVACY off"); - vap->iv_stats.is_rx_noprivacy++; - IEEE80211_NODE_STAT(ni, rx_noprivacy); - goto out; - } - key = ieee80211_crypto_decap(ni, m, hdrspace); - if (key == NULL) { - /* NB: stats+msgs handled in crypto_decap */ - IEEE80211_NODE_STAT(ni, rx_wepfail); - goto out; - } - wh = mtod(m, struct ieee80211_frame *); - wh->i_fc[1] &= ~IEEE80211_FC1_WEP; - } else { - /* XXX M_WEP and IEEE80211_F_PRIVACY */ - key = NULL; - } - - /* - * Save QoS bits for use below--before we strip the header. - */ - if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { - qos = (dir == IEEE80211_FC1_DIR_DSTODS) ? - ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] : - ((struct ieee80211_qosframe *)wh)->i_qos[0]; - } else - qos = 0; - - /* - * Next up, any fragmentation. - */ - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - m = ieee80211_defrag(ni, m, hdrspace); - if (m == NULL) { - /* Fragment dropped or frame not complete yet */ - goto out; - } - } - wh = NULL; /* no longer valid, catch any uses */ - - /* - * Next strip any MSDU crypto bits. - */ - if (key != NULL && !ieee80211_crypto_demic(vap, key, m, 0)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - ni->ni_macaddr, "data", "%s", "demic error"); - vap->iv_stats.is_rx_demicfail++; - IEEE80211_NODE_STAT(ni, rx_demicfail); - goto out; - } - - /* copy to listener after decrypt */ - if (ieee80211_radiotap_active_vap(vap)) - ieee80211_radiotap_rx(vap, m); - need_tap = 0; - - /* - * Finally, strip the 802.11 header. - */ - m = ieee80211_decap(vap, m, hdrspace); - if (m == NULL) { - /* XXX mask bit to check for both */ - /* don't count Null data frames as errors */ - if (subtype == IEEE80211_FC0_SUBTYPE_NODATA || - subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL) - goto out; - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - ni->ni_macaddr, "data", "%s", "decap error"); - vap->iv_stats.is_rx_decap++; - IEEE80211_NODE_STAT(ni, rx_decap); - goto err; - } - eh = mtod(m, struct ether_header *); - if (!ieee80211_node_is_authorized(ni)) { - /* - * Deny any non-PAE frames received prior to - * authorization. For open/shared-key - * authentication the port is mark authorized - * after authentication completes. For 802.1x - * the port is not marked authorized by the - * authenticator until the handshake has completed. - */ - if (eh->ether_type != htons(ETHERTYPE_PAE)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - eh->ether_shost, "data", - "unauthorized port: ether type 0x%x len %u", - eh->ether_type, m->m_pkthdr.len); - vap->iv_stats.is_rx_unauth++; - IEEE80211_NODE_STAT(ni, rx_unauth); - goto err; - } - } else { - /* - * When denying unencrypted frames, discard - * any non-PAE frames received without encryption. - */ - if ((vap->iv_flags & IEEE80211_F_DROPUNENC) && - (key == NULL && (m->m_flags & M_WEP) == 0) && - eh->ether_type != htons(ETHERTYPE_PAE)) { - /* - * Drop unencrypted frames. - */ - vap->iv_stats.is_rx_unencrypted++; - IEEE80211_NODE_STAT(ni, rx_unencrypted); - goto out; - } - } - /* XXX require HT? */ - if (qos & IEEE80211_QOS_AMSDU) { - m = ieee80211_decap_amsdu(ni, m); - if (m == NULL) - return IEEE80211_FC0_TYPE_DATA; - } else { -#ifdef IEEE80211_SUPPORT_SUPERG - m = ieee80211_decap_fastframe(vap, ni, m); - if (m == NULL) - return IEEE80211_FC0_TYPE_DATA; -#endif - } - ieee80211_deliver_data(vap, ni, m); - return IEEE80211_FC0_TYPE_DATA; - - case IEEE80211_FC0_TYPE_MGT: - vap->iv_stats.is_rx_mgmt++; - IEEE80211_NODE_STAT(ni, rx_mgmt); - if (dir != IEEE80211_FC1_DIR_NODS) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, "data", "incorrect dir 0x%x", dir); - vap->iv_stats.is_rx_wrongdir++; - goto err; - } - if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, - ni->ni_macaddr, "mgt", "too short: len %u", - m->m_pkthdr.len); - vap->iv_stats.is_rx_tooshort++; - goto out; - } -#ifdef IEEE80211_DEBUG - if (ieee80211_msg_debug(vap) || ieee80211_msg_dumppkts(vap)) { - if_printf(ifp, "received %s from %s rssi %d\n", - ieee80211_mgt_subtype_name[subtype >> - IEEE80211_FC0_SUBTYPE_SHIFT], - ether_sprintf(wh->i_addr2), rssi); - } -#endif - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "WEP set but not permitted"); - vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ - goto out; - } - vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); - goto out; - - case IEEE80211_FC0_TYPE_CTL: - vap->iv_stats.is_rx_ctl++; - IEEE80211_NODE_STAT(ni, rx_ctrl); - goto out; - - default: - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "bad", "frame type 0x%x", type); - /* should not come here */ - break; - } -err: - ifp->if_ierrors++; -out: - if (m != NULL) { - if (need_tap && ieee80211_radiotap_active_vap(vap)) - ieee80211_radiotap_rx(vap, m); - m_freem(m); - } - return type; -} - -static void -wds_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int nf) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_frame *wh; - u_int8_t *frm, *efrm; - - wh = mtod(m0, struct ieee80211_frame *); - frm = (u_int8_t *)&wh[1]; - efrm = mtod(m0, u_int8_t *) + m0->m_len; - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_ACTION: - case IEEE80211_FC0_SUBTYPE_ACTION_NOACK: - if (ni == vap->iv_bss) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "unknown node"); - vap->iv_stats.is_rx_mgtdiscard++; - } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1)) { - /* NB: not interested in multicast frames. */ - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not for us"); - vap->iv_stats.is_rx_mgtdiscard++; - } else if (vap->iv_state != IEEE80211_S_RUN) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "wrong state %s", - ieee80211_state_name[vap->iv_state]); - vap->iv_stats.is_rx_mgtdiscard++; - } else { - if (ieee80211_parse_action(ni, m0) == 0) - (void)ic->ic_recv_action(ni, wh, frm, efrm); - } - break; - - case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - case IEEE80211_FC0_SUBTYPE_BEACON: - case IEEE80211_FC0_SUBTYPE_ATIM: - case IEEE80211_FC0_SUBTYPE_DISASSOC: - case IEEE80211_FC0_SUBTYPE_AUTH: - case IEEE80211_FC0_SUBTYPE_DEAUTH: - IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not handled"); - vap->iv_stats.is_rx_mgtdiscard++; - break; - - default: - IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "mgt", "subtype 0x%x not handled", subtype); - vap->iv_stats.is_rx_badsubtype++; - break; - } -} diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_wds.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_wds.h deleted file mode 100644 index 35a7bd322f..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_wds.h +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _FBSD_COMPAT_NET80211_IEEE80211_WDS_H_ -#define _FBSD_COMPAT_NET80211_IEEE80211_WDS_H_ - -/* - * WDS implementation definitions. - */ -void ieee80211_wds_attach(struct ieee80211com *); -void ieee80211_wds_detach(struct ieee80211com *); - -void ieee80211_dwds_mcast(struct ieee80211vap *, struct mbuf *); -void ieee80211_dwds_discover(struct ieee80211_node *, struct mbuf *); -int ieee80211_node_wdsq_age(struct ieee80211_node *); -#endif /* _FBSD_COMPAT_NET80211_IEEE80211_WDS_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_xauth.c b/src/libs/compat/freebsd_wlan/net80211/ieee80211_xauth.c deleted file mode 100644 index 2341ffb162..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_xauth.c +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * Copyright (c) 2004 Video54 Technologies, Inc. - * Copyright (c) 2004-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * External authenticator placeholder module. - * - * This support is optional; it is only used when the 802.11 layer's - * authentication mode is set to use 802.1x or WPA is enabled separately - * (for WPA-PSK). If compiled as a module this code does not need - * to be present unless 802.1x/WPA is in use. - * - * The authenticator hooks into the 802.11 layer. At present we use none - * of the available callbacks--the user mode authenticator process works - * entirely from messages about stations joining and leaving. - */ -#include "opt_wlan.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include - -/* XXX number of references from net80211 layer; needed for module code */ -static int nrefs = 0; - -/* - * One module handles everything for now. May want - * to split things up for embedded applications. - */ -static const struct ieee80211_authenticator xauth = { - .ia_name = "external", - .ia_attach = NULL, - .ia_detach = NULL, - .ia_node_join = NULL, - .ia_node_leave = NULL, -}; - -IEEE80211_AUTH_MODULE(xauth, 1); -IEEE80211_AUTH_ALG(x8021x, IEEE80211_AUTH_8021X, xauth); -IEEE80211_AUTH_ALG(wpa, IEEE80211_AUTH_WPA, xauth); diff --git a/src/libs/compat/freebsd_wlan/net80211/opt_inet.h b/src/libs/compat/freebsd_wlan/net80211/opt_inet.h deleted file mode 100644 index 16007efdfa..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/opt_inet.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _FBSD_COMPAT_NET80211_OPT_INET_H_ -#define _FBSD_COMPAT_NET80211_OPT_INET_H_ - -#define INET 1 - -#endif /* _FBSD_COMPAT_NET80211_OPT_INET_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/opt_inet6.h b/src/libs/compat/freebsd_wlan/net80211/opt_inet6.h deleted file mode 100644 index 6ae7676ed4..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/opt_inet6.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _FBSD_COMPAT_NET80211_OPT_INET6_H_ -#define _FBSD_COMPAT_NET80211_OPT_INET6_H_ - -//#define INET6 1 - -#endif /* _FBSD_COMPAT_NET80211_OPT_INET6_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/opt_ipx.h b/src/libs/compat/freebsd_wlan/net80211/opt_ipx.h deleted file mode 100644 index f54c7169a6..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/opt_ipx.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _FBSD_COMPAT_NET80211_OPT_IPX_H_ -#define _FBSD_COMPAT_NET80211_OPT_IPX_H_ - -//define IPX 1 - -#endif /* _FBSD_COMPAT_NET80211_OPT_IPX_H_ */ diff --git a/src/libs/compat/freebsd_wlan/net80211/opt_wlan.h b/src/libs/compat/freebsd_wlan/net80211/opt_wlan.h deleted file mode 100644 index accc87e7b2..0000000000 --- a/src/libs/compat/freebsd_wlan/net80211/opt_wlan.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _FBSD_COMPAT_NET80211_OPT_WLAN_H_ -#define _FBSD_COMPAT_NET80211_OPT_WLAN_H_ - -#define IEEE80211_DEBUG 1 -//#define IEEE80211_AMDPU_AGE 1 -//#define IEEE80211_SUPPORT_MESH 1 - -#endif /* _FBSD_COMPAT_NET80211_OPT_WLAN_H_ */