head 1.21; access; symbols netbsd-10-0-RELEASE:1.21 netbsd-10-0-RC6:1.21 netbsd-10-0-RC5:1.21 netbsd-10-0-RC4:1.21 netbsd-10-0-RC3:1.21 netbsd-10-0-RC2:1.21 thorpej-ifq:1.21.0.50 thorpej-ifq-base:1.21 thorpej-altq-separation:1.21.0.48 thorpej-altq-separation-base:1.21 netbsd-10-0-RC1:1.21 netbsd-10:1.21.0.46 netbsd-10-base:1.21 bouyer-sunxi-drm:1.21.0.44 bouyer-sunxi-drm-base:1.21 netbsd-9-3-RELEASE:1.21 thorpej-i2c-spi-conf2:1.21.0.42 thorpej-i2c-spi-conf2-base:1.21 thorpej-futex2:1.21.0.40 thorpej-futex2-base:1.21 thorpej-cfargs2:1.21.0.38 thorpej-cfargs2-base:1.21 cjep_sun2x-base1:1.21 cjep_sun2x:1.21.0.36 cjep_sun2x-base:1.21 cjep_staticlib_x-base1:1.21 netbsd-9-2-RELEASE:1.21 cjep_staticlib_x:1.21.0.34 cjep_staticlib_x-base:1.21 thorpej-i2c-spi-conf:1.21.0.32 thorpej-i2c-spi-conf-base:1.21 thorpej-cfargs:1.21.0.30 thorpej-cfargs-base:1.21 thorpej-futex:1.21.0.28 thorpej-futex-base:1.21 netbsd-9-1-RELEASE:1.21 bouyer-xenpvh-base2:1.21 phil-wifi-20200421:1.21 bouyer-xenpvh-base1:1.21 phil-wifi-20200411:1.21 bouyer-xenpvh:1.21.0.26 bouyer-xenpvh-base:1.21 is-mlppp:1.21.0.24 is-mlppp-base:1.21 phil-wifi-20200406:1.21 netbsd-8-2-RELEASE:1.21 ad-namecache-base3:1.21 netbsd-9-0-RELEASE:1.21 netbsd-9-0-RC2:1.21 ad-namecache-base2:1.21 ad-namecache-base1:1.21 ad-namecache:1.21.0.22 ad-namecache-base:1.21 netbsd-9-0-RC1:1.21 phil-wifi-20191119:1.21 netbsd-9:1.21.0.20 netbsd-9-base:1.21 phil-wifi-20190609:1.21 netbsd-8-1-RELEASE:1.21 netbsd-8-1-RC1:1.21 isaki-audio2:1.21.0.18 isaki-audio2-base:1.21 pgoyette-compat-merge-20190127:1.21 pgoyette-compat-20190127:1.21 pgoyette-compat-20190118:1.21 pgoyette-compat-1226:1.21 pgoyette-compat-1126:1.21 pgoyette-compat-1020:1.21 pgoyette-compat-0930:1.21 pgoyette-compat-0906:1.21 netbsd-7-2-RELEASE:1.19 pgoyette-compat-0728:1.21 netbsd-8-0-RELEASE:1.21 phil-wifi-freebsd-base:1.21.16.1 phil-wifi:1.21.0.16 phil-wifi-base:1.21 pgoyette-compat-0625:1.21 netbsd-8-0-RC2:1.21 pgoyette-compat-0521:1.21 pgoyette-compat-0502:1.21 pgoyette-compat-0422:1.21 netbsd-8-0-RC1:1.21 pgoyette-compat-0415:1.21 pgoyette-compat-0407:1.21 pgoyette-compat-0330:1.21 pgoyette-compat-0322:1.21 pgoyette-compat-0315:1.21 netbsd-7-1-2-RELEASE:1.19 pgoyette-compat:1.21.0.14 pgoyette-compat-base:1.21 netbsd-7-1-1-RELEASE:1.19 tls-maxphys-base-20171202:1.21 matt-nb8-mediatek:1.21.0.12 matt-nb8-mediatek-base:1.21 nick-nhusb-base-20170825:1.21 perseant-stdc-iso10646:1.21.0.10 perseant-stdc-iso10646-base:1.21 netbsd-8:1.21.0.8 netbsd-8-base:1.21 prg-localcount2-base3:1.21 prg-localcount2-base2:1.21 prg-localcount2-base1:1.21 prg-localcount2:1.21.0.6 prg-localcount2-base:1.21 pgoyette-localcount-20170426:1.21 bouyer-socketcan-base1:1.21 jdolecek-ncq:1.21.0.4 jdolecek-ncq-base:1.21 pgoyette-localcount-20170320:1.21 netbsd-7-1:1.19.0.10 netbsd-7-1-RELEASE:1.19 netbsd-7-1-RC2:1.19 nick-nhusb-base-20170204:1.21 netbsd-7-nhusb-base-20170116:1.19 bouyer-socketcan:1.21.0.2 bouyer-socketcan-base:1.21 pgoyette-localcount-20170107:1.21 netbsd-7-1-RC1:1.19 nick-nhusb-base-20161204:1.21 pgoyette-localcount-20161104:1.21 netbsd-7-0-2-RELEASE:1.19 nick-nhusb-base-20161004:1.21 localcount-20160914:1.20 netbsd-7-nhusb:1.19.0.8 netbsd-7-nhusb-base:1.19 pgoyette-localcount-20160806:1.20 pgoyette-localcount-20160726:1.20 pgoyette-localcount:1.20.0.2 pgoyette-localcount-base:1.20 nick-nhusb-base-20160907:1.20 nick-nhusb-base-20160529:1.19 netbsd-7-0-1-RELEASE:1.19 nick-nhusb-base-20160422:1.19 nick-nhusb-base-20160319:1.19 nick-nhusb-base-20151226:1.19 netbsd-7-0:1.19.0.6 netbsd-7-0-RELEASE:1.19 nick-nhusb-base-20150921:1.19 netbsd-7-0-RC3:1.19 netbsd-7-0-RC2:1.19 netbsd-7-0-RC1:1.19 nick-nhusb-base-20150606:1.19 nick-nhusb-base-20150406:1.19 nick-nhusb:1.19.0.4 nick-nhusb-base:1.19 netbsd-5-2-3-RELEASE:1.15 netbsd-5-1-5-RELEASE:1.15 netbsd-6-0-6-RELEASE:1.17 netbsd-6-1-5-RELEASE:1.17 netbsd-7:1.19.0.2 netbsd-7-base:1.19 yamt-pagecache-base9:1.19 yamt-pagecache-tag8:1.17 netbsd-6-1-4-RELEASE:1.17 netbsd-6-0-5-RELEASE:1.17 tls-earlyentropy:1.18.0.2 tls-earlyentropy-base:1.19 riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.18 riastradh-drm2-base3:1.18 netbsd-6-1-3-RELEASE:1.17 netbsd-6-0-4-RELEASE:1.17 netbsd-5-2-2-RELEASE:1.15 netbsd-5-1-4-RELEASE:1.15 netbsd-6-1-2-RELEASE:1.17 netbsd-6-0-3-RELEASE:1.17 netbsd-5-2-1-RELEASE:1.15 netbsd-5-1-3-RELEASE:1.15 rmind-smpnet-nbase:1.19 netbsd-6-1-1-RELEASE:1.17 riastradh-drm2-base2:1.17 riastradh-drm2-base1:1.17 riastradh-drm2:1.17.0.34 riastradh-drm2-base:1.17 rmind-smpnet:1.17.0.26 rmind-smpnet-base:1.19 netbsd-6-1:1.17.0.32 netbsd-6-0-2-RELEASE:1.17 netbsd-6-1-RELEASE:1.17 khorben-n900:1.17.0.30 netbsd-6-1-RC4:1.17 netbsd-6-1-RC3:1.17 agc-symver:1.17.0.28 agc-symver-base:1.17 netbsd-6-1-RC2:1.17 netbsd-6-1-RC1:1.17 yamt-pagecache-base8:1.17 netbsd-5-2:1.15.0.16 netbsd-6-0-1-RELEASE:1.17 yamt-pagecache-base7:1.17 netbsd-5-2-RELEASE:1.15 netbsd-5-2-RC1:1.15 matt-nb6-plus-nbase:1.17 yamt-pagecache-base6:1.17 netbsd-6-0:1.17.0.24 netbsd-6-0-RELEASE:1.17 netbsd-6-0-RC2:1.17 tls-maxphys:1.17.0.22 tls-maxphys-base:1.19 matt-nb6-plus:1.17.0.20 matt-nb6-plus-base:1.17 netbsd-6-0-RC1:1.17 jmcneill-usbmp-base10:1.17 yamt-pagecache-base5:1.17 jmcneill-usbmp-base9:1.17 yamt-pagecache-base4:1.17 jmcneill-usbmp-base8:1.17 jmcneill-usbmp-base7:1.17 jmcneill-usbmp-base6:1.17 jmcneill-usbmp-base5:1.17 jmcneill-usbmp-base4:1.17 jmcneill-usbmp-base3:1.17 jmcneill-usbmp-pre-base2:1.17 jmcneill-usbmp-base2:1.17 netbsd-6:1.17.0.18 netbsd-6-base:1.17 netbsd-5-1-2-RELEASE:1.15 netbsd-5-1-1-RELEASE:1.15 jmcneill-usbmp:1.17.0.16 jmcneill-usbmp-base:1.17 jmcneill-audiomp3:1.17.0.14 jmcneill-audiomp3-base:1.17 yamt-pagecache-base3:1.17 yamt-pagecache-base2:1.17 yamt-pagecache:1.17.0.12 yamt-pagecache-base:1.17 rmind-uvmplock-nbase:1.17 cherry-xenmp:1.17.0.10 cherry-xenmp-base:1.17 bouyer-quota2-nbase:1.17 bouyer-quota2:1.17.0.8 bouyer-quota2-base:1.17 jruoho-x86intr:1.17.0.6 jruoho-x86intr-base:1.17 matt-mips64-premerge-20101231:1.17 matt-nb5-mips64-premerge-20101231:1.15 matt-nb5-pq3:1.15.0.14 matt-nb5-pq3-base:1.15 netbsd-5-1:1.15.0.12 netbsd-5-1-RELEASE:1.15 uebayasi-xip-base4:1.17 uebayasi-xip-base3:1.17 yamt-nfs-mp-base11:1.17 netbsd-5-1-RC4:1.15 matt-nb5-mips64-k15:1.15 uebayasi-xip-base2:1.17 yamt-nfs-mp-base10:1.17 netbsd-5-1-RC3:1.15 netbsd-5-1-RC2:1.15 uebayasi-xip-base1:1.17 netbsd-5-1-RC1:1.15 rmind-uvmplock:1.17.0.4 rmind-uvmplock-base:1.17 yamt-nfs-mp-base9:1.17 uebayasi-xip:1.17.0.2 uebayasi-xip-base:1.17 netbsd-5-0-2-RELEASE:1.15 matt-nb5-mips64-premerge-20091211:1.15 matt-premerge-20091211:1.17 yamt-nfs-mp-base8:1.16 matt-nb5-mips64-u2-k2-k4-k7-k8-k9:1.15 matt-nb4-mips64-k7-u2a-k9b:1.15 matt-nb5-mips64-u1-k1-k5:1.15 yamt-nfs-mp-base7:1.16 matt-nb5-mips64:1.15.0.10 netbsd-5-0-1-RELEASE:1.15 jymxensuspend-base:1.16 yamt-nfs-mp-base6:1.16 yamt-nfs-mp-base5:1.16 yamt-nfs-mp-base4:1.16 jym-xensuspend-nbase:1.17 yamt-nfs-mp-base3:1.16 nick-hppapmap-base4:1.16 nick-hppapmap-base3:1.16 netbsd-5-0:1.15.0.8 netbsd-5-0-RELEASE:1.15 netbsd-5-0-RC4:1.15 netbsd-5-0-RC3:1.15 nick-hppapmap-base2:1.16 netbsd-5-0-RC2:1.15 jym-xensuspend:1.16.0.4 jym-xensuspend-base:1.16 netbsd-5-0-RC1:1.15 haad-dm-base2:1.16 haad-nbase2:1.16 ad-audiomp2:1.16.0.2 ad-audiomp2-base:1.16 netbsd-5:1.15.0.6 netbsd-5-base:1.15 nick-hppapmap:1.15.0.4 nick-hppapmap-base:1.16 matt-mips64-base2:1.15 matt-mips64:1.14.0.62 haad-dm-base1:1.15 wrstuden-revivesa-base-4:1.15 netbsd-4-0-1-RELEASE:1.14 wrstuden-revivesa-base-3:1.15 wrstuden-revivesa-base-2:1.15 wrstuden-fixsa-newbase:1.14 nick-csl-alignment-base5:1.14 haad-dm:1.15.0.2 haad-dm-base:1.16 wrstuden-revivesa-base-1:1.14 simonb-wapbl-nbase:1.15 yamt-pf42-base4:1.14 simonb-wapbl:1.14.0.60 simonb-wapbl-base:1.15 yamt-pf42-base3:1.14 hpcarm-cleanup-nbase:1.14 yamt-pf42-baseX:1.14 yamt-pf42-base2:1.14 yamt-nfs-mp-base2:1.14 wrstuden-revivesa:1.14.0.58 wrstuden-revivesa-base:1.14 yamt-nfs-mp:1.14.0.56 yamt-nfs-mp-base:1.14 yamt-pf42:1.14.0.54 yamt-pf42-base:1.14 ad-socklock-base1:1.14 yamt-lazymbuf-base15:1.14 yamt-lazymbuf-base14:1.14 keiichi-mipv6-nbase:1.14 mjf-devfs2:1.14.0.52 mjf-devfs2-base:1.16 nick-net80211-sync:1.14.0.50 nick-net80211-sync-base:1.14 keiichi-mipv6:1.14.0.48 keiichi-mipv6-base:1.14 bouyer-xeni386-merge1:1.14 matt-armv6-prevmlocking:1.14 wrstuden-fixsa-base-1:1.14 vmlocking2-base3:1.14 netbsd-4-0:1.14.0.46 netbsd-4-0-RELEASE:1.14 bouyer-xeni386-nbase:1.14 yamt-kmem-base3:1.14 cube-autoconf:1.14.0.44 cube-autoconf-base:1.14 yamt-kmem-base2:1.14 bouyer-xeni386:1.14.0.42 bouyer-xeni386-base:1.14 yamt-kmem:1.14.0.40 yamt-kmem-base:1.14 vmlocking2-base2:1.14 reinoud-bufcleanup-nbase:1.14 vmlocking2:1.14.0.38 vmlocking2-base1:1.14 netbsd-4-0-RC5:1.14 matt-nb4-arm:1.14.0.36 matt-nb4-arm-base:1.14 matt-armv6-nbase:1.14 jmcneill-base:1.14 netbsd-4-0-RC4:1.14 mjf-devfs:1.14.0.34 mjf-devfs-base:1.14 bouyer-xenamd64-base2:1.14 vmlocking-nbase:1.14 yamt-x86pmap-base4:1.14 bouyer-xenamd64:1.14.0.32 bouyer-xenamd64-base:1.14 netbsd-4-0-RC3:1.14 yamt-x86pmap-base3:1.14 yamt-x86pmap-base2:1.14 netbsd-4-0-RC2:1.14 yamt-x86pmap:1.14.0.30 yamt-x86pmap-base:1.14 netbsd-4-0-RC1:1.14 matt-armv6:1.14.0.28 matt-armv6-base:1.14 matt-mips64-base:1.14 jmcneill-pm:1.14.0.26 jmcneill-pm-base:1.14 hpcarm-cleanup:1.14.0.24 hpcarm-cleanup-base:1.14 nick-csl-alignment:1.14.0.22 nick-csl-alignment-base:1.14 netbsd-3-1-1-RELEASE:1.9 netbsd-3-0-3-RELEASE:1.9 yamt-idlelwp-base8:1.14 wrstuden-fixsa:1.14.0.20 wrstuden-fixsa-base:1.14 thorpej-atomic:1.14.0.18 thorpej-atomic-base:1.14 reinoud-bufcleanup:1.14.0.16 reinoud-bufcleanup-base:1.14 mjf-ufs-trans:1.14.0.14 mjf-ufs-trans-base:1.14 vmlocking:1.14.0.12 vmlocking-base:1.14 ad-audiomp:1.14.0.10 ad-audiomp-base:1.14 yamt-idlelwp:1.14.0.8 post-newlock2-merge:1.14 newlock2-nbase:1.14 yamt-splraiseipl-base5:1.14 yamt-splraiseipl-base4:1.14 yamt-splraiseipl-base3:1.14 abandoned-netbsd-4-base:1.13 abandoned-netbsd-4:1.13.0.18 netbsd-3-1:1.9.0.6 netbsd-3-1-RELEASE:1.9 netbsd-3-0-2-RELEASE:1.9 yamt-splraiseipl-base2:1.14 netbsd-3-1-RC4:1.9 yamt-splraiseipl:1.14.0.4 yamt-splraiseipl-base:1.14 netbsd-3-1-RC3:1.9 yamt-pdpolicy-base9:1.14 newlock2:1.14.0.2 newlock2-base:1.14 yamt-pdpolicy-base8:1.14 netbsd-3-1-RC2:1.9 netbsd-3-1-RC1:1.9 yamt-pdpolicy-base7:1.13 netbsd-4:1.14.0.6 netbsd-4-base:1.14 yamt-pdpolicy-base6:1.13 chap-midi-nbase:1.13 netbsd-3-0-1-RELEASE:1.9 gdamore-uart:1.13.0.16 gdamore-uart-base:1.13 simonb-timcounters-final:1.13 yamt-pdpolicy-base5:1.13 chap-midi:1.13.0.14 chap-midi-base:1.13 yamt-pdpolicy-base4:1.13 yamt-pdpolicy-base3:1.13 peter-altq-base:1.13 peter-altq:1.13.0.12 yamt-pdpolicy-base2:1.13 elad-kernelauth-base:1.13 elad-kernelauth:1.13.0.10 yamt-pdpolicy:1.13.0.8 yamt-pdpolicy-base:1.13 yamt-uio_vmspace-base5:1.13 simonb-timecounters:1.13.0.6 simonb-timecounters-base:1.13 rpaulo-netinet-merge-pcb:1.13.0.4 rpaulo-netinet-merge-pcb-base:1.14 yamt-uio_vmspace:1.13.0.2 netbsd-3-0:1.9.0.4 netbsd-3-0-RELEASE:1.9 netbsd-3-0-RC6:1.9 yamt-readahead-base3:1.12 netbsd-3-0-RC5:1.9 netbsd-3-0-RC4:1.9 netbsd-3-0-RC3:1.9 yamt-readahead-base2:1.12 netbsd-3-0-RC2:1.9 yamt-readahead-pervnode:1.12 yamt-readahead-perfile:1.12 yamt-readahead:1.12.0.6 yamt-readahead-base:1.12 netbsd-3-0-RC1:1.9 yamt-vop-base3:1.12 netbsd-2-0-3-RELEASE:1.3 netbsd-2-1:1.3.0.6 yamt-vop-base2:1.12 thorpej-vnode-attr:1.12.0.4 thorpej-vnode-attr-base:1.12 netbsd-2-1-RELEASE:1.3 yamt-vop:1.12.0.2 yamt-vop-base:1.12 netbsd-2-1-RC6:1.3 netbsd-2-1-RC5:1.3 netbsd-2-1-RC4:1.3 netbsd-2-1-RC3:1.3 netbsd-2-1-RC2:1.3 netbsd-2-1-RC1:1.3 yamt-lazymbuf:1.11.0.2 yamt-km-base4:1.9 netbsd-2-0-2-RELEASE:1.3 yamt-km-base3:1.9 netbsd-3:1.9.0.2 netbsd-3-base:1.9 yamt-km-base2:1.8 yamt-km:1.8.0.8 yamt-km-base:1.8 kent-audio2:1.8.0.6 kent-audio2-base:1.9 netbsd-2-0-1-RELEASE:1.3 kent-audio1-beforemerge:1.8 netbsd-2:1.3.0.4 netbsd-2-base:1.3 kent-audio1:1.8.0.4 kent-audio1-base:1.8 netbsd-2-0-RELEASE:1.3 netbsd-2-0-RC5:1.3 netbsd-2-0-RC4:1.3 netbsd-2-0-RC3:1.3 netbsd-2-0-RC2:1.3 netbsd-2-0-RC1:1.3 ktrace-lwp-base:1.12 ktrace-lwp:1.8.0.2 netbsd-2-0:1.3.0.2 netbsd-2-0-base:1.3; locks; strict; comment @ * @; 1.21 date 2016.09.27.20.20.06; author christos; state Exp; branches 1.21.16.1; next 1.20; 1.20 date 2016.07.07.06.55.43; author msaitoh; state Exp; branches 1.20.2.1; next 1.19; 1.19 date 2014.04.07.00.07.40; author pooka; state Exp; branches 1.19.4.1; next 1.18; 1.18 date 2014.02.25.18.30.12; author pooka; state Exp; branches 1.18.2.1; next 1.17; 1.17 date 2009.10.19.23.19.39; author rmind; state Exp; branches 1.17.12.1 1.17.22.1 1.17.26.1; next 1.16; 1.16 date 2008.11.12.12.36.28; author ad; state Exp; branches; next 1.15; 1.15 date 2008.06.24.10.33.46; author gmcgarry; state Exp; branches 1.15.2.1 1.15.4.1; next 1.14; 1.14 date 2006.08.30.15.40.41; author christos; state Exp; branches 1.14.50.1 1.14.52.1 1.14.56.1 1.14.58.1 1.14.60.1; next 1.13; 1.13 date 2005.12.11.12.24.54; author christos; state Exp; branches 1.13.4.1 1.13.8.1; next 1.12; 1.12 date 2005.07.26.22.52.48; author dyoung; state Exp; branches; next 1.11; 1.11 date 2005.06.22.06.16.02; author dyoung; state Exp; branches 1.11.2.1; next 1.10; 1.10 date 2005.06.20.02.49.18; author atatat; state Exp; branches; next 1.9; 1.9 date 2005.02.26.22.45.09; author perry; state Exp; branches; next 1.8; 1.8 date 2004.07.23.06.44.56; author mycroft; state Exp; branches 1.8.2.1 1.8.6.1 1.8.8.1; next 1.7; 1.7 date 2004.05.25.04.33.59; author atatat; state Exp; branches; next 1.6; 1.6 date 2004.05.06.07.11.40; author dyoung; state Exp; branches; next 1.5; 1.5 date 2004.05.06.03.03.20; author dyoung; state Exp; branches; next 1.4; 1.4 date 2004.03.29.04.09.45; author dyoung; state Exp; branches; next 1.3; 1.3 date 2004.03.17.17.00.34; author dyoung; state Exp; branches; next 1.2; 1.2 date 2003.12.07.05.29.39; author dyoung; state Exp; branches; next 1.1; 1.1 date 2003.10.26.07.56.41; author dyoung; state Exp; branches; next ; 1.21.16.1 date 2018.06.28.21.03.07; author phil; state Exp; branches; next 1.21.16.2; commitid fU5eenqZ23IoH5IA; 1.21.16.2 date 2018.07.12.16.35.34; author phil; state Exp; branches; next 1.21.16.3; commitid US0n8axK0fqSKRJA; 1.21.16.3 date 2018.07.16.20.11.11; author phil; state Exp; branches; next 1.21.16.4; commitid 57tT6pqTipGJQoKA; 1.21.16.4 date 2018.07.20.20.33.05; author phil; state Exp; branches; next 1.21.16.5; commitid aRnRKvjLmzAeQUKA; 1.21.16.5 date 2019.06.10.22.09.46; author christos; state Exp; branches; next ; commitid jtc8rnCzWiEEHGqB; 1.20.2.1 date 2016.11.04.14.49.21; author pgoyette; state Exp; branches; next ; 1.19.4.1 date 2016.07.09.20.25.21; author skrll; state Exp; branches; next 1.19.4.2; 1.19.4.2 date 2016.10.05.20.56.08; author skrll; state Exp; branches; next ; 1.18.2.1 date 2014.08.10.06.56.18; author tls; state Exp; branches; next ; 1.17.12.1 date 2014.05.22.11.41.09; author yamt; state Exp; branches; next ; 1.17.22.1 date 2014.08.20.00.04.35; author tls; state Exp; branches; next 1.17.22.2; 1.17.22.2 date 2017.12.03.11.39.03; author jdolecek; state Exp; branches; next ; commitid XcIYRZTAh1LmerhA; 1.17.26.1 date 2014.05.18.17.46.13; author rmind; state Exp; branches; next ; 1.15.2.1 date 2008.12.13.01.15.26; author haad; state Exp; branches; next ; 1.15.4.1 date 2009.01.19.13.20.13; author skrll; state Exp; branches; next ; 1.14.50.1 date 2008.02.22.16.50.26; author skrll; state Exp; branches; next ; 1.14.52.1 date 2008.06.29.09.33.19; author mjf; state Exp; branches; next 1.14.52.2; 1.14.52.2 date 2009.01.17.13.29.32; author mjf; state Exp; branches; next ; 1.14.56.1 date 2009.05.04.08.14.16; author yamt; state Exp; branches; next 1.14.56.2; 1.14.56.2 date 2010.03.11.15.04.28; author yamt; state Exp; branches; next ; 1.14.58.1 date 2008.09.18.04.37.00; author wrstuden; state Exp; branches; next ; 1.14.60.1 date 2008.06.27.15.11.48; author simonb; state Exp; branches; next ; 1.13.4.1 date 2006.09.09.02.58.25; author rpaulo; state Exp; branches; next ; 1.13.8.1 date 2006.09.03.15.25.36; author yamt; state Exp; branches; next ; 1.11.2.1 date 2006.12.30.20.50.28; author yamt; state Exp; branches; next ; 1.8.2.1 date 2004.07.23.06.44.56; author skrll; state dead; branches; next 1.8.2.2; 1.8.2.2 date 2004.08.03.10.54.21; author skrll; state Exp; branches; next 1.8.2.3; 1.8.2.3 date 2004.09.18.14.54.39; author skrll; state Exp; branches; next 1.8.2.4; 1.8.2.4 date 2004.09.21.13.36.55; author skrll; state Exp; branches; next 1.8.2.5; 1.8.2.5 date 2005.03.04.16.53.17; author skrll; state Exp; branches; next 1.8.2.6; 1.8.2.6 date 2005.11.10.14.10.51; author skrll; state Exp; branches; next ; 1.8.6.1 date 2005.04.29.11.29.32; author kent; state Exp; branches; next ; 1.8.8.1 date 2005.03.19.08.36.35; author yamt; state Exp; branches; next ; desc @@ 1.21 log @- use ether_snprintf() so that we don't overwrite our buffer for printing ethernet-like addresses - make this compile againw without IEEE80211_DEBUG. @ text @/* $NetBSD: ieee80211_rssadapt.c,v 1.20 2016/07/07 06:55:43 msaitoh 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. * * 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 #ifdef __NetBSD__ __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.20 2016/07/07 06:55:43 msaitoh Exp $"); #endif #include #include #include /* for hz */ #include #include #include #include #include #include #include #include #ifdef interpolate #undef interpolate #endif #define interpolate(parm, old, new) ((parm##_old * (old) + \ (parm##_denom - parm##_old) * (new)) / \ parm##_denom) #ifdef IEEE80211_DEBUG static struct timeval lastrateadapt; /* time of last rate adaptation msg */ static int currssadaptps = 0; /* rate-adaptation msgs this second */ static int ieee80211_adaptrate = 4; /* rate-adaptation max msgs/sec */ #define RSSADAPT_DO_PRINT() \ ((ieee80211_rssadapt_debug > 0) && \ ppsratecheck(&lastrateadapt, &currssadaptps, ieee80211_adaptrate)) #define RSSADAPT_PRINTF(X) \ if (RSSADAPT_DO_PRINT()) \ printf X int ieee80211_rssadapt_debug = 0; #else #define RSSADAPT_DO_PRINT() (0) #define RSSADAPT_PRINTF(X) #endif static struct ieee80211_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 __NetBSD__ #ifdef IEEE80211_DEBUG /* TBD factor with sysctl_ath_verify, sysctl_ieee80211_verify. */ static int sysctl_ieee80211_rssadapt_debug(SYSCTLFN_ARGS) { int error, t; struct sysctlnode node; node = *rnode; t = *(int*)rnode->sysctl_data; node.sysctl_data = &t; error = sysctl_lookup(SYSCTLFN_CALL(&node)); if (error || newp == NULL) return (error); if (t < 0 || t > 2) return (EINVAL); *(int*)rnode->sysctl_data = t; return (0); } #endif /* IEEE80211_DEBUG */ /* TBD factor with sysctl_ath_verify, sysctl_ieee80211_verify. */ static int sysctl_ieee80211_rssadapt_expavgctl(SYSCTLFN_ARGS) { struct ieee80211_rssadapt_expavgctl rc; int error; struct sysctlnode node; node = *rnode; rc = *(struct ieee80211_rssadapt_expavgctl *)rnode->sysctl_data; node.sysctl_data = &rc; error = sysctl_lookup(SYSCTLFN_CALL(&node)); if (error || newp == NULL) return (error); if (/* rc.rc_decay_old < 0 || */ rc.rc_decay_denom < rc.rc_decay_old) return (EINVAL); if (/* rc.rc_thresh_old < 0 || */ rc.rc_thresh_denom < rc.rc_thresh_old) return (EINVAL); if (/* rc.rc_avgrssi_old < 0 || */ rc.rc_avgrssi_denom < rc.rc_avgrssi_old) return (EINVAL); *(struct ieee80211_rssadapt_expavgctl *)rnode->sysctl_data = rc; return (0); } /* * Setup sysctl(3) MIB, net.ieee80211.* * * TBD condition CTLFLAG_PERMANENT on being a module or not */ void ieee80211_rssadapt_sysctl_setup(struct sysctllog **clog) { int rc; const struct sysctlnode *node; if ((rc = sysctl_createv(clog, 0, NULL, &node, CTLFLAG_PERMANENT, CTLTYPE_NODE, "link", NULL, NULL, 0, NULL, 0, CTL_NET, PF_LINK, CTL_EOL)) != 0) goto err; if ((rc = sysctl_createv(clog, 0, &node, &node, CTLFLAG_PERMANENT, CTLTYPE_NODE, "ieee80211", NULL, NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) goto err; if ((rc = sysctl_createv(clog, 0, &node, &node, CTLFLAG_PERMANENT, CTLTYPE_NODE, "rssadapt", SYSCTL_DESCR("Received Signal Strength adaptation controls"), NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) goto err; #ifdef IEEE80211_DEBUG /* control debugging printfs */ if ((rc = sysctl_createv(clog, 0, &node, NULL, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "debug", SYSCTL_DESCR("Enable RSS adaptation debugging output"), sysctl_ieee80211_rssadapt_debug, 0, &ieee80211_rssadapt_debug, 0, CTL_CREATE, CTL_EOL)) != 0) goto err; #endif /* IEEE80211_DEBUG */ /* control rate of decay for exponential averages */ if ((rc = sysctl_createv(clog, 0, &node, NULL, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_STRUCT, "expavgctl", SYSCTL_DESCR("RSS exponential averaging control"), sysctl_ieee80211_rssadapt_expavgctl, 0, &master_expavgctl, sizeof(master_expavgctl), CTL_CREATE, CTL_EOL)) != 0) goto err; return; err: printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); } #endif /* __NetBSD__ */ int ieee80211_rssadapt_choose(struct ieee80211_rssadapt *ra, struct ieee80211_rateset *rs, struct ieee80211_frame *wh, u_int len, int fixed_rate, const char *dvname, int do_not_adapt) { u_int16_t (*thrs)[IEEE80211_RATE_SIZE]; int flags = 0, i, rateidx = 0, thridx, top; if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) flags |= IEEE80211_RATE_BASIC; for (i = 0, top = IEEE80211_RSSADAPT_BKT0; i < IEEE80211_RSSADAPT_BKTS; i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) { thridx = i; if (len <= top) break; } thrs = &ra->ra_rate_thresh[thridx]; if (fixed_rate != -1) { if ((rs->rs_rates[fixed_rate] & flags) == flags) { rateidx = fixed_rate; goto out; } flags |= IEEE80211_RATE_BASIC; i = fixed_rate; } else i = rs->rs_nrates; while (--i >= 0) { rateidx = i; if ((rs->rs_rates[i] & flags) != flags) continue; if (do_not_adapt) break; if ((*thrs)[i] < ra->ra_avg_rssi) break; } out: #ifdef IEEE80211_DEBUG if (ieee80211_rssadapt_debug && dvname != NULL) { printf("%s: dst %s threshold[%d, %d.%d] %d < %d\n", dvname, ether_sprintf(wh->i_addr1), len, (rs->rs_rates[rateidx] & IEEE80211_RATE_VAL) / 2, (rs->rs_rates[rateidx] & IEEE80211_RATE_VAL) * 5 % 10, (*thrs)[rateidx], ra->ra_avg_rssi); } #endif /* IEEE80211_DEBUG */ return rateidx; } void ieee80211_rssadapt_updatestats(struct ieee80211_rssadapt *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(100000, 10000000 / MAX(1, 10 * ra->ra_pktrate)); ra->ra_raise_interval.tv_sec = interval / (1000 * 1000); ra->ra_raise_interval.tv_usec = interval % (1000 * 1000); } void ieee80211_rssadapt_input(struct ieee80211com *ic, struct ieee80211_node *ni, struct ieee80211_rssadapt *ra, int rssi) { #ifdef IEEE80211_DEBUG int last_avg_rssi = ra->ra_avg_rssi; #endif ra->ra_avg_rssi = interpolate(master_expavgctl.rc_avgrssi, ra->ra_avg_rssi, (rssi << 8)); RSSADAPT_PRINTF(("%s: src %s rssi %d avg %d -> %d\n", ic->ic_ifp->if_xname, ether_sprintf(ni->ni_macaddr), rssi, last_avg_rssi, ra->ra_avg_rssi)); } /* * Adapt the data rate to suit the conditions. When a transmitted * packet is dropped after IEEE80211_RSSADAPT_RETRY_LIMIT retransmissions, * raise the RSS threshold for transmitting packets of similar length at * the same data rate. */ void ieee80211_rssadapt_lower_rate(struct ieee80211com *ic, struct ieee80211_node *ni, struct ieee80211_rssadapt *ra, struct ieee80211_rssdesc *id) { struct ieee80211_rateset *rs = &ni->ni_rates; u_int16_t last_thr; u_int i, thridx, top; ra->ra_nfail++; if (id->id_rateidx >= rs->rs_nrates) { RSSADAPT_PRINTF(("ieee80211_rssadapt_lower_rate: " "%s rate #%d > #%d out of bounds\n", ether_sprintf(ni->ni_macaddr), id->id_rateidx, rs->rs_nrates - 1)); return; } for (i = 0, top = IEEE80211_RSSADAPT_BKT0; i < IEEE80211_RSSADAPT_BKTS; i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) { thridx = i; if (id->id_len <= top) break; } last_thr = ra->ra_rate_thresh[thridx][id->id_rateidx]; ra->ra_rate_thresh[thridx][id->id_rateidx] = interpolate(master_expavgctl.rc_thresh, last_thr, (id->id_rssi << 8)); RSSADAPT_PRINTF(("%s: dst %s rssi %d threshold[%d, %d.%d] %d -> %d\n", ic->ic_ifp->if_xname, ether_sprintf(ni->ni_macaddr), id->id_rssi, id->id_len, (rs->rs_rates[id->id_rateidx] & IEEE80211_RATE_VAL) / 2, (rs->rs_rates[id->id_rateidx] & IEEE80211_RATE_VAL) * 5 % 10, last_thr, ra->ra_rate_thresh[thridx][id->id_rateidx])); } void ieee80211_rssadapt_raise_rate(struct ieee80211com *ic, struct ieee80211_rssadapt *ra, struct ieee80211_rssdesc *id) { u_int16_t (*thrs)[IEEE80211_RATE_SIZE], newthr, oldthr; struct ieee80211_node *ni = id->id_node; struct ieee80211_rateset *rs = &ni->ni_rates; int i, rate, top; #ifdef IEEE80211_DEBUG int j; #endif ra->ra_nok++; if (!ratecheck(&ra->ra_last_raise, &ra->ra_raise_interval)) return; for (i = 0, top = IEEE80211_RSSADAPT_BKT0; i < IEEE80211_RSSADAPT_BKTS; i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) { thrs = &ra->ra_rate_thresh[i]; if (id->id_len <= top) break; } if (id->id_rateidx + 1 < rs->rs_nrates && (*thrs)[id->id_rateidx + 1] > (*thrs)[id->id_rateidx]) { rate = (rs->rs_rates[id->id_rateidx + 1] & IEEE80211_RATE_VAL); __USE(rate); RSSADAPT_PRINTF(("%s: threshold[%d, %d.%d] decay %d ", ic->ic_ifp->if_xname, IEEE80211_RSSADAPT_BKT0 << (IEEE80211_RSSADAPT_BKTPOWER* i), rate / 2, rate * 5 % 10, (*thrs)[id->id_rateidx + 1])); oldthr = (*thrs)[id->id_rateidx + 1]; if ((*thrs)[id->id_rateidx] == 0) newthr = ra->ra_avg_rssi; else newthr = (*thrs)[id->id_rateidx]; (*thrs)[id->id_rateidx + 1] = interpolate(master_expavgctl.rc_decay, oldthr, newthr); RSSADAPT_PRINTF(("-> %d\n", (*thrs)[id->id_rateidx + 1])); } #ifdef IEEE80211_DEBUG if (RSSADAPT_DO_PRINT()) { printf("%s: dst %s thresholds\n", ic->ic_ifp->if_xname, ether_sprintf(ni->ni_macaddr)); for (i = 0; i < IEEE80211_RSSADAPT_BKTS; i++) { printf("%d-byte", IEEE80211_RSSADAPT_BKT0 << (IEEE80211_RSSADAPT_BKTPOWER * i)); for (j = 0; j < rs->rs_nrates; j++) { rate = (rs->rs_rates[j] & IEEE80211_RATE_VAL); printf(", T[%d.%d] = %d", rate / 2, rate * 5 % 10, ra->ra_rate_thresh[i][j]); } printf("\n"); } } #endif /* IEEE80211_DEBUG */ } @ 1.21.16.1 log @Start of WiFi refresh. Copy of FreeBSD net80211 directory with git mirror commit id of 09e3123164ec345822e00465039503686efde455, no changes yet. ieee80211_netbsd.[ch] from ieee80211_freebsd.[ch]. @ text @d1 1 a1 2 /* $FreeBSD$ */ /* $NetBSD: ieee80211_rssadapt.c,v 1.9 2005/02/26 22:45:09 perry Exp $ */ a2 3 * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 2010 Rui Paulo a13 3 * 3. The name of David Young may not be used to endorse or promote * products derived from this software without specific prior * written permission. d28 5 a32 1 #include "opt_wlan.h" d35 2 a36 5 #include #include #include #include #include a39 1 #include d41 1 a41 1 #include d43 1 d45 1 a46 1 #include d48 25 a72 11 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; }; d74 1 a74 1 static struct rssadapt_expavgctl master_expavgctl = { d83 8 a90 6 #ifdef interpolate #undef interpolate #endif #define interpolate(parm, old, new) ((parm##_old * (old) + \ (parm##_denom - parm##_old) * (new)) / \ parm##_denom) d92 6 a97 33 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 ieee80211_node *, const struct ieee80211_ratectl_tx_status *); 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); d99 3 a101 5 static void rssadapt_setinterval(const struct ieee80211vap *vap, int msecs) { struct ieee80211_rssadapt *rs = vap->iv_rs; int t; d103 1 a103 4 if (msecs < 100) msecs = 100; t = msecs_to_ticks(msecs); rs->interval = (t < 1) ? 1 : t; d105 1 d107 3 a109 2 static void rssadapt_init(struct ieee80211vap *vap) d111 22 a132 1 struct ieee80211_rssadapt *rs; d134 1 a134 2 KASSERT(vap->iv_rs == NULL, ("%s: iv_rs already initialized", __func__)); d136 1 a136 10 nrefs++; /* XXX locking */ vap->iv_rs = rs = IEEE80211_MALLOC(sizeof(struct ieee80211_rssadapt), M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_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); d139 7 a145 2 static void rssadapt_deinit(struct ieee80211vap *vap) d147 2 a148 4 IEEE80211_FREE(vap->iv_rs, M_80211_RATECTL); KASSERT(nrefs > 0, ("imbalanced attach/detach")); nrefs--; /* XXX locking */ } d150 45 a194 2 static void rssadapt_updatestats(struct ieee80211_rssadapt_node *ra) d196 5 a200 1 long interval; d202 7 a208 2 ra->ra_pktrate = (ra->ra_pktrate + 10*(ra->ra_nfail + ra->ra_nok))/2; ra->ra_nfail = ra->ra_nok = 0; d210 1 a210 7 /* * 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); } d212 4 a215 16 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 = IEEE80211_MALLOC(sizeof(struct ieee80211_rssadapt_node), M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO); if (ra == NULL) { if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl " "structure\n"); return; d217 2 d220 1 a220 12 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; d222 21 a242 2 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, "RSSADAPT initial rate %d", ni->ni_txrate); d245 2 a246 2 static void rssadapt_node_deinit(struct ieee80211_node *ni) d248 1 d250 3 a252 2 IEEE80211_FREE(ni->ni_rctls, M_80211_RATECTL); } d254 6 a259 13 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; d262 3 a264 2 static int rssadapt_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg) d266 3 a268 10 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; } d270 2 a271 1 thrs = &ra->ra_rate_thresh[bucket(pktlen)]; d273 3 a275 15 /* 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; d280 1 a280 1 * packet is dropped after RAL_RSSADAPT_RETRY_LIMIT retransmissions, d284 18 a301 19 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); } d303 7 a309 23 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); d311 24 a334 3 ra->ra_last_raise = ticks; } } d336 1 a336 6 static void rssadapt_tx_complete(const struct ieee80211_node *ni, const struct ieee80211_ratectl_tx_status *status) { struct ieee80211_rssadapt_node *ra = ni->ni_rctls; int pktlen, rssi; d338 1 a338 3 if ((status->flags & (IEEE80211_RATECTL_STATUS_PKTLEN|IEEE80211_RATECTL_STATUS_RSSI)) != (IEEE80211_RATECTL_STATUS_PKTLEN|IEEE80211_RATECTL_STATUS_RSSI)) d341 6 a346 11 pktlen = status->pktlen; rssi = status->rssi; if (status->status == IEEE80211_RATECTL_TX_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); a347 1 } d349 16 a364 7 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; d366 2 a367 6 error = sysctl_handle_int(oidp, &msecs, 0, req); if (error || !req->newptr) return error; rssadapt_setinterval(vap, msecs); return 0; } d369 15 a383 8 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)"); @ 1.21.16.2 log @State save. New kernel config for this brach only. TESTWIFI does produce a kernel. It is not working. athn files not compiling yet and commented out of the TESTWIFI kernel, which only has urtwn 802.11 driver enabled. ieee80211_alq.c and ieee80211_ddb.c not compiling yet. @ text @d1 2 a2 2 /* $NetBSD: ieee80211_rssadapt.c,v 1.21.16.1 2018/06/28 21:03:07 phil Exp $ */ a41 4 #ifdef __NetBSD__ /* Why doesn't FreeBSD have this? */ #include #endif a45 1 #ifdef __FreeBSD__ a46 1 #endif a47 1 #ifdef __FreeBSD__ a48 4 #endif #ifdef __NetBSD__ #include #endif a53 5 #ifdef __NetBSD__ #undef KASSERT #define KASSERT(__cond, __complaint) FBSDKASSERT(__cond, __complaint) #endif d100 1 a100 1 static const struct ieee80211_ratectl rssadapt __unused = { a341 1 #ifdef notyet a355 1 #endif d361 1 a361 1 #ifdef notyet a364 1 #endif @ 1.21.16.3 log @State save. urtwn now can attach and shows up in the "ifconfig -a" list. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.21.16.2 2018/07/12 16:35:34 phil Exp $ */ d116 1 a116 5 #if __FreeBSD__ static const struct ieee80211_ratectl rssadapt = { #elif __NetBSD__ const struct ieee80211_ratectl ratectl_rssadapt = { #endif a128 1 #if __FreeBSD__ a130 1 #endif @ 1.21.16.4 log @State save: urtwn: ifp->if_softc points to a vap, not the urtwn softc, fix code for this. add missing routines, need to get them filled out correctly. 80211: Add back some NetBSD ioctls, start working on the sysctl tree. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.21.16.3 2018/07/16 20:11:11 phil Exp $ */ a109 1 #ifdef notyet a111 1 #endif a166 1 #ifdef notyet a167 1 #endif d379 1 d385 1 d389 1 a390 1 #endif @ 1.21.16.5 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.21.16.4 2018/07/20 20:33:05 phil Exp $ */ a34 6 #include #ifdef __NetBSD__ __KERNEL_RCSID(0, "$NetBSD$"); #endif #ifdef _KERNEL_OPT a35 1 #endif @ 1.20 log @KNF. Remove extra spaces. No functional change. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.19 2014/04/07 00:07:40 pooka Exp $ */ d31 1 a31 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.19 2014/04/07 00:07:40 pooka Exp $"); d353 1 @ 1.20.2.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.21 2016/09/27 20:20:06 christos Exp $ */ d31 1 a31 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.21 2016/09/27 20:20:06 christos Exp $"); a352 1 __USE(rate); @ 1.19 log @Use module-compatible sysctl init instead of link sets. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.18 2014/02/25 18:30:12 pooka Exp $ */ d31 1 a31 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.18 2014/02/25 18:30:12 pooka Exp $"); d248 1 a248 1 long interval; @ 1.19.4.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.20 2016/07/07 06:55:43 msaitoh Exp $ */ d31 1 a31 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.20 2016/07/07 06:55:43 msaitoh Exp $"); d248 1 a248 1 long interval; @ 1.19.4.2 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.19.4.1 2016/07/09 20:25:21 skrll Exp $ */ d31 1 a31 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.19.4.1 2016/07/09 20:25:21 skrll Exp $"); a352 1 __USE(rate); @ 1.18 log @Ensure that the top level sysctl nodes (kern, vfs, net, ...) exist before the sysctl link sets are processed, and remove redundancy. Shaves >13kB off of an amd64 GENERIC, not to mention >1k duplicate lines of code. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.17 2009/10/19 23:19:39 rmind Exp $ */ d31 1 a31 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.17 2009/10/19 23:19:39 rmind Exp $"); d144 2 a145 2 SYSCTL_SETUP(sysctl_ieee80211_rssadapt, "sysctl ieee80211 rssadapt subtree setup") @ 1.18.2.1 log @Rebase. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.19 2014/04/07 00:07:40 pooka Exp $ */ d31 1 a31 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.19 2014/04/07 00:07:40 pooka Exp $"); d144 2 a145 2 void ieee80211_rssadapt_sysctl_setup(struct sysctllog **clog) @ 1.17 log @Drop 3rd and 4th clauses from David Young's license. Reviewed and approved by dyoung@@ (copyright holder). @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.16 2008/11/12 12:36:28 ad Exp $ */ d31 1 a31 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.16 2008/11/12 12:36:28 ad Exp $"); a150 5 CTLFLAG_PERMANENT, CTLTYPE_NODE, "net", NULL, NULL, 0, NULL, 0, CTL_NET, CTL_EOL)) != 0) goto err; if ((rc = sysctl_createv(clog, 0, &node, &node, d152 1 a152 1 NULL, 0, NULL, 0, PF_LINK, CTL_EOL)) != 0) @ 1.17.22.1 log @Rebase to HEAD as of a few days ago. @ text @d1 1 a1 1 /* $NetBSD$ */ d31 1 a31 1 __KERNEL_RCSID(0, "$NetBSD$"); d144 2 a145 2 void ieee80211_rssadapt_sysctl_setup(struct sysctllog **clog) d151 5 d157 1 a157 1 NULL, 0, NULL, 0, CTL_NET, PF_LINK, CTL_EOL)) != 0) @ 1.17.22.2 log @update from HEAD @ text @d248 1 a248 1 long interval; a352 1 __USE(rate); @ 1.17.12.1 log @sync with head. for a reference, the tree before this commit was tagged as yamt-pagecache-tag8. this commit was splitted into small chunks to avoid a limitation of cvs. ("Protocol error: too many arguments") @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.17 2009/10/19 23:19:39 rmind Exp $ */ d31 1 a31 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.17 2009/10/19 23:19:39 rmind Exp $"); d144 2 a145 2 void ieee80211_rssadapt_sysctl_setup(struct sysctllog **clog) d151 5 d157 1 a157 1 NULL, 0, NULL, 0, CTL_NET, PF_LINK, CTL_EOL)) != 0) @ 1.17.26.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.17 2009/10/19 23:19:39 rmind Exp $ */ d31 1 a31 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.17 2009/10/19 23:19:39 rmind Exp $"); d144 2 a145 2 void ieee80211_rssadapt_sysctl_setup(struct sysctllog **clog) d151 5 d157 1 a157 1 NULL, 0, NULL, 0, CTL_NET, PF_LINK, CTL_EOL)) != 0) @ 1.16 log @Remove LKMs and switch to the module framework, pass 1. Proposed on tech-kern@@. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.15 2008/06/24 10:33:46 gmcgarry Exp $ */ a13 3 * 3. The name of David Young may not be used to endorse or promote * products derived from this software without specific prior * written permission. d31 1 a31 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.15 2008/06/24 10:33:46 gmcgarry Exp $"); @ 1.15 log @Replace gcc-style designated initialisers with c99-style. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.14 2006/08/30 15:40:41 christos Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.14 2006/08/30 15:40:41 christos Exp $"); d145 1 a145 1 * TBD condition CTLFLAG_PERMANENT on being an LKM or not @ 1.15.4.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.16 2008/11/12 12:36:28 ad Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.16 2008/11/12 12:36:28 ad Exp $"); d145 1 a145 1 * TBD condition CTLFLAG_PERMANENT on being a module or not @ 1.15.2.1 log @Update haad-dm branch to haad-dm-base2. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.16 2008/11/12 12:36:28 ad Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.16 2008/11/12 12:36:28 ad Exp $"); d145 1 a145 1 * TBD condition CTLFLAG_PERMANENT on being a module or not @ 1.14 log @comment out impossible comparisons. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.13 2005/12/11 12:24:54 christos Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.13 2005/12/11 12:24:54 christos Exp $"); d78 6 a83 6 rc_decay_denom : 16, rc_decay_old : 15, rc_thresh_denom : 8, rc_thresh_old : 4, rc_avgrssi_denom : 8, rc_avgrssi_old : 4 @ 1.14.56.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.14 2006/08/30 15:40:41 christos Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.14 2006/08/30 15:40:41 christos Exp $"); d78 6 a83 6 .rc_decay_denom = 16, .rc_decay_old = 15, .rc_thresh_denom = 8, .rc_thresh_old = 4, .rc_avgrssi_denom = 8, .rc_avgrssi_old = 4 d145 1 a145 1 * TBD condition CTLFLAG_PERMANENT on being a module or not @ 1.14.56.2 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.14.56.1 2009/05/04 08:14:16 yamt Exp $ */ d14 3 d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.14.56.1 2009/05/04 08:14:16 yamt Exp $"); @ 1.14.58.1 log @Sync with wrstuden-revivesa-base-2. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.14 2006/08/30 15:40:41 christos Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.14 2006/08/30 15:40:41 christos Exp $"); d78 6 a83 6 .rc_decay_denom = 16, .rc_decay_old = 15, .rc_thresh_denom = 8, .rc_thresh_old = 4, .rc_avgrssi_denom = 8, .rc_avgrssi_old = 4 @ 1.14.52.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD$ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD$"); d78 6 a83 6 .rc_decay_denom = 16, .rc_decay_old = 15, .rc_thresh_denom = 8, .rc_thresh_old = 4, .rc_avgrssi_denom = 8, .rc_avgrssi_old = 4 @ 1.14.52.2 log @Sync with HEAD. @ text @d145 1 a145 1 * TBD condition CTLFLAG_PERMANENT on being a module or not @ 1.14.60.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.15 2008/06/24 10:33:46 gmcgarry Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.15 2008/06/24 10:33:46 gmcgarry Exp $"); d78 6 a83 6 .rc_decay_denom = 16, .rc_decay_old = 15, .rc_thresh_denom = 8, .rc_thresh_old = 4, .rc_avgrssi_denom = 8, .rc_avgrssi_old = 4 @ 1.14.50.1 log @Beginning of a sync with net80211 from FreeBSD. Lots to do. Sources taken from 2008-02-22. @ text @@ 1.13 log @merge ktrace-lwp. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.8.2.5 2005/11/10 14:10:51 skrll Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.8.2.5 2005/11/10 14:10:51 skrll Exp $"); d125 1 a125 1 if (rc.rc_decay_old < 0 || d129 1 a129 1 if (rc.rc_thresh_old < 0 || d133 1 a133 1 if (rc.rc_avgrssi_old < 0 || @ 1.13.4.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.14 2006/08/30 15:40:41 christos Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.14 2006/08/30 15:40:41 christos Exp $"); d125 1 a125 1 if (/* rc.rc_decay_old < 0 || */ d129 1 a129 1 if (/* rc.rc_thresh_old < 0 || */ d133 1 a133 1 if (/* rc.rc_avgrssi_old < 0 || */ @ 1.13.8.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.13 2005/12/11 12:24:54 christos Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.13 2005/12/11 12:24:54 christos Exp $"); d125 1 a125 1 if (/* rc.rc_decay_old < 0 || */ d129 1 a129 1 if (/* rc.rc_thresh_old < 0 || */ d133 1 a133 1 if (/* rc.rc_avgrssi_old < 0 || */ @ 1.12 log @Resolve conflicts. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.7 2004/05/25 04:33:59 atatat Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD$"); @ 1.11 log @Resolve conflicts in importation of 18-May-2005 ath(4) / net80211(9) from FreeBSD. Introduce compatibility shims (sys/dev/ic/ath_netbsd.[ch], sys/net80211/ieee80211_netbsd.[ch]). Update drivers (an, atu, atw, awi, ipw, iwi, rtw, wi) for the new net80211(9) API. @ text @@ 1.11.2.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.11 2005/06/22 06:16:02 dyoung Exp $"); d125 1 a125 1 if (/* rc.rc_decay_old < 0 || */ d129 1 a129 1 if (/* rc.rc_thresh_old < 0 || */ d133 1 a133 1 if (/* rc.rc_avgrssi_old < 0 || */ @ 1.10 log @Change the rest of the sysctl subsystem to use const consistently. The __UNCONST macro is now used only where necessary and the RW macros are gone. Most of the changes here are consumers of the sysctl_createv(9) interface that now takes a pair of const pointers which used not to be. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.9 2005/02/26 22:45:09 perry Exp $ */ d32 5 d46 1 a48 1 #include d256 1 a256 1 long interval; d282 1 a282 1 ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr), d325 1 a325 1 ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr), d362 1 a362 1 ic->ic_if.if_xname, d378 1 a378 1 printf("%s: dst %s thresholds\n", ic->ic_if.if_xname, @ 1.9 log @nuke trailing whitespace @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.8 2004/07/23 06:44:56 mycroft Exp $ */ d146 1 a146 1 struct sysctlnode *node; @ 1.8 log @Diff reduction vs. madwifi. Change the signature of IEEE80211_DPRINTF() so that it uses a bitmask, and convert some of the if_printf()s to IEEE80211_DPRINTF()s. XXX I'm using a global variable at the moment rather than per-interface. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.7 2004/05/25 04:33:59 atatat Exp $ */ d251 1 a251 1 long interval; @ 1.8.2.1 log @file ieee80211_rssadapt.c was added on branch ktrace-lwp on 2004-08-03 10:54:21 +0000 @ text @d1 386 @ 1.8.2.2 log @Sync with HEAD @ text @a0 386 /* $NetBSD: ieee80211_rssadapt.c,v 1.8.2.1 2004/08/03 10:54:21 skrll 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. */ #include #include #include /* for hz */ #include #include #include #include #include #include #include #include #ifdef interpolate #undef interpolate #endif #define interpolate(parm, old, new) ((parm##_old * (old) + \ (parm##_denom - parm##_old) * (new)) / \ parm##_denom) #ifdef IEEE80211_DEBUG static struct timeval lastrateadapt; /* time of last rate adaptation msg */ static int currssadaptps = 0; /* rate-adaptation msgs this second */ static int ieee80211_adaptrate = 4; /* rate-adaptation max msgs/sec */ #define RSSADAPT_DO_PRINT() \ ((ieee80211_rssadapt_debug > 0) && \ ppsratecheck(&lastrateadapt, &currssadaptps, ieee80211_adaptrate)) #define RSSADAPT_PRINTF(X) \ if (RSSADAPT_DO_PRINT()) \ printf X int ieee80211_rssadapt_debug = 0; #else #define RSSADAPT_DO_PRINT() (0) #define RSSADAPT_PRINTF(X) #endif static struct ieee80211_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 __NetBSD__ #ifdef IEEE80211_DEBUG /* TBD factor with sysctl_ath_verify, sysctl_ieee80211_verify. */ static int sysctl_ieee80211_rssadapt_debug(SYSCTLFN_ARGS) { int error, t; struct sysctlnode node; node = *rnode; t = *(int*)rnode->sysctl_data; node.sysctl_data = &t; error = sysctl_lookup(SYSCTLFN_CALL(&node)); if (error || newp == NULL) return (error); if (t < 0 || t > 2) return (EINVAL); *(int*)rnode->sysctl_data = t; return (0); } #endif /* IEEE80211_DEBUG */ /* TBD factor with sysctl_ath_verify, sysctl_ieee80211_verify. */ static int sysctl_ieee80211_rssadapt_expavgctl(SYSCTLFN_ARGS) { struct ieee80211_rssadapt_expavgctl rc; int error; struct sysctlnode node; node = *rnode; rc = *(struct ieee80211_rssadapt_expavgctl *)rnode->sysctl_data; node.sysctl_data = &rc; error = sysctl_lookup(SYSCTLFN_CALL(&node)); if (error || newp == NULL) return (error); if (rc.rc_decay_old < 0 || rc.rc_decay_denom < rc.rc_decay_old) return (EINVAL); if (rc.rc_thresh_old < 0 || rc.rc_thresh_denom < rc.rc_thresh_old) return (EINVAL); if (rc.rc_avgrssi_old < 0 || rc.rc_avgrssi_denom < rc.rc_avgrssi_old) return (EINVAL); *(struct ieee80211_rssadapt_expavgctl *)rnode->sysctl_data = rc; return (0); } /* * Setup sysctl(3) MIB, net.ieee80211.* * * TBD condition CTLFLAG_PERMANENT on being an LKM or not */ SYSCTL_SETUP(sysctl_ieee80211_rssadapt, "sysctl ieee80211 rssadapt subtree setup") { int rc; struct sysctlnode *node; if ((rc = sysctl_createv(clog, 0, NULL, &node, CTLFLAG_PERMANENT, CTLTYPE_NODE, "net", NULL, NULL, 0, NULL, 0, CTL_NET, CTL_EOL)) != 0) goto err; if ((rc = sysctl_createv(clog, 0, &node, &node, CTLFLAG_PERMANENT, CTLTYPE_NODE, "link", NULL, NULL, 0, NULL, 0, PF_LINK, CTL_EOL)) != 0) goto err; if ((rc = sysctl_createv(clog, 0, &node, &node, CTLFLAG_PERMANENT, CTLTYPE_NODE, "ieee80211", NULL, NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) goto err; if ((rc = sysctl_createv(clog, 0, &node, &node, CTLFLAG_PERMANENT, CTLTYPE_NODE, "rssadapt", SYSCTL_DESCR("Received Signal Strength adaptation controls"), NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) goto err; #ifdef IEEE80211_DEBUG /* control debugging printfs */ if ((rc = sysctl_createv(clog, 0, &node, NULL, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "debug", SYSCTL_DESCR("Enable RSS adaptation debugging output"), sysctl_ieee80211_rssadapt_debug, 0, &ieee80211_rssadapt_debug, 0, CTL_CREATE, CTL_EOL)) != 0) goto err; #endif /* IEEE80211_DEBUG */ /* control rate of decay for exponential averages */ if ((rc = sysctl_createv(clog, 0, &node, NULL, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_STRUCT, "expavgctl", SYSCTL_DESCR("RSS exponential averaging control"), sysctl_ieee80211_rssadapt_expavgctl, 0, &master_expavgctl, sizeof(master_expavgctl), CTL_CREATE, CTL_EOL)) != 0) goto err; return; err: printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); } #endif /* __NetBSD__ */ int ieee80211_rssadapt_choose(struct ieee80211_rssadapt *ra, struct ieee80211_rateset *rs, struct ieee80211_frame *wh, u_int len, int fixed_rate, const char *dvname, int do_not_adapt) { u_int16_t (*thrs)[IEEE80211_RATE_SIZE]; int flags = 0, i, rateidx = 0, thridx, top; if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) flags |= IEEE80211_RATE_BASIC; for (i = 0, top = IEEE80211_RSSADAPT_BKT0; i < IEEE80211_RSSADAPT_BKTS; i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) { thridx = i; if (len <= top) break; } thrs = &ra->ra_rate_thresh[thridx]; if (fixed_rate != -1) { if ((rs->rs_rates[fixed_rate] & flags) == flags) { rateidx = fixed_rate; goto out; } flags |= IEEE80211_RATE_BASIC; i = fixed_rate; } else i = rs->rs_nrates; while (--i >= 0) { rateidx = i; if ((rs->rs_rates[i] & flags) != flags) continue; if (do_not_adapt) break; if ((*thrs)[i] < ra->ra_avg_rssi) break; } out: #ifdef IEEE80211_DEBUG if (ieee80211_rssadapt_debug && dvname != NULL) { printf("%s: dst %s threshold[%d, %d.%d] %d < %d\n", dvname, ether_sprintf(wh->i_addr1), len, (rs->rs_rates[rateidx] & IEEE80211_RATE_VAL) / 2, (rs->rs_rates[rateidx] & IEEE80211_RATE_VAL) * 5 % 10, (*thrs)[rateidx], ra->ra_avg_rssi); } #endif /* IEEE80211_DEBUG */ return rateidx; } void ieee80211_rssadapt_updatestats(struct ieee80211_rssadapt *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(100000, 10000000 / MAX(1, 10 * ra->ra_pktrate)); ra->ra_raise_interval.tv_sec = interval / (1000 * 1000); ra->ra_raise_interval.tv_usec = interval % (1000 * 1000); } void ieee80211_rssadapt_input(struct ieee80211com *ic, struct ieee80211_node *ni, struct ieee80211_rssadapt *ra, int rssi) { #ifdef IEEE80211_DEBUG int last_avg_rssi = ra->ra_avg_rssi; #endif ra->ra_avg_rssi = interpolate(master_expavgctl.rc_avgrssi, ra->ra_avg_rssi, (rssi << 8)); RSSADAPT_PRINTF(("%s: src %s rssi %d avg %d -> %d\n", ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr), rssi, last_avg_rssi, ra->ra_avg_rssi)); } /* * Adapt the data rate to suit the conditions. When a transmitted * packet is dropped after IEEE80211_RSSADAPT_RETRY_LIMIT retransmissions, * raise the RSS threshold for transmitting packets of similar length at * the same data rate. */ void ieee80211_rssadapt_lower_rate(struct ieee80211com *ic, struct ieee80211_node *ni, struct ieee80211_rssadapt *ra, struct ieee80211_rssdesc *id) { struct ieee80211_rateset *rs = &ni->ni_rates; u_int16_t last_thr; u_int i, thridx, top; ra->ra_nfail++; if (id->id_rateidx >= rs->rs_nrates) { RSSADAPT_PRINTF(("ieee80211_rssadapt_lower_rate: " "%s rate #%d > #%d out of bounds\n", ether_sprintf(ni->ni_macaddr), id->id_rateidx, rs->rs_nrates - 1)); return; } for (i = 0, top = IEEE80211_RSSADAPT_BKT0; i < IEEE80211_RSSADAPT_BKTS; i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) { thridx = i; if (id->id_len <= top) break; } last_thr = ra->ra_rate_thresh[thridx][id->id_rateidx]; ra->ra_rate_thresh[thridx][id->id_rateidx] = interpolate(master_expavgctl.rc_thresh, last_thr, (id->id_rssi << 8)); RSSADAPT_PRINTF(("%s: dst %s rssi %d threshold[%d, %d.%d] %d -> %d\n", ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr), id->id_rssi, id->id_len, (rs->rs_rates[id->id_rateidx] & IEEE80211_RATE_VAL) / 2, (rs->rs_rates[id->id_rateidx] & IEEE80211_RATE_VAL) * 5 % 10, last_thr, ra->ra_rate_thresh[thridx][id->id_rateidx])); } void ieee80211_rssadapt_raise_rate(struct ieee80211com *ic, struct ieee80211_rssadapt *ra, struct ieee80211_rssdesc *id) { u_int16_t (*thrs)[IEEE80211_RATE_SIZE], newthr, oldthr; struct ieee80211_node *ni = id->id_node; struct ieee80211_rateset *rs = &ni->ni_rates; int i, rate, top; #ifdef IEEE80211_DEBUG int j; #endif ra->ra_nok++; if (!ratecheck(&ra->ra_last_raise, &ra->ra_raise_interval)) return; for (i = 0, top = IEEE80211_RSSADAPT_BKT0; i < IEEE80211_RSSADAPT_BKTS; i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) { thrs = &ra->ra_rate_thresh[i]; if (id->id_len <= top) break; } if (id->id_rateidx + 1 < rs->rs_nrates && (*thrs)[id->id_rateidx + 1] > (*thrs)[id->id_rateidx]) { rate = (rs->rs_rates[id->id_rateidx + 1] & IEEE80211_RATE_VAL); RSSADAPT_PRINTF(("%s: threshold[%d, %d.%d] decay %d ", ic->ic_if.if_xname, IEEE80211_RSSADAPT_BKT0 << (IEEE80211_RSSADAPT_BKTPOWER* i), rate / 2, rate * 5 % 10, (*thrs)[id->id_rateidx + 1])); oldthr = (*thrs)[id->id_rateidx + 1]; if ((*thrs)[id->id_rateidx] == 0) newthr = ra->ra_avg_rssi; else newthr = (*thrs)[id->id_rateidx]; (*thrs)[id->id_rateidx + 1] = interpolate(master_expavgctl.rc_decay, oldthr, newthr); RSSADAPT_PRINTF(("-> %d\n", (*thrs)[id->id_rateidx + 1])); } #ifdef IEEE80211_DEBUG if (RSSADAPT_DO_PRINT()) { printf("%s: dst %s thresholds\n", ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr)); for (i = 0; i < IEEE80211_RSSADAPT_BKTS; i++) { printf("%d-byte", IEEE80211_RSSADAPT_BKT0 << (IEEE80211_RSSADAPT_BKTPOWER * i)); for (j = 0; j < rs->rs_nrates; j++) { rate = (rs->rs_rates[j] & IEEE80211_RATE_VAL); printf(", T[%d.%d] = %d", rate / 2, rate * 5 % 10, ra->ra_rate_thresh[i][j]); } printf("\n"); } } #endif /* IEEE80211_DEBUG */ } @ 1.8.2.3 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.8.2.2 2004/09/18 14:54:39 skrll Exp $ */ @ 1.8.2.4 log @Fix the sync with head I botched. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.8.2.3 2004/09/21 13:36:55 skrll Exp $ */ @ 1.8.2.5 log @Sync with HEAD. Hi Perry! @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.8.2.4 2005/03/04 16:53:17 skrll Exp $ */ d251 1 a251 1 long interval; @ 1.8.2.6 log @Sync with HEAD. Here we go again... @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.8.2.5 2005/11/10 14:10:51 skrll Exp $ */ a31 5 #include #ifdef __NetBSD__ __KERNEL_RCSID(0, "$NetBSD: ieee80211_rssadapt.c,v 1.8.2.5 2005/11/10 14:10:51 skrll Exp $"); #endif a40 1 #include d43 1 d146 1 a146 1 const struct sysctlnode *node; d251 1 a251 1 long interval; d277 1 a277 1 ic->ic_ifp->if_xname, ether_sprintf(ni->ni_macaddr), d320 1 a320 1 ic->ic_ifp->if_xname, ether_sprintf(ni->ni_macaddr), d357 1 a357 1 ic->ic_ifp->if_xname, d373 1 a373 1 printf("%s: dst %s thresholds\n", ic->ic_ifp->if_xname, @ 1.8.6.1 log @sync with -current @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.9 2005/02/26 22:45:09 perry Exp $ */ d251 1 a251 1 long interval; @ 1.8.8.1 log @sync with head. xen and whitespace. xen part is not finished. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.8 2004/07/23 06:44:56 mycroft Exp $ */ d251 1 a251 1 long interval; @ 1.7 log @Sysctl descriptions under net subtree (net.key not done) @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.6 2004/05/06 07:11:40 dyoung Exp $ */ a96 3 IEEE80211_DPRINTF(("%s: t = %d, nodenum = %d, rnodenum = %d\n", __func__, t, node.sysctl_num, rnode->sysctl_num)); a119 7 IEEE80211_DPRINTF(("%s: decay = %d/%d, thresh = %d/%d, " "avgrssi = %d/%d, nodenum = %d, rnodenum = %d\n", __func__, rc.rc_decay_old, rc.rc_decay_denom, rc.rc_thresh_old, rc.rc_thresh_denom, rc.rc_avgrssi_old, rc.rc_avgrssi_denom, node.sysctl_num, rnode->sysctl_num)); @ 1.6 log @Following Andrew Brown's suggestion, move net.ieee80211 to net.link.ieee80211. The convention is that nodes directly under net are protocol families (PF_*). Also, simplify the sysctl setup for net80211 and rssadapt, following another suggestion by Andrew. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.5 2004/05/06 03:03:20 dyoung Exp $ */ d174 2 a175 1 CTLFLAG_PERMANENT, CTLTYPE_NODE, "rssadapt", NULL, d182 2 a183 1 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "debug", NULL, d192 2 a193 1 "expavgctl", NULL, sysctl_ieee80211_rssadapt_expavgctl, 0, @ 1.5 log @Create ieee80211_rssadapt_debug to control rssadapt(9) debug messages independently from net80211 debug messages. Create a new sysctl, net.ieee80211.rssadapt.debug, for turning the debug messages on and off. Create a new sysctl, net.ieee80211.rssadapt.expavgctl, to control the rate of decay for the exponential averages used by rssadapt(9). @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.4 2004/03/29 04:09:45 dyoung Exp $ */ d155 1 a155 1 int rc, ieee80211_node_num, rssadapt_node_num; d158 1 a158 1 if ((rc = sysctl_createv(clog, 0, NULL, NULL, d163 6 a168 1 if ((rc = sysctl_createv(clog, 0, NULL, &node, d170 1 a170 1 NULL, 0, NULL, 0, CTL_NET, CTL_CREATE, CTL_EOL)) != 0) d173 1 a173 3 ieee80211_node_num = node->sysctl_num; if ((rc = sysctl_createv(clog, 0, NULL, &node, d175 1 a175 2 NULL, 0, NULL, 0, CTL_NET, ieee80211_node_num, CTL_CREATE, CTL_EOL)) != 0) a177 2 rssadapt_node_num = node->sysctl_num; d180 1 a180 1 if ((rc = sysctl_createv(clog, 0, NULL, &node, d183 1 a183 2 CTL_NET, ieee80211_node_num, rssadapt_node_num, CTL_CREATE, CTL_EOL)) != 0) d188 1 a188 1 if ((rc = sysctl_createv(clog, 0, NULL, &node, d191 2 a192 2 &master_expavgctl, sizeof(master_expavgctl), CTL_NET, ieee80211_node_num, rssadapt_node_num, CTL_CREATE, CTL_EOL)) != 0) @ 1.4 log @Get the sense of ra->ra_nok and ra->ra_nfail right. They indicate successes and failures, respectively, not the other way around. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.3 2004/03/17 17:00:34 dyoung Exp $ */ d35 1 d59 1 a59 1 ((ieee80211_debug > 0) && \ d65 2 d72 1 a72 1 struct ieee80211_rssadapt_expavgctl master_expavgctl = { d81 121 d244 2 a245 1 if (dvname != NULL) { d252 1 @ 1.3 log @In wi(4), wi_choose_rate used to contain device-independent code. I have pulled that code into the function ieee80211_rssadapt_choose so that I can re-use it in ath(4), atw(4), and in other drivers. In rssadapt(9), I have also created a struct ieee80211_rssadapt_expavgctl that contains parameters for rate adaptation. When IEEE80211_RSSADAPT_DEBUG is enabled, I will using sysctl to expose an ieee80211_rssadapt_expavgctl for each wireless device. Also in rssadapt(9), I have introduced an interpolate() macro which makes the exponential-averaging code more compact. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.2 2003/12/07 05:29:39 dyoung Exp $ */ d178 1 a178 1 ra->ra_nok++; d221 1 a221 1 ra->ra_nfail++; @ 1.2 log @Oops. Make it compile with 'options IEEE80211_DEBUG'. @ text @d1 1 a1 1 /* $NetBSD: ieee80211_rssadapt.c,v 1.1 2003/10/26 07:56:41 dyoung Exp $ */ d45 7 d69 60 a128 9 /* RSS threshold decay. */ u_int ieee80211_rssadapt_decay_denom = 16; u_int ieee80211_rssadapt_decay_old = 15; /* RSS threshold update. */ u_int ieee80211_rssadapt_thresh_denom = 8; u_int ieee80211_rssadapt_thresh_old = 4; /* RSS average update. */ u_int ieee80211_rssadapt_avgrssi_denom = 8; u_int ieee80211_rssadapt_avgrssi_old = 4; d155 2 a156 4 ra->ra_avg_rssi = (ieee80211_rssadapt_avgrssi_old * ra->ra_avg_rssi + ieee80211_rssadapt_avgrssi_new * (rssi << 8)) / ieee80211_rssadapt_avgrssi_denom; d198 2 a199 3 (ieee80211_rssadapt_thresh_old * last_thr + ieee80211_rssadapt_thresh_new * (id->id_rssi << 8)) / ieee80211_rssadapt_thresh_denom; d248 1 a248 3 (ieee80211_rssadapt_decay_old * oldthr + ieee80211_rssadapt_decay_new * newthr) / ieee80211_rssadapt_decay_denom; @ 1.1 log @Support data-rate adaptation loosely based on the paper "Link Adaptation Strategy for IEEE 802.11 WLAN via Received Signal Strength Measurement" by Javier del Prado Pavon and Sunghyun Choi. This module should provide faster adaptation and higher throughput than Lucent's rate-adaptation scheme. Individual drivers need to be modified to use this module. Patches for wi(4) are forthcoming. @ text @d1 1 a1 1 /* $NetBSD$ */ d93 1 d95 1 d161 4 a164 1 int i, j, rate, top; @