summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2020-09-12 19:33:25 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2020-09-12 19:33:25 +0000
commit752c173687a3f220c24e8e251a98b448dbeed3ff (patch)
tree355b76d1a6f3b353a476194481bb93fbcff4c37c
parentc55ffe543826f574f6560b05642ee4c06178853c (diff)
downloadsrc-test2-752c173687a3f220c24e8e251a98b448dbeed3ff.tar.gz
src-test2-752c173687a3f220c24e8e251a98b448dbeed3ff.zip
Notes
-rw-r--r--lib/lib80211/lib80211_regdomain.c2
-rw-r--r--lib/lib80211/lib80211_regdomain.h8
-rw-r--r--lib/lib80211/regdomain.xml68
-rw-r--r--sbin/ifconfig/ifieee80211.c131
-rw-r--r--share/man/man4/ath.416
-rw-r--r--share/man/man4/net80211.412
-rw-r--r--share/man/man4/run.44
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h20
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c83
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c28
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c11
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c12
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_phy.c14
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c11
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.c2
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.h2
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300eep.h10
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_ap121.h5
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_aphrodite.h5
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_cus157.h5
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_generic.h5
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_hb112.h5
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_hb116.h5
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_osprey_k31.h5
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_wasp_2.h6
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_xb112.h5
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_xb113.h5
-rw-r--r--sys/dev/an/if_an.c2
-rw-r--r--sys/dev/ath/ah_osdep.c1
-rw-r--r--sys/dev/ath/ah_osdep_ar5210.c1
-rw-r--r--sys/dev/ath/ah_osdep_ar5211.c1
-rw-r--r--sys/dev/ath/ah_osdep_ar5212.c1
-rw-r--r--sys/dev/ath/ah_osdep_ar5416.c1
-rw-r--r--sys/dev/ath/ah_osdep_ar9300.c1
-rw-r--r--sys/dev/ath/ath_dfs/null/dfs_null.c2
-rw-r--r--sys/dev/ath/ath_hal/ah.c5
-rw-r--r--sys/dev/ath/ath_hal/ah.h23
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom_9287.c9
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom_9287.h1
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom_v14.c8
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom_v3.c6
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom_v3.h1
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom_v4k.c6
-rw-r--r--sys/dev/ath/ath_hal/ah_internal.h1
-rw-r--r--sys/dev/ath/ath_hal/ah_regdomain.c4
-rw-r--r--sys/dev/ath/ath_hal/ah_regdomain/ah_rd_domains.h1
-rw-r--r--sys/dev/ath/ath_hal/ah_regdomain/ah_rd_freqbands.h3
-rw-r--r--sys/dev/ath/ath_hal/ah_soc.h8
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210_recv.c3
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210_reset.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_keycache.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_misc.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_phy.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_recv.c3
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211phy.h1
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211reg.h1
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar2316.c4
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar2317.c4
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar2413.c4
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar2425.c5
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5111.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5112.c4
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_ani.c4
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_misc.c3
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_phy.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_recv.c9
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_reset.c4
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c5
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212phy.h1
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5413.c5
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312_eeprom.c3
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312_gpio.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312_interrupts.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312_reset.c4
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312reg.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5315_gpio.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar2133.c6
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416.h5
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_ani.c3
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_attach.c5
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_cal.c4
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_cal.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_gpio.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_power.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_recv.c11
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_reset.c27
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c1
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c16
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416desc.h1
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416reg.h2
-rw-r--r--sys/dev/ath/ath_hal/ar9001/ar9130_attach.c3
-rw-r--r--sys/dev/ath/ath_hal/ar9001/ar9160_attach.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9280_attach.c3
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9280_olc.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9285.c1
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9285_attach.c4
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9285_btcoex.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9285_reset.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_attach.c3
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_cal.c3
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_reset.c1
-rw-r--r--sys/dev/ath/ath_rate/amrr/amrr.c21
-rw-r--r--sys/dev/ath/ath_rate/onoe/onoe.c20
-rw-r--r--sys/dev/ath/ath_rate/sample/sample.c521
-rw-r--r--sys/dev/ath/ath_rate/sample/sample.h13
-rw-r--r--sys/dev/ath/ath_rate/sample/tx_schedules.h36
-rw-r--r--sys/dev/ath/if_ath.c161
-rw-r--r--sys/dev/ath/if_ath_ahb.c3
-rw-r--r--sys/dev/ath/if_ath_beacon.c1
-rw-r--r--sys/dev/ath/if_ath_beacon.h1
-rw-r--r--sys/dev/ath/if_ath_btcoex.c3
-rw-r--r--sys/dev/ath/if_ath_dfs.c1
-rw-r--r--sys/dev/ath/if_ath_drv.c1
-rw-r--r--sys/dev/ath/if_ath_ioctl.c2
-rw-r--r--sys/dev/ath/if_ath_led.c1
-rw-r--r--sys/dev/ath/if_ath_lna_div.c3
-rw-r--r--sys/dev/ath/if_ath_misc.h6
-rw-r--r--sys/dev/ath/if_ath_pci.c3
-rw-r--r--sys/dev/ath/if_ath_pci_devlist.h2
-rw-r--r--sys/dev/ath/if_ath_rate.c1
-rw-r--r--sys/dev/ath/if_ath_rx.c48
-rw-r--r--sys/dev/ath/if_ath_rx_edma.c51
-rw-r--r--sys/dev/ath/if_ath_spectral.c3
-rw-r--r--sys/dev/ath/if_ath_sysctl.c12
-rw-r--r--sys/dev/ath/if_ath_tx.c140
-rw-r--r--sys/dev/ath/if_ath_tx.h1
-rw-r--r--sys/dev/ath/if_ath_tx_edma.c5
-rw-r--r--sys/dev/ath/if_ath_tx_ht.c24
-rw-r--r--sys/dev/ath/if_athioctl.h1
-rw-r--r--sys/dev/ath/if_athrate.h20
-rw-r--r--sys/dev/ath/if_athvar.h9
-rw-r--r--sys/dev/bwi/bwimac.c2
-rw-r--r--sys/dev/bwi/bwiphy.c3
-rw-r--r--sys/dev/bwi/bwirf.c2
-rw-r--r--sys/dev/bwi/if_bwi.c15
-rw-r--r--sys/dev/bwi/if_bwi_pci.c3
-rw-r--r--sys/dev/bwi/if_bwireg.h1
-rw-r--r--sys/dev/bwn/if_bwn.c19
-rw-r--r--sys/dev/bwn/if_bwn_pci.c2
-rw-r--r--sys/dev/bwn/if_bwn_pcivar.h1
-rw-r--r--sys/dev/bwn/if_bwn_phy_g.c1
-rw-r--r--sys/dev/bwn/if_bwnvar.h1
-rw-r--r--sys/dev/iwm/if_iwm.c10
-rw-r--r--sys/dev/iwn/if_iwn.c17
-rw-r--r--sys/dev/mwl/if_mwl.c17
-rw-r--r--sys/dev/mwl/if_mwl_pci.c4
-rw-r--r--sys/dev/mwl/mwlreg.h16
-rw-r--r--sys/dev/otus/if_otus.c497
-rw-r--r--sys/dev/otus/if_otusreg.h48
-rw-r--r--sys/dev/rtwn/if_rtwn.c10
-rw-r--r--sys/dev/rtwn/if_rtwn_beacon.c1
-rw-r--r--sys/dev/rtwn/if_rtwn_calib.c1
-rw-r--r--sys/dev/rtwn/if_rtwn_cam.c1
-rw-r--r--sys/dev/rtwn/if_rtwn_efuse.c1
-rw-r--r--sys/dev/rtwn/if_rtwn_fw.c1
-rw-r--r--sys/dev/rtwn/if_rtwn_fw.h1
-rw-r--r--sys/dev/rtwn/if_rtwn_ridx.h1
-rw-r--r--sys/dev/rtwn/if_rtwn_rx.c33
-rw-r--r--sys/dev/rtwn/if_rtwn_rx.h1
-rw-r--r--sys/dev/rtwn/if_rtwn_task.c1
-rw-r--r--sys/dev/rtwn/if_rtwn_tx.c1
-rw-r--r--sys/dev/rtwn/if_rtwnreg.h3
-rw-r--r--sys/dev/rtwn/if_rtwnvar.h4
-rw-r--r--sys/dev/rtwn/pci/rtwn_pci_attach.c2
-rw-r--r--sys/dev/rtwn/pci/rtwn_pci_reg.c1
-rw-r--r--sys/dev/rtwn/pci/rtwn_pci_rx.c1
-rw-r--r--sys/dev/rtwn/pci/rtwn_pci_tx.c1
-rw-r--r--sys/dev/rtwn/pci/rtwn_pci_var.h1
-rw-r--r--sys/dev/rtwn/rtl8188e/pci/r88ee.h3
-rw-r--r--sys/dev/rtwn/rtl8188e/pci/r88ee_reg.h1
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e.h1
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e_beacon.c1
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e_calib.c1
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e_chan.c1
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e_fw.c1
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e_init.c1
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e_led.c1
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e_priv.h1
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e_reg.h3
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e_rf.c1
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e_rom.c1
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e_rx.c1
-rw-r--r--sys/dev/rtwn/rtl8188e/r88e_tx.c1
-rw-r--r--sys/dev/rtwn/rtl8188e/usb/r88eu.h2
-rw-r--r--sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c1
-rw-r--r--sys/dev/rtwn/rtl8188e/usb/r88eu_init.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/pci/r92ce.h2
-rw-r--r--sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/pci/r92ce_calib.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/pci/r92ce_fw.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/pci/r92ce_init.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/pci/r92ce_priv.h2
-rw-r--r--sys/dev/rtwn/rtl8192c/pci/r92ce_reg.h1
-rw-r--r--sys/dev/rtwn/rtl8192c/pci/r92ce_rx.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/pci/r92ce_tx.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c.h1
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_attach.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_beacon.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_calib.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_chan.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_fw.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_init.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_priv.h3
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_reg.h4
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_rf.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_rom.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_rx.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_tx.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_tx_desc.h1
-rw-r--r--sys/dev/rtwn/rtl8192c/usb/r92cu.h2
-rw-r--r--sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/usb/r92cu_init.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/usb/r92cu_led.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/usb/r92cu_priv.h3
-rw-r--r--sys/dev/rtwn/rtl8192c/usb/r92cu_reg.h2
-rw-r--r--sys/dev/rtwn/rtl8192c/usb/r92cu_rx.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/usb/r92cu_tx.c1
-rw-r--r--sys/dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h2
-rw-r--r--sys/dev/rtwn/rtl8192e/r92e.h1
-rw-r--r--sys/dev/rtwn/rtl8192e/r92e_chan.c1
-rw-r--r--sys/dev/rtwn/rtl8192e/r92e_priv.h2
-rw-r--r--sys/dev/rtwn/rtl8192e/usb/r92eu.h1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a.h1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_beacon.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_calib.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_caps.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_chan.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_fw.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_fw_cmd.h1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_init.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_led.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_priv.h3
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_reg.h3
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_rf.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_rom.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_rx.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_tx.c2
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_tx_desc.h1
-rw-r--r--sys/dev/rtwn/rtl8812a/usb/r12au.h1
-rw-r--r--sys/dev/rtwn/rtl8812a/usb/r12au_attach.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/usb/r12au_init.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/usb/r12au_rx.c1
-rw-r--r--sys/dev/rtwn/rtl8812a/usb/r12au_tx.c1
-rw-r--r--sys/dev/rtwn/rtl8821a/r21a.h1
-rw-r--r--sys/dev/rtwn/rtl8821a/r21a_beacon.c1
-rw-r--r--sys/dev/rtwn/rtl8821a/r21a_calib.c1
-rw-r--r--sys/dev/rtwn/rtl8821a/r21a_chan.c1
-rw-r--r--sys/dev/rtwn/rtl8821a/r21a_fw.c1
-rw-r--r--sys/dev/rtwn/rtl8821a/r21a_init.c1
-rw-r--r--sys/dev/rtwn/rtl8821a/r21a_led.c1
-rw-r--r--sys/dev/rtwn/rtl8821a/r21a_priv.h3
-rw-r--r--sys/dev/rtwn/rtl8821a/r21a_reg.h1
-rw-r--r--sys/dev/rtwn/rtl8821a/r21a_rom.c1
-rw-r--r--sys/dev/rtwn/rtl8821a/r21a_rx.c1
-rw-r--r--sys/dev/rtwn/rtl8821a/usb/r21au.h1
-rw-r--r--sys/dev/rtwn/rtl8821a/usb/r21au_attach.c1
-rw-r--r--sys/dev/rtwn/rtl8821a/usb/r21au_dfs.c1
-rw-r--r--sys/dev/rtwn/rtl8821a/usb/r21au_init.c2
-rw-r--r--sys/dev/rtwn/usb/rtwn_usb_attach.c1
-rw-r--r--sys/dev/rtwn/usb/rtwn_usb_attach.h1
-rw-r--r--sys/dev/rtwn/usb/rtwn_usb_ep.c1
-rw-r--r--sys/dev/rtwn/usb/rtwn_usb_reg.c1
-rw-r--r--sys/dev/rtwn/usb/rtwn_usb_tx.c2
-rw-r--r--sys/dev/usb/usbdevs1
-rw-r--r--sys/dev/usb/wlan/if_rsu.c36
-rw-r--r--sys/dev/usb/wlan/if_run.c186
-rw-r--r--sys/dev/usb/wlan/if_runreg.h7
-rw-r--r--sys/dev/usb/wlan/if_runvar.h7
-rw-r--r--sys/dev/usb/wlan/if_zyd.c51
-rw-r--r--sys/dev/wi/if_wavelan_ieee.h8
-rw-r--r--sys/dev/wi/if_wi.c52
-rw-r--r--sys/dev/wi/if_wi_macio.c1
-rw-r--r--sys/dev/wi/if_wi_pccard.c1
-rw-r--r--sys/dev/wi/if_wi_pci.c3
-rw-r--r--sys/dev/wpi/if_wpireg.h5
-rw-r--r--sys/dev/wtap/if_wtap.c14
-rw-r--r--sys/kern/kern_jail.c6
-rw-r--r--sys/net80211/_ieee80211.h22
-rw-r--r--sys/net80211/ieee80211.c201
-rw-r--r--sys/net80211/ieee80211.h2
-rw-r--r--sys/net80211/ieee80211_adhoc.c27
-rw-r--r--sys/net80211/ieee80211_amrr.c22
-rw-r--r--sys/net80211/ieee80211_ddb.c34
-rw-r--r--sys/net80211/ieee80211_freebsd.c26
-rw-r--r--sys/net80211/ieee80211_freebsd.h5
-rw-r--r--sys/net80211/ieee80211_hostap.c38
-rw-r--r--sys/net80211/ieee80211_ht.c489
-rw-r--r--sys/net80211/ieee80211_ht.h18
-rw-r--r--sys/net80211/ieee80211_input.h3
-rw-r--r--sys/net80211/ieee80211_ioctl.c82
-rw-r--r--sys/net80211/ieee80211_ioctl.h5
-rw-r--r--sys/net80211/ieee80211_node.c187
-rw-r--r--sys/net80211/ieee80211_node.h6
-rw-r--r--sys/net80211/ieee80211_output.c191
-rw-r--r--sys/net80211/ieee80211_phy.h15
-rw-r--r--sys/net80211/ieee80211_power.c2
-rw-r--r--sys/net80211/ieee80211_proto.c542
-rw-r--r--sys/net80211/ieee80211_proto.h11
-rw-r--r--sys/net80211/ieee80211_regdomain.c34
-rw-r--r--sys/net80211/ieee80211_scan_sta.c8
-rw-r--r--sys/net80211/ieee80211_scan_sw.c55
-rw-r--r--sys/net80211/ieee80211_sta.c106
-rw-r--r--sys/net80211/ieee80211_sta.h9
-rw-r--r--sys/net80211/ieee80211_var.h78
-rw-r--r--sys/net80211/ieee80211_vht.c54
-rw-r--r--sys/net80211/ieee80211_vht.h2
-rw-r--r--sys/sys/priv.h6
-rw-r--r--tools/tools/ath/Makefile2
-rw-r--r--tools/tools/ath/ath_ee_9300_print/main.c278
-rw-r--r--tools/tools/ath/athani/Makefile23
-rw-r--r--tools/tools/ath/athani/main.c226
-rw-r--r--tools/tools/ath/athratestats/main.c43
-rw-r--r--tools/tools/net80211/wlanstats/main.c2
-rw-r--r--tools/tools/net80211/wlanstats/wlanstats.c10
322 files changed, 4230 insertions, 1749 deletions
diff --git a/lib/lib80211/lib80211_regdomain.c b/lib/lib80211/lib80211_regdomain.c
index ba80ceb4b38e..8dfd435e07a0 100644
--- a/lib/lib80211/lib80211_regdomain.c
+++ b/lib/lib80211/lib80211_regdomain.c
@@ -192,7 +192,7 @@ decode_flag(struct mystate *mt, const char *p, int len)
FLAG(IEEE80211_CHAN_VHT40),
FLAG(IEEE80211_CHAN_VHT80),
/*
- * XXX VHT80_80? This likely should be done by
+ * XXX VHT80P80? This likely should be done by
* 80MHz chan logic in net80211 / ifconfig.
*/
FLAG(IEEE80211_CHAN_VHT160),
diff --git a/lib/lib80211/lib80211_regdomain.h b/lib/lib80211/lib80211_regdomain.h
index a8a4207c98ac..913dc161cdb0 100644
--- a/lib/lib80211/lib80211_regdomain.h
+++ b/lib/lib80211/lib80211_regdomain.h
@@ -73,10 +73,10 @@ struct regdomain {
netband_head bands_11b; /* 11b operation */
netband_head bands_11g; /* 11g operation */
netband_head bands_11a; /* 11a operation */
- netband_head bands_11ng;/* 11ng operation */
- netband_head bands_11na;/* 11na operation */
- netband_head bands_11ac;/* 11ac 5GHz operation */
- netband_head bands_11acg;/* 11ac 2GHz operation */
+ netband_head bands_11ng; /* 11ng operation */
+ netband_head bands_11na; /* 11na operation */
+ netband_head bands_11ac; /* 11ac 5GHz operation */
+ netband_head bands_11acg; /* 11ac 2GHz operation */
LIST_ENTRY(regdomain) next;
};
diff --git a/lib/lib80211/regdomain.xml b/lib/lib80211/regdomain.xml
index 21d544cbb043..cad3039c3d3d 100644
--- a/lib/lib80211/regdomain.xml
+++ b/lib/lib80211/regdomain.xml
@@ -111,6 +111,44 @@
<flags>IEEE80211_CHAN_HT40</flags>
</band>
</netband>
+ <netband mode="11ac">
+ <band>
+ <freqband ref="AC1_5180_5240_20"/>
+ <maxpower>17</maxpower>
+ <flags>IEEE80211_CHAN_HT20</flags>
+ <flags>IEEE80211_CHAN_VHT20</flags>
+ </band>
+ <band>
+ <freqband ref="AC1_5180_5240_40"/>
+ <maxpower>17</maxpower>
+ <flags>IEEE80211_CHAN_HT40</flags>
+ <flags>IEEE80211_CHAN_VHT40</flags>
+ </band>
+ <band>
+ <freqband ref="AC1_5180_5240_80"/>
+ <maxpower>17</maxpower>
+ <flags>IEEE80211_CHAN_HT40</flags>
+ <flags>IEEE80211_CHAN_VHT80</flags>
+ </band>
+ <band>
+ <freqband ref="AC1_5745_5805_20"/>
+ <maxpower>17</maxpower>
+ <flags>IEEE80211_CHAN_HT20</flags>
+ <flags>IEEE80211_CHAN_VHT20</flags>
+ </band>
+ <band>
+ <freqband ref="AC1_5745_5805_40"/>
+ <maxpower>17</maxpower>
+ <flags>IEEE80211_CHAN_HT40</flags>
+ <flags>IEEE80211_CHAN_VHT40</flags>
+ </band>
+ <band>
+ <freqband ref="AC1_5745_5805_80"/>
+ <maxpower>17</maxpower>
+ <flags>IEEE80211_CHAN_HT40</flags>
+ <flags>IEEE80211_CHAN_VHT80</flags>
+ </band>
+ </netband>
</rd>
<!-- FCC3 is FCC w/ DFS on Upper-UNI -->
@@ -1735,6 +1773,21 @@
<chanwidth>20</chanwidth> <chansep>20</chansep>
<flags>IEEE80211_CHAN_A</flags>
</freqband>
+<freqband id="AC1_5180_5240_20">
+ <freqstart>5180</freqstart> <freqend>5240</freqend>
+ <chanwidth>20</chanwidth> <chansep>20</chansep>
+ <flags>IEEE80211_CHAN_A</flags>
+</freqband>
+<freqband id="AC1_5180_5240_40">
+ <freqstart>5180</freqstart> <freqend>5240</freqend>
+ <chanwidth>40</chanwidth> <chansep>20</chansep>
+ <flags>IEEE80211_CHAN_A</flags>
+</freqband>
+<freqband id="AC1_5180_5240_80">
+ <freqstart>5180</freqstart> <freqend>5240</freqend>
+ <chanwidth>80</chanwidth> <chansep>20</chansep>
+ <flags>IEEE80211_CHAN_A</flags>
+</freqband>
<freqband id="H4_5180_5240">
<freqstart>5180</freqstart> <freqend>5240</freqend>
<chanwidth>40</chanwidth> <chansep>20</chansep>
@@ -1825,6 +1878,21 @@
<chanwidth>20</chanwidth> <chansep>20</chansep>
<flags>IEEE80211_CHAN_A</flags>
</freqband>
+<freqband id="AC1_5745_5805_20">
+ <freqstart>5745</freqstart> <freqend>5805</freqend>
+ <chanwidth>20</chanwidth> <chansep>20</chansep>
+ <flags>IEEE80211_CHAN_A</flags>
+</freqband>
+<freqband id="AC1_5745_5805_40">
+ <freqstart>5745</freqstart> <freqend>5805</freqend>
+ <chanwidth>40</chanwidth> <chansep>20</chansep>
+ <flags>IEEE80211_CHAN_A</flags>
+</freqband>
+<freqband id="AC1_5745_5805_80">
+ <freqstart>5745</freqstart> <freqend>5805</freqend>
+ <chanwidth>80</chanwidth> <chansep>20</chansep>
+ <flags>IEEE80211_CHAN_A</flags>
+</freqband>
<freqband id="H4_5745_5805">
<freqstart>5745</freqstart> <freqend>5805</freqend>
<chanwidth>40</chanwidth> <chansep>20</chansep>
diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c
index dcb91e0441da..d7794be320e5 100644
--- a/sbin/ifconfig/ifieee80211.c
+++ b/sbin/ifconfig/ifieee80211.c
@@ -125,6 +125,17 @@
#define IEEE80211_NODE_AMSDU_RX 0x040000 /* AMSDU rx enabled */
#define IEEE80211_NODE_AMSDU_TX 0x080000 /* AMSDU tx enabled */
#define IEEE80211_NODE_VHT 0x100000 /* VHT enabled */
+#define IEEE80211_NODE_LDPC 0x200000 /* LDPC enabled */
+#define IEEE80211_NODE_UAPSD 0x400000 /* UAPSD enabled */
+#endif
+
+/* XXX should also figure out where to put these for k/u-space sharing. */
+#ifndef IEEE80211_FVHT_VHT
+#define IEEE80211_FVHT_VHT 0x000000001 /* CONF: VHT supported */
+#define IEEE80211_FVHT_USEVHT40 0x000000002 /* CONF: Use VHT40 */
+#define IEEE80211_FVHT_USEVHT80 0x000000004 /* CONF: Use VHT80 */
+#define IEEE80211_FVHT_USEVHT160 0x000000008 /* CONF: Use VHT160 */
+#define IEEE80211_FVHT_USEVHT80P80 0x000000010 /* CONF: Use VHT 80+80 */
#endif
#define MAXCHAN 1536 /* max 1.5K channels */
@@ -1804,6 +1815,12 @@ set80211ldpc(const char *val, int d, int s, const struct afswtch *rafp)
set80211(s, IEEE80211_IOC_LDPC, ldpc, 0, NULL);
}
+static void
+set80211uapsd(const char *val, int d, int s, const struct afswtch *rafp)
+{
+ set80211(s, IEEE80211_IOC_UAPSD, d, 0, NULL);
+}
+
static
DECL_CMD_FUNC(set80211ampdulimit, val, d)
{
@@ -2159,8 +2176,6 @@ regdomain_addchans(struct ieee80211req_chaninfo *ci,
/*
* VHT first - HT is a subset.
- *
- * XXX TODO: VHT80p80, VHT160 is not yet done.
*/
if (flags & IEEE80211_CHAN_VHT) {
if ((chanFlags & IEEE80211_CHAN_VHT20) &&
@@ -2184,7 +2199,20 @@ regdomain_addchans(struct ieee80211req_chaninfo *ci,
"VHT80 channel\n", freq);
continue;
}
-
+ if ((chanFlags & IEEE80211_CHAN_VHT160) &&
+ (flags & IEEE80211_CHAN_VHT160) == 0) {
+ if (verbose)
+ printf("%u: skip, not a "
+ "VHT160 channel\n", freq);
+ continue;
+ }
+ if ((chanFlags & IEEE80211_CHAN_VHT80P80) &&
+ (flags & IEEE80211_CHAN_VHT80P80) == 0) {
+ if (verbose)
+ printf("%u: skip, not a "
+ "VHT80+80 channel\n", freq);
+ continue;
+ }
flags &= ~IEEE80211_CHAN_VHT;
flags |= chanFlags & IEEE80211_CHAN_VHT;
}
@@ -2370,7 +2398,7 @@ regdomain_makechannels(
&dc->dc_chaninfo);
}
- /* XXX TODO: VHT80_80, VHT160 */
+ /* XXX TODO: VHT80P80, VHT160 */
}
if (!LIST_EMPTY(&rd->bands_11ng) && dc->dc_htcaps != 0) {
@@ -2631,6 +2659,10 @@ getflags(int flags)
*cp++ = 't';
if (flags & IEEE80211_NODE_AMSDU_RX)
*cp++ = 'r';
+ if (flags & IEEE80211_NODE_UAPSD)
+ *cp++ = 'U';
+ if (flags & IEEE80211_NODE_LDPC)
+ *cp++ = 'L';
*cp = '\0';
return flagstring;
}
@@ -3840,8 +3872,8 @@ list_stations(int s)
, "TXSEQ"
, "RXSEQ"
);
- else
- printf("%-17.17s %4s %4s %4s %4s %4s %6s %6s %4s %-7s\n"
+ else
+ printf("%-17.17s %4s %4s %4s %4s %4s %6s %6s %4s %-12s\n"
, "ADDR"
, "AID"
, "CHAN"
@@ -3875,8 +3907,8 @@ list_stations(int s)
, gettxseq(si)
, getrxseq(si)
);
- else
- printf("%s %4u %4d %3dM %4.1f %4d %6d %6d %-4.4s %-7.7s"
+ else
+ printf("%s %4u %4d %3dM %4.1f %4d %6d %6d %-4.4s %-12.12s"
, ether_ntoa((const struct ether_addr*)
si->isi_macaddr)
, IEEE80211_AID(si->isi_associd)
@@ -3937,8 +3969,11 @@ get_chaninfo(const struct ieee80211_channel *c, int precise,
if (IEEE80211_IS_CHAN_TURBO(c))
strlcat(buf, " Turbo", bsize);
if (precise) {
- /* XXX should make VHT80U, VHT80D */
- if (IEEE80211_IS_CHAN_VHT80(c) &&
+ if (IEEE80211_IS_CHAN_VHT80P80(c))
+ strlcat(buf, " vht/80p80", bsize);
+ else if (IEEE80211_IS_CHAN_VHT160(c))
+ strlcat(buf, " vht/160", bsize);
+ else if (IEEE80211_IS_CHAN_VHT80(c) &&
IEEE80211_IS_CHAN_HT40D(c))
strlcat(buf, " vht/80-", bsize);
else if (IEEE80211_IS_CHAN_VHT80(c) &&
@@ -3992,10 +4027,11 @@ print_chaninfo(const struct ieee80211_channel *c, int verb)
static int
chanpref(const struct ieee80211_channel *c)
{
+
+ if (IEEE80211_IS_CHAN_VHT80P80(c))
+ return 90;
if (IEEE80211_IS_CHAN_VHT160(c))
return 80;
- if (IEEE80211_IS_CHAN_VHT80_80(c))
- return 75;
if (IEEE80211_IS_CHAN_VHT80(c))
return 70;
if (IEEE80211_IS_CHAN_VHT40(c))
@@ -4767,6 +4803,23 @@ getid(int s, int ix, void *data, size_t len, int *plen, int mesh)
return 0;
}
+static int
+getdevicename(int s, void *data, size_t len, int *plen)
+{
+ struct ieee80211req ireq;
+
+ (void) memset(&ireq, 0, sizeof(ireq));
+ (void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name));
+ ireq.i_type = IEEE80211_IOC_IC_NAME;
+ ireq.i_val = -1;
+ ireq.i_data = data;
+ ireq.i_len = len;
+ if (ioctl(s, SIOCG80211, &ireq) < 0)
+ return (-1);
+ *plen = ireq.i_len;
+ return (0);
+}
+
static void
ieee80211_status(int s)
{
@@ -5288,30 +5341,40 @@ end:
break;
}
}
+ if (get80211val(s, IEEE80211_IOC_UAPSD, &val) != -1) {
+ switch (val) {
+ case 0:
+ LINE_CHECK("-uapsd");
+ break;
+ case 1:
+ LINE_CHECK("uapsd");
+ break;
+ }
+ }
}
if (IEEE80211_IS_CHAN_VHT(c) || verbose) {
getvhtconf(s);
- if (vhtconf & 0x1)
+ if (vhtconf & IEEE80211_FVHT_VHT)
LINE_CHECK("vht");
else
LINE_CHECK("-vht");
- if (vhtconf & 0x2)
+ if (vhtconf & IEEE80211_FVHT_USEVHT40)
LINE_CHECK("vht40");
else
LINE_CHECK("-vht40");
- if (vhtconf & 0x4)
+ if (vhtconf & IEEE80211_FVHT_USEVHT80)
LINE_CHECK("vht80");
else
LINE_CHECK("-vht80");
- if (vhtconf & 0x8)
- LINE_CHECK("vht80p80");
- else
- LINE_CHECK("-vht80p80");
- if (vhtconf & 0x10)
+ if (vhtconf & IEEE80211_FVHT_USEVHT160)
LINE_CHECK("vht160");
else
LINE_CHECK("-vht160");
+ if (vhtconf & IEEE80211_FVHT_USEVHT80P80)
+ LINE_CHECK("vht80p80");
+ else
+ LINE_CHECK("-vht80p80");
}
if (get80211val(s, IEEE80211_IOC_WME, &wme) != -1) {
@@ -5481,6 +5544,12 @@ end:
}
LINE_BREAK();
+
+ if (getdevicename(s, data, sizeof(data), &len) < 0)
+ return;
+ LINE_CHECK("parent interface: %s", data);
+
+ LINE_BREAK();
}
static int
@@ -5872,6 +5941,8 @@ static struct cmd ieee80211_cmds[] = {
DEF_CMD("-ldpctx", -1, set80211ldpc),
DEF_CMD("ldpc", 3, set80211ldpc), /* NB: tx+rx */
DEF_CMD("-ldpc", -3, set80211ldpc),
+ DEF_CMD("uapsd", 1, set80211uapsd),
+ DEF_CMD("-uapsd", 0, set80211uapsd),
DEF_CMD("puren", 1, set80211puren),
DEF_CMD("-puren", 0, set80211puren),
DEF_CMD("doth", 1, set80211doth),
@@ -5904,16 +5975,16 @@ static struct cmd ieee80211_cmds[] = {
DEF_CMD("-ht40", 0, set80211htconf),
DEF_CMD("ht", 3, set80211htconf), /* NB: 20+40 */
DEF_CMD("-ht", 0, set80211htconf),
- DEF_CMD("vht", 1, set80211vhtconf),
- DEF_CMD("-vht", 0, set80211vhtconf),
- DEF_CMD("vht40", 2, set80211vhtconf),
- DEF_CMD("-vht40", -2, set80211vhtconf),
- DEF_CMD("vht80", 4, set80211vhtconf),
- DEF_CMD("-vht80", -4, set80211vhtconf),
- DEF_CMD("vht80p80", 8, set80211vhtconf),
- DEF_CMD("-vht80p80", -8, set80211vhtconf),
- DEF_CMD("vht160", 16, set80211vhtconf),
- DEF_CMD("-vht160", -16, set80211vhtconf),
+ DEF_CMD("vht", IEEE80211_FVHT_VHT, set80211vhtconf),
+ DEF_CMD("-vht", 0, set80211vhtconf),
+ DEF_CMD("vht40", IEEE80211_FVHT_USEVHT40, set80211vhtconf),
+ DEF_CMD("-vht40", -IEEE80211_FVHT_USEVHT40, set80211vhtconf),
+ DEF_CMD("vht80", IEEE80211_FVHT_USEVHT80, set80211vhtconf),
+ DEF_CMD("-vht80", -IEEE80211_FVHT_USEVHT80, set80211vhtconf),
+ DEF_CMD("vht160", IEEE80211_FVHT_USEVHT160, set80211vhtconf),
+ DEF_CMD("-vht160", -IEEE80211_FVHT_USEVHT160, set80211vhtconf),
+ DEF_CMD("vht80p80", IEEE80211_FVHT_USEVHT80P80, set80211vhtconf),
+ DEF_CMD("-vht80p80", -IEEE80211_FVHT_USEVHT80P80, set80211vhtconf),
DEF_CMD("rifs", 1, set80211rifs),
DEF_CMD("-rifs", 0, set80211rifs),
DEF_CMD("smps", IEEE80211_HTCAP_SMPS_ENA, set80211smps),
diff --git a/share/man/man4/ath.4 b/share/man/man4/ath.4
index acd83a86d3ff..fb88c31569a2 100644
--- a/share/man/man4/ath.4
+++ b/share/man/man4/ath.4
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"/
-.Dd April 14, 2014
+.Dd June 16, 2020
.Dt ATH 4
.Os
.Sh NAME
@@ -60,10 +60,10 @@ The
driver provides support for wireless network adapters based on
the Atheros AR5210, AR5211, AR5212, AR5416 and AR9300 programming APIs.
These APIs are used by a wide variety of chips; most all chips with
-a PCI and/or CardBus interface are supported.
+a PCI, PCIe and/or CardBus interface are supported.
.Pp
Supported features include 802.11 and 802.3 frames, power management, BSS,
-IBSS, MBSS, TDMA, and host-based access point operation modes.
+IBSS, MBSS, WDS/DWDS TDMA, and host-based access point operation modes.
All host/device interaction is via DMA.
.Pp
Please note that from FreeBSD-9.0, the
@@ -148,12 +148,13 @@ For more information on configuring this device, see
.Pp
Devices supported by the
.Nm
-driver come in either Cardbus or mini-PCI packages.
-Wireless cards in Cardbus slots may be inserted and ejected on the fly.
+driver come in Cardbus, ExpressCard, Mini-PCI and Mini-PCIe packages.
+Wireless cards in Cardbus and ExpressCard slots may be inserted and
+ejected on the fly.
.Sh HARDWARE
The
.Nm
-driver supports all Atheros Cardbus and PCI cards,
+driver supports all Atheros Cardbus, ExpressCard, PCI and PCIe cards,
except those that are based on the AR5005VL chipset.
.Sh EXAMPLES
Join a specific BSS network with WEP encryption:
@@ -293,8 +294,7 @@ device driver first appeared in
Revision A1 of the D-LINK DWL-G520 and DWL-G650 are based on an
Intersil PrismGT chip and are not supported by this driver.
.Sh BUGS
-The driver does not fully enable power-save operation of the chip
-in station mode; consequently power use is suboptimal (e.g. on a laptop).
+The driver does supports optional station mode power-save operation.
.Pp
The AR5210 can only do WEP in hardware; consequently hardware assisted WEP
is disabled in order to allow software implementations of TKIP and CCMP to
diff --git a/share/man/man4/net80211.4 b/share/man/man4/net80211.4
index 650bbf48272a..629e84c35566 100644
--- a/share/man/man4/net80211.4
+++ b/share/man/man4/net80211.4
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 10, 2009
+.Dd August 7, 2020
.Dt NET80211 4
.Os
.Sh NAME
@@ -393,6 +393,16 @@ Valid values are:
and
.Dv IEEE80211_HWMP_ROOTMODE_RANN
(send broadcast Root Announcement (RANN) frames).
+.It Dv IEEE80211_IOC_IC_NAME
+Return the underlying hardware
+.Xr device 9
+name in the buffer pointed to by
+.Va i_data
+and the name length including terminating NUL character in
+.Va i_len .
+If the buffer length is too small to hold the full name
+.Er EINVAL
+will be returned.
.It Dv IEEE80211_IOC_INACTIVITY
Return whether or not the system handles inactivity processing in
.Va i_val .
diff --git a/share/man/man4/run.4 b/share/man/man4/run.4
index 8e44dcfa4afd..b95a346f9697 100644
--- a/share/man/man4/run.4
+++ b/share/man/man4/run.4
@@ -16,7 +16,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 8, 2018
+.Dd June 16, 2020
.Dt RUN 4
.Os
.Sh NAME
@@ -251,5 +251,5 @@ driver was written by
.Sh CAVEATS
The
.Nm
-driver does not support any of the 802.11n capabilities offered by the
+driver supports some of the 11n capabilities found in the
RT2800, RT3000 and RT3900 chipsets.
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h
index 00807ac430ee..49e887353e52 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h
@@ -19,18 +19,14 @@
#include "ar9300_freebsd_inc.h"
-#define AH_BIG_ENDIAN 4321
-#define AH_LITTLE_ENDIAN 1234
-
-#if _BYTE_ORDER == _BIG_ENDIAN
-#define AH_BYTE_ORDER AH_BIG_ENDIAN
-#else
-#define AH_BYTE_ORDER AH_LITTLE_ENDIAN
-#endif
-
/* XXX doesn't belong here */
#define AR_EEPROM_MODAL_SPURS 5
+/* Ensure that AH_BYTE_ORDER is defined */
+#ifndef AH_BYTE_ORDER
+#error AH_BYTE_ORDER needs to be defined!
+#endif
+
/*
* (a) this should be N(a),
* (b) FreeBSD does define nitems,
@@ -43,10 +39,8 @@
#include "ah_devid.h"
#include "ar9300eep.h" /* For Eeprom definitions */
-
#define AR9300_MAGIC 0x19741014
-
/* MAC register values */
#define INIT_CONFIG_STATUS 0x00000000
@@ -1396,7 +1390,7 @@ extern void ar9300_wowoffload_download_ns_info(struct ath_hal *ah, u_int32_t id
extern HAL_BOOL ar9300_reset(struct ath_hal *ah, HAL_OPMODE opmode,
struct ieee80211_channel *chan, HAL_HT_MACMODE macmode, u_int8_t txchainmask,
u_int8_t rxchainmask, HAL_HT_EXTPROTSPACING extprotspacing,
- HAL_BOOL b_channel_change, HAL_STATUS *status, int is_scan);
+ HAL_BOOL b_channel_change, HAL_STATUS *status, HAL_RESET_TYPE reset_type, int is_scan);
extern HAL_BOOL ar9300_lean_channel_change(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan,
HAL_HT_MACMODE macmode, u_int8_t txchainmask, u_int8_t rxchainmask);
extern HAL_BOOL ar9300_set_reset_reg(struct ath_hal *ah, u_int32_t type);
@@ -1406,7 +1400,7 @@ extern u_int16_t ar9300_is_single_ant_power_save_possible(struct ath_hal *ah);
extern void ar9300_set_operating_mode(struct ath_hal *ah, int opmode);
extern HAL_BOOL ar9300_phy_disable(struct ath_hal *ah);
extern HAL_BOOL ar9300_disable(struct ath_hal *ah);
-extern HAL_BOOL ar9300_chip_reset(struct ath_hal *ah, struct ieee80211_channel *);
+extern HAL_BOOL ar9300_chip_reset(struct ath_hal *ah, struct ieee80211_channel *, HAL_RESET_TYPE type);
extern HAL_BOOL ar9300_calibration(struct ath_hal *ah, struct ieee80211_channel *chan,
u_int8_t rxchainmask, HAL_BOOL longcal, HAL_BOOL *isIQdone, int is_scan, u_int32_t *sched_cals);
extern void ar9300_reset_cal_valid(struct ath_hal *ah,
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c
index ff22fb800064..dfa0cf619f8a 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c
@@ -462,13 +462,55 @@ ar9300_ani_control(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
u_int level = param;
u_int is_on;
+ HALDEBUG(ah, HAL_DEBUG_ANI, "%s: cmd=%d, param=%d, chan=%p, funcmask=0x%08x\n",
+ __func__,
+ cmd,
+ param,
+ chan,
+ ahp->ah_ani_function);
+
+
if (chan == NULL && cmd != HAL_ANI_MODE) {
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
"%s: ignoring cmd 0x%02x - no channel\n", __func__, cmd);
return AH_FALSE;
}
- switch (cmd & ahp->ah_ani_function) {
+ /*
+ * These two control the top-level cck/ofdm immunity levels and will
+ * program the rest of the values.
+ */
+ if (cmd == HAL_ANI_NOISE_IMMUNITY_LEVEL) {
+ if (param > HAL_ANI_OFDM_NUM_LEVEL)
+ return AH_FALSE;
+ ar9300_ani_set_odfm_noise_immunity_level(ah, param);
+ return AH_TRUE;
+ }
+
+ if (cmd == HAL_ANI_CCK_NOISE_IMMUNITY_LEVEL) {
+ if (param > HAL_ANI_CCK_NUM_LEVEL)
+ return AH_FALSE;
+ ar9300_ani_set_cck_noise_immunity_level(ah, param);
+ return AH_TRUE;
+ }
+
+ /*
+ * Check to see if this command is available in the
+ * current operating mode.
+ */
+ if (((1 << cmd) & ahp->ah_ani_function) == 0) {
+ HALDEBUG(ah, HAL_DEBUG_ANI,
+ "%s: early check: invalid cmd 0x%02x (allowed=0x%02x)\n",
+ __func__, cmd, ahp->ah_ani_function);
+ return AH_FALSE;
+ }
+
+ /*
+ * The rest of these program in the requested parameter values
+ * into the PHY.
+ */
+ switch (cmd) {
+
case HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION:
{
int m1_thresh_low, m2_thresh_low;
@@ -887,13 +929,16 @@ ar9300_ani_reset(struct ath_hal *ah, HAL_BOOL is_scanning)
/* only allow a subset of functions in AP mode */
if (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) {
if (IS_CHAN_2GHZ(ichan)) {
- ahp->ah_ani_function = (HAL_ANI_SPUR_IMMUNITY_LEVEL |
- HAL_ANI_FIRSTEP_LEVEL |
- HAL_ANI_MRC_CCK);
+ ahp->ah_ani_function = (1 << HAL_ANI_SPUR_IMMUNITY_LEVEL) |
+ (1 << HAL_ANI_FIRSTEP_LEVEL) |
+ (1 << HAL_ANI_MRC_CCK);
} else {
ahp->ah_ani_function = 0;
}
+ } else {
+ ahp->ah_ani_function = HAL_ANI_ALL;
}
+
/* always allow mode (on/off) to be controlled */
ahp->ah_ani_function |= HAL_ANI_MODE;
@@ -1172,6 +1217,7 @@ ar9300_ani_ar_poll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
cck_phy_err_cnt = OS_REG_READ(ah, AR_PHY_ERR_2);
/* Populate HAL_ANISTATS */
+ /* XXX TODO: are these correct? */
if (ani_stats) {
ani_stats->cckphyerr_cnt =
cck_phy_err_cnt - ani_state->cck_phy_err_count;
@@ -1212,18 +1258,32 @@ ar9300_ani_ar_poll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
return;
}
+ /*
+ * Calculate the OFDM/CCK phy error rate over the listen time interval.
+ * This is used in subsequent math to see if the OFDM/CCK phy error rate
+ * is above or below the threshold checks.
+ */
+
ofdm_phy_err_rate =
ani_state->ofdm_phy_err_count * 1000 / ani_state->listen_time;
cck_phy_err_rate =
ani_state->cck_phy_err_count * 1000 / ani_state->listen_time;
HALDEBUG(ah, HAL_DEBUG_ANI,
- "%s: listen_time=%d OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n",
+ "%s: listen_time=%d (total: %d) OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n",
__func__, listen_time,
+ ani_state->listen_time,
ani_state->ofdm_noise_immunity_level, ofdm_phy_err_rate,
ani_state->cck_noise_immunity_level, cck_phy_err_rate,
ani_state->ofdms_turn);
+ /*
+ * Check for temporary noise spurs. This is intended to be used by
+ * rate control to check if we should try higher packet rates or not.
+ * If the noise period is short enough then we shouldn't avoid trying
+ * higher rates but if the noise is high/sustained then it's likely
+ * not a great idea to try the higher MCS rates.
+ */
if (ani_state->listen_time >= HAL_NOISE_DETECT_PERIOD) {
old_phy_noise_spur = ani_state->phy_noise_spur;
if (ofdm_phy_err_rate <= ani_state->ofdm_trig_low &&
@@ -1236,7 +1296,7 @@ ar9300_ani_ar_poll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
}
if (old_phy_noise_spur != ani_state->phy_noise_spur) {
HALDEBUG(ah, HAL_DEBUG_ANI,
- "%s: enviroment change from %d to %d\n",
+ "%s: environment change from %d to %d\n",
__func__, old_phy_noise_spur, ani_state->phy_noise_spur);
}
}
@@ -1259,6 +1319,10 @@ ar9300_ani_ar_poll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
ar9300_ani_lower_immunity(ah);
ani_state->ofdms_turn = !ani_state->ofdms_turn;
}
+ /*
+ * Force an ANI restart regardless of whether the lower immunity
+ * level was met.
+ */
HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: 1 listen_time=%d ofdm=%d/s cck=%d/s - "
"calling ar9300_ani_restart\n",
@@ -1292,6 +1356,13 @@ ar9300_ani_ar_poll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
ani_state->ofdms_turn = AH_TRUE;
}
}
+
+ /*
+ * Note that currently this poll function doesn't reset the listen
+ * time after it accumulates a second worth of error samples.
+ * It will continue to accumulate samples until a counter overflows,
+ * or a raise threshold is met, or 5 seconds passes.
+ */
}
/*
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c
index 063075e397d0..0251222c50b4 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c
@@ -3040,6 +3040,33 @@ ar9300_eeprom_set_transmit_power(struct ath_hal *ah,
ahp->reg_dmn = ath_hal_getctl(ah, chan);
/*
+ * After reading FCC/OET 13TR1003 (Directional Gain of IEEE 802.11
+ * MIMO devices employing cyclic delay diversity) and looking at what
+ * ath9k does, let's disable the CDD check until it's clearer exactly
+ * how the maximum cap should be applied here.
+ *
+ * Right now the CDD check is simply unconditionally reducing the
+ * gain of legacy and 1/2 stream rates depending upon the chainmask.
+ * (CDD is used when transmitting rates that don't already use up the
+ * full set of streams - eg OFDM or MCS0-7 on a 2 or 3 chain TX path.)
+ *
+ * It's dropping the 2-chain TX by 3dB and 3-chain by 5dB to "meet"
+ * power spectral density requirements but it's not currently taking
+ * into account how close to the regulatory limit the hardware/antenna
+ * system is already at. It doesn't help that the conductive testing
+ * limits have the array gain at 0dB for all AR9300/derivative
+ * configurations.
+ *
+ * It also doesn't let us do single chain transmit at the full allowed
+ * power for the regulatory/CTL limits as it subtracts it from what's
+ * programmed into the hardware.
+ *
+ * ath9k doesn't factor any of the CDD stuff into account, so I'm going
+ * to disable it here and in the TPC path until I get a better idea
+ * of what to really do here.
+ */
+#if 0
+ /*
* Always use CDD/direct per rate power table for register based approach.
* For FCC, CDD calculations should factor in the array gain, hence
* this adjust call. ETSI and MKK does not have this requirement.
@@ -3050,6 +3077,7 @@ ar9300_eeprom_set_transmit_power(struct ath_hal *ah,
__func__);
ar9300_adjust_reg_txpower_cdd(ah, target_power_val_t2);
}
+#endif
if (ar9300_eeprom_get(ahp, EEP_PAPRD_ENABLED)) {
for (i = 0; i < ar9300_rate_size; i++) {
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
index e066ff280231..37e64bc86cdd 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
@@ -355,7 +355,7 @@ ar9300_attach_freebsd_ops(struct ath_hal *ah)
ah->ah_setRxDP = ar9300_set_rx_dp;
ah->ah_enableReceive = ar9300_enable_receive;
ah->ah_stopDmaReceive = ar9300_stop_dma_receive_freebsd;
- ah->ah_startPcuReceive = ar9300_start_pcu_receive_freebsd;
+ ah->ah_startPcuReceive = ar9300_start_pcu_receive;
ah->ah_stopPcuReceive = ar9300_stop_pcu_receive;
ah->ah_setMulticastFilter = ar9300_set_multicast_filter;
ah->ah_setMulticastFilterIndex = ar9300SetMulticastFilterIndex;
@@ -543,6 +543,7 @@ ar9300_reset_freebsd(struct ath_hal *ah, HAL_OPMODE opmode,
HAL_HT_EXTPROTSPACING_20, /* always 20Mhz channel spacing */
bChannelChange,
status,
+ resetType,
AH_FALSE); /* XXX should really extend ath_hal_reset() */
return (r);
@@ -679,14 +680,6 @@ ar9300_reset_cal_valid_freebsd(struct ath_hal *ah,
}
-void
-ar9300_start_pcu_receive_freebsd(struct ath_hal *ah)
-{
-
- /* is_scanning flag == NULL */
- ar9300_start_pcu_receive(ah, AH_FALSE);
-}
-
/*
* FreeBSD will just pass in the descriptor value as 'pa'.
* The Atheros HAL treats 'pa' as the physical address of the RX
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c
index 6e49325cdac3..1793cf06378b 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c
@@ -1263,15 +1263,13 @@ ar9300_get_diag_state(struct ath_hal *ah, int request,
if (ani == AH_NULL)
return AH_FALSE;
/* Convert ar9300 HAL to FreeBSD HAL ANI state */
- /* XXX TODO: add all of these to the HAL ANI state structure */
bzero(&ahp->ext_ani_state, sizeof(ahp->ext_ani_state));
- /* XXX should this be OFDM or CCK noise immunity level? */
ahp->ext_ani_state.noiseImmunityLevel = ani->ofdm_noise_immunity_level;
ahp->ext_ani_state.spurImmunityLevel = ani->spur_immunity_level;
ahp->ext_ani_state.firstepLevel = ani->firstep_level;
ahp->ext_ani_state.ofdmWeakSigDetectOff = ani->ofdm_weak_sig_detect_off;
- /* mrc_cck_off */
- /* cck_noise_immunity_level */
+ ahp->ext_ani_state.mrcCck = !! ani->mrc_cck_off;
+ ahp->ext_ani_state.cckNoiseImmunityLevel = ani->cck_noise_immunity_level;
ahp->ext_ani_state.listenTime = ani->listen_time;
@@ -1289,12 +1287,18 @@ ar9300_get_diag_state(struct ath_hal *ah, int request,
0 : sizeof(HAL_ANI_STATS);
return AH_TRUE;
case HAL_DIAG_ANI_CMD:
+ {
+ HAL_ANI_CMD savefunc = ahp->ah_ani_function;
if (argsize != 2*sizeof(u_int32_t)) {
return AH_FALSE;
}
+ /* temporarly allow all functions so we can override */
+ ahp->ah_ani_function = HAL_ANI_ALL;
ar9300_ani_control(
ah, ((const u_int32_t *)args)[0], ((const u_int32_t *)args)[1]);
+ ahp->ah_ani_function = savefunc;
return AH_TRUE;
+ }
#if 0
case HAL_DIAG_TXCONT:
/*AR9300_CONTTXMODE(ah, (struct ath_desc *)args, argsize );*/
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_phy.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_phy.c
index 24622e732cbd..5bf342e43624 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_phy.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_phy.c
@@ -55,10 +55,12 @@ static inline void ar9300_init_rate_txpower_stbc(struct ath_hal *ah,
const HAL_RATE_TABLE *rt, HAL_BOOL is40,
int rt_ss_offset, int rt_ds_offset,
int rt_ts_offset, u_int8_t chainmask);
+#if 0
static inline void ar9300_adjust_rate_txpower_cdd(struct ath_hal *ah,
const HAL_RATE_TABLE *rt, HAL_BOOL is40,
int rt_ss_offset, int rt_ds_offset,
int rt_ts_offset, u_int8_t chainmask);
+#endif
#define AR9300_11A_RT_OFDM_OFFSET 0
HAL_RATE_TABLE ar9300_11a_table = {
@@ -442,6 +444,8 @@ ar9300_adjust_reg_txpower_cdd(struct ath_hal *ah,
((int16_t)AH_MIN((ahp->twice_antenna_reduction -
(ahp->twice_antenna_gain + AR9300_TXBF_2TX_ARRAY_GAIN)), 0));
cdd_power = ahp->upper_limit[1] + twice_array_gain;
+
+ HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: 2 chain; cdd_power=%d", __func__, cdd_power);
/* Adjust OFDM legacy rates as well */
for (i = ALL_TARGET_LEGACY_6_24; i <= ALL_TARGET_LEGACY_54; i++) {
if (power_per_rate[i] > cdd_power) {
@@ -471,6 +475,7 @@ ar9300_adjust_reg_txpower_cdd(struct ath_hal *ah,
((int16_t)AH_MIN((ahp->twice_antenna_reduction -
(ahp->twice_antenna_gain + AR9300_TXBF_3TX_ARRAY_GAIN)), 0));
cdd_power = ahp->upper_limit[2] + twice_array_gain;
+ HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: 3 chain; cdd_power=%d", __func__, cdd_power);
/* Adjust OFDM legacy rates as well */
for (i = ALL_TARGET_LEGACY_6_24; i <= ALL_TARGET_LEGACY_54; i++) {
if (power_per_rate[i] > cdd_power) {
@@ -531,6 +536,7 @@ ar9300_init_rate_txpower(struct ath_hal *ah, u_int mode,
AR9300_11NA_RT_HT_SS_OFFSET,
AR9300_11NA_RT_HT_DS_OFFSET,
AR9300_11NA_RT_HT_TS_OFFSET, chainmask);
+#if 0
/* For FCC the array gain has to be factored for CDD mode */
if (is_reg_dmn_fcc(ath_hal_getctl(ah, chan))) {
ar9300_adjust_rate_txpower_cdd(ah, rt, is40,
@@ -538,6 +544,7 @@ ar9300_init_rate_txpower(struct ath_hal *ah, u_int mode,
AR9300_11NA_RT_HT_DS_OFFSET,
AR9300_11NA_RT_HT_TS_OFFSET, chainmask);
}
+#endif
break;
case HAL_MODE_11G:
ar9300_init_rate_txpower_cck(ah, rt, power_per_rate, chainmask);
@@ -561,6 +568,7 @@ ar9300_init_rate_txpower(struct ath_hal *ah, u_int mode,
AR9300_11NG_RT_HT_SS_OFFSET,
AR9300_11NG_RT_HT_DS_OFFSET,
AR9300_11NG_RT_HT_TS_OFFSET, chainmask);
+#if 0
/* For FCC the array gain needs to be factored for CDD mode */
if (is_reg_dmn_fcc(ath_hal_getctl(ah, chan))) {
ar9300_adjust_rate_txpower_cdd(ah, rt, is40,
@@ -568,6 +576,7 @@ ar9300_init_rate_txpower(struct ath_hal *ah, u_int mode,
AR9300_11NG_RT_HT_DS_OFFSET,
AR9300_11NG_RT_HT_TS_OFFSET, chainmask);
}
+#endif
break;
default:
HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, "%s: invalid mode 0x%x\n",
@@ -941,6 +950,10 @@ ar9300_init_rate_txpower_stbc(struct ath_hal *ah, const HAL_RATE_TABLE *rt,
return;
}
+/*
+ * To see why this is disabled, look at ar9300_eeprom.c for FCC/OET 13TR1003.
+ */
+#if 0
static inline void
ar9300_adjust_rate_txpower_cdd(struct ath_hal *ah, const HAL_RATE_TABLE *rt,
HAL_BOOL is40,
@@ -1037,6 +1050,7 @@ ar9300_adjust_rate_txpower_cdd(struct ath_hal *ah, const HAL_RATE_TABLE *rt,
return;
}
+#endif
void ar9300_disp_tpc_tables(struct ath_hal *ah)
{
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c
index 40cdbdd173f2..2b4374d237bd 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c
@@ -2064,7 +2064,7 @@ ar9300_set_rf_mode(struct ath_hal *ah, struct ieee80211_channel *chan)
* Places the hardware into reset and then pulls it out of reset
*/
HAL_BOOL
-ar9300_chip_reset(struct ath_hal *ah, struct ieee80211_channel *chan)
+ar9300_chip_reset(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_RESET_TYPE reset_type)
{
struct ath_hal_9300 *ahp = AH9300(ah);
int type = HAL_RESET_WARM;
@@ -2080,8 +2080,13 @@ ar9300_chip_reset(struct ath_hal *ah, struct ieee80211_channel *chan)
*/
if (ahp->ah_chip_full_sleep ||
(ah->ah_config.ah_force_full_reset == 1) ||
+ (reset_type == HAL_RESET_FORCE_COLD) ||
+ (reset_type == HAL_RESET_BBPANIC) ||
OS_REG_READ(ah, AR_Q_TXE) ||
(OS_REG_READ(ah, AR_CR) & AR_CR_RXE)) {
+ HALDEBUG(ah, HAL_DEBUG_RESET,
+ "%s: full reset; reset_type=%d, full_sleep=%d\n",
+ __func__, reset_type, ahp->ah_chip_full_sleep);
type = HAL_RESET_COLD;
}
@@ -4510,7 +4515,7 @@ HAL_BOOL
ar9300_reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan,
HAL_HT_MACMODE macmode, u_int8_t txchainmask, u_int8_t rxchainmask,
HAL_HT_EXTPROTSPACING extprotspacing, HAL_BOOL b_channel_change,
- HAL_STATUS *status, int is_scan)
+ HAL_STATUS *status, HAL_RESET_TYPE reset_type, int is_scan)
{
#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
u_int32_t save_led_state;
@@ -4864,7 +4869,7 @@ ar9300_reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *ch
/* Mark PHY inactive prior to reset, to be undone in ar9300_init_bb () */
ar9300_mark_phy_inactive(ah);
- if (!ar9300_chip_reset(ah, chan)) {
+ if (!ar9300_chip_reset(ah, chan, reset_type)) {
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: chip reset failed\n", __func__);
FAIL(HAL_EIO);
}
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.c
index 7fe4374a3456..8b587f941084 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.c
@@ -691,7 +691,7 @@ ar9300_Stub_StopDmaReceive(struct ath_hal *ah)
}
void
-ar9300_Stub_StartPcuReceive(struct ath_hal *ah)
+ar9300_Stub_StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning)
{
ath_hal_printf(ah, "%s: called\n", __func__);
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.h
index 82397f9fcb1a..f4dab5cbe55c 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.h
@@ -112,7 +112,7 @@ extern void ar9300_Stub_SetRxDP(struct ath_hal *ah, uint32_t rxdp,
HAL_RX_QUEUE);
extern void ar9300_Stub_EnableReceive(struct ath_hal *ah);
extern HAL_BOOL ar9300_Stub_StopDmaReceive(struct ath_hal *ah);
-extern void ar9300_Stub_StartPcuReceive(struct ath_hal *ah);
+extern void ar9300_Stub_StartPcuReceive(struct ath_hal *ah, HAL_BOOL);
extern void ar9300_Stub_StopPcuReceive(struct ath_hal *ah);
extern void ar9300_Stub_SetMulticastFilter(struct ath_hal *ah,
uint32_t filter0, uint32_t filter1);
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300eep.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300eep.h
index 516303033835..9230fd57e2e4 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300eep.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300eep.h
@@ -18,13 +18,17 @@
#define _ATH_AR9300_EEP_H_
#include "opt_ah.h"
-
#include "ah.h"
#if defined(WIN32) || defined(WIN64)
#pragma pack (push, ar9300, 1)
#endif
+/* Ensure that AH_BYTE_ORDER is defined */
+#ifndef AH_BYTE_ORDER
+#error AH_BYTE_ORDER needs to be defined!
+#endif
+
/* FreeBSD extras - should be in ah_eeprom.h ? */
#define AR_EEPROM_EEPCAP_COMPRESS_DIS 0x0001
#define AR_EEPROM_EEPCAP_AES_DIS 0x0002
@@ -345,11 +349,13 @@ typedef struct CalCtlEdgePwr {
u_int8_t flag :2,
t_power :6;
} __packed CAL_CTL_EDGE_PWR;
-#else
+#elif AH_BYTE_ORDER == AH_LITTLE_ENDIAN
typedef struct CalCtlEdgePwr {
u_int8_t t_power :6,
flag :2;
} __packed CAL_CTL_EDGE_PWR;
+#else
+#error AH_BYTE_ORDER undefined!
#endif
typedef struct ospCalCtlData_5G {
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_ap121.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_ap121.h
index 6468445b8a82..fabed1cb8fe0 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_ap121.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_ap121.h
@@ -25,6 +25,11 @@
#ifndef __ar9300templateAP121_h__
#define __ar9300templateAP121_h__
+/* Ensure that AH_BYTE_ORDER is defined */
+#ifndef AH_BYTE_ORDER
+#error AH_BYTE_ORDER needs to be defined!
+#endif
+
static ar9300_eeprom_t ar9300_template_ap121=
{
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_aphrodite.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_aphrodite.h
index a9e5f3635976..0f756b81cd81 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_aphrodite.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_aphrodite.h
@@ -26,6 +26,11 @@
#ifndef __ar9300templateAphrodite_h__
#define __ar9300templateAphrodite_h__
+/* Ensure that AH_BYTE_ORDER is defined */
+#ifndef AH_BYTE_ORDER
+#error AH_BYTE_ORDER needs to be defined!
+#endif
+
static ar9300_eeprom_t ar9300_template_aphrodite=
{
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_cus157.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_cus157.h
index dc37977956ec..fab9558bf588 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_cus157.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_cus157.h
@@ -25,6 +25,11 @@
#ifndef __ar9300template_cus157_h__
#define __ar9300template_cus157_h__
+/* Ensure that AH_BYTE_ORDER is defined */
+#ifndef AH_BYTE_ORDER
+#error AH_BYTE_ORDER needs to be defined!
+#endif
+
static ar9300_eeprom_t Ar9300Template_cus157=
{
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_generic.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_generic.h
index 6b7a0d1bb8f4..08b30c215eaf 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_generic.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_generic.h
@@ -25,6 +25,11 @@
#ifndef __ar9300templateGeneric_h__
#define __ar9300templateGeneric_h__
+/* Ensure that AH_BYTE_ORDER is defined */
+#ifndef AH_BYTE_ORDER
+#error AH_BYTE_ORDER needs to be defined!
+#endif
+
static ar9300_eeprom_t ar9300_template_generic=
{
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_hb112.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_hb112.h
index c3bbc1d30203..674d8e430e94 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_hb112.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_hb112.h
@@ -25,6 +25,11 @@
#ifndef __ar9300templateHB112_h__
#define __ar9300templateHB112_h__
+/* Ensure that AH_BYTE_ORDER is defined */
+#ifndef AH_BYTE_ORDER
+#error AH_BYTE_ORDER needs to be defined!
+#endif
+
static ar9300_eeprom_t ar9300_template_hb112=
{
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_hb116.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_hb116.h
index c1de18ebbe0e..600955181bbc 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_hb116.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_hb116.h
@@ -26,6 +26,11 @@
#ifndef __ar9300templateHB116_h__
#define __ar9300templateHB116_h__
+/* Ensure that AH_BYTE_ORDER is defined */
+#ifndef AH_BYTE_ORDER
+#error AH_BYTE_ORDER needs to be defined!
+#endif
+
static ar9300_eeprom_t ar9300_template_hb116=
{
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_osprey_k31.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_osprey_k31.h
index b6b09e80985b..14fdaab18f2f 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_osprey_k31.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_osprey_k31.h
@@ -25,6 +25,11 @@
#ifndef __ar9300templateOsprey_k31_h__
#define __ar9300templateOsprey_k31_h__
+/* Ensure that AH_BYTE_ORDER is defined */
+#ifndef AH_BYTE_ORDER
+#error AH_BYTE_ORDER needs to be defined!
+#endif
+
static ar9300_eeprom_t ar9300_template_osprey_k31=
{
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_wasp_2.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_wasp_2.h
index 2eb165f3a72f..0e53dace2b9e 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_wasp_2.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_wasp_2.h
@@ -24,6 +24,12 @@
#ifndef __ar9300template_wasp_2_h__
#define __ar9300template_wasp_2_h__
+
+/* Ensure that AH_BYTE_ORDER is defined */
+#ifndef AH_BYTE_ORDER
+#error AH_BYTE_ORDER needs to be defined!
+#endif
+
static ar9300_eeprom_t ar9300_template_wasp_2=
{
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_xb112.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_xb112.h
index 864efbab8ce1..645ab78a7157 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_xb112.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_xb112.h
@@ -25,6 +25,11 @@
#ifndef __ar9300templateXB112_h__
#define __ar9300templateXB112_h__
+/* Ensure that AH_BYTE_ORDER is defined */
+#ifndef AH_BYTE_ORDER
+#error AH_BYTE_ORDER needs to be defined!
+#endif
+
static ar9300_eeprom_t ar9300_template_xb112=
{
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_xb113.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_xb113.h
index 7b715455a6cb..291b163be823 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_xb113.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300template_xb113.h
@@ -25,6 +25,11 @@
#ifndef __ar9300templateXB113_h__
#define __ar9300templateXB113_h__
+/* Ensure that AH_BYTE_ORDER is defined */
+#ifndef AH_BYTE_ORDER
+#error AH_BYTE_ORDER needs to be defined!
+#endif
+
static ar9300_eeprom_t ar9300_template_xb113=
{
diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c
index 70866f1d002b..bbe248a4457b 100644
--- a/sys/dev/an/if_an.c
+++ b/sys/dev/an/if_an.c
@@ -2320,7 +2320,7 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
}
break;
case SIOCS80211:
- if ((error = priv_check(td, PRIV_NET80211_MANAGE)))
+ if ((error = priv_check(td, PRIV_NET80211_VAP_MANAGE)))
goto out;
AN_LOCK(sc);
sc->areq.an_len = sizeof(sc->areq);
diff --git a/sys/dev/ath/ah_osdep.c b/sys/dev/ath/ah_osdep.c
index 23d967ec75e3..db9264546d23 100644
--- a/sys/dev/ath/ah_osdep.c
+++ b/sys/dev/ath/ah_osdep.c
@@ -444,7 +444,6 @@ ath_hal_modevent(module_t mod __unused, int type, void *data __unused)
default:
error = EOPNOTSUPP;
break;
-
}
return (error);
}
diff --git a/sys/dev/ath/ah_osdep_ar5210.c b/sys/dev/ath/ah_osdep_ar5210.c
index 905befe9ca95..e47a2dc11054 100644
--- a/sys/dev/ath/ah_osdep_ar5210.c
+++ b/sys/dev/ath/ah_osdep_ar5210.c
@@ -64,7 +64,6 @@ ath_hal_ar5210_modevent(module_t mod __unused, int type, void *data __unused)
default:
error = EOPNOTSUPP;
break;
-
}
return (error);
}
diff --git a/sys/dev/ath/ah_osdep_ar5211.c b/sys/dev/ath/ah_osdep_ar5211.c
index 92400965e55b..c87f9ff9b0cb 100644
--- a/sys/dev/ath/ah_osdep_ar5211.c
+++ b/sys/dev/ath/ah_osdep_ar5211.c
@@ -64,7 +64,6 @@ ath_hal_ar5211_modevent(module_t mod __unused, int type, void *data __unused)
default:
error = EOPNOTSUPP;
break;
-
}
return (error);
}
diff --git a/sys/dev/ath/ah_osdep_ar5212.c b/sys/dev/ath/ah_osdep_ar5212.c
index 3bc21ef803ec..daaa81ff2509 100644
--- a/sys/dev/ath/ah_osdep_ar5212.c
+++ b/sys/dev/ath/ah_osdep_ar5212.c
@@ -85,7 +85,6 @@ ath_hal_ar5212_modevent(module_t mod __unused, int type, void *data __unused)
default:
error = EOPNOTSUPP;
break;
-
}
return (error);
}
diff --git a/sys/dev/ath/ah_osdep_ar5416.c b/sys/dev/ath/ah_osdep_ar5416.c
index a735838068b6..058027b44c8f 100644
--- a/sys/dev/ath/ah_osdep_ar5416.c
+++ b/sys/dev/ath/ah_osdep_ar5416.c
@@ -92,7 +92,6 @@ ath_hal_ar5416_modevent(module_t mod __unused, int type, void *data __unused)
default:
error = EOPNOTSUPP;
break;
-
}
return (error);
}
diff --git a/sys/dev/ath/ah_osdep_ar9300.c b/sys/dev/ath/ah_osdep_ar9300.c
index f481d7ea2a2d..70dbfc2c3d39 100644
--- a/sys/dev/ath/ah_osdep_ar9300.c
+++ b/sys/dev/ath/ah_osdep_ar9300.c
@@ -64,7 +64,6 @@ ath_hal_ar9300_modevent(module_t mod __unused, int type, void *data __unused)
default:
error = EOPNOTSUPP;
break;
-
}
return (error);
}
diff --git a/sys/dev/ath/ath_dfs/null/dfs_null.c b/sys/dev/ath/ath_dfs/null/dfs_null.c
index 1463c8c96648..2c262d1c9ef5 100644
--- a/sys/dev/ath/ath_dfs/null/dfs_null.c
+++ b/sys/dev/ath/ath_dfs/null/dfs_null.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/socket.h>
-
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_media.h>
diff --git a/sys/dev/ath/ath_hal/ah.c b/sys/dev/ath/ath_hal/ah.c
index 7f5649ed4e8d..e2305d10b452 100644
--- a/sys/dev/ath/ath_hal/ah.c
+++ b/sys/dev/ath/ath_hal/ah.c
@@ -556,7 +556,6 @@ ath_hal_get_curmode(struct ath_hal *ah, const struct ieee80211_channel *chan)
return HAL_MODE_11NG_HT20;
}
-
typedef enum {
WIRELESS_MODE_11a = 0,
WIRELESS_MODE_TURBO = 1,
@@ -971,7 +970,7 @@ ath_hal_getregdump(struct ath_hal *ah, const HAL_REGRANGE *regs,
}
return (char *) dp - (char *) dstbuf;
}
-
+
static void
ath_hal_setregs(struct ath_hal *ah, const HAL_REGWRITE *regs, int space)
{
@@ -1127,7 +1126,6 @@ ath_hal_getTxQProps(struct ath_hal *ah,
return AH_FALSE;
}
- qInfo->tqi_qflags = qi->tqi_qflags;
qInfo->tqi_ver = qi->tqi_ver;
qInfo->tqi_subtype = qi->tqi_subtype;
qInfo->tqi_qflags = qi->tqi_qflags;
@@ -1141,6 +1139,7 @@ ath_hal_getTxQProps(struct ath_hal *ah,
qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
qInfo->tqi_burstTime = qi->tqi_burstTime;
qInfo->tqi_readyTime = qi->tqi_readyTime;
+ qInfo->tqi_compBuf = qi->tqi_physCompBuf;
return AH_TRUE;
}
diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h
index b887e9f5afb4..e39ff2b7d03d 100644
--- a/sys/dev/ath/ath_hal/ah.h
+++ b/sys/dev/ath/ath_hal/ah.h
@@ -33,6 +33,18 @@
#include "ah_osdep.h"
/*
+ * Endianness macros; used by various structures and code.
+ */
+#define AH_BIG_ENDIAN 4321
+#define AH_LITTLE_ENDIAN 1234
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define AH_BYTE_ORDER AH_BIG_ENDIAN
+#else
+#define AH_BYTE_ORDER AH_LITTLE_ENDIAN
+#endif
+
+/*
* The maximum number of TX/RX chains supported.
* This is intended to be used by various statistics gathering operations
* (NF, RSSI, EVM).
@@ -727,7 +739,6 @@ typedef enum {
HAL_HT_EXTPROTSPACING_25 = 1, /* 25 MHz spacing */
} HAL_HT_EXTPROTSPACING;
-
typedef enum {
HAL_RX_CLEAR_CTL_LOW = 0x1, /* force control channel to appear busy */
HAL_RX_CLEAR_EXT_LOW = 0x2, /* force extension channel to appear busy */
@@ -893,11 +904,13 @@ typedef struct {
} HAL_ANI_STATS;
typedef struct {
- uint8_t noiseImmunityLevel;
+ uint8_t noiseImmunityLevel; /* Global for pre-AR9380; OFDM later*/
+ uint8_t cckNoiseImmunityLevel; /* AR9380: CCK specific NI */
uint8_t spurImmunityLevel;
uint8_t firstepLevel;
uint8_t ofdmWeakSigDetectOff;
uint8_t cckWeakSigThreshold;
+ uint8_t mrcCck; /* MRC CCK is enabled */
uint32_t listenTime;
/* NB: intentionally ordered so data exported to user space is first */
@@ -956,7 +969,7 @@ typedef struct {
*/
typedef enum {
HAL_ANI_PRESENT = 0, /* is ANI support present */
- HAL_ANI_NOISE_IMMUNITY_LEVEL = 1, /* set level */
+ HAL_ANI_NOISE_IMMUNITY_LEVEL = 1, /* set level (global or ofdm) */
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION = 2, /* enable/disable */
HAL_ANI_CCK_WEAK_SIGNAL_THR = 3, /* enable/disable */
HAL_ANI_FIRSTEP_LEVEL = 4, /* set level */
@@ -964,6 +977,7 @@ typedef enum {
HAL_ANI_MODE = 6, /* 0 => manual, 1 => auto (XXX do not change) */
HAL_ANI_PHYERR_RESET = 7, /* reset phy error stats */
HAL_ANI_MRC_CCK = 8,
+ HAL_ANI_CCK_NOISE_IMMUNITY_LEVEL = 9, /* set level (cck) */
} HAL_ANI_CMD;
#define HAL_ANI_ALL 0xffffffff
@@ -1038,7 +1052,6 @@ typedef enum {
HAL_DFS_MKK4_DOMAIN = 3, /* Japan dfs domain */
} HAL_DFS_DOMAIN;
-
/*
* MFP decryption options for initializing the MAC.
*/
@@ -1311,7 +1324,7 @@ struct ath_hal {
void __ahdecl(*ah_setRxDP)(struct ath_hal*, uint32_t rxdp, HAL_RX_QUEUE);
void __ahdecl(*ah_enableReceive)(struct ath_hal*);
HAL_BOOL __ahdecl(*ah_stopDmaReceive)(struct ath_hal*);
- void __ahdecl(*ah_startPcuReceive)(struct ath_hal*);
+ void __ahdecl(*ah_startPcuReceive)(struct ath_hal*, HAL_BOOL);
void __ahdecl(*ah_stopPcuReceive)(struct ath_hal*);
void __ahdecl(*ah_setMulticastFilter)(struct ath_hal*,
uint32_t filter0, uint32_t filter1);
diff --git a/sys/dev/ath/ath_hal/ah_eeprom_9287.c b/sys/dev/ath/ath_hal/ah_eeprom_9287.c
index 974580d26394..42b3ff8b3252 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom_9287.c
+++ b/sys/dev/ath/ath_hal/ah_eeprom_9287.c
@@ -207,11 +207,11 @@ static uint16_t
v9287EepromGetSpurChan(struct ath_hal *ah, int ix, HAL_BOOL is2GHz)
{
HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
-
+
HALASSERT(is2GHz == AH_TRUE);
if (is2GHz != AH_TRUE)
return 0; /* XXX ? */
-
+
HALASSERT(0 <= ix && ix < AR5416_EEPROM_MODAL_SPURS);
return ee->ee_base.modalHeader.spurChans[ix].spurChan;
}
@@ -234,7 +234,6 @@ fbin2freq(uint8_t fbin, HAL_BOOL is2GHz)
return (uint16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
}
-
/*
* Copy EEPROM Conformance Testing Limits contents
* into the allocated space
@@ -247,7 +246,7 @@ v9287EepromReadCTLInfo(struct ath_hal *ah, HAL_EEPROM_9287 *ee)
{
RD_EDGES_POWER *rep = ee->ee_rdEdgesPower;
int i, j;
-
+
HALASSERT(AR9287_NUM_CTLS <= sizeof(ee->ee_rdEdgesPower)/NUM_EDGES);
for (i = 0; ee->ee_base.ctlIndex[i] != 0 && i < AR9287_NUM_CTLS; i++) {
@@ -359,7 +358,7 @@ ath_hal_9287EepromAttach(struct ath_hal *ah)
len = ee->ee_base.baseEepHeader.length;
}
len = AH_MIN(len, sizeof(HAL_EEPROM_9287)) / sizeof(uint16_t);
-
+
/* Apply the checksum, done in native eeprom format */
/* XXX - Need to check to make sure checksum calculation is done
* in the correct endian format. Right now, it seems it would
diff --git a/sys/dev/ath/ath_hal/ah_eeprom_9287.h b/sys/dev/ath/ath_hal/ah_eeprom_9287.h
index 891b4841b153..6d15a6df0204 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom_9287.h
+++ b/sys/dev/ath/ath_hal/ah_eeprom_9287.h
@@ -166,5 +166,4 @@ typedef struct {
typedef struct modal_eep_ar9287_header MODAL_EEP_9287_HEADER;
typedef struct base_eep_ar9287_header BASE_EEP_9287_HEADER;
-
#endif /* __AH_EEPROM_9287_H__ */
diff --git a/sys/dev/ath/ath_hal/ah_eeprom_v14.c b/sys/dev/ath/ath_hal/ah_eeprom_v14.c
index 3ae81217327d..d8bb96d56b28 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom_v14.c
+++ b/sys/dev/ath/ath_hal/ah_eeprom_v14.c
@@ -249,7 +249,7 @@ static uint16_t
v14EepromGetSpurChan(struct ath_hal *ah, int ix, HAL_BOOL is2GHz)
{
HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom;
-
+
HALASSERT(0 <= ix && ix < AR5416_EEPROM_MODAL_SPURS);
return ee->ee_base.modalHeader[is2GHz].spurChans[ix].spurChan;
}
@@ -284,7 +284,7 @@ v14EepromReadCTLInfo(struct ath_hal *ah, HAL_EEPROM_v14 *ee)
{
RD_EDGES_POWER *rep = ee->ee_rdEdgesPower;
int i, j;
-
+
HALASSERT(AR5416_NUM_CTLS <= sizeof(ee->ee_rdEdgesPower)/NUM_EDGES);
for (i = 0; ee->ee_base.ctlIndex[i] != 0 && i < AR5416_NUM_CTLS; i++) {
@@ -342,7 +342,7 @@ ath_hal_v14EepromAttach(struct ath_hal *ah)
uint32_t sum;
HALASSERT(ee == AH_NULL);
-
+
/*
* Don't check magic if we're supplied with an EEPROM block,
* typically this is from Howl but it may also be from later
@@ -398,7 +398,7 @@ ath_hal_v14EepromAttach(struct ath_hal *ah)
len = ee->ee_base.baseEepHeader.length;
}
len = AH_MIN(len, sizeof(struct ar5416eeprom)) / sizeof(uint16_t);
-
+
/* Apply the checksum, done in native eeprom format */
/* XXX - Need to check to make sure checksum calculation is done
* in the correct endian format. Right now, it seems it would
diff --git a/sys/dev/ath/ath_hal/ah_eeprom_v3.c b/sys/dev/ath/ath_hal/ah_eeprom_v3.c
index 9d7d011fcd65..2f1b2940de47 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom_v3.c
+++ b/sys/dev/ath/ath_hal/ah_eeprom_v3.c
@@ -739,14 +739,14 @@ readEepromRawPowerCalInfo2413(struct ath_hal *ah, HAL_EEPROM *ee)
int numEEPROMWordsPerChannel;
uint32_t off;
HAL_BOOL ret = AH_FALSE;
-
+
HALASSERT(ee->ee_version >= AR_EEPROM_VER5_0);
HALASSERT(ee->ee_eepMap == 2);
-
+
pCal = ath_hal_malloc(sizeof(EEPROM_DATA_STRUCT_2413));
if (pCal == AH_NULL)
goto exit;
-
+
off = ee->ee_eepMap2PowerCalStart;
if (ee->ee_Amode) {
OS_MEMZERO(pCal, sizeof(EEPROM_DATA_STRUCT_2413));
diff --git a/sys/dev/ath/ath_hal/ah_eeprom_v3.h b/sys/dev/ath/ath_hal/ah_eeprom_v3.h
index 2ec54713b261..be71a2486fde 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom_v3.h
+++ b/sys/dev/ath/ath_hal/ah_eeprom_v3.h
@@ -231,7 +231,6 @@ typedef struct cornerCalInfo {
#define NUM_TARGET_POWER_LOCATIONS_11B 4
#define NUM_TARGET_POWER_LOCATIONS_11G 6
-
typedef struct {
uint16_t xpd_gain;
uint16_t numPcdacs;
diff --git a/sys/dev/ath/ath_hal/ah_eeprom_v4k.c b/sys/dev/ath/ath_hal/ah_eeprom_v4k.c
index 69142ded5447..a9d16100d917 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom_v4k.c
+++ b/sys/dev/ath/ath_hal/ah_eeprom_v4k.c
@@ -200,7 +200,7 @@ static uint16_t
v4kEepromGetSpurChan(struct ath_hal *ah, int ix, HAL_BOOL is2GHz)
{
HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom;
-
+
HALASSERT(0 <= ix && ix < AR5416_EEPROM_MODAL_SPURS);
HALASSERT(is2GHz);
return ee->ee_base.modalHeader.spurChans[ix].spurChan;
@@ -236,7 +236,7 @@ v4kEepromReadCTLInfo(struct ath_hal *ah, HAL_EEPROM_v4k *ee)
{
RD_EDGES_POWER *rep = ee->ee_rdEdgesPower;
int i, j;
-
+
HALASSERT(AR5416_4K_NUM_CTLS <= sizeof(ee->ee_rdEdgesPower)/NUM_EDGES);
for (i = 0; ee->ee_base.ctlIndex[i] != 0 && i < AR5416_4K_NUM_CTLS; i++) {
@@ -347,7 +347,7 @@ ath_hal_v4kEepromAttach(struct ath_hal *ah)
len = ee->ee_base.baseEepHeader.length;
}
len = AH_MIN(len, sizeof(struct ar5416eeprom_4k)) / sizeof(uint16_t);
-
+
/* Apply the checksum, done in native eeprom format */
/* XXX - Need to check to make sure checksum calculation is done
* in the correct endian format. Right now, it seems it would
diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h
index 6b584c2454b3..87c67d73ddca 100644
--- a/sys/dev/ath/ath_hal/ah_internal.h
+++ b/sys/dev/ath/ath_hal/ah_internal.h
@@ -849,7 +849,6 @@ typedef struct {
uint16_t ee_data; /* write data */
} HAL_DIAG_EEVAL;
-
typedef struct {
u_int offset; /* reg offset */
uint32_t val; /* reg value */
diff --git a/sys/dev/ath/ath_hal/ah_regdomain.c b/sys/dev/ath/ath_hal/ah_regdomain.c
index 77bf417c2e41..c0ae4a94a4c6 100644
--- a/sys/dev/ath/ath_hal/ah_regdomain.c
+++ b/sys/dev/ath/ath_hal/ah_regdomain.c
@@ -695,7 +695,7 @@ getchannels(struct ath_hal *ah,
else if (cm->flags & IEEE80211_CHAN_2GHZ)
rd = rd2GHz;
else {
- ath_hal_printf(ah, "%s: Unkonwn HAL flags 0x%x\n",
+ ath_hal_printf(ah, "%s: Unknown HAL flags 0x%x\n",
__func__, cm->flags);
return HAL_EINVAL;
}
@@ -953,7 +953,6 @@ ath_hal_getctl(struct ath_hal *ah, const struct ieee80211_channel *c)
return ctl;
}
-
/*
* Update the current dfsDomain setting based on the given
* country code.
@@ -979,7 +978,6 @@ ath_hal_update_dfsdomain(struct ath_hal *ah)
__func__, AH_PRIVATE(ah)->ah_dfsDomain);
}
-
/*
* Return the max allowed antenna gain and apply any regulatory
* domain specific changes.
diff --git a/sys/dev/ath/ath_hal/ah_regdomain/ah_rd_domains.h b/sys/dev/ath/ath_hal/ah_regdomain/ah_rd_domains.h
index 6555147b4e60..5956a804b03a 100644
--- a/sys/dev/ath/ath_hal/ah_regdomain/ah_rd_domains.h
+++ b/sys/dev/ath/ath_hal/ah_regdomain/ah_rd_domains.h
@@ -64,7 +64,6 @@
W1(_fg) | W1(_fh) | W1(_fi) }
static REG_DOMAIN regDomains[] = {
-
{.regDmnEnum = DEBUG_REG_DMN,
.conformanceTestLimit = FCC,
.dfsMask = DFS_FCC3,
diff --git a/sys/dev/ath/ath_hal/ah_regdomain/ah_rd_freqbands.h b/sys/dev/ath/ath_hal/ah_regdomain/ah_rd_freqbands.h
index c7169113c11b..5475c6508972 100644
--- a/sys/dev/ath/ath_hal/ah_regdomain/ah_rd_freqbands.h
+++ b/sys/dev/ath/ath_hal/ah_regdomain/ah_rd_freqbands.h
@@ -198,7 +198,6 @@ static REG_DMN_FREQ_BAND regDmn5GhzFreq[] = {
#define W2_5825_5825 AFTER(W2_5180_5240)
};
-
/*
* 5GHz Turbo (dynamic & static) tags
*/
@@ -373,7 +372,7 @@ static REG_DMN_FREQ_BAND regDmn2Ghz11gFreq[] = {
#define G3_2412_2462 AFTER(G2_2412_2462)
{ 2412, 2462, 27, 6, 5, 5, NO_DFS, NO_PSCAN },
#define G4_2412_2462 AFTER(G3_2412_2462)
-
+
{ 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2432_2442 AFTER(G4_2412_2462)
diff --git a/sys/dev/ath/ath_hal/ah_soc.h b/sys/dev/ath/ath_hal/ah_soc.h
index 3d77b8234857..e391a2c869e8 100644
--- a/sys/dev/ath/ath_hal/ah_soc.h
+++ b/sys/dev/ath/ath_hal/ah_soc.h
@@ -62,18 +62,18 @@ struct ar531x_boarddata {
#define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */
uint16_t resetConfigGpio; /* Reset factory GPIO pin */
uint16_t sysLedGpio; /* System LED GPIO pin */
-
+
uint32_t cpuFreq; /* CPU core frequency in Hz */
uint32_t sysFreq; /* System frequency in Hz */
uint32_t cntFreq; /* Calculated C0_COUNT frequency */
-
+
uint8_t wlan0Mac[6];
uint8_t enet0Mac[6];
uint8_t enet1Mac[6];
-
+
uint16_t pciId; /* Pseudo PCIID for common code */
uint16_t memCap; /* cap bank1 in MB */
-
+
/* version 3 */
uint8_t wlan1Mac[6]; /* (ar5212) */
};
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210.h b/sys/dev/ath/ath_hal/ar5210/ar5210.h
index 756c8e03e51e..373c676e25b3 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210.h
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210.h
@@ -195,7 +195,7 @@ extern uint32_t ar5210GetRxDP(struct ath_hal *, HAL_RX_QUEUE);
extern void ar5210SetRxDP(struct ath_hal *, uint32_t rxdp, HAL_RX_QUEUE);
extern void ar5210EnableReceive(struct ath_hal *);
extern HAL_BOOL ar5210StopDmaReceive(struct ath_hal *);
-extern void ar5210StartPcuReceive(struct ath_hal *);
+extern void ar5210StartPcuReceive(struct ath_hal *, HAL_BOOL);
extern void ar5210StopPcuReceive(struct ath_hal *);
extern void ar5210SetMulticastFilter(struct ath_hal *,
uint32_t filter0, uint32_t filter1);
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c b/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c
index 38295b99d1ca..a11e0300721f 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c
@@ -50,7 +50,6 @@ ar5210SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE qtype)
OS_REG_WRITE(ah, AR_RXDP, rxdp);
}
-
/*
* Set Receive Enable bits.
*/
@@ -86,7 +85,7 @@ ar5210StopDmaReceive(struct ath_hal *ah)
* Start Transmit at the PCU engine (unpause receive)
*/
void
-ar5210StartPcuReceive(struct ath_hal *ah)
+ar5210StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning)
{
ar5210UpdateDiagReg(ah,
OS_REG_READ(ah, AR_DIAG_SW) & ~(AR_DIAG_SW_DIS_RX));
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c b/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c
index b5656fb36419..bf1b9683a2cc 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c
@@ -611,7 +611,6 @@ ar5210SetResetReg(struct ath_hal *ah, uint32_t resetMask, u_int delay)
return rt;
}
-
/*
* Returns: the pcdac value
*/
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211.h b/sys/dev/ath/ath_hal/ar5211/ar5211.h
index 7188966ef9ea..186e69e9cd84 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211.h
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211.h
@@ -218,7 +218,7 @@ extern uint32_t ar5211GetRxDP(struct ath_hal *, HAL_RX_QUEUE);
extern void ar5211SetRxDP(struct ath_hal *, uint32_t rxdp, HAL_RX_QUEUE);
extern void ar5211EnableReceive(struct ath_hal *);
extern HAL_BOOL ar5211StopDmaReceive(struct ath_hal *);
-extern void ar5211StartPcuReceive(struct ath_hal *);
+extern void ar5211StartPcuReceive(struct ath_hal *, HAL_BOOL);
extern void ar5211StopPcuReceive(struct ath_hal *);
extern void ar5211SetMulticastFilter(struct ath_hal *,
uint32_t filter0, uint32_t filter1);
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_keycache.c b/sys/dev/ath/ath_hal/ar5211/ar5211_keycache.c
index 8d703023edb3..7a8ed460ff80 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_keycache.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_keycache.c
@@ -163,7 +163,6 @@ ar5211SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry,
if (k->kv_len <= 104 / NBBY)
key4 &= 0xff;
-
/*
* Note: WEP key cache hardware requires that each double-word
* pair be written in even/odd order (since the destination is
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_misc.c b/sys/dev/ath/ath_hal/ar5211/ar5211_misc.c
index 4395818ab2bd..ea1327b11a6a 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_misc.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_misc.c
@@ -708,7 +708,6 @@ ar5211Get11nExtBusy(struct ath_hal *ah)
return (0);
}
-
/*
* There's no channel survey support for the AR5211.
*/
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_phy.c b/sys/dev/ath/ath_hal/ar5211/ar5211_phy.c
index 6507c879ed92..42d9665396a1 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_phy.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_phy.c
@@ -81,7 +81,6 @@ HAL_RATE_TABLE ar5211_11b_table = {
#undef CCK
#undef TURBO
-
const HAL_RATE_TABLE *
ar5211GetRateTable(struct ath_hal *ah, u_int mode)
{
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c b/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c
index 9b3bb677d5d6..1922f8775d54 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c
@@ -51,7 +51,6 @@ ar5211SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE qtype)
HALASSERT(OS_REG_READ(ah, AR_RXDP) == rxdp);
}
-
/*
* Set Receive Enable bits.
*/
@@ -87,7 +86,7 @@ ar5211StopDmaReceive(struct ath_hal *ah)
* Start Transmit at the PCU engine (unpause receive)
*/
void
-ar5211StartPcuReceive(struct ath_hal *ah)
+ar5211StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning)
{
OS_REG_WRITE(ah, AR_DIAG_SW,
OS_REG_READ(ah, AR_DIAG_SW) & ~(AR_DIAG_SW_DIS_RX));
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c b/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c
index 4bcb8fd6497a..9b32c4de496e 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c
@@ -193,7 +193,6 @@ setTxQInterrupts(struct ath_hal *ah, HAL_TX_QUEUE_INFO *qi)
AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
}
-
/*
* Free a tx DCU/QCU combination.
*/
@@ -677,7 +676,6 @@ ar5211GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *
return AH_FALSE;
}
-
void
ar5211SetTxDescLink(struct ath_hal *ah, void *ds, uint32_t link)
{
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211phy.h b/sys/dev/ath/ath_hal/ar5211/ar5211phy.h
index c344cdc9b054..9e44b903b085 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211phy.h
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211phy.h
@@ -48,7 +48,6 @@
#define AR_PHY_PLL_CTL_40 0x18 /* 40 MHz */
#define AR_PHY_PLL_CTL_20 0x13 /* 20 MHz half rate 11a for emulation */
-
#define AR_PHY_RX_DELAY 0x9914 /* PHY analog_power_on_time, in 100ns increments */
#define AR_PHY_RX_DELAY_M 0x00003FFF /* Mask for delay from active assertion (wake up) */
/* to enable_receiver */
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211reg.h b/sys/dev/ath/ath_hal/ar5211/ar5211reg.h
index ef2fb863d815..3cbdacc972c1 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211reg.h
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211reg.h
@@ -808,7 +808,6 @@
#define AR5211_USEC_RX_LAT_M 0x1F800000 /* Rx latency */
#define AR5211_USEC_RX_LAT_S 23
-
#define AR_BEACON_PERIOD 0x0000FFFF /* Beacon period in TU/msec */
#define AR_BEACON_PERIOD_S 0 /* Byte offset of PERIOD start*/
#define AR_BEACON_TIM 0x007F0000 /* Byte offset of TIM start */
diff --git a/sys/dev/ath/ath_hal/ar5212/ar2316.c b/sys/dev/ath/ath_hal/ar5212/ar2316.c
index 186e72e9856c..1259c777d99c 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar2316.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar2316.c
@@ -629,7 +629,7 @@ ar2316GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2316 *data)
{
uint32_t ii;
uint16_t Pmax=0,numVpd;
-
+
for (ii=0; ii< MAX_NUM_PDGAINS_PER_CHANNEL; ii++) {
/* work forwards cuase lowest pdGain for highest power */
numVpd = data->pDataPerPDGain[ii].numVpd;
@@ -664,7 +664,7 @@ ar2316GetChannelMaxMinPower(struct ath_hal *ah,
numChannels = pRawDataset->numChannels;
data = pRawDataset->pDataPerChannel;
-
+
/* Make sure the channel is in the range of the TP values
* (freq piers)
*/
diff --git a/sys/dev/ath/ath_hal/ar5212/ar2317.c b/sys/dev/ath/ath_hal/ar5212/ar2317.c
index 29a9b369f3a5..814e4318b39d 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar2317.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar2317.c
@@ -608,7 +608,7 @@ ar2317GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2317 *data)
uint32_t ii;
uint16_t Pmax=0,numVpd;
uint16_t vpdmax;
-
+
for (ii=0; ii< MAX_NUM_PDGAINS_PER_CHANNEL; ii++) {
/* work forwards cuase lowest pdGain for highest power */
numVpd = data->pDataPerPDGain[ii].numVpd;
@@ -644,7 +644,7 @@ ar2317GetChannelMaxMinPower(struct ath_hal *ah,
numChannels = pRawDataset->numChannels;
data = pRawDataset->pDataPerChannel;
-
+
/* Make sure the channel is in the range of the TP values
* (freq piers)
*/
diff --git a/sys/dev/ath/ath_hal/ar5212/ar2413.c b/sys/dev/ath/ath_hal/ar5212/ar2413.c
index e2a8d0203360..3c1ce6805a2a 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar2413.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar2413.c
@@ -624,7 +624,7 @@ ar2413GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2413 *data)
{
uint32_t ii;
uint16_t Pmax=0,numVpd;
-
+
for (ii=0; ii< MAX_NUM_PDGAINS_PER_CHANNEL; ii++) {
/* work forwards cuase lowest pdGain for highest power */
numVpd = data->pDataPerPDGain[ii].numVpd;
@@ -659,7 +659,7 @@ ar2413GetChannelMaxMinPower(struct ath_hal *ah,
numChannels = pRawDataset->numChannels;
data = pRawDataset->pDataPerChannel;
-
+
/* Make sure the channel is in the range of the TP values
* (freq piers)
*/
diff --git a/sys/dev/ath/ath_hal/ar5212/ar2425.c b/sys/dev/ath/ath_hal/ar5212/ar2425.c
index 9159ad2370d1..979f45b3619e 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar2425.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar2425.c
@@ -492,7 +492,6 @@ ar2425getGainBoundariesAndPdadcsForPowers(struct ath_hal *ah, uint16_t channel,
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "<==%s\n", __func__);
}
-
/* Same as 2413 set power table */
static HAL_BOOL
ar2425SetPowerTable(struct ath_hal *ah,
@@ -586,7 +585,7 @@ ar2425GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2413 *data)
{
uint32_t ii;
uint16_t Pmax=0,numVpd;
-
+
for (ii=0; ii< MAX_NUM_PDGAINS_PER_CHANNEL; ii++) {
/* work forwards cuase lowest pdGain for highest power */
numVpd = data->pDataPerPDGain[ii].numVpd;
@@ -622,7 +621,7 @@ ar2425GetChannelMaxMinPower(struct ath_hal *ah,
numChannels = pRawDataset->numChannels;
data = pRawDataset->pDataPerChannel;
-
+
/* Make sure the channel is in the range of the TP values
* (freq piers)
*/
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5111.c b/sys/dev/ath/ath_hal/ar5212/ar5111.c
index 128332266b52..fe8acccd0691 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5111.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5111.c
@@ -336,7 +336,6 @@ ar5111SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan,
ar5212ModifyRfBuffer(rfReg, rfWaitS, 5, 19, 0);
ar5212ModifyRfBuffer(rfReg, rfWaitI, 5, 24, 0);
ar5212ModifyRfBuffer(rfReg, rfMaxTime, 2, 49, 0);
-
}
HAL_INI_WRITE_BANK(ah, ar5212Bank7_5111, rfReg, regWrites);
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5112.c b/sys/dev/ath/ath_hal/ar5212/ar5112.c
index 1e9e20355677..0c3a6032e5fa 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5112.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5112.c
@@ -281,7 +281,7 @@ ar5112SetRfRegs(struct ath_hal *ah,
ar5212ModifyRfBuffer(priv->Bank6Data, ob5GHz, 3, 279, 0);
ar5212ModifyRfBuffer(priv->Bank6Data, db5GHz, 3, 282, 0);
}
-
+
/* Lower synth voltage for X112 Rev 2.0 only */
if (IS_RADX112_REV2(ah)) {
/* Non-Reversed analyg registers - so values are pre-reversed */
@@ -763,7 +763,7 @@ ar5112GetMinPower(struct ath_hal *ah, const EXPN_DATA_PER_CHANNEL_5112 *data)
retVal = minPwr - (minPcdac*2);
return(retVal);
}
-
+
static HAL_BOOL
ar5112GetChannelMaxMinPower(struct ath_hal *ah,
const struct ieee80211_channel *chan,
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212.h b/sys/dev/ath/ath_hal/ar5212/ar5212.h
index 0baba50c55e6..f80f88c5df85 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212.h
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212.h
@@ -539,7 +539,7 @@ extern uint32_t ar5212GetRxDP(struct ath_hal *ath, HAL_RX_QUEUE);
extern void ar5212SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE);
extern void ar5212EnableReceive(struct ath_hal *ah);
extern HAL_BOOL ar5212StopDmaReceive(struct ath_hal *ah);
-extern void ar5212StartPcuReceive(struct ath_hal *ah);
+extern void ar5212StartPcuReceive(struct ath_hal *ah, HAL_BOOL);
extern void ar5212StopPcuReceive(struct ath_hal *ah);
extern void ar5212SetMulticastFilter(struct ath_hal *ah,
uint32_t filter0, uint32_t filter1);
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_ani.c b/sys/dev/ath/ath_hal/ar5212/ar5212_ani.c
index 4e2cd683df8c..eb9999e1ca5d 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_ani.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_ani.c
@@ -225,7 +225,7 @@ ar5212AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState = ahp->ah_curani;
const struct ar5212AniParams *params = AH_NULL;
-
+
/*
* This function may be called before there's a current
* channel (eg to disable ANI.)
@@ -784,7 +784,7 @@ ar5212AniLowerImmunity(struct ath_hal *ah)
struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState;
const struct ar5212AniParams *params;
-
+
HALASSERT(ANI_ENA(ah));
aniState = ahp->ah_curani;
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c b/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c
index ead62adfce48..b52045baea19 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c
@@ -27,7 +27,6 @@
#include "ar5212/ar5212reg.h"
#include "ar5212/ar5212phy.h"
-
/*
* Checks to see if an interrupt is pending on our NIC
*
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c b/sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c
index fa6936231952..8daaf250ec0b 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c
@@ -245,7 +245,6 @@ ar5212SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry,
OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
(void) ar5212SetKeyCacheEntryMac(ah, entry, mac);
-
/*
* Write MIC entry according to new or old key layout.
* The MISC_MODE register is assumed already set so
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c b/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
index 6450c8d6f426..577e1e7491b3 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
@@ -623,7 +623,7 @@ ar5212SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
* timeouts. This value is in core clocks.
*/
timeout = ACK_CTS_TIMEOUT_11A + (coverageclass * 3 * clkRate);
-
+
/*
* Write the values: slot, eifs, ack/cts timeouts.
*/
@@ -1194,7 +1194,6 @@ ar5212EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
val &= ~ AR_PHY_RADAR_0_ENA;
if (IS_5413(ah)) {
-
if (pe->pe_blockradar == 1)
OS_REG_SET_BIT(ah, AR_PHY_RADAR_2,
AR_PHY_RADAR_2_BLOCKOFDMWEAK);
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_phy.c b/sys/dev/ath/ath_hal/ar5212/ar5212_phy.c
index 6f9c9dc1744b..ba56477fa506 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_phy.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_phy.c
@@ -129,7 +129,6 @@ HAL_RATE_TABLE ar5212_11b_table = {
},
};
-
/* Venice TODO: roundUpRate() is broken when the rate table does not represent rates
* in increasing order e.g. 5.5, 11, 6, 9.
* An average rate of 6 Mbps will currently map to 11 Mbps.
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_recv.c b/sys/dev/ath/ath_hal/ar5212/ar5212_recv.c
index a2e36be5f70e..8ead1250fb87 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_recv.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_recv.c
@@ -87,7 +87,7 @@ ar5212StopDmaReceive(struct ath_hal *ah)
* Start Transmit at the PCU engine (unpause receive)
*/
void
-ar5212StartPcuReceive(struct ath_hal *ah)
+ar5212StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning)
{
struct ath_hal_private *ahp = AH_PRIVATE(ah);
@@ -95,8 +95,8 @@ ar5212StartPcuReceive(struct ath_hal *ah)
OS_REG_WRITE(ah, AR_DIAG_SW,
OS_REG_READ(ah, AR_DIAG_SW) &~ AR_DIAG_RX_DIS);
ar5212EnableMibCounters(ah);
- /* NB: restore current settings */
- ar5212AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, AH_TRUE);
+ /* NB: restore current settings if we're not scanning */
+ ar5212AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, !is_scanning);
}
/*
@@ -265,7 +265,6 @@ ar5212ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds,
rs->rs_datalen = ads->ds_rxstatus0 & AR_DataLen;
rs->rs_tstamp = MS(ads->ds_rxstatus1, AR_RcvTimestamp);
rs->rs_status = 0;
- /* XXX what about KeyCacheMiss? */
rs->rs_rssi = MS(ads->ds_rxstatus0, AR_RcvSigStrength);
/* discard invalid h/w rssi data */
if (rs->rs_rssi == -128)
@@ -274,6 +273,8 @@ ar5212ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds,
rs->rs_keyix = MS(ads->ds_rxstatus1, AR_KeyIdx);
else
rs->rs_keyix = HAL_RXKEYIX_INVALID;
+ if (ads->ds_rxstatus1 & AR_KeyCacheMiss)
+ rs->rs_status |= HAL_RXERR_KEYMISS;
/* NB: caller expected to do rate table mapping */
rs->rs_rate = MS(ads->ds_rxstatus0, AR_RcvRate);
rs->rs_antenna = MS(ads->ds_rxstatus0, AR_RcvAntenna);
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c b/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c
index a5e9ca65d056..12fe41b0c19f 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c
@@ -692,7 +692,7 @@ done:
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
RESTORE_CCK(ah, chan, isBmode);
-
+
OS_MARK(ah, AH_MARK_RESET_DONE, 0);
return AH_TRUE;
@@ -1192,7 +1192,6 @@ ar5212MacStop(struct ath_hal *ah)
return status;
}
-
/*
* Write the given reset bit mask into the reset register
*/
@@ -1923,7 +1922,6 @@ ar5212SetSpurMitigation(struct ath_hal *ah,
#undef CHAN_TO_SPUR
}
-
/*
* Delta slope coefficient computation.
* Required for OFDM operation.
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c b/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
index 6b8730b0d063..cebaa989ef8d 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
@@ -107,7 +107,6 @@ ar5212GetTxQueueProps(struct ath_hal *ah, int q, HAL_TXQ_INFO *qInfo)
struct ath_hal_5212 *ahp = AH5212(ah);
HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
-
if (q >= pCap->halTotalQueues) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n",
__func__, q);
@@ -346,7 +345,7 @@ ar5212ResetTxQueue(struct ath_hal *ah, u_int q)
SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_INT)
| AR_Q_RDYTIMECFG_ENA);
}
-
+
OS_REG_WRITE(ah, AR_DCHNTIME(q),
SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR)
| (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
@@ -473,7 +472,7 @@ ar5212ResetTxQueue(struct ath_hal *ah, u_int q)
OS_REG_READ(ah, AR_Q0_MISC + 4*q)
| AR_Q_MISC_QCU_COMP_EN);
}
-
+
/*
* Always update the secondary interrupt mask registers - this
* could be a new queue getting enabled in a running system or
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212phy.h b/sys/dev/ath/ath_hal/ar5212/ar5212phy.h
index a91f2c10ee87..74ccb268fa0d 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212phy.h
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212phy.h
@@ -78,7 +78,6 @@
#define AR_PHY_TSTDAC_CONST_Q_S 9
#define AR_PHY_TSTDAC_CONST_I 0x000001FF
-
#define AR_PHY_SETTLING 0x9844
#define AR_PHY_SETTLING_AGC 0x0000007F
#define AR_PHY_SETTLING_AGC_S 0
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5413.c b/sys/dev/ath/ath_hal/ar5212/ar5413.c
index 1d57b9ec7450..1b1817c6c3c4 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5413.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5413.c
@@ -241,7 +241,6 @@ ar5413SetRfRegs(struct ath_hal *ah,
} else {
ar5212ModifyRfBuffer(priv->Bank6Data, ob5GHz, 3, 247, 0);
ar5212ModifyRfBuffer(priv->Bank6Data, db5GHz, 3, 244, 0);
-
}
/* Bank 7 Setup */
@@ -668,7 +667,7 @@ ar5413GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2413 *data)
{
uint32_t ii;
uint16_t Pmax=0,numVpd;
-
+
for (ii=0; ii< MAX_NUM_PDGAINS_PER_CHANNEL; ii++) {
/* work forwards cuase lowest pdGain for highest power */
numVpd = data->pDataPerPDGain[ii].numVpd;
@@ -705,7 +704,7 @@ ar5413GetChannelMaxMinPower(struct ath_hal *ah,
numChannels = pRawDataset->numChannels;
data = pRawDataset->pDataPerChannel;
-
+
/* Make sure the channel is in the range of the TP values
* (freq piers)
*/
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312_eeprom.c b/sys/dev/ath/ath_hal/ar5312/ar5312_eeprom.c
index 9b79c36c323f..74a7394665ee 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312_eeprom.c
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312_eeprom.c
@@ -20,7 +20,6 @@
*/
#include "opt_ah.h"
-
#ifdef AH_SUPPORT_AR5312
#include "ah.h"
@@ -39,7 +38,7 @@ ar5312EepromRead(struct ath_hal *ah, u_int off, uint16_t *dataIn)
int i,offset;
const char *eepromAddr = AR5312_RADIOCONFIG(ah);
uint8_t *data;
-
+
data = (uint8_t *) dataIn;
for (i=0,offset=2*off; i<2; i++,offset++) {
data[i] = eepromAddr[offset];
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312_gpio.c b/sys/dev/ath/ath_hal/ar5312/ar5312_gpio.c
index 809904d649b5..84bfd50099c3 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312_gpio.c
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312_gpio.c
@@ -129,5 +129,4 @@ ar5312GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel)
(void) ar5212SetInterrupts(ah, AH5212(ah)->ah_maskReg | HAL_INT_GPIO);
}
-
#endif /* AH_SUPPORT_AR5312 */
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312_interrupts.c b/sys/dev/ath/ath_hal/ar5312/ar5312_interrupts.c
index 43cdda719db6..926fcc2863e1 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312_interrupts.c
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312_interrupts.c
@@ -29,7 +29,6 @@
#include "ar5312/ar5312reg.h"
#include "ar5312/ar5312phy.h"
-
/*
* Checks to see if an interrupt is pending on our NIC
*
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312_reset.c b/sys/dev/ath/ath_hal/ar5312/ar5312_reset.c
index ebc12277a736..2daea4007c98 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312_reset.c
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312_reset.c
@@ -271,7 +271,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
/* Set the mute mask to the correct default */
OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F);
}
-
+
if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) {
/* Clear reg to alllow RX_CLEAR line debug */
OS_REG_WRITE(ah, AR_PHY_BLUETOOTH, 0);
@@ -827,12 +827,10 @@ ar5312MacReset(struct ath_hal *ah, unsigned int RCMask)
OS_REG_READ(ah,
(AR5315_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5315_RESET));
-
}
else
#endif
{
-
switch(wlanNum) {
case 0:
resetBB = AR5312_RC_BB0_CRES | AR5312_RC_WBB0_RES;
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312reg.h b/sys/dev/ath/ath_hal/ar5312/ar5312reg.h
index 0e78a52dfe9e..34c8aef51ef1 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312reg.h
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312reg.h
@@ -29,7 +29,6 @@
/* Register base addresses for modules which are not wmac modules */
/* 531X has a fixed memory map */
-
#define REG_WRITE(_reg,_val) *((volatile uint32_t *)(_reg)) = (_val);
#define REG_READ(_reg) *((volatile uint32_t *)(_reg))
/*
@@ -129,7 +128,6 @@
#define AR5312_RC_WMAC1_RES 0x00020000 /* Warm reset to WMAC1 */
#define AR5312_RC_WBB1_RES 0x00040000 /* Warm reset to WBB */
-
#define AR_RAD2112_SREV_MAJOR 0x40 /* 2112 Major Rev */
enum AR5312PowerMode {
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5315_gpio.c b/sys/dev/ath/ath_hal/ar5312/ar5315_gpio.c
index 5fe8eec6c225..41a7bd6cfb38 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5315_gpio.c
+++ b/sys/dev/ath/ath_hal/ar5312/ar5315_gpio.c
@@ -128,5 +128,4 @@ ar5315GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel)
(void) ar5212SetInterrupts(ah, AH5212(ah)->ah_maskReg | HAL_INT_GPIO);
}
-
#endif /* AH_SUPPORT_2316 || AH_SUPPORT_2317 */
diff --git a/sys/dev/ath/ath_hal/ar5416/ar2133.c b/sys/dev/ath/ath_hal/ar5416/ar2133.c
index c4ac3e9fee05..1cb5432609d7 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar2133.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar2133.c
@@ -278,7 +278,7 @@ ar2133SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan,
/* Setup Bank 6 Write */
ath_hal_ini_bank_setup(priv->Bank6Data, &AH5416(ah)->ah_ini_bank6, modesIndex);
-
+
/* Only the 5 or 2 GHz OB/DB need to be set for a mode */
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: 2ghz: OB_2:%d, DB_2:%d\n",
@@ -419,6 +419,7 @@ ar2133GetChannelMaxMinPower(struct ath_hal *ah,
return(AH_FALSE);
}
#else
+ // XXX TODO: actually go implement for 11n chips!
*maxPow = *minPow = 0;
return AH_FALSE;
#endif
@@ -472,7 +473,6 @@ ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
"NF calibrated [ctl] [chain 1] is %d\n", nf);
nfarray[1] = nf;
-
nf = MS(OS_REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR);
if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1);
@@ -521,7 +521,7 @@ ar2133RfDetach(struct ath_hal *ah)
ath_hal_free(ahp->ah_rfHal);
ahp->ah_rfHal = AH_NULL;
}
-
+
/*
* Allocate memory for analog bank scratch buffers
* Scratch Buffer will be reinitialized every reset so no need to zero now
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416.h b/sys/dev/ath/ath_hal/ar5416/ar5416.h
index d71d2f922919..3f0787ec17c3 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416.h
@@ -289,7 +289,7 @@ extern HAL_BOOL ar5416SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry,
extern uint32_t ar5416GetRxFilter(struct ath_hal *ah);
extern void ar5416SetRxFilter(struct ath_hal *ah, uint32_t bits);
extern HAL_BOOL ar5416StopDmaReceive(struct ath_hal *ah);
-extern void ar5416StartPcuReceive(struct ath_hal *ah);
+extern void ar5416StartPcuReceive(struct ath_hal *ah, HAL_BOOL);
extern void ar5416StopPcuReceive(struct ath_hal *ah);
extern HAL_BOOL ar5416SetupRxDesc(struct ath_hal *,
struct ath_desc *, uint32_t size, u_int flags);
@@ -306,7 +306,8 @@ extern HAL_BOOL ar5416PhyDisable(struct ath_hal *ah);
extern HAL_RFGAIN ar5416GetRfgain(struct ath_hal *ah);
extern HAL_BOOL ar5416Disable(struct ath_hal *ah);
extern HAL_BOOL ar5416ChipReset(struct ath_hal *ah,
- const struct ieee80211_channel *);
+ const struct ieee80211_channel *,
+ HAL_RESET_TYPE);
extern int ar5416GetRegChainOffset(struct ath_hal *ah, int i);
extern HAL_BOOL ar5416SetBoardValues(struct ath_hal *,
const struct ieee80211_channel *);
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
index a10d884aaaf8..340d67f2e52b 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
@@ -223,7 +223,6 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
return AH_FALSE;
}
-
switch (cmd) {
case HAL_ANI_NOISE_IMMUNITY_LEVEL: {
u_int level = param;
@@ -727,7 +726,7 @@ ar5416AniLowerImmunity(struct ath_hal *ah)
struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState;
const struct ar5212AniParams *params;
-
+
HALASSERT(ANI_ENA(ah));
aniState = ahp->ah_curani;
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
index 8957dedb39dc..369e4b0bb551 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
@@ -376,7 +376,7 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc,
if (ecode != HAL_OK)
goto bad;
- if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */
+ if (!ar5416ChipReset(ah, AH_NULL, HAL_RESET_NORMAL)) { /* reset chip */
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n",
__func__);
ecode = HAL_EIO;
@@ -721,7 +721,6 @@ ar5416SpurMitigate(struct ath_hal *ah, const struct ieee80211_channel *chan)
SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
OS_REG_WRITE(ah, AR_PHY_TIMING11, new);
-
/*
* ============================================
* pilot mask 1 [31:0] = +6..-26, no 0 bin
@@ -893,7 +892,7 @@ ar5416FillCapabilityInfo(struct ath_hal *ah)
struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;
uint16_t val;
-
+
/* Construct wireless mode from EEPROM */
pCap->halWirelessModes = 0;
if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) {
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c b/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c
index 7de707b3293c..e1b61bb3ccb4 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c
@@ -155,7 +155,7 @@ ar5416SetStaBeaconTimers(struct ath_hal *ah, const HAL_BEACON_STATE *bs)
uint32_t nextTbtt, nextdtim,beaconintval, dtimperiod;
HALASSERT(bs->bs_intval != 0);
-
+
/* NB: no cfp setting since h/w automatically takes care */
OS_REG_WRITE(ah, AR_NEXT_TBTT, TU_TO_USEC(bs->bs_nexttbtt));
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
index 106833fe6303..44b436c4f389 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
@@ -196,7 +196,6 @@ ar5416RunInitCals(struct ath_hal *ah, int init_cal_count)
}
#endif
-
/*
* AGC calibration for the AR5416, AR9130, AR9160, AR9280.
*/
@@ -623,7 +622,6 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
h = AH5416(ah)->ah_cal.nfCalHist;
HALDEBUG(ah, HAL_DEBUG_NFCAL, "CCA: ");
for (i = 0; i < AR5416_NUM_NF_READINGS; i ++) {
-
/* Don't write to EXT radio CCA registers unless in HT/40 mode */
/* XXX this check should really be cleaner! */
if (i > 2 && !IEEE80211_IS_CHAN_HT40(chan))
@@ -674,7 +672,6 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
* of next noise floor calibration the baseband does.
*/
for (i = 0; i < AR5416_NUM_NF_READINGS; i ++) {
-
/* Don't write to EXT radio CCA registers unless in HT/40 mode */
/* XXX this check should really be cleaner! */
if (i > 2 && !IEEE80211_IS_CHAN_HT40(chan))
@@ -781,7 +778,6 @@ ar5416SanitizeNF(struct ath_hal *ah, int16_t *nf)
}
}
-
/*
* Read the NF and check it against the noise floor threshold
*
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.h b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.h
index 5cf1ed0ef108..73a6a87499eb 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.h
@@ -20,7 +20,7 @@
*/
#ifndef _ATH_AR5416_CAL_H_
#define _ATH_AR5416_CAL_H_
-
+
typedef enum {
ADC_DC_INIT_CAL = 0x1,
ADC_GAIN_CAL = 0x2,
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_gpio.c b/sys/dev/ath/ath_hal/ar5416/ar5416_gpio.c
index 1695eda2c5f6..e1d1320d0852 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_gpio.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_gpio.c
@@ -131,7 +131,7 @@ ar5416GpioCfgOutput(struct ath_hal *ah, uint32_t gpio, HAL_GPIO_MUX_TYPE type)
return AH_TRUE;
#undef N
}
-
+
/*
* Configure GPIO Input lines
*/
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_power.c b/sys/dev/ath/ath_hal/ar5416/ar5416_power.c
index bcd5fd9807a8..ac1366fedefa 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_power.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_power.c
@@ -114,7 +114,7 @@ static void
ar5416SetPowerModeNetworkSleep(struct ath_hal *ah, int setChip)
{
OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
-
+
if (setChip)
OS_REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN);
}
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c b/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c
index 372e2795dc20..f58f29a12602 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c
@@ -106,14 +106,14 @@ ar5416StopDmaReceive(struct ath_hal *ah)
* Start receive at the PCU engine
*/
void
-ar5416StartPcuReceive(struct ath_hal *ah)
+ar5416StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning)
{
struct ath_hal_private *ahp = AH_PRIVATE(ah);
HALDEBUG(ah, HAL_DEBUG_RX, "%s: Start PCU Receive \n", __func__);
ar5212EnableMibCounters(ah);
- /* NB: restore current settings */
- ar5416AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, AH_TRUE);
+ /* NB: restore current settings if we're not scanning */
+ ar5416AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, ! is_scanning);
/*
* NB: must do after enabling phy errors to avoid rx
* frames w/ corrupted descriptor status.
@@ -183,8 +183,6 @@ ar5416ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds,
rs->rs_datalen = ads->ds_rxstatus1 & AR_DataLen;
rs->rs_tstamp = ads->AR_RcvTimestamp;
- /* XXX what about KeyCacheMiss? */
-
rs->rs_rssi = MS(ads->ds_rxstatus4, AR_RxRSSICombined);
rs->rs_rssi_ctl[0] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt00);
rs->rs_rssi_ctl[1] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt01);
@@ -277,5 +275,8 @@ ar5416ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds,
rs->rs_status |= HAL_RXERR_MIC;
}
+ if (ads->ds_rxstatus8 & AR_KeyMiss)
+ rs->rs_status |= HAL_RXERR_KEYMISS;
+
return HAL_OK;
}
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
index 6c5cf53c325b..f3d6fcab0d68 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
@@ -170,13 +170,15 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
if (AR_SREV_HOWL(ah) ||
(AR_SREV_MERLIN(ah) &&
ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) ||
+ (resetType == HAL_RESET_FORCE_COLD) ||
+ (resetType == HAL_RESET_BBPANIC) ||
(ah->ah_config.ah_force_full_reset))
tsf = ar5416GetTsf64(ah);
/* Mark PHY as inactive; marked active in ar5416InitBB() */
ar5416MarkPhyInactive(ah);
- if (!ar5416ChipReset(ah, chan)) {
+ if (!ar5416ChipReset(ah, chan, resetType)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
FAIL(HAL_EIO);
}
@@ -384,7 +386,6 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
}
-
/*
* disable seq number generation in hw
*/
@@ -604,7 +605,7 @@ ar5416InitDMA(struct ath_hal *ah)
* Setup receive FIFO threshold to hold off TX activities
*/
OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
-
+
/*
* reduce the number of usable entries in PCU TXBUF to avoid
* wrap around.
@@ -643,7 +644,7 @@ ar5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *chan)
/* Activate the PHY (includes baseband activate and synthesizer on) */
OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
-
+
/*
* If the AP starts the calibration before the base band timeout
* completes we could get rx_clear false triggering. Add an
@@ -775,7 +776,8 @@ ar5416SetRfMode(struct ath_hal *ah, const struct ieee80211_channel *chan)
* Places the hardware into reset and then pulls it out of reset
*/
HAL_BOOL
-ar5416ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
+ar5416ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ HAL_RESET_TYPE resetType)
{
OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
/*
@@ -788,6 +790,13 @@ ar5416ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
} else if (ah->ah_config.ah_force_full_reset) {
if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON))
return AH_FALSE;
+ } else if ((resetType == HAL_RESET_FORCE_COLD) ||
+ (resetType == HAL_RESET_BBPANIC)) {
+ HALDEBUG(ah, HAL_DEBUG_RESET,
+ "%s: full reset; resetType=%d\n",
+ __func__, resetType);
+ if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON))
+ return AH_FALSE;
} else {
if (!ar5416SetResetReg(ah, HAL_RESET_WARM))
return AH_FALSE;
@@ -1039,7 +1048,6 @@ ar5416WriteTxPowerRateRegisters(struct ath_hal *ah,
#undef POW_SM
}
-
/**************************************************************
* ar5416SetTransmitPower
*
@@ -1086,7 +1094,7 @@ ar5416SetTransmitPower(struct ath_hal *ah,
if (IS_EEP_MINOR_V2(ah)) {
AH5416(ah)->ah_ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
}
-
+
if (!ar5416SetPowerPerRateTable(ah, pEepData, chan,
&AH5416(ah)->ah_ratesArray[0],
cfgCtl,
@@ -1515,7 +1523,7 @@ ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan)
pll |= SM(0xb, AR_RTC_PLL_DIV);
} else
pll |= SM(0xb, AR_RTC_PLL_DIV);
-
+
OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
/* TODO:
@@ -1647,7 +1655,6 @@ ar5416SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan)
if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah))
ar5416SetDefGainValues(ah, pModal, eep, txRxAttenLocal, regChainOffset, i);
-
}
if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
@@ -2794,7 +2801,6 @@ ar5416MarkPhyInactive(struct ath_hal *ah)
#define AR5416_HALF_RATE_USEC_44 21 /* ((44 / 2) - 1 ) */
#define AR5416_QUARTER_RATE_USEC_44 10 /* ((44 / 4) - 1 ) */
-
/* XXX What should these be for 40/44MHz clocks (and half/quarter) ? */
#define AR5416_RX_NON_FULL_RATE_LATENCY 63
#define AR5416_TX_HALF_RATE_LATENCY 108
@@ -2893,4 +2899,3 @@ ar5416SetIFSTiming(struct ath_hal *ah, const struct ieee80211_channel *chan)
OS_REG_RMW_FIELD(ah, AR_D_GBL_IFS_MISC,
AR_D_GBL_IFS_MISC_USEC_DURATION, init_usec);
}
-
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c b/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c
index a5f1251607a8..496abbf4e9b4 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c
@@ -243,4 +243,3 @@ ar5416RestoreSpectralConfig(struct ath_hal *ah, uint32_t restoreval)
}
return;
}
-
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
index 869d5fbea30a..e3330fe820b8 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
@@ -266,7 +266,6 @@ ar5416GetTxRatePower(struct ath_hal *ah, uint8_t rate, uint8_t tx_chainmask,
*/
if (AR_SREV_MERLIN_20_OR_LATER(ah) &&
ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) {
-
if (rate == 0x19 || rate == 0x1a || rate == 0x1b ||
rate == (0x19 | 0x04) || rate == (0x1a | 0x04) ||
rate == (0x1b | 0x04)) {
@@ -543,7 +542,7 @@ ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds,
int isaggr = 0;
uint32_t last_aggr = 0;
-
+
(void) hdrLen;
(void) ah;
@@ -613,7 +612,7 @@ ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds,
}
ds_txstatus[0] = ds_txstatus[1] = 0;
ds_txstatus[9] &= ~AR_TxDone;
-
+
return AH_TRUE;
}
@@ -631,7 +630,7 @@ ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
HALASSERT(isValidTxRate(txRate0));
HALASSERT((flags & RTSCTS) != RTSCTS);
/* XXX validate antMode */
-
+
txPower = (txPower + ahp->ah_txPowerIndexOffset );
if(txPower > 63) txPower=63;
@@ -646,7 +645,7 @@ ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel1)
| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel2)
| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel3);
-
+
/* NB: no V1 WAR */
ads->ds_ctl8 = SM(0, AR_AntCtl0);
ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1);
@@ -673,7 +672,7 @@ ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(0, AR_XmitPower2);
ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(0, AR_XmitPower3);
}
-
+
return AH_TRUE;
#undef RTSCTS
}
@@ -1114,7 +1113,6 @@ ar5416GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *
return AH_TRUE;
}
-
/*
* TX queue management routines - AR5416 and later chipsets
*/
@@ -1326,7 +1324,7 @@ ar5416ResetTxQueue(struct ath_hal *ah, u_int q)
SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_INT)
| AR_Q_RDYTIMECFG_ENA);
}
-
+
OS_REG_WRITE(ah, AR_DCHNTIME(q),
SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR)
| (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
@@ -1464,7 +1462,7 @@ ar5416ResetTxQueue(struct ath_hal *ah, u_int q)
OS_REG_READ(ah, AR_Q0_MISC + 4*q)
| AR_Q_MISC_QCU_COMP_EN);
}
-
+
/*
* Always update the secondary interrupt mask registers - this
* could be a new queue getting enabled in a running system or
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h
index 0e58bc61eba8..efe56a11965f 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h
@@ -64,7 +64,6 @@ struct ar5416_rx_desc { /* rx desc has 2 control words + 9 status words */
uint32_t status8;
};
-
struct ar5416_desc {
uint32_t ds_link; /* link pointer */
uint32_t ds_data; /* data buffer pointer */
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
index ff4f558efa83..85c1d6454952 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
@@ -669,7 +669,6 @@
#define AR_XSREV_VERSION_OWL_PCI 0x0D
#define AR_XSREV_VERSION_OWL_PCIE 0x0C
-
/*
* These are from ath9k/Atheros and assume an AR_SREV version mask
* of 0x07, rather than 0x0F which is being used in the FreeBSD HAL.
@@ -808,7 +807,6 @@
(AR_SREV_KIWI(_ah) && \
AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KIWI_13)
-
/* Not yet implemented chips */
#define AR_SREV_9271(_ah) 0
diff --git a/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c
index 1d78b053c372..70277cc6ca2a 100644
--- a/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c
+++ b/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c
@@ -173,7 +173,7 @@ ar9130Attach(uint16_t devid, HAL_SOFTC sc,
if (ecode != HAL_OK)
goto bad;
- if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */
+ if (!ar5416ChipReset(ah, AH_NULL, HAL_RESET_NORMAL)) { /* reset chip */
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
ecode = HAL_EIO;
goto bad;
@@ -243,7 +243,6 @@ ar9130Attach(uint16_t devid, HAL_SOFTC sc,
AH_PRIVATE(ah)->ah_currentRDext =
ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL);
-
/*
* ah_miscMode is populated by ar5416FillCapabilityInfo()
* starting from griffin. Set here to make sure that
diff --git a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
index f74da22d1e7c..b67699358aab 100644
--- a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
+++ b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
@@ -200,7 +200,7 @@ ar9160Attach(uint16_t devid, HAL_SOFTC sc,
HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes, ar9160PciePhy, 2);
ar5416AttachPCIE(ah);
- if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */
+ if (!ar5416ChipReset(ah, AH_NULL, HAL_RESET_NORMAL)) { /* reset chip */
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
ecode = HAL_EIO;
goto bad;
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
index 92479214e5a5..17604e720cef 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
@@ -259,7 +259,7 @@ ar9280Attach(uint16_t devid, HAL_SOFTC sc,
if (ecode != HAL_OK)
goto bad;
- if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */
+ if (!ar5416ChipReset(ah, AH_NULL, HAL_RESET_NORMAL)) { /* reset chip */
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
ecode = HAL_EIO;
goto bad;
@@ -434,7 +434,6 @@ ar9280ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore, HAL_BOOL power_off)
OS_DELAY(1000);
}
-
/*
* Set PCIe workaround bits
*
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c b/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c
index 5eeb420d5d3a..9d75e3b43131 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c
@@ -171,7 +171,6 @@ ar9280olcTemperatureCompensation(struct ath_hal *ah)
}
}
-
static int16_t
ar9280ChangeGainBoundarySettings(struct ath_hal *ah, uint16_t *gb,
uint16_t numXpdGain, uint16_t pdGainOverlap_t2, int8_t pwr_table_offset,
@@ -302,7 +301,6 @@ ar9280SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
(void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET, &pwr_table_offset);
-
if (IS_EEP_MINOR_V2(ah)) {
pdGainOverlap_t2 = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pdGainOverlap;
} else {
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285.c b/sys/dev/ath/ath_hal/ar9002/ar9285.c
index c4362637c173..0044f73a97c5 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9285.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9285.c
@@ -52,7 +52,6 @@ ar9285GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
"NF calibrated [ctl] [chain 0] is %d\n", nf);
nfarray[0] = nf;
-
nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1);
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
index 5c140b98dbb1..7fc6b96a25c9 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
@@ -196,7 +196,7 @@ ar9285Attach(uint16_t devid, HAL_SOFTC sc,
AH5416(ah)->ah_writeIni = ar9285WriteIni;
AH5416(ah)->ah_rx_chainmask = AR9285_DEFAULT_RXCHAINMASK;
AH5416(ah)->ah_tx_chainmask = AR9285_DEFAULT_TXCHAINMASK;
-
+
ahp->ah_maxTxTrigLev = MAX_TX_FIFO_THRESHOLD >> 1;
if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
@@ -249,7 +249,7 @@ ar9285Attach(uint16_t devid, HAL_SOFTC sc,
if (ecode != HAL_OK)
goto bad;
- if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */
+ if (!ar5416ChipReset(ah, AH_NULL, HAL_RESET_NORMAL)) { /* reset chip */
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n",
__func__);
ecode = HAL_EIO;
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_btcoex.c b/sys/dev/ath/ath_hal/ar9002/ar9285_btcoex.c
index 3a168ae45ead..0596f19c3b64 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9285_btcoex.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9285_btcoex.c
@@ -150,5 +150,3 @@ ar9285BTCoexSetParameter(struct ath_hal *ah, u_int32_t type, u_int32_t value)
break;
}
}
-
-
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c b/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c
index 3da59311e5dc..25ae031da2af 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c
@@ -77,7 +77,7 @@ ar9285SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
/* Store settings */
AH5212(ah)->ah_antControl = settings;
AH5212(ah)->ah_diversity = (settings == HAL_ANT_VARIABLE);
-
+
/* XXX don't fiddle if the PHY is in sleep mode or ! chan */
/* Begin setting the relevant registers */
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c
index 961e25e89efa..7b598a05720c 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c
@@ -107,7 +107,7 @@ ar9285SetTransmitPower(struct ath_hal *ah,
if (IS_EEP_MINOR_V2(ah)) {
AH5416(ah)->ah_ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
}
-
+
if (!ar9285SetPowerPerRateTable(ah, pEepData, chan,
&AH5416(ah)->ah_ratesArray[0],cfgCtl,
twiceAntennaReduction,
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
index 8341535bdb97..3cd13f73b772 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
@@ -146,7 +146,6 @@ ar9287Attach(uint16_t devid, HAL_SOFTC sc,
ah->ah_eepromdata = eepromdata;
}
-
/* XXX override with 9280 specific state */
/* override 5416 methods for our needs */
AH5416(ah)->ah_initPLL = ar9280InitPLL;
@@ -242,7 +241,7 @@ ar9287Attach(uint16_t devid, HAL_SOFTC sc,
if (ecode != HAL_OK)
goto bad;
- if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */
+ if (!ar5416ChipReset(ah, AH_NULL, HAL_RESET_NORMAL)) { /* reset chip */
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
ecode = HAL_EIO;
goto bad;
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c
index 09940a187e7d..3bdb4c7f0810 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c
@@ -41,7 +41,6 @@
#include "ar9002/ar9287_cal.h"
-
void
ar9287PACal(struct ath_hal *ah, HAL_BOOL is_reset)
{
@@ -55,7 +54,7 @@ HAL_BOOL
ar9287InitCalHardware(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-
+
/* Calibrate the AGC */
OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c
index 372d6c476d12..e4b6eed5bfec 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c
@@ -113,7 +113,6 @@ ar9287SetPowerCalTable(struct ath_hal *ah,
*pTxPowerIndexOffset = 0;
}
-
/* XXX hard-coded values? */
#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
diff --git a/sys/dev/ath/ath_rate/amrr/amrr.c b/sys/dev/ath/ath_rate/amrr/amrr.c
index 9a7518373c19..b04b728b2bc5 100644
--- a/sys/dev/ath/ath_rate/amrr/amrr.c
+++ b/sys/dev/ath/ath_rate/amrr/amrr.c
@@ -64,7 +64,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/socket.h>
-
+
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_arp.h>
@@ -104,8 +104,9 @@ ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an)
void
ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
- int shortPreamble, size_t frameLen,
- u_int8_t *rix, int *try0, u_int8_t *txrate)
+ int shortPreamble, size_t frameLen, int tid, int is_aggr,
+ u_int8_t *rix, int *try0, u_int8_t *txrate, int *maxdur,
+ int *maxpktlen)
{
struct amrr_node *amn = ATH_NODE_AMRR(an);
@@ -115,6 +116,8 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
*txrate = amn->amn_tx_rate0sp;
else
*txrate = amn->amn_tx_rate0;
+ maxdur = -1;
+ maxpktlen = -1;
}
/*
@@ -125,7 +128,7 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
*/
void
ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
- uint8_t rix0, struct ath_rc_series *rc)
+ uint8_t rix0, int is_aggr, struct ath_rc_series *rc)
{
struct amrr_node *amn = ATH_NODE_AMRR(an);
@@ -142,7 +145,6 @@ ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
rc[3].tries = amn->amn_tx_try3;
}
-
void
ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
struct ath_desc *ds, int shortPreamble, u_int8_t rix)
@@ -159,7 +161,7 @@ ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
void
ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
const struct ath_rc_series *rc, const struct ath_tx_status *ts,
- int frame_size, int nframes, int nbad)
+ int frame_size, int rc_framesize, int nframes, int nbad)
{
struct amrr_node *amn = ATH_NODE_AMRR(an);
int sr = ts->ts_shortretry;
@@ -196,6 +198,11 @@ ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
ath_rate_ctl_start(sc, &an->an_node);
}
+void
+ath_rate_update_rx_rssi(struct ath_softc *sc, struct ath_node *an, int rssi)
+{
+}
+
static void
node_reset(struct amrr_node *amn)
{
@@ -209,7 +216,6 @@ node_reset(struct amrr_node *amn)
amn->amn_success_threshold = ath_rate_min_success_threshold;
}
-
/**
* The code below assumes that we are dealing with hardware multi rate retry
* I have no idea what will happen if you try to use this module with another
@@ -408,7 +414,6 @@ ath_rate_ctl(void *arg, struct ieee80211_node *ni)
} else {
amn->amn_recovery = 0;
}
-
}
if (is_enough (amn) || rix != amn->amn_rix) {
/* reset counters. */
diff --git a/sys/dev/ath/ath_rate/onoe/onoe.c b/sys/dev/ath/ath_rate/onoe/onoe.c
index 05604c08823c..5229feaeebfd 100644
--- a/sys/dev/ath/ath_rate/onoe/onoe.c
+++ b/sys/dev/ath/ath_rate/onoe/onoe.c
@@ -52,7 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/socket.h>
-
+
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_arp.h>
@@ -112,8 +112,9 @@ ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an)
void
ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
- int shortPreamble, size_t frameLen,
- u_int8_t *rix, int *try0, u_int8_t *txrate)
+ int shortPreamble, size_t frameLen, int tid, int is_aggr,
+ u_int8_t *rix, int *try0, u_int8_t *txrate, int *maxdur,
+ int *maxpktlen)
{
struct onoe_node *on = ATH_NODE_ONOE(an);
@@ -123,6 +124,8 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
*txrate = on->on_tx_rate0sp;
else
*txrate = on->on_tx_rate0;
+ *maxdur = -1;
+ *maxpktlen = -1;
}
/*
@@ -133,7 +136,7 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
*/
void
ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
- uint8_t rix0, struct ath_rc_series *rc)
+ uint8_t rix0, int is_aggr, struct ath_rc_series *rc)
{
struct onoe_node *on = ATH_NODE_ONOE(an);
@@ -166,7 +169,7 @@ ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
void
ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
const struct ath_rc_series *rc, const struct ath_tx_status *ts,
- int frame_size, int nframes, int nbad)
+ int frame_size, int rc_framesize, int nframes, int nbad)
{
struct onoe_node *on = ATH_NODE_ONOE(an);
@@ -189,6 +192,11 @@ ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
ath_rate_ctl_start(sc, &an->an_node);
}
+void
+ath_rate_update_rx_rssi(struct ath_softc *sc, struct ath_node *an, int rssi)
+{
+}
+
static void
ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate)
{
@@ -218,7 +226,7 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate)
ni->ni_txrate = ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL;
on->on_tx_rix0 = sc->sc_rixmap[ni->ni_txrate];
on->on_tx_rate0 = rt->info[on->on_tx_rix0].rateCode;
-
+
on->on_tx_rate0sp = on->on_tx_rate0 |
rt->info[on->on_tx_rix0].shortPreamble;
if (sc->sc_mrretry) {
diff --git a/sys/dev/ath/ath_rate/sample/sample.c b/sys/dev/ath/ath_rate/sample/sample.c
index 45fad2786849..31df8a60c976 100644
--- a/sys/dev/ath/ath_rate/sample/sample.c
+++ b/sys/dev/ath/ath_rate/sample/sample.c
@@ -62,7 +62,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/socket.h>
-
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_media.h>
@@ -107,6 +107,140 @@ __FBSDID("$FreeBSD$");
* a few different packet sizes independently for each link.
*/
+/* XXX TODO: move this into ath_hal/net80211 so it can be shared */
+
+#define MCS_HT20 0
+#define MCS_HT20_SGI 1
+#define MCS_HT40 2
+#define MCS_HT40_SGI 3
+
+/*
+ * This is currently a copy/paste from the 11n tx code.
+ *
+ * It's used to determine the maximum frame length allowed for the
+ * given rate. For now this ignores SGI/LGI and will assume long-GI.
+ * This only matters for lower rates that can't fill a full 64k A-MPDU.
+ *
+ * (But it's also important because right now rate control doesn't set
+ * flags like SGI/LGI, STBC, LDPC, TX power, etc.)
+ *
+ * When selecting a set of rates the rate control code will iterate
+ * over the HT20/HT40 max frame length and tell the caller the maximum
+ * length (@ LGI.) It will also choose a bucket that's the minimum
+ * of this value and the provided aggregate length. That way the
+ * rate selection will closely match what the eventual formed aggregate
+ * will be rather than "not at all".
+ */
+
+static int ath_rate_sample_max_4ms_framelen[4][32] = {
+ [MCS_HT20] = {
+ 3212, 6432, 9648, 12864, 19300, 25736, 28952, 32172,
+ 6424, 12852, 19280, 25708, 38568, 51424, 57852, 64280,
+ 9628, 19260, 28896, 38528, 57792, 65532, 65532, 65532,
+ 12828, 25656, 38488, 51320, 65532, 65532, 65532, 65532,
+ },
+ [MCS_HT20_SGI] = {
+ 3572, 7144, 10720, 14296, 21444, 28596, 32172, 35744,
+ 7140, 14284, 21428, 28568, 42856, 57144, 64288, 65532,
+ 10700, 21408, 32112, 42816, 64228, 65532, 65532, 65532,
+ 14256, 28516, 42780, 57040, 65532, 65532, 65532, 65532,
+ },
+ [MCS_HT40] = {
+ 6680, 13360, 20044, 26724, 40092, 53456, 60140, 65532,
+ 13348, 26700, 40052, 53400, 65532, 65532, 65532, 65532,
+ 20004, 40008, 60016, 65532, 65532, 65532, 65532, 65532,
+ 26644, 53292, 65532, 65532, 65532, 65532, 65532, 65532,
+ },
+ [MCS_HT40_SGI] = {
+ 7420, 14844, 22272, 29696, 44544, 59396, 65532, 65532,
+ 14832, 29668, 44504, 59340, 65532, 65532, 65532, 65532,
+ 22232, 44464, 65532, 65532, 65532, 65532, 65532, 65532,
+ 29616, 59232, 65532, 65532, 65532, 65532, 65532, 65532,
+ }
+};
+
+/*
+ * Given the (potentially MRR) transmit schedule, calculate the maximum
+ * allowed packet size for forming aggregates based on the lowest
+ * MCS rate in the transmit schedule.
+ *
+ * Returns -1 if it's a legacy rate or no MRR.
+ *
+ * XXX TODO: this needs to be limited by the RTS/CTS AR5416 8KB bug limit!
+ * (by checking rts/cts flags and applying sc_rts_aggr_limit)
+ *
+ * XXX TODO: apply per-node max-ampdu size and driver ampdu size limits too.
+ */
+static int
+ath_rate_sample_find_min_pktlength(struct ath_softc *sc,
+ struct ath_node *an, uint8_t rix0, int is_aggr)
+{
+#define MCS_IDX(ix) (rt->info[ix].dot11Rate)
+ const HAL_RATE_TABLE *rt = sc->sc_currates;
+ struct sample_node *sn = ATH_NODE_SAMPLE(an);
+ const struct txschedule *sched = &sn->sched[rix0];
+ int max_pkt_length = 65530; // ATH_AGGR_MAXSIZE
+ // Note: this may not be true in all cases; need to check?
+ int is_ht40 = (an->an_node.ni_chw == 40);
+ // Note: not great, but good enough..
+ int idx = is_ht40 ? MCS_HT40 : MCS_HT20;
+
+ if (rt->info[rix0].phy != IEEE80211_T_HT) {
+ return -1;
+ }
+
+ if (! sc->sc_mrretry) {
+ return -1;
+ }
+
+ KASSERT(rix0 == sched->r0, ("rix0 (%x) != sched->r0 (%x)!\n",
+ rix0, sched->r0));
+
+ /*
+ * Update based on sched->r{0,1,2,3} if sched->t{0,1,2,3}
+ * is not zero.
+ *
+ * Note: assuming all four PHYs are HT!
+ *
+ * XXX TODO: right now I hardcode here and in getxtxrates() that
+ * rates 2 and 3 in the tx schedule are ignored. This is important
+ * for forming larger aggregates because right now (a) the tx schedule
+ * per rate is fixed, and (b) reliable packet transmission at those
+ * higher rates kinda needs a lower MCS rate in there somewhere.
+ * However, this means we can only form shorter aggregates.
+ * If we've negotiated aggregation then we can actually just
+ * rely on software retransmit rather than having things fall
+ * back to like MCS0/1 in hardware, and rate control will hopefully
+ * do the right thing.
+ *
+ * Once the whole rate schedule is passed into ath_rate_findrate(),
+ * the ath_rc_series is populated ,the fixed tx schedule stuff
+ * is removed AND getxtxrates() is removed then we can remove this
+ * check as it can just NOT populate t2/t3. It also means
+ * probing can actually use rix0 for probeing and rix1 for the
+ * current best rate..
+ */
+ if (sched->t0 != 0) {
+ max_pkt_length = MIN(max_pkt_length,
+ ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r0)]);
+ }
+ if (sched->t1 != 0) {
+ max_pkt_length = MIN(max_pkt_length,
+ ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r1)]);
+ }
+ if (sched->t2 != 0 && (! is_aggr)) {
+ max_pkt_length = MIN(max_pkt_length,
+ ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r2)]);
+ }
+ if (sched->t3 != 0 && (! is_aggr)) {
+ max_pkt_length = MIN(max_pkt_length,
+ ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r3)]);
+ }
+
+ return max_pkt_length;
+#undef MCS
+}
+
static void ath_rate_ctl_reset(struct ath_softc *, struct ieee80211_node *);
static __inline int
@@ -125,6 +259,22 @@ size_to_bin(int size)
return 2;
#endif
#if NUM_PACKET_SIZE_BINS > 4
+ if (size <= packet_size_bins[3])
+ return 3;
+#endif
+#if NUM_PACKET_SIZE_BINS > 5
+ if (size <= packet_size_bins[4])
+ return 4;
+#endif
+#if NUM_PACKET_SIZE_BINS > 6
+ if (size <= packet_size_bins[5])
+ return 5;
+#endif
+#if NUM_PACKET_SIZE_BINS > 7
+ if (size <= packet_size_bins[6])
+ return 6;
+#endif
+#if NUM_PACKET_SIZE_BINS > 8
#error "add support for more packet sizes"
#endif
return NUM_PACKET_SIZE_BINS-1;
@@ -167,12 +317,12 @@ pick_best_rate(struct ath_node *an, const HAL_RATE_TABLE *rt,
int size_bin, int require_acked_before)
{
struct sample_node *sn = ATH_NODE_SAMPLE(an);
- int best_rate_rix, best_rate_tt, best_rate_pct;
+ int best_rate_rix, best_rate_tt, best_rate_pct;
uint64_t mask;
int rix, tt, pct;
- best_rate_rix = 0;
- best_rate_tt = 0;
+ best_rate_rix = 0;
+ best_rate_tt = 0;
best_rate_pct = 0;
for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) {
if ((mask & 1) == 0) /* not a supported rate */
@@ -194,8 +344,7 @@ pick_best_rate(struct ath_node *an, const HAL_RATE_TABLE *rt,
if (sn->stats[size_bin][rix].total_packets > 0) {
pct = sn->stats[size_bin][rix].ewma_pct;
} else {
- /* XXX for now, assume 95% ok */
- pct = 95;
+ pct = -1; /* No percent yet to compare against! */
}
/* don't use a bit-rate that has been failing */
@@ -203,18 +352,35 @@ pick_best_rate(struct ath_node *an, const HAL_RATE_TABLE *rt,
continue;
/*
- * For HT, Don't use a bit rate that is much more
- * lossy than the best.
+ * For HT, Don't use a bit rate that is more
+ * lossy than the best. Give a bit of leeway.
*
- * XXX this isn't optimal; it's just designed to
- * eliminate rates that are going to be obviously
- * worse.
+ * Don't consider best rates that we haven't seen
+ * packets for yet; let sampling start inflence that.
*/
if (an->an_node.ni_flags & IEEE80211_NODE_HT) {
+ if (pct == -1)
+ continue;
+#if 0
+ IEEE80211_NOTE(an->an_node.ni_vap,
+ IEEE80211_MSG_RATECTL,
+ &an->an_node,
+ "%s: size %d comparing best rate 0x%x pkts/ewma/tt (%ju/%d/%d) "
+ "to 0x%x pkts/ewma/tt (%ju/%d/%d)",
+ __func__,
+ bin_to_size(size_bin),
+ rt->info[best_rate_rix].dot11Rate,
+ sn->stats[size_bin][best_rate_rix].total_packets,
+ best_rate_pct,
+ best_rate_tt,
+ rt->info[rix].dot11Rate,
+ sn->stats[size_bin][rix].total_packets,
+ pct,
+ tt);
+#endif
if (best_rate_pct > (pct + 50))
continue;
}
-
/*
* For non-MCS rates, use the current average txtime for
* comparison.
@@ -228,19 +394,19 @@ pick_best_rate(struct ath_node *an, const HAL_RATE_TABLE *rt,
}
/*
- * Since 2 stream rates have slightly higher TX times,
+ * Since 2 and 3 stream rates have slightly higher TX times,
* allow a little bit of leeway. This should later
* be abstracted out and properly handled.
*/
if (an->an_node.ni_flags & IEEE80211_NODE_HT) {
- if (best_rate_tt == 0 || (tt * 8 <= best_rate_tt * 10)) {
+ if (best_rate_tt == 0 || ((tt * 10) <= (best_rate_tt * 10))) {
best_rate_tt = tt;
best_rate_rix = rix;
best_rate_pct = pct;
}
}
- }
- return (best_rate_tt ? best_rate_rix : -1);
+ }
+ return (best_rate_tt ? best_rate_rix : -1);
}
/*
@@ -256,11 +422,11 @@ pick_sample_rate(struct sample_softc *ssc , struct ath_node *an,
int current_rix, rix;
unsigned current_tt;
uint64_t mask;
-
+
current_rix = sn->current_rix[size_bin];
if (current_rix < 0) {
/* no successes yet, send at the lowest bit-rate */
- /* XXX should return MCS0 if HT */
+ /* XXX TODO should return MCS0 if HT */
return 0;
}
@@ -316,10 +482,22 @@ pick_sample_rate(struct sample_softc *ssc , struct ath_node *an,
/*
* For HT, only sample a few rates on either side of the
* current rix; there's quite likely a lot of them.
+ *
+ * This is limited to testing rate indexes on either side of
+ * this MCS, but for all spatial streams.
+ *
+ * Otherwise we'll (a) never really sample higher MCS
+ * rates if we're stuck low, and we'll make weird moves
+ * like sample MCS8 if we're using MCS7.
*/
if (an->an_node.ni_flags & IEEE80211_NODE_HT) {
- if (rix < (current_rix - 3) ||
- rix > (current_rix + 3)) {
+ uint8_t current_mcs, rix_mcs;
+
+ current_mcs = MCS(current_rix) & 0x7;
+ rix_mcs = MCS(rix) & 0x7;
+
+ if (rix_mcs < (current_mcs - 2) ||
+ rix_mcs > (current_mcs + 2)) {
mask &= ~((uint64_t) 1<<rix);
goto nextrate;
}
@@ -459,11 +637,11 @@ ath_rate_pick_seed_rate_ht(struct ath_softc *sc, struct ath_node *an,
continue;
/*
- * Pick a medium-speed rate regardless of stream count
- * which has not seen any failures. Higher rates may fail;
- * we'll try them later.
+ * Pick a medium-speed rate at 1 spatial stream
+ * which has not seen any failures.
+ * Higher rates may fail; we'll try them later.
*/
- if (((MCS(rix) & 0x7) <= 4) &&
+ if (((MCS(rix)& 0x7f) <= 4) &&
sn->stats[size_bin][rix].successive_failures == 0) {
break;
}
@@ -479,11 +657,11 @@ ath_rate_pick_seed_rate_ht(struct ath_softc *sc, struct ath_node *an,
#undef DOT11RATE
}
-
void
ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
- int shortPreamble, size_t frameLen,
- u_int8_t *rix0, int *try0, u_int8_t *txrate)
+ int shortPreamble, size_t frameLen, int tid,
+ int is_aggr, u_int8_t *rix0, int *try0,
+ u_int8_t *txrate, int *maxdur, int *maxpktlen)
{
#define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
#define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
@@ -492,12 +670,22 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);
struct ieee80211com *ic = &sc->sc_ic;
const HAL_RATE_TABLE *rt = sc->sc_currates;
- const int size_bin = size_to_bin(frameLen);
+ int size_bin = size_to_bin(frameLen);
int rix, mrr, best_rix, change_rates;
unsigned average_tx_time;
+ int max_pkt_len;
ath_rate_update_static_rix(sc, &an->an_node);
+ /* For now don't take TID, is_aggr into account */
+ /* Also for now don't calculate a max duration; that'll come later */
+ *maxdur = -1;
+
+ /*
+ * For now just set it to the frame length; we'll optimise it later.
+ */
+ *maxpktlen = frameLen;
+
if (sn->currates != sc->sc_currates) {
device_printf(sc->sc_dev, "%s: currates != sc_currates!\n",
__func__);
@@ -509,28 +697,62 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
if (sn->static_rix != -1) {
rix = sn->static_rix;
*try0 = ATH_TXMAXTRY;
+
+ /*
+ * Ensure we limit max packet length here too!
+ */
+ max_pkt_len = ath_rate_sample_find_min_pktlength(sc, an,
+ sn->static_rix,
+ is_aggr);
+ if (max_pkt_len > 0) {
+ *maxpktlen = frameLen = MIN(frameLen, max_pkt_len);
+ size_bin = size_to_bin(frameLen);
+ }
goto done;
}
mrr = sc->sc_mrretry;
/* XXX check HT protmode too */
+ /* XXX turn into a cap; 11n MACs support MRR+RTSCTS */
if (mrr && (ic->ic_flags & IEEE80211_F_USEPROT && !sc->sc_mrrprot))
mrr = 0;
best_rix = pick_best_rate(an, rt, size_bin, !mrr);
+
+ /*
+ * At this point we've chosen the best rix, so now we
+ * need to potentially update our maximum packet length
+ * and size_bin if we're doing 11n rates.
+ */
+ max_pkt_len = ath_rate_sample_find_min_pktlength(sc, an, best_rix,
+ is_aggr);
+ if (max_pkt_len > 0) {
+#if 0
+ device_printf(sc->sc_dev,
+ "Limiting maxpktlen from %d to %d bytes\n",
+ (int) frameLen, max_pkt_len);
+#endif
+ *maxpktlen = frameLen = MIN(frameLen, max_pkt_len);
+ size_bin = size_to_bin(frameLen);
+ }
+
if (best_rix >= 0) {
average_tx_time = sn->stats[size_bin][best_rix].average_tx_time;
} else {
average_tx_time = 0;
}
+
/*
* Limit the time measuring the performance of other tx
* rates to sample_rate% of the total transmission time.
*/
- if (sn->sample_tt[size_bin] < average_tx_time * (sn->packets_since_sample[size_bin]*ssc->sample_rate/100)) {
+ if (sn->sample_tt[size_bin] <
+ average_tx_time *
+ (sn->packets_since_sample[size_bin]*ssc->sample_rate/100)) {
rix = pick_sample_rate(ssc, an, rt, size_bin);
IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
- &an->an_node, "att %d sample_tt %d size %u sample rate %d %s current rate %d %s",
+ &an->an_node, "att %d sample_tt %d size %u "
+ "sample rate %d %s current rate %d %s",
average_tx_time,
sn->sample_tt[size_bin],
bin_to_size(size_bin),
@@ -581,9 +803,9 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
int cur_rix = sn->current_rix[size_bin];
int cur_att = sn->stats[size_bin][cur_rix].average_tx_time;
/*
- * If the node is HT, upgrade it if the MCS rate is
- * higher and the average tx time is within 20% of
- * the current rate. It can fail a little.
+ * If the node is HT, it if the rate isn't the
+ * same and the average tx time is within 10%
+ * of the current rate. It can fail a little.
*
* This is likely not optimal!
*/
@@ -591,13 +813,16 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
printf("cur rix/att %x/%d, best rix/att %x/%d\n",
MCS(cur_rix), cur_att, MCS(best_rix), average_tx_time);
#endif
- if ((MCS(best_rix) > MCS(cur_rix)) &&
- (average_tx_time * 8) <= (cur_att * 10)) {
+ if ((best_rix != cur_rix) &&
+ (average_tx_time * 9) <= (cur_att * 10)) {
IEEE80211_NOTE(an->an_node.ni_vap,
IEEE80211_MSG_RATECTL, &an->an_node,
- "%s: HT: best_rix 0x%d > cur_rix 0x%x, average_tx_time %d, cur_att %d",
- __func__,
- MCS(best_rix), MCS(cur_rix), average_tx_time, cur_att);
+ "%s: HT: size %d best_rix 0x%x > "
+ " cur_rix 0x%x, average_tx_time %d,"
+ " cur_att %d",
+ __func__, bin_to_size(size_bin),
+ MCS(best_rix), MCS(cur_rix),
+ average_tx_time, cur_att);
change_rates = 1;
}
}
@@ -609,15 +834,19 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
IEEE80211_NOTE(an->an_node.ni_vap,
IEEE80211_MSG_RATECTL,
&an->an_node,
-"%s: size %d switch rate %d (%d/%d) -> %d (%d/%d) after %d packets mrr %d",
+"%s: size %d switch rate %d %s (%d/%d) EWMA %d -> %d %s (%d/%d) EWMA %d after %d packets mrr %d",
__func__,
bin_to_size(size_bin),
- RATE(sn->current_rix[size_bin]),
+ dot11rate(rt, sn->current_rix[size_bin]),
+ dot11rate_label(rt, sn->current_rix[size_bin]),
sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time,
sn->stats[size_bin][sn->current_rix[size_bin]].perfect_tx_time,
- RATE(best_rix),
+ sn->stats[size_bin][sn->current_rix[size_bin]].ewma_pct,
+ dot11rate(rt, best_rix),
+ dot11rate_label(rt, best_rix),
sn->stats[size_bin][best_rix].average_tx_time,
sn->stats[size_bin][best_rix].perfect_tx_time,
+ sn->stats[size_bin][best_rix].ewma_pct,
sn->packets_since_switch[size_bin],
mrr);
}
@@ -627,7 +856,9 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
/*
* Set the visible txrate for this node.
*/
- an->an_node.ni_txrate = (rt->info[best_rix].phy == IEEE80211_T_HT) ? MCS(best_rix) : DOT11RATE(best_rix);
+ an->an_node.ni_txrate =
+ (rt->info[best_rix].phy == IEEE80211_T_HT) ?
+ MCS(best_rix) : DOT11RATE(best_rix);
}
rix = sn->current_rix[size_bin];
sn->packets_since_switch[size_bin]++;
@@ -654,6 +885,7 @@ done:
*txrate = rt->info[rix].rateCode
| (shortPreamble ? rt->info[rix].shortPreamble : 0);
sn->packets_sent[size_bin]++;
+
#undef DOT11RATE
#undef MCS
#undef RATE
@@ -665,7 +897,7 @@ done:
*/
void
ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
- uint8_t rix0, struct ath_rc_series *rc)
+ uint8_t rix0, int is_aggr, struct ath_rc_series *rc)
{
struct sample_node *sn = ATH_NODE_SAMPLE(an);
const struct txschedule *sched = &sn->sched[rix0];
@@ -682,8 +914,13 @@ ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
rc[0].tries = sched->t0;
rc[1].tries = sched->t1;
- rc[2].tries = sched->t2;
- rc[3].tries = sched->t3;
+
+ if (is_aggr) {
+ rc[2].tries = rc[3].tries = 0;
+ } else {
+ rc[2].tries = sched->t2;
+ rc[3].tries = sched->t3;
+ }
}
void
@@ -711,13 +948,22 @@ ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
s3code, sched->t3); /* series 3 */
}
+/*
+ * Update the current statistics.
+ *
+ * Note that status is for the FINAL transmit status, not this
+ * particular attempt. So, check if tries > tries0 and if so
+ * assume this status failed.
+ *
+ * This is important because some failures are due to both
+ * short AND long retries; if the final issue was a short
+ * retry failure then we still want to account for the
+ * bad long retry attempts.
+ */
static void
update_stats(struct ath_softc *sc, struct ath_node *an,
int frame_size,
int rix0, int tries0,
- int rix1, int tries1,
- int rix2, int tries2,
- int rix3, int tries3,
int short_tries, int tries, int status,
int nframes, int nbad)
{
@@ -728,38 +974,39 @@ update_stats(struct ath_softc *sc, struct ath_node *an,
#endif
const int size_bin = size_to_bin(frame_size);
const int size = bin_to_size(size_bin);
- int tt, tries_so_far;
+ int tt;
int is_ht40 = (an->an_node.ni_chw == 40);
int pct;
if (!IS_RATE_DEFINED(sn, rix0))
return;
- tt = calc_usecs_unicast_packet(sc, size, rix0, short_tries,
- MIN(tries0, tries) - 1, is_ht40);
- tries_so_far = tries0;
- if (tries1 && tries_so_far < tries) {
- if (!IS_RATE_DEFINED(sn, rix1))
- return;
- tt += calc_usecs_unicast_packet(sc, size, rix1, short_tries,
- MIN(tries1 + tries_so_far, tries) - tries_so_far - 1, is_ht40);
- tries_so_far += tries1;
+ /*
+ * Treat long retries as us exceeding retries, even
+ * if the eventual attempt at some other MRR schedule
+ * succeeded.
+ */
+ if (tries > tries0) {
+ status = HAL_TXERR_XRETRY;
}
- if (tries2 && tries_so_far < tries) {
- if (!IS_RATE_DEFINED(sn, rix2))
- return;
- tt += calc_usecs_unicast_packet(sc, size, rix2, short_tries,
- MIN(tries2 + tries_so_far, tries) - tries_so_far - 1, is_ht40);
- tries_so_far += tries2;
- }
+ /*
+ * If status is FAIL then we treat all frames as bad.
+ * This better accurately tracks EWMA and average TX time
+ * because even if the eventual transmission succeeded,
+ * transmission at this rate did not.
+ */
+ if (status != 0)
+ nbad = nframes;
- if (tries3 && tries_so_far < tries) {
- if (!IS_RATE_DEFINED(sn, rix3))
- return;
- tt += calc_usecs_unicast_packet(sc, size, rix3, short_tries,
- MIN(tries3 + tries_so_far, tries) - tries_so_far - 1, is_ht40);
- }
+ /*
+ * Ignore short tries count as contributing to failure.
+ * Right now there's no way to know if it's part of any
+ * given rate attempt, and outside of the RTS/CTS management
+ * rate, it doesn't /really/ help.
+ */
+ tt = calc_usecs_unicast_packet(sc, size, rix0,
+ 0 /* short_tries */, MIN(tries0, tries) - 1, is_ht40);
if (sn->stats[size_bin][rix0].total_packets < ssc->smoothing_minpackets) {
/* just average the first few packets */
@@ -772,34 +1019,9 @@ update_stats(struct ath_softc *sc, struct ath_node *an,
((sn->stats[size_bin][rix0].average_tx_time * ssc->smoothing_rate) +
(tt * (100 - ssc->smoothing_rate))) / 100;
}
-
- /*
- * XXX Don't mark the higher bit rates as also having failed; as this
- * unfortunately stops those rates from being tasted when trying to
- * TX. This happens with 11n aggregation.
- *
- * This is valid for higher CCK rates, higher OFDM rates, and higher
- * HT rates within the current number of streams (eg MCS0..7, 8..15,
- * etc.)
- */
+
if (nframes == nbad) {
-#if 0
- int y;
-#endif
sn->stats[size_bin][rix0].successive_failures += nbad;
-#if 0
- for (y = size_bin+1; y < NUM_PACKET_SIZE_BINS; y++) {
- /*
- * Also say larger packets failed since we
- * assume if a small packet fails at a
- * bit-rate then a larger one will also.
- */
- sn->stats[y][rix0].successive_failures += nbad;
- sn->stats[y][rix0].last_tx = ticks;
- sn->stats[y][rix0].tries += tries;
- sn->stats[y][rix0].total_packets += nframes;
- }
-#endif
} else {
sn->stats[size_bin][rix0].packets_acked += (nframes - nbad);
sn->stats[size_bin][rix0].successive_failures = 0;
@@ -828,20 +1050,31 @@ update_stats(struct ath_softc *sc, struct ath_node *an,
(pct * (100 - ssc->smoothing_rate))) / 100;
}
+ /*
+ * Only update the sample time for the initial sample rix.
+ * We've updated the statistics on each of the other retries
+ * fine, but we should only update the sample_tt with what
+ * was actually sampled.
+ *
+ * However, to aide in debugging, log all the failures for
+ * each of the buckets
+ */
+ IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
+ &an->an_node,
+ "%s: size %d %s %s rate %d %s tries (%d/%d) tt %d "
+ "avg_tt (%d/%d) nfrm %d nbad %d",
+ __func__,
+ size,
+ status ? "FAIL" : "OK",
+ rix0 == sn->current_sample_rix[size_bin] ? "sample" : "mrr",
+ dot11rate(rt, rix0),
+ dot11rate_label(rt, rix0),
+ short_tries, tries, tt,
+ sn->stats[size_bin][rix0].average_tx_time,
+ sn->stats[size_bin][rix0].perfect_tx_time,
+ nframes, nbad);
if (rix0 == sn->current_sample_rix[size_bin]) {
- IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
- &an->an_node,
-"%s: size %d %s sample rate %d %s tries (%d/%d) tt %d avg_tt (%d/%d) nfrm %d nbad %d",
- __func__,
- size,
- status ? "FAIL" : "OK",
- dot11rate(rt, rix0),
- dot11rate_label(rt, rix0),
- short_tries, tries, tt,
- sn->stats[size_bin][rix0].average_tx_time,
- sn->stats[size_bin][rix0].perfect_tx_time,
- nframes, nbad);
sn->sample_tt[size_bin] = tt;
sn->current_sample_rix[size_bin] = -1;
}
@@ -859,7 +1092,7 @@ badrate(struct ath_softc *sc, int series, int hwrate, int tries, int status)
void
ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
const struct ath_rc_series *rc, const struct ath_tx_status *ts,
- int frame_size, int nframes, int nbad)
+ int frame_size, int rc_framesize, int nframes, int nbad)
{
struct ieee80211com *ic = &sc->sc_ic;
struct sample_node *sn = ATH_NODE_SAMPLE(an);
@@ -879,6 +1112,40 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
if (frame_size == 0) /* NB: should not happen */
frame_size = 1500;
+ if (rc_framesize == 0) /* NB: should not happen */
+ rc_framesize = 1500;
+
+ /*
+ * There are still some places where what rate control set as
+ * a limit but the hardware decided, for some reason, to transmit
+ * at a smaller size that fell into a different bucket.
+ *
+ * The eternal question here is - which size_bin should it go in?
+ * The one that was requested, or the one that was transmitted?
+ *
+ * Here's the problem - if we use the one that was transmitted,
+ * we may continue to hit corner cases where we make a rate
+ * selection using a higher bin but only update the smaller bin;
+ * thus never really "adapting".
+ *
+ * If however we update the larger bin, we're not accurately
+ * representing the channel state at that frame/aggregate size.
+ * However if we keep hitting the larger request but completing
+ * a smaller size, we at least updates based on what the
+ * request was /for/.
+ *
+ * I'm going to err on the side of caution and choose the
+ * latter.
+ */
+ if (size_to_bin(frame_size) != size_to_bin(rc_framesize)) {
+#if 0
+ device_printf(sc->sc_dev,
+ "%s: completed but frame size buckets mismatch "
+ "(completed %d tx'ed %d)\n",
+ __func__, frame_size, rc_framesize);
+#endif
+ frame_size = rc_framesize;
+ }
if (sn->ratemask == 0) {
IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
@@ -916,9 +1183,6 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
short_tries, long_tries, nframes, nbad);
update_stats(sc, an, frame_size,
final_rix, long_tries,
- 0, 0,
- 0, 0,
- 0, 0,
short_tries, long_tries, status,
nframes, nbad);
@@ -957,20 +1221,15 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
}
/*
- * NB: series > 0 are not penalized for failure
- * based on the try counts under the assumption
- * that losses are often bursty and since we
- * sample higher rates 1 try at a time doing so
- * may unfairly penalize them.
+ * This used to not penalise other tries because loss
+ * can be bursty, but it's then not accurately keeping
+ * the avg TX time and EWMA updated.
*/
if (rc[0].tries) {
update_stats(sc, an, frame_size,
rc[0].rix, rc[0].tries,
- rc[1].rix, rc[1].tries,
- rc[2].rix, rc[2].tries,
- rc[3].rix, rc[3].tries,
short_tries, long_tries,
- long_tries > rc[0].tries,
+ status,
nframes, nbad);
long_tries -= rc[0].tries;
}
@@ -978,9 +1237,6 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
if (rc[1].tries && finalTSIdx > 0) {
update_stats(sc, an, frame_size,
rc[1].rix, rc[1].tries,
- rc[2].rix, rc[2].tries,
- rc[3].rix, rc[3].tries,
- 0, 0,
short_tries, long_tries,
status,
nframes, nbad);
@@ -990,9 +1246,6 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
if (rc[2].tries && finalTSIdx > 1) {
update_stats(sc, an, frame_size,
rc[2].rix, rc[2].tries,
- rc[3].rix, rc[3].tries,
- 0, 0,
- 0, 0,
short_tries, long_tries,
status,
nframes, nbad);
@@ -1002,9 +1255,6 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
if (rc[3].tries && finalTSIdx > 2) {
update_stats(sc, an, frame_size,
rc[3].rix, rc[3].tries,
- 0, 0,
- 0, 0,
- 0, 0,
short_tries, long_tries,
status,
nframes, nbad);
@@ -1019,6 +1269,11 @@ ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
ath_rate_ctl_reset(sc, &an->an_node);
}
+void
+ath_rate_update_rx_rssi(struct ath_softc *sc, struct ath_node *an, int rssi)
+{
+}
+
static const struct txschedule *mrr_schedules[IEEE80211_MODE_MAX+2] = {
NULL, /* IEEE80211_MODE_AUTO */
series_11a, /* IEEE80211_MODE_11A */
@@ -1375,7 +1630,7 @@ struct ath_ratectrl *
ath_rate_attach(struct ath_softc *sc)
{
struct sample_softc *ssc;
-
+
ssc = malloc(sizeof(struct sample_softc), M_DEVBUF, M_NOWAIT|M_ZERO);
if (ssc == NULL)
return NULL;
@@ -1394,6 +1649,6 @@ void
ath_rate_detach(struct ath_ratectrl *arc)
{
struct sample_softc *ssc = (struct sample_softc *) arc;
-
+
free(ssc, M_DEVBUF);
}
diff --git a/sys/dev/ath/ath_rate/sample/sample.h b/sys/dev/ath/ath_rate/sample/sample.h
index a4f471e1c188..3b6fe9f6fba2 100644
--- a/sys/dev/ath/ath_rate/sample/sample.h
+++ b/sys/dev/ath/ath_rate/sample/sample.h
@@ -76,12 +76,11 @@ struct txschedule {
};
/*
- * for now, we track performance for three different packet
- * size buckets
+ * We track performance for eight different packet size buckets.
*/
-#define NUM_PACKET_SIZE_BINS 2
+#define NUM_PACKET_SIZE_BINS 7
-static const int packet_size_bins[NUM_PACKET_SIZE_BINS] = { 250, 1600 };
+static const int packet_size_bins[NUM_PACKET_SIZE_BINS] = { 250, 1600, 4096, 8192, 16384, 32768, 65536 };
static inline int
bin_to_size(int index)
@@ -106,7 +105,7 @@ struct sample_node {
int current_rix[NUM_PACKET_SIZE_BINS];
int packets_since_switch[NUM_PACKET_SIZE_BINS];
- unsigned ticks_since_switch[NUM_PACKET_SIZE_BINS];
+ int ticks_since_switch[NUM_PACKET_SIZE_BINS];
int packets_since_sample[NUM_PACKET_SIZE_BINS];
unsigned sample_tt[NUM_PACKET_SIZE_BINS];
@@ -138,7 +137,7 @@ static unsigned calc_usecs_unicast_packet(struct ath_softc *sc,
const HAL_RATE_TABLE *rt = sc->sc_currates;
struct ieee80211com *ic = &sc->sc_ic;
int rts, cts;
-
+
unsigned t_slot = 20;
unsigned t_difs = 50;
unsigned t_sifs = 10;
@@ -146,7 +145,7 @@ static unsigned calc_usecs_unicast_packet(struct ath_softc *sc,
int x = 0;
int cw = WIFI_CW_MIN;
int cix;
-
+
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
if (rix >= rt->rateCount) {
diff --git a/sys/dev/ath/ath_rate/sample/tx_schedules.h b/sys/dev/ath/ath_rate/sample/tx_schedules.h
index 02805bec6566..c89ba59f111b 100644
--- a/sys/dev/ath/ath_rate/sample/tx_schedules.h
+++ b/sys/dev/ath/ath_rate/sample/tx_schedules.h
@@ -172,30 +172,30 @@ static const struct txschedule series_11ng[] = {
{ 4,NG1( 26), 3,NG1(19.5), 4,NG1( 6.5), 2,NG1(6.5) }, /* 26Mb/s */
{ 4,NG1( 39), 3,NG1( 26), 4,NG1(19.5), 2,NG1(6.5) }, /* 39Mb/s */
{ 4,NG1( 52), 3,NG1( 39), 4,NG1( 26), 2,NG1(6.5) }, /* 52Mb/s */
- { 4,NG1(58.5), 3,NG1( 52), 4,NG1( 39), 2,NG1( 13) }, /*58.5Mb/s */
- { 4,NG1( 65), 3,NG1(58.5), 4,NG1( 52), 2,NG1( 13) }, /* 65Mb/s */
+ { 4,NG1(58.5), 3,NG1( 52), 4,NG1( 39), 2,NG1(6.5) }, /*58.5Mb/s */
+ { 4,NG1( 65), 3,NG1(58.5), 4,NG1( 52), 2,NG1(6.5) }, /* 65Mb/s */
/* 2 stream rates */
- { 3,NG2( 13), 3,NG2( 13), 0,NG2( 13), 0,NG2( 13) }, /* 13Mb/s */
- { 4,NG2( 26), 3,NG2( 13), 4,NG2( 13), 0,NG2( 13) }, /* 26Mb/s */
- { 4,NG2( 39), 3,NG2( 26), 4,NG2( 13), 2,NG2( 13) }, /* 39Mb/s */
- { 4,NG2( 52), 3,NG2( 39), 4,NG2( 26), 2,NG2( 13) }, /* 52Mb/s */
- { 4,NG2( 78), 3,NG2( 52), 4,NG2( 39), 2,NG2( 13) }, /* 78Mb/s */
- { 4,NG2( 104), 3,NG2( 78), 4,NG2( 52), 2,NG2( 13) }, /* 104Mb/s */
- { 4,NG2( 117), 3,NG2( 104), 4,NG2( 78), 2,NG2( 26) }, /* 117Mb/s */
- { 4,NG2( 130), 3,NG2( 117), 4,NG2( 104), 2,NG2( 26) }, /* 130Mb/s */
+ { 3,NG2( 13), 3,NG1(6.5), 0,NG2( 13), 0,NG2( 13) }, /* 13Mb/s */
+ { 4,NG2( 26), 3,NG2( 13), 4,NG1(6.5), 0,NG2( 13) }, /* 26Mb/s */
+ { 4,NG2( 39), 3,NG2( 26), 4,NG2( 13), 2,NG1(6.5) }, /* 39Mb/s */
+ { 4,NG2( 52), 3,NG2( 39), 4,NG2( 26), 2,NG1(6.5) }, /* 52Mb/s */
+ { 4,NG2( 78), 3,NG2( 52), 4,NG2( 39), 2,NG1(6.5) }, /* 78Mb/s */
+ { 4,NG2( 104), 3,NG2( 78), 4,NG2( 52), 2,NG1(6.5) }, /* 104Mb/s */
+ { 4,NG2( 117), 3,NG2( 104), 4,NG2( 78), 2,NG1(6.5) }, /* 117Mb/s */
+ { 4,NG2( 130), 3,NG2( 117), 4,NG2( 104), 2,NG1(6.5) }, /* 130Mb/s */
/* 3 stream rates */
- { 3,NG3(19.5), 3,NG3(19.5), 0,NG3(19.5), 0,NG3(19.5) }, /* 19Mb/s */
- { 3,NG3( 39), 3,NG3(19.5), 0,NG3(19.5), 0,NG3(19.5) }, /* 39Mb/s */
- { 3,NG3(58.5), 3,NG3( 39), 0,NG3(19.5), 0,NG3(19.5) }, /* 58Mb/s */
- { 3,NG3( 78), 3,NG3(58.5), 0,NG3( 39), 0,NG3(19.5) }, /* 78Mb/s */
- { 3,NG3( 117), 3,NG3( 78), 0,NG3(58.5), 0,NG3(19.5) }, /* 117Mb/s */
- { 3,NG3( 156), 3,NG3( 117), 0,NG3( 78), 0,NG3(19.5) }, /* 156Mb/s */
- { 3,NG3(175.5), 3,NG3( 156), 0,NG3( 117), 0,NG3( 39) }, /* 175Mb/s */
- { 3,NG3( 195), 3,NG3( 195), 0,NG3( 156), 0,NG3(58.5) }, /* 195Mb/s */
+ { 3,NG3(19.5), 3,NG1(6.5), 0,NG3(19.5), 0,NG3(19.5) }, /* 19Mb/s */
+ { 3,NG3( 39), 3,NG3(19.5), 4,NG1(6.5), 0,NG3(19.5) }, /* 39Mb/s */
+ { 3,NG3(58.5), 3,NG3( 39), 4,NG1(6.5), 0,NG3(19.5) }, /* 58Mb/s */
+ { 3,NG3( 78), 3,NG3(58.5), 4,NG1(6.5), 0,NG3(19.5) }, /* 78Mb/s */
+ { 3,NG3( 117), 3,NG3( 78), 4,NG1(6.5), 0,NG3(19.5) }, /* 117Mb/s */
+ { 3,NG3( 156), 3,NG3( 117), 4,NG1(6.5), 0,NG3(19.5) }, /* 156Mb/s */
+ { 3,NG3(175.5), 3,NG3( 156), 4,NG1(6.5), 0,NG3( 39) }, /* 175Mb/s */
+ { 3,NG3( 195), 3,NG3( 195), 4,NG1(6.5), 0,NG3(58.5) }, /* 195Mb/s */
};
#undef G
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index 7e6ab3c614b7..34a9311c834a 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -160,7 +160,6 @@ static int ath_init(struct ath_softc *);
static void ath_stop(struct ath_softc *);
static int ath_reset_vap(struct ieee80211vap *, u_long);
static int ath_transmit(struct ieee80211com *, struct mbuf *);
-static int ath_media_change(struct ifnet *);
static void ath_watchdog(void *);
static void ath_parent(struct ieee80211com *);
static void ath_fatal_proc(void *, int);
@@ -1221,7 +1220,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
IEEE80211_HTC_TXLDPC;
}
-
device_printf(sc->sc_dev,
"[HT] %d RX streams; %d TX streams\n", rxs, txs);
}
@@ -1767,8 +1765,8 @@ ath_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ATH_UNLOCK(sc);
/* complete setup */
- ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status,
- mac);
+ ieee80211_vap_attach(vap, ieee80211_media_change,
+ ieee80211_media_status, mac);
return vap;
bad2:
reclaim_address(sc, mac);
@@ -1801,6 +1799,7 @@ ath_vap_delete(struct ieee80211vap *vap)
ath_hal_intrset(ah, 0); /* disable interrupts */
/* XXX Do all frames from all vaps/nodes need draining here? */
ath_stoprecv(sc, 1); /* stop recv side */
+ ath_rx_flush(sc);
ath_draintxq(sc, ATH_RESET_DEFAULT); /* stop hw xmit side */
}
@@ -2379,7 +2378,7 @@ ath_fatal_proc(void *arg, int pending)
"0x%08x 0x%08x 0x%08x, 0x%08x 0x%08x 0x%08x\n", state[0],
state[1] , state[2], state[3], state[4], state[5]);
}
- ath_reset(sc, ATH_RESET_NOLOSS);
+ ath_reset(sc, ATH_RESET_NOLOSS, HAL_RESET_FORCE_COLD);
}
static void
@@ -2490,11 +2489,11 @@ ath_bmiss_proc(void *arg, int pending)
* to clear.
*/
if (ath_hal_gethangstate(sc->sc_ah, 0xff, &hangs) && hangs != 0) {
- ath_reset(sc, ATH_RESET_NOLOSS);
+ ath_reset(sc, ATH_RESET_NOLOSS, HAL_RESET_BBPANIC);
device_printf(sc->sc_dev,
"bb hang detected (0x%x), resetting\n", hangs);
} else {
- ath_reset(sc, ATH_RESET_NOLOSS);
+ ath_reset(sc, ATH_RESET_NOLOSS, HAL_RESET_FORCE_COLD);
ieee80211_beacon_miss(&sc->sc_ic);
}
@@ -2893,7 +2892,8 @@ ath_reset_grablock(struct ath_softc *sc, int dowait)
* to reset or reload hardware state.
*/
int
-ath_reset(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
+ath_reset(struct ath_softc *sc, ATH_RESET_TYPE reset_type,
+ HAL_RESET_TYPE ah_reset_type)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ath_hal *ah = sc->sc_ah;
@@ -2961,7 +2961,7 @@ ath_reset(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
ath_hal_setchainmasks(sc->sc_ah, sc->sc_cur_txchainmask,
sc->sc_cur_rxchainmask);
if (!ath_hal_reset(ah, sc->sc_opmode, ic->ic_curchan, AH_TRUE,
- HAL_RESET_NORMAL, &status))
+ ah_reset_type, &status))
device_printf(sc->sc_dev,
"%s: unable to reset hardware; hal status %u\n",
__func__, status);
@@ -3097,7 +3097,7 @@ ath_reset_vap(struct ieee80211vap *vap, u_long cmd)
return 0;
}
/* XXX? Full or NOLOSS? */
- return ath_reset(sc, ATH_RESET_FULL);
+ return ath_reset(sc, ATH_RESET_FULL, HAL_RESET_NORMAL);
}
struct ath_buf *
@@ -3538,16 +3538,8 @@ finish:
ATH_UNLOCK(sc);
ATH_KTR(sc, ATH_KTR_TX, 0, "ath_transmit: finished");
-
- return (retval);
-}
-static int
-ath_media_change(struct ifnet *ifp)
-{
- int error = ieee80211_media_change(ifp);
- /* NB: only the fixed rate can change and that doesn't need a reset */
- return (error == ENETRESET ? 0 : error);
+ return (retval);
}
/*
@@ -3591,6 +3583,25 @@ ath_update_promisc(struct ieee80211com *ic)
DPRINTF(sc, ATH_DEBUG_MODE, "%s: RX filter 0x%x\n", __func__, rfilt);
}
+static u_int
+ath_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
+{
+ uint32_t val, *mfilt = arg;
+ char *dl;
+ uint8_t pos;
+
+ /* calculate XOR of eight 6bit values */
+ dl = LLADDR(sdl);
+ val = le32dec(dl + 0);
+ pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+ val = le32dec(dl + 3);
+ pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+ pos &= 0x3f;
+ mfilt[pos / 32] |= (1 << (pos % 32));
+
+ return (1);
+}
+
/*
* Driver-internal mcast update call.
*
@@ -3605,35 +3616,13 @@ ath_update_mcast_hw(struct ath_softc *sc)
/* calculate and install multicast filter */
if (ic->ic_allmulti == 0) {
struct ieee80211vap *vap;
- struct ifnet *ifp;
- struct ifmultiaddr *ifma;
/*
* Merge multicast addresses to form the hardware filter.
*/
mfilt[0] = mfilt[1] = 0;
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- ifp = vap->iv_ifp;
- if_maddr_rlock(ifp);
- CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- caddr_t dl;
- uint32_t val;
- uint8_t pos;
-
- /* calculate XOR of eight 6bit values */
- dl = LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr);
- val = le32dec(dl + 0);
- pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^
- val;
- val = le32dec(dl + 3);
- pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^
- val;
- pos &= 0x3f;
- mfilt[pos / 32] |= (1 << (pos % 32));
- }
- if_maddr_runlock(ifp);
- }
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
+ if_foreach_llmaddr(vap->iv_ifp, ath_hash_maddr, &mfilt);
} else
mfilt[0] = mfilt[1] = ~0;
@@ -3780,7 +3769,7 @@ ath_reset_proc(void *arg, int pending)
#if 0
device_printf(sc->sc_dev, "%s: resetting\n", __func__);
#endif
- ath_reset(sc, ATH_RESET_NOLOSS);
+ ath_reset(sc, ATH_RESET_NOLOSS, HAL_RESET_FORCE_COLD);
}
/*
@@ -3807,7 +3796,7 @@ ath_bstuck_proc(void *arg, int pending)
* This assumes that there's no simultaneous channel mode change
* occurring.
*/
- ath_reset(sc, ATH_RESET_NOLOSS);
+ ath_reset(sc, ATH_RESET_NOLOSS, HAL_RESET_FORCE_COLD);
}
static int
@@ -3882,6 +3871,10 @@ ath_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
/* XXX setup ath_tid */
ath_tx_tid_init(sc, an);
+ an->an_node_stats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
+ an->an_node_stats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
+ an->an_node_stats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
+
DPRINTF(sc, ATH_DEBUG_NODE, "%s: %6D: an %p\n", __func__, mac, ":", an);
return &an->an_node;
}
@@ -4300,7 +4293,7 @@ ath_tx_default_comp(struct ath_softc *sc, struct ath_buf *bf, int fail)
void
ath_tx_update_ratectrl(struct ath_softc *sc, struct ieee80211_node *ni,
struct ath_rc_series *rc, struct ath_tx_status *ts, int frmlen,
- int nframes, int nbad)
+ int rc_framelen, int nframes, int nbad)
{
struct ath_node *an;
@@ -4311,9 +4304,16 @@ ath_tx_update_ratectrl(struct ath_softc *sc, struct ieee80211_node *ni,
an = ATH_NODE(ni);
ATH_NODE_UNLOCK_ASSERT(an);
+ /*
+ * XXX TODO: teach the rate control about TXERR_FILT and
+ * see about handling it (eg see how many attempts were
+ * made before it got filtered and account for that.)
+ */
+
if ((ts->ts_status & HAL_TXERR_FILT) == 0) {
ATH_NODE_LOCK(an);
- ath_rate_tx_complete(sc, an, rc, ts, frmlen, nframes, nbad);
+ ath_rate_tx_complete(sc, an, rc, ts, frmlen, rc_framelen,
+ nframes, nbad);
ATH_NODE_UNLOCK(an);
}
}
@@ -4354,10 +4354,15 @@ ath_tx_process_buf_completion(struct ath_softc *sc, struct ath_txq *txq,
/*
* XXX assume this isn't an aggregate
* frame.
+ *
+ * XXX TODO: also do this for filtered frames?
+ * Once rate control knows about them?
*/
ath_tx_update_ratectrl(sc, ni,
bf->bf_state.bfs_rc, ts,
- bf->bf_state.bfs_pktlen, 1,
+ bf->bf_state.bfs_pktlen,
+ bf->bf_state.bfs_pktlen,
+ 1,
(ts->ts_status == 0 ? 0 : 1));
}
ath_tx_default_comp(sc, bf, 0);
@@ -4365,8 +4370,6 @@ ath_tx_process_buf_completion(struct ath_softc *sc, struct ath_txq *txq,
bf->bf_comp(sc, bf, 0);
}
-
-
/*
* Process completed xmit descriptors from the specified queue.
* Kick the packet scheduler if needed. This can occur from this
@@ -4493,6 +4496,8 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched)
sc->sc_stats.ast_tx_rssi = ts->ts_rssi;
ATH_RSSI_LPF(sc->sc_halstats.ns_avgtxrssi,
ts->ts_rssi);
+ ATH_RSSI_LPF(ATH_NODE(ni)->an_node_stats.ns_avgtxrssi,
+ ts->ts_rssi);
}
ATH_TXQ_UNLOCK(txq);
@@ -5435,6 +5440,20 @@ ath_calibrate(void *arg)
__func__, sc->sc_curchan->ic_freq);
sc->sc_stats.ast_per_calfail++;
}
+ /*
+ * XXX TODO: get the NF calibration results from the HAL.
+ * If we failed NF cal then schedule a hard reset to potentially
+ * un-freeze the PHY.
+ *
+ * Note we have to be careful here to not get stuck in an
+ * infinite NIC restart. Ideally we'd not restart if we
+ * failed the first NF cal - that /can/ fail sometimes in
+ * a noisy environment.
+ *
+ * Instead, we should likely temporarily shorten the longCal
+ * period to happen pretty quickly and if a subsequent one
+ * fails, do a full reset.
+ */
if (shortCal)
sc->sc_lastshortcal = ticks;
}
@@ -6072,7 +6091,6 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
taskqueue_unblock(sc->sc_tq);
} else if (nstate == IEEE80211_S_INIT) {
-
/* Quiet time handling - ensure we resync */
memset(&avp->quiet_ie, 0, sizeof(avp->quiet_ie));
@@ -6090,6 +6108,17 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
taskqueue_block(sc->sc_tq);
sc->sc_beacons = 0;
}
+
+ /*
+ * For at least STA mode we likely should clear the ANI
+ * and NF calibration state and allow the NIC/HAL to figure
+ * out optimal parameters at runtime. Otherwise if we
+ * disassociate due to interference / deafness it may persist
+ * when we reconnect.
+ *
+ * Note: may need to do this for other states too, not just
+ * _S_INIT.
+ */
#ifdef IEEE80211_SUPPORT_TDMA
ath_hal_setcca(ah, AH_TRUE);
#endif
@@ -6119,9 +6148,39 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
}
ATH_UNLOCK(sc);
}
+
+ /*
+ * Note - the ANI/calibration timer isn't re-enabled during
+ * network sleep for now. One unfortunate side-effect is that
+ * the PHY/airtime statistics aren't gathered on the channel
+ * but I haven't yet tested to see if reading those registers
+ * CAN occur during network sleep.
+ *
+ * This should be revisited in a future commit, even if it's
+ * just to split out the airtime polling from ANI/calibration.
+ */
} else if (nstate == IEEE80211_S_SCAN) {
/* Quiet time handling - ensure we resync */
memset(&avp->quiet_ie, 0, sizeof(avp->quiet_ie));
+
+ /*
+ * If we're in scan mode then startpcureceive() is
+ * hopefully being called with "reset ANI" for this channel;
+ * but once we attempt to reassociate we program in the previous
+ * ANI values and.. not do any calibration until we're running.
+ * This may mean we stay deaf unless we can associate successfully.
+ *
+ * So do kick off the cal timer to get NF/ANI going.
+ */
+ ATH_LOCK(sc);
+ if (ath_longcalinterval != 0) {
+ /* start periodic recalibration timer */
+ callout_reset(&sc->sc_cal_ch, 1, ath_calibrate, sc);
+ } else {
+ DPRINTF(sc, ATH_DEBUG_CALIBRATE,
+ "%s: calibration disabled\n", __func__);
+ }
+ ATH_UNLOCK(sc);
}
bad:
ieee80211_free_node(ni);
diff --git a/sys/dev/ath/if_ath_ahb.c b/sys/dev/ath/if_ath_ahb.c
index 3c4c05e57846..ea329589f1ab 100644
--- a/sys/dev/ath/if_ath_ahb.c
+++ b/sys/dev/ath/if_ath_ahb.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <sys/socket.h>
-
+
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_arp.h>
@@ -336,7 +336,6 @@ static device_method_t ath_ahb_methods[] = {
DEVMETHOD(device_shutdown, ath_ahb_shutdown),
DEVMETHOD(device_suspend, ath_ahb_suspend),
DEVMETHOD(device_resume, ath_ahb_resume),
-
{ 0,0 }
};
static driver_t ath_ahb_driver = {
diff --git a/sys/dev/ath/if_ath_beacon.c b/sys/dev/ath/if_ath_beacon.c
index 509e24caf601..ac1244c5f8e7 100644
--- a/sys/dev/ath/if_ath_beacon.c
+++ b/sys/dev/ath/if_ath_beacon.c
@@ -777,7 +777,6 @@ ath_beacon_generate(struct ath_softc *sc, struct ieee80211vap *vap)
* insure cab frames are triggered by this beacon.
*/
if (vap->iv_bcn_off.bo_tim[4] & 1) {
-
/* NB: only at DTIM */
ATH_TXQ_LOCK(&avp->av_mcastq);
if (nmcastq) {
diff --git a/sys/dev/ath/if_ath_beacon.h b/sys/dev/ath/if_ath_beacon.h
index e4a9e7918af2..cda145ba32e2 100644
--- a/sys/dev/ath/if_ath_beacon.h
+++ b/sys/dev/ath/if_ath_beacon.h
@@ -53,4 +53,3 @@ extern void ath_beacon_proc(void *arg, int pending);
extern void ath_beacon_miss(struct ath_softc *sc);
#endif
-
diff --git a/sys/dev/ath/if_ath_btcoex.c b/sys/dev/ath/if_ath_btcoex.c
index 881a2c8acf95..1f0400b696f5 100644
--- a/sys/dev/ath/if_ath_btcoex.c
+++ b/sys/dev/ath/if_ath_btcoex.c
@@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/socket.h>
-
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_media.h>
@@ -481,4 +481,3 @@ bad:
free(outdata, M_TEMP);
return (error);
}
-
diff --git a/sys/dev/ath/if_ath_dfs.c b/sys/dev/ath/if_ath_dfs.c
index 2078f154981c..8f1bc5b015ae 100644
--- a/sys/dev/ath/if_ath_dfs.c
+++ b/sys/dev/ath/if_ath_dfs.c
@@ -63,7 +63,6 @@ ath_dfs_modevent(module_t mod __unused, int type, void *data __unused)
default:
error = EOPNOTSUPP;
break;
-
}
return (error);
}
diff --git a/sys/dev/ath/if_ath_drv.c b/sys/dev/ath/if_ath_drv.c
index cc7b9162fb2c..c4384cb73916 100644
--- a/sys/dev/ath/if_ath_drv.c
+++ b/sys/dev/ath/if_ath_drv.c
@@ -68,7 +68,6 @@ ath_modevent(module_t mod __unused, int type, void *data __unused)
default:
error = EOPNOTSUPP;
break;
-
}
return (error);
}
diff --git a/sys/dev/ath/if_ath_ioctl.c b/sys/dev/ath/if_ath_ioctl.c
index 9601ba3456bb..f58742d6e5fb 100644
--- a/sys/dev/ath/if_ath_ioctl.c
+++ b/sys/dev/ath/if_ath_ioctl.c
@@ -204,7 +204,6 @@ ath_ioctl_diag(struct ath_softc *sc, struct ath_diag *ad)
}
}
-
ATH_LOCK(sc);
if (id != HAL_DIAG_REGS)
ath_power_set_power_state(sc, HAL_PM_AWAKE);
@@ -306,4 +305,3 @@ ath_ioctl(struct ieee80211com *ic, u_long cmd, void *data)
return (ENOTTY);
}
}
-
diff --git a/sys/dev/ath/if_ath_led.c b/sys/dev/ath/if_ath_led.c
index 3cd519a8d198..8b4ac821f2be 100644
--- a/sys/dev/ath/if_ath_led.c
+++ b/sys/dev/ath/if_ath_led.c
@@ -112,7 +112,6 @@ __FBSDID("$FreeBSD$");
* XXX TODO: move the LED sysctls here.
*/
-
/*
* Configure the hardware for software and LED blinking.
* The user may choose to configure part of each, depending upon the
diff --git a/sys/dev/ath/if_ath_lna_div.c b/sys/dev/ath/if_ath_lna_div.c
index 7b970285b9b7..c89a6b107749 100644
--- a/sys/dev/ath/if_ath_lna_div.c
+++ b/sys/dev/ath/if_ath_lna_div.c
@@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/socket.h>
-
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_media.h>
@@ -1018,4 +1018,3 @@ div_comb_done:
antcomb->main_recv_cnt = 0;
antcomb->alt_recv_cnt = 0;
}
-
diff --git a/sys/dev/ath/if_ath_misc.h b/sys/dev/ath/if_ath_misc.h
index f34bbbfaeebc..b108c29bab4b 100644
--- a/sys/dev/ath/if_ath_misc.h
+++ b/sys/dev/ath/if_ath_misc.h
@@ -58,12 +58,14 @@ extern void ath_freebuf(struct ath_softc *sc, struct ath_buf *bf);
extern void ath_returnbuf_head(struct ath_softc *sc, struct ath_buf *bf);
extern void ath_returnbuf_tail(struct ath_softc *sc, struct ath_buf *bf);
-extern int ath_reset(struct ath_softc *, ATH_RESET_TYPE);
+extern int ath_reset(struct ath_softc *, ATH_RESET_TYPE,
+ HAL_RESET_TYPE ah_reset_type);
extern void ath_tx_default_comp(struct ath_softc *sc, struct ath_buf *bf,
int fail);
extern void ath_tx_update_ratectrl(struct ath_softc *sc,
struct ieee80211_node *ni, struct ath_rc_series *rc,
- struct ath_tx_status *ts, int frmlen, int nframes, int nbad);
+ struct ath_tx_status *ts, int frmlen, int rc_framelen,
+ int nframes, int nbad);
extern int ath_hal_gethangstate(struct ath_hal *ah, uint32_t mask,
uint32_t *hangs);
diff --git a/sys/dev/ath/if_ath_pci.c b/sys/dev/ath/if_ath_pci.c
index 0b35e6670015..d3b130e091dc 100644
--- a/sys/dev/ath/if_ath_pci.c
+++ b/sys/dev/ath/if_ath_pci.c
@@ -52,7 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <sys/socket.h>
-
+
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_arp.h>
@@ -383,7 +383,6 @@ static device_method_t ath_pci_methods[] = {
DEVMETHOD(device_shutdown, ath_pci_shutdown),
DEVMETHOD(device_suspend, ath_pci_suspend),
DEVMETHOD(device_resume, ath_pci_resume),
-
{ 0,0 }
};
static driver_t ath_pci_driver = {
diff --git a/sys/dev/ath/if_ath_pci_devlist.h b/sys/dev/ath/if_ath_pci_devlist.h
index dc49ab578d65..ec5bb1405553 100644
--- a/sys/dev/ath/if_ath_pci_devlist.h
+++ b/sys/dev/ath/if_ath_pci_devlist.h
@@ -663,7 +663,5 @@ static const struct pci_device_table ath_pci_id_table[] = {
/* PCI-E AR9565 (WB335) */
{ PCI_VDEVICE(PCI_VENDOR_ID_ATHEROS, 0x0036),
.driver_data = ATH_PCI_BT_ANT_DIV },
-
{ 0 }
};
-
diff --git a/sys/dev/ath/if_ath_rate.c b/sys/dev/ath/if_ath_rate.c
index 8eb7a518c2a4..ff2e0e1336f1 100644
--- a/sys/dev/ath/if_ath_rate.c
+++ b/sys/dev/ath/if_ath_rate.c
@@ -63,7 +63,6 @@ ath_rate_modevent(module_t mod __unused, int type, void *data __unused)
default:
error = EOPNOTSUPP;
break;
-
}
return (error);
}
diff --git a/sys/dev/ath/if_ath_rx.c b/sys/dev/ath/if_ath_rx.c
index b06a3f797dde..141547dac424 100644
--- a/sys/dev/ath/if_ath_rx.c
+++ b/sys/dev/ath/if_ath_rx.c
@@ -363,6 +363,11 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_BEACON:
+ /*
+ * Always update the per-node beacon RSSI if we're hearing
+ * beacons from that node.
+ */
+ ATH_RSSI_LPF(ATH_NODE(ni)->an_node_stats.ns_avgbrssi, rssi);
/*
* Only do the following processing if it's for
@@ -374,12 +379,12 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
* trying to sync / merge to BSSes that aren't
* actually us.
*/
- if (IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) {
+ if ((vap->iv_opmode != IEEE80211_M_HOSTAP) &&
+ IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) {
/* update rssi statistics for use by the hal */
/* XXX unlocked check against vap->iv_bss? */
ATH_RSSI_LPF(sc->sc_halstats.ns_avgbrssi, rssi);
-
tsf_beacon = ((uint64_t) le32dec(ni->ni_tstamp.data + 4)) << 32;
tsf_beacon |= le32dec(ni->ni_tstamp.data);
@@ -422,8 +427,9 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
tsf_remainder = (tsf_beacon - tsf_beacon_old) % tsf_intval;
}
- DPRINTF(sc, ATH_DEBUG_BEACON, "%s: old_tsf=%llu (%u), new_tsf=%llu (%u), target_tsf=%llu (%u), delta=%lld, bmiss=%d, remainder=%d\n",
+ DPRINTF(sc, ATH_DEBUG_BEACON, "%s: %s: old_tsf=%llu (%u), new_tsf=%llu (%u), target_tsf=%llu (%u), delta=%lld, bmiss=%d, remainder=%d\n",
__func__,
+ ieee80211_get_vap_ifname(vap),
(unsigned long long) tsf_beacon_old,
(unsigned int) (tsf_beacon_old >> 10),
(unsigned long long) tsf_beacon,
@@ -434,17 +440,28 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
tsf_delta_bmiss,
tsf_remainder);
- DPRINTF(sc, ATH_DEBUG_BEACON, "%s: tsf=%llu (%u), nexttbtt=%llu (%u), delta=%d\n",
+ DPRINTF(sc, ATH_DEBUG_BEACON, "%s: %s: ni=%6D bssid=%6D tsf=%llu (%u), nexttbtt=%llu (%u), delta=%d\n",
__func__,
+ ieee80211_get_vap_ifname(vap),
+ ni->ni_bssid, ":",
+ vap->iv_bss->ni_bssid, ":",
(unsigned long long) tsf_beacon,
(unsigned int) (tsf_beacon >> 10),
(unsigned long long) nexttbtt,
(unsigned int) (nexttbtt >> 10),
(int32_t) tsf_beacon - (int32_t) nexttbtt + tsf_intval);
- /* We only do syncbeacon on STA VAPs; not on IBSS */
+ /*
+ * We only do syncbeacon on STA VAPs; not on IBSS;
+ * but don't do it with swbmiss enabled or we
+ * may end up overwriting AP mode beacon config.
+ *
+ * The driver (and net80211) should be smarter about
+ * this..
+ */
if (vap->iv_opmode == IEEE80211_M_STA &&
sc->sc_syncbeacon &&
+ (!sc->sc_swbmiss) &&
ni == vap->iv_bss &&
(vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP)) {
DPRINTF(sc, ATH_DEBUG_BEACON,
@@ -946,6 +963,21 @@ rx_accept:
m->m_flags |= M_AMPDU;
/*
+ * Inform rate control about the received RSSI.
+ * It can then use this information to potentially drastically
+ * alter the available rate based on the RSSI estimate.
+ *
+ * This is super important when associating to a far away station;
+ * you don't want to waste time trying higher rates at some low
+ * packet exchange rate (like during DHCP) just to establish
+ * that higher MCS rates aren't available.
+ */
+ ATH_RSSI_LPF(ATH_NODE(ni)->an_node_stats.ns_avgrssi,
+ rs->rs_rssi);
+ ath_rate_update_rx_rssi(sc, ATH_NODE(ni),
+ ATH_RSSI(ATH_NODE(ni)->an_node_stats.ns_avgrssi));
+
+ /*
* Sending station is known, dispatch directly.
*/
(void) ieee80211_add_rx_params(m, &rxs);
@@ -973,7 +1005,7 @@ rx_accept:
*/
/*
- * Track rx rssi and do any rx antenna management.
+ * Track legacy station RX rssi and do any rx antenna management.
*/
ATH_RSSI_LPF(sc->sc_halstats.ns_avgrssi, rs->rs_rssi);
if (sc->sc_diversity) {
@@ -1228,7 +1260,7 @@ rx_proc_next:
ath_hal_putrxbuf(ah, bf->bf_daddr, HAL_RX_QUEUE_HP);
ath_hal_rxena(ah); /* enable recv descriptors */
ath_mode_init(sc); /* set filters, etc. */
- ath_hal_startpcurecv(ah); /* re-enable PCU/DMA engine */
+ ath_hal_startpcurecv(ah, (!! sc->sc_scanning)); /* re-enable PCU/DMA engine */
#endif
ath_hal_intrset(ah, sc->sc_imask);
@@ -1444,7 +1476,7 @@ ath_legacy_startrecv(struct ath_softc *sc)
ath_hal_putrxbuf(ah, bf->bf_daddr, HAL_RX_QUEUE_HP);
ath_hal_rxena(ah); /* enable recv descriptors */
ath_mode_init(sc); /* set filters, etc. */
- ath_hal_startpcurecv(ah); /* re-enable PCU/DMA engine */
+ ath_hal_startpcurecv(ah, (!! sc->sc_scanning)); /* re-enable PCU/DMA engine */
ATH_RX_UNLOCK(sc);
return 0;
diff --git a/sys/dev/ath/if_ath_rx_edma.c b/sys/dev/ath/if_ath_rx_edma.c
index 725447d61739..e528dc8d2e43 100644
--- a/sys/dev/ath/if_ath_rx_edma.c
+++ b/sys/dev/ath/if_ath_rx_edma.c
@@ -162,6 +162,9 @@ ath_edma_stoprecv(struct ath_softc *sc, int dodelay)
{
struct ath_hal *ah = sc->sc_ah;
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: called, dodelay=%d\n",
+ __func__, dodelay);
+
ATH_RX_LOCK(sc);
ath_hal_stoppcurecv(ah);
@@ -191,6 +194,8 @@ ath_edma_stoprecv(struct ath_softc *sc, int dodelay)
sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending = NULL;
}
ATH_RX_UNLOCK(sc);
+
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: done\n", __func__);
}
/*
@@ -205,6 +210,8 @@ ath_edma_reinit_fifo(struct ath_softc *sc, HAL_RX_QUEUE qtype)
struct ath_buf *bf;
int i, j;
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: called\n", __func__);
+
ATH_RX_LOCK_ASSERT(sc);
i = re->m_fifo_head;
@@ -227,6 +234,7 @@ ath_edma_reinit_fifo(struct ath_softc *sc, HAL_RX_QUEUE qtype)
i,
re->m_fifo_tail);
}
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: done\n", __func__);
}
/*
@@ -237,6 +245,10 @@ ath_edma_startrecv(struct ath_softc *sc)
{
struct ath_hal *ah = sc->sc_ah;
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX,
+ "%s: called; resetted=%d, stopped=%d\n", __func__,
+ sc->sc_rx_resetted, sc->sc_rx_stopped);
+
ATH_RX_LOCK(sc);
/*
@@ -252,7 +264,7 @@ ath_edma_startrecv(struct ath_softc *sc)
/*
* In theory the hardware has been initialised, right?
*/
- if (sc->sc_rx_resetted == 1) {
+ if (sc->sc_rx_resetted == 1 || sc->sc_rx_stopped == 1) {
DPRINTF(sc, ATH_DEBUG_EDMA_RX,
"%s: Re-initing HP FIFO\n", __func__);
ath_edma_reinit_fifo(sc, HAL_RX_QUEUE_HP);
@@ -262,8 +274,11 @@ ath_edma_startrecv(struct ath_softc *sc)
sc->sc_rx_resetted = 0;
} else {
device_printf(sc->sc_dev,
- "%s: called without resetting chip?\n",
- __func__);
+ "%s: called without resetting chip? "
+ "resetted=%d, stopped=%d\n",
+ __func__,
+ sc->sc_rx_resetted,
+ sc->sc_rx_stopped);
}
/* Add up to m_fifolen entries in each queue */
@@ -282,7 +297,7 @@ ath_edma_startrecv(struct ath_softc *sc)
sc->sc_rxedma[HAL_RX_QUEUE_LP].m_fifolen);
ath_mode_init(sc);
- ath_hal_startpcurecv(ah);
+ ath_hal_startpcurecv(ah, (!! sc->sc_scanning));
/*
* We're now doing RX DMA!
@@ -290,6 +305,7 @@ ath_edma_startrecv(struct ath_softc *sc)
sc->sc_rx_stopped = 0;
ATH_RX_UNLOCK(sc);
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: ready\n", __func__);
return (0);
}
@@ -298,6 +314,8 @@ static void
ath_edma_recv_sched_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype,
int dosched)
{
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: called; qtype=%d, dosched=%d\n",
+ __func__, qtype, dosched);
ATH_LOCK(sc);
ath_power_set_power_state(sc, HAL_PM_AWAKE);
@@ -309,13 +327,19 @@ ath_edma_recv_sched_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype,
ath_power_restore_power_state(sc);
ATH_UNLOCK(sc);
+ /* XXX TODO: methodize */
taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask);
+
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: done\n", __func__);
}
static void
ath_edma_recv_sched(struct ath_softc *sc, int dosched)
{
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: called; dosched=%d\n",
+ __func__, dosched);
+
ATH_LOCK(sc);
ath_power_set_power_state(sc, HAL_PM_AWAKE);
ATH_UNLOCK(sc);
@@ -327,19 +351,27 @@ ath_edma_recv_sched(struct ath_softc *sc, int dosched)
ath_power_restore_power_state(sc);
ATH_UNLOCK(sc);
+ /* XXX TODO: methodize */
taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask);
+
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: done\n", __func__);
}
static void
ath_edma_recv_flush(struct ath_softc *sc)
{
- DPRINTF(sc, ATH_DEBUG_RECV, "%s: called\n", __func__);
+ DPRINTF(sc, ATH_DEBUG_RECV | ATH_DEBUG_EDMA_RX, "%s: called\n", __func__);
ATH_PCU_LOCK(sc);
sc->sc_rxproc_cnt++;
ATH_PCU_UNLOCK(sc);
+ // XXX TODO: methodize; make it an RX stop/block
+ while (taskqueue_cancel(sc->sc_tq, &sc->sc_rxtask, NULL) != 0) {
+ taskqueue_drain(sc->sc_tq, &sc->sc_rxtask);
+ }
+
ATH_LOCK(sc);
ath_power_set_power_state(sc, HAL_PM_AWAKE);
ATH_UNLOCK(sc);
@@ -368,6 +400,8 @@ ath_edma_recv_flush(struct ath_softc *sc)
ATH_PCU_LOCK(sc);
sc->sc_rxproc_cnt--;
ATH_PCU_UNLOCK(sc);
+
+ DPRINTF(sc, ATH_DEBUG_RECV | ATH_DEBUG_EDMA_RX, "%s: done\n", __func__);
}
/*
@@ -391,6 +425,8 @@ ath_edma_recv_proc_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype,
nf = ath_hal_getchannoise(ah, sc->sc_curchan);
sc->sc_stats.ast_rx_noise = nf;
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: called; qtype=%d, dosched=%d\n", __func__, qtype, dosched);
+
ATH_RX_LOCK(sc);
#if 1
@@ -604,9 +640,6 @@ ath_edma_recv_tasklet(void *arg, int npending)
ath_power_set_power_state(sc, HAL_PM_AWAKE);
ATH_UNLOCK(sc);
- ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_HP, 1);
- ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_LP, 1);
-
ath_edma_recv_proc_deferred_queue(sc, HAL_RX_QUEUE_HP, 1);
ath_edma_recv_proc_deferred_queue(sc, HAL_RX_QUEUE_LP, 1);
@@ -628,6 +661,8 @@ ath_edma_recv_tasklet(void *arg, int npending)
ATH_PCU_LOCK(sc);
sc->sc_rxproc_cnt--;
ATH_PCU_UNLOCK(sc);
+
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: called; done!\n", __func__);
}
/*
diff --git a/sys/dev/ath/if_ath_spectral.c b/sys/dev/ath/if_ath_spectral.c
index eaf91b9b1cab..44d5064c182d 100644
--- a/sys/dev/ath/if_ath_spectral.c
+++ b/sys/dev/ath/if_ath_spectral.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/socket.h>
-
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_media.h>
@@ -299,4 +299,3 @@ bad:
return (error);
}
-
diff --git a/sys/dev/ath/if_ath_sysctl.c b/sys/dev/ath/if_ath_sysctl.c
index 3e4e47246357..fd43ba4f6083 100644
--- a/sys/dev/ath/if_ath_sysctl.c
+++ b/sys/dev/ath/if_ath_sysctl.c
@@ -382,7 +382,8 @@ ath_sysctl_tpscale(SYSCTL_HANDLER_ARGS)
goto finish;
error = !ath_hal_settpscale(sc->sc_ah, scale) ? EINVAL :
- (sc->sc_running) ? ath_reset(sc, ATH_RESET_NOLOSS) : 0;
+ (sc->sc_running) ? ath_reset(sc, ATH_RESET_NOLOSS,
+ HAL_RESET_NORMAL) : 0;
finish:
ATH_LOCK(sc);
@@ -443,7 +444,8 @@ ath_sysctl_rfkill(SYSCTL_HANDLER_ARGS)
error = EINVAL;
goto finish;
}
- error = sc->sc_running ? ath_reset(sc, ATH_RESET_FULL) : 0;
+ error = sc->sc_running ? ath_reset(sc, ATH_RESET_FULL,
+ HAL_RESET_NORMAL) : 0;
finish:
ATH_LOCK(sc);
@@ -670,7 +672,7 @@ ath_sysctl_intmit(SYSCTL_HANDLER_ARGS)
* things in an inconsistent state.
*/
if (sc->sc_running)
- ath_reset(sc, ATH_RESET_NOLOSS);
+ ath_reset(sc, ATH_RESET_NOLOSS, HAL_RESET_NORMAL);
error = 0;
@@ -1062,7 +1064,7 @@ ath_sysctl_stats_attach(struct ath_softc *sc)
struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
-
+
/* Create "clear" node */
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"clear_stats", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
@@ -1296,7 +1298,7 @@ ath_sysctl_stats_attach(struct ath_softc *sc)
SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_ldpc",
CTLFLAG_RD, &sc->sc_stats.ast_tx_ldpc, 0,
"Number of LDPC frames transmitted");
-
+
/* Attach the RX phy error array */
ath_sysctl_stats_attach_rxphyerr(sc, child);
diff --git a/sys/dev/ath/if_ath_tx.c b/sys/dev/ath/if_ath_tx.c
index 8d90a5d27fb1..f8800fab04cd 100644
--- a/sys/dev/ath/if_ath_tx.c
+++ b/sys/dev/ath/if_ath_tx.c
@@ -363,7 +363,7 @@ ath_tx_dmasetup(struct ath_softc *sc, struct ath_buf *bf, struct mbuf *m0)
*/
static void
ath_tx_chaindesclist(struct ath_softc *sc, struct ath_desc *ds0,
- struct ath_buf *bf, int is_aggr, int is_first_subframe,
+ struct ath_buf *bf, bool is_aggr, int is_first_subframe,
int is_last_subframe)
{
struct ath_hal *ah = sc->sc_ah;
@@ -1307,7 +1307,7 @@ ath_tx_set_rtscts(struct ath_softc *sc, struct ath_buf *bf)
/* Squirrel away in ath_buf */
bf->bf_state.bfs_ctsrate = ctsrate;
bf->bf_state.bfs_ctsduration = ctsduration;
-
+
/*
* Must disable multi-rate retry when using RTS/CTS.
*/
@@ -1376,10 +1376,13 @@ ath_tx_setds(struct ath_softc *sc, struct ath_buf *bf)
* as they may depend upon the rate chosen.
*/
static void
-ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_buf *bf)
+ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_buf *bf, int tid,
+ int pktlen, int is_aggr)
{
uint8_t rate, rix;
int try0;
+ int maxdur; // Note: Unused for now
+ int maxpktlen;
if (! bf->bf_state.bfs_doratelookup)
return;
@@ -1389,7 +1392,7 @@ ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_buf *bf)
ATH_NODE_LOCK(ATH_NODE(bf->bf_node));
ath_rate_findrate(sc, ATH_NODE(bf->bf_node), bf->bf_state.bfs_shpream,
- bf->bf_state.bfs_pktlen, &rix, &try0, &rate);
+ pktlen, tid, is_aggr, &rix, &try0, &rate, &maxdur, &maxpktlen);
/* In case MRR is disabled, make sure rc[0] is setup correctly */
bf->bf_state.bfs_rc[0].rix = rix;
@@ -1398,13 +1401,14 @@ ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_buf *bf)
if (bf->bf_state.bfs_ismrr && try0 != ATH_TXMAXTRY)
ath_rate_getxtxrates(sc, ATH_NODE(bf->bf_node), rix,
- bf->bf_state.bfs_rc);
+ is_aggr, bf->bf_state.bfs_rc);
ATH_NODE_UNLOCK(ATH_NODE(bf->bf_node));
sc->sc_txrix = rix; /* for LED blinking */
sc->sc_lastdatarix = rix; /* for fast frames */
bf->bf_state.bfs_try0 = try0;
bf->bf_state.bfs_txrate0 = rate;
+ bf->bf_state.bfs_rc_maxpktlen = maxpktlen;
}
/*
@@ -1482,7 +1486,6 @@ ath_tx_should_swq_frame(struct ath_softc *sc, struct ath_node *an,
}
}
-
/*
* Transmit the given frame to the hardware.
*
@@ -1519,7 +1522,7 @@ ath_tx_xmit_normal(struct ath_softc *sc, struct ath_txq *txq,
bf->bf_state.bfs_txflags |= HAL_TXDESC_CLRDMASK;
/* Setup the descriptor before handoff */
- ath_tx_do_ratelookup(sc, bf);
+ ath_tx_do_ratelookup(sc, bf, tid->tid, bf->bf_state.bfs_pktlen, false);
ath_tx_calc_duration(sc, bf);
ath_tx_calc_protection(sc, bf);
ath_tx_set_rtscts(sc, bf);
@@ -2515,7 +2518,6 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
sc->sc_txstart_cnt--;
ATH_PCU_UNLOCK(sc);
-
/* Put the hardware back to sleep if required */
ATH_LOCK(sc);
ath_power_restore_power_state(sc);
@@ -2709,7 +2711,6 @@ ath_tx_addto_baw(struct ath_softc *sc, struct ath_node *an,
tap->txa_start, tap->txa_wnd, index, cindex, tid->baw_head,
tid->baw_tail);
-
#if 0
assert(tid->tx_buf[cindex] == NULL);
#endif
@@ -3094,7 +3095,8 @@ ath_tx_xmit_aggr(struct ath_softc *sc, struct ath_node *an,
ath_tx_update_clrdmask(sc, tid, bf);
/* Direct dispatch to hardware */
- ath_tx_do_ratelookup(sc, bf);
+ ath_tx_do_ratelookup(sc, bf, tid->tid, bf->bf_state.bfs_pktlen,
+ false);
ath_tx_calc_duration(sc, bf);
ath_tx_calc_protection(sc, bf);
ath_tx_set_rtscts(sc, bf);
@@ -3220,7 +3222,6 @@ ath_tx_swq(struct ath_softc *sc, struct ieee80211_node *ni,
*/
/* XXX TXQ locking */
if (txq->axq_depth + txq->fifo.axq_depth == 0) {
-
bf = ATH_TID_FIRST(atid);
ATH_TID_REMOVE(atid, bf, bf_list);
@@ -4257,7 +4258,9 @@ ath_tx_normal_comp(struct ath_softc *sc, struct ath_buf *bf, int fail)
*/
if (fail == 0 && ((bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) == 0))
ath_tx_update_ratectrl(sc, ni, bf->bf_state.bfs_rc,
- ts, bf->bf_state.bfs_pktlen,
+ ts,
+ bf->bf_state.bfs_pktlen,
+ bf->bf_state.bfs_pktlen,
1, (ts->ts_status == 0) ? 0 : 1);
ath_tx_default_comp(sc, bf, fail);
@@ -4305,7 +4308,6 @@ ath_tx_comp_cleanup_unaggr(struct ath_softc *sc, struct ath_buf *bf)
ath_tx_default_comp(sc, bf, 0);
}
-
/*
* This as it currently stands is a bit dumb. Ideally we'd just
* fail the frame the normal way and have it permanently fail
@@ -4686,13 +4688,11 @@ ath_tx_comp_aggr_error(struct ath_softc *sc, struct ath_buf *bf_first,
/*
* Update rate control - all frames have failed.
- *
- * XXX use the length in the first frame in the series;
- * XXX just so things are consistent for now.
*/
ath_tx_update_ratectrl(sc, ni, bf_first->bf_state.bfs_rc,
&bf_first->bf_status.ds_txstat,
- bf_first->bf_state.bfs_pktlen,
+ bf_first->bf_state.bfs_al,
+ bf_first->bf_state.bfs_rc_maxpktlen,
bf_first->bf_state.bfs_nframes, bf_first->bf_state.bfs_nframes);
ATH_TX_LOCK(sc);
@@ -4841,6 +4841,7 @@ ath_tx_aggr_comp_aggr(struct ath_softc *sc, struct ath_buf *bf_first,
int drops = 0;
int nframes = 0, nbad = 0, nf;
int pktlen;
+ int agglen, rc_agglen;
/* XXX there's too much on the stack? */
struct ath_rc_series rc[ATH_RC_NUM];
int txseq;
@@ -4853,6 +4854,8 @@ ath_tx_aggr_comp_aggr(struct ath_softc *sc, struct ath_buf *bf_first,
* has been completed and freed.
*/
ts = bf_first->bf_status.ds_txstat;
+ agglen = bf_first->bf_state.bfs_al;
+ rc_agglen = bf_first->bf_state.bfs_rc_maxpktlen;
TAILQ_INIT(&bf_q);
TAILQ_INIT(&bf_cq);
@@ -5003,7 +5006,11 @@ ath_tx_aggr_comp_aggr(struct ath_softc *sc, struct ath_buf *bf_first,
"%s: AR5416 bug: hasba=%d; txok=%d, isaggr=%d, "
"seq_st=%d\n",
__func__, hasba, tx_ok, isaggr, seq_st);
- /* XXX TODO: schedule an interface reset */
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_fataltask);
+ /* And as we can't really trust the BA here .. */
+ ba[0] = 0;
+ ba[1] = 0;
+ seq_st = 0;
#ifdef ATH_DEBUG
ath_printtxbuf(sc, bf_first,
sc->sc_ac2q[atid->ac]->axq_qnum, 0, 0);
@@ -5088,9 +5095,10 @@ ath_tx_aggr_comp_aggr(struct ath_softc *sc, struct ath_buf *bf_first,
* Now we know how many frames were bad, call the rate
* control code.
*/
- if (fail == 0)
- ath_tx_update_ratectrl(sc, ni, rc, &ts, pktlen, nframes,
- nbad);
+ if (fail == 0) {
+ ath_tx_update_ratectrl(sc, ni, rc, &ts, agglen, rc_agglen,
+ nframes, nbad);
+ }
/*
* send bar if we dropped any frames
@@ -5181,6 +5189,7 @@ ath_tx_aggr_comp_unaggr(struct ath_softc *sc, struct ath_buf *bf, int fail)
ath_tx_update_ratectrl(sc, ni, bf->bf_state.bfs_rc,
&bf->bf_status.ds_txstat,
bf->bf_state.bfs_pktlen,
+ bf->bf_state.bfs_pktlen,
1, (ts.ts_status == 0) ? 0 : 1);
/*
@@ -5353,6 +5362,65 @@ ath_tx_aggr_comp(struct ath_softc *sc, struct ath_buf *bf, int fail)
}
/*
+ * Grab the software queue depth that we COULD transmit.
+ *
+ * This includes checks if it's in the BAW, whether it's a frame
+ * that is supposed to be in the BAW. Other checks could be done;
+ * but for now let's try and avoid doing the whole of ath_tx_form_aggr()
+ * here.
+ */
+static int
+ath_tx_tid_swq_depth_bytes(struct ath_softc *sc, struct ath_node *an,
+ struct ath_tid *tid)
+{
+ struct ath_buf *bf;
+ struct ieee80211_tx_ampdu *tap;
+ int nbytes = 0;
+
+ ATH_TX_LOCK_ASSERT(sc);
+
+ tap = ath_tx_get_tx_tid(an, tid->tid);
+
+ /*
+ * Iterate over each buffer and sum the pkt_len.
+ * Bail if we exceed ATH_AGGR_MAXSIZE bytes; we won't
+ * ever queue more than that in a single frame.
+ */
+ TAILQ_FOREACH(bf, &tid->tid_q, bf_list) {
+ /*
+ * TODO: I'm not sure if we're going to hit cases where
+ * no frames get sent because the list is empty.
+ */
+
+ /* Check if it's in the BAW */
+ if (tap != NULL && (! BAW_WITHIN(tap->txa_start, tap->txa_wnd,
+ SEQNO(bf->bf_state.bfs_seqno)))) {
+ break;
+ }
+
+ /* Check if it's even supposed to be in the BAW */
+ if (! bf->bf_state.bfs_dobaw) {
+ break;
+ }
+
+ nbytes += bf->bf_state.bfs_pktlen;
+ if (nbytes >= ATH_AGGR_MAXSIZE)
+ break;
+
+ /*
+ * Check if we're likely going to leak a frame
+ * as part of a PSPOLL. Break out at this point;
+ * we're only going to send a single frame anyway.
+ */
+ if (an->an_leak_count) {
+ break;
+ }
+ }
+
+ return MIN(nbytes, ATH_AGGR_MAXSIZE);
+}
+
+/*
* Schedule some packets from the given node/TID to the hardware.
*
* This is the aggregate version.
@@ -5366,6 +5434,7 @@ ath_tx_tid_hw_queue_aggr(struct ath_softc *sc, struct ath_node *an,
struct ieee80211_tx_ampdu *tap;
ATH_AGGR_STATUS status;
ath_bufhead bf_q;
+ int swq_pktbytes;
DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: tid=%d\n", __func__, tid->tid);
ATH_TX_LOCK_ASSERT(sc);
@@ -5429,7 +5498,8 @@ ath_tx_tid_hw_queue_aggr(struct ath_softc *sc, struct ath_node *an,
/* Update CLRDMASK just before this frame is queued */
ath_tx_update_clrdmask(sc, tid, bf);
- ath_tx_do_ratelookup(sc, bf);
+ ath_tx_do_ratelookup(sc, bf, tid->tid,
+ bf->bf_state.bfs_pktlen, false);
ath_tx_calc_duration(sc, bf);
ath_tx_calc_protection(sc, bf);
ath_tx_set_rtscts(sc, bf);
@@ -5446,17 +5516,18 @@ ath_tx_tid_hw_queue_aggr(struct ath_softc *sc, struct ath_node *an,
TAILQ_INIT(&bf_q);
/*
- * Do a rate control lookup on the first frame in the
- * list. The rate control code needs that to occur
- * before it can determine whether to TX.
- * It's inaccurate because the rate control code doesn't
- * really "do" aggregate lookups, so it only considers
- * the size of the first frame.
+ * Loop over the swq to find out how long
+ * each packet is (up until 64k) and provide that
+ * to the rate control lookup.
*/
- ath_tx_do_ratelookup(sc, bf);
- bf->bf_state.bfs_rc[3].rix = 0;
- bf->bf_state.bfs_rc[3].tries = 0;
+ swq_pktbytes = ath_tx_tid_swq_depth_bytes(sc, an, tid);
+ ath_tx_do_ratelookup(sc, bf, tid->tid, swq_pktbytes, true);
+ /*
+ * Note this only is used for the fragment paths and
+ * should really be rethought out if we want to do
+ * things like an RTS burst across >1 aggregate.
+ */
ath_tx_calc_duration(sc, bf);
ath_tx_calc_protection(sc, bf);
@@ -5535,7 +5606,6 @@ ath_tx_tid_hw_queue_aggr(struct ath_softc *sc, struct ath_node *an,
* already points to the rest in the chain.
*/
ath_tx_setds_11n(sc, bf);
-
}
queuepkt:
/* Set completion handler, multi-frame aggregate or not */
@@ -5607,7 +5677,6 @@ ath_tx_tid_hw_queue_norm(struct ath_softc *sc, struct ath_node *an,
__func__, tid->tid);
for (;;) {
-
/*
* If the upper layers have paused the TID, don't
* queue any further packets.
@@ -5644,7 +5713,8 @@ ath_tx_tid_hw_queue_norm(struct ath_softc *sc, struct ath_node *an,
ath_tx_update_clrdmask(sc, tid, bf);
/* Program descriptors + rate control */
- ath_tx_do_ratelookup(sc, bf);
+ ath_tx_do_ratelookup(sc, bf, tid->tid,
+ bf->bf_state.bfs_pktlen, false);
ath_tx_calc_duration(sc, bf);
ath_tx_calc_protection(sc, bf);
ath_tx_set_rtscts(sc, bf);
@@ -5838,7 +5908,6 @@ ath_tx_ampdu_pending(struct ath_softc *sc, struct ath_node *an, int tid)
* Is AMPDU-TX pending for the given TID?
*/
-
/*
* Method to handle sending an ADDBA request.
*
@@ -5966,7 +6035,6 @@ ath_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
return r;
}
-
/*
* Stop ADDBA on a queue.
*
diff --git a/sys/dev/ath/if_ath_tx.h b/sys/dev/ath/if_ath_tx.h
index 517007716e9f..2ad2f75e926d 100644
--- a/sys/dev/ath/if_ath_tx.h
+++ b/sys/dev/ath/if_ath_tx.h
@@ -71,7 +71,6 @@
#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
-
/* extracting the seqno from buffer seqno */
#define SEQNO(_a) ((_a) >> IEEE80211_SEQ_SEQ_SHIFT)
diff --git a/sys/dev/ath/if_ath_tx_edma.c b/sys/dev/ath/if_ath_tx_edma.c
index 375c7ff4bbc8..4ec98b3382c9 100644
--- a/sys/dev/ath/if_ath_tx_edma.c
+++ b/sys/dev/ath/if_ath_tx_edma.c
@@ -654,7 +654,7 @@ ath_edma_setup_txfifo(struct ath_softc *sc, int qnum)
* Set initial "empty" state.
*/
te->m_fifo_head = te->m_fifo_tail = te->m_fifo_depth = 0;
-
+
return (0);
}
@@ -778,7 +778,6 @@ ath_edma_tx_proc(void *arg, int npending)
#endif
ath_edma_tx_processq(sc, 1);
-
ATH_PCU_LOCK(sc);
sc->sc_txproc_cnt--;
ATH_PCU_UNLOCK(sc);
@@ -1012,6 +1011,8 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched)
sc->sc_stats.ast_tx_rssi = ts.ts_rssi;
ATH_RSSI_LPF(sc->sc_halstats.ns_avgtxrssi,
ts.ts_rssi);
+ ATH_RSSI_LPF(ATH_NODE(ni)->an_node_stats.ns_avgtxrssi,
+ ts.ts_rssi);
}
/* Handle frame completion and rate control update */
diff --git a/sys/dev/ath/if_ath_tx_ht.c b/sys/dev/ath/if_ath_tx_ht.c
index 249cbe23b538..c7fa41443d26 100644
--- a/sys/dev/ath/if_ath_tx_ht.c
+++ b/sys/dev/ath/if_ath_tx_ht.c
@@ -840,16 +840,25 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_node *an,
goto finish;
}
+ /*
+ * Limit the maximum number of frames in this A-MPDU
+ * to half of the window size. This is done to prevent
+ * sending a LOT of frames that may fail in one batch
+ * when operating in higher MCS rates. If there are more
+ * frames available to send then up to two A-MPDUs will
+ * be queued per hardware queue, so we'll "just" get
+ * a second A-MPDU.
+ */
h_baw = tap->txa_wnd / 2;
for (;;) {
bf = ATH_TID_FIRST(tid);
- if (bf_first == NULL)
- bf_first = bf;
if (bf == NULL) {
status = ATH_AGGR_DONE;
break;
- } else {
+ }
+ if (bf_first == NULL) {
+ bf_first = bf;
/*
* It's the first frame;
* set the aggregation limit based on the
@@ -857,6 +866,10 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_node *an,
*/
aggr_limit = ath_get_aggr_limit(sc, &an->an_node,
bf_first);
+ if (bf_first->bf_state.bfs_rc_maxpktlen > 0) {
+ aggr_limit = MIN(aggr_limit,
+ bf_first->bf_state.bfs_rc_maxpktlen);
+ }
}
/* Set this early just so things don't get confused */
@@ -1013,7 +1026,6 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_node *an,
break;
}
#endif
-
}
finish:
@@ -1022,6 +1034,10 @@ finish:
* dequeue a packet ..
*/
if (bf_first) {
+ DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
+ "%s: al=%d bytes; requested %d bytes\n",
+ __func__, al, bf_first->bf_state.bfs_rc_maxpktlen);
+
bf_first->bf_state.bfs_al = al;
bf_first->bf_state.bfs_nframes = nframes;
}
diff --git a/sys/dev/ath/if_athioctl.h b/sys/dev/ath/if_athioctl.h
index 82decdefe3d4..8367a3ebac18 100644
--- a/sys/dev/ath/if_athioctl.h
+++ b/sys/dev/ath/if_athioctl.h
@@ -193,7 +193,6 @@ struct ath_diag {
#define SIOCGATHDIAG _IOWR('i', 138, struct ath_diag)
#define SIOCGATHPHYERR _IOWR('i', 140, struct ath_diag)
-
/*
* The rate control ioctl has to support multiple potential rate
* control classes. For now, instead of trying to support an
diff --git a/sys/dev/ath/if_athrate.h b/sys/dev/ath/if_athrate.h
index 5aec9e6b3870..45711a1735bc 100644
--- a/sys/dev/ath/if_athrate.h
+++ b/sys/dev/ath/if_athrate.h
@@ -125,17 +125,23 @@ void ath_rate_newassoc(struct ath_softc *, struct ath_node *,
* Return the four TX rate index and try counts for the current data packet.
*/
void ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
- uint8_t rix0, struct ath_rc_series *rc);
+ uint8_t rix0, int is_aggr, struct ath_rc_series *rc);
/*
* Return the transmit info for a data packet. If multi-rate state
* is to be setup then try0 should contain a value other than ATH_TXMATRY
* and ath_rate_setupxtxdesc will be called after deciding if the frame
* can be transmitted with multi-rate retry.
+ *
+ * maxdur is an optional return value (or -1 if not set) that defines
+ * the maximum frame duration in microseconds. This allows the rate
+ * control selection to override the maximum duration (normally 4ms)
+ * that the packet aggregation logic makes.
*/
void ath_rate_findrate(struct ath_softc *, struct ath_node *,
- int shortPreamble, size_t frameLen,
- u_int8_t *rix, int *try0, u_int8_t *txrate);
+ int shortPreamble, size_t frameLen, int tid, int is_aggr,
+ u_int8_t *rix, int *try0, u_int8_t *txrate, int *maxdur,
+ int *maxpktlen);
/*
* Setup any extended (multi-rate) descriptor state for a data packet.
* The rate index returned by ath_rate_findrate is passed back in.
@@ -154,7 +160,13 @@ void ath_rate_setupxtxdesc(struct ath_softc *, struct ath_node *,
struct ath_buf;
void ath_rate_tx_complete(struct ath_softc *, struct ath_node *,
const struct ath_rc_series *, const struct ath_tx_status *,
- int pktlen, int nframes, int nbad);
+ int pktlen, int rc_framelen, int nframes, int nbad);
+
+/*
+ * Update rate control with a per-packet receive RSSI value.
+ */
+void ath_rate_update_rx_rssi(struct ath_softc *, struct ath_node *,
+ int rssi);
/*
* Fetch the global rate control statistics.
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index 96d22f511746..c789b2c459c1 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -204,6 +204,7 @@ struct ath_node {
node */
int clrdmask; /* has clrdmask been set */
uint32_t an_leak_count; /* How many frames to leak during pause */
+ HAL_NODE_STATS an_node_stats; /* HAL node stats for this node */
/* variable-length rate control state follows */
};
#define ATH_NODE(ni) ((struct ath_node *)(ni))
@@ -307,6 +308,7 @@ struct ath_buf {
/* 16 bit? */
uint32_t bfs_ctsduration; /* CTS duration (pre-11n NICs) */
+ int32_t bfs_rc_maxpktlen; /* max packet length/bucket from ratectrl or -1 */
struct ath_rc_series bfs_rc[ATH_RC_NUM]; /* non-11n TX series */
} bf_state;
};
@@ -409,7 +411,6 @@ struct ath_txq {
#define ATH_TXQ_UNLOCK_ASSERT(_tq) mtx_assert(&(_tq)->axq_lock, \
MA_NOTOWNED)
-
#define ATH_NODE_LOCK(_an) mtx_lock(&(_an)->an_mtx)
#define ATH_NODE_UNLOCK(_an) mtx_unlock(&(_an)->an_mtx)
#define ATH_NODE_LOCK_ASSERT(_an) mtx_assert(&(_an)->an_mtx, MA_OWNED)
@@ -1155,8 +1156,8 @@ void ath_intr(void *);
((*(_ah)->ah_stopTxDma)((_ah), (_qnum)))
#define ath_hal_stoppcurecv(_ah) \
((*(_ah)->ah_stopPcuReceive)((_ah)))
-#define ath_hal_startpcurecv(_ah) \
- ((*(_ah)->ah_startPcuReceive)((_ah)))
+#define ath_hal_startpcurecv(_ah, _is_scanning) \
+ ((*(_ah)->ah_startPcuReceive)((_ah), (_is_scanning)))
#define ath_hal_stopdmarecv(_ah) \
((*(_ah)->ah_stopDmaReceive)((_ah)))
#define ath_hal_getdiagstate(_ah, _id, _indata, _insize, _outdata, _outsize) \
@@ -1352,7 +1353,7 @@ void ath_intr(void *);
== HAL_OK)
#define ath_hal_setrxbufsize(_ah, _req) \
(ath_hal_setcapability(_ah, HAL_CAP_RXBUFSIZE, 0, _req, NULL) \
- == HAL_OK)
+ == AH_TRUE)
#define ath_hal_getchannoise(_ah, _c) \
((*(_ah)->ah_getChanNoise)((_ah), (_c)))
diff --git a/sys/dev/bwi/bwimac.c b/sys/dev/bwi/bwimac.c
index f998873a713b..3e77e43004fa 100644
--- a/sys/dev/bwi/bwimac.c
+++ b/sys/dev/bwi/bwimac.c
@@ -57,7 +57,7 @@ __FBSDID("$FreeBSD$");
#include <sys/linker.h>
#include <sys/firmware.h>
-
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
diff --git a/sys/dev/bwi/bwiphy.c b/sys/dev/bwi/bwiphy.c
index a17735590007..291e3253f502 100644
--- a/sys/dev/bwi/bwiphy.c
+++ b/sys/dev/bwi/bwiphy.c
@@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
-
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
@@ -88,7 +88,6 @@ static void bwi_phy_config_agc(struct bwi_mac *);
static void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
static void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
-
#define SUP_BPHY(num) { .rev = num, .init = bwi_phy_init_11b_rev##num }
static const struct {
diff --git a/sys/dev/bwi/bwirf.c b/sys/dev/bwi/bwirf.c
index dbf658d5caa7..1345c64d126a 100644
--- a/sys/dev/bwi/bwirf.c
+++ b/sys/dev/bwi/bwirf.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
-
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c
index feb522acfc3c..af1cbd41d883 100644
--- a/sys/dev/bwi/if_bwi.c
+++ b/sys/dev/bwi/if_bwi.c
@@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/taskqueue.h>
-
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
@@ -118,7 +118,6 @@ static void bwi_set_channel(struct ieee80211com *);
static void bwi_scan_end(struct ieee80211com *);
static int bwi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void bwi_updateslot(struct ieee80211com *);
-static int bwi_media_change(struct ifnet *);
static void bwi_calibrate(void *);
@@ -607,8 +606,8 @@ bwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_init(vap);
/* complete setup */
- ieee80211_vap_attach(vap, bwi_media_change, ieee80211_media_status,
- mac);
+ ieee80211_vap_attach(vap, ieee80211_media_change,
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -1807,14 +1806,6 @@ back:
}
static int
-bwi_media_change(struct ifnet *ifp)
-{
- int error = ieee80211_media_change(ifp);
- /* NB: only the fixed rate can change and that doesn't need a reset */
- return (error == ENETRESET ? 0 : error);
-}
-
-static int
bwi_dma_alloc(struct bwi_softc *sc)
{
int error, i, has_txstats;
diff --git a/sys/dev/bwi/if_bwi_pci.c b/sys/dev/bwi/if_bwi_pci.c
index f95ef854ceaa..d82b7d4d60de 100644
--- a/sys/dev/bwi/if_bwi_pci.c
+++ b/sys/dev/bwi/if_bwi_pci.c
@@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <sys/socket.h>
-
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_media.h>
@@ -246,7 +246,6 @@ static device_method_t bwi_pci_methods[] = {
DEVMETHOD(device_shutdown, bwi_pci_shutdown),
DEVMETHOD(device_suspend, bwi_pci_suspend),
DEVMETHOD(device_resume, bwi_pci_resume),
-
{ 0,0 }
};
static driver_t bwi_driver = {
diff --git a/sys/dev/bwi/if_bwireg.h b/sys/dev/bwi/if_bwireg.h
index 67c80cec9615..d1d37c491634 100644
--- a/sys/dev/bwi/if_bwireg.h
+++ b/sys/dev/bwi/if_bwireg.h
@@ -77,7 +77,6 @@
#define BWI_CONF_LO_REQTO_MASK __BITS(6, 4) /* request timeout */
#define BWI_CONF_LO_REQTO 3
-
#define BWI_ID_LO 0xff8
#define BWI_ID_LO_BUSREV_MASK __BITS(31, 28)
/* Bus revision */
diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
index 067484acbaf3..b2ffe7b1f6ba 100644
--- a/sys/dev/bwn/if_bwn.c
+++ b/sys/dev/bwn/if_bwn.c
@@ -580,7 +580,7 @@ bwn_attach(device_t dev)
device_printf(sc->sc_dev, "couldn't allocate registers\n");
return (error);
}
-
+
if ((error = bhnd_alloc_pmu(sc->sc_dev))) {
bus_release_resource(sc->sc_dev, SYS_RES_MEMORY,
sc->sc_mem_rid, sc->sc_mem_res);
@@ -632,9 +632,10 @@ bwn_attach(device_t dev)
goto fail;
bhnd_format_chip_id(chip_name, sizeof(chip_name), sc->sc_cid.chip_id);
- device_printf(sc->sc_dev, "WLAN (%s rev %u) "
+ device_printf(sc->sc_dev, "WLAN (%s rev %u sromrev %u) "
"PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
- chip_name, bhnd_get_hwrev(sc->sc_dev), mac->mac_phy.analog,
+ chip_name, bhnd_get_hwrev(sc->sc_dev),
+ sc->sc_board_info.board_srom_rev, mac->mac_phy.analog,
mac->mac_phy.type, mac->mac_phy.rev, mac->mac_phy.rf_manuf,
mac->mac_phy.rf_ver, mac->mac_phy.rf_rev);
if (mac->mac_flags & BWN_MAC_FLAG_DMA)
@@ -684,7 +685,7 @@ fail:
free(mac, M_DEVBUF);
bhnd_release_pmu(dev);
bwn_release_bus_providers(sc);
-
+
if (sc->sc_mem_res != NULL) {
bus_release_resource(sc->sc_dev, SYS_RES_MEMORY,
sc->sc_mem_rid, sc->sc_mem_res);
@@ -1306,7 +1307,6 @@ bwn_attach_core(struct bwn_mac *mac)
have_bg = 1;
have_a = 1;
}
-
#if 0
device_printf(sc->sc_dev, "%s: iost=0x%04hx, have_a=%d, have_bg=%d,"
@@ -3040,7 +3040,7 @@ bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
struct bhnd_dma_translation *dt;
uint32_t addr, addrext, ctl;
int slot;
-
+
descbase = dr->dr_ring_descbase;
dma = &dr->dr_mac->mac_method.dma;
dt = &dma->translation;
@@ -3136,8 +3136,7 @@ bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
uint32_t addrext;
uint32_t ctl0, ctl1;
int slot;
-
-
+
descbase = dr->dr_ring_descbase;
dma = &dr->dr_mac->mac_method.dma;
dt = &dma->translation;
@@ -3685,7 +3684,6 @@ bwn_gpio_control(struct bwn_mac *mac, uint32_t pins)
return (0);
}
-
static int
bwn_gpio_init(struct bwn_mac *mac)
{
@@ -4526,7 +4524,6 @@ bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
iv = GET_NEXTIV32(iv);
} else {
-
if (array_size < sizeof(iv->data.d16))
goto fail;
array_size -= sizeof(iv->data.d16);
@@ -6004,7 +6001,6 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
break;
}
-
phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
if (macstat & BWN_RX_MAC_FCSERR)
@@ -7168,7 +7164,6 @@ bwn_dma_attach(struct bwn_mac *mac)
return (ENXIO);
}
-
/* Fetch our device->host DMA translation and tag */
error = bhnd_get_dma_translation(sc->sc_dev, addr_width, 0, &dmat,
&dma_translation);
diff --git a/sys/dev/bwn/if_bwn_pci.c b/sys/dev/bwn/if_bwn_pci.c
index 610f8bdeb823..51ff56184f8a 100644
--- a/sys/dev/bwn/if_bwn_pci.c
+++ b/sys/dev/bwn/if_bwn_pci.c
@@ -90,7 +90,6 @@ static const struct bwn_pci_device siba_devices[] = {
BWN_QUIRK_UNTESTED),
BWN_BCM_DEV(BCM4328_D11G, "BCM4328/4312 802.11g", 0),
-
{ 0, 0, NULL, 0 }
};
@@ -102,7 +101,6 @@ static const struct bwn_pci_device bcma_devices[] = {
BWN_BCM_DEV(BCM43224_D11N, "BCM43224 802.11n Dual-Band", 0),
BWN_BCM_DEV(BCM43224_D11N_ID_VEN1, "BCM43224 802.11n Dual-Band",0),
BWN_BCM_DEV(BCM43225_D11N2G, "BCM43225 802.11n 2GHz", 0),
-
{ 0, 0, NULL, 0}
};
diff --git a/sys/dev/bwn/if_bwn_pcivar.h b/sys/dev/bwn/if_bwn_pcivar.h
index 06c781e557f6..2b134de07e26 100644
--- a/sys/dev/bwn/if_bwn_pcivar.h
+++ b/sys/dev/bwn/if_bwn_pcivar.h
@@ -91,7 +91,6 @@ struct bwn_pci_device {
uint32_t quirks;
};
-
#define BWN_BCM_DEV(_devid, _desc, _quirks) \
{ PCI_VENDOR_BROADCOM, PCI_DEVID_ ## _devid, \
"Broadcom " _desc " Wireless", _quirks }
diff --git a/sys/dev/bwn/if_bwn_phy_g.c b/sys/dev/bwn/if_bwn_phy_g.c
index fecb06109282..1659eb2a99bb 100644
--- a/sys/dev/bwn/if_bwn_phy_g.c
+++ b/sys/dev/bwn/if_bwn_phy_g.c
@@ -1689,7 +1689,6 @@ bwn_wa_grev1(struct bwn_mac *mac)
bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
bwn_tab_noise_g2[i]);
-
for (i = 0; i < N(bwn_tab_rotor); i++)
bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
bwn_tab_rotor[i]);
diff --git a/sys/dev/bwn/if_bwnvar.h b/sys/dev/bwn/if_bwnvar.h
index a97268de93d6..42930c20377a 100644
--- a/sys/dev/bwn/if_bwnvar.h
+++ b/sys/dev/bwn/if_bwnvar.h
@@ -161,7 +161,6 @@ struct bwn_mac;
#define BWN_DMA_WRITE(dr, offset, value) \
(BWN_WRITE_4(dr->dr_mac, dr->dr_base + offset, value))
-
typedef enum {
BWN_PHY_BAND_2G = 0,
BWN_PHY_BAND_5G_LO = 1,
diff --git a/sys/dev/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c
index e1bdb6d79b64..7657190e763e 100644
--- a/sys/dev/iwm/if_iwm.c
+++ b/sys/dev/iwm/if_iwm.c
@@ -4415,22 +4415,26 @@ iwm_setrates(struct iwm_softc *sc, struct iwm_node *in, int rix)
static int
iwm_media_change(struct ifnet *ifp)
{
+#if 0
struct ieee80211vap *vap = ifp->if_softc;
struct ieee80211com *ic = vap->iv_ic;
struct iwm_softc *sc = ic->ic_softc;
+#endif
int error;
error = ieee80211_media_change(ifp);
- if (error != ENETRESET)
- return error;
+ if (error != 0)
+ return (error);
+#if 0
IWM_LOCK(sc);
if (ic->ic_nrunning > 0) {
iwm_stop(sc);
iwm_init(sc);
}
IWM_UNLOCK(sc);
- return error;
+#endif
+ return (0);
}
static void
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index e3b87f214ec2..2e576efc288c 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -194,7 +194,6 @@ static void iwn_read_eeprom_enhinfo(struct iwn_softc *);
static struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
const uint8_t mac[IEEE80211_ADDR_LEN]);
static void iwn_newassoc(struct ieee80211_node *, int);
-static int iwn_media_change(struct ifnet *);
static int iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void iwn_calib_timeout(void *);
static void iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *);
@@ -1351,11 +1350,13 @@ iwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ivp->iv_newstate = vap->iv_newstate;
vap->iv_newstate = iwn_newstate;
sc->ivap[IWN_RXON_BSS_CTX] = vap;
+ vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K;
+ vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_4; /* 4uS */
ieee80211_ratectl_init(vap);
/* Complete setup. */
- ieee80211_vap_attach(vap, iwn_media_change, ieee80211_media_status,
- mac);
+ ieee80211_vap_attach(vap, ieee80211_media_change,
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -2882,16 +2883,6 @@ iwn_newassoc(struct ieee80211_node *ni, int isnew)
}
static int
-iwn_media_change(struct ifnet *ifp)
-{
- int error;
-
- error = ieee80211_media_change(ifp);
- /* NB: only the fixed rate can change and that doesn't need a reset */
- return (error == ENETRESET ? 0 : error);
-}
-
-static int
iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct iwn_vap *ivp = IWN_VAP(vap);
diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c
index a33e49324968..be5d279f6e10 100644
--- a/sys/dev/mwl/if_mwl.c
+++ b/sys/dev/mwl/if_mwl.c
@@ -59,7 +59,7 @@ __FBSDID("$FreeBSD$");
#include <sys/taskqueue.h>
#include <machine/bus.h>
-
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
@@ -1470,16 +1470,17 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
static int
mwl_media_change(struct ifnet *ifp)
{
- struct ieee80211vap *vap = ifp->if_softc;
+ struct ieee80211vap *vap;
int error;
- error = ieee80211_media_change(ifp);
/* NB: only the fixed rate can change and that doesn't need a reset */
- if (error == ENETRESET) {
- mwl_setrates(vap);
- error = 0;
- }
- return error;
+ error = ieee80211_media_change(ifp);
+ if (error != 0)
+ return (error);
+
+ vap = ifp->if_softc;
+ mwl_setrates(vap);
+ return (0);
}
#ifdef MWL_DEBUG
diff --git a/sys/dev/mwl/if_mwl_pci.c b/sys/dev/mwl/if_mwl_pci.c
index 6dd521a6ed9a..bf17fe4750b1 100644
--- a/sys/dev/mwl/if_mwl_pci.c
+++ b/sys/dev/mwl/if_mwl_pci.c
@@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <sys/socket.h>
-
+
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_media.h>
@@ -98,7 +98,6 @@ static const struct mwl_pci_ident mwl_pci_ids[] = {
{ 0x11ab, 0x2a0c, "Marvell 88W8363" },
{ 0x11ab, 0x2a21, "Marvell 88W8363" },
{ 0x11ab, 0x2a24, "Marvell 88W8363" },
-
{ 0, 0, NULL }
};
@@ -280,7 +279,6 @@ static device_method_t mwl_pci_methods[] = {
DEVMETHOD(device_shutdown, mwl_pci_shutdown),
DEVMETHOD(device_suspend, mwl_pci_suspend),
DEVMETHOD(device_resume, mwl_pci_resume),
-
{ 0,0 }
};
static driver_t mwl_pci_driver = {
diff --git a/sys/dev/mwl/mwlreg.h b/sys/dev/mwl/mwlreg.h
index 9b64dda9f83a..899b97c21cd0 100644
--- a/sys/dev/mwl/mwlreg.h
+++ b/sys/dev/mwl/mwlreg.h
@@ -57,7 +57,6 @@
#define MACREG_REG_A2H_INTERRUPT_CLEAR_SEL 0x00000C38 // (From ARM to host)
#define MACREG_REG_A2H_INTERRUPT_STATUS_MASK 0x00000C3C // (From ARM to host)
-
// Map to 0x80000000 on BAR1
#define MACREG_REG_GEN_PTR 0x00000C10
#define MACREG_REG_INT_CODE 0x00000C14
@@ -101,7 +100,6 @@
#define MACREG_A2HRIC_BIT_MASK ISR_SRC_BITS
-
// Bit definitio for MACREG_REG_H2A_INTERRUPT_CAUSE (H2ARIC)
#define MACREG_H2ARIC_BIT_PPA_READY 0x00000001 // bit 0
#define MACREG_H2ARIC_BIT_DOOR_BELL 0x00000002 // bit 1
@@ -341,7 +339,6 @@ struct mwl_rxdesc {
#define HostCmd_RESULT_BUSY 0x0004 // System is busy (command ignored)
#define HostCmd_RESULT_PARTIAL_DATA 0x0005 // Data buffer is not big enough
-
/*
// Definition of action or option for each command
//
@@ -377,7 +374,6 @@ struct mwl_rxdesc {
#define HostCmd_WEP_KEY_INDEX_MASK 0x3fffffff
-
// Define action or option for HostCmd_CMD_802_11_RESET
#define HostCmd_ACT_HALT 0x0001
#define HostCmd_ACT_RESTART 0x0002
@@ -485,7 +481,6 @@ typedef struct {
u_int32_t Enable; /* FALSE: Disable or TRUE: Enable */
} __packed HostCmd_DS_BSS_START;
-
typedef struct {
u_int8_t ElemId;
u_int8_t Len;
@@ -704,7 +699,7 @@ typedef struct {
uint32_t FixedRate; // legacy rate(not index) or an MCS code.
uint32_t RetryCount;
} __packed FIXED_RATE_ENTRY;
-
+
typedef struct {
FWCmdHdr CmdHdr;
uint32_t Action; //HostCmd_ACT_GEN_GET 0x0000
@@ -723,7 +718,7 @@ typedef struct {
uint32_t EntryCount;
FIXED_RATE_ENTRY FixedRateTable[4];
} __packed USE_FIXED_RATE_INFO;
-
+
typedef struct {
FWCmdHdr CmdHdr;
uint32_t Action;
@@ -745,7 +740,6 @@ typedef struct {
uint8_t Slot; // Slot=0 if regular, Slot=1 if short.
} __packed HostCmd_FW_SET_SLOT;
-
// Define data structure for HostCmd_CMD_802_11_GET_STAT
typedef struct {
FWCmdHdr CmdHdr;
@@ -778,7 +772,6 @@ typedef struct {
uint32_t RxExcludedFrames;
} __packed HostCmd_DS_802_11_GET_STAT;
-
// Define data structure for HostCmd_CMD_MAC_REG_ACCESS
typedef struct {
FWCmdHdr CmdHdr;
@@ -806,7 +799,6 @@ typedef struct {
uint8_t Reserverd[3];
} __packed HostCmd_DS_RF_REG_ACCESS;
-
// Define data structure for HostCmd_CMD_802_11_RADIO_CONTROL
typedef struct {
FWCmdHdr CmdHdr;
@@ -815,7 +807,6 @@ typedef struct {
uint16_t RadioOn;
} __packed HostCmd_DS_802_11_RADIO_CONTROL;
-
#define TX_POWER_LEVEL_TOTAL 8
// Define data structure for HostCmd_CMD_802_11_RF_TX_POWER
typedef struct {
@@ -1141,7 +1132,6 @@ typedef struct {
uint8_t ActionData[1];
} __packed HostCmd_FW_UPDATE_ENCRYPTION;
-
typedef struct {
FWCmdHdr CmdHdr;
uint32_t ActionType; // ENCR_ACTION_TYPE
@@ -1272,8 +1262,6 @@ typedef struct {
uint8_t Watchdogbitmap; // for SW/BA
} __packed HostCmd_FW_GET_WATCHDOG_BITMAP;
-
-
// Define data structure for HostCmd_CMD_SET_REGION_POWER
typedef struct {
FWCmdHdr CmdHdr;
diff --git a/sys/dev/otus/if_otus.c b/sys/dev/otus/if_otus.c
index 3ac3130e7791..df8199901c4f 100644
--- a/sys/dev/otus/if_otus.c
+++ b/sys/dev/otus/if_otus.c
@@ -90,6 +90,7 @@ SYSCTL_INT(_hw_usb_otus, OID_AUTO, debug, CTLFLAG_RWTUN, &otus_debug, 0,
#define OTUS_DEBUG_REGIO 0x00000200
#define OTUS_DEBUG_IRQ 0x00000400
#define OTUS_DEBUG_TXCOMP 0x00000800
+#define OTUS_DEBUG_RX_BUFFER 0x00001000
#define OTUS_DEBUG_ANY 0xffffffff
#define OTUS_DPRINTF(sc, dm, ...) \
@@ -130,7 +131,6 @@ static device_attach_t otus_attach;
static device_detach_t otus_detach;
static int otus_attachhook(struct otus_softc *);
-void otus_get_chanlist(struct otus_softc *);
static void otus_getradiocaps(struct ieee80211com *, int, int *,
struct ieee80211_channel[]);
int otus_load_firmware(struct otus_softc *, const char *,
@@ -166,7 +166,6 @@ void otus_write(struct otus_softc *, uint32_t, uint32_t);
int otus_write_barrier(struct otus_softc *);
static struct ieee80211_node *otus_node_alloc(struct ieee80211vap *vap,
const uint8_t mac[IEEE80211_ADDR_LEN]);
-int otus_media_change(struct ifnet *);
int otus_read_eeprom(struct otus_softc *);
void otus_newassoc(struct ieee80211_node *, int);
void otus_cmd_rxeof(struct otus_softc *, uint8_t *, int);
@@ -394,9 +393,8 @@ otus_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
uvp->newstate = vap->iv_newstate;
vap->iv_newstate = otus_newstate;
- /* XXX TODO: double-check */
- vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_16;
- vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_32K;
+ vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_8;
+ vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K;
ieee80211_ratectl_init(vap);
@@ -698,6 +696,16 @@ otus_attachhook(struct otus_softc *sc)
IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->eeprom.baseEepHeader.macAddr);
sc->sc_led_newstate = otus_led_newstate_type3; /* XXX */
+ if (sc->txmask == 0x5)
+ ic->ic_txstream = 2;
+ else
+ ic->ic_txstream = 1;
+
+ if (sc->rxmask == 0x5)
+ ic->ic_rxstream = 2;
+ else
+ ic->ic_rxstream = 1;
+
device_printf(sc->sc_dev,
"MAC/BBP AR9170, RF AR%X, MIMO %dT%dR, address %s\n",
(sc->capflags & AR5416_OPFLAGS_11A) ?
@@ -720,33 +728,21 @@ otus_attachhook(struct otus_softc *sc)
IEEE80211_C_WME | /* WME/QoS */
IEEE80211_C_SHSLOT | /* Short slot time supported. */
IEEE80211_C_FF | /* Atheros fast-frames supported. */
- IEEE80211_C_MONITOR |
+ IEEE80211_C_MONITOR | /* Enable monitor mode */
+ IEEE80211_C_SWAMSDUTX | /* Do software A-MSDU TX */
IEEE80211_C_WPA; /* WPA/RSN. */
- /* XXX TODO: 11n */
-
+ ic->ic_htcaps =
+ IEEE80211_HTC_HT |
#if 0
- if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) {
- /* Set supported .11b and .11g rates. */
- ic->ic_sup_rates[IEEE80211_MODE_11B] =
- ieee80211_std_rateset_11b;
- ic->ic_sup_rates[IEEE80211_MODE_11G] =
- ieee80211_std_rateset_11g;
- }
- if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) {
- /* Set supported .11a rates. */
- ic->ic_sup_rates[IEEE80211_MODE_11A] =
- ieee80211_std_rateset_11a;
- }
+ IEEE80211_HTC_AMPDU |
#endif
+ IEEE80211_HTC_AMSDU |
+ IEEE80211_HTCAP_MAXAMSDU_3839 |
+ IEEE80211_HTCAP_SMPS_OFF;
-#if 0
- /* Build the list of supported channels. */
- otus_get_chanlist(sc);
-#else
otus_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
ic->ic_channels);
-#endif
ieee80211_ifattach(ic);
ic->ic_raw_xmit = otus_raw_xmit;
@@ -779,38 +775,6 @@ otus_attachhook(struct otus_softc *sc)
return (0);
}
-void
-otus_get_chanlist(struct otus_softc *sc)
-{
- struct ieee80211com *ic = &sc->sc_ic;
- uint16_t domain;
- uint8_t chan;
- int i;
-
- /* XXX regulatory domain. */
- domain = le16toh(sc->eeprom.baseEepHeader.regDmn[0]);
- OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, "regdomain=0x%04x\n", domain);
-
- if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) {
- for (i = 0; i < 14; i++) {
- chan = ar_chans[i];
- ic->ic_channels[chan].ic_freq =
- ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
- ic->ic_channels[chan].ic_flags =
- IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
- IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
- }
- }
- if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) {
- for (i = 14; i < nitems(ar_chans); i++) {
- chan = ar_chans[i];
- ic->ic_channels[chan].ic_freq =
- ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ);
- ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A;
- }
- }
-}
-
static void
otus_getradiocaps(struct ieee80211com *ic,
int maxchans, int *nchans, struct ieee80211_channel chans[])
@@ -823,15 +787,13 @@ otus_getradiocaps(struct ieee80211com *ic,
if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) {
setbit(bands, IEEE80211_MODE_11B);
setbit(bands, IEEE80211_MODE_11G);
-#if 0
- if (sc->sc_ht)
- setbit(bands, IEEE80211_MODE_11NG);
-#endif
+ setbit(bands, IEEE80211_MODE_11NG);
ieee80211_add_channel_list_2ghz(chans, maxchans, nchans,
ar_chans, 14, bands, 0);
}
if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) {
setbit(bands, IEEE80211_MODE_11A);
+ setbit(bands, IEEE80211_MODE_11NA);
ieee80211_add_channel_list_5ghz(chans, maxchans, nchans,
&ar_chans[14], nitems(ar_chans) - 14, bands, 0);
}
@@ -1375,35 +1337,6 @@ otus_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
M_NOWAIT | M_ZERO);
}
-#if 0
-int
-otus_media_change(struct ifnet *ifp)
-{
- struct otus_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = &sc->sc_ic;
- uint8_t rate, ridx;
- int error;
-
- error = ieee80211_media_change(ifp);
- if (error != ENETRESET)
- return error;
-
- if (ic->ic_fixed_rate != -1) {
- rate = ic->ic_sup_rates[ic->ic_curmode].
- rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
- for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++)
- if (otus_rates[ridx].rate == rate)
- break;
- sc->fixed_ridx = ridx;
- }
-
- if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
- error = otus_init(sc);
-
- return error;
-}
-#endif
-
int
otus_read_eeprom(struct otus_softc *sc)
{
@@ -1587,6 +1520,12 @@ otus_cmd_rxeof(struct otus_softc *sc, uint8_t *buf, int len)
}
}
+/*
+ * Handle a single MPDU.
+ *
+ * This may be a single MPDU, or it may be a sub-frame from an A-MPDU.
+ * In the latter case some of the header details need to be adjusted.
+ */
void
otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len, struct mbufq *rxq)
{
@@ -1595,41 +1534,126 @@ otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len, struct mbufq *rxq)
#if 0
struct ieee80211_node *ni;
#endif
- struct ar_rx_tail *tail;
+ struct ar_rx_macstatus *mac_status = NULL;
+ struct ar_rx_phystatus *phy_status = NULL;
struct ieee80211_frame *wh;
struct mbuf *m;
- uint8_t *plcp;
// int s;
- int mlen;
- if (__predict_false(len < AR_PLCP_HDR_LEN)) {
- OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
- "sub-xfer too short %d\n", len);
- return;
+
+ if (otus_debug & OTUS_DEBUG_RX_BUFFER) {
+ device_printf(sc->sc_dev, "%s: %*D\n",
+ __func__, len, buf, "-");
}
- plcp = buf;
- /* All bits in the PLCP header are set to 1 for non-MPDU. */
- if (memcmp(plcp, AR_PLCP_HDR_INTR, AR_PLCP_HDR_LEN) == 0) {
- otus_cmd_rxeof(sc, plcp + AR_PLCP_HDR_LEN,
+ /*
+ * Before any data path stuff - check to see if this is a command
+ * response.
+ *
+ * All bits in the PLCP header are set to 1 for non-MPDU.
+ */
+ if ((len >= AR_PLCP_HDR_LEN) &&
+ memcmp(buf, AR_PLCP_HDR_INTR, AR_PLCP_HDR_LEN) == 0) {
+ otus_cmd_rxeof(sc, buf + AR_PLCP_HDR_LEN,
len - AR_PLCP_HDR_LEN);
return;
}
- /* Received MPDU. */
- if (__predict_false(len < AR_PLCP_HDR_LEN + sizeof (*tail))) {
- OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "MPDU too short %d\n", len);
+ /*
+ * First step - get the status for the given frame.
+ * This will tell us whether it's a single MPDU or
+ * an A-MPDU subframe.
+ */
+ if (len < sizeof(*mac_status)) {
+ OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
+ "%s: sub-xfer too short (no mac_status) (len %d)\n",
+ __func__, len);
counter_u64_add(ic->ic_ierrors, 1);
return;
}
- tail = (struct ar_rx_tail *)(plcp + len - sizeof (*tail));
+ /*
+ * Remove the mac_status from the payload length.
+ *
+ * Note: cheating, don't reallocate the buffer!
+ */
+ mac_status = (struct ar_rx_macstatus *)(buf + len - sizeof(*mac_status));
+ len -= sizeof(*mac_status);
+
+ OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "%s: mac status=0x%x\n",
+ __func__, mac_status->status);
+
+ /*
+ * Next - check the MAC status before doing anything else.
+ * Extract out the PLCP header for single and first frames;
+ * since there's a single RX path we can shove PLCP headers
+ * from both into sc->ar_last_rx_plcp[] so it can be reused.
+ */
+ if (((mac_status->status & AR_RX_STATUS_MPDU_MASK) == AR_RX_STATUS_MPDU_SINGLE) ||
+ ((mac_status->status & AR_RX_STATUS_MPDU_MASK) == AR_RX_STATUS_MPDU_FIRST)) {
+ /*
+ * Ok, we need to at least have a PLCP header at
+ * this point.
+ */
+ if (len < AR_PLCP_HDR_LEN) {
+ OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
+ "%s sub-xfer too short (no mac+plcp) (len %d\n)",
+ __func__, len);
+ counter_u64_add(ic->ic_ierrors, 1);
+ return;
+ }
+ memcpy(sc->ar_last_rx_plcp, buf, AR_PLCP_HDR_LEN);
+
+ /*
+ * At this point we can just consume the PLCP header.
+ * The beginning of the frame should thus be data.
+ */
+ buf += AR_PLCP_HDR_LEN;
+ len -= AR_PLCP_HDR_LEN;
+ }
- /* Discard error frames; don't discard BAD_RA (eg monitor mode); let net80211 do that */
- if (__predict_false((tail->error & ~AR_RX_ERROR_BAD_RA) != 0)) {
- OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "error frame 0x%02x\n", tail->error);
- if (tail->error & AR_RX_ERROR_FCS) {
+ /*
+ * Next - see if we have a PHY status.
+ *
+ * The PHY status is at the end of the final A-MPDU subframe
+ * or a single MPDU frame.
+ *
+ * We'll use this to tag frames with noise floor / RSSI
+ * if they have valid information.
+ */
+ if (((mac_status->status & AR_RX_STATUS_MPDU_MASK) == AR_RX_STATUS_MPDU_SINGLE) ||
+ ((mac_status->status & AR_RX_STATUS_MPDU_MASK) == AR_RX_STATUS_MPDU_LAST)) {
+ if (len < sizeof(*phy_status)) {
+ OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
+ "%s sub-xfer too short (no phy status) (len %d\n)",
+ __func__, len);
+ counter_u64_add(ic->ic_ierrors, 1);
+ return;
+ }
+ /*
+ * Take a pointer to the phy status and remove the length
+ * from the end of the buffer.
+ *
+ * Note: we're cheating here; don't reallocate the buffer!
+ */
+ phy_status = (struct ar_rx_phystatus *)
+ (buf + len - sizeof(*phy_status));
+ len -= sizeof(*phy_status);
+ }
+
+ /*
+ * Middle frames just have a MAC status (stripped above.)
+ * No PHY status, and PLCP is from ar_last_rx_plcp.
+ */
+
+ /*
+ * Discard error frames; don't discard BAD_RA (eg monitor mode);
+ * let net80211 do that
+ */
+ if (__predict_false((mac_status->error & ~AR_RX_ERROR_BAD_RA) != 0)) {
+ OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "error frame 0x%02x\n", mac_status->error);
+ if (mac_status->error & AR_RX_ERROR_FCS) {
OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "bad FCS\n");
- } else if (tail->error & AR_RX_ERROR_MMIC) {
+ } else if (mac_status->error & AR_RX_ERROR_MMIC) {
/* Report Michael MIC failures to net80211. */
#if 0
ieee80211_notify_michael_failure(ni->ni_vap, wh, keyidx);
@@ -1639,77 +1663,75 @@ otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len, struct mbufq *rxq)
counter_u64_add(ic->ic_ierrors, 1);
return;
}
- /* Compute MPDU's length. */
- mlen = len - AR_PLCP_HDR_LEN - sizeof (*tail);
- /* Make sure there's room for an 802.11 header + FCS. */
- if (__predict_false(mlen < IEEE80211_MIN_LEN)) {
+
+ /*
+ * Make sure there's room for an 802.11 header + FCS.
+ *
+ * Note: a CTS/ACK is 14 bytes (FC, DUR, RA, FCS).
+ * Making it IEEE80211_MIN_LEN misses CTS/ACKs.
+ *
+ * This won't be tossed at this point; eventually once
+ * rx radiotap is implemented this will allow for
+ * CTS/ACK frames. Passing them up to net80211 will
+ * currently make it angry (too short packets.)
+ */
+ if (len < 2 + 2 + IEEE80211_ADDR_LEN + IEEE80211_CRC_LEN) {
+ OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
+ "%s: too short for 802.11 (len %d)\n",
+ __func__, len);
counter_u64_add(ic->ic_ierrors, 1);
return;
}
- mlen -= IEEE80211_CRC_LEN; /* strip 802.11 FCS */
- wh = (struct ieee80211_frame *)(plcp + AR_PLCP_HDR_LEN);
+ len -= IEEE80211_CRC_LEN; /* strip 802.11 FCS */
+ wh = (struct ieee80211_frame *) buf;
/*
- * TODO: I see > 2KiB buffers in this path; is it A-MSDU or something?
+ * The firmware does seem to spit out a bunch of frames
+ * with invalid frame control values here. Just toss them
+ * rather than letting net80211 get angry and log.
*/
- m = m_get2(mlen, M_NOWAIT, MT_DATA, M_PKTHDR);
+ if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
+ IEEE80211_FC0_VERSION_0) {
+ OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
+ "%s: invalid 802.11 fc version (firmware bug?)\n",
+ __func__);
+ counter_u64_add(ic->ic_ierrors, 1);
+ return;
+ }
+
+ m = m_get2(len, M_NOWAIT, MT_DATA, M_PKTHDR);
if (m == NULL) {
- device_printf(sc->sc_dev, "%s: failed m_get2() (mlen=%d)\n", __func__, mlen);
+ device_printf(sc->sc_dev, "%s: failed m_get2() (len=%d)\n",
+ __func__, len);
counter_u64_add(ic->ic_ierrors, 1);
return;
}
/* Finalize mbuf. */
- memcpy(mtod(m, uint8_t *), wh, mlen);
- m->m_pkthdr.len = m->m_len = mlen;
+ memcpy(mtod(m, uint8_t *), wh, len);
+ m->m_pkthdr.len = m->m_len = len;
-#if 0
- if (__predict_false(sc->sc_drvbpf != NULL)) {
- struct otus_rx_radiotap_header *tap = &sc->sc_rxtap;
- struct mbuf mb;
-
- tap->wr_flags = 0;
- tap->wr_antsignal = tail->rssi;
- tap->wr_rate = 2; /* In case it can't be found below. */
- switch (tail->status & AR_RX_STATUS_MT_MASK) {
- case AR_RX_STATUS_MT_CCK:
- switch (plcp[0]) {
- case 10: tap->wr_rate = 2; break;
- case 20: tap->wr_rate = 4; break;
- case 55: tap->wr_rate = 11; break;
- case 110: tap->wr_rate = 22; break;
- }
- if (tail->status & AR_RX_STATUS_SHPREAMBLE)
- tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
- break;
- case AR_RX_STATUS_MT_OFDM:
- switch (plcp[0] & 0xf) {
- case 0xb: tap->wr_rate = 12; break;
- case 0xf: tap->wr_rate = 18; break;
- case 0xa: tap->wr_rate = 24; break;
- case 0xe: tap->wr_rate = 36; break;
- case 0x9: tap->wr_rate = 48; break;
- case 0xd: tap->wr_rate = 72; break;
- case 0x8: tap->wr_rate = 96; break;
- case 0xc: tap->wr_rate = 108; break;
- }
- break;
- }
- mb.m_data = (caddr_t)tap;
- mb.m_next = m;
- mb.m_nextpkt = NULL;
- mb.m_type = 0;
- mb.m_flags = 0;
- bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
+ /* XXX TODO: add setting rx radiotap fields here */
+
+ /*
+ * Ok, check the frame length and toss if it's too short
+ * for net80211. This will toss ACK/CTS.
+ */
+ if (m->m_len < IEEE80211_MIN_LEN) {
+ /* XXX TODO: add radiotap receive here */
+ m_free(m); m = NULL;
+ return;
}
-#endif
- /* Add RSSI/NF to this mbuf */
+ /* Add RSSI to this mbuf if we have a PHY header */
bzero(&rxs, sizeof(rxs));
- rxs.r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI;
+ rxs.r_flags = IEEE80211_R_NF;
rxs.c_nf = sc->sc_nf[0]; /* XXX chain 0 != combined rssi/nf */
- rxs.c_rssi = tail->rssi;
+ if (phy_status != NULL) {
+ rxs.r_flags |= IEEE80211_R_RSSI;
+ rxs.c_rssi = phy_status->rssi;
+ }
/* XXX TODO: add MIMO RSSI/NF as well */
if (ieee80211_add_rx_params(m, &rxs) == 0) {
counter_u64_add(ic->ic_ierrors, 1);
@@ -1740,10 +1762,18 @@ otus_rxeof(struct usb_xfer *xfer, struct otus_data *data, struct mbufq *rxq)
caddr_t buf = data->buf;
struct ar_rx_head *head;
uint16_t hlen;
- int len;
+ int len, offset = 0;
usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
+ OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
+ "%s: transfer completed; len=%d\n",
+ __func__, len);
+ if (otus_debug & OTUS_DEBUG_RX_BUFFER) {
+ device_printf(sc->sc_dev, "%s: %*D\n",
+ __func__, len, buf, "-");
+ }
+
while (len >= sizeof (*head)) {
head = (struct ar_rx_head *)buf;
if (__predict_false(head->tag != htole16(AR_RX_HEAD_TAG))) {
@@ -1752,19 +1782,26 @@ otus_rxeof(struct usb_xfer *xfer, struct otus_data *data, struct mbufq *rxq)
break;
}
hlen = le16toh(head->len);
+ OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "%s: hlen=%d\n",
+ __func__, hlen);
if (__predict_false(sizeof (*head) + hlen > len)) {
OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
"xfer too short %d/%d\n", len, hlen);
break;
}
/* Process sub-xfer. */
- otus_sub_rxeof(sc, (uint8_t *)&head[1], hlen, rxq);
+ otus_sub_rxeof(sc, (uint8_t *) (((uint8_t *) buf) + 4), hlen, rxq);
/* Next sub-xfer is aligned on a 32-bit boundary. */
hlen = (sizeof (*head) + hlen + 3) & ~3;
+ offset += hlen;
+ OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE,
+ "%s: rounded size is %d, next packet starts at %d\n",
+ __func__, hlen, offset);
buf += hlen;
len -= hlen;
}
+ OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "%s: done!\n", __func__);
}
static void
@@ -2090,6 +2127,11 @@ otus_rate_to_hw_rate(struct otus_softc *sc, uint8_t rate)
is_2ghz = !! (IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_curchan));
+ /* MCS check */
+ if (rate & 0x80) {
+ return rate;
+ }
+
switch (rate) {
/* CCK */
case 2:
@@ -2125,12 +2167,17 @@ otus_rate_to_hw_rate(struct otus_softc *sc, uint8_t rate)
return (0x0); /* 1MB CCK */
else
return (0xb); /* 6MB OFDM */
-
- /* XXX TODO: HT */
}
}
static int
+otus_hw_rate_is_ht(struct otus_softc *sc, uint8_t hw_rate)
+{
+
+ return !! (hw_rate & 0x80);
+}
+
+static int
otus_hw_rate_is_ofdm(struct otus_softc *sc, uint8_t hw_rate)
{
@@ -2258,7 +2305,10 @@ otus_tx(struct otus_softc *sc, struct ieee80211_node *ni, struct mbuf *m,
if (!ismcast) {
if (m->m_pkthdr.len + IEEE80211_CRC_LEN >= vap->iv_rtsthreshold)
macctl |= AR_TX_MAC_RTS;
- else if (ic->ic_flags & IEEE80211_F_USEPROT) {
+ else if (otus_hw_rate_is_ht(sc, rate)) {
+ if (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS)
+ macctl |= AR_TX_MAC_RTS;
+ } else if (ic->ic_flags & IEEE80211_F_USEPROT) {
if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
macctl |= AR_TX_MAC_CTS;
else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
@@ -2266,8 +2316,15 @@ otus_tx(struct otus_softc *sc, struct ieee80211_node *ni, struct mbuf *m,
}
}
- phyctl |= AR_TX_PHY_MCS(rate);
- if (otus_hw_rate_is_ofdm(sc, rate)) {
+ phyctl |= AR_TX_PHY_MCS(rate & 0x7f); /* Note: MCS rates are 0x80 and above */
+ if (otus_hw_rate_is_ht(sc, rate)) {
+ phyctl |= AR_TX_PHY_MT_HT;
+ /* Always use all tx antennas for now, just to be safe */
+ phyctl |= AR_TX_PHY_ANTMSK(sc->txmask);
+
+ /* Heavy clip */
+ phyctl |= (rate & 0x7) << AR_TX_PHY_TX_HEAVY_CLIP_SHIFT;
+ } else if (otus_hw_rate_is_ofdm(sc, rate)) {
phyctl |= AR_TX_PHY_MT_OFDM;
/* Always use all tx antennas for now, just to be safe */
phyctl |= AR_TX_PHY_ANTMSK(sc->txmask);
@@ -2283,7 +2340,6 @@ otus_tx(struct otus_softc *sc, struct ieee80211_node *ni, struct mbuf *m,
if (!(macctl & AR_TX_MAC_NOACK))
OTUS_NODE(ni)->tx_done++;
-
/* Fill Tx descriptor. */
head = (struct ar_tx_head *)data->buf;
head->len = htole16(m->m_pkthdr.len + IEEE80211_CRC_LEN);
@@ -2308,63 +2364,63 @@ otus_tx(struct otus_softc *sc, struct ieee80211_node *ni, struct mbuf *m,
return 0;
}
+static u_int
+otus_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
+{
+ uint32_t val, *hashes = arg;
+
+ val = le32dec(LLADDR(sdl) + 4);
+ /* Get address byte 5 */
+ val = val & 0x0000ff00;
+ val = val >> 8;
+
+ /* As per below, shift it >> 2 to get only 6 bits */
+ val = val >> 2;
+ if (val < 32)
+ hashes[0] |= 1 << val;
+ else
+ hashes[1] |= 1 << (val - 32);
+
+ return (1);
+}
+
+
int
otus_set_multi(struct otus_softc *sc)
{
- uint32_t lo, hi;
struct ieee80211com *ic = &sc->sc_ic;
+ uint32_t hashes[2];
int r;
if (ic->ic_allmulti > 0 || ic->ic_promisc > 0 ||
ic->ic_opmode == IEEE80211_M_MONITOR) {
- lo = 0xffffffff;
- hi = 0xffffffff;
+ hashes[0] = 0xffffffff;
+ hashes[1] = 0xffffffff;
} else {
struct ieee80211vap *vap;
- struct ifnet *ifp;
- struct ifmultiaddr *ifma;
-
- lo = hi = 0;
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- ifp = vap->iv_ifp;
- if_maddr_rlock(ifp);
- CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- caddr_t dl;
- uint32_t val;
-
- dl = LLADDR((struct sockaddr_dl *) ifma->ifma_addr);
- val = le32dec(dl + 4);
- /* Get address byte 5 */
- val = val & 0x0000ff00;
- val = val >> 8;
-
- /* As per below, shift it >> 2 to get only 6 bits */
- val = val >> 2;
- if (val < 32)
- lo |= 1 << val;
- else
- hi |= 1 << (val - 32);
- }
- if_maddr_runlock(ifp);
- }
+
+ hashes[0] = hashes[1] = 0;
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
+ if_foreach_llmaddr(vap->iv_ifp, otus_hash_maddr,
+ hashes);
}
#if 0
/* XXX openbsd code */
while (enm != NULL) {
bit = enm->enm_addrlo[5] >> 2;
if (bit < 32)
- lo |= 1 << bit;
+ hashes[0] |= 1 << bit;
else
- hi |= 1 << (bit - 32);
+ hashes[1] |= 1 << (bit - 32);
ETHER_NEXT_MULTI(step, enm);
}
#endif
- hi |= 1U << 31; /* Make sure the broadcast bit is set. */
+ hashes[1] |= 1U << 31; /* Make sure the broadcast bit is set. */
OTUS_LOCK(sc);
- otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_L, lo);
- otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_H, hi);
+ otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_L, hashes[0]);
+ otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_H, hashes[1]);
r = otus_write_barrier(sc);
/* XXX operating mode? filter? */
OTUS_UNLOCK(sc);
@@ -2459,6 +2515,22 @@ otus_updateslot(struct otus_softc *sc)
(void)otus_write_barrier(sc);
}
+/*
+ * Things to do based on 2GHz or 5GHz:
+ *
+ * + slottime
+ * + dyn_sifs_ack
+ * + rts_cts_rate
+ * + slot time
+ * + mac_rates
+ * + mac_tpc
+ *
+ * And in the transmit path
+ * + tpc: carl9170_tx_rate_tpc_chains
+ * + carl9170_tx_physet()
+ * + disable short premable tx
+ */
+
int
otus_init_mac(struct otus_softc *sc)
{
@@ -2637,10 +2709,17 @@ otus_program_phy(struct otus_softc *sc, struct ieee80211_channel *c)
int error, i;
/* Select PHY programming based on band and bandwidth. */
- if (IEEE80211_IS_CHAN_2GHZ(c))
- vals = ar5416_phy_vals_2ghz_20mhz;
- else
- vals = ar5416_phy_vals_5ghz_20mhz;
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ if (IEEE80211_IS_CHAN_HT40(c))
+ vals = ar5416_phy_vals_2ghz_40mhz;
+ else
+ vals = ar5416_phy_vals_2ghz_20mhz;
+ } else {
+ if (IEEE80211_IS_CHAN_HT40(c))
+ vals = ar5416_phy_vals_5ghz_40mhz;
+ else
+ vals = ar5416_phy_vals_5ghz_20mhz;
+ }
for (i = 0; i < nitems(ar5416_phy_regs); i++)
otus_write(sc, AR_PHY(ar5416_phy_regs[i]), vals[i]);
sc->phy_vals = vals;
diff --git a/sys/dev/otus/if_otusreg.h b/sys/dev/otus/if_otusreg.h
index e5100841ad87..190bf19eb2ae 100644
--- a/sys/dev/otus/if_otusreg.h
+++ b/sys/dev/otus/if_otusreg.h
@@ -201,12 +201,17 @@ struct ar_tx_head {
uint32_t phyctl;
/* Modulation type. */
+#define AR_TX_PHY_MT_SHIFT 0 /* 0:1 - PHY mode */
#define AR_TX_PHY_MT_CCK 0
#define AR_TX_PHY_MT_OFDM 1
#define AR_TX_PHY_MT_HT 2
-#define AR_TX_PHY_GF (1 << 2)
-#define AR_TX_PHY_BW_SHIFT 3
-#define AR_TX_PHY_TPC_SHIFT 9
+#define AR_TX_PHY_GF (1 << 2) /* 2 - greenfield */
+#define AR_TX_PHY_BW_SHIFT 3 /* 4:3 - bandwidth */
+#define AR_TX_PHY_BW_20MHZ 0
+#define AR_TX_PHY_BW_40MHZ 2
+#define AR_TX_PHY_BW_40MHZ_DUP 3
+#define AR_TX_PHY_TX_HEAVY_CLIP_SHIFT 6 /* 9:6 - heavy clip */
+#define AR_TX_PHY_TPC_SHIFT 9 /* 14:9 - TX power */
#define AR_TX_PHY_ANTMSK(msk) ((msk) << 15)
#define AR_TX_PHY_MCS(mcs) ((mcs) << 18)
#define AR_TX_PHY_SHGI (1U << 31)
@@ -220,15 +225,11 @@ struct ar_rx_head {
} __packed;
/* Rx descriptor. */
-struct ar_rx_tail {
- uint8_t rssi_ant[3];
- uint8_t rssi_ant_ext[3];
- uint8_t rssi; /* Combined RSSI. */
- uint8_t evm[2][6]; /* Error Vector Magnitude. */
- uint8_t phy_err;
- uint8_t sa_idx;
- uint8_t da_idx;
- uint8_t error;
+
+struct ar_rx_macstatus {
+ uint8_t sa_idx;
+ uint8_t da_idx;
+ uint8_t error;
#define AR_RX_ERROR_TIMEOUT (1 << 0)
#define AR_RX_ERROR_OVERRUN (1 << 1)
#define AR_RX_ERROR_DECRYPT (1 << 2)
@@ -236,14 +237,26 @@ struct ar_rx_tail {
#define AR_RX_ERROR_BAD_RA (1 << 4)
#define AR_RX_ERROR_PLCP (1 << 5)
#define AR_RX_ERROR_MMIC (1 << 6)
-
- uint8_t status;
+ uint8_t status;
/* Modulation type (same as AR_TX_PHY_MT). */
#define AR_RX_STATUS_MT_MASK 0x3
#define AR_RX_STATUS_MT_CCK 0
#define AR_RX_STATUS_MT_OFDM 1
#define AR_RX_STATUS_MT_HT 2
#define AR_RX_STATUS_SHPREAMBLE (1 << 3)
+#define AR_RX_STATUS_MPDU_MASK 0x30
+#define AR_RX_STATUS_MPDU_SINGLE 0x00
+#define AR_RX_STATUS_MPDU_LAST 0x10
+#define AR_RX_STATUS_MPDU_FIRST 0x20
+#define AR_RX_STATUS_MPDU_MIDDLE 0x30
+} __packed;
+
+struct ar_rx_phystatus {
+ uint8_t rssi_ant[3];
+ uint8_t rssi_ant_ext[3];
+ uint8_t rssi; /* Combined RSSI. */
+ uint8_t evm[2][6]; /* Error Vector Magnitude. */
+ uint8_t phy_err;
} __packed;
#define AR_PLCP_HDR_LEN 12
@@ -468,7 +481,6 @@ static const uint32_t ar5416_phy_vals_5ghz_20mhz[] = {
0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0
};
-#ifdef notyet
static const uint32_t ar5416_phy_vals_5ghz_40mhz[] = {
0x00000007, 0x000003c4, 0x00000000, 0xad848e19, 0x7d14e000,
0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e,
@@ -537,9 +549,7 @@ static const uint32_t ar5416_phy_vals_5ghz_40mhz[] = {
0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803,
0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0
};
-#endif
-#ifdef notyet
static const uint32_t ar5416_phy_vals_2ghz_40mhz[] = {
0x00000007, 0x000003c4, 0x00000000, 0xad848e19, 0x7d14e000,
0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e,
@@ -608,7 +618,6 @@ static const uint32_t ar5416_phy_vals_2ghz_40mhz[] = {
0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803,
0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0
};
-#endif
static const uint32_t ar5416_phy_vals_2ghz_20mhz[] = {
0x00000007, 0x00000300, 0x00000000, 0xad848e19, 0x7d14e000,
@@ -1054,6 +1063,9 @@ struct otus_softc {
struct usb_xfer *sc_xfer[OTUS_N_XFER];
+ /* Last seen PLCP header; for A-MPDU decap */
+ uint8_t ar_last_rx_plcp[AR_PLCP_HDR_LEN];
+
STAILQ_HEAD(, otus_data) sc_rx_active;
STAILQ_HEAD(, otus_data) sc_rx_inactive;
STAILQ_HEAD(, otus_data) sc_tx_active[OTUS_N_XFER];
diff --git a/sys/dev/rtwn/if_rtwn.c b/sys/dev/rtwn/if_rtwn.c
index e410010cc433..ae29ad700310 100644
--- a/sys/dev/rtwn/if_rtwn.c
+++ b/sys/dev/rtwn/if_rtwn.c
@@ -79,7 +79,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_reg.h>
-
static void rtwn_radiotap_attach(struct rtwn_softc *);
static void rtwn_vap_decrement_counters(struct rtwn_softc *,
enum ieee80211_opmode, int);
@@ -1525,14 +1524,17 @@ rtwn_getradiocaps(struct ieee80211com *ic,
{
struct rtwn_softc *sc = ic->ic_softc;
uint8_t bands[IEEE80211_MODE_BYTES];
- int i;
+ int cbw_flags, i;
+
+ cbw_flags = (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) ?
+ NET80211_CBW_FLAG_HT40 : 0;
memset(bands, 0, sizeof(bands));
setbit(bands, IEEE80211_MODE_11B);
setbit(bands, IEEE80211_MODE_11G);
setbit(bands, IEEE80211_MODE_11NG);
ieee80211_add_channels_default_2ghz(chans, maxchans, nchans,
- bands, !!(ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40));
+ bands, cbw_flags);
/* XXX workaround add_channel_list() limitations */
setbit(bands, IEEE80211_MODE_11A);
@@ -1543,7 +1545,7 @@ rtwn_getradiocaps(struct ieee80211com *ic,
ieee80211_add_channel_list_5ghz(chans, maxchans, nchans,
sc->chan_list_5ghz[i], sc->chan_num_5ghz[i], bands,
- !!(ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40));
+ cbw_flags);
}
}
diff --git a/sys/dev/rtwn/if_rtwn_beacon.c b/sys/dev/rtwn/if_rtwn_beacon.c
index 99a1ad80ff91..63eb7a00730a 100644
--- a/sys/dev/rtwn/if_rtwn_beacon.c
+++ b/sys/dev/rtwn/if_rtwn_beacon.c
@@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_reg.h>
-
static void
rtwn_reset_beacon_valid(struct rtwn_softc *sc, int id)
{
diff --git a/sys/dev/rtwn/if_rtwn_calib.c b/sys/dev/rtwn/if_rtwn_calib.c
index 5c3ed7e6491e..7eb7c5c021c1 100644
--- a/sys/dev/rtwn/if_rtwn_calib.c
+++ b/sys/dev/rtwn/if_rtwn_calib.c
@@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/if_rtwn_debug.h>
#include <dev/rtwn/if_rtwn_task.h>
-
static void
rtwn_temp_calib(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/if_rtwn_cam.c b/sys/dev/rtwn/if_rtwn_cam.c
index 539fb411f770..6ee630533675 100644
--- a/sys/dev/rtwn/if_rtwn_cam.c
+++ b/sys/dev/rtwn/if_rtwn_cam.c
@@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_reg.h>
-
void
rtwn_init_cam(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/if_rtwn_efuse.c b/sys/dev/rtwn/if_rtwn_efuse.c
index b14f97377dd4..b2ec82e37972 100644
--- a/sys/dev/rtwn/if_rtwn_efuse.c
+++ b/sys/dev/rtwn/if_rtwn_efuse.c
@@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_reg.h>
-
static int
rtwn_efuse_switch_power(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/if_rtwn_fw.c b/sys/dev/rtwn/if_rtwn_fw.c
index 5cc71d2b8043..75ff59dd13e9 100644
--- a/sys/dev/rtwn/if_rtwn_fw.c
+++ b/sys/dev/rtwn/if_rtwn_fw.c
@@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_reg.h>
-
#ifndef RTWN_WITHOUT_UCODE
static int
rtwn_fw_loadpage(struct rtwn_softc *sc, int page, const uint8_t *buf,
diff --git a/sys/dev/rtwn/if_rtwn_fw.h b/sys/dev/rtwn/if_rtwn_fw.h
index 41e84ee82f17..50d2aa31b148 100644
--- a/sys/dev/rtwn/if_rtwn_fw.h
+++ b/sys/dev/rtwn/if_rtwn_fw.h
@@ -53,7 +53,6 @@ struct r92c_fw_hdr {
uint32_t reserved5;
} __packed;
-
int rtwn_load_firmware(struct rtwn_softc *);
#endif /* IF_RTWN_FW_H */
diff --git a/sys/dev/rtwn/if_rtwn_ridx.h b/sys/dev/rtwn/if_rtwn_ridx.h
index 2e6f8d98456f..902c470d25bc 100644
--- a/sys/dev/rtwn/if_rtwn_ridx.h
+++ b/sys/dev/rtwn/if_rtwn_ridx.h
@@ -47,7 +47,6 @@
#define RTWN_RATE_IS_OFDM(rate) \
((rate) >= RTWN_RIDX_OFDM6 && (rate) != RTWN_RIDX_UNKNOWN)
-
static const uint8_t ridx2rate[] =
{ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
diff --git a/sys/dev/rtwn/if_rtwn_rx.c b/sys/dev/rtwn/if_rtwn_rx.c
index 21609e31515c..cc7d96151522 100644
--- a/sys/dev/rtwn/if_rtwn_rx.c
+++ b/sys/dev/rtwn/if_rtwn_rx.c
@@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_reg.h>
-
void
rtwn_get_rates(struct rtwn_softc *sc, const struct ieee80211_rateset *rs,
const struct ieee80211_htrateset *rs_ht, uint32_t *rates_p,
@@ -366,6 +365,18 @@ rtwn_get_multi_pos(const uint8_t maddr[])
return (pos);
}
+static u_int
+rtwm_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
+{
+ uint32_t *mfilt = arg;
+ uint8_t pos;
+
+ pos = rtwn_get_multi_pos(LLADDR(sdl));
+ mfilt[pos / 32] |= (1 << (pos % 32));
+
+ return (1);
+}
+
void
rtwn_set_multi(struct rtwn_softc *sc)
{
@@ -377,32 +388,16 @@ rtwn_set_multi(struct rtwn_softc *sc)
/* general structure was copied from ath(4). */
if (ic->ic_allmulti == 0) {
struct ieee80211vap *vap;
- struct ifnet *ifp;
- struct ifmultiaddr *ifma;
/*
* Merge multicast addresses to form the hardware filter.
*/
mfilt[0] = mfilt[1] = 0;
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- ifp = vap->iv_ifp;
- if_maddr_rlock(ifp);
- CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- caddr_t dl;
- uint8_t pos;
-
- dl = LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr);
- pos = rtwn_get_multi_pos(dl);
-
- mfilt[pos / 32] |= (1 << (pos % 32));
- }
- if_maddr_runlock(ifp);
- }
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
+ if_foreach_llmaddr(vap->iv_ifp, rtwm_hash_maddr, mfilt);
} else
mfilt[0] = mfilt[1] = ~0;
-
rtwn_write_4(sc, R92C_MAR + 0, mfilt[0]);
rtwn_write_4(sc, R92C_MAR + 4, mfilt[1]);
diff --git a/sys/dev/rtwn/if_rtwn_rx.h b/sys/dev/rtwn/if_rtwn_rx.h
index 49897eb956b9..ecfe2e0abdd3 100644
--- a/sys/dev/rtwn/if_rtwn_rx.h
+++ b/sys/dev/rtwn/if_rtwn_rx.h
@@ -21,7 +21,6 @@
#define RTWN_NOISE_FLOOR -95
-
void rtwn_get_rates(struct rtwn_softc *, const struct ieee80211_rateset *,
const struct ieee80211_htrateset *, uint32_t *, int *, int);
void rtwn_set_basicrates(struct rtwn_softc *, uint32_t);
diff --git a/sys/dev/rtwn/if_rtwn_task.c b/sys/dev/rtwn/if_rtwn_task.c
index 87f695f1020c..89822cf2a25b 100644
--- a/sys/dev/rtwn/if_rtwn_task.c
+++ b/sys/dev/rtwn/if_rtwn_task.c
@@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/if_rtwn_task.h>
-
static void
rtwn_cmdq_cb(void *arg, int pending)
{
diff --git a/sys/dev/rtwn/if_rtwn_tx.c b/sys/dev/rtwn/if_rtwn_tx.c
index 69ce3ae7c495..32bdd1b6b3f0 100644
--- a/sys/dev/rtwn/if_rtwn_tx.c
+++ b/sys/dev/rtwn/if_rtwn_tx.c
@@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/if_rtwn_ridx.h>
#include <dev/rtwn/if_rtwn_tx.h>
-
void
rtwn_drain_mbufq(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/if_rtwnreg.h b/sys/dev/rtwn/if_rtwnreg.h
index 00903d884bcb..b1eac291c49d 100644
--- a/sys/dev/rtwn/if_rtwnreg.h
+++ b/sys/dev/rtwn/if_rtwnreg.h
@@ -26,7 +26,6 @@
#define R92C_H2C_NBOX 4
-
/* Common part of Tx descriptor (named only!). */
struct rtwn_tx_desc_common {
uint16_t pktlen;
@@ -115,7 +114,6 @@ struct rtwn_rx_stat_pci {
#define RW(var, field, val) \
(((var) & ~field##_M) | SM(field, val))
-
#define RTWN_MAX_CONDITIONS 3
/*
@@ -155,7 +153,6 @@ struct rtwn_rf_prog {
const struct rtwn_rf_prog *next;
};
-
/* XXX move to net80211. */
static __inline int
rtwn_chan2centieee(const struct ieee80211_channel *c)
diff --git a/sys/dev/rtwn/if_rtwnvar.h b/sys/dev/rtwn/if_rtwnvar.h
index fe31aa5447cb..b63d4ddf2902 100644
--- a/sys/dev/rtwn/if_rtwnvar.h
+++ b/sys/dev/rtwn/if_rtwnvar.h
@@ -80,7 +80,6 @@ struct rtwn_tx_phystat {
uint32_t phydw[RTWN_PHY_STATUS_SIZE / sizeof(uint32_t)];
};
-
struct rtwn_softc;
union sec_param {
@@ -423,7 +422,6 @@ MALLOC_DECLARE(M_RTWN_PRIV);
#define RTWN_NT_LOCK_INITIALIZED(sc) mtx_initialized(&(sc)->nt_mtx)
#define RTWN_NT_LOCK_DESTROY(sc) mtx_destroy(&(sc)->nt_mtx)
-
void rtwn_sysctlattach(struct rtwn_softc *);
int rtwn_attach(struct rtwn_softc *);
@@ -431,7 +429,6 @@ void rtwn_detach(struct rtwn_softc *);
void rtwn_resume(struct rtwn_softc *);
void rtwn_suspend(struct rtwn_softc *);
-
/* Interface-specific. */
#define rtwn_write_1(_sc, _addr, _val) \
(((_sc)->sc_write_1)((_sc), (_addr), (_val)))
@@ -591,7 +588,6 @@ void rtwn_suspend(struct rtwn_softc *);
#define rtwn_init_bcnq1_boundary(_sc) \
(((_sc)->sc_init_bcnq1_boundary)((_sc)))
-
/*
* Methods to access subfields in registers.
*/
diff --git a/sys/dev/rtwn/pci/rtwn_pci_attach.c b/sys/dev/rtwn/pci/rtwn_pci_attach.c
index a7a6e849fa09..efa6bc01501e 100644
--- a/sys/dev/rtwn/pci/rtwn_pci_attach.c
+++ b/sys/dev/rtwn/pci/rtwn_pci_attach.c
@@ -63,7 +63,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
-
static device_probe_t rtwn_pci_probe;
static device_attach_t rtwn_pci_attach;
static device_detach_t rtwn_pci_detach;
@@ -92,7 +91,6 @@ static void rtwn_pci_beacon_update_end(struct rtwn_softc *,
struct ieee80211vap *);
static void rtwn_pci_attach_methods(struct rtwn_softc *);
-
static const struct rtwn_pci_ident *
rtwn_pci_probe_sub(device_t dev)
{
diff --git a/sys/dev/rtwn/pci/rtwn_pci_reg.c b/sys/dev/rtwn/pci/rtwn_pci_reg.c
index 6fe188c3f76d..0ee417acbd73 100644
--- a/sys/dev/rtwn/pci/rtwn_pci_reg.c
+++ b/sys/dev/rtwn/pci/rtwn_pci_reg.c
@@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/pci/rtwn_pci_var.h>
#include <dev/rtwn/pci/rtwn_pci_reg.h>
-
int
rtwn_pci_write_1(struct rtwn_softc *sc, uint16_t addr, uint8_t val)
{
diff --git a/sys/dev/rtwn/pci/rtwn_pci_rx.c b/sys/dev/rtwn/pci/rtwn_pci_rx.c
index 362856c4c35a..df95ec701b72 100644
--- a/sys/dev/rtwn/pci/rtwn_pci_rx.c
+++ b/sys/dev/rtwn/pci/rtwn_pci_rx.c
@@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/pci/rtwn_pci_var.h>
#include <dev/rtwn/pci/rtwn_pci_rx.h>
-
void
rtwn_pci_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs,
int error)
diff --git a/sys/dev/rtwn/pci/rtwn_pci_tx.c b/sys/dev/rtwn/pci/rtwn_pci_tx.c
index 434e0488a9d1..6dd84f367212 100644
--- a/sys/dev/rtwn/pci/rtwn_pci_tx.c
+++ b/sys/dev/rtwn/pci/rtwn_pci_tx.c
@@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
-
static struct mbuf *
rtwn_mbuf_defrag(struct mbuf *m0, int how)
{
diff --git a/sys/dev/rtwn/pci/rtwn_pci_var.h b/sys/dev/rtwn/pci/rtwn_pci_var.h
index 95b2effe55d4..82541767edaf 100644
--- a/sys/dev/rtwn/pci/rtwn_pci_var.h
+++ b/sys/dev/rtwn/pci/rtwn_pci_var.h
@@ -101,7 +101,6 @@ enum {
(RTWN_PCI_INTR_RX_ERROR | RTWN_PCI_INTR_RX_OVERFLOW | \
RTWN_PCI_INTR_RX_DESC_UNAVAIL | RTWN_PCI_INTR_RX_DONE)
-
struct rtwn_pci_softc {
struct rtwn_softc pc_sc; /* must be the first */
diff --git a/sys/dev/rtwn/rtl8188e/pci/r88ee.h b/sys/dev/rtwn/rtl8188e/pci/r88ee.h
index e011dc1edf7d..319d9c69952b 100644
--- a/sys/dev/rtwn/rtl8188e/pci/r88ee.h
+++ b/sys/dev/rtwn/rtl8188e/pci/r88ee.h
@@ -21,7 +21,6 @@
#include <dev/rtwn/rtl8188e/r88e.h>
-
/*
* Global definitions.
*/
@@ -33,7 +32,6 @@
(R88EE_PUBQ_NPAGES + R88EE_HPQ_NPAGES + \
R88EE_NPQ_NPAGES + R88EE_LPQ_NPAGES)
-
/*
* Function declarations.
*/
@@ -50,4 +48,3 @@ void r88ee_start_xfers(struct rtwn_softc *);
void r88ee_post_init(struct rtwn_softc *);
#endif /* RTL8188EE_H */
-
diff --git a/sys/dev/rtwn/rtl8188e/pci/r88ee_reg.h b/sys/dev/rtwn/rtl8188e/pci/r88ee_reg.h
index 96fbe888ac48..a6c743c6771c 100644
--- a/sys/dev/rtwn/rtl8188e/pci/r88ee_reg.h
+++ b/sys/dev/rtwn/rtl8188e/pci/r88ee_reg.h
@@ -23,4 +23,3 @@
#include <dev/rtwn/rtl8188e/r88e_reg.h>
#endif /* R88EE_REG_H */
-
diff --git a/sys/dev/rtwn/rtl8188e/r88e.h b/sys/dev/rtwn/rtl8188e/r88e.h
index ce9fa19a87b5..b6cd6053d015 100644
--- a/sys/dev/rtwn/rtl8188e/r88e.h
+++ b/sys/dev/rtwn/rtl8188e/r88e.h
@@ -33,7 +33,6 @@
#define R88E_CALIB_THRESHOLD 4
-
/*
* Function declarations.
*/
diff --git a/sys/dev/rtwn/rtl8188e/r88e_beacon.c b/sys/dev/rtwn/rtl8188e/r88e_beacon.c
index 4c29d37fab24..affc768ae035 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_beacon.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_beacon.c
@@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
-
void
r88e_beacon_enable(struct rtwn_softc *sc, int id, int enable)
{
diff --git a/sys/dev/rtwn/rtl8188e/r88e_calib.c b/sys/dev/rtwn/rtl8188e/r88e_calib.c
index 4d0dffa93910..b4de1138948e 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_calib.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_calib.c
@@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
-
/* Registers to save and restore during IQ calibration. */
struct r88e_iq_cal_reg_vals {
uint32_t adda[16];
diff --git a/sys/dev/rtwn/rtl8188e/r88e_chan.c b/sys/dev/rtwn/rtl8188e/r88e_chan.c
index 7e33fe887786..be2271c6f51c 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_chan.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_chan.c
@@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8188e/r88e_priv.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
-
static int
r88e_get_power_group(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
diff --git a/sys/dev/rtwn/rtl8188e/r88e_fw.c b/sys/dev/rtwn/rtl8188e/r88e_fw.c
index dbce406b8b90..ea74252fccb1 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_fw.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_fw.c
@@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8188e/r88e_reg.h>
#include <dev/rtwn/rtl8188e/r88e_fw_cmd.h>
-
#ifndef RTWN_WITHOUT_UCODE
int
r88e_fw_cmd(struct rtwn_softc *sc, uint8_t id, const void *buf, int len)
diff --git a/sys/dev/rtwn/rtl8188e/r88e_init.c b/sys/dev/rtwn/rtl8188e/r88e_init.c
index 99796c5f074a..8c13057e03bf 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_init.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_init.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
-
static void
r88e_crystalcap_write(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/rtl8188e/r88e_led.c b/sys/dev/rtwn/rtl8188e/r88e_led.c
index 2bbcdb15cab6..3c93a2b78958 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_led.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_led.c
@@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
-
void
r88e_set_led(struct rtwn_softc *sc, int led, int on)
{
diff --git a/sys/dev/rtwn/rtl8188e/r88e_priv.h b/sys/dev/rtwn/rtl8188e/r88e_priv.h
index 8ec5502d846a..81d82c71d7b3 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_priv.h
+++ b/sys/dev/rtwn/rtl8188e/r88e_priv.h
@@ -33,7 +33,6 @@ struct rtwn_r88e_txpwr {
int8_t bw20_tx_pwr_diff;
};
-
/*
* MAC initialization values.
*/
diff --git a/sys/dev/rtwn/rtl8188e/r88e_reg.h b/sys/dev/rtwn/rtl8188e/r88e_reg.h
index 94b9a66053a1..d578373f7551 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_reg.h
+++ b/sys/dev/rtwn/rtl8188e/r88e_reg.h
@@ -44,7 +44,6 @@
#define R88E_TX_RPT_TIME 0x4f0
#define R88E_SCH_TXCMD 0x5f8
-
/* Bits for R88E_HIMR. */
#define R88E_HIMR_ROK 0x00000001 /* receive DMA OK */
#define R88E_HIMR_RDU 0x00000002 /* Rx descriptor unavailable */
@@ -100,7 +99,6 @@
/* Bits for R92C_SECCFG. */
#define R88E_SECCFG_CHK_KEYID 0x0100
-
/*
* Baseband registers.
*/
@@ -108,7 +106,6 @@
#define R88E_LSSI_PARAM_ADDR_M 0x0ff00000
#define R88E_LSSI_PARAM_ADDR_S 20
-
/*
* RF (6052) registers.
*/
diff --git a/sys/dev/rtwn/rtl8188e/r88e_rf.c b/sys/dev/rtwn/rtl8188e/r88e_rf.c
index a836f138aeb5..e5966a4cc0a4 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_rf.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_rf.c
@@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
-
void
r88e_rf_write(struct rtwn_softc *sc, int chain, uint8_t addr, uint32_t val)
{
diff --git a/sys/dev/rtwn/rtl8188e/r88e_rom.c b/sys/dev/rtwn/rtl8188e/r88e_rom.c
index f1baf5ffc594..d84d1b8149d8 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_rom.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_rom.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8188e/r88e_priv.h>
#include <dev/rtwn/rtl8188e/r88e_rom_image.h>
-
void
r88e_parse_rom(struct rtwn_softc *sc, uint8_t *buf)
{
diff --git a/sys/dev/rtwn/rtl8188e/r88e_rx.c b/sys/dev/rtwn/rtl8188e/r88e_rx.c
index 29b76552bcbf..dad1bc56446a 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_rx.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_rx.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_rx_desc.h>
-
int
r88e_classify_intr(struct rtwn_softc *sc, void *buf, int len)
{
diff --git a/sys/dev/rtwn/rtl8188e/r88e_tx.c b/sys/dev/rtwn/rtl8188e/r88e_tx.c
index dd3aaecefa44..d9920f73e3cf 100644
--- a/sys/dev/rtwn/rtl8188e/r88e_tx.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_tx.c
@@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_tx_desc.h>
-
void
r88e_tx_enable_ampdu(void *buf, int enable)
{
diff --git a/sys/dev/rtwn/rtl8188e/usb/r88eu.h b/sys/dev/rtwn/rtl8188e/usb/r88eu.h
index e79b1387c4c1..9b9198e0a8c0 100644
--- a/sys/dev/rtwn/rtl8188e/usb/r88eu.h
+++ b/sys/dev/rtwn/rtl8188e/usb/r88eu.h
@@ -23,14 +23,12 @@
#include <dev/rtwn/rtl8188e/r88e.h>
-
/*
* Global definitions.
*/
#define R88EU_PUBQ_NPAGES 142
#define R88EU_TX_PAGE_COUNT 169
-
/*
* Function declarations.
*/
diff --git a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
index 1ae0fc24c1e8..a264629a6057 100644
--- a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
+++ b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
@@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8188e/usb/r88eu.h>
-
static struct rtwn_r88e_txpwr r88e_txpwr;
void r88eu_attach(struct rtwn_usb_softc *);
diff --git a/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c b/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c
index 1fcecbd4d9a7..156f6ea79cdf 100644
--- a/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c
+++ b/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c
@@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8188e/usb/r88eu.h>
#include <dev/rtwn/rtl8188e/usb/r88eu_reg.h>
-
void
r88eu_init_bb(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce.h b/sys/dev/rtwn/rtl8192c/pci/r92ce.h
index 5d13f1608dd3..39e08b4afb12 100644
--- a/sys/dev/rtwn/rtl8192c/pci/r92ce.h
+++ b/sys/dev/rtwn/rtl8192c/pci/r92ce.h
@@ -25,7 +25,6 @@
#include <dev/rtwn/rtl8192c/r92c.h>
-
/*
* Global definitions.
*/
@@ -35,7 +34,6 @@
#define R92CE_TX_PAGE_COUNT \
(R92CE_PUBQ_NPAGES + R92CE_HPQ_NPAGES + R92CE_LPQ_NPAGES)
-
/*
* Function declarations.
*/
diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
index bff91b743383..d3f653741977 100644
--- a/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
+++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
@@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_tx_desc.h>
-
static struct rtwn_r92c_txpwr r92c_txpwr;
void r92ce_attach(struct rtwn_pci_softc *);
diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce_calib.c b/sys/dev/rtwn/rtl8192c/pci/r92ce_calib.c
index aebf60ae62bc..f4e68e12af28 100644
--- a/sys/dev/rtwn/rtl8192c/pci/r92ce_calib.c
+++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_calib.c
@@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/pci/r92ce.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
-
/* Registers to save and restore during IQ calibration. */
struct r92ce_iq_cal_reg_vals {
uint32_t adda[16];
diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce_fw.c b/sys/dev/rtwn/rtl8192c/pci/r92ce_fw.c
index b28104463b6c..b28f80ce0805 100644
--- a/sys/dev/rtwn/rtl8192c/pci/r92ce_fw.c
+++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_fw.c
@@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/pci/r92ce.h>
-
#ifndef RTWN_WITHOUT_UCODE
void
r92ce_fw_reset(struct rtwn_softc *sc, int reason)
diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce_init.c b/sys/dev/rtwn/rtl8192c/pci/r92ce_init.c
index 5b7f9a0e1987..7b07f6cfc518 100644
--- a/sys/dev/rtwn/rtl8192c/pci/r92ce_init.c
+++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_init.c
@@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/pci/r92ce.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
-
void
r92ce_init_intr(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce_priv.h b/sys/dev/rtwn/rtl8192c/pci/r92ce_priv.h
index 7416516cd986..08172a607f27 100644
--- a/sys/dev/rtwn/rtl8192c/pci/r92ce_priv.h
+++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_priv.h
@@ -25,7 +25,6 @@
#include <dev/rtwn/rtl8192c/r92c_priv.h>
-
/*
* MAC initialization values.
*/
@@ -53,7 +52,6 @@ static const struct rtwn_mac_prog rtl8192ce_mac[] = {
{ 0x70b, 0x87 }
};
-
/*
* Baseband initialization values.
*/
diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce_reg.h b/sys/dev/rtwn/rtl8192c/pci/r92ce_reg.h
index 355d8f4622cd..d76cc64e2c7f 100644
--- a/sys/dev/rtwn/rtl8192c/pci/r92ce_reg.h
+++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_reg.h
@@ -51,7 +51,6 @@
#define R92C_UART_TX_DES 0x370
#define R92C_UART_RX_DES 0x378
-
/* Bits for R92C_GPIO_MUXCFG. */
#define R92C_GPIO_MUXCFG_RFKILL 0x0008
diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce_rx.c b/sys/dev/rtwn/rtl8192c/pci/r92ce_rx.c
index d8b3c5e0b53e..7cd6283ea18a 100644
--- a/sys/dev/rtwn/rtl8192c/pci/r92ce_rx.c
+++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_rx.c
@@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/pci/r92ce.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
-
int
r92ce_get_intr_status(struct rtwn_pci_softc *pc, int *rings)
{
diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce_tx.c b/sys/dev/rtwn/rtl8192c/pci/r92ce_tx.c
index 19de15b5a63e..ea6535f46b5f 100644
--- a/sys/dev/rtwn/rtl8192c/pci/r92ce_tx.c
+++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_tx.c
@@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/pci/r92ce.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_tx_desc.h>
-
void
r92ce_setup_tx_desc(struct rtwn_pci_softc *pc, void *desc,
uint32_t next_desc_addr)
diff --git a/sys/dev/rtwn/rtl8192c/r92c.h b/sys/dev/rtwn/rtl8192c/r92c.h
index f215e34fd8ce..4d4307c786a4 100644
--- a/sys/dev/rtwn/rtl8192c/r92c.h
+++ b/sys/dev/rtwn/rtl8192c/r92c.h
@@ -35,7 +35,6 @@
#define R92C_CALIB_THRESHOLD 2
-
/*
* Function declarations.
*/
diff --git a/sys/dev/rtwn/rtl8192c/r92c_attach.c b/sys/dev/rtwn/rtl8192c/r92c_attach.c
index a0df8ec7688d..d71a595dc6a7 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_attach.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_attach.c
@@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
-
void
r92c_detach_private(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/rtl8192c/r92c_beacon.c b/sys/dev/rtwn/rtl8192c/r92c_beacon.c
index 15af77a06fea..477358bbf931 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_beacon.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_beacon.c
@@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
-
void
r92c_beacon_init(struct rtwn_softc *sc, void *buf, int id)
{
diff --git a/sys/dev/rtwn/rtl8192c/r92c_calib.c b/sys/dev/rtwn/rtl8192c/r92c_calib.c
index 7a2e998c1bfb..c340c816c727 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_calib.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_calib.c
@@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c.h>
#include <dev/rtwn/rtl8192c/r92c_reg.h>
-
/* Registers to save and restore during IQ calibration. */
struct r92c_iq_cal_reg_vals {
uint32_t adda[16];
diff --git a/sys/dev/rtwn/rtl8192c/r92c_chan.c b/sys/dev/rtwn/rtl8192c/r92c_chan.c
index 94a1284fed18..01e0cfb629f1 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_chan.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_chan.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
-
static int
r92c_get_power_group(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
diff --git a/sys/dev/rtwn/rtl8192c/r92c_fw.c b/sys/dev/rtwn/rtl8192c/r92c_fw.c
index 0791990a0c00..7ad6d7d2dfe6 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_fw.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_fw.c
@@ -60,7 +60,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_fw_cmd.h>
#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
-
#ifndef RTWN_WITHOUT_UCODE
static int
r92c_fw_cmd(struct rtwn_softc *sc, uint8_t id, const void *buf, int len)
diff --git a/sys/dev/rtwn/rtl8192c/r92c_init.c b/sys/dev/rtwn/rtl8192c/r92c_init.c
index bf043b8e376f..4e29fe0b033c 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_init.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_init.c
@@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
-
int
r92c_check_condition(struct rtwn_softc *sc, const uint8_t cond[])
{
diff --git a/sys/dev/rtwn/rtl8192c/r92c_priv.h b/sys/dev/rtwn/rtl8192c/r92c_priv.h
index 80f058284941..645f07a58704 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_priv.h
+++ b/sys/dev/rtwn/rtl8192c/r92c_priv.h
@@ -36,7 +36,6 @@ struct rtwn_r92c_txpwr {
int8_t ht20_max_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
};
-
/*
* Baseband initialization values (shared parts).
*/
@@ -132,7 +131,6 @@ static const struct rtwn_agc_prog rtl8192ce_agc[] = {
}
};
-
/*
* RF initialization values.
*/
@@ -331,7 +329,6 @@ static const struct rtwn_rf_prog rtl8192c_rf[] = {
{ 0, NULL, NULL, { 0 }, NULL }
};
-
struct rtwn_r92c_txagc {
uint8_t pwr[R92C_GROUP_2G][28]; /* RTWN_RIDX_HT_MCS(15) + 1 */
};
diff --git a/sys/dev/rtwn/rtl8192c/r92c_reg.h b/sys/dev/rtwn/rtl8192c/r92c_reg.h
index c3def33e21bb..d01168fe395a 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_reg.h
+++ b/sys/dev/rtwn/rtl8192c/r92c_reg.h
@@ -224,7 +224,6 @@
#define R92C_MACID1 0x700
#define R92C_BSSID1 0x708
-
#define R92C_MACID(id) ((id) == 0 ? R92C_MACID0 : R92C_MACID1)
#define R92C_BSSID(id) ((id) == 0 ? R92C_BSSID0 : R92C_BSSID1)
@@ -628,7 +627,6 @@
#define R92C_CAMCMD_CLR 0x40000000
#define R92C_CAMCMD_POLLING 0x80000000
-
/*
* CAM entries.
*/
@@ -666,7 +664,6 @@
#define R92C_RXFLTMAP_SUBTYPE(subtype) \
(1 << ((subtype) >> IEEE80211_FC0_SUBTYPE_SHIFT))
-
/*
* Baseband registers.
*/
@@ -850,7 +847,6 @@
#define R92C_POWER_IQK_RESULT_S 16
#define R92C_POWER_IQK_RESULT_M 0x03ff0000
-
/*
* RF (6052) registers.
*/
diff --git a/sys/dev/rtwn/rtl8192c/r92c_rf.c b/sys/dev/rtwn/rtl8192c/r92c_rf.c
index f36f035f2a9b..c547a06ea980 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_rf.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_rf.c
@@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
-
uint32_t
r92c_rf_read(struct rtwn_softc *sc, int chain, uint8_t addr)
{
diff --git a/sys/dev/rtwn/rtl8192c/r92c_rom.c b/sys/dev/rtwn/rtl8192c/r92c_rom.c
index 0a85c817b2f8..ea3f3a253df0 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_rom.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_rom.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8192c/r92c_rom_image.h>
-
static void
r92c_set_chains(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/rtl8192c/r92c_rx.c b/sys/dev/rtwn/rtl8192c/r92c_rx.c
index 24759d1bb0f9..258b914d4465 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_rx.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_rx.c
@@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c.h>
#include <dev/rtwn/rtl8192c/r92c_rx_desc.h>
-
int
r92c_classify_intr(struct rtwn_softc *sc, void *buf, int len)
{
diff --git a/sys/dev/rtwn/rtl8192c/r92c_tx.c b/sys/dev/rtwn/rtl8192c/r92c_tx.c
index 07f787e75bab..ab2d05635358 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_tx.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_tx.c
@@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
-
static int
r92c_tx_get_sco(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
diff --git a/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h b/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h
index c3bc87caa31f..c65ece0e3c02 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h
+++ b/sys/dev/rtwn/rtl8192c/r92c_tx_desc.h
@@ -109,7 +109,6 @@ struct r92c_tx_desc {
#define R92C_TXDW6_MAX_AGG_S 11
} __packed __attribute__((aligned(4)));
-
/* Rate adaptation modes. */
#define R92C_RAID_11BGN 0
#define R92C_RAID_11GN 1
diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu.h b/sys/dev/rtwn/rtl8192c/usb/r92cu.h
index 4cc010494a18..f9b9861867bc 100644
--- a/sys/dev/rtwn/rtl8192c/usb/r92cu.h
+++ b/sys/dev/rtwn/rtl8192c/usb/r92cu.h
@@ -23,14 +23,12 @@
#include <dev/rtwn/rtl8192c/r92c.h>
-
/*
* Global definitions.
*/
#define R92CU_PUBQ_NPAGES 231
#define R92CU_TX_PAGE_COUNT 248
-
/*
* Function declarations.
*/
diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
index 4a7698410c56..ef436ee3ed01 100644
--- a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
+++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
@@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/usb/r92cu_reg.h>
#include <dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h>
-
static struct rtwn_r92c_txpwr r92c_txpwr;
void r92cu_attach(struct rtwn_usb_softc *);
diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_init.c b/sys/dev/rtwn/rtl8192c/usb/r92cu_init.c
index 13ccd50adbb8..94563fed635e 100644
--- a/sys/dev/rtwn/rtl8192c/usb/r92cu_init.c
+++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_init.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/usb/r92cu.h>
#include <dev/rtwn/rtl8192c/usb/r92cu_reg.h>
-
void
r92cu_init_bb(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_led.c b/sys/dev/rtwn/rtl8192c/usb/r92cu_led.c
index 724320946639..534987b6a1c0 100644
--- a/sys/dev/rtwn/rtl8192c/usb/r92cu_led.c
+++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_led.c
@@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/usb/r92cu.h>
-
void
r92cu_set_led(struct rtwn_softc *sc, int led, int on)
{
diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_priv.h b/sys/dev/rtwn/rtl8192c/usb/r92cu_priv.h
index 8e3203f082f3..a7f9e8d49596 100644
--- a/sys/dev/rtwn/rtl8192c/usb/r92cu_priv.h
+++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_priv.h
@@ -23,7 +23,6 @@
#include <dev/rtwn/rtl8192c/r92c_priv.h>
-
/*
* MAC initialization values.
*/
@@ -52,7 +51,6 @@ static const struct rtwn_mac_prog rtl8192cu_mac[] = {
{ 0x70a, 0x65 }, { 0x70b, 0x87 }
};
-
/*
* Baseband initialization values.
*/
@@ -274,7 +272,6 @@ static const struct rtwn_bb_prog rtl8192cu_bb[] = {
}
};
-
static const uint32_t rtl8188ru_agc_vals[] = {
0x7b000001, 0x7b010001, 0x7b020001, 0x7b030001, 0x7b040001,
0x7b050001, 0x7b060001, 0x7b070001, 0x7b080001, 0x7a090001,
diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_reg.h b/sys/dev/rtwn/rtl8192c/usb/r92cu_reg.h
index a9db29ccbca4..f8ab133f5371 100644
--- a/sys/dev/rtwn/rtl8192c/usb/r92cu_reg.h
+++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_reg.h
@@ -23,14 +23,12 @@
#include <dev/rtwn/rtl8192c/r92c_reg.h>
-
/*
* MAC registers.
*/
/* System Configuration. */
#define R92C_USB_SIE_INTF 0x0e0
-
/*
* USB registers.
*/
diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_rx.c b/sys/dev/rtwn/rtl8192c/usb/r92cu_rx.c
index fcd760b6136b..6710b1a8fa3c 100644
--- a/sys/dev/rtwn/rtl8192c/usb/r92cu_rx.c
+++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_rx.c
@@ -48,7 +48,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/usb/r92cu.h>
-
int
r92cu_align_rx(int totlen, int len)
{
diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_tx.c b/sys/dev/rtwn/rtl8192c/usb/r92cu_tx.c
index 04dbade0651a..a9e37ba819de 100644
--- a/sys/dev/rtwn/rtl8192c/usb/r92cu_tx.c
+++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_tx.c
@@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/usb/r92cu.h>
#include <dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h>
-
void
r92cu_dump_tx_desc(struct rtwn_softc *sc, const void *desc)
{
diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h b/sys/dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h
index 16c2d0587e4c..f160f1310913 100644
--- a/sys/dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h
+++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h
@@ -42,4 +42,4 @@ struct r92cu_tx_desc {
uint16_t pad;
} __packed __attribute__((aligned(4)));
-#endif /* R92CU_TX_DESC_H */ \ No newline at end of file
+#endif /* R92CU_TX_DESC_H */
diff --git a/sys/dev/rtwn/rtl8192e/r92e.h b/sys/dev/rtwn/rtl8192e/r92e.h
index a961236c062d..c4a60330259a 100644
--- a/sys/dev/rtwn/rtl8192e/r92e.h
+++ b/sys/dev/rtwn/rtl8192e/r92e.h
@@ -40,7 +40,6 @@
#define R92E_MAX_FW_SIZE 0x8000
-
/*
* Function declarations.
*/
diff --git a/sys/dev/rtwn/rtl8192e/r92e_chan.c b/sys/dev/rtwn/rtl8192e/r92e_chan.c
index 7b3c5630dd18..0211e2883888 100644
--- a/sys/dev/rtwn/rtl8192e/r92e_chan.c
+++ b/sys/dev/rtwn/rtl8192e/r92e_chan.c
@@ -127,7 +127,6 @@ r92e_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c,
min_mcs = RTWN_RIDX_HT_MCS(i * 8);
for (ridx = min_mcs; ridx <= max_mcs; ridx++)
power[ridx] += pwr_diff;
-
}
/* Apply max limit. */
diff --git a/sys/dev/rtwn/rtl8192e/r92e_priv.h b/sys/dev/rtwn/rtl8192e/r92e_priv.h
index 1bcae4f9aafd..ddf8c48ca4e9 100644
--- a/sys/dev/rtwn/rtl8192e/r92e_priv.h
+++ b/sys/dev/rtwn/rtl8192e/r92e_priv.h
@@ -61,7 +61,6 @@ static const struct rtwn_mac_prog rtl8192eu_mac[] = {
{ 0x70b, 0x87 }
};
-
/*
* Baseband initialization values.
*/
@@ -147,7 +146,6 @@ static const struct rtwn_bb_prog rtl8192eu_bb[] = {
}
};
-
static const uint32_t rtl8192eu_agc_vals[] = {
0xfb000001, 0xfb010001, 0xfb020001, 0xfb030001, 0xfb040001,
0xfb050001, 0xfa060001, 0xf9070001, 0xf8080001, 0xf7090001,
diff --git a/sys/dev/rtwn/rtl8192e/usb/r92eu.h b/sys/dev/rtwn/rtl8192e/usb/r92eu.h
index a59ceb63be04..3ca6e067585b 100644
--- a/sys/dev/rtwn/rtl8192e/usb/r92eu.h
+++ b/sys/dev/rtwn/rtl8192e/usb/r92eu.h
@@ -26,7 +26,6 @@
* $FreeBSD$
*/
-
#ifndef RTL8192EU_H
#define RTL8192EU_H
diff --git a/sys/dev/rtwn/rtl8812a/r12a.h b/sys/dev/rtwn/rtl8812a/r12a.h
index e8de45aa9da5..f3bbdf77360b 100644
--- a/sys/dev/rtwn/rtl8812a/r12a.h
+++ b/sys/dev/rtwn/rtl8812a/r12a.h
@@ -52,7 +52,6 @@ static const uint8_t r12a_chan_5ghz_1[] =
static const uint8_t r12a_chan_5ghz_2[] =
{ 149, 153, 157, 161, 165, 169, 173, 177 };
-
/*
* Function declarations.
*/
diff --git a/sys/dev/rtwn/rtl8812a/r12a_beacon.c b/sys/dev/rtwn/rtl8812a/r12a_beacon.c
index 7a3335e84f71..879d513eb66c 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_beacon.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_beacon.c
@@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/r12a_reg.h>
#include <dev/rtwn/rtl8812a/r12a_tx_desc.h>
-
void
r12a_beacon_init(struct rtwn_softc *sc, void *buf, int id)
{
diff --git a/sys/dev/rtwn/rtl8812a/r12a_calib.c b/sys/dev/rtwn/rtl8812a/r12a_calib.c
index c87151b5355a..268e06b5ba20 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_calib.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_calib.c
@@ -60,7 +60,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/r12a_reg.h>
#include <dev/rtwn/rtl8812a/r12a_var.h>
-
void
r12a_lc_calib(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/rtl8812a/r12a_caps.c b/sys/dev/rtwn/rtl8812a/r12a_caps.c
index aa1c755cb138..ab175b41ec70 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_caps.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_caps.c
@@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/r12a_reg.h>
#include <dev/rtwn/rtl8812a/r12a_var.h>
-
int
r12a_ioctl_net(struct ieee80211com *ic, u_long cmd, void *data)
{
diff --git a/sys/dev/rtwn/rtl8812a/r12a_chan.c b/sys/dev/rtwn/rtl8812a/r12a_chan.c
index 9536c6db4a31..a1b39b97c67c 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_chan.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_chan.c
@@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/r12a_reg.h>
#include <dev/rtwn/rtl8812a/r12a_var.h>
-
static void
r12a_write_txpower(struct rtwn_softc *sc, int chain,
struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT])
diff --git a/sys/dev/rtwn/rtl8812a/r12a_fw.c b/sys/dev/rtwn/rtl8812a/r12a_fw.c
index f7b88e42c4f8..08847d7fff07 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_fw.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_fw.c
@@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/r12a_var.h>
#include <dev/rtwn/rtl8812a/r12a_fw_cmd.h>
-
#ifndef RTWN_WITHOUT_UCODE
void
r12a_fw_reset(struct rtwn_softc *sc, int reason)
diff --git a/sys/dev/rtwn/rtl8812a/r12a_fw_cmd.h b/sys/dev/rtwn/rtl8812a/r12a_fw_cmd.h
index 58b82ed14268..e50e918912ad 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_fw_cmd.h
+++ b/sys/dev/rtwn/rtl8812a/r12a_fw_cmd.h
@@ -77,7 +77,6 @@ struct r12a_fw_cmd_iq_calib {
#define RTWN_CMD_IQ_EXT_LNA_5G(lna) ((lna) << 1)
} __packed;
-
/*
* C2H event types.
*/
diff --git a/sys/dev/rtwn/rtl8812a/r12a_init.c b/sys/dev/rtwn/rtl8812a/r12a_init.c
index 8ec401d9d0e4..af1a746b75a8 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_init.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_init.c
@@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/r12a_reg.h>
#include <dev/rtwn/rtl8812a/r12a_var.h>
-
int
r12a_check_condition(struct rtwn_softc *sc, const uint8_t cond[])
{
diff --git a/sys/dev/rtwn/rtl8812a/r12a_led.c b/sys/dev/rtwn/rtl8812a/r12a_led.c
index aa67c67b97a7..c2b76d1abdaf 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_led.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_led.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/r12a.h>
#include <dev/rtwn/rtl8812a/r12a_reg.h>
-
void
r12a_set_led(struct rtwn_softc *sc, int led, int on)
{
diff --git a/sys/dev/rtwn/rtl8812a/r12a_priv.h b/sys/dev/rtwn/rtl8812a/r12a_priv.h
index e75e32fcf9ba..f770e3b0ac6a 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_priv.h
+++ b/sys/dev/rtwn/rtl8812a/r12a_priv.h
@@ -73,7 +73,6 @@ static const struct rtwn_mac_prog rtl8812au_mac_no_ext_pa_lna[] = {
RTL8812AU_MAC_PROG_END
};
-
/*
* Baseband initialization values.
*/
@@ -212,7 +211,6 @@ static const struct rtwn_bb_prog rtl8812au_bb[] = {
}
};
-
static const uint32_t rtl8812au_agc_vals0_lna_g0[] = {
0xfc000001, 0xfb020001, 0xfa040001, 0xf9060001, 0xf8080001,
0xf70a0001, 0xf60c0001, 0xf50e0001, 0xf4100001, 0xf3120001,
@@ -832,7 +830,6 @@ static const struct rtwn_rf_prog rtl8812au_rf[] = {
{ 0, NULL, NULL, { 0 }, NULL }
};
-
/*
* Registers to save before IQ calibration.
*/
diff --git a/sys/dev/rtwn/rtl8812a/r12a_reg.h b/sys/dev/rtwn/rtl8812a/r12a_reg.h
index 581e7078138d..b6aa302e69d0 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_reg.h
+++ b/sys/dev/rtwn/rtl8812a/r12a_reg.h
@@ -50,7 +50,6 @@
#define R12A_ARFR_2G(i) (0x48c + (i) * 8)
#define R12A_HT_SINGLE_AMPDU 0x4c7
-
/* Bits for R92C_MAC_PHY_CTRL. */
#define R12A_MAC_PHY_CRYSTALCAP_M 0x7ff80000
#define R12A_MAC_PHY_CRYSTALCAP_S 19
@@ -89,7 +88,6 @@
#define R12A_RCR_TCP_OFFLD_EN 0x02000000
#define R12A_RCR_VHT_ACK 0x04000000
-
/*
* Baseband registers.
*/
@@ -234,7 +232,6 @@
#define R12A_TXAGC_MCS15_M 0xff000000
#define R12A_TXAGC_MCS15_S 24
-
/*
* RF (6052) registers.
*/
diff --git a/sys/dev/rtwn/rtl8812a/r12a_rf.c b/sys/dev/rtwn/rtl8812a/r12a_rf.c
index 43bd7b9ae608..a9936a1209a3 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_rf.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_rf.c
@@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/r12a.h>
#include <dev/rtwn/rtl8812a/r12a_reg.h>
-
uint32_t
r12a_rf_read(struct rtwn_softc *sc, int chain, uint8_t addr)
{
diff --git a/sys/dev/rtwn/rtl8812a/r12a_rom.c b/sys/dev/rtwn/rtl8812a/r12a_rom.c
index f5d16a3ff718..9eaa03adf3d9 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_rom.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_rom.c
@@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/r12a_var.h>
#include <dev/rtwn/rtl8812a/r12a_rom_image.h>
-
void
r12a_parse_rom_common(struct rtwn_softc *sc, uint8_t *buf)
{
diff --git a/sys/dev/rtwn/rtl8812a/r12a_rx.c b/sys/dev/rtwn/rtl8812a/r12a_rx.c
index 9fb410531711..d8dcb3de12c5 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_rx.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_rx.c
@@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/r12a_fw_cmd.h>
#include <dev/rtwn/rtl8812a/r12a_rx_desc.h>
-
#ifndef RTWN_WITHOUT_UCODE
void
r12a_ratectl_tx_complete(struct rtwn_softc *sc, uint8_t *buf, int len)
diff --git a/sys/dev/rtwn/rtl8812a/r12a_tx.c b/sys/dev/rtwn/rtl8812a/r12a_tx.c
index 9c8b27b233f3..3ce171c82444 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_tx.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_tx.c
@@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/r12a.h>
#include <dev/rtwn/rtl8812a/r12a_tx_desc.h>
-
static int
r12a_get_primary_channel(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
@@ -424,7 +423,6 @@ r12a_fill_tx_desc_null(struct rtwn_softc *sc, void *buf, int is11b, int qos,
if (!qos) {
txd->txdw8 = htole32(R12A_TXDW8_HWSEQ_EN);
txd->txdw3 |= htole32(SM(R12A_TXDW3_SEQ_SEL, id));
-
}
}
diff --git a/sys/dev/rtwn/rtl8812a/r12a_tx_desc.h b/sys/dev/rtwn/rtl8812a/r12a_tx_desc.h
index 9d3ad8b18162..ad01b6829d57 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_tx_desc.h
+++ b/sys/dev/rtwn/rtl8812a/r12a_tx_desc.h
@@ -130,7 +130,6 @@ struct r12a_tx_desc {
#define R12A_TXDW9_SEQ_S 12
} __packed __attribute__((aligned(4)));
-
/* Rate adaptation modes. */
#define R12A_RAID_11BGN_2_40 0
#define R12A_RAID_11BGN_1_40 1
diff --git a/sys/dev/rtwn/rtl8812a/usb/r12au.h b/sys/dev/rtwn/rtl8812a/usb/r12au.h
index 1ea08a2d94dd..bb4173d08abf 100644
--- a/sys/dev/rtwn/rtl8812a/usb/r12au.h
+++ b/sys/dev/rtwn/rtl8812a/usb/r12au.h
@@ -31,7 +31,6 @@
#include <dev/rtwn/rtl8812a/r12a.h>
-
/*
* Function declarations.
*/
diff --git a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
index 209e772a15a4..dd5223ce969b 100644
--- a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
+++ b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c
@@ -72,7 +72,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/usb/r12au.h>
#include <dev/rtwn/rtl8812a/usb/r12au_tx_desc.h>
-
void r12au_attach(struct rtwn_usb_softc *);
static void
diff --git a/sys/dev/rtwn/rtl8812a/usb/r12au_init.c b/sys/dev/rtwn/rtl8812a/usb/r12au_init.c
index 9a6bc2bb7c8e..109ae5cba180 100644
--- a/sys/dev/rtwn/rtl8812a/usb/r12au_init.c
+++ b/sys/dev/rtwn/rtl8812a/usb/r12au_init.c
@@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/usb/r12au.h>
#include <dev/rtwn/rtl8812a/usb/r12au_reg.h>
-
void
r12au_init_rx_agg(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/rtl8812a/usb/r12au_rx.c b/sys/dev/rtwn/rtl8812a/usb/r12au_rx.c
index a38fcd333287..de58a87354bd 100644
--- a/sys/dev/rtwn/rtl8812a/usb/r12au_rx.c
+++ b/sys/dev/rtwn/rtl8812a/usb/r12au_rx.c
@@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/usb/r12au.h>
-
int
r12au_classify_intr(struct rtwn_softc *sc, void *buf, int len)
{
diff --git a/sys/dev/rtwn/rtl8812a/usb/r12au_tx.c b/sys/dev/rtwn/rtl8812a/usb/r12au_tx.c
index 51496681591f..bc5f2ea9a02f 100644
--- a/sys/dev/rtwn/rtl8812a/usb/r12au_tx.c
+++ b/sys/dev/rtwn/rtl8812a/usb/r12au_tx.c
@@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8812a/usb/r12au.h>
#include <dev/rtwn/rtl8812a/usb/r12au_tx_desc.h>
-
void
r12au_dump_tx_desc(struct rtwn_softc *sc, const void *desc)
{
diff --git a/sys/dev/rtwn/rtl8821a/r21a.h b/sys/dev/rtwn/rtl8821a/r21a.h
index cfc99cb9fbb8..9491cf49615e 100644
--- a/sys/dev/rtwn/rtl8821a/r21a.h
+++ b/sys/dev/rtwn/rtl8821a/r21a.h
@@ -39,7 +39,6 @@
#define R21A_TX_PAGE_SIZE 256
-
/*
* Function declarations.
*/
diff --git a/sys/dev/rtwn/rtl8821a/r21a_beacon.c b/sys/dev/rtwn/rtl8821a/r21a_beacon.c
index f88f6def1baf..29de33e53f29 100644
--- a/sys/dev/rtwn/rtl8821a/r21a_beacon.c
+++ b/sys/dev/rtwn/rtl8821a/r21a_beacon.c
@@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8821a/r21a.h>
#include <dev/rtwn/rtl8821a/r21a_reg.h>
-
void
r21a_beacon_init(struct rtwn_softc *sc, void *buf, int id)
{
diff --git a/sys/dev/rtwn/rtl8821a/r21a_calib.c b/sys/dev/rtwn/rtl8821a/r21a_calib.c
index e1f1522e9ae4..395231a37b2d 100644
--- a/sys/dev/rtwn/rtl8821a/r21a_calib.c
+++ b/sys/dev/rtwn/rtl8821a/r21a_calib.c
@@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8821a/r21a_reg.h>
#include <dev/rtwn/rtl8821a/r21a_priv.h>
-
#ifndef RTWN_WITHOUT_UCODE
int
r21a_iq_calib_fw_supported(struct rtwn_softc *sc)
diff --git a/sys/dev/rtwn/rtl8821a/r21a_chan.c b/sys/dev/rtwn/rtl8821a/r21a_chan.c
index 49305057d2c1..68b3ef986fe5 100644
--- a/sys/dev/rtwn/rtl8821a/r21a_chan.c
+++ b/sys/dev/rtwn/rtl8821a/r21a_chan.c
@@ -60,7 +60,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8821a/r21a.h>
#include <dev/rtwn/rtl8821a/r21a_reg.h>
-
static void
r21a_bypass_ext_lna_2ghz(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/rtl8821a/r21a_fw.c b/sys/dev/rtwn/rtl8821a/r21a_fw.c
index b0d0a5bcabbf..a512d8f4be49 100644
--- a/sys/dev/rtwn/rtl8821a/r21a_fw.c
+++ b/sys/dev/rtwn/rtl8821a/r21a_fw.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8821a/r21a.h>
#include <dev/rtwn/rtl8821a/r21a_reg.h>
-
#ifndef RTWN_WITHOUT_UCODE
void
r21a_fw_reset(struct rtwn_softc *sc, int reason)
diff --git a/sys/dev/rtwn/rtl8821a/r21a_init.c b/sys/dev/rtwn/rtl8821a/r21a_init.c
index d8a0b1264ec4..8dc4faafe8d2 100644
--- a/sys/dev/rtwn/rtl8821a/r21a_init.c
+++ b/sys/dev/rtwn/rtl8821a/r21a_init.c
@@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8821a/r21a_priv.h>
#include <dev/rtwn/rtl8821a/r21a_reg.h>
-
int
r21a_power_on(struct rtwn_softc *sc)
{
diff --git a/sys/dev/rtwn/rtl8821a/r21a_led.c b/sys/dev/rtwn/rtl8821a/r21a_led.c
index 3e682c2a5efd..af75d4078208 100644
--- a/sys/dev/rtwn/rtl8821a/r21a_led.c
+++ b/sys/dev/rtwn/rtl8821a/r21a_led.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8821a/r21a.h>
#include <dev/rtwn/rtl8821a/r21a_reg.h>
-
void
r21a_set_led(struct rtwn_softc *sc, int led, int on)
{
diff --git a/sys/dev/rtwn/rtl8821a/r21a_priv.h b/sys/dev/rtwn/rtl8821a/r21a_priv.h
index d4cfa46afecf..298dd36040ef 100644
--- a/sys/dev/rtwn/rtl8821a/r21a_priv.h
+++ b/sys/dev/rtwn/rtl8821a/r21a_priv.h
@@ -60,7 +60,6 @@ static const struct rtwn_mac_prog rtl8821au_mac[] = {
{ 0x70b, 0x87 }, { 0x718, 0x40 }
};
-
/*
* Baseband initialization values.
*/
@@ -217,7 +216,6 @@ static const struct rtwn_agc_prog rtl8821au_agc[] = {
}
};
-
/*
* RF initialization values.
*/
@@ -445,7 +443,6 @@ static const struct rtwn_rf_prog rtl8821au_rf[] = {
{ 0, NULL, NULL, { 0 }, NULL }
};
-
/*
* Registers to save before IQ calibration.
*/
diff --git a/sys/dev/rtwn/rtl8821a/r21a_reg.h b/sys/dev/rtwn/rtl8821a/r21a_reg.h
index d13872d59cbc..287fcbd7f6f4 100644
--- a/sys/dev/rtwn/rtl8821a/r21a_reg.h
+++ b/sys/dev/rtwn/rtl8821a/r21a_reg.h
@@ -38,7 +38,6 @@
#define R21A_DWBCN0_CTRL R92C_TDECTRL
#define R21A_DWBCN1_CTRL 0x228
-
/* Bits for R92C_MAC_PHY_CTRL. */
#define R21A_MAC_PHY_CRYSTALCAP_M 0x00fff000
#define R21A_MAC_PHY_CRYSTALCAP_S 12
diff --git a/sys/dev/rtwn/rtl8821a/r21a_rom.c b/sys/dev/rtwn/rtl8821a/r21a_rom.c
index cda5913e9a81..45642043c0fb 100644
--- a/sys/dev/rtwn/rtl8821a/r21a_rom.c
+++ b/sys/dev/rtwn/rtl8821a/r21a_rom.c
@@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8821a/r21a.h>
#include <dev/rtwn/rtl8821a/r21a_reg.h>
-
void
r21a_parse_rom(struct rtwn_softc *sc, uint8_t *buf)
{
diff --git a/sys/dev/rtwn/rtl8821a/r21a_rx.c b/sys/dev/rtwn/rtl8821a/r21a_rx.c
index bd0721b3edc7..5670c2bf70d3 100644
--- a/sys/dev/rtwn/rtl8821a/r21a_rx.c
+++ b/sys/dev/rtwn/rtl8821a/r21a_rx.c
@@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8821a/r21a.h>
-
int8_t
r21a_get_rssi_cck(struct rtwn_softc *sc, void *physt)
{
diff --git a/sys/dev/rtwn/rtl8821a/usb/r21au.h b/sys/dev/rtwn/rtl8821a/usb/r21au.h
index a327d2ad7fa6..5e000446a997 100644
--- a/sys/dev/rtwn/rtl8821a/usb/r21au.h
+++ b/sys/dev/rtwn/rtl8821a/usb/r21au.h
@@ -31,7 +31,6 @@
#include <dev/rtwn/rtl8821a/r21a.h>
-
/*
* Function declarations.
*/
diff --git a/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c b/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
index 89a5bb870f7d..463d4876ae82 100644
--- a/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
+++ b/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c
@@ -70,7 +70,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8821a/usb/r21au.h>
-
void r21au_attach(struct rtwn_usb_softc *);
static void
diff --git a/sys/dev/rtwn/rtl8821a/usb/r21au_dfs.c b/sys/dev/rtwn/rtl8821a/usb/r21au_dfs.c
index ef230c852561..d1940d23e883 100644
--- a/sys/dev/rtwn/rtl8821a/usb/r21au_dfs.c
+++ b/sys/dev/rtwn/rtl8821a/usb/r21au_dfs.c
@@ -60,7 +60,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8821a/usb/r21au.h>
#include <dev/rtwn/rtl8821a/usb/r21au_reg.h>
-
#define R21AU_RADAR_CHECK_PERIOD (2 * hz)
static void
diff --git a/sys/dev/rtwn/rtl8821a/usb/r21au_init.c b/sys/dev/rtwn/rtl8821a/usb/r21au_init.c
index 140c291473d9..5f092def29b7 100644
--- a/sys/dev/rtwn/rtl8821a/usb/r21au_init.c
+++ b/sys/dev/rtwn/rtl8821a/usb/r21au_init.c
@@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8821a/usb/r21au.h>
#include <dev/rtwn/rtl8821a/usb/r21au_reg.h>
-
void
r21au_init_tx_agg(struct rtwn_softc *sc)
{
@@ -69,4 +68,3 @@ r21au_init_tx_agg(struct rtwn_softc *sc)
rtwn_write_1(sc, R21A_DWBCN1_CTRL, uc->tx_agg_desc_num << 1);
}
-
diff --git a/sys/dev/rtwn/usb/rtwn_usb_attach.c b/sys/dev/rtwn/usb/rtwn_usb_attach.c
index bdd6de217079..cb775bae3188 100644
--- a/sys/dev/rtwn/usb/rtwn_usb_attach.c
+++ b/sys/dev/rtwn/usb/rtwn_usb_attach.c
@@ -88,7 +88,6 @@ static void rtwn_usb_sysctlattach(struct rtwn_softc *);
#define RTWN_CONFIG_INDEX 0
-
static int
rtwn_usb_match(device_t self)
{
diff --git a/sys/dev/rtwn/usb/rtwn_usb_attach.h b/sys/dev/rtwn/usb/rtwn_usb_attach.h
index 9efa9ae330e3..40076dbb941c 100644
--- a/sys/dev/rtwn/usb/rtwn_usb_attach.h
+++ b/sys/dev/rtwn/usb/rtwn_usb_attach.h
@@ -158,6 +158,7 @@ static const STRUCT_USB_HOST_ID rtwn_devs[] = {
RTWN_RTL8821AU_DEV(DLINK, DWA172A1),
RTWN_RTL8821AU_DEV(EDIMAX, EW7811UTC_1),
RTWN_RTL8821AU_DEV(EDIMAX, EW7811UTC_2),
+ RTWN_RTL8821AU_DEV(ELECOM, WDB433SU2M2),
RTWN_RTL8821AU_DEV(HAWKING, HD65U),
RTWN_RTL8821AU_DEV(MELCO, WIU2433DM),
RTWN_RTL8821AU_DEV(MELCO, WIU2433DHP),
diff --git a/sys/dev/rtwn/usb/rtwn_usb_ep.c b/sys/dev/rtwn/usb/rtwn_usb_ep.c
index 4cbb011a5b1c..b6658b6a03d1 100644
--- a/sys/dev/rtwn/usb/rtwn_usb_ep.c
+++ b/sys/dev/rtwn/usb/rtwn_usb_ep.c
@@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/rtl8192c/usb/r92cu_reg.h>
-
static const struct usb_config rtwn_config_common[RTWN_N_TRANSFER] = {
[RTWN_BULK_RX] = {
.type = UE_BULK,
diff --git a/sys/dev/rtwn/usb/rtwn_usb_reg.c b/sys/dev/rtwn/usb/rtwn_usb_reg.c
index c464b69d7ece..fad6d04ec5ff 100644
--- a/sys/dev/rtwn/usb/rtwn_usb_reg.c
+++ b/sys/dev/rtwn/usb/rtwn_usb_reg.c
@@ -58,7 +58,6 @@ static int rtwn_usb_read_region_1(struct rtwn_softc *,
/* USB Requests. */
#define R92C_REQ_REGS 0x05
-
static int
rtwn_do_request(struct rtwn_softc *sc, struct usb_device_request *req,
void *data)
diff --git a/sys/dev/rtwn/usb/rtwn_usb_tx.c b/sys/dev/rtwn/usb/rtwn_usb_tx.c
index 2c5d55d3a56b..9e36474f1eca 100644
--- a/sys/dev/rtwn/usb/rtwn_usb_tx.c
+++ b/sys/dev/rtwn/usb/rtwn_usb_tx.c
@@ -67,12 +67,10 @@ static struct rtwn_data * rtwn_usb_getbuf(struct rtwn_usb_softc *);
static void rtwn_usb_txeof(struct rtwn_usb_softc *,
struct rtwn_data *, int);
-
static const uint8_t wme2qid[] =
{ RTWN_BULK_TX_BE, RTWN_BULK_TX_BK,
RTWN_BULK_TX_VI, RTWN_BULK_TX_VO };
-
static struct rtwn_data *
_rtwn_usb_getbuf(struct rtwn_usb_softc *uc)
{
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 7d0cd9a33cc5..2df411739313 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -1860,6 +1860,7 @@ product ELECOM LDUSBTX1 0x4002 LD-USB/TX
product ELECOM LDUSBLTX 0x4005 LD-USBL/TX
product ELECOM WDC150SU2M 0x4008 WDC-150SU2M
product ELECOM LDUSBTX2 0x400b LD-USB/TX
+product ELECOM WDB433SU2M2 0x400f WDB-433SU2M2
product ELECOM LDUSB20 0x4010 LD-USB20
product ELECOM UCSGT 0x5003 UC-SGT
product ELECOM UCSGT0 0x5004 UC-SGT
diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c
index 30d1fa1120ed..27a6c2a0aaa0 100644
--- a/sys/dev/usb/wlan/if_rsu.c
+++ b/sys/dev/usb/wlan/if_rsu.c
@@ -778,7 +778,8 @@ rsu_getradiocaps(struct ieee80211com *ic,
if (sc->sc_ht)
setbit(bands, IEEE80211_MODE_11NG);
ieee80211_add_channels_default_2ghz(chans, maxchans, nchans,
- bands, (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) != 0);
+ bands, (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) ?
+ NET80211_CBW_FLAG_HT40 : 0);
}
static void
@@ -857,6 +858,18 @@ rsu_get_multi_pos(const uint8_t maddr[])
return (pos);
}
+static u_int
+rsu_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
+{
+ uint32_t *mfilt = arg;
+ uint8_t pos;
+
+ pos = rsu_get_multi_pos(LLADDR(sdl));
+ mfilt[pos / 32] |= (1 << (pos % 32));
+
+ return (1);
+}
+
static void
rsu_set_multi(struct rsu_softc *sc)
{
@@ -868,28 +881,13 @@ rsu_set_multi(struct rsu_softc *sc)
/* general structure was copied from ath(4). */
if (ic->ic_allmulti == 0) {
struct ieee80211vap *vap;
- struct ifnet *ifp;
- struct ifmultiaddr *ifma;
/*
* Merge multicast addresses to form the hardware filter.
*/
mfilt[0] = mfilt[1] = 0;
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- ifp = vap->iv_ifp;
- if_maddr_rlock(ifp);
- CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- caddr_t dl;
- uint8_t pos;
-
- dl = LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr);
- pos = rsu_get_multi_pos(dl);
-
- mfilt[pos / 32] |= (1 << (pos % 32));
- }
- if_maddr_runlock(ifp);
- }
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
+ if_foreach_llmaddr(vap->iv_ifp, rsu_hash_maddr, &mfilt);
} else
mfilt[0] = mfilt[1] = ~0;
@@ -1984,7 +1982,7 @@ rsu_join_bss(struct rsu_softc *sc, struct ieee80211_node *ni)
frm = ieee80211_add_qos(frm, ni);
if ((ic->ic_flags & IEEE80211_F_WME) &&
(ni->ni_ies.wme_ie != NULL))
- frm = ieee80211_add_wme_info(frm, &ic->ic_wme);
+ frm = ieee80211_add_wme_info(frm, &ic->ic_wme, ni);
if (ni->ni_flags & IEEE80211_NODE_HT) {
frm = ieee80211_add_htcap(frm, ni);
frm = ieee80211_add_htinfo(frm, ni);
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index 7b2bd0d51f24..9eb261274b62 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -63,6 +63,9 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_ratectl.h>
+#ifdef IEEE80211_SUPPORT_SUPERG
+#include <net80211/ieee80211_superg.h>
+#endif
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -493,6 +496,9 @@ static void run_adjust_freq_offset(struct run_softc *);
static void run_init_locked(struct run_softc *);
static void run_stop(void *);
static void run_delay(struct run_softc *, u_int);
+static void run_update_chw(struct ieee80211com *ic);
+static int run_ampdu_enable(struct ieee80211_node *ni,
+ struct ieee80211_tx_ampdu *tap);
static eventhandler_tag run_etag;
@@ -504,10 +510,13 @@ static const struct rt2860_rate {
uint16_t sp_ack_dur;
uint16_t lp_ack_dur;
} rt2860_rates[] = {
+ /* CCK rates (11b) */
{ 2, 0, IEEE80211_T_DS, 0, 314, 314 },
{ 4, 1, IEEE80211_T_DS, 1, 258, 162 },
{ 11, 2, IEEE80211_T_DS, 2, 223, 127 },
{ 22, 3, IEEE80211_T_DS, 3, 213, 117 },
+
+ /* OFDM rates (11a / 11g) */
{ 12, 0, IEEE80211_T_OFDM, 4, 60, 60 },
{ 18, 1, IEEE80211_T_OFDM, 4, 52, 52 },
{ 24, 2, IEEE80211_T_OFDM, 6, 48, 48 },
@@ -515,9 +524,46 @@ static const struct rt2860_rate {
{ 48, 4, IEEE80211_T_OFDM, 8, 44, 44 },
{ 72, 5, IEEE80211_T_OFDM, 8, 40, 40 },
{ 96, 6, IEEE80211_T_OFDM, 8, 40, 40 },
- { 108, 7, IEEE80211_T_OFDM, 8, 40, 40 }
+ { 108, 7, IEEE80211_T_OFDM, 8, 40, 40 },
+
+ /* MCS - single stream */
+ { 0x80, 0, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x81, 1, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x82, 2, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x83, 3, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x84, 4, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x85, 5, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x86, 6, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x87, 7, IEEE80211_T_HT, 4, 60, 60 },
+
+ /* MCS - 2 streams */
+ { 0x88, 8, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x89, 9, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x8a, 10, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x8b, 11, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x8c, 12, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x8d, 13, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x8e, 14, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x8f, 15, IEEE80211_T_HT, 4, 60, 60 },
+
+ /* MCS - 3 streams */
+ { 0x90, 16, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x91, 17, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x92, 18, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x93, 19, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x94, 20, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x95, 21, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x96, 22, IEEE80211_T_HT, 4, 60, 60 },
+ { 0x97, 23, IEEE80211_T_HT, 4, 60, 60 },
};
+/* These are indexes into the above rt2860_rates[] array */
+#define RT2860_RIDX_CCK1 0
+#define RT2860_RIDX_CCK11 3
+#define RT2860_RIDX_OFDM6 4
+#define RT2860_RIDX_MCS0 12
+#define RT2860_RIDX_MAX 36
+
static const struct {
uint16_t reg;
uint32_t val;
@@ -805,9 +851,27 @@ run_attach(device_t self)
IEEE80211_C_MBSS |
IEEE80211_C_SHPREAMBLE | /* short preamble supported */
IEEE80211_C_SHSLOT | /* short slot time supported */
+ IEEE80211_C_SWAMSDUTX | /* Do software A-MSDU TX */
+ IEEE80211_C_FF | /* Atheros fast-frames */
IEEE80211_C_WME | /* WME */
IEEE80211_C_WPA; /* WPA1|WPA2(RSN) */
+ /*
+ * RF2020 is not an 11n device.
+ */
+ if (sc->rf_rev != RT3070_RF_2020) {
+ device_printf(sc->sc_dev, "[HT] Enabling 802.11n\n");
+ ic->ic_htcaps =
+ IEEE80211_HTC_HT |
+ IEEE80211_HTC_AMPDU |
+ IEEE80211_HTC_AMSDU |
+ IEEE80211_HTCAP_MAXAMSDU_3839 |
+ IEEE80211_HTCAP_SMPS_OFF;
+
+ ic->ic_rxstream = sc->nrxchains;
+ ic->ic_txstream = sc->ntxchains;
+ }
+
ic->ic_cryptocaps =
IEEE80211_CRYPTO_WEP |
IEEE80211_CRYPTO_AES_CCM |
@@ -837,6 +901,8 @@ run_attach(device_t self)
ic->ic_vap_delete = run_vap_delete;
ic->ic_transmit = run_transmit;
ic->ic_parent = run_parent;
+ ic->ic_update_chw = run_update_chw;
+ ic->ic_ampdu_enable = run_ampdu_enable;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -972,6 +1038,17 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
vap->iv_update_beacon = run_update_beacon;
vap->iv_max_aid = RT2870_WCID_MAX;
+
+ /*
+ * The linux rt2800 driver limits 1 stream devices to a 32KB
+ * RX AMPDU.
+ */
+ if (ic->ic_rxstream > 1)
+ vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K;
+ else
+ vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_32K;
+ vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_2; /* 2uS */
+
/*
* To delete the right key from h/w, we need wcid.
* Luckily, there is unused space in ieee80211_key{}, wk_pad,
@@ -2047,7 +2124,7 @@ run_media_change(struct ifnet *ifp)
RUN_LOCK(sc);
error = ieee80211_media_change(ifp);
- if (error != ENETRESET) {
+ if (error != 0) {
RUN_UNLOCK(sc);
return (error);
}
@@ -2057,11 +2134,13 @@ run_media_change(struct ifnet *ifp)
struct ieee80211_node *ni;
struct run_node *rn;
+ /* XXX TODO: methodize with MCS rates */
rate = ic->ic_sup_rates[ic->ic_curmode].
rs_rates[tp->ucastrate] & IEEE80211_RATE_VAL;
for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
if (rt2860_rates[ridx].rate == rate)
break;
+
ni = ieee80211_ref_node(vap->iv_bss);
rn = RUN_NODE(ni);
rn->fix_ridx = ridx;
@@ -2603,7 +2682,7 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
struct run_node *rn = RUN_NODE(ni);
union run_stats sta[2];
uint16_t (*wstat)[3];
- int error;
+ int error, ridx;
RUN_LOCK(sc);
@@ -2654,12 +2733,17 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
}
ieee80211_ratectl_tx_update(vap, txs);
- rn->amrr_ridx = ieee80211_ratectl_rate(ni, NULL, 0);
+ ieee80211_ratectl_rate(ni, NULL, 0);
+ /* XXX TODO: methodize with MCS rates */
+ for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
+ if (rt2860_rates[ridx].rate == ni->ni_txrate)
+ break;
+ rn->amrr_ridx = ridx;
fail:
RUN_UNLOCK(sc);
- RUN_DPRINTF(sc, RUN_DEBUG_RATE, "ridx=%d\n", rn->amrr_ridx);
+ RUN_DPRINTF(sc, RUN_DEBUG_RATE, "rate=%d, ridx=%d\n", ni->ni_txrate, rn->amrr_ridx);
}
static void
@@ -2682,14 +2766,12 @@ static void
run_newassoc(struct ieee80211_node *ni, int isnew)
{
struct run_node *rn = RUN_NODE(ni);
- struct ieee80211_rateset *rs = &ni->ni_rates;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = vap->iv_ic;
struct run_softc *sc = ic->ic_softc;
uint8_t rate;
uint8_t ridx;
uint8_t wcid;
- int i, j;
wcid = (vap->iv_opmode == IEEE80211_M_STA) ?
1 : RUN_AID2WCID(ni->ni_associd);
@@ -2719,31 +2801,8 @@ run_newassoc(struct ieee80211_node *ni, int isnew)
"new assoc isnew=%d associd=%x addr=%s\n",
isnew, ni->ni_associd, ether_sprintf(ni->ni_macaddr));
- for (i = 0; i < rs->rs_nrates; i++) {
- rate = rs->rs_rates[i] & IEEE80211_RATE_VAL;
- /* convert 802.11 rate to hardware rate index */
- for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
- if (rt2860_rates[ridx].rate == rate)
- break;
- rn->ridx[i] = ridx;
- /* determine rate of control response frames */
- for (j = i; j >= 0; j--) {
- if ((rs->rs_rates[j] & IEEE80211_RATE_BASIC) &&
- rt2860_rates[rn->ridx[i]].phy ==
- rt2860_rates[rn->ridx[j]].phy)
- break;
- }
- if (j >= 0) {
- rn->ctl_ridx[i] = rn->ridx[j];
- } else {
- /* no basic rate found, use mandatory one */
- rn->ctl_ridx[i] = rt2860_rates[ridx].ctl_ridx;
- }
- RUN_DPRINTF(sc, RUN_DEBUG_STATE | RUN_DEBUG_RATE,
- "rate=0x%02x ridx=%d ctl_ridx=%d\n",
- rs->rs_rates[i], rn->ridx[i], rn->ctl_ridx[i]);
- }
rate = vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)].mgmtrate;
+ /* XXX TODO: methodize with MCS rates */
for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
if (rt2860_rates[ridx].rate == rate)
break;
@@ -2873,6 +2932,10 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
} else
ni = NULL;
+ if(ni && ni->ni_flags & IEEE80211_NODE_HT) {
+ m->m_flags |= M_AMPDU;
+ }
+
if (__predict_false(flags & RT2860_RX_MICERR)) {
/* report MIC failures to net80211 for TKIP */
if (ni != NULL)
@@ -2982,10 +3045,11 @@ run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
tr_setup:
if (sc->rx_m == NULL) {
sc->rx_m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
- MJUMPAGESIZE /* xfer can be bigger than MCLBYTES */);
+ RUN_MAX_RXSZ);
}
if (sc->rx_m == NULL) {
- RUN_DPRINTF(sc, RUN_DEBUG_RECV | RUN_DEBUG_RECV_DESC,
+ RUN_DPRINTF(sc, RUN_DEBUG_RECV |
+ RUN_DEBUG_RECV_DESC | RUN_DEBUG_USB,
"could not allocate mbuf - idle with stall\n");
counter_u64_add(ic->ic_ierrors, 1);
usbd_xfer_set_stall(xfer);
@@ -3084,6 +3148,9 @@ tr_setup:
/* make sure we free the source buffer, if any */
m_freem(m);
+#ifdef IEEE80211_SUPPORT_SUPERG
+ ieee80211_ff_age_all(ic, 100);
+#endif
RUN_LOCK(sc);
}
@@ -3229,6 +3296,15 @@ tr_setup:
}
break;
}
+#ifdef IEEE80211_SUPPORT_SUPERG
+ /* XXX TODO: make this deferred rather than unlock/relock */
+ /* XXX TODO: should only do the QoS AC this belongs to */
+ if (pq->tx_nfree >= RUN_TX_RING_COUNT) {
+ RUN_UNLOCK(sc);
+ ieee80211_ff_flush_all(ic);
+ RUN_LOCK(sc);
+ }
+#endif
}
static void
@@ -3313,15 +3389,21 @@ run_set_tx_desc(struct run_softc *sc, struct run_tx_data *data)
if (ridx != RT2860_RIDX_CCK1 &&
(ic->ic_flags & IEEE80211_F_SHPREAMBLE))
mcs |= RT2860_PHY_SHPRE;
- } else
+ } else if (rt2860_rates[ridx].phy == IEEE80211_T_OFDM) {
mcs |= RT2860_PHY_OFDM;
+ } else if (rt2860_rates[ridx].phy == IEEE80211_T_HT) {
+ /* XXX TODO: [adrian] set short preamble for MCS? */
+ mcs |= RT2860_PHY_HT_MIX; /* Mixed, not greenfield */
+ }
txwi->phy = htole16(mcs);
/* check if RTS/CTS or CTS-to-self protection is required */
if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
- (m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold ||
+ ((m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) ||
((ic->ic_flags & IEEE80211_F_USEPROT) &&
- rt2860_rates[ridx].phy == IEEE80211_T_OFDM)))
+ rt2860_rates[ridx].phy == IEEE80211_T_OFDM) ||
+ ((ic->ic_htprotmode == IEEE80211_PROT_RTSCTS) &&
+ rt2860_rates[ridx].phy == IEEE80211_T_HT)))
txwi->txop |= RT2860_TX_TXOP_HT;
else
txwi->txop |= RT2860_TX_TXOP_BACKOFF;
@@ -3385,7 +3467,8 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
/* pickup a rate index */
if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
type != IEEE80211_FC0_TYPE_DATA || m->m_flags & M_EAPOL) {
- ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
+ /* XXX TODO: methodize for 11n; use MCS0 for 11NA/11NG */
+ ridx = (ic->ic_curmode == IEEE80211_MODE_11A || ic->ic_curmode == IEEE80211_MODE_11NA) ?
RT2860_RIDX_OFDM6 : RT2860_RIDX_CCK1;
ctl_ridx = rt2860_rates[ridx].ctl_ridx;
} else {
@@ -3604,6 +3687,7 @@ run_sendprot(struct run_softc *sc,
data->m = mprot;
data->ni = ieee80211_ref_node(ni);
+ /* XXX TODO: methodize with MCS rates */
for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
if (rt2860_rates[ridx].rate == protrate)
break;
@@ -3679,6 +3763,7 @@ run_tx_param(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
data->m = m;
data->ni = ni;
+ /* XXX TODO: methodize with MCS rates */
for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
if (rt2860_rates[ridx].rate == rate)
break;
@@ -4851,12 +4936,19 @@ run_getradiocaps(struct ieee80211com *ic,
memset(bands, 0, sizeof(bands));
setbit(bands, IEEE80211_MODE_11B);
setbit(bands, IEEE80211_MODE_11G);
+ if (sc->rf_rev != RT3070_RF_2020)
+ setbit(bands, IEEE80211_MODE_11NG);
+
+ /* Note: for now, only support HT20 channels */
ieee80211_add_channels_default_2ghz(chans, maxchans, nchans, bands, 0);
if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850 ||
sc->rf_rev == RT3070_RF_3052 || sc->rf_rev == RT3593_RF_3053 ||
sc->rf_rev == RT5592_RF_5592) {
setbit(bands, IEEE80211_MODE_11A);
+ if (sc->rf_rev != RT3070_RF_2020)
+ setbit(bands, IEEE80211_MODE_11NA);
+ /* Note: for now, only support HT20 channels */
ieee80211_add_channel_list_5ghz(chans, maxchans, nchans,
run_chan_5ghz, nitems(run_chan_5ghz), bands, 0);
}
@@ -6200,6 +6292,10 @@ run_init_locked(struct run_softc *sc)
/* turn radio LED on */
run_set_leds(sc, RT2860_LED_RADIO);
+ /* Set up AUTO_RSP_CFG register for auto response */
+ run_write(sc, RT2860_AUTO_RSP_CFG, RT2860_AUTO_RSP_EN |
+ RT2860_BAC_ACKPOLICY_EN | RT2860_CTS_40M_MODE_EN);
+
sc->sc_flags |= RUN_RUNNING;
sc->cmdq_run = RUN_CMDQ_GO;
@@ -6306,6 +6402,22 @@ run_delay(struct run_softc *sc, u_int ms)
&sc->sc_mtx : NULL, USB_MS_TO_TICKS(ms));
}
+
+static void
+run_update_chw(struct ieee80211com *ic)
+{
+
+ printf("%s: TODO\n", __func__);
+}
+
+static int
+run_ampdu_enable(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
+{
+
+ /* For now, no A-MPDU TX support in the driver */
+ return (0);
+}
+
static device_method_t run_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, run_match),
diff --git a/sys/dev/usb/wlan/if_runreg.h b/sys/dev/usb/wlan/if_runreg.h
index 8561d2c14947..ded41b62b3e5 100644
--- a/sys/dev/usb/wlan/if_runreg.h
+++ b/sys/dev/usb/wlan/if_runreg.h
@@ -781,7 +781,7 @@ struct rt2860_txwi {
#define RT2860_PHY_MODE 0xc000
#define RT2860_PHY_CCK (0 << 14)
#define RT2860_PHY_OFDM (1 << 14)
-#define RT2860_PHY_HT (2 << 14)
+#define RT2860_PHY_HT_MIX (2 << 14)
#define RT2860_PHY_HT_GF (3 << 14)
#define RT2860_PHY_SGI (1 << 8)
#define RT2860_PHY_BW40 (1 << 7)
@@ -955,11 +955,6 @@ struct rt2860_rxwi {
#define RT5390_EEPROM_IQ_GAIN_CAL_TX1_CH140_TO_CH165_5GHZ 0x14e
#define RT5390_EEPROM_IQ_PHASE_CAL_TX1_CH140_TO_CH165_5GHZ 0x14f
-#define RT2860_RIDX_CCK1 0
-#define RT2860_RIDX_CCK11 3
-#define RT2860_RIDX_OFDM6 4
-#define RT2860_RIDX_MAX 12
-
/*
* EEPROM access macro.
*/
diff --git a/sys/dev/usb/wlan/if_runvar.h b/sys/dev/usb/wlan/if_runvar.h
index a17d5b467d36..bb6231c3f947 100644
--- a/sys/dev/usb/wlan/if_runvar.h
+++ b/sys/dev/usb/wlan/if_runvar.h
@@ -23,14 +23,15 @@
#ifndef _IF_RUNVAR_H_
#define _IF_RUNVAR_H_
+/* Support up to 4KB frames - useful for A-MSDU/FF. */
#define RUN_MAX_RXSZ \
MIN(4096, MJUMPAGESIZE)
-/* NB: "11" is the maximum number of padding bytes needed for Tx */
+/* Support up to 8KB frames - useful for A-MSDU/FF. */
#define RUN_MAX_TXSZ \
(sizeof (struct rt2870_txd) + \
sizeof (struct rt2860_txwi) + \
- MCLBYTES + 11)
+ 8192 + 11)
#define RUN_TX_TIMEOUT 5000 /* ms */
@@ -97,8 +98,6 @@ STAILQ_HEAD(run_tx_data_head, run_tx_data);
struct run_node {
struct ieee80211_node ni;
- uint8_t ridx[IEEE80211_RATE_MAXSIZE];
- uint8_t ctl_ridx[IEEE80211_RATE_MAXSIZE];
uint8_t amrr_ridx;
uint8_t mgt_ridx;
uint8_t fix_ridx;
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index 852587d417c5..d823034ea94f 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -1970,49 +1970,48 @@ fail:
return (error);
}
+static u_int
+zyd_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
+{
+ uint32_t *hash = arg;
+ uint8_t v;
+
+ v = ((uint8_t *)LLADDR(sdl))[5] >> 2;
+ if (v < 32)
+ hash[0] |= 1 << v;
+ else
+ hash[1] |= 1 << (v - 32);
+
+ return (1);
+}
+
static void
zyd_set_multi(struct zyd_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
- uint32_t low, high;
+ uint32_t hash[2];
int error;
if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0)
return;
- low = 0x00000000;
- high = 0x80000000;
+ hash[0] = 0x00000000;
+ hash[1] = 0x80000000;
if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_allmulti > 0 ||
ic->ic_promisc > 0) {
- low = 0xffffffff;
- high = 0xffffffff;
+ hash[0] = 0xffffffff;
+ hash[1] = 0xffffffff;
} else {
struct ieee80211vap *vap;
- struct ifnet *ifp;
- struct ifmultiaddr *ifma;
- uint8_t v;
-
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- ifp = vap->iv_ifp;
- if_maddr_rlock(ifp);
- CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- v = ((uint8_t *)LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr))[5] >> 2;
- if (v < 32)
- low |= 1 << v;
- else
- high |= 1 << (v - 32);
- }
- if_maddr_runlock(ifp);
- }
+
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
+ if_foreach_llmaddr(vap->iv_ifp, zyd_hash_maddr, &hash);
}
/* reprogram multicast global hash table */
- zyd_write32_m(sc, ZYD_MAC_GHTBL, low);
- zyd_write32_m(sc, ZYD_MAC_GHTBH, high);
+ zyd_write32_m(sc, ZYD_MAC_GHTBL, hash[0]);
+ zyd_write32_m(sc, ZYD_MAC_GHTBH, hash[1]);
fail:
if (error != 0)
device_printf(sc->sc_dev,
diff --git a/sys/dev/wi/if_wavelan_ieee.h b/sys/dev/wi/if_wavelan_ieee.h
index dd8a9883eda3..27b7ed0f80bb 100644
--- a/sys/dev/wi/if_wavelan_ieee.h
+++ b/sys/dev/wi/if_wavelan_ieee.h
@@ -478,7 +478,6 @@ struct wi_rx_frame {
#define WI_MGMT_HDRLEN 0x3C
#define WI_CTL_HDRLEN 0x3C
-
/*
* all data packets have a snap (sub-network access protocol) header that
* isn't entirely definied, but added for ethernet compatibility.
@@ -488,7 +487,6 @@ struct wi_snap_frame {
u_int16_t wi_type;
};
-
/*
* management frame headers
* note: all management frames consist of a static header and variable length
@@ -592,7 +590,6 @@ struct wi_mgmt_deauth_hdr {
u_int16_t wi_reason;
};
-
/*
* rid configuration register definitions
*/
@@ -602,7 +599,6 @@ struct wi_mgmt_deauth_hdr {
#define WI_RID_PROCFRAME 0x3137 /* Return full frame information */
#define WI_RID_PRISM2 0x3138 /* tell if we're a prism2 card or not */
-
/*
* 802.11 definitions
*/
@@ -650,7 +646,6 @@ struct wi_mgmt_deauth_hdr {
#define WI_FCS_LEN 0x4 /* checksum length */
-
/*
* management definitions
*/
@@ -693,7 +688,6 @@ struct wi_mgmt_deauth_hdr {
#define WI_VAR_SRATES_MASK 0x7F
-
/*
* control definitions
*/
@@ -704,7 +698,6 @@ struct wi_mgmt_deauth_hdr {
#define WI_STYPE_CTL_CFEND 0x00E0
#define WI_STYPE_CTL_CFENDCFACK 0x00F0
-
/*
* ap scanning structures
*/
@@ -729,7 +722,6 @@ struct wi_scan_p2_hdr {
};
#define WI_PRISM2_RES_SIZE 62
-
/*
* prism2 debug mode definitions
*/
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index 35eb5343d7d7..96b16e6af1d9 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -162,7 +162,7 @@ static void wi_scan_end(struct ieee80211com *);
static void wi_getradiocaps(struct ieee80211com *, int, int *,
struct ieee80211_channel[]);
static void wi_set_channel(struct ieee80211com *);
-
+
static __inline int
wi_write_val(struct wi_softc *sc, int rid, u_int16_t val)
{
@@ -1506,41 +1506,45 @@ finish:
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
}
+struct wi_mcast_ctx {
+ struct wi_mcast mlist;
+ int mcnt;
+};
+
+static u_int
+wi_copy_mcast(void *arg, struct sockaddr_dl *sdl, u_int count)
+{
+ struct wi_mcast_ctx *ctx = arg;
+
+ if (ctx->mcnt >= 16)
+ return (0);
+ IEEE80211_ADDR_COPY(&ctx->mlist.wi_mcast[ctx->mcnt++], LLADDR(sdl));
+
+ return (1);
+}
+
static int
wi_write_multi(struct wi_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap;
- struct wi_mcast mlist;
- int n;
+ struct wi_mcast_ctx ctx;
if (ic->ic_allmulti > 0 || ic->ic_promisc > 0) {
allmulti:
- memset(&mlist, 0, sizeof(mlist));
- return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
- sizeof(mlist));
+ memset(&ctx.mlist, 0, sizeof(ctx.mlist));
+ return wi_write_rid(sc, WI_RID_MCAST_LIST, &ctx.mlist,
+ sizeof(ctx.mlist));
}
- n = 0;
+ ctx.mcnt = 0;
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- struct ifnet *ifp;
- struct ifmultiaddr *ifma;
-
- ifp = vap->iv_ifp;
- if_maddr_rlock(ifp);
- CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- if (n >= 16)
- goto allmulti;
- IEEE80211_ADDR_COPY(&mlist.wi_mcast[n],
- (LLADDR((struct sockaddr_dl *)ifma->ifma_addr)));
- n++;
- }
- if_maddr_runlock(ifp);
+ if_foreach_llmaddr(vap->iv_ifp, wi_copy_mcast, &ctx);
+ if (ctx.mcnt >= 16)
+ goto allmulti;
}
- return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
- IEEE80211_ADDR_LEN * n);
+ return wi_write_rid(sc, WI_RID_MCAST_LIST, &ctx.mlist,
+ IEEE80211_ADDR_LEN * ctx.mcnt);
}
static void
diff --git a/sys/dev/wi/if_wi_macio.c b/sys/dev/wi/if_wi_macio.c
index 438dde0fb994..42f86c91c60d 100644
--- a/sys/dev/wi/if_wi_macio.c
+++ b/sys/dev/wi/if_wi_macio.c
@@ -87,7 +87,6 @@ static device_method_t wi_macio_methods[] = {
DEVMETHOD(device_attach, wi_macio_attach),
DEVMETHOD(device_detach, wi_detach),
DEVMETHOD(device_shutdown, wi_shutdown),
-
{ 0, 0 }
};
diff --git a/sys/dev/wi/if_wi_pccard.c b/sys/dev/wi/if_wi_pccard.c
index 9c84c01c9b96..ef24271f4ab5 100644
--- a/sys/dev/wi/if_wi_pccard.c
+++ b/sys/dev/wi/if_wi_pccard.c
@@ -85,7 +85,6 @@ static device_method_t wi_pccard_methods[] = {
DEVMETHOD(device_attach, wi_pccard_attach),
DEVMETHOD(device_detach, wi_detach),
DEVMETHOD(device_shutdown, wi_shutdown),
-
{ 0, 0 }
};
diff --git a/sys/dev/wi/if_wi_pci.c b/sys/dev/wi/if_wi_pci.c
index c0431617d4be..e537239408a5 100644
--- a/sys/dev/wi/if_wi_pci.c
+++ b/sys/dev/wi/if_wi_pci.c
@@ -84,7 +84,6 @@ static device_method_t wi_pci_methods[] = {
DEVMETHOD(device_shutdown, wi_shutdown),
DEVMETHOD(device_suspend, wi_pci_suspend),
DEVMETHOD(device_resume, wi_pci_resume),
-
{ 0, 0 }
};
@@ -246,7 +245,7 @@ wi_pci_suspend(device_t dev)
WI_LOCK(sc);
wi_stop(sc, 1);
WI_UNLOCK(sc);
-
+
return (0);
}
diff --git a/sys/dev/wpi/if_wpireg.h b/sys/dev/wpi/if_wpireg.h
index b0154f22bc5e..04ef481fe08b 100644
--- a/sys/dev/wpi/if_wpireg.h
+++ b/sys/dev/wpi/if_wpireg.h
@@ -92,7 +92,6 @@
#define WPI_FH_MSG_CONFIG 0xe88
#define WPI_FH_TX_STATUS 0xe90
-
/*
* NIC internal memory offsets.
*/
@@ -119,7 +118,6 @@
#define WPI_BSM_DRAM_DATA_SIZE 0x349c
#define WPI_BSM_SRAM_BASE 0x3800
-
/* Possible flags for register WPI_HW_IF_CONFIG. */
#define WPI_HW_IF_CONFIG_ALM_MB (1 << 8)
#define WPI_HW_IF_CONFIG_ALM_MM (1 << 9)
@@ -558,7 +556,6 @@ struct wpi_beacon_missed {
uint32_t received;
} __packed;
-
/* Structure for command WPI_CMD_MRR_SETUP. */
#define WPI_RIDX_MAX 11
struct wpi_mrr_setup {
@@ -806,7 +803,6 @@ struct wpi_stats {
/* Possible flags for command WPI_CMD_GET_STATISTICS. */
#define WPI_STATISTICS_BEACON_DISABLE (1 << 1)
-
/* Firmware error dump entry. */
struct wpi_fw_dump {
uint32_t desc;
@@ -818,7 +814,6 @@ struct wpi_fw_dump {
/* Firmware image file header. */
struct wpi_firmware_hdr {
-
#define WPI_FW_MINVERSION 2144
#define WPI_FW_NAME "wpifw"
diff --git a/sys/dev/wtap/if_wtap.c b/sys/dev/wtap/if_wtap.c
index 6129d9d879f3..8f50c00a1f11 100644
--- a/sys/dev/wtap/if_wtap.c
+++ b/sys/dev/wtap/if_wtap.c
@@ -149,16 +149,6 @@ wtap_medium_enqueue(struct wtap_vap *avp, struct mbuf *m)
return medium_transmit(avp->av_md, avp->id, m);
}
-static int
-wtap_media_change(struct ifnet *ifp)
-{
-
- DWTAP_PRINTF("%s\n", __func__);
- int error = ieee80211_media_change(ifp);
- /* NB: only the fixed rate can change and that doesn't need a reset */
- return (error == ENETRESET ? 0 : error);
-}
-
/*
* Intercept management frames to collect beacon rssi data
* and to do ibss merges.
@@ -351,8 +341,8 @@ wtap_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
vap->iv_bmiss = wtap_bmiss;
/* complete setup */
- ieee80211_vap_attach(vap, wtap_media_change, ieee80211_media_status,
- mac);
+ ieee80211_vap_attach(vap, ieee80211_media_change,
+ ieee80211_media_status, mac);
avp->av_dev = make_dev(&wtap_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
"%s", (const char *)sc->name);
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 8d3583673776..60cbea3c9849 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -3132,10 +3132,8 @@ prison_priv_check(struct ucred *cred, int priv)
/*
* 802.11-related privileges.
*/
- case PRIV_NET80211_GETKEY:
-#ifdef notyet
- case PRIV_NET80211_MANAGE: /* XXX-BZ discuss with sam@ */
-#endif
+ case PRIV_NET80211_VAP_GETKEY:
+ case PRIV_NET80211_VAP_MANAGE:
#ifdef notyet
/*
diff --git a/sys/net80211/_ieee80211.h b/sys/net80211/_ieee80211.h
index 354362fcf09e..38ab1acb1c65 100644
--- a/sys/net80211/_ieee80211.h
+++ b/sys/net80211/_ieee80211.h
@@ -157,7 +157,7 @@ struct ieee80211_channel {
/*
* Note: for VHT operation we will need significantly more than
* IEEE80211_CHAN_MAX channels because of the combinations of
- * VHT20, VHT40, VHT80, VHT80+80 and VHT160.
+ * VHT20, VHT40, VHT80, VHT160, and VHT80+80.
*/
#define IEEE80211_CHAN_MAX 1024
#define IEEE80211_CHAN_BYTES howmany(IEEE80211_CHAN_MAX, NBBY)
@@ -194,8 +194,8 @@ struct ieee80211_channel {
#define IEEE80211_CHAN_VHT40U 0x02000000 /* VHT40 channel, ext above */
#define IEEE80211_CHAN_VHT40D 0x04000000 /* VHT40 channel, ext below */
#define IEEE80211_CHAN_VHT80 0x08000000 /* VHT80 channel */
-#define IEEE80211_CHAN_VHT80_80 0x10000000 /* VHT80+80 channel */
-#define IEEE80211_CHAN_VHT160 0x20000000 /* VHT160 channel */
+#define IEEE80211_CHAN_VHT160 0x10000000 /* VHT160 channel */
+#define IEEE80211_CHAN_VHT80P80 0x20000000 /* VHT80+80 channel */
/* XXX note: 0x80000000 is used in src/sbin/ifconfig/ifieee80211.c :( */
#define IEEE80211_CHAN_HT40 (IEEE80211_CHAN_HT40U | IEEE80211_CHAN_HT40D)
@@ -203,14 +203,14 @@ struct ieee80211_channel {
#define IEEE80211_CHAN_VHT40 (IEEE80211_CHAN_VHT40U | IEEE80211_CHAN_VHT40D)
#define IEEE80211_CHAN_VHT (IEEE80211_CHAN_VHT20 | IEEE80211_CHAN_VHT40 \
- | IEEE80211_CHAN_VHT80 | IEEE80211_CHAN_VHT80_80 \
- | IEEE80211_CHAN_VHT160)
+ | IEEE80211_CHAN_VHT80 | IEEE80211_CHAN_VHT160 \
+ | IEEE80211_CHAN_VHT80P80)
#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" \
- "\031VHT20\032VHT40U\033VHT40D\034VHT80\035VHT80_80\036VHT160"
+ "\031VHT20\032VHT40U\033VHT40D\034VHT80\035VHT160\036VHT80P80"
/*
* Useful combinations of channel characteristics.
@@ -337,10 +337,10 @@ struct ieee80211_channel {
((_c)->ic_flags & IEEE80211_CHAN_VHT) != 0)
#define IEEE80211_IS_CHAN_VHT80(_c) \
(((_c)->ic_flags & IEEE80211_CHAN_VHT80) != 0)
-#define IEEE80211_IS_CHAN_VHT80_80(_c) \
- (((_c)->ic_flags & IEEE80211_CHAN_VHT80_80) != 0)
#define IEEE80211_IS_CHAN_VHT160(_c) \
(((_c)->ic_flags & IEEE80211_CHAN_VHT160) != 0)
+#define IEEE80211_IS_CHAN_VHT80P80(_c) \
+ (((_c)->ic_flags & IEEE80211_CHAN_VHT80P80) != 0)
#define IEEE80211_CHAN2IEEE(_c) (_c)->ic_ieee
@@ -488,6 +488,7 @@ struct ieee80211_mimo_info {
#define IEEE80211_C_MBSS 0x00040000 /* CAPABILITY: MBSS available */
#define IEEE80211_C_SWSLEEP 0x00080000 /* CAPABILITY: do sleep here */
#define IEEE80211_C_SWAMSDUTX 0x00100000 /* CAPABILITY: software A-MSDU TX */
+#define IEEE80211_C_UAPSD 0x00200000 /* CAPABILITY: U-APSD */
/* 0x7c0000 available */
#define IEEE80211_C_WPA1 0x00800000 /* CAPABILITY: WPA1 avail */
#define IEEE80211_C_WPA2 0x01000000 /* CAPABILITY: WPA2 avail */
@@ -529,10 +530,13 @@ struct ieee80211_mimo_info {
#define IEEE80211_HTC_TXUNEQUAL 0x00800000 /* CAPABILITY: TX unequal MCS */
#define IEEE80211_HTC_TXMCS32 0x01000000 /* CAPABILITY: MCS32 support */
#define IEEE80211_HTC_TXLDPC 0x02000000 /* CAPABILITY: TX using LDPC */
+#define IEEE80211_HTC_RX_AMSDU_AMPDU 0x04000000 /* CAPABILITY: RX A-MSDU in A-MPDU */
+#define IEEE80211_HTC_TX_AMSDU_AMPDU 0x08000000 /* CAPABILITY: TX A-MSDU in A-MPDU */
#define IEEE80211_C_HTCAP_BITS \
"\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
- "\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS\32TXLDPC"
+ "\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS\32TXLDPC\33RXAMSDUAMPDU" \
+ "\34TXAMSDUAMPDU"
/*
* RX status notification - which fields are valid.
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index a36abf1aa0d9..68a13ec8b2f1 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -529,8 +529,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
ifp = if_alloc(IFT_ETHER);
if (ifp == NULL) {
- ic_printf(ic, "%s: unable to allocate ifnet\n",
- __func__);
+ ic_printf(ic, "%s: unable to allocate ifnet\n", __func__);
return ENOMEM;
}
if_initname(ifp, name, unit);
@@ -616,6 +615,12 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
if (vap->iv_opmode == IEEE80211_M_HOSTAP &&
(vap->iv_caps & IEEE80211_C_DFS))
vap->iv_flags_ext |= IEEE80211_FEXT_DFS;
+ /* NB: only flip on U-APSD for hostap/sta for now */
+ if ((vap->iv_opmode == IEEE80211_M_STA)
+ || (vap->iv_opmode == IEEE80211_M_HOSTAP)) {
+ if (vap->iv_caps & IEEE80211_C_UAPSD)
+ vap->iv_flags_ext |= IEEE80211_FEXT_UAPSD;
+ }
vap->iv_des_chan = IEEE80211_CHAN_ANYC; /* any channel is ok */
vap->iv_bmissthreshold = IEEE80211_HWBMISS_DEFAULT;
@@ -645,6 +650,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
ieee80211_scan_vattach(vap);
ieee80211_regdomain_vattach(vap);
ieee80211_radiotap_vattach(vap);
+ ieee80211_vap_reset_erp(vap);
ieee80211_ratectl_set(vap, IEEE80211_RATECTL_NONE);
return 0;
@@ -1162,23 +1168,17 @@ set_vht_extchan(struct ieee80211_channel *c)
{
int i;
- if (! IEEE80211_IS_CHAN_VHT(c)) {
+ if (! IEEE80211_IS_CHAN_VHT(c))
return (0);
- }
- if (IEEE80211_IS_CHAN_VHT20(c)) {
- c->ic_vht_ch_freq1 = c->ic_ieee;
- return (1);
+ if (IEEE80211_IS_CHAN_VHT80P80(c)) {
+ printf("%s: TODO VHT80+80 channel (ieee=%d, flags=0x%08x)\n",
+ __func__, c->ic_ieee, c->ic_flags);
}
- if (IEEE80211_IS_CHAN_VHT40(c)) {
- if (IEEE80211_IS_CHAN_HT40U(c))
- c->ic_vht_ch_freq1 = c->ic_ieee + 2;
- else if (IEEE80211_IS_CHAN_HT40D(c))
- c->ic_vht_ch_freq1 = c->ic_ieee - 2;
- else
- return (0);
- return (1);
+ if (IEEE80211_IS_CHAN_VHT160(c)) {
+ printf("%s: TODO VHT160 channel (ieee=%d, flags=0x%08x)\n",
+ __func__, c->ic_ieee, c->ic_flags);
}
if (IEEE80211_IS_CHAN_VHT80(c)) {
@@ -1202,10 +1202,23 @@ set_vht_extchan(struct ieee80211_channel *c)
return (0);
}
+ if (IEEE80211_IS_CHAN_VHT40(c)) {
+ if (IEEE80211_IS_CHAN_HT40U(c))
+ c->ic_vht_ch_freq1 = c->ic_ieee + 2;
+ else if (IEEE80211_IS_CHAN_HT40D(c))
+ c->ic_vht_ch_freq1 = c->ic_ieee - 2;
+ else
+ return (0);
+ return (1);
+ }
+
+ if (IEEE80211_IS_CHAN_VHT20(c)) {
+ c->ic_vht_ch_freq1 = c->ic_ieee;
+ return (1);
+ }
+
printf("%s: unknown VHT channel type (ieee=%d, flags=0x%08x)\n",
- __func__,
- c->ic_ieee,
- c->ic_flags);
+ __func__, c->ic_ieee, c->ic_flags);
return (0);
}
@@ -1240,11 +1253,7 @@ addchan(struct ieee80211_channel chans[], int maxchans, int *nchans,
#if 0
printf("%s: %d: ieee=%d, freq=%d, flags=0x%08x\n",
- __func__,
- *nchans,
- ieee,
- freq,
- flags);
+ __func__, *nchans, ieee, freq, flags);
#endif
c = &chans[(*nchans)++];
@@ -1274,9 +1283,7 @@ copychan_prev(struct ieee80211_channel chans[], int maxchans, int *nchans,
#if 0
printf("%s: %d: flags=0x%08x\n",
- __func__,
- *nchans,
- flags);
+ __func__, *nchans, flags);
#endif
c = &chans[(*nchans)++];
@@ -1294,7 +1301,7 @@ copychan_prev(struct ieee80211_channel chans[], int maxchans, int *nchans,
* XXX VHT-2GHz
*/
static void
-getflags_2ghz(const uint8_t bands[], uint32_t flags[], int ht40)
+getflags_2ghz(const uint8_t bands[], uint32_t flags[], int cbw_flags)
{
int nmodes;
@@ -1305,7 +1312,7 @@ getflags_2ghz(const uint8_t bands[], uint32_t flags[], int ht40)
flags[nmodes++] = IEEE80211_CHAN_G;
if (isset(bands, IEEE80211_MODE_11NG))
flags[nmodes++] = IEEE80211_CHAN_G | IEEE80211_CHAN_HT20;
- if (ht40) {
+ if (cbw_flags & NET80211_CBW_FLAG_HT40) {
flags[nmodes++] = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U;
flags[nmodes++] = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D;
}
@@ -1313,12 +1320,12 @@ getflags_2ghz(const uint8_t bands[], uint32_t flags[], int ht40)
}
static void
-getflags_5ghz(const uint8_t bands[], uint32_t flags[], int ht40, int vht80)
+getflags_5ghz(const uint8_t bands[], uint32_t flags[], int cbw_flags)
{
int nmodes;
/*
- * the addchan_list function seems to expect the flags array to
+ * The addchan_list() function seems to expect the flags array to
* be in channel width order, so the VHT bits are interspersed
* as appropriate to maintain said order.
*
@@ -1337,36 +1344,51 @@ getflags_5ghz(const uint8_t bands[], uint32_t flags[], int ht40, int vht80)
}
/* 40MHz */
- if (ht40) {
+ if (cbw_flags & NET80211_CBW_FLAG_HT40)
flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U;
- }
- if (ht40 && isset(bands, IEEE80211_MODE_VHT_5GHZ)) {
- flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U
- | IEEE80211_CHAN_VHT40U;
- }
- if (ht40) {
+ if ((cbw_flags & NET80211_CBW_FLAG_HT40) &&
+ isset(bands, IEEE80211_MODE_VHT_5GHZ))
+ flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U |
+ IEEE80211_CHAN_VHT40U;
+ if (cbw_flags & NET80211_CBW_FLAG_HT40)
flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D;
+ if ((cbw_flags & NET80211_CBW_FLAG_HT40) &&
+ isset(bands, IEEE80211_MODE_VHT_5GHZ))
+ flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D |
+ IEEE80211_CHAN_VHT40D;
+
+ /* 80MHz */
+ if ((cbw_flags & NET80211_CBW_FLAG_VHT80) &&
+ isset(bands, IEEE80211_MODE_VHT_5GHZ)) {
+ flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U |
+ IEEE80211_CHAN_VHT80;
+ flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D |
+ IEEE80211_CHAN_VHT80;
}
- if (ht40 && isset(bands, IEEE80211_MODE_VHT_5GHZ)) {
- flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D
- | IEEE80211_CHAN_VHT40D;
+
+ /* VHT160 */
+ if ((cbw_flags & NET80211_CBW_FLAG_VHT160) &&
+ isset(bands, IEEE80211_MODE_VHT_5GHZ)) {
+ flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U |
+ IEEE80211_CHAN_VHT160;
+ flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D |
+ IEEE80211_CHAN_VHT160;
}
- /* 80MHz */
- if (vht80 && isset(bands, IEEE80211_MODE_VHT_5GHZ)) {
- flags[nmodes++] = IEEE80211_CHAN_A |
- IEEE80211_CHAN_HT40U | IEEE80211_CHAN_VHT80;
- flags[nmodes++] = IEEE80211_CHAN_A |
- IEEE80211_CHAN_HT40D | IEEE80211_CHAN_VHT80;
+ /* VHT80+80 */
+ if ((cbw_flags & NET80211_CBW_FLAG_VHT80P80) &&
+ isset(bands, IEEE80211_MODE_VHT_5GHZ)) {
+ flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U |
+ IEEE80211_CHAN_VHT80P80;
+ flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D |
+ IEEE80211_CHAN_VHT80P80;
}
- /* XXX VHT80+80 */
- /* XXX VHT160 */
flags[nmodes] = 0;
}
static void
-getflags(const uint8_t bands[], uint32_t flags[], int ht40, int vht80)
+getflags(const uint8_t bands[], uint32_t flags[], int cbw_flags)
{
flags[0] = 0;
@@ -1379,15 +1401,16 @@ getflags(const uint8_t bands[], uint32_t flags[], int ht40, int vht80)
isset(bands, IEEE80211_MODE_VHT_2GHZ))
return;
- getflags_5ghz(bands, flags, ht40, vht80);
+ getflags_5ghz(bands, flags, cbw_flags);
} else
- getflags_2ghz(bands, flags, ht40);
+ getflags_2ghz(bands, flags, cbw_flags);
}
/*
* Add one 20 MHz channel into specified channel list.
* You MUST NOT mix bands when calling this. It will not add 5ghz
* channels if you have any B/G/N band bit set.
+ * This also does not support 40/80/160/80+80.
*/
/* XXX VHT */
int
@@ -1398,7 +1421,7 @@ ieee80211_add_channel(struct ieee80211_channel chans[], int maxchans,
uint32_t flags[IEEE80211_MODE_MAX];
int i, error;
- getflags(bands, flags, 0, 0);
+ getflags(bands, flags, 0);
KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__));
error = addchan(chans, maxchans, nchans, ieee, freq, maxregpower,
@@ -1549,6 +1572,9 @@ add_chanlist(struct ieee80211_channel chans[], int maxchans, int *nchans,
*/
is_vht = !! (flags[j] & IEEE80211_CHAN_VHT);
+ /* XXX TODO FIXME VHT80P80. */
+ /* XXX TODO FIXME VHT160. */
+
/*
* Test for VHT80.
* XXX This is all very broken right now.
@@ -1622,12 +1648,12 @@ add_chanlist(struct ieee80211_channel chans[], int maxchans, int *nchans,
int
ieee80211_add_channel_list_2ghz(struct ieee80211_channel chans[], int maxchans,
int *nchans, const uint8_t ieee[], int nieee, const uint8_t bands[],
- int ht40)
+ int cbw_flags)
{
uint32_t flags[IEEE80211_MODE_MAX];
/* XXX no VHT for now */
- getflags_2ghz(bands, flags, ht40);
+ getflags_2ghz(bands, flags, cbw_flags);
KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__));
return (add_chanlist(chans, maxchans, nchans, ieee, nieee, flags));
@@ -1635,30 +1661,27 @@ ieee80211_add_channel_list_2ghz(struct ieee80211_channel chans[], int maxchans,
int
ieee80211_add_channels_default_2ghz(struct ieee80211_channel chans[],
- int maxchans, int *nchans, const uint8_t bands[], int ht40)
+ int maxchans, int *nchans, const uint8_t bands[], int cbw_flags)
{
const uint8_t default_chan_list[] =
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
return (ieee80211_add_channel_list_2ghz(chans, maxchans, nchans,
- default_chan_list, nitems(default_chan_list), bands, ht40));
+ default_chan_list, nitems(default_chan_list), bands, cbw_flags));
}
int
ieee80211_add_channel_list_5ghz(struct ieee80211_channel chans[], int maxchans,
int *nchans, const uint8_t ieee[], int nieee, const uint8_t bands[],
- int ht40)
+ int cbw_flags)
{
- uint32_t flags[IEEE80211_MODE_MAX];
- int vht80 = 0;
-
/*
- * For now, assume VHT == VHT80 support as a minimum.
+ * XXX-BZ with HT and VHT there is no 1:1 mapping anymore. Review all
+ * uses of IEEE80211_MODE_MAX and add a new #define name for array size.
*/
- if (isset(bands, IEEE80211_MODE_VHT_5GHZ))
- vht80 = 1;
+ uint32_t flags[2 * IEEE80211_MODE_MAX];
- getflags_5ghz(bands, flags, ht40, vht80);
+ getflags_5ghz(bands, flags, cbw_flags);
KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__));
return (add_chanlist(chans, maxchans, nchans, ieee, nieee, flags));
@@ -1769,11 +1792,7 @@ ieee80211_lookup_channel_rxstatus(struct ieee80211vap *vap,
IEEE80211_DPRINTF(vap, IEEE80211_MSG_INPUT,
"%s: freq=%d, ieee=%d, flags=0x%08x; c=%p\n",
- __func__,
- (int) rxs->c_freq,
- (int) rxs->c_ieee,
- flags,
- c);
+ __func__, (int) rxs->c_freq, (int) rxs->c_ieee, flags, c);
return (c);
}
@@ -1914,12 +1933,18 @@ ieee80211_media_setup(struct ieee80211com *ic,
/*
* Add VHT media.
+ * XXX-BZ skip "VHT_2GHZ" for now.
*/
- for (; mode <= IEEE80211_MODE_VHT_5GHZ; mode++) {
+ for (mode = IEEE80211_MODE_VHT_5GHZ; mode <= IEEE80211_MODE_VHT_5GHZ;
+ mode++) {
if (isclr(ic->ic_modecaps, mode))
continue;
addmedia(media, caps, addsta, mode, IFM_AUTO);
addmedia(media, caps, addsta, mode, IFM_IEEE80211_VHT);
+ }
+ if (isset(ic->ic_modecaps, IEEE80211_MODE_VHT_5GHZ)) {
+ addmedia(media, caps, addsta,
+ IEEE80211_MODE_AUTO, IFM_IEEE80211_VHT);
/* XXX TODO: VHT maxrate */
}
@@ -2038,6 +2063,12 @@ media2mode(const struct ifmedia_entry *ime, uint32_t flags, uint16_t *mode)
case IFM_IEEE80211_11NG:
*mode = IEEE80211_MODE_11NG;
break;
+ case IFM_IEEE80211_VHT2G:
+ *mode = IEEE80211_MODE_VHT_2GHZ;
+ break;
+ case IFM_IEEE80211_VHT5G:
+ *mode = IEEE80211_MODE_VHT_5GHZ;
+ break;
case IFM_AUTO:
*mode = IEEE80211_MODE_AUTO;
break;
@@ -2200,7 +2231,7 @@ ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode)
ieee80211_setbasicrates(&ic->ic_sup_rates[mode], mode);
ic->ic_curmode = mode;
- ieee80211_reset_erp(ic); /* reset ERP state */
+ ieee80211_reset_erp(ic); /* reset global ERP state */
return 0;
}
@@ -2381,12 +2412,36 @@ ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode m
{ 75, IFM_IEEE80211_MCS },
{ 76, IFM_IEEE80211_MCS },
};
+ static const struct ratemedia vhtrates[] = {
+ { 0, IFM_IEEE80211_VHT },
+ { 1, IFM_IEEE80211_VHT },
+ { 2, IFM_IEEE80211_VHT },
+ { 3, IFM_IEEE80211_VHT },
+ { 4, IFM_IEEE80211_VHT },
+ { 5, IFM_IEEE80211_VHT },
+ { 6, IFM_IEEE80211_VHT },
+ { 7, IFM_IEEE80211_VHT },
+ { 8, IFM_IEEE80211_VHT }, /* Optional. */
+ { 9, IFM_IEEE80211_VHT }, /* Optional. */
+#if 0
+ /* Some QCA and BRCM seem to support this; offspec. */
+ { 10, IFM_IEEE80211_VHT },
+ { 11, IFM_IEEE80211_VHT },
+#endif
+ };
int m;
/*
- * Check 11n rates first for match as an MCS.
+ * Check 11ac/11n rates first for match as an MCS.
*/
- if (mode == IEEE80211_MODE_11NA) {
+ if (mode == IEEE80211_MODE_VHT_5GHZ) {
+ if (rate & IFM_IEEE80211_VHT) {
+ rate &= ~IFM_IEEE80211_VHT;
+ m = findmedia(vhtrates, nitems(vhtrates), rate);
+ if (m != IFM_AUTO)
+ return (m | IFM_IEEE80211_VHT);
+ }
+ } else if (mode == IEEE80211_MODE_11NA) {
if (rate & IEEE80211_RATE_MCS) {
rate &= ~IEEE80211_RATE_MCS;
m = findmedia(htrates, nitems(htrates), rate);
diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h
index 61389169bc47..62c40e263aba 100644
--- a/sys/net80211/ieee80211.h
+++ b/sys/net80211/ieee80211.h
@@ -430,6 +430,8 @@ struct ieee80211_action_ht_mimopowersave {
#define IEEE80211_BAPS_TID_S 2
#define IEEE80211_BAPS_POLICY 0x0002 /* block ack policy */
#define IEEE80211_BAPS_POLICY_S 1
+#define IEEE80211_BAPS_AMSDU 0x0001 /* A-MSDU permitted */
+#define IEEE80211_BAPS_AMSDU_S 0
#define IEEE80211_BAPS_POLICY_DELAYED (0<<IEEE80211_BAPS_POLICY_S)
#define IEEE80211_BAPS_POLICY_IMMEDIATE (1<<IEEE80211_BAPS_POLICY_S)
diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
index 24f6ba448e7b..ea1519b3381d 100644
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -715,6 +715,15 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
wh = mtod(m0, struct ieee80211_frame *);
frm = (uint8_t *)&wh[1];
efrm = mtod(m0, uint8_t *) + m0->m_len;
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_INPUT | IEEE80211_MSG_DEBUG,
+ "%s: recv mgmt frame, addr2=%6D, ni=%p (%6D) fc=%.02x %.02x\n",
+ __func__,
+ wh->i_addr2, ":",
+ ni,
+ ni->ni_macaddr, ":",
+ wh->i_fc[0],
+ wh->i_fc[1]);
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
case IEEE80211_FC0_SUBTYPE_BEACON: {
@@ -788,6 +797,20 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
} else
ni = NULL;
+ /*
+ * Send a probe request so we announce 11n
+ * capabilities.
+ *
+ * Don't do this if we're scanning.
+ */
+ if (! (ic->ic_flags & IEEE80211_F_SCAN))
+ ieee80211_send_probereq(ni, /* node */
+ vap->iv_myaddr, /* SA */
+ ni->ni_macaddr, /* DA */
+ vap->iv_bss->ni_bssid, /* BSSID */
+ vap->iv_bss->ni_essid,
+ vap->iv_bss->ni_esslen); /* SSID */
+
} else if (ni->ni_capinfo == 0) {
/*
* Update faked node created on transmit.
@@ -936,11 +959,11 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
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,
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT | IEEE80211_MSG_DEBUG,
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,
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT | IEEE80211_MSG_DEBUG,
wh, NULL, "wrong state %s",
ieee80211_state_name[vap->iv_state]);
vap->iv_stats.is_rx_mgtdiscard++;
diff --git a/sys/net80211/ieee80211_amrr.c b/sys/net80211/ieee80211_amrr.c
index f686b83bf04c..384a5956fe4e 100644
--- a/sys/net80211/ieee80211_amrr.c
+++ b/sys/net80211/ieee80211_amrr.c
@@ -477,18 +477,12 @@ amrr_sysctlattach(struct ieee80211vap *vap,
}
static void
-amrr_node_stats(struct ieee80211_node *ni, struct sbuf *s)
+amrr_print_node_rate(struct ieee80211_amrr_node *amn,
+ struct ieee80211_node *ni, struct sbuf *s)
{
int rate;
- struct ieee80211_amrr_node *amn = ni->ni_rctls;
struct ieee80211_rateset *rs;
- /* XXX TODO: check locking? */
-
- if (!amn)
- return;
-
- /* XXX TODO: this should be a method */
if (amrr_node_is_11n(ni)) {
rs = (struct ieee80211_rateset *) &ni->ni_htrates;
rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
@@ -498,7 +492,19 @@ amrr_node_stats(struct ieee80211_node *ni, struct sbuf *s)
rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
sbuf_printf(s, "rate: %d Mbit\n", rate / 2);
}
+}
+
+static void
+amrr_node_stats(struct ieee80211_node *ni, struct sbuf *s)
+{
+ struct ieee80211_amrr_node *amn = ni->ni_rctls;
+
+ /* XXX TODO: check locking? */
+
+ if (!amn)
+ return;
+ amrr_print_node_rate(amn, ni, s);
sbuf_printf(s, "ticks: %d\n", amn->amn_ticks);
sbuf_printf(s, "txcnt: %u\n", amn->amn_txcnt);
sbuf_printf(s, "success: %u\n", amn->amn_success);
diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c
index f45bb471ef7a..272aaf988ba1 100644
--- a/sys/net80211/ieee80211_ddb.c
+++ b/sys/net80211/ieee80211_ddb.c
@@ -209,6 +209,7 @@ _db_show_txampdu(const char *sep, int ix, const struct ieee80211_tx_ampdu *tap)
static void
_db_show_rxampdu(const char *sep, int ix, const struct ieee80211_rx_ampdu *rap)
{
+ struct mbuf *m;
int i;
db_printf("%srxampdu[%d]: %p flags 0x%x tid %u\n",
@@ -219,10 +220,15 @@ _db_show_rxampdu(const char *sep, int ix, const struct ieee80211_rx_ampdu *rap)
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]);
+ if (mbufq_len(&rap->rxa_mq[i]) > 0) {
+ db_printf("%s m[%2u:%4u] ", sep, i,
+ IEEE80211_SEQ_ADD(rap->rxa_start, i));
+ STAILQ_FOREACH(m, &rap->rxa_mq[i].mq_head,
+ m_stailqpkt) {
+ db_printf(" %p", m);
+ }
+ db_printf("\n");
+ }
}
static void
@@ -477,6 +483,17 @@ _db_show_vap(const struct ieee80211vap *vap, int showmesh, int showprocs)
if (vap->iv_tdma != NULL)
_db_show_tdma("\t", vap->iv_tdma, showprocs);
#endif /* IEEE80211_SUPPORT_TDMA */
+
+ db_printf("\tsta_assoc %u", vap->iv_sta_assoc);
+ db_printf(" ht_sta_assoc %u", vap->iv_ht_sta_assoc);
+ db_printf(" ht40_sta_assoc %u", vap->iv_ht40_sta_assoc);
+ db_printf("\n");
+ db_printf(" nonerpsta %u", vap->iv_nonerpsta);
+ db_printf(" longslotsta %u", vap->iv_longslotsta);
+ db_printf(" lastnonerp %d", vap->iv_lastnonerp);
+ db_printf(" lastnonht %d", vap->iv_lastnonht);
+ db_printf("\n");
+
if (showprocs) {
DB_PRINTSYM("\t", "iv_key_alloc", vap->iv_key_alloc);
DB_PRINTSYM("\t", "iv_key_delete", vap->iv_key_delete);
@@ -602,17 +619,8 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int 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);
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index dd710a8078f0..cb8c0a6a63e7 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/module.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
@@ -79,6 +80,10 @@ wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
struct ieee80211com *ic;
int error;
+ error = priv_check(curthread, PRIV_NET80211_CREATE_VAP);
+ if (error)
+ return error;
+
error = copyin(params, &cp, sizeof(cp));
if (error)
return error;
@@ -788,8 +793,11 @@ ieee80211_notify_replay_failure(struct ieee80211vap *vap,
struct ifnet *ifp = vap->iv_ifp;
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
- "%s replay detected tid %d <rsc %ju, csc %ju, keyix %u rxkeyix %u>",
- k->wk_cipher->ic_name, tid, (intmax_t) rsc,
+ "%s replay detected tid %d <rsc %ju (%jx), csc %ju (%jx), keyix %u rxkeyix %u>",
+ k->wk_cipher->ic_name, tid,
+ (intmax_t) rsc,
+ (intmax_t) rsc,
+ (intmax_t) k->wk_keyrsc[tid],
(intmax_t) k->wk_keyrsc[tid],
k->wk_keyix, k->wk_rxkeyix);
@@ -1030,6 +1038,20 @@ wlan_iflladdr(void *arg __unused, struct ifnet *ifp)
}
/*
+ * Fetch the VAP name.
+ *
+ * This returns a const char pointer suitable for debugging,
+ * but don't expect it to stick around for much longer.
+ */
+const char *
+ieee80211_get_vap_ifname(struct ieee80211vap *vap)
+{
+ if (vap->iv_ifp == NULL)
+ return "(none)";
+ return vap->iv_ifp->if_xname;
+}
+
+/*
* Module glue.
*
* NB: the module name is "wlan" for compatibility with NetBSD.
diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h
index 4e06b76ad60a..19a8e45672a9 100644
--- a/sys/net80211/ieee80211_freebsd.h
+++ b/sys/net80211/ieee80211_freebsd.h
@@ -245,6 +245,7 @@ void ieee80211_drain_ifq(struct ifqueue *);
void ieee80211_flush_ifq(struct ifqueue *, struct ieee80211vap *);
void ieee80211_vap_destroy(struct ieee80211vap *);
+const char * ieee80211_get_vap_ifname(struct ieee80211vap *);
#define IFNET_IS_UP_RUNNING(_ifp) \
(((_ifp)->if_flags & IFF_UP) && \
@@ -254,9 +255,9 @@ void ieee80211_vap_destroy(struct ieee80211vap *);
#define ticks_to_msecs(t) TICKS_2_MSEC(t)
#define ticks_to_secs(t) ((t) / hz)
-#define ieee80211_time_after(a,b) ((long)(b) - (long)(a) < 0)
+#define ieee80211_time_after(a,b) ((int)(b) - (int)(a) < 0)
#define ieee80211_time_before(a,b) ieee80211_time_after(b,a)
-#define ieee80211_time_after_eq(a,b) ((long)(a) - (long)(b) >= 0)
+#define ieee80211_time_after_eq(a,b) ((int)(a) - (int)(b) >= 0)
#define ieee80211_time_before_eq(a,b) ieee80211_time_after_eq(b,a)
struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index 263e0c3a2b67..6687276d0181 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <net80211/ieee80211_wds.h>
#include <net80211/ieee80211_vht.h>
+#include <net80211/ieee80211_sta.h> /* for parse_wmeie */
#define IEEE80211_RATE2MBS(r) (((r) & IEEE80211_RATE_VAL) / 2)
@@ -205,8 +206,9 @@ hostap_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
* 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;
+ vap->iv_flags_ext &= ~IEEE80211_FEXT_NONERP_PR;
+ vap->iv_flags_ht &= ~IEEE80211_FHT_NONHT_PR;
+ /* XXX TODO: schedule deferred update? */
/* fall thru... */
case IEEE80211_S_CAC:
/*
@@ -1811,10 +1813,13 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
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) {
+ vap->iv_lastnonerp = ticks;
+ vap->iv_flags_ext |= IEEE80211_FEXT_NONERP_PR;
+ /*
+ * XXX TODO: this may need to check all VAPs?
+ */
+ if (vap->iv_protmode != IEEE80211_PROT_NONE &&
+ (vap->iv_flags & IEEE80211_F_USEPROT) == 0) {
IEEE80211_NOTE_FRAME(vap,
IEEE80211_MSG_ASSOC, wh,
"non-ERP present on channel %d "
@@ -1822,8 +1827,8 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
"enable use of protection",
ic->ic_curchan->ic_ieee,
scan.erp, scan.chan);
- ic->ic_flags |= IEEE80211_F_USEPROT;
- ieee80211_notify_erp(ic);
+ vap->iv_flags |= IEEE80211_F_USEPROT;
+ ieee80211_vap_update_erp_protmode(vap);
}
}
/*
@@ -1843,12 +1848,12 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
break;
}
if (scan.htinfo == NULL) {
- ieee80211_htprot_update(ic,
+ ieee80211_htprot_update(vap,
IEEE80211_HTINFO_OPMODE_PROTOPT |
IEEE80211_HTINFO_NONHT_PRESENT);
} else if (ishtmixed(scan.htinfo)) {
/* XXX? take NONHT_PRESENT from beacon? */
- ieee80211_htprot_update(ic,
+ ieee80211_htprot_update(vap,
IEEE80211_HTINFO_OPMODE_MIXED |
IEEE80211_HTINFO_NONHT_PRESENT);
}
@@ -2253,8 +2258,18 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
* Mark node as capable of QoS.
*/
ni->ni_flags |= IEEE80211_NODE_QOS;
+ if (ieee80211_parse_wmeie(wme, wh, ni) > 0) {
+ if (ni->ni_uapsd != 0)
+ ni->ni_flags |=
+ IEEE80211_NODE_UAPSD;
+ else
+ ni->ni_flags &=
+ ~IEEE80211_NODE_UAPSD;
+ }
} else
- ni->ni_flags &= ~IEEE80211_NODE_QOS;
+ ni->ni_flags &=
+ ~(IEEE80211_NODE_QOS |
+ IEEE80211_NODE_UAPSD);
#ifdef IEEE80211_SUPPORT_SUPERG
if (ath != NULL) {
setie(ath_ie, ath - sfrm);
@@ -2268,6 +2283,7 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
#undef setie
} else {
ni->ni_flags &= ~IEEE80211_NODE_QOS;
+ ni->ni_flags &= ~IEEE80211_NODE_UAPSD;
ni->ni_ath_flags = 0;
}
ieee80211_node_join(ni, resp);
diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c
index d0c6e7a4f415..c17bfc89b716 100644
--- a/sys/net80211/ieee80211_ht.c
+++ b/sys/net80211/ieee80211_ht.c
@@ -267,6 +267,9 @@ ieee80211_ht_vattach(struct ieee80211vap *vap)
vap->iv_ampdu_mintraffic[WME_AC_VO] = 32;
vap->iv_ampdu_mintraffic[WME_AC_VI] = 32;
+ vap->iv_htprotmode = IEEE80211_PROT_RTSCTS;
+ vap->iv_curhtprotmode = IEEE80211_HTINFO_OPMODE_PURE;
+
if (vap->iv_htcaps & IEEE80211_HTC_HT) {
/*
* Device is HT capable; enable all HT-related
@@ -514,6 +517,22 @@ ieee80211_decap_amsdu(struct ieee80211_node *ni, struct mbuf *m)
return m; /* last delivered by caller */
}
+static void
+ampdu_rx_purge_slot(struct ieee80211_rx_ampdu *rap, int i)
+{
+ struct mbuf *m;
+
+ /* Walk the queue, removing frames as appropriate */
+ while (mbufq_len(&rap->rxa_mq[i]) != 0) {
+ m = mbufq_dequeue(&rap->rxa_mq[i]);
+ if (m == NULL)
+ break;
+ rap->rxa_qbytes -= m->m_pkthdr.len;
+ rap->rxa_qframes--;
+ m_freem(m);
+ }
+}
+
/*
* Add the given frame to the current RX reorder slot.
*
@@ -525,16 +544,94 @@ static int
ampdu_rx_add_slot(struct ieee80211_rx_ampdu *rap, int off, int tid,
ieee80211_seq rxseq,
struct ieee80211_node *ni,
- struct mbuf *m)
+ struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs)
{
+ const struct ieee80211_rx_stats *rxs_final = NULL;
struct ieee80211vap *vap = ni->ni_vap;
+ int toss_dup;
+#define PROCESS 0 /* caller should process frame */
+#define CONSUMED 1 /* frame consumed, caller does nothing */
- if (rap->rxa_m[off] == NULL) {
- rap->rxa_m[off] = m;
+ /*
+ * Figure out if this is a duplicate frame for the given slot.
+ *
+ * We're assuming that the driver will hand us all the frames
+ * for a given AMSDU decap pass and if we get /a/ frame
+ * for an AMSDU decap then we'll get all of them.
+ *
+ * The tricksy bit is that we don't know when the /end/ of
+ * the decap pass is, because we aren't tracking state here
+ * per-slot to know that we've finished receiving the frame list.
+ *
+ * The driver sets RX_F_AMSDU and RX_F_AMSDU_MORE to tell us
+ * what's going on; so ideally we'd just check the frame at the
+ * end of the reassembly slot to see if its F_AMSDU w/ no F_AMSDU_MORE -
+ * that means we've received the whole AMSDU decap pass.
+ */
+
+ /*
+ * Get the rxs of the final mbuf in the slot, if one exists.
+ */
+ if (mbufq_len(&rap->rxa_mq[off]) != 0) {
+ rxs_final = ieee80211_get_rx_params_ptr(mbufq_last(&rap->rxa_mq[off]));
+ }
+
+ /* Default to tossing the duplicate frame */
+ toss_dup = 1;
+
+ /*
+ * Check to see if the final frame has F_AMSDU and F_AMSDU set, AND
+ * this frame has F_AMSDU set (MORE or otherwise.) That's a sign
+ * that more can come.
+ */
+
+ if ((rxs != NULL) && (rxs_final != NULL) &&
+ ieee80211_check_rxseq_amsdu(rxs) &&
+ ieee80211_check_rxseq_amsdu(rxs_final)) {
+ if (! ieee80211_check_rxseq_amsdu_more(rxs_final)) {
+ /*
+ * amsdu_more() returning 0 means "it's not the
+ * final frame" so we can append more
+ * frames here.
+ */
+ toss_dup = 0;
+ }
+ }
+
+ /*
+ * If the list is empty OR we have determined we can put more
+ * driver decap'ed AMSDU frames in here, then insert.
+ */
+ if ((mbufq_len(&rap->rxa_mq[off]) == 0) || (toss_dup == 0)) {
+ if (mbufq_enqueue(&rap->rxa_mq[off], m) != 0) {
+ IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT | IEEE80211_MSG_11N,
+ ni->ni_macaddr,
+ "a-mpdu queue fail",
+ "seqno %u tid %u BA win <%u:%u> off=%d, qlen=%d, maxqlen=%d",
+ rxseq, tid, rap->rxa_start,
+ IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1),
+ off,
+ mbufq_len(&rap->rxa_mq[off]),
+ rap->rxa_mq[off].mq_maxlen);
+ /* XXX error count */
+ m_freem(m);
+ return CONSUMED;
+ }
rap->rxa_qframes++;
rap->rxa_qbytes += m->m_pkthdr.len;
vap->iv_stats.is_ampdu_rx_reorder++;
- return (0);
+ /*
+ * Statistics for AMSDU decap.
+ */
+ if (rxs != NULL && ieee80211_check_rxseq_amsdu(rxs)) {
+ if (ieee80211_check_rxseq_amsdu_more(rxs)) {
+ /* more=1, AMSDU, end of batch */
+ IEEE80211_NODE_STAT(ni, rx_amsdu_more_end);
+ } else {
+ IEEE80211_NODE_STAT(ni, rx_amsdu_more);
+ }
+ }
} else {
IEEE80211_DISCARD_MAC(vap,
IEEE80211_MSG_INPUT | IEEE80211_MSG_11N,
@@ -542,26 +639,27 @@ ampdu_rx_add_slot(struct ieee80211_rx_ampdu *rap, int off, int tid,
"seqno %u tid %u BA win <%u:%u>",
rxseq, tid, rap->rxa_start,
IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1));
+ if (rxs != NULL) {
+ IEEE80211_DISCARD_MAC(vap,
+ IEEE80211_MSG_INPUT | IEEE80211_MSG_11N,
+ ni->ni_macaddr, "a-mpdu duplicate",
+ "seqno %d tid %u pktflags 0x%08x\n",
+ rxseq, tid, rxs->c_pktflags);
+ }
+ if (rxs_final != NULL) {
+ IEEE80211_DISCARD_MAC(vap,
+ IEEE80211_MSG_INPUT | IEEE80211_MSG_11N,
+ ni->ni_macaddr, "a-mpdu duplicate",
+ "final: pktflags 0x%08x\n",
+ rxs_final->c_pktflags);
+ }
vap->iv_stats.is_rx_dup++;
IEEE80211_NODE_STAT(ni, rx_dup);
m_freem(m);
- return (-1);
}
-}
-
-static void
-ampdu_rx_purge_slot(struct ieee80211_rx_ampdu *rap, int i)
-{
- struct mbuf *m;
-
- m = rap->rxa_m[i];
- if (m == NULL)
- return;
-
- rap->rxa_m[i] = NULL;
- rap->rxa_qbytes -= m->m_pkthdr.len;
- rap->rxa_qframes--;
- m_freem(m);
+ return CONSUMED;
+#undef CONSUMED
+#undef PROCESS
}
/*
@@ -582,6 +680,18 @@ ampdu_rx_purge(struct ieee80211_rx_ampdu *rap)
rap->rxa_qbytes, rap->rxa_qframes));
}
+static void
+ieee80211_ampdu_rx_init_rap(struct ieee80211_node *ni,
+ struct ieee80211_rx_ampdu *rap)
+{
+ int i;
+
+ /* XXX TODO: ensure the queues are empty */
+ memset(rap, 0, sizeof(*rap));
+ for (i = 0; i < IEEE80211_AGGR_BAWMAX; i++)
+ mbufq_init(&rap->rxa_mq[i], 256);
+}
+
/*
* Start A-MPDU rx/re-order processing for the specified TID.
*/
@@ -589,6 +699,7 @@ static int
ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
int baparamset, int batimeout, int baseqctl)
{
+ struct ieee80211vap *vap = ni->ni_vap;
int bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ);
if (rap->rxa_flags & IEEE80211_AGGR_RUNNING) {
@@ -598,12 +709,19 @@ ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
*/
ampdu_rx_purge(rap);
}
- memset(rap, 0, sizeof(*rap));
+ ieee80211_ampdu_rx_init_rap(ni, 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;
+ /* XXX this should be a configuration flag */
+ if ((vap->iv_htcaps & IEEE80211_HTC_RX_AMSDU_AMPDU) &&
+ (MS(baparamset, IEEE80211_BAPS_AMSDU)))
+ rap->rxa_flags |= IEEE80211_AGGR_AMSDU;
+ else
+ rap->rxa_flags &= ~IEEE80211_AGGR_AMSDU;
+
return 0;
}
@@ -627,7 +745,8 @@ ieee80211_ampdu_rx_start_ext(struct ieee80211_node *ni, int tid, int seq, int ba
ampdu_rx_purge(rap);
}
- memset(rap, 0, sizeof(*rap));
+ ieee80211_ampdu_rx_init_rap(ni, rap);
+
rap->rxa_wnd = (baw== 0) ?
IEEE80211_AGGR_BAWMAX : min(baw, IEEE80211_AGGR_BAWMAX);
if (seq == -1) {
@@ -639,6 +758,8 @@ ieee80211_ampdu_rx_start_ext(struct ieee80211_node *ni, int tid, int seq, int ba
}
rap->rxa_flags |= IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND;
+ /* XXX TODO: no amsdu flag */
+
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni,
"%s: tid=%d, start=%d, wnd=%d, flags=0x%08x",
__func__,
@@ -695,18 +816,20 @@ ampdu_dispatch_slot(struct ieee80211_rx_ampdu *rap, struct ieee80211_node *ni,
int i)
{
struct mbuf *m;
+ int n = 0;
- if (rap->rxa_m[i] == NULL)
- return (0);
-
- m = rap->rxa_m[i];
- rap->rxa_m[i] = NULL;
- rap->rxa_qbytes -= m->m_pkthdr.len;
- rap->rxa_qframes--;
+ while (mbufq_len(&rap->rxa_mq[i]) != 0) {
+ m = mbufq_dequeue(&rap->rxa_mq[i]);
+ if (m == NULL)
+ break;
+ n++;
- ampdu_dispatch(ni, m);
+ rap->rxa_qbytes -= m->m_pkthdr.len;
+ rap->rxa_qframes--;
- return (1);
+ ampdu_dispatch(ni, m);
+ }
+ return (n);
}
static void
@@ -715,22 +838,22 @@ ampdu_rx_moveup(struct ieee80211_rx_ampdu *rap, struct ieee80211_node *ni,
{
struct ieee80211vap *vap = ni->ni_vap;
+ /*
+ * 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;
-
- if (winstart != -1) {
+ for (j = i+1; j < rap->rxa_wnd; j++) {
/*
- * NB: in window-sliding mode, loop assumes i > 0
- * and/or rxa_m[0] is NULL
+ * Concat the list contents over, which will
+ * blank the source list for us.
*/
- 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)
+ if (mbufq_len(&rap->rxa_mq[j]) != 0) {
+ n = n - mbufq_len(&rap->rxa_mq[j]);
+ mbufq_concat(&rap->rxa_mq[j-i], &rap->rxa_mq[j]);
+ KASSERT(n >= 0, ("%s: n < 0 (%d)", __func__, n));
+ if (n == 0)
break;
}
}
@@ -755,18 +878,18 @@ static void
ampdu_rx_dispatch(struct ieee80211_rx_ampdu *rap, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
- int i;
+ int i, r, r2;
/* flush run of frames */
+ r2 = 0;
for (i = 1; i < rap->rxa_wnd; i++) {
- if (ampdu_dispatch_slot(rap, ni, i) == 0)
+ r = ampdu_dispatch_slot(rap, ni, i);
+ if (r == 0)
break;
+ r2 += r;
}
- /*
- * If frames remain, copy the mbuf pointers down so
- * they correspond to the offsets in the new window.
- */
+ /* move up frames */
ampdu_rx_moveup(rap, ni, i, -1);
/*
@@ -774,7 +897,14 @@ ampdu_rx_dispatch(struct ieee80211_rx_ampdu *rap, struct ieee80211_node *ni)
* reflect the frames just dispatched.
*/
rap->rxa_start = IEEE80211_SEQ_ADD(rap->rxa_start, i);
- vap->iv_stats.is_ampdu_rx_oor += i;
+ vap->iv_stats.is_ampdu_rx_oor += r2;
+
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni,
+ "%s: moved slot up %d slots to start at %d (%d frames)",
+ __func__,
+ i,
+ rap->rxa_start,
+ r2);
}
/*
@@ -783,14 +913,20 @@ ampdu_rx_dispatch(struct ieee80211_rx_ampdu *rap, struct ieee80211_node *ni)
static void
ampdu_rx_flush(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
{
- struct ieee80211vap *vap = ni->ni_vap;
int i, r;
for (i = 0; i < rap->rxa_wnd; i++) {
r = ampdu_dispatch_slot(rap, ni, i);
if (r == 0)
continue;
- vap->iv_stats.is_ampdu_rx_oor += r;
+ ni->ni_vap->iv_stats.is_ampdu_rx_oor += r;
+
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni,
+ "%s: moved slot up %d slots to start at %d (%d frames)",
+ __func__,
+ 1,
+ rap->rxa_start,
+ r);
if (rap->rxa_qframes == 0)
break;
@@ -819,14 +955,23 @@ ampdu_rx_flush_upto(struct ieee80211_node *ni,
*/
seqno = rap->rxa_start;
for (i = 0; i < rap->rxa_wnd; i++) {
- r = ampdu_dispatch_slot(rap, ni, i);
- if (r == 0) {
+ if ((r = mbufq_len(&rap->rxa_mq[i])) != 0) {
+ (void) ampdu_dispatch_slot(rap, ni, i);
+ } else {
if (!IEEE80211_SEQ_BA_BEFORE(seqno, winstart))
break;
}
vap->iv_stats.is_ampdu_rx_oor += r;
seqno = IEEE80211_SEQ_INC(seqno);
+
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni,
+ "%s: moved slot up %d slots to start at %d (%d frames)",
+ __func__,
+ 1,
+ seqno,
+ r);
}
+
/*
* If frames remain, copy the mbuf pointers down so
* they correspond to the offsets in the new window.
@@ -849,6 +994,10 @@ ampdu_rx_flush_upto(struct ieee80211_node *ni,
* 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.
+ *
+ * A-MSDU: handle hardware decap'ed A-MSDU frames that are
+ * pretending to be MPDU's. They're dispatched directly if
+ * able; or attempted to put into the receive reordering slot.
*/
int
ieee80211_ampdu_reorder(struct ieee80211_node *ni, struct mbuf *m,
@@ -862,6 +1011,8 @@ ieee80211_ampdu_reorder(struct ieee80211_node *ni, struct mbuf *m,
ieee80211_seq rxseq;
uint8_t tid;
int off;
+ int amsdu = ieee80211_check_rxseq_amsdu(rxs);
+ int amsdu_end = ieee80211_check_rxseq_amsdu_more(rxs);
KASSERT((m->m_flags & (M_AMPDU | M_AMPDU_MPDU)) == M_AMPDU,
("!a-mpdu or already re-ordered, flags 0x%x", m->m_flags));
@@ -930,16 +1081,25 @@ again:
/*
* Dispatch as many packets as we can.
*/
- KASSERT(rap->rxa_m[0] == NULL, ("unexpected dup"));
+ KASSERT((mbufq_len(&rap->rxa_mq[0]) == 0), ("unexpected dup"));
ampdu_dispatch(ni, m);
ampdu_rx_dispatch(rap, ni);
return CONSUMED;
} else {
/*
- * In order; advance window and notify
+ * In order; advance window if needed and notify
* caller to dispatch directly.
*/
- rap->rxa_start = IEEE80211_SEQ_INC(rxseq);
+ if (amsdu) {
+ if (amsdu_end) {
+ rap->rxa_start = IEEE80211_SEQ_INC(rxseq);
+ IEEE80211_NODE_STAT(ni, rx_amsdu_more_end);
+ } else {
+ IEEE80211_NODE_STAT(ni, rx_amsdu_more);
+ }
+ } else {
+ rap->rxa_start = IEEE80211_SEQ_INC(rxseq);
+ }
return PROCESS;
}
}
@@ -983,7 +1143,24 @@ again:
rap->rxa_qframes;
ampdu_rx_flush(ni, rap);
}
- rap->rxa_start = IEEE80211_SEQ_INC(rxseq);
+ /*
+ * Advance the window if needed and notify
+ * the caller to dispatch directly.
+ */
+ if (amsdu) {
+ if (amsdu_end) {
+ rap->rxa_start =
+ IEEE80211_SEQ_INC(rxseq);
+ IEEE80211_NODE_STAT(ni,
+ rx_amsdu_more_end);
+ } else {
+ IEEE80211_NODE_STAT(ni,
+ rx_amsdu_more);
+ }
+ } else {
+ rap->rxa_start =
+ IEEE80211_SEQ_INC(rxseq);
+ }
return PROCESS;
}
} else {
@@ -994,8 +1171,7 @@ again:
}
/* save packet - this consumes, no matter what */
- ampdu_rx_add_slot(rap, off, tid, rxseq, ni, m);
-
+ ampdu_rx_add_slot(rap, off, tid, rxseq, ni, m, rxs);
return CONSUMED;
}
if (off < IEEE80211_SEQ_BA_RANGE) {
@@ -1159,8 +1335,10 @@ ieee80211_ht_node_init(struct ieee80211_node *ni)
tap->txa_ni = ni;
ieee80211_txampdu_init_pps(tap);
/* NB: further initialization deferred */
+ ieee80211_ampdu_rx_init_rap(ni, &ni->ni_rx_ampdu[tid]);
}
- ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU;
+ ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU |
+ IEEE80211_NODE_AMSDU;
}
/*
@@ -1326,42 +1504,41 @@ ieee80211_ht_wds_init(struct ieee80211_node *ni)
ieee80211_txampdu_init_pps(tap);
}
/* NB: AMPDU tx/rx governed by IEEE80211_FHT_AMPDU_{TX,RX} */
- ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU;
+ ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU |
+ IEEE80211_NODE_AMSDU;
}
/*
- * Notify hostap vaps of a change in the HTINFO ie.
+ * Notify a VAP of a change in the HTINFO ie if it's a hostap VAP.
+ *
+ * This is to be called from the deferred HT protection update
+ * task once the flags are updated.
*/
-static void
-htinfo_notify(struct ieee80211com *ic)
+void
+ieee80211_htinfo_notify(struct ieee80211vap *vap)
{
- struct ieee80211vap *vap;
- int first = 1;
- IEEE80211_LOCK_ASSERT(ic);
+ IEEE80211_LOCK_ASSERT(vap->iv_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);
- }
+ if (vap->iv_opmode != IEEE80211_M_HOSTAP)
+ return;
+ if (vap->iv_state != IEEE80211_S_RUN ||
+ !IEEE80211_IS_CHAN_HT(vap->iv_bss->ni_chan))
+ return;
+
+ 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"
+ , vap->iv_sta_assoc
+ , vap->iv_ht_sta_assoc
+ , vap->iv_ht40_sta_assoc
+ , (vap->iv_flags_ht & IEEE80211_FHT_NONHT_PR) ?
+ ", non-HT sta present" : ""
+ , vap->iv_curhtprotmode);
+
+ ieee80211_beacon_notify(vap, IEEE80211_BEACON_HTINFO);
}
/*
@@ -1369,26 +1546,28 @@ htinfo_notify(struct ieee80211com *ic)
* state and handle updates.
*/
static void
-htinfo_update(struct ieee80211com *ic)
+htinfo_update(struct ieee80211vap *vap)
{
+ struct ieee80211com *ic = vap->iv_ic;
uint8_t protmode;
- if (ic->ic_sta_assoc != ic->ic_ht_sta_assoc) {
+ if (vap->iv_sta_assoc != vap->iv_ht_sta_assoc) {
protmode = IEEE80211_HTINFO_OPMODE_MIXED
| IEEE80211_HTINFO_NONHT_PRESENT;
- } else if (ic->ic_flags_ht & IEEE80211_FHT_NONHT_PR) {
+ } else if (vap->iv_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) {
+ vap->iv_sta_assoc != vap->iv_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);
+ if (protmode != vap->iv_curhtprotmode) {
+ vap->iv_curhtprotmode = protmode;
+ /* Update VAP with new protection mode */
+ ieee80211_vap_update_ht_protmode(vap);
}
}
@@ -1398,16 +1577,16 @@ htinfo_update(struct ieee80211com *ic)
void
ieee80211_ht_node_join(struct ieee80211_node *ni)
{
- struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211vap *vap = ni->ni_vap;
- IEEE80211_LOCK_ASSERT(ic);
+ IEEE80211_LOCK_ASSERT(vap->iv_ic);
if (ni->ni_flags & IEEE80211_NODE_HT) {
- ic->ic_ht_sta_assoc++;
+ vap->iv_ht_sta_assoc++;
if (ni->ni_chw == 40)
- ic->ic_ht40_sta_assoc++;
+ vap->iv_ht40_sta_assoc++;
}
- htinfo_update(ic);
+ htinfo_update(vap);
}
/*
@@ -1416,16 +1595,16 @@ ieee80211_ht_node_join(struct ieee80211_node *ni)
void
ieee80211_ht_node_leave(struct ieee80211_node *ni)
{
- struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211vap *vap = ni->ni_vap;
- IEEE80211_LOCK_ASSERT(ic);
+ IEEE80211_LOCK_ASSERT(vap->iv_ic);
if (ni->ni_flags & IEEE80211_NODE_HT) {
- ic->ic_ht_sta_assoc--;
+ vap->iv_ht_sta_assoc--;
if (ni->ni_chw == 40)
- ic->ic_ht40_sta_assoc--;
+ vap->iv_ht40_sta_assoc--;
}
- htinfo_update(ic);
+ htinfo_update(vap);
}
/*
@@ -1439,25 +1618,27 @@ ieee80211_ht_node_leave(struct ieee80211_node *ni)
* 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)
+ieee80211_htprot_update(struct ieee80211vap *vap, int protmode)
{
+ struct ieee80211com *ic = vap->iv_ic;
#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;
+ vap->iv_flags_ht |= IEEE80211_FHT_NONHT_PR;
+ vap->iv_lastnonht = ticks;
- if (protmode != ic->ic_curhtprotmode &&
- (OPMODE(ic->ic_curhtprotmode) != IEEE80211_HTINFO_OPMODE_MIXED ||
+ if (protmode != vap->iv_curhtprotmode &&
+ (OPMODE(vap->iv_curhtprotmode) != IEEE80211_HTINFO_OPMODE_MIXED ||
OPMODE(protmode) == IEEE80211_HTINFO_OPMODE_PROTOPT)) {
- /* push beacon update */
- ic->ic_curhtprotmode = protmode;
- htinfo_notify(ic);
+ vap->iv_curhtprotmode = protmode;
+ /* Update VAP with new protection mode */
+ ieee80211_vap_update_ht_protmode(vap);
}
IEEE80211_UNLOCK(ic);
#undef OPMODE
@@ -1472,18 +1653,17 @@ ieee80211_htprot_update(struct ieee80211com *ic, int protmode)
* gone we time out this condition.
*/
void
-ieee80211_ht_timeout(struct ieee80211com *ic)
+ieee80211_ht_timeout(struct ieee80211vap *vap)
{
- IEEE80211_LOCK_ASSERT(ic);
- if ((ic->ic_flags_ht & IEEE80211_FHT_NONHT_PR) &&
- ieee80211_time_after(ticks, ic->ic_lastnonht + IEEE80211_NONHT_PRESENT_AGE)) {
-#if 0
- IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni,
+ IEEE80211_LOCK_ASSERT(vap->iv_ic);
+
+ if ((vap->iv_flags_ht & IEEE80211_FHT_NONHT_PR) &&
+ ieee80211_time_after(ticks, vap->iv_lastnonht + IEEE80211_NONHT_PRESENT_AGE)) {
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_11N,
"%s", "time out non-HT STA present on channel");
-#endif
- ic->ic_flags_ht &= ~IEEE80211_FHT_NONHT_PR;
- htinfo_update(ic);
+ vap->iv_flags_ht &= ~IEEE80211_FHT_NONHT_PR;
+ htinfo_update(vap);
}
}
@@ -1774,7 +1954,7 @@ ieee80211_vht_get_vhtflags(struct ieee80211_node *ni, uint32_t htflags)
(MS(vap->iv_vhtcaps,
IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) == 2) &&
(vap->iv_flags_vht & IEEE80211_FVHT_USEVHT80P80)) {
- vhtflags = IEEE80211_CHAN_VHT80_80;
+ vhtflags = IEEE80211_CHAN_VHT80P80;
/* Mirror the HT40 flags */
if (htflags == IEEE80211_CHAN_HT40U) {
vhtflags |= IEEE80211_CHAN_HT40U;
@@ -2170,6 +2350,7 @@ ieee80211_addba_response(struct ieee80211_node *ni,
struct ieee80211_tx_ampdu *tap,
int status, int baparamset, int batimeout)
{
+ struct ieee80211vap *vap = ni->ni_vap;
int bufsiz, tid;
/* XXX locking */
@@ -2179,10 +2360,16 @@ ieee80211_addba_response(struct ieee80211_node *ni,
/* 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;
+ /* TODO: this should be a vap flag */
+ if ((vap->iv_htcaps & IEEE80211_HTC_TX_AMSDU_AMPDU) &&
+ (ni->ni_flags & IEEE80211_NODE_AMSDU_TX) &&
+ (MS(baparamset, IEEE80211_BAPS_AMSDU)))
+ tap->txa_flags |= IEEE80211_AGGR_AMSDU;
+ else
+ tap->txa_flags &= ~IEEE80211_AGGR_AMSDU;
} else {
/* mark tid so we don't try again */
tap->txa_flags |= IEEE80211_AGGR_NAK;
@@ -2201,7 +2388,7 @@ ieee80211_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
addba_stop_timeout(tap);
if (tap->txa_flags & IEEE80211_AGGR_RUNNING) {
/* XXX clear aggregation queue */
- tap->txa_flags &= ~IEEE80211_AGGR_RUNNING;
+ tap->txa_flags &= ~(IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_AMSDU);
}
tap->txa_attempts = 0;
}
@@ -2234,12 +2421,13 @@ ht_recv_action_ba_addba_request(struct ieee80211_node *ni,
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",
+ "(tid %d bufsiz %d) batimeout %d baseqctl %d:%d amsdu %d",
dialogtoken, baparamset,
tid, MS(baparamset, IEEE80211_BAPS_BUFSIZ),
batimeout,
MS(baseqctl, IEEE80211_BASEQ_START),
- MS(baseqctl, IEEE80211_BASEQ_FRAG));
+ MS(baseqctl, IEEE80211_BASEQ_FRAG),
+ MS(baparamset, IEEE80211_BAPS_AMSDU));
rap = &ni->ni_rx_ampdu[tid];
@@ -2252,7 +2440,7 @@ ht_recv_action_ba_addba_request(struct ieee80211_node *ni,
*/
if ((ni->ni_flags & IEEE80211_NODE_AMPDU_RX) &&
(vap->iv_flags_ht & IEEE80211_FHT_AMPDU_RX)) {
- /* XXX handle ampdu_rx_start failure */
+ /* XXX TODO: handle ampdu_rx_start failure */
ic->ic_ampdu_rx_start(ni, rap,
baparamset, batimeout, baseqctl);
@@ -2271,6 +2459,16 @@ ht_recv_action_ba_addba_request(struct ieee80211_node *ni,
| SM(tid, IEEE80211_BAPS_TID)
| SM(rap->rxa_wnd, IEEE80211_BAPS_BUFSIZ)
;
+
+ /*
+ * TODO: we're out of iv_flags_ht fields; once
+ * this is extended we should make this configurable.
+ */
+ if ((baparamset & IEEE80211_BAPS_AMSDU) &&
+ (ni->ni_flags & IEEE80211_NODE_AMSDU_RX) &&
+ (vap->iv_htcaps & IEEE80211_HTC_RX_AMSDU_AMPDU))
+ args[2] |= IEEE80211_BAPS_AMSDU;
+
args[3] = 0;
args[4] = 0;
ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA,
@@ -2289,6 +2487,7 @@ ht_recv_action_ba_addba_response(struct ieee80211_node *ni,
uint8_t dialogtoken, policy;
uint16_t baparamset, batimeout, code;
int tid, bufsiz;
+ int amsdu;
dialogtoken = frm[2];
code = le16dec(frm+3);
@@ -2296,6 +2495,7 @@ ht_recv_action_ba_addba_response(struct ieee80211_node *ni,
tid = MS(baparamset, IEEE80211_BAPS_TID);
bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ);
policy = MS(baparamset, IEEE80211_BAPS_POLICY);
+ amsdu = !! MS(baparamset, IEEE80211_BAPS_AMSDU);
batimeout = le16dec(frm+7);
tap = &ni->ni_tx_ampdu[tid];
@@ -2343,10 +2543,13 @@ ht_recv_action_ba_addba_response(struct ieee80211_node *ni,
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,
+ "baparamset 0x%x (tid %d bufsiz %d amsdu %d) batimeout %d",
+ dialogtoken, code, baparamset, tid,
+ bufsiz,
+ amsdu,
batimeout);
ic->ic_addba_response(ni, tap, code, baparamset, batimeout);
return 0;
@@ -2503,6 +2706,12 @@ ieee80211_ampdu_request(struct ieee80211_node *ni,
| SM(tid, IEEE80211_BAPS_TID)
| SM(IEEE80211_AGGR_BAWMAX, IEEE80211_BAPS_BUFSIZ)
;
+
+ /* XXX TODO: this should be a flag, not iv_htcaps */
+ if ((ni->ni_flags & IEEE80211_NODE_AMSDU_TX) &&
+ (ni->ni_vap->iv_htcaps & IEEE80211_HTC_TX_AMSDU_AMPDU))
+ args[2] |= IEEE80211_BAPS_AMSDU;
+
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])) {
@@ -2834,11 +3043,11 @@ ht_send_action_ba_addba(struct ieee80211_node *ni,
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",
+ "baparamset 0x%x (tid %d amsdu %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]);
+ MS(args[2], IEEE80211_BAPS_AMSDU), args[3], args[4]);
IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
"ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
@@ -3299,6 +3508,12 @@ ieee80211_ht_update_beacon(struct ieee80211vap *vap,
ht->hi_byte1 |= IEEE80211_HTINFO_TXWIDTH_2040;
/* protection mode */
+ /*
+ * XXX TODO: this uses the global flag, not the per-VAP flag.
+ * Eventually (once the protection modes are done per-channel
+ * rather than per-VAP) we can flip this over to be per-VAP but
+ * using the channel protection mode.
+ */
ht->hi_byte2 = (ht->hi_byte2 &~ PROTMODE) | ic->ic_curhtprotmode;
ieee80211_free_node(ni);
@@ -3339,7 +3554,11 @@ ieee80211_add_htinfo_body(uint8_t *frm, struct ieee80211_node *ni)
if (IEEE80211_IS_CHAN_HT40(ni->ni_chan))
frm[0] |= IEEE80211_HTINFO_TXWIDTH_2040;
- frm[1] = ic->ic_curhtprotmode;
+ /*
+ * Add current protection mode. Unlike for beacons,
+ * this will respect the per-VAP flags.
+ */
+ frm[1] = vap->iv_curhtprotmode;
frm += 5;
diff --git a/sys/net80211/ieee80211_ht.h b/sys/net80211/ieee80211_ht.h
index 4e02cd3270ee..7f62b0f7c756 100644
--- a/sys/net80211/ieee80211_ht.h
+++ b/sys/net80211/ieee80211_ht.h
@@ -33,6 +33,8 @@
* 802.11n protocol implementation definitions.
*/
+#include <sys/mbuf.h>
+
#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)
@@ -47,6 +49,7 @@ struct ieee80211_tx_ampdu {
#define IEEE80211_AGGR_NAK 0x0010 /* peer NAK'd ADDBA request */
#define IEEE80211_AGGR_BARPEND 0x0020 /* BAR response pending */
#define IEEE80211_AGGR_WAITRX 0x0040 /* Wait for first RX frame to define BAW */
+#define IEEE80211_AGGR_AMSDU 0x0080 /* A-MSDU in A-MPDU TX allowed */
uint8_t txa_tid;
uint8_t txa_token; /* dialog token */
int txa_lastsample; /* ticks @ last traffic sample */
@@ -68,6 +71,14 @@ struct ieee80211_tx_ampdu {
#define IEEE80211_AMPDU_RUNNING(tap) \
(((tap)->txa_flags & IEEE80211_AGGR_RUNNING) != 0)
+/*
+ * Return non-zero if AMPDU tx for the TID is running and we can do
+ * A-MSDU in A-MPDU
+ */
+#define IEEE80211_AMPDU_RUNNING_AMSDU(tap) \
+ (((tap)->txa_flags & (IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_AMSDU)) \
+ == (IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_AMSDU))
+
/* return non-zero if AMPDU tx for the TID was NACKed */
#define IEEE80211_AMPDU_NACKED(tap)\
(!! ((tap)->txa_flags & IEEE80211_AGGR_NAK))
@@ -160,7 +171,7 @@ struct ieee80211_rx_ampdu {
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];
+ struct mbufq rxa_mq[IEEE80211_AGGR_BAWMAX];
void *rxa_private;
uint64_t rxa_pad[3];
};
@@ -199,8 +210,8 @@ struct ieee80211_channel *ieee80211_ht_adjust_channel(struct ieee80211com *,
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_htprot_update(struct ieee80211vap *, int protmode);
+void ieee80211_ht_timeout(struct ieee80211vap *);
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 *,
@@ -230,5 +241,6 @@ void ieee80211_ampdu_rx_stop_ext(struct ieee80211_node *ni, int tid);
int ieee80211_ampdu_tx_request_ext(struct ieee80211_node *ni, int tid);
int ieee80211_ampdu_tx_request_active_ext(struct ieee80211_node *ni,
int tid, int status);
+void ieee80211_htinfo_notify(struct ieee80211vap *vap);
#endif /* _NET80211_IEEE80211_HT_H_ */
diff --git a/sys/net80211/ieee80211_input.h b/sys/net80211/ieee80211_input.h
index 2f3afc3b7e41..810dcbde7978 100644
--- a/sys/net80211/ieee80211_input.h
+++ b/sys/net80211/ieee80211_input.h
@@ -136,7 +136,8 @@ ishtinfooui(const uint8_t *frm)
static __inline int
ieee80211_check_rxseq_amsdu(const struct ieee80211_rx_stats *rxs)
{
-
+ if (rxs == NULL)
+ return 0;
return (!! (rxs->c_pktflags & IEEE80211_RX_F_AMSDU));
}
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 6ef5f9fb2b75..b5e79f2ef07f 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -106,7 +106,8 @@ ieee80211_ioctl_getkey(struct ieee80211vap *vap, struct ieee80211req *ireq)
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) {
+ /* XXX TODO: move priv check to ieee80211_freebsd.c */
+ if (priv_check(curthread, PRIV_NET80211_VAP_GETKEY) == 0) {
/* NB: only root can read key data */
ik.ik_keyrsc = wk->wk_keyrsc[IEEE80211_NONQOS_TID];
ik.ik_keytsc = wk->wk_keytsc;
@@ -784,6 +785,13 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
int error = 0;
switch (ireq->i_type) {
+ case IEEE80211_IOC_IC_NAME:
+ len = strlen(ic->ic_name) + 1;
+ if (len > ireq->i_len)
+ return (EINVAL);
+ ireq->i_len = len;
+ error = copyout(ic->ic_name, ireq->i_data, ireq->i_len);
+ break;
case IEEE80211_IOC_SSID:
switch (vap->iv_state) {
case IEEE80211_S_INIT:
@@ -815,7 +823,8 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
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) {
+ /* XXX TODO: move priv check to ieee80211_freebsd.c */
+ if (priv_check(curthread, PRIV_NET80211_VAP_GETKEY) == 0) {
bcopy(vap->iv_nw_keys[kid].wk_key, tmpkey, len);
} else {
bzero(tmpkey, len);
@@ -851,7 +860,7 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
ireq->i_val = vap->iv_rtsthreshold;
break;
case IEEE80211_IOC_PROTMODE:
- ireq->i_val = ic->ic_protmode;
+ ireq->i_val = vap->iv_protmode;
break;
case IEEE80211_IOC_TXPOWER:
/*
@@ -1097,7 +1106,7 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
error = ieee80211_ioctl_getdevcaps(ic, ireq);
break;
case IEEE80211_IOC_HTPROTMODE:
- ireq->i_val = ic->ic_htprotmode;
+ ireq->i_val = vap->iv_htprotmode;
break;
case IEEE80211_IOC_HTCONF:
if (vap->iv_flags_ht & IEEE80211_FHT_HT) {
@@ -1145,22 +1154,14 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
if (vap->iv_flags_ht & IEEE80211_FHT_LDPC_RX)
ireq->i_val |= 2;
break;
-
- /* VHT */
- case IEEE80211_IOC_VHTCONF:
+ case IEEE80211_IOC_UAPSD:
ireq->i_val = 0;
- if (vap->iv_flags_vht & IEEE80211_FVHT_VHT)
- ireq->i_val |= 1;
- if (vap->iv_flags_vht & IEEE80211_FVHT_USEVHT40)
- ireq->i_val |= 2;
- if (vap->iv_flags_vht & IEEE80211_FVHT_USEVHT80)
- ireq->i_val |= 4;
- if (vap->iv_flags_vht & IEEE80211_FVHT_USEVHT80P80)
- ireq->i_val |= 8;
- if (vap->iv_flags_vht & IEEE80211_FVHT_USEVHT160)
- ireq->i_val |= 16;
+ if (vap->iv_flags_ext & IEEE80211_FEXT_UAPSD)
+ ireq->i_val = 1;
+ break;
+ case IEEE80211_IOC_VHTCONF:
+ ireq->i_val = vap->iv_flags_vht & IEEE80211_FVHT_MASK;
break;
-
default:
error = ieee80211_ioctl_getdefault(vap, ireq);
break;
@@ -2907,11 +2908,13 @@ ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211r
case IEEE80211_IOC_PROTMODE:
if (ireq->i_val > IEEE80211_PROT_RTSCTS)
return EINVAL;
- ic->ic_protmode = (enum ieee80211_protmode)ireq->i_val;
+ vap->iv_protmode = (enum ieee80211_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;
+ /* driver callback for protection mode update */
+ ieee80211_vap_update_erp_protmode(vap);
break;
case IEEE80211_IOC_TXPOWER:
if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0)
@@ -3379,11 +3382,13 @@ ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211r
case IEEE80211_IOC_HTPROTMODE:
if (ireq->i_val > IEEE80211_PROT_RTSCTS)
return EINVAL;
- ic->ic_htprotmode = ireq->i_val ?
+ vap->iv_htprotmode = ireq->i_val ?
IEEE80211_PROT_RTSCTS : IEEE80211_PROT_NONE;
/* NB: if not operating in 11n this can wait */
if (isvapht(vap))
error = ERESTART;
+ /* Notify driver layer of HT protmode changes */
+ ieee80211_vap_update_ht_protmode(vap);
break;
case IEEE80211_IOC_STA_VLAN:
error = ieee80211_ioctl_setstavlan(vap, ireq);
@@ -3462,34 +3467,44 @@ ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211r
if (isvapht(vap))
error = ERESTART;
break;
+ case IEEE80211_IOC_UAPSD:
+ if ((vap->iv_caps & IEEE80211_C_UAPSD) == 0)
+ return EOPNOTSUPP;
+ if (ireq->i_val == 0)
+ vap->iv_flags_ext &= ~IEEE80211_FEXT_UAPSD;
+ else if (ireq->i_val == 1)
+ vap->iv_flags_ext |= IEEE80211_FEXT_UAPSD;
+ else
+ return EINVAL;
+ break;
/* VHT */
case IEEE80211_IOC_VHTCONF:
- if (ireq->i_val & 1)
+ if (ireq->i_val & IEEE80211_FVHT_VHT)
ieee80211_syncflag_vht(vap, IEEE80211_FVHT_VHT);
else
ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_VHT);
- if (ireq->i_val & 2)
+ if (ireq->i_val & IEEE80211_FVHT_USEVHT40)
ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT40);
else
ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT40);
- if (ireq->i_val & 4)
+ if (ireq->i_val & IEEE80211_FVHT_USEVHT80)
ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT80);
else
ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT80);
- if (ireq->i_val & 8)
- ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT80P80);
- else
- ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT80P80);
-
- if (ireq->i_val & 16)
+ if (ireq->i_val & IEEE80211_FVHT_USEVHT160)
ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT160);
else
ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT160);
+ if (ireq->i_val & IEEE80211_FVHT_USEVHT80P80)
+ ieee80211_syncflag_vht(vap, IEEE80211_FVHT_USEVHT80P80);
+ else
+ ieee80211_syncflag_vht(vap, -IEEE80211_FVHT_USEVHT80P80);
+
error = ENETRESET;
break;
@@ -3615,7 +3630,8 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
(struct ieee80211req *) data);
break;
case SIOCS80211:
- error = priv_check(curthread, PRIV_NET80211_MANAGE);
+ /* XXX TODO: move priv check to ieee80211_freebsd.c */
+ error = priv_check(curthread, PRIV_NET80211_VAP_MANAGE);
if (error == 0)
error = ieee80211_ioctl_set80211(vap, cmd,
(struct ieee80211req *) data);
@@ -3660,6 +3676,12 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
}
break;
+ case SIOCSIFLLADDR:
+ /* XXX TODO: move priv check to ieee80211_freebsd.c */
+ error = priv_check(curthread, PRIV_NET80211_VAP_SETMAC);
+ if (error == 0)
+ break;
+ /* Fallthrough */
default:
/*
* Pass unknown ioctls first to the driver, and if it
diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h
index 5021285bad1a..573661d5323d 100644
--- a/sys/net80211/ieee80211_ioctl.h
+++ b/sys/net80211/ieee80211_ioctl.h
@@ -710,6 +710,8 @@ struct ieee80211req {
#define IEEE80211_IOC_GREENFIELD 112 /* Greenfield (on, off) */
#define IEEE80211_IOC_STBC 113 /* STBC Tx/RX (on, off) */
#define IEEE80211_IOC_LDPC 114 /* LDPC Tx/RX (on, off) */
+#define IEEE80211_IOC_UAPSD 115 /* UAPSD (on, off) */
+#define IEEE80211_IOC_UAPSD_INFO 116 /* UAPSD (SP, per-AC enable) */
/* VHT */
#define IEEE80211_IOC_VHTCONF 130 /* VHT config (off, on; widths) */
@@ -741,6 +743,9 @@ struct ieee80211req {
#define IEEE80211_IOC_QUIET_OFFSET 207 /* Quiet Offset */
#define IEEE80211_IOC_QUIET_DUR 208 /* Quiet Duration */
#define IEEE80211_IOC_QUIET_COUNT 209 /* Quiet Count */
+
+#define IEEE80211_IOC_IC_NAME 210 /* HW device name. */
+
/*
* Parameters for controlling a scan requested with
* IEEE80211_IOC_SCAN_REQ.
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index a1415d73ec6d..9ee5b1b83cde 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -80,6 +80,7 @@ static int ieee80211_sta_join1(struct ieee80211_node *);
static struct ieee80211_node *node_alloc(struct ieee80211vap *,
const uint8_t [IEEE80211_ADDR_LEN]);
+static int node_init(struct ieee80211_node *);
static void node_cleanup(struct ieee80211_node *);
static void node_free(struct ieee80211_node *);
static void node_age(struct ieee80211_node *);
@@ -98,7 +99,7 @@ static void ieee80211_node_table_init(struct ieee80211com *ic,
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 *);
+static void ieee80211_vap_erp_timeout(struct ieee80211vap *);
MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state");
MALLOC_DEFINE(M_80211_NODE_IE, "80211nodeie", "802.11 node ie");
@@ -116,6 +117,7 @@ ieee80211_node_attach(struct ieee80211com *ic)
ieee80211_node_timeout, ic);
ic->ic_node_alloc = node_alloc;
+ ic->ic_node_init = node_init;
ic->ic_node_free = node_free;
ic->ic_node_cleanup = node_cleanup;
ic->ic_node_age = node_age;
@@ -446,7 +448,7 @@ ieee80211_reset_bss(struct ieee80211vap *vap)
ieee80211_node_table_reset(&ic->ic_sta, vap);
/* XXX multi-bss: wrong */
- ieee80211_reset_erp(ic);
+ ieee80211_vap_reset_erp(vap);
ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr);
KASSERT(ni != NULL, ("unable to setup initial BSS node"));
@@ -672,7 +674,6 @@ ieee80211_ibss_merge(struct ieee80211_node *ni)
{
#ifdef IEEE80211_DEBUG
struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
#endif
if (! ieee80211_ibss_merge_check(ni))
@@ -681,9 +682,9 @@ ieee80211_ibss_merge(struct ieee80211_node *ni)
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" : ""
+ vap->iv_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long",
+ vap->iv_flags&IEEE80211_F_SHSLOT ? "short" : "long",
+ vap->iv_flags&IEEE80211_F_USEPROT ? ", protection" : ""
);
return ieee80211_sta_join1(ieee80211_ref_node(ni));
}
@@ -881,7 +882,7 @@ ieee80211_sta_join1(struct ieee80211_node *selbs)
* the auto-select case; this should be redundant if the
* mode is locked.
*/
- ieee80211_reset_erp(ic);
+ ieee80211_vap_reset_erp(vap);
ieee80211_wme_initparams(vap);
if (vap->iv_opmode == IEEE80211_M_STA) {
@@ -1074,6 +1075,12 @@ node_alloc(struct ieee80211vap *vap, const uint8_t macaddr[IEEE80211_ADDR_LEN])
return ni;
}
+static int
+node_init(struct ieee80211_node *ni)
+{
+ return 0;
+}
+
/*
* Initialize an ie blob with the specified data. If previous
* data exists re-use the data block. As a side effect we clear
@@ -1414,6 +1421,15 @@ ieee80211_alloc_node(struct ieee80211_node_table *nt,
ni->ni_ic = ic;
IEEE80211_NODE_UNLOCK(nt);
+ /* handle failure; free node state */
+ if (ic->ic_node_init(ni) != 0) {
+ vap->iv_stats.is_rx_nodealloc++;
+ ieee80211_psq_cleanup(&ni->ni_psq);
+ ieee80211_ratectl_node_deinit(ni);
+ _ieee80211_free_node(ni);
+ return NULL;
+ }
+
IEEE80211_NOTE(vap, IEEE80211_MSG_INACT, ni,
"%s: inact_reload %u", __func__, ni->ni_inact_reload);
@@ -1456,6 +1472,16 @@ ieee80211_tmp_node(struct ieee80211vap *vap,
ieee80211_psq_init(&ni->ni_psq, "unknown");
ieee80211_ratectl_node_init(ni);
+
+ /* handle failure; free node state */
+ if (ic->ic_node_init(ni) != 0) {
+ vap->iv_stats.is_rx_nodealloc++;
+ ieee80211_psq_cleanup(&ni->ni_psq);
+ ieee80211_ratectl_node_deinit(ni);
+ _ieee80211_free_node(ni);
+ return NULL;
+ }
+
} else {
/* XXX msg */
vap->iv_stats.is_rx_nodealloc++;
@@ -2481,12 +2507,27 @@ ieee80211_drain(struct ieee80211com *ic)
}
/*
+ * Per-ieee80211vap inactivity timer callback.
+ */
+static void
+ieee80211_vap_timeout(struct ieee80211vap *vap)
+{
+
+ IEEE80211_LOCK_ASSERT(vap->iv_ic);
+
+ ieee80211_vap_erp_timeout(vap);
+ ieee80211_ht_timeout(vap);
+ ieee80211_vht_timeout(vap);
+}
+
+/*
* Per-ieee80211com inactivity timer callback.
*/
void
ieee80211_node_timeout(void *arg)
{
struct ieee80211com *ic = arg;
+ struct ieee80211vap *vap;
/*
* Defer timeout processing if a channel switch is pending.
@@ -2503,9 +2544,8 @@ ieee80211_node_timeout(void *arg)
ieee80211_ageq_age(&ic->ic_stageq, IEEE80211_INACT_WAIT);
IEEE80211_LOCK(ic);
- ieee80211_erp_timeout(ic);
- ieee80211_ht_timeout(ic);
- ieee80211_vht_timeout(ic);
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
+ ieee80211_vap_timeout(vap);
IEEE80211_UNLOCK(ic);
}
callout_reset(&ic->ic_inact, IEEE80211_INACT_WAIT*hz,
@@ -2618,7 +2658,12 @@ ieee80211_dump_nodes(struct ieee80211_node_table *nt)
(ieee80211_iter_func *) ieee80211_dump_node, nt);
}
-static void
+/*
+ * Iterate over the VAPs and update their ERP beacon IEs.
+ *
+ * Note this must be called from the deferred ERP update task paths.
+ */
+void
ieee80211_notify_erp_locked(struct ieee80211com *ic)
{
struct ieee80211vap *vap;
@@ -2630,14 +2675,6 @@ ieee80211_notify_erp_locked(struct ieee80211com *ic)
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.
*/
@@ -2645,6 +2682,7 @@ static void
ieee80211_node_join_11g(struct ieee80211_node *ni)
{
struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211vap *vap = ni->ni_vap;
IEEE80211_LOCK_ASSERT(ic);
@@ -2656,18 +2694,20 @@ ieee80211_node_join_11g(struct ieee80211_node *ni)
* next beacon transmission (per sec. 7.3.1.4 of 11g).
*/
if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) {
- ic->ic_longslotsta++;
+ vap->iv_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 */
+ vap->iv_longslotsta);
+ /*
+ * XXX TODO: this may need all VAPs checked!
+ */
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);
+ ieee80211_vap_set_shortslottime(vap, 0);
}
}
/*
@@ -2676,10 +2716,10 @@ ieee80211_node_join_11g(struct ieee80211_node *ni)
* if configured.
*/
if (!ieee80211_iserp_rateset(&ni->ni_rates)) {
- ic->ic_nonerpsta++;
+ vap->iv_nonerpsta++;
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ASSOC, ni,
"station is !ERP, %d non-ERP stations associated",
- ic->ic_nonerpsta);
+ vap->iv_nonerpsta);
/*
* If station does not support short preamble
* then we must enable use of Barker preamble.
@@ -2687,20 +2727,21 @@ ieee80211_node_join_11g(struct ieee80211_node *ni)
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;
+ vap->iv_flags |= IEEE80211_F_USEBARKER;
+ vap->iv_flags &= ~IEEE80211_F_SHPREAMBLE;
+ ieee80211_vap_update_preamble(vap);
}
/*
* 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) {
+ if (vap->iv_protmode != IEEE80211_PROT_NONE &&
+ vap->iv_nonerpsta == 1 &&
+ (vap->iv_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);
+ vap->iv_flags |= IEEE80211_F_USEPROT;
+ ieee80211_vap_update_erp_protmode(vap);
}
} else
ni->ni_flags |= IEEE80211_NODE_ERP;
@@ -2735,7 +2776,6 @@ ieee80211_node_join(struct ieee80211_node *ni, int resp)
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);
@@ -2754,16 +2794,17 @@ ieee80211_node_join(struct ieee80211_node *ni, int resp)
* XXX VHT - should log VHT channel width, etc
*/
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",
+ "station associated at aid %d: %s preamble, %s slot time%s%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" : "",
+ vap->iv_flags & IEEE80211_F_SHPREAMBLE ? "short" : "long",
+ vap->iv_flags & IEEE80211_F_SHSLOT ? "short" : "long",
+ vap->iv_flags & IEEE80211_F_USEPROT ? ", protection" : "",
ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "",
/* XXX update for VHT string */
ni->ni_flags & IEEE80211_NODE_HT ?
(ni->ni_chw == 40 ? ", HT40" : ", HT20") : "",
ni->ni_flags & IEEE80211_NODE_AMPDU ? " (+AMPDU)" : "",
+ ni->ni_flags & IEEE80211_NODE_AMSDU ? " (+AMSDU)" : "",
ni->ni_flags & IEEE80211_NODE_MIMO_RTS ? " (+SMPS-DYN)" :
ni->ni_flags & IEEE80211_NODE_MIMO_PS ? " (+SMPS)" : "",
ni->ni_flags & IEEE80211_NODE_RIFS ? " (+RIFS)" : "",
@@ -2787,20 +2828,23 @@ ieee80211_node_join(struct ieee80211_node *ni, int resp)
}
static void
-disable_protection(struct ieee80211com *ic)
+disable_protection(struct ieee80211vap *vap)
{
- 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));
+ struct ieee80211com *ic = vap->iv_ic;
- ic->ic_flags &= ~IEEE80211_F_USEPROT;
+ KASSERT(vap->iv_nonerpsta == 0 &&
+ (vap->iv_flags_ext & IEEE80211_FEXT_NONERP_PR) == 0,
+ ("%d non ERP stations, flags 0x%x", vap->iv_nonerpsta,
+ vap->iv_flags_ext));
+
+ vap->iv_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;
+ vap->iv_flags |= IEEE80211_F_SHPREAMBLE;
+ vap->iv_flags &= ~IEEE80211_F_USEBARKER;
}
- ieee80211_notify_erp_locked(ic);
+ ieee80211_vap_update_erp_protmode(vap);
+ ieee80211_vap_update_preamble(vap);
}
/*
@@ -2810,6 +2854,7 @@ static void
ieee80211_node_leave_11g(struct ieee80211_node *ni)
{
struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211vap *vap = ni->ni_vap;
IEEE80211_LOCK_ASSERT(ic);
@@ -2821,13 +2866,16 @@ ieee80211_node_leave_11g(struct ieee80211_node *ni)
* 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--;
+ KASSERT(vap->iv_longslotsta > 0,
+ ("bogus long slot station count %d", vap->iv_longslotsta));
+ vap->iv_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) {
+ vap->iv_longslotsta);
+ /*
+ * XXX TODO: this may need all VAPs checked!
+ */
+ if (vap->iv_longslotsta == 0) {
/*
* Re-enable use of short slot time if supported
* and not operating in IBSS mode (per spec).
@@ -2838,7 +2886,7 @@ ieee80211_node_leave_11g(struct ieee80211_node *ni)
IEEE80211_MSG_ASSOC,
"%s: re-enable use of short slot time\n",
__func__);
- ieee80211_set_shortslottime(ic, 1);
+ ieee80211_vap_set_shortslottime(vap, 1);
}
}
}
@@ -2846,18 +2894,18 @@ ieee80211_node_leave_11g(struct ieee80211_node *ni)
* 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--;
+ KASSERT(vap->iv_nonerpsta > 0,
+ ("bogus non-ERP station count %d", vap->iv_nonerpsta));
+ vap->iv_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 station leaves, count now %d%s", vap->iv_nonerpsta,
+ (vap->iv_flags_ext & IEEE80211_FEXT_NONERP_PR) ?
" (non-ERP sta present)" : "");
- if (ic->ic_nonerpsta == 0 &&
- (ic->ic_flags_ext & IEEE80211_FEXT_NONERP_PR) == 0) {
+ if (vap->iv_nonerpsta == 0 &&
+ (vap->iv_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);
+ disable_protection(vap);
}
}
}
@@ -2871,20 +2919,18 @@ ieee80211_node_leave_11g(struct ieee80211_node *ni)
* condition.
*/
static void
-ieee80211_erp_timeout(struct ieee80211com *ic)
+ieee80211_vap_erp_timeout(struct ieee80211vap *vap)
{
- IEEE80211_LOCK_ASSERT(ic);
+ IEEE80211_LOCK_ASSERT(vap->iv_ic);
- if ((ic->ic_flags_ext & IEEE80211_FEXT_NONERP_PR) &&
- ieee80211_time_after(ticks, ic->ic_lastnonerp + IEEE80211_NONERP_PRESENT_AGE)) {
-#if 0
- IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
+ if ((vap->iv_flags_ext & IEEE80211_FEXT_NONERP_PR) &&
+ ieee80211_time_after(ticks, vap->iv_lastnonerp + IEEE80211_NONERP_PRESENT_AGE)) {
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
"%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);
+ vap->iv_flags_ext &= ~IEEE80211_FEXT_NONERP_PR;
+ if (vap->iv_nonerpsta == 0)
+ disable_protection(vap);
}
}
@@ -2923,7 +2969,6 @@ ieee80211_node_leave(struct ieee80211_node *ni)
IEEE80211_LOCK(ic);
IEEE80211_AID_CLR(vap, ni->ni_associd);
vap->iv_sta_assoc--;
- ic->ic_sta_assoc--;
if (IEEE80211_IS_CHAN_VHT(ic->ic_bsschan))
ieee80211_vht_node_leave(ni);
diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h
index 3e21cdda2108..ff826d30ca72 100644
--- a/sys/net80211/ieee80211_node.h
+++ b/sys/net80211/ieee80211_node.h
@@ -146,6 +146,7 @@ struct ieee80211_node {
#define IEEE80211_NODE_AMSDU_TX 0x080000 /* AMSDU tx enabled */
#define IEEE80211_NODE_VHT 0x100000 /* VHT enabled */
#define IEEE80211_NODE_LDPC 0x200000 /* LDPC enabled */
+#define IEEE80211_NODE_UAPSD 0x400000 /* U-APSD power save enabled */
uint16_t ni_associd; /* association ID */
uint16_t ni_vlan; /* vlan tag */
uint16_t ni_txpower; /* current transmit power */
@@ -256,6 +257,9 @@ struct ieee80211_node {
uint32_t ni_quiet_ie_set; /* Quiet time IE was seen */
struct ieee80211_quiet_ie ni_quiet_ie; /* last seen quiet IE */
+ /* U-APSD */
+ uint8_t ni_uapsd; /* U-APSD per-node flags matching WMM STA QoS Info field */
+
uint64_t ni_spare[3];
};
MALLOC_DECLARE(M_80211_NODE);
@@ -475,7 +479,7 @@ int ieee80211_iterate_nodes_vap(struct ieee80211_node_table *,
void ieee80211_iterate_nodes(struct ieee80211_node_table *,
ieee80211_iter_func *, void *);
-void ieee80211_notify_erp(struct ieee80211com *);
+void ieee80211_notify_erp_locked(struct ieee80211com *);
void ieee80211_dump_node(struct ieee80211_node_table *,
struct ieee80211_node *);
void ieee80211_dump_nodes(struct ieee80211_node_table *);
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 5187529029cb..dc28f0f41753 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -125,6 +125,11 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = vap->iv_ifp;
int mcast;
+ int do_ampdu = 0;
+ int do_amsdu = 0;
+ int do_ampdu_amsdu = 0;
+ int no_ampdu = 1; /* Will be set to 0 if ampdu is active */
+ int do_ff = 0;
if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
(m->m_flags & M_PWR_SAV) == 0) {
@@ -168,6 +173,27 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
BPF_MTAP(ifp, m); /* 802.3 tx */
+
+ /*
+ * Figure out if we can do A-MPDU, A-MSDU or FF.
+ *
+ * A-MPDU depends upon vap/node config.
+ * A-MSDU depends upon vap/node config.
+ * FF depends upon vap config, IE and whether
+ * it's 11abg (and not 11n/11ac/etc.)
+ *
+ * Note that these flags indiciate whether we can do
+ * it at all, rather than the situation (eg traffic type.)
+ */
+ do_ampdu = ((ni->ni_flags & IEEE80211_NODE_AMPDU_TX) &&
+ (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_TX));
+ do_amsdu = ((ni->ni_flags & IEEE80211_NODE_AMSDU_TX) &&
+ (vap->iv_flags_ht & IEEE80211_FHT_AMSDU_TX));
+ do_ff =
+ ((ni->ni_flags & IEEE80211_NODE_HT) == 0) &&
+ ((ni->ni_flags & IEEE80211_NODE_VHT) == 0) &&
+ (IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF));
+
/*
* Check if A-MPDU tx aggregation is setup or if we
* should try to enable it. The sta must be associated
@@ -185,8 +211,7 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
* frames will always have sequence numbers allocated from the NON_QOS
* TID.
*/
- if ((ni->ni_flags & IEEE80211_NODE_AMPDU_TX) &&
- (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_TX)) {
+ if (do_ampdu) {
if ((m->m_flags & M_EAPOL) == 0 && (! mcast)) {
int tid = WME_AC_TO_TID(M_WME_GETAC(m));
struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid];
@@ -207,6 +232,23 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
ieee80211_ampdu_request(ni, tap);
/* XXX hold frame for reply? */
}
+ /*
+ * Now update the no-ampdu flag. A-MPDU may have been
+ * started or administratively disabled above; so now we
+ * know whether we're running yet or not.
+ *
+ * This will let us know whether we should be doing A-MSDU
+ * at this point. We only do A-MSDU if we're either not
+ * doing A-MPDU, or A-MPDU is NACKed, or A-MPDU + A-MSDU
+ * is available.
+ *
+ * Whilst here, update the amsdu-ampdu flag. The above may
+ * have also set or cleared the amsdu-in-ampdu txa_flags
+ * combination so we can correctly do A-MPDU + A-MSDU.
+ */
+ no_ampdu = (! IEEE80211_AMPDU_RUNNING(tap)
+ || (IEEE80211_AMPDU_NACKED(tap)));
+ do_ampdu_amsdu = IEEE80211_AMPDU_RUNNING_AMSDU(tap);
}
}
@@ -221,15 +263,11 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
* to really need to. For A-MSDU we'd have to set the
* A-MSDU QoS bit in the wifi header, so we just plain
* can't do it.
- *
- * Strictly speaking, we could actually /do/ A-MSDU / FF
- * with A-MPDU together which for certain circumstances
- * is beneficial (eg A-MSDU of TCK ACKs.) However,
- * I'll ignore that for now so existing behaviour is maintained.
- * Later on it would be good to make "amsdu + ampdu" configurable.
*/
- else if (__predict_true((vap->iv_caps & IEEE80211_C_8023ENCAP) == 0)) {
- if ((! mcast) && ieee80211_amsdu_tx_ok(ni)) {
+ if (__predict_true((vap->iv_caps & IEEE80211_C_8023ENCAP) == 0)) {
+ if ((! mcast) &&
+ (do_ampdu_amsdu || (no_ampdu && do_amsdu)) &&
+ ieee80211_amsdu_tx_ok(ni)) {
m = ieee80211_amsdu_check(ni, m);
if (m == NULL) {
/* NB: any ni ref held on stageq */
@@ -238,8 +276,7 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
__func__);
return (0);
}
- } else if ((! mcast) && IEEE80211_ATH_CAP(vap, ni,
- IEEE80211_NODE_FF)) {
+ } else if ((! mcast) && do_ff) {
m = ieee80211_ff_check(ni, m);
if (m == NULL) {
/* NB: any ni ref held on stageq */
@@ -1469,10 +1506,27 @@ ieee80211_encap(struct ieee80211vap *vap, struct ieee80211_node *ni,
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)))
+ (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY))) {
key = ieee80211_crypto_getucastkey(vap, ni);
- else
+ } else if ((vap->iv_opmode == IEEE80211_M_WDS) &&
+ (! (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY))) {
+ /*
+ * Use ucastkey for DWDS transmit nodes, multicast
+ * or otherwise.
+ *
+ * This is required to ensure that multicast frames
+ * from a DWDS AP to a DWDS STA is encrypted with
+ * a key that can actually work.
+ *
+ * There's no default key for multicast traffic
+ * on a DWDS WDS VAP node (note NOT the DWDS enabled
+ * AP VAP, the dynamically created per-STA WDS node)
+ * so encap fails and transmit fails.
+ */
+ 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,
@@ -2044,15 +2098,34 @@ ieee80211_add_ssid(uint8_t *frm, const uint8_t *ssid, u_int len)
* Add an erp element to a frame.
*/
static uint8_t *
-ieee80211_add_erp(uint8_t *frm, struct ieee80211com *ic)
+ieee80211_add_erp(uint8_t *frm, struct ieee80211vap *vap)
{
+ struct ieee80211com *ic = vap->iv_ic;
uint8_t erp;
*frm++ = IEEE80211_ELEMID_ERP;
*frm++ = 1;
erp = 0;
- if (ic->ic_nonerpsta != 0)
+
+ /*
+ * TODO: This uses the global flags for now because
+ * the per-VAP flags are fine for per-VAP, but don't
+ * take into account which VAPs share the same channel
+ * and which are on different channels.
+ *
+ * ERP and HT/VHT protection mode is a function of
+ * how many stations are on a channel, not specifically
+ * the VAP or global. But, until we grow that status,
+ * the global flag will have to do.
+ */
+ if (ic->ic_flags_ext & IEEE80211_FEXT_NONERP_PR)
erp |= IEEE80211_ERP_NON_ERP_PRESENT;
+
+ /*
+ * TODO: same as above; these should be based not
+ * on the vap or ic flags, but instead on a combination
+ * of per-VAP and channels.
+ */
if (ic->ic_flags & IEEE80211_F_USEPROT)
erp |= IEEE80211_ERP_USE_PROTECTION;
if (ic->ic_flags & IEEE80211_F_USEBARKER)
@@ -2100,26 +2173,48 @@ add_ie(uint8_t *frm, const uint8_t *ie)
* Add a WME information element to a frame.
*/
uint8_t *
-ieee80211_add_wme_info(uint8_t *frm, struct ieee80211_wme_state *wme)
+ieee80211_add_wme_info(uint8_t *frm, struct ieee80211_wme_state *wme,
+ struct ieee80211_node *ni)
{
- 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);
+ static const uint8_t oui[4] = { WME_OUI_BYTES, WME_OUI_TYPE };
+ struct ieee80211vap *vap = ni->ni_vap;
+
+ *frm++ = IEEE80211_ELEMID_VENDOR;
+ *frm++ = sizeof(struct ieee80211_wme_info) - 2;
+ memcpy(frm, oui, sizeof(oui));
+ frm += sizeof(oui);
+ *frm++ = WME_INFO_OUI_SUBTYPE;
+ *frm++ = WME_VERSION;
+
+ /* QoS info field depends upon operating mode */
+ switch (vap->iv_opmode) {
+ case IEEE80211_M_HOSTAP:
+ *frm = wme->wme_bssChanParams.cap_info;
+ if (vap->iv_flags_ext & IEEE80211_FEXT_UAPSD)
+ *frm |= WME_CAPINFO_UAPSD_EN;
+ frm++;
+ break;
+ case IEEE80211_M_STA:
+ /*
+ * NB: UAPSD drivers must set this up in their
+ * VAP creation method.
+ */
+ *frm++ = vap->iv_uapsdinfo;
+ break;
+ default:
+ *frm++ = 0;
+ break;
+ }
+
+ return frm;
}
/*
* Add a WME parameters element to a frame.
*/
static uint8_t *
-ieee80211_add_wme_param(uint8_t *frm, struct ieee80211_wme_state *wme)
+ieee80211_add_wme_param(uint8_t *frm, struct ieee80211_wme_state *wme,
+ int uapsd_enable)
{
#define SM(_v, _f) (((_v) << _f##_S) & _f)
#define ADDSHORT(frm, v) do { \
@@ -2139,8 +2234,12 @@ ieee80211_add_wme_param(uint8_t *frm, struct ieee80211_wme_state *wme)
memcpy(frm, &param, sizeof(param));
frm += __offsetof(struct ieee80211_wme_info, wme_info);
- *frm++ = wme->wme_bssChanParams.cap_info; /* AC info */
+ *frm = wme->wme_bssChanParams.cap_info; /* AC info */
+ if (uapsd_enable)
+ *frm |= WME_CAPINFO_UAPSD_EN;
+ frm++;
*frm++ = 0; /* reserved field */
+ /* XXX TODO - U-APSD bits - SP, flags below */
for (i = 0; i < WME_NUM_AC; i++) {
const struct wmeParams *ac =
&wme->wme_bssChanParams.cap_wmeParams[i];
@@ -2487,7 +2586,6 @@ ieee80211_send_probereq(struct ieee80211_node *ni,
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"));
@@ -2500,10 +2598,10 @@ ieee80211_getcapinfo(struct ieee80211vap *vap, struct ieee80211_channel *chan)
capinfo = 0;
if (vap->iv_flags & IEEE80211_F_PRIVACY)
capinfo |= IEEE80211_CAPINFO_PRIVACY;
- if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
+ if ((vap->iv_flags & IEEE80211_F_SHPREAMBLE) &&
IEEE80211_IS_CHAN_2GHZ(chan))
capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
- if (ic->ic_flags & IEEE80211_F_SHSLOT)
+ if (vap->iv_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;
@@ -2679,7 +2777,7 @@ ieee80211_send_mgmt(struct ieee80211_node *ni, int type, int arg)
* NB: Some 11a AP's reject the request when
* short preamble is set.
*/
- if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
+ if ((vap->iv_flags & IEEE80211_F_SHPREAMBLE) &&
IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) &&
@@ -2733,7 +2831,7 @@ ieee80211_send_mgmt(struct ieee80211_node *ni, int type, int arg)
frm = ieee80211_add_wpa(frm, vap);
if ((ic->ic_flags & IEEE80211_F_WME) &&
ni->ni_ies.wme_ie != NULL)
- frm = ieee80211_add_wme_info(frm, &ic->ic_wme);
+ frm = ieee80211_add_wme_info(frm, &ic->ic_wme, ni);
/*
* Same deal - only send HT info if we're on an 11n
@@ -2825,7 +2923,8 @@ ieee80211_send_mgmt(struct ieee80211_node *ni, int type, int arg)
}
if ((vap->iv_flags & IEEE80211_F_WME) &&
ni->ni_ies.wme_ie != NULL)
- frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
+ frm = ieee80211_add_wme_param(frm, &ic->ic_wme,
+ !! (vap->iv_flags_ext & IEEE80211_FEXT_UAPSD));
if ((ni->ni_flags & HTFLAGS) == HTFLAGS) {
frm = ieee80211_add_htcap_vendor(frm, ni);
frm = ieee80211_add_htinfo_vendor(frm, ni);
@@ -3015,7 +3114,7 @@ ieee80211_alloc_proberesp(struct ieee80211_node *bss, int legacy)
}
}
if (IEEE80211_IS_CHAN_ANYG(bss->ni_chan))
- frm = ieee80211_add_erp(frm, ic);
+ frm = ieee80211_add_erp(frm, vap);
frm = ieee80211_add_xrates(frm, rs);
frm = ieee80211_add_rsn(frm, vap);
/*
@@ -3036,7 +3135,8 @@ ieee80211_alloc_proberesp(struct ieee80211_node *bss, int legacy)
}
frm = ieee80211_add_wpa(frm, vap);
if (vap->iv_flags & IEEE80211_F_WME)
- frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
+ frm = ieee80211_add_wme_param(frm, &ic->ic_wme,
+ !! (vap->iv_flags_ext & IEEE80211_FEXT_UAPSD));
if (IEEE80211_IS_CHAN_HT(bss->ni_chan) &&
(vap->iv_flags_ht & IEEE80211_FHT_HTCOMPAT) &&
legacy != IEEE80211_SEND_LEGACY_11B) {
@@ -3184,6 +3284,7 @@ ieee80211_alloc_prot(struct ieee80211_node *ni, const struct mbuf *m,
uint8_t rate, int prot)
{
struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211vap *vap = ni->ni_vap;
const struct ieee80211_frame *wh;
struct mbuf *mprot;
uint16_t dur;
@@ -3195,7 +3296,7 @@ ieee80211_alloc_prot(struct ieee80211_node *ni, const struct mbuf *m,
wh = mtod(m, const struct ieee80211_frame *);
pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
- isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
+ isshort = (vap->iv_flags & IEEE80211_F_SHPREAMBLE) != 0;
dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort)
+ ieee80211_ack_duration(ic->ic_rt, rate, isshort);
@@ -3204,7 +3305,7 @@ ieee80211_alloc_prot(struct ieee80211_node *ni, const struct mbuf *m,
dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort);
mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur);
} else
- mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
+ mprot = ieee80211_alloc_cts(ic, vap->iv_myaddr, dur);
return (mprot);
}
@@ -3412,7 +3513,7 @@ ieee80211_beacon_construct(struct mbuf *m, uint8_t *frm,
if (IEEE80211_IS_CHAN_ANYG(ni->ni_chan)) {
bo->bo_erp = frm;
- frm = ieee80211_add_erp(frm, ic);
+ frm = ieee80211_add_erp(frm, vap);
}
frm = ieee80211_add_xrates(frm, rs);
frm = ieee80211_add_rsn(frm, vap);
@@ -3434,7 +3535,8 @@ ieee80211_beacon_construct(struct mbuf *m, uint8_t *frm,
frm = ieee80211_add_wpa(frm, vap);
if (vap->iv_flags & IEEE80211_F_WME) {
bo->bo_wme = frm;
- frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
+ frm = ieee80211_add_wme_param(frm, &ic->ic_wme,
+ !! (vap->iv_flags_ext & IEEE80211_FEXT_UAPSD));
}
if (IEEE80211_IS_CHAN_HT(ni->ni_chan) &&
(vap->iv_flags_ht & IEEE80211_FHT_HTCOMPAT)) {
@@ -3726,7 +3828,8 @@ ieee80211_beacon_update(struct ieee80211_node *ni, struct mbuf *m, int mcast)
wme->wme_hipri_switch_hysteresis;
}
if (isset(bo->bo_flags, IEEE80211_BEACON_WME)) {
- (void) ieee80211_add_wme_param(bo->bo_wme, wme);
+ (void) ieee80211_add_wme_param(bo->bo_wme, wme,
+ vap->iv_flags_ext & IEEE80211_FEXT_UAPSD);
clrbit(bo->bo_flags, IEEE80211_BEACON_WME);
}
}
@@ -3895,7 +3998,7 @@ ieee80211_beacon_update(struct ieee80211_node *ni, struct mbuf *m, int mcast)
/*
* ERP element needs updating.
*/
- (void) ieee80211_add_erp(bo->bo_erp, ic);
+ (void) ieee80211_add_erp(bo->bo_erp, vap);
clrbit(bo->bo_flags, IEEE80211_BEACON_ERP);
}
#ifdef IEEE80211_SUPPORT_SUPERG
diff --git a/sys/net80211/ieee80211_phy.h b/sys/net80211/ieee80211_phy.h
index 1539e8793353..45ff6c6b6b03 100644
--- a/sys/net80211/ieee80211_phy.h
+++ b/sys/net80211/ieee80211_phy.h
@@ -55,11 +55,26 @@
#define IEEE80211_DUR_SHSLOT 9 /* ERP short slottime */
#define IEEE80211_DUR_OFDM_SLOT 9 /* OFDM slottime */
+/*
+ * For drivers that don't implement per-VAP slot time
+ * (ie, they rely on net80211 figuring out the union
+ * between VAPs to program a single radio) - return
+ * the current radio configured slot time.
+ */
#define IEEE80211_GET_SLOTTIME(ic) \
((ic->ic_flags & IEEE80211_F_SHSLOT) ? \
IEEE80211_DUR_SHSLOT : IEEE80211_DUR_SLOT)
/*
+ * For drivers that implement per-VAP slot time; look
+ * at the per-VAP flags to determine whether this VAP
+ * is in short or long slot time.
+ */
+#define IEEE80211_VAP_GET_SLOTTIME(vap) \
+ ((vap->iv_flags & IEEE80211_F_SHSLOT) ? \
+ IEEE80211_DUR_SHSLOT : IEEE80211_DUR_SLOT)
+
+/*
* DIFS (microseconds).
*/
#define IEEE80211_DUR_DIFS(sifs, slot) ((sifs) + 2 * (slot))
diff --git a/sys/net80211/ieee80211_power.c b/sys/net80211/ieee80211_power.c
index f38a5148fef2..75d2dbea92ce 100644
--- a/sys/net80211/ieee80211_power.c
+++ b/sys/net80211/ieee80211_power.c
@@ -335,7 +335,7 @@ ieee80211_pwrsave(struct ieee80211_node *ni, struct mbuf *m)
if (psq->psq_len >= psq->psq_maxlen) {
psq->psq_drops++;
IEEE80211_PSQ_UNLOCK(psq);
- IEEE80211_NOTE(vap, IEEE80211_MSG_ANY, ni,
+ IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
"pwr save q overflow, drops %d (size %d)",
psq->psq_drops, psq->psq_len);
#ifdef IEEE80211_DEBUG
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index c70a159adad0..2f98deea88d9 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -244,7 +244,11 @@ static void update_promisc(void *, int);
static void update_channel(void *, int);
static void update_chw(void *, int);
static void vap_update_wme(void *, int);
+static void vap_update_slot(void *, int);
static void restart_vaps(void *, int);
+static void vap_update_erp_protmode(void *, int);
+static void vap_update_preamble(void *, int);
+static void vap_update_ht_protmode(void *, int);
static void ieee80211_newstate_cb(void *, int);
static int
@@ -274,7 +278,7 @@ ieee80211_proto_attach(struct ieee80211com *ic)
max_hdr = max_linkhdr + max_protohdr;
max_datalen = MHLEN - max_hdr;
}
- ic->ic_protmode = IEEE80211_PROT_CTSONLY;
+ //ic->ic_protmode = IEEE80211_PROT_CTSONLY;
TASK_INIT(&ic->ic_parent_task, 0, parent_updown, ic);
TASK_INIT(&ic->ic_mcast_task, 0, update_mcast, ic);
@@ -340,6 +344,10 @@ ieee80211_proto_vattach(struct ieee80211vap *vap)
TASK_INIT(&vap->iv_nstate_task, 0, ieee80211_newstate_cb, vap);
TASK_INIT(&vap->iv_swbmiss_task, 0, beacon_swmiss, vap);
TASK_INIT(&vap->iv_wme_task, 0, vap_update_wme, vap);
+ TASK_INIT(&vap->iv_slot_task, 0, vap_update_slot, vap);
+ TASK_INIT(&vap->iv_erp_protmode_task, 0, vap_update_erp_protmode, vap);
+ TASK_INIT(&vap->iv_ht_protmode_task, 0, vap_update_ht_protmode, vap);
+ TASK_INIT(&vap->iv_preamble_task, 0, vap_update_preamble, vap);
/*
* Install default tx rate handling: no fixed rate, lowest
* supported rate for mgmt and multicast frames. Default
@@ -386,6 +394,7 @@ ieee80211_proto_vattach(struct ieee80211vap *vap)
vap->iv_update_beacon = null_update_beacon;
vap->iv_deliver_data = ieee80211_deliver_data;
+ vap->iv_protmode = IEEE80211_PROT_CTSONLY;
/* attach support for operating mode */
ic->ic_vattach[vap->iv_opmode](vap);
@@ -750,24 +759,57 @@ ieee80211_fix_rate(struct ieee80211_node *ni,
/*
* Reset 11g-related state.
+ *
+ * This is for per-VAP ERP/11g state.
+ *
+ * Eventually everything in ieee80211_reset_erp() will be
+ * per-VAP and in here.
*/
void
-ieee80211_reset_erp(struct ieee80211com *ic)
+ieee80211_vap_reset_erp(struct ieee80211vap *vap)
{
- ic->ic_flags &= ~IEEE80211_F_USEPROT;
- ic->ic_nonerpsta = 0;
- ic->ic_longslotsta = 0;
+ struct ieee80211com *ic = vap->iv_ic;
+
+ vap->iv_nonerpsta = 0;
+ vap->iv_longslotsta = 0;
+
+ vap->iv_flags &= ~IEEE80211_F_USEPROT;
+ /*
+ * Set short preamble and ERP barker-preamble flags.
+ */
+ if (IEEE80211_IS_CHAN_A(ic->ic_curchan) ||
+ (vap->iv_caps & IEEE80211_C_SHPREAMBLE)) {
+ vap->iv_flags |= IEEE80211_F_SHPREAMBLE;
+ vap->iv_flags &= ~IEEE80211_F_USEBARKER;
+ } else {
+ vap->iv_flags &= ~IEEE80211_F_SHPREAMBLE;
+ vap->iv_flags |= IEEE80211_F_USEBARKER;
+ }
+
/*
* 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_vap_set_shortslottime(vap,
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 &&
+ vap->iv_opmode == IEEE80211_M_HOSTAP &&
(ic->ic_caps & IEEE80211_C_SHSLOT)));
+}
+
+/*
+ * Reset 11g-related state.
+ *
+ * Note this resets the global state and a caller should schedule
+ * a re-check of all the VAPs after setup to update said state.
+ */
+void
+ieee80211_reset_erp(struct ieee80211com *ic)
+{
+#if 0
+ ic->ic_flags &= ~IEEE80211_F_USEPROT;
/*
* Set short preamble and ERP barker-preamble flags.
*/
@@ -779,21 +821,450 @@ ieee80211_reset_erp(struct ieee80211com *ic)
ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
ic->ic_flags |= IEEE80211_F_USEBARKER;
}
+#endif
+ /* XXX TODO: schedule a new per-VAP ERP calculation */
+}
+
+/*
+ * Deferred slot time update.
+ *
+ * For per-VAP slot time configuration, call the VAP
+ * method if the VAP requires it. Otherwise, just call the
+ * older global method.
+ *
+ * If the per-VAP method is called then it's expected that
+ * the driver/firmware will take care of turning the per-VAP
+ * flags into slot time configuration.
+ *
+ * If the per-VAP method is not called then the global flags will be
+ * flipped into sync with the VAPs; ic_flags IEEE80211_F_SHSLOT will
+ * be set only if all of the vaps will have it set.
+ *
+ * Look at the comments for vap_update_erp_protmode() for more
+ * background; this assumes all VAPs are on the same channel.
+ */
+static void
+vap_update_slot(void *arg, int npending)
+{
+ struct ieee80211vap *vap = arg;
+ struct ieee80211com *ic = vap->iv_ic;
+ struct ieee80211vap *iv;
+ int num_shslot = 0, num_lgslot = 0;
+
+ /*
+ * Per-VAP path - we've already had the flags updated;
+ * so just notify the driver and move on.
+ */
+ if (vap->iv_updateslot != NULL) {
+ vap->iv_updateslot(vap);
+ return;
+ }
+
+ /*
+ * Iterate over all of the VAP flags to update the
+ * global flag.
+ *
+ * If all vaps have short slot enabled then flip on
+ * short slot. If any vap has it disabled then
+ * we leave it globally disabled. This should provide
+ * correct behaviour in a multi-BSS scenario where
+ * at least one VAP has short slot disabled for some
+ * reason.
+ */
+ IEEE80211_LOCK(ic);
+ TAILQ_FOREACH(iv, &ic->ic_vaps, iv_next) {
+ if (iv->iv_flags & IEEE80211_F_SHSLOT)
+ num_shslot++;
+ else
+ num_lgslot++;
+ }
+
+ /*
+ * It looks backwards but - if the number of short slot VAPs
+ * is zero then we're not short slot. Else, we have one
+ * or more short slot VAPs and we're checking to see if ANY
+ * of them have short slot disabled.
+ */
+ if (num_shslot == 0)
+ ic->ic_flags &= ~IEEE80211_F_SHSLOT;
+ else if (num_lgslot == 0)
+ ic->ic_flags |= IEEE80211_F_SHSLOT;
+ IEEE80211_UNLOCK(ic);
+
+ /*
+ * Call the driver with our new global slot time flags.
+ */
+ if (ic->ic_updateslot != NULL)
+ ic->ic_updateslot(ic);
+}
+
+/*
+ * Deferred ERP protmode update.
+ *
+ * This currently calculates the global ERP protection mode flag
+ * based on each of the VAPs. Any VAP with it enabled is enough
+ * for the global flag to be enabled. All VAPs with it disabled
+ * is enough for it to be disabled.
+ *
+ * This may make sense right now for the supported hardware where
+ * net80211 is controlling the single channel configuration, but
+ * offload firmware that's doing channel changes (eg off-channel
+ * TDLS, off-channel STA, off-channel P2P STA/AP) may get some
+ * silly looking flag updates.
+ *
+ * Ideally the protection mode calculation is done based on the
+ * channel, and all VAPs using that channel will inherit it.
+ * But until that's what net80211 does, this wil have to do.
+ */
+static void
+vap_update_erp_protmode(void *arg, int npending)
+{
+ struct ieee80211vap *vap = arg;
+ struct ieee80211com *ic = vap->iv_ic;
+ struct ieee80211vap *iv;
+ int enable_protmode = 0;
+ int non_erp_present = 0;
+
+ /*
+ * Iterate over all of the VAPs to calculate the overlapping
+ * ERP protection mode configuration and ERP present math.
+ *
+ * For now we assume that if a driver can handle this per-VAP
+ * then it'll ignore the ic->ic_protmode variant and instead
+ * will look at the vap related flags.
+ */
+ IEEE80211_LOCK(ic);
+ TAILQ_FOREACH(iv, &ic->ic_vaps, iv_next) {
+ if (iv->iv_flags & IEEE80211_F_USEPROT)
+ enable_protmode = 1;
+ if (iv->iv_flags_ext & IEEE80211_FEXT_NONERP_PR)
+ non_erp_present = 1;
+ }
+
+ if (enable_protmode)
+ ic->ic_flags |= IEEE80211_F_USEPROT;
+ else
+ ic->ic_flags &= ~IEEE80211_F_USEPROT;
+
+ if (non_erp_present)
+ ic->ic_flags_ext |= IEEE80211_FEXT_NONERP_PR;
+ else
+ ic->ic_flags_ext &= ~IEEE80211_FEXT_NONERP_PR;
+
+ /* Beacon update on all VAPs */
+ ieee80211_notify_erp_locked(ic);
+
+ IEEE80211_UNLOCK(ic);
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG,
+ "%s: called; enable_protmode=%d, non_erp_present=%d\n",
+ __func__, enable_protmode, non_erp_present);
+
+ /*
+ * Now that the global configuration flags are calculated,
+ * notify the VAP about its configuration.
+ *
+ * The global flags will be used when assembling ERP IEs
+ * for multi-VAP operation, even if it's on a different
+ * channel. Yes, that's going to need fixing in the
+ * future.
+ */
+ if (vap->iv_erp_protmode_update != NULL)
+ vap->iv_erp_protmode_update(vap);
+}
+
+/*
+ * Deferred ERP short preamble/barker update.
+ *
+ * All VAPs need to use short preamble for it to be globally
+ * enabled or not.
+ *
+ * Look at the comments for vap_update_erp_protmode() for more
+ * background; this assumes all VAPs are on the same channel.
+ */
+static void
+vap_update_preamble(void *arg, int npending)
+{
+ struct ieee80211vap *vap = arg;
+ struct ieee80211com *ic = vap->iv_ic;
+ struct ieee80211vap *iv;
+ int barker_count = 0, short_preamble_count = 0, count = 0;
+
+ /*
+ * Iterate over all of the VAPs to calculate the overlapping
+ * short or long preamble configuration.
+ *
+ * For now we assume that if a driver can handle this per-VAP
+ * then it'll ignore the ic->ic_flags variant and instead
+ * will look at the vap related flags.
+ */
+ IEEE80211_LOCK(ic);
+ TAILQ_FOREACH(iv, &ic->ic_vaps, iv_next) {
+ if (iv->iv_flags & IEEE80211_F_USEBARKER)
+ barker_count++;
+ if (iv->iv_flags & IEEE80211_F_SHPREAMBLE)
+ short_preamble_count++;
+ count++;
+ }
+
+ /*
+ * As with vap_update_erp_protmode(), the global flags are
+ * currently used for beacon IEs.
+ */
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG,
+ "%s: called; barker_count=%d, short_preamble_count=%d\n",
+ __func__, barker_count, short_preamble_count);
+
+ /*
+ * Only flip on short preamble if all of the VAPs support
+ * it.
+ */
+ if (barker_count == 0 && short_preamble_count == count) {
+ 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_DPRINTF(vap, IEEE80211_MSG_DEBUG,
+ "%s: global barker=%d preamble=%d\n",
+ __func__,
+ !! (ic->ic_flags & IEEE80211_F_USEBARKER),
+ !! (ic->ic_flags & IEEE80211_F_SHPREAMBLE));
+
+ /* Beacon update on all VAPs */
+ ieee80211_notify_erp_locked(ic);
+
+ IEEE80211_UNLOCK(ic);
+
+ /* Driver notification */
+ if (vap->iv_erp_protmode_update != NULL)
+ vap->iv_preamble_update(vap);
+}
+
+/*
+ * Deferred HT protmode update and beacon update.
+ *
+ * Look at the comments for vap_update_erp_protmode() for more
+ * background; this assumes all VAPs are on the same channel.
+ */
+static void
+vap_update_ht_protmode(void *arg, int npending)
+{
+ struct ieee80211vap *vap = arg;
+ struct ieee80211vap *iv;
+ struct ieee80211com *ic = vap->iv_ic;
+ int num_vaps = 0, num_pure = 0, num_mixed = 0;
+ int num_optional = 0, num_ht2040 = 0, num_nonht = 0;
+ int num_ht_sta = 0, num_ht40_sta = 0, num_sta = 0;
+ int num_nonhtpr = 0;
+
+ /*
+ * Iterate over all of the VAPs to calculate everything.
+ *
+ * There are a few different flags to calculate:
+ *
+ * + whether there's HT only or HT+legacy stations;
+ * + whether there's HT20, HT40, or HT20+HT40 stations;
+ * + whether the desired protection mode is mixed, pure or
+ * one of the two above.
+ *
+ * For now we assume that if a driver can handle this per-VAP
+ * then it'll ignore the ic->ic_htprotmode / ic->ic_curhtprotmode
+ * variant and instead will look at the vap related variables.
+ *
+ * XXX TODO: non-greenfield STAs present (IEEE80211_HTINFO_NONGF_PRESENT) !
+ */
+
+ IEEE80211_LOCK(ic);
+ TAILQ_FOREACH(iv, &ic->ic_vaps, iv_next) {
+ num_vaps++;
+ /* overlapping BSSes advertising non-HT status present */
+ if (iv->iv_flags_ht & IEEE80211_FHT_NONHT_PR)
+ num_nonht++;
+ /* Operating mode flags */
+ if (iv->iv_curhtprotmode & IEEE80211_HTINFO_NONHT_PRESENT)
+ num_nonhtpr++;
+ switch (iv->iv_curhtprotmode & IEEE80211_HTINFO_OPMODE) {
+ case IEEE80211_HTINFO_OPMODE_PURE:
+ num_pure++;
+ break;
+ case IEEE80211_HTINFO_OPMODE_PROTOPT:
+ num_optional++;
+ break;
+ case IEEE80211_HTINFO_OPMODE_HT20PR:
+ num_ht2040++;
+ break;
+ case IEEE80211_HTINFO_OPMODE_MIXED:
+ num_mixed++;
+ break;
+ }
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_11N,
+ "%s: vap %s: nonht_pr=%d, curhtprotmode=0x%02x\n",
+ __func__,
+ ieee80211_get_vap_ifname(iv),
+ !! (iv->iv_flags_ht & IEEE80211_FHT_NONHT_PR),
+ iv->iv_curhtprotmode);
+
+ num_ht_sta += iv->iv_ht_sta_assoc;
+ num_ht40_sta += iv->iv_ht40_sta_assoc;
+ num_sta += iv->iv_sta_assoc;
+ }
+
+ /*
+ * Step 1 - if any VAPs indicate NONHT_PR set (overlapping BSS
+ * non-HT present), set it here. This shouldn't be used by
+ * anything but the old overlapping BSS logic so if any drivers
+ * consume it, it's up to date.
+ */
+ if (num_nonht > 0)
+ ic->ic_flags_ht |= IEEE80211_FHT_NONHT_PR;
+ else
+ ic->ic_flags_ht &= ~IEEE80211_FHT_NONHT_PR;
+
+ /*
+ * Step 2 - default HT protection mode to MIXED (802.11-2016 10.26.3.1.)
+ *
+ * + If all VAPs are PURE, we can stay PURE.
+ * + If all VAPs are PROTOPT, we can go to PROTOPT.
+ * + If any VAP has HT20PR then it sees at least a HT40+HT20 station.
+ * Note that we may have a VAP with one HT20 and a VAP with one HT40;
+ * So we look at the sum ht and sum ht40 sta counts; if we have a
+ * HT station and the HT20 != HT40 count, we have to do HT20PR here.
+ * Note all stations need to be HT for this to be an option.
+ * + The fall-through is MIXED, because it means we have some odd
+ * non HT40-involved combination of opmode and this is the most
+ * sensible default.
+ */
+ ic->ic_curhtprotmode = IEEE80211_HTINFO_OPMODE_MIXED;
+
+ if (num_pure == num_vaps)
+ ic->ic_curhtprotmode = IEEE80211_HTINFO_OPMODE_PURE;
+
+ if (num_optional == num_vaps)
+ ic->ic_curhtprotmode = IEEE80211_HTINFO_OPMODE_PROTOPT;
+
+ /*
+ * Note: we need /a/ HT40 station somewhere for this to
+ * be a possibility.
+ */
+ if ((num_ht2040 > 0) ||
+ ((num_ht_sta > 0) && (num_ht40_sta > 0) &&
+ (num_ht_sta != num_ht40_sta)))
+ ic->ic_curhtprotmode = IEEE80211_HTINFO_OPMODE_HT20PR;
+
+ /*
+ * Step 3 - if any of the stations across the VAPs are
+ * non-HT then this needs to be flipped back to MIXED.
+ */
+ if (num_ht_sta != num_sta)
+ ic->ic_curhtprotmode = IEEE80211_HTINFO_OPMODE_MIXED;
+
+ /*
+ * Step 4 - If we see any overlapping BSS non-HT stations
+ * via beacons then flip on NONHT_PRESENT.
+ */
+ if (num_nonhtpr > 0)
+ ic->ic_curhtprotmode |= IEEE80211_HTINFO_NONHT_PRESENT;
+
+ /* Notify all VAPs to potentially update their beacons */
+ TAILQ_FOREACH(iv, &ic->ic_vaps, iv_next)
+ ieee80211_htinfo_notify(iv);
+
+ IEEE80211_UNLOCK(ic);
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_11N,
+ "%s: global: nonht_pr=%d ht_opmode=0x%02x\n",
+ __func__,
+ !! (ic->ic_flags_ht & IEEE80211_FHT_NONHT_PR),
+ ic->ic_curhtprotmode);
+
+ /* Driver update */
+ if (vap->iv_erp_protmode_update != NULL)
+ vap->iv_ht_protmode_update(vap);
}
/*
* Set the short slot time state and notify the driver.
+ *
+ * This is the per-VAP slot time state.
*/
void
-ieee80211_set_shortslottime(struct ieee80211com *ic, int onoff)
+ieee80211_vap_set_shortslottime(struct ieee80211vap *vap, int onoff)
{
+ struct ieee80211com *ic = vap->iv_ic;
+
+ /* XXX lock? */
+
+ /*
+ * Only modify the per-VAP slot time.
+ */
if (onoff)
- ic->ic_flags |= IEEE80211_F_SHSLOT;
+ vap->iv_flags |= IEEE80211_F_SHSLOT;
else
- ic->ic_flags &= ~IEEE80211_F_SHSLOT;
- /* notify driver */
- if (ic->ic_updateslot != NULL)
- ic->ic_updateslot(ic);
+ vap->iv_flags &= ~IEEE80211_F_SHSLOT;
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG,
+ "%s: called; onoff=%d\n", __func__, onoff);
+ /* schedule the deferred slot flag update and update */
+ ieee80211_runtask(ic, &vap->iv_slot_task);
+}
+
+/*
+ * Update the VAP short /long / barker preamble state and
+ * update beacon state if needed.
+ *
+ * For now it simply copies the global flags into the per-vap
+ * flags and schedules the callback. Later this will support
+ * both global and per-VAP flags, especially useful for
+ * and STA+STA multi-channel operation (eg p2p).
+ */
+void
+ieee80211_vap_update_preamble(struct ieee80211vap *vap)
+{
+ struct ieee80211com *ic = vap->iv_ic;
+
+ /* XXX lock? */
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG,
+ "%s: called\n", __func__);
+ /* schedule the deferred slot flag update and update */
+ ieee80211_runtask(ic, &vap->iv_preamble_task);
+}
+
+/*
+ * Update the VAP 11g protection mode and update beacon state
+ * if needed.
+ */
+void
+ieee80211_vap_update_erp_protmode(struct ieee80211vap *vap)
+{
+ struct ieee80211com *ic = vap->iv_ic;
+
+ /* XXX lock? */
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG,
+ "%s: called\n", __func__);
+ /* schedule the deferred slot flag update and update */
+ ieee80211_runtask(ic, &vap->iv_erp_protmode_task);
+}
+
+/*
+ * Update the VAP 11n protection mode and update beacon state
+ * if needed.
+ */
+void
+ieee80211_vap_update_ht_protmode(struct ieee80211vap *vap)
+{
+ struct ieee80211com *ic = vap->iv_ic;
+
+ /* XXX lock? */
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG,
+ "%s: called\n", __func__);
+ /* schedule the deferred protmode update */
+ ieee80211_runtask(ic, &vap->iv_ht_protmode_task);
}
/*
@@ -1053,8 +1524,11 @@ ieee80211_wme_initparams_locked(struct ieee80211vap *vap)
* field and updates hardware when said field changes.
* Otherwise the hardware is programmed with defaults, not what
* the beacon actually announces.
+ *
+ * Note that we can't ever have 0xff as an actual value;
+ * the only valid values are 0..15.
*/
- wme->wme_wmeChanParams.cap_info = 0;
+ wme->wme_wmeChanParams.cap_info = 0xfe;
/*
* Select mode; we can be called early in which case we
@@ -1247,7 +1721,7 @@ ieee80211_wme_updateparams_locked(struct ieee80211vap *vap)
* further.
*/
if (vap->iv_opmode == IEEE80211_M_HOSTAP &&
- ic->ic_sta_assoc < 2 && (wme->wme_flags & WME_F_AGGRMODE) != 0) {
+ vap->iv_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,
@@ -1273,22 +1747,6 @@ ieee80211_wme_updateparams_locked(struct ieee80211vap *vap)
ieee80211_wme_acnames[WME_AC_BE], chanp->wmep_logcwmin);
}
- /*
- * Arrange for the beacon update.
- *
- * XXX what about MBSS, WDS?
- */
- if (vap->iv_opmode == IEEE80211_M_HOSTAP
- || vap->iv_opmode == IEEE80211_M_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);
- }
-
/* schedule the deferred WME update */
ieee80211_runtask(ic, &vap->iv_wme_task);
@@ -1402,7 +1860,7 @@ update_chw(void *arg, int npending)
}
/*
- * Deferred WME update.
+ * Deferred WME parameter and beacon update.
*
* In preparation for per-VAP WME configuration, call the VAP
* method if the VAP requires it. Otherwise, just call the
@@ -1414,12 +1872,32 @@ vap_update_wme(void *arg, int npending)
{
struct ieee80211vap *vap = arg;
struct ieee80211com *ic = vap->iv_ic;
+ struct ieee80211_wme_state *wme = &ic->ic_wme;
+ /* Driver update */
if (vap->iv_wme_update != NULL)
vap->iv_wme_update(vap,
ic->ic_wme.wme_chanParams.cap_wmeParams);
else
ic->ic_wme.wme_update(ic);
+
+ IEEE80211_LOCK(ic);
+ /*
+ * Arrange for the beacon update.
+ *
+ * XXX what about MBSS, WDS?
+ */
+ if (vap->iv_opmode == IEEE80211_M_HOSTAP
+ || vap->iv_opmode == IEEE80211_M_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);
+ }
+ IEEE80211_UNLOCK(ic);
}
static void
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 9d224b1f5c18..fafedf46cab5 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -152,10 +152,12 @@ uint8_t *ieee80211_add_qos(uint8_t *, const struct ieee80211_node *);
uint16_t ieee80211_getcapinfo(struct ieee80211vap *,
struct ieee80211_channel *);
struct ieee80211_wme_state;
-uint8_t * ieee80211_add_wme_info(uint8_t *frm, struct ieee80211_wme_state *wme);
+uint8_t * ieee80211_add_wme_info(uint8_t *frm, struct ieee80211_wme_state *wme,
+ struct ieee80211_node *ni);
+void ieee80211_vap_reset_erp(struct ieee80211vap *);
void ieee80211_reset_erp(struct ieee80211com *);
-void ieee80211_set_shortslottime(struct ieee80211com *, int onoff);
+void ieee80211_vap_set_shortslottime(struct ieee80211vap *, int onoff);
int ieee80211_iserp_rateset(const struct ieee80211_rateset *);
void ieee80211_setbasicrates(struct ieee80211_rateset *,
enum ieee80211_phymode);
@@ -284,7 +286,7 @@ struct ieee80211_wme_state {
u_int wme_hipri_switch_thresh;/* aggressive mode switch thresh */
u_int wme_hipri_switch_hysteresis;/* aggressive mode switch hysteresis */
- struct wmeParams wme_params[4]; /* from assoc resp for each AC*/
+ struct wmeParams wme_params[WME_NUM_AC]; /* 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 */
@@ -301,6 +303,9 @@ void ieee80211_wme_vap_getparams(struct ieee80211vap *vap,
void ieee80211_wme_ic_getparams(struct ieee80211com *ic,
struct chanAccParams *);
int ieee80211_wme_vap_ac_is_noack(struct ieee80211vap *vap, int ac);
+void ieee80211_vap_update_preamble(struct ieee80211vap *vap);
+void ieee80211_vap_update_erp_protmode(struct ieee80211vap *vap);
+void ieee80211_vap_update_ht_protmode(struct ieee80211vap *vap);
/*
* Return pointer to the QoS field from a Qos frame.
diff --git a/sys/net80211/ieee80211_regdomain.c b/sys/net80211/ieee80211_regdomain.c
index b3c0302a5645..095d7941bb15 100644
--- a/sys/net80211/ieee80211_regdomain.c
+++ b/sys/net80211/ieee80211_regdomain.c
@@ -118,10 +118,11 @@ ieee80211_init_channels(struct ieee80211com *ic,
{
struct ieee80211_channel *chans = ic->ic_channels;
int *nchans = &ic->ic_nchans;
- int ht40;
+ int cbw_flags;
/* XXX just do something for now */
- ht40 = !!(ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40);
+ cbw_flags = (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) ?
+ NET80211_CBW_FLAG_HT40 : 0;
*nchans = 0;
if (isset(bands, IEEE80211_MODE_11B) ||
isset(bands, IEEE80211_MODE_11G) ||
@@ -131,19 +132,40 @@ ieee80211_init_channels(struct ieee80211com *ic,
nchan -= 3;
ieee80211_add_channel_list_2ghz(chans, IEEE80211_CHAN_MAX,
- nchans, def_chan_2ghz, nchan, bands, ht40);
+ nchans, def_chan_2ghz, nchan, bands, cbw_flags);
}
+ /* XXX IEEE80211_MODE_VHT_2GHZ if we really want to. */
+
if (isset(bands, IEEE80211_MODE_11A) ||
isset(bands, IEEE80211_MODE_11NA)) {
ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX,
nchans, def_chan_5ghz_band1, nitems(def_chan_5ghz_band1),
- bands, ht40);
+ bands, cbw_flags);
+ ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX,
+ nchans, def_chan_5ghz_band2, nitems(def_chan_5ghz_band2),
+ bands, cbw_flags);
+ ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX,
+ nchans, def_chan_5ghz_band3, nitems(def_chan_5ghz_band3),
+ bands, cbw_flags);
+ }
+ if (isset(bands, IEEE80211_MODE_VHT_5GHZ)) {
+ cbw_flags |= NET80211_CBW_FLAG_HT40; /* Make sure this is set; or assert? */
+ cbw_flags |= NET80211_CBW_FLAG_VHT80;
+#define MS(_v, _f) (((_v) & _f) >> _f##_S)
+ if (MS(ic->ic_vhtcaps, IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) >= 1)
+ cbw_flags |= NET80211_CBW_FLAG_VHT160;
+ if (MS(ic->ic_vhtcaps, IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) == 2)
+ cbw_flags |= NET80211_CBW_FLAG_VHT80P80;
+#undef MS
+ ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX,
+ nchans, def_chan_5ghz_band1, nitems(def_chan_5ghz_band1),
+ bands, cbw_flags);
ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX,
nchans, def_chan_5ghz_band2, nitems(def_chan_5ghz_band2),
- bands, ht40);
+ bands, cbw_flags);
ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX,
nchans, def_chan_5ghz_band3, nitems(def_chan_5ghz_band3),
- bands, ht40);
+ bands, cbw_flags);
}
if (rd != NULL)
ic->ic_regdomain = *rd;
diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c
index ecfdcd03c7c4..ea75504a7235 100644
--- a/sys/net80211/ieee80211_scan_sta.c
+++ b/sys/net80211/ieee80211_scan_sta.c
@@ -1276,6 +1276,8 @@ sta_pick_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
* handle notification that this has completed.
*/
ss->ss_flags &= ~IEEE80211_SCAN_NOPICK;
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
+ "%s: nopick; return 1\n", __func__);
return 1;
}
/*
@@ -1285,7 +1287,9 @@ sta_pick_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
/* 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__);
+ "%s: no scan candidate, join=%d, return 0\n",
+ __func__,
+ !! (ss->ss_flags & IEEE80211_SCAN_NOJOIN));
if (ss->ss_flags & IEEE80211_SCAN_NOJOIN)
return 0;
notfound:
@@ -1310,6 +1314,8 @@ notfound:
chan = demote11b(vap, chan);
if (!ieee80211_sta_join(vap, chan, &selbs->base))
goto notfound;
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
+ "%s: terminate scan; return 1\n", __func__);
return 1; /* terminate scan */
}
diff --git a/sys/net80211/ieee80211_scan_sw.c b/sys/net80211/ieee80211_scan_sw.c
index 33e28868f97d..4fcd26db61b1 100644
--- a/sys/net80211/ieee80211_scan_sw.c
+++ b/sys/net80211/ieee80211_scan_sw.c
@@ -298,6 +298,11 @@ ieee80211_swscan_check_scan(const struct ieee80211_scanner *scan,
* use. Also discard any frames that might come
* in while temporarily marked as scanning.
*/
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
+ "cache hot; ic_lastscan=%d, scanvalid=%d, ticks=%d\n",
+ ic->ic_lastscan,
+ vap->iv_scanvalid,
+ ticks);
SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_DISCARD;
ic->ic_flags |= IEEE80211_F_SCAN;
@@ -307,6 +312,8 @@ ieee80211_swscan_check_scan(const struct ieee80211_scanner *scan,
ic->ic_flags &= ~IEEE80211_F_SCAN;
SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_DISCARD;
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
+ "%s: scan_end returned %d\n", __func__, result);
if (result) {
ieee80211_notify_scan_done(vap);
return 1;
@@ -675,19 +682,32 @@ scan_curchan_task(void *arg, int pending)
struct ieee80211com *ic = ss->ss_ic;
struct ieee80211_channel *chan;
unsigned long maxdwell;
- int scandone;
+ int scandone, scanstop;
IEEE80211_LOCK(ic);
end:
+ /*
+ * Note: only /end/ the scan if we're CANCEL rather than
+ * CANCEL+INTERRUPT (ie, 'PAUSE').
+ *
+ * We can stop the scan if we hit cancel, but we shouldn't
+ * call scan_end(ss, 1) if we're just PAUSEing the scan.
+ */
scandone = (ss->ss_next >= ss->ss_last) ||
- (ss_priv->ss_iflags & ISCAN_CANCEL) != 0;
+ ((ss_priv->ss_iflags & ISCAN_PAUSE) == ISCAN_CANCEL);
+ scanstop = (ss->ss_next >= ss->ss_last) ||
+ ((ss_priv->ss_iflags & ISCAN_CANCEL) != 0);
IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN,
- "%s: loop start; scandone=%d\n",
+ "%s: loop start; scandone=%d, scanstop=%d, ss_iflags=0x%x, ss_next=%u, ss_last=%u\n",
__func__,
- scandone);
+ scandone,
+ scanstop,
+ (uint32_t) ss_priv->ss_iflags,
+ (uint32_t) ss->ss_next,
+ (uint32_t) ss->ss_last);
- if (scandone || (ss->ss_flags & IEEE80211_SCAN_GOTPICK) ||
+ if (scanstop || (ss->ss_flags & IEEE80211_SCAN_GOTPICK) ||
(ss_priv->ss_iflags & ISCAN_ABORT) ||
ieee80211_time_after(ticks + ss->ss_mindwell, ss_priv->ss_scanend)) {
ss_priv->ss_iflags &= ~ISCAN_RUNNING;
@@ -787,11 +807,12 @@ scan_end(struct ieee80211_scan_state *ss, int scandone)
* Since a cancellation may have occurred during one of the
* driver calls (whilst unlocked), update scandone.
*/
- if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_CANCEL) != 0) {
+ if ((scandone == 0) && ((ss_priv->ss_iflags & ISCAN_PAUSE) == ISCAN_CANCEL)) {
/* XXX printf? */
if_printf(vap->iv_ifp,
- "%s: OOPS! scan cancelled during driver call (1)!\n",
- __func__);
+ "%s: OOPS! scan cancelled during driver call (1) (ss_iflags=0x%x)!\n",
+ __func__,
+ ss_priv->ss_iflags);
scandone = 1;
}
@@ -856,11 +877,12 @@ scan_end(struct ieee80211_scan_state *ss, int scandone)
* Since a cancellation may have occurred during one of the
* driver calls (whilst unlocked), update scandone.
*/
- if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_CANCEL) != 0) {
+ if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_PAUSE) == ISCAN_CANCEL) {
/* XXX printf? */
if_printf(vap->iv_ifp,
- "%s: OOPS! scan cancelled during driver call (2)!\n",
- __func__);
+ "%s: OOPS! scan cancelled during driver call (2) (ss_iflags=0x%x)!\n",
+ __func__,
+ ss_priv->ss_iflags);
scandone = 1;
}
@@ -900,11 +922,18 @@ scan_done(struct ieee80211_scan_state *ss, int scandone)
*/
if ((vap->iv_flags_ext & IEEE80211_FEXT_SCAN_OFFLOAD) == 0)
vap->iv_sta_ps(vap, 0);
- if (ss->ss_next >= ss->ss_last)
+ if (ss->ss_next >= ss->ss_last) {
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
+ "%s: Dropping out of scan; ss_next=%u, ss_last=%u\n",
+ __func__,
+ (uint32_t) ss->ss_next,
+ (uint32_t) ss->ss_last);
ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN;
+ }
/* send 'scan done' event if not interrupted due to traffic. */
- if (!(ss_priv->ss_iflags & ISCAN_INTERRUPT))
+ if (!(ss_priv->ss_iflags & ISCAN_INTERRUPT) ||
+ (ss->ss_next >= ss->ss_last))
ieee80211_notify_scan_done(vap);
}
ss_priv->ss_iflags &= ~(ISCAN_PAUSE | ISCAN_ABORT);
diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c
index 46ba73a9ecd8..f852c4b88b58 100644
--- a/sys/net80211/ieee80211_sta.c
+++ b/sys/net80211/ieee80211_sta.c
@@ -1129,25 +1129,56 @@ bad:
IEEE80211_SCAN_FAIL_STATUS);
}
+/*
+ * Parse the WME IE for QoS and U-APSD information.
+ *
+ * Returns -1 if the IE isn't found, 1 if it's found.
+ */
+int
+ieee80211_parse_wmeie(uint8_t *frm, const struct ieee80211_frame *wh,
+ struct ieee80211_node *ni)
+{
+ u_int len = frm[1];
+
+ ni->ni_uapsd = 0;
+
+ if (len < sizeof(struct ieee80211_wme_param)-2) {
+ IEEE80211_DISCARD_IE(ni->ni_vap,
+ IEEE80211_MSG_ELEMID | IEEE80211_MSG_WME,
+ wh, "WME", "too short, len %u", len);
+ return -1;
+ }
+
+ ni->ni_uapsd = frm[WME_CAPINFO_IE_OFFSET];
+
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_POWER | IEEE80211_MSG_ASSOC,
+ ni, "U-APSD settings from STA: 0x%02x", ni->ni_uapsd);
+
+ return 1;
+}
+
int
ieee80211_parse_wmeparams(struct ieee80211vap *vap, uint8_t *frm,
- const struct ieee80211_frame *wh)
+ const struct ieee80211_frame *wh, uint8_t *qosinfo)
{
#define MS(_v, _f) (((_v) & _f) >> _f##_S)
struct ieee80211_wme_state *wme = &vap->iv_ic->ic_wme;
- u_int len = frm[1], qosinfo;
+ u_int len = frm[1], qosinfo_count;
int i;
+ *qosinfo = 0;
+
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;
+ *qosinfo = frm[__offsetof(struct ieee80211_wme_param, param_qosInfo)];
+ qosinfo_count = *qosinfo & WME_QOSINFO_COUNT;
+
/* XXX do proper check for wraparound */
- if (qosinfo == wme->wme_wmeChanParams.cap_info)
+ if (qosinfo_count == wme->wme_wmeChanParams.cap_info)
return 0;
frm += __offsetof(struct ieee80211_wme_param, params_acParams);
for (i = 0; i < WME_NUM_AC; i++) {
@@ -1159,9 +1190,18 @@ ieee80211_parse_wmeparams(struct ieee80211vap *vap, uint8_t *frm,
wmep->wmep_logcwmin = MS(frm[1], WME_PARAM_LOGCWMIN);
wmep->wmep_logcwmax = MS(frm[1], WME_PARAM_LOGCWMAX);
wmep->wmep_txopLimit = le16dec(frm+2);
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME,
+ "%s: WME: %d: acm=%d aifsn=%d logcwmin=%d logcwmax=%d txopLimit=%d\n",
+ __func__,
+ i,
+ wmep->wmep_acm,
+ wmep->wmep_aifsn,
+ wmep->wmep_logcwmin,
+ wmep->wmep_logcwmax,
+ wmep->wmep_txopLimit);
frm += 4;
}
- wme->wme_wmeChanParams.cap_info = qosinfo;
+ wme->wme_wmeChanParams.cap_info = qosinfo_count;
return 1;
#undef MS
}
@@ -1350,11 +1390,12 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
struct ieee80211com *ic = ni->ni_ic;
struct ieee80211_channel *rxchan = ic->ic_curchan;
struct ieee80211_frame *wh;
+ int ht_state_change = 0, do_ht = 0;
uint8_t *frm, *efrm;
uint8_t *rates, *xrates, *wme, *htcap, *htinfo;
uint8_t *vhtcap, *vhtopmode;
uint8_t rate;
- int ht_state_change = 0, do_ht = 0;
+ uint8_t qosinfo;
wh = mtod(m0, struct ieee80211_frame *);
frm = (uint8_t *)&wh[1];
@@ -1419,12 +1460,13 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
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;
+ vap->iv_flags |= IEEE80211_F_USEPROT;
else
- ic->ic_flags &= ~IEEE80211_F_USEPROT;
+ vap->iv_flags &= ~IEEE80211_F_USEPROT;
ni->ni_erp = scan.erp;
/* XXX statistic */
- /* XXX driver notification */
+ /* driver notification */
+ ieee80211_vap_update_erp_protmode(vap);
}
if ((ni->ni_capinfo ^ scan.capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) {
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC,
@@ -1435,7 +1477,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
* NB: we assume short preamble doesn't
* change dynamically
*/
- ieee80211_set_shortslottime(ic,
+ ieee80211_vap_set_shortslottime(vap,
IEEE80211_IS_CHAN_A(ic->ic_bsschan) ||
(scan.capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
ni->ni_capinfo = (ni->ni_capinfo &~ IEEE80211_CAPINFO_SHORT_SLOTTIME)
@@ -1443,9 +1485,18 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
/* XXX statistic */
}
if (scan.wme != NULL &&
- (ni->ni_flags & IEEE80211_NODE_QOS) &&
- ieee80211_parse_wmeparams(vap, scan.wme, wh) > 0)
- ieee80211_wme_updateparams(vap);
+ (ni->ni_flags & IEEE80211_NODE_QOS)) {
+ int _retval;
+ if ((_retval = ieee80211_parse_wmeparams(vap,
+ scan.wme, wh, &qosinfo)) >= 0) {
+ if (qosinfo & WME_CAPINFO_UAPSD_EN)
+ ni->ni_flags |=
+ IEEE80211_NODE_UAPSD;
+ if (_retval > 0)
+ ieee80211_wme_updateparams(vap);
+ }
+ } else
+ ni->ni_flags &= ~IEEE80211_NODE_UAPSD;
#ifdef IEEE80211_SUPPORT_SUPERG
if (scan.ath != NULL)
ieee80211_parse_athparams(ni, scan.ath, wh);
@@ -1782,7 +1833,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
if (ni->ni_jointime == 0)
ni->ni_jointime = time_uptime;
if (wme != NULL &&
- ieee80211_parse_wmeparams(vap, wme, wh) >= 0) {
+ ieee80211_parse_wmeparams(vap, wme, wh, &qosinfo) >= 0) {
ni->ni_flags |= IEEE80211_NODE_QOS;
ieee80211_wme_updateparams(vap);
} else
@@ -1841,15 +1892,16 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
*/
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;
+ vap->iv_flags |= IEEE80211_F_SHPREAMBLE;
+ vap->iv_flags &= ~IEEE80211_F_USEBARKER;
} else {
- ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
- ic->ic_flags |= IEEE80211_F_USEBARKER;
+ vap->iv_flags &= ~IEEE80211_F_SHPREAMBLE;
+ vap->iv_flags |= IEEE80211_F_USEBARKER;
}
- ieee80211_set_shortslottime(ic,
+ ieee80211_vap_set_shortslottime(vap,
IEEE80211_IS_CHAN_A(ic->ic_curchan) ||
(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
+ ieee80211_vap_update_preamble(vap);
/*
* Honor ERP protection.
*
@@ -1857,21 +1909,23 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
*/
if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) &&
(ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
- ic->ic_flags |= IEEE80211_F_USEPROT;
+ vap->iv_flags |= IEEE80211_F_USEPROT;
else
- ic->ic_flags &= ~IEEE80211_F_USEPROT;
+ vap->iv_flags &= ~IEEE80211_F_USEPROT;
+ ieee80211_vap_update_erp_protmode(vap);
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",
+ "%sassoc success at aid %d: %s preamble, %s slot time%s%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" : "",
+ vap->iv_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long",
+ vap->iv_flags&IEEE80211_F_SHSLOT ? "short" : "long",
+ vap->iv_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_AMSDU ? " (+AMSDU)" : "",
ni->ni_flags & IEEE80211_NODE_MIMO_RTS ? " (+SMPS-DYN)" :
ni->ni_flags & IEEE80211_NODE_MIMO_PS ? " (+SMPS)" : "",
ni->ni_flags & IEEE80211_NODE_RIFS ? " (+RIFS)" : "",
diff --git a/sys/net80211/ieee80211_sta.h b/sys/net80211/ieee80211_sta.h
index 79c576d140ba..5f953c7a4dd3 100644
--- a/sys/net80211/ieee80211_sta.h
+++ b/sys/net80211/ieee80211_sta.h
@@ -40,5 +40,12 @@ void ieee80211_sta_vattach(struct ieee80211vap *);
* Used by the adhoc/mesh/tdma paths.
*/
extern int ieee80211_parse_wmeparams(struct ieee80211vap *vap, uint8_t *frm,
- const struct ieee80211_frame *wh);
+ const struct ieee80211_frame *wh, uint8_t *qosinfo);
+
+/*
+ * Used in the hostap path.
+ */
+extern int ieee80211_parse_wmeie(uint8_t *frm,
+ const struct ieee80211_frame *wh, struct ieee80211_node *ni);
+
#endif /* !_NET80211_IEEE80211_STA_H_ */
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 8fe8f01c751a..dd469b6a7c1d 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -231,17 +231,11 @@ struct ieee80211com {
/* 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? */
+ /* Protection mode for net80211 driven channel NICs */
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_curhtprotmode;/* HTINFO bss state */
+
uint8_t ic_rxstream; /* # RX streams */
uint8_t ic_txstream; /* # TX streams */
@@ -308,11 +302,22 @@ struct ieee80211com {
/* TDMA update notification */
void (*ic_tdma_update)(struct ieee80211_node *,
const struct ieee80211_tdma_param *, int);
- /* node state management */
+
+ /* Node state management */
+
+ /* Allocate a new node */
struct ieee80211_node* (*ic_node_alloc)(struct ieee80211vap *,
const uint8_t [IEEE80211_ADDR_LEN]);
+
+ /* Driver node initialisation after net80211 setup */
+ int (*ic_node_init)(struct ieee80211_node *);
+
+ /* Driver node deallocation */
void (*ic_node_free)(struct ieee80211_node *);
+
+ /* Driver node state cleanup before deallocation */
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*);
@@ -377,6 +382,8 @@ struct ieee80211_aclator;
struct ieee80211_tdma_state;
struct ieee80211_mesh_state;
struct ieee80211_hwmp_state;
+struct ieee80211_rx_histogram;
+struct ieee80211_tx_histogram;
struct ieee80211vap {
struct ifmedia iv_media; /* interface media config */
@@ -562,6 +569,38 @@ struct ieee80211vap {
const struct wmeParams *wme_params);
struct task iv_wme_task; /* deferred VAP WME update */
+ /* associated state; protection mode */
+ enum ieee80211_protmode iv_protmode; /* 802.11g protection mode */
+ enum ieee80211_protmode iv_htprotmode; /* HT protection mode */
+ uint8_t iv_curhtprotmode;/* HTINFO bss state */
+
+ uint16_t iv_nonerpsta; /* # non-ERP stations */
+ uint16_t iv_longslotsta; /* # long slot time stations */
+ uint16_t iv_ht_sta_assoc;/* HT stations associated */
+ uint16_t iv_ht40_sta_assoc;/* HT40 stations associated */
+ int iv_lastnonerp; /* last time non-ERP sta noted*/
+ int iv_lastnonht; /* last time non-HT sta noted */
+
+ /* update device state for 802.11 slot time change */
+ void (*iv_updateslot)(struct ieee80211vap *);
+ struct task iv_slot_task; /* deferred slot time update */
+
+ struct task iv_erp_protmode_task; /* deferred ERP protmode update */
+ void (*iv_erp_protmode_update)(struct ieee80211vap *);
+
+ struct task iv_preamble_task; /* deferred short/barker preamble update */
+ void (*iv_preamble_update)(struct ieee80211vap *);
+
+ struct task iv_ht_protmode_task; /* deferred HT protmode update */
+ void (*iv_ht_protmode_update)(struct ieee80211vap *);
+
+ /* per-vap U-APSD state */
+ uint8_t iv_uapsdinfo; /* sta mode QoS Info flags */
+
+ /* Optional transmit/receive histogram statistics */
+ struct ieee80211_rx_histogram *rx_histogram;
+ struct ieee80211_tx_histogram *tx_histogram;
+
uint64_t iv_spare[5];
uint32_t iv_com_state; /* com usage / detached flag */
uint32_t iv_spare1;
@@ -645,6 +684,7 @@ MALLOC_DECLARE(M_80211_VAP);
#define IEEE80211_FEXT_FRAG_OFFLOAD 0x00200000 /* CONF: hardware does 802.11 fragmentation + assignment */
#define IEEE80211_FEXT_VHT 0x00400000 /* CONF: VHT support */
#define IEEE80211_FEXT_QUIET_IE 0x00800000 /* STATUS: quiet IE in a beacon has been added */
+#define IEEE80211_FEXT_UAPSD 0x01000000 /* CONF: enable U-APSD */
#define IEEE80211_FEXT_BITS \
"\20\2INACT\3SCANWAIT\4BGSCAN\5WPS\6TSN\7SCANREQ\10RESUME" \
@@ -682,10 +722,14 @@ MALLOC_DECLARE(M_80211_VAP);
#define IEEE80211_FVHT_VHT 0x000000001 /* CONF: VHT supported */
#define IEEE80211_FVHT_USEVHT40 0x000000002 /* CONF: Use VHT40 */
#define IEEE80211_FVHT_USEVHT80 0x000000004 /* CONF: Use VHT80 */
-#define IEEE80211_FVHT_USEVHT80P80 0x000000008 /* CONF: Use VHT 80+80 */
-#define IEEE80211_FVHT_USEVHT160 0x000000010 /* CONF: Use VHT160 */
+#define IEEE80211_FVHT_USEVHT160 0x000000008 /* CONF: Use VHT160 */
+#define IEEE80211_FVHT_USEVHT80P80 0x000000010 /* CONF: Use VHT 80+80 */
+#define IEEE80211_FVHT_MASK \
+ (IEEE80211_FVHT_VHT | IEEE80211_FVHT_USEVHT40 | \
+ IEEE80211_FVHT_USEVHT80 | IEEE80211_FVHT_USEVHT160 | \
+ IEEE80211_FVHT_USEVHT80P80)
#define IEEE80211_VFHT_BITS \
- "\20\1VHT\2VHT40\3VHT80\4VHT80P80\5VHT160"
+ "\20\1VHT\2VHT40\3VHT80\4VHT160\5VHT80P80"
#define IEEE80211_COM_DETACHED 0x00000001 /* ieee80211_ifdetach called */
#define IEEE80211_COM_REF_ADD 0x00000002 /* add / remove reference */
@@ -733,6 +777,10 @@ int ieee80211_add_channel_ht40(struct ieee80211_channel[], int, int *,
uint32_t ieee80211_get_channel_center_freq(const struct ieee80211_channel *);
uint32_t ieee80211_get_channel_center_freq1(const struct ieee80211_channel *);
uint32_t ieee80211_get_channel_center_freq2(const struct ieee80211_channel *);
+#define NET80211_CBW_FLAG_HT40 0x01
+#define NET80211_CBW_FLAG_VHT80 0x02
+#define NET80211_CBW_FLAG_VHT160 0x04
+#define NET80211_CBW_FLAG_VHT80P80 0x08
int ieee80211_add_channel_list_2ghz(struct ieee80211_channel[], int, int *,
const uint8_t[], int, const uint8_t[], int);
int ieee80211_add_channels_default_2ghz(struct ieee80211_channel[], int,
@@ -878,10 +926,10 @@ static __inline int
ieee80211_vhtchanflags(const struct ieee80211_channel *c)
{
+ if (IEEE80211_IS_CHAN_VHT80P80(c))
+ return IEEE80211_FVHT_USEVHT80P80;
if (IEEE80211_IS_CHAN_VHT160(c))
return IEEE80211_FVHT_USEVHT160;
- if (IEEE80211_IS_CHAN_VHT80_80(c))
- return IEEE80211_FVHT_USEVHT80P80;
if (IEEE80211_IS_CHAN_VHT80(c))
return IEEE80211_FVHT_USEVHT80;
if (IEEE80211_IS_CHAN_VHT40(c))
diff --git a/sys/net80211/ieee80211_vht.c b/sys/net80211/ieee80211_vht.c
index e50c11c5edcd..dbf9f9f69b4b 100644
--- a/sys/net80211/ieee80211_vht.c
+++ b/sys/net80211/ieee80211_vht.c
@@ -93,9 +93,7 @@ vht_recv_action_placeholder(struct ieee80211_node *ni,
#ifdef IEEE80211_DEBUG
ieee80211_note(ni->ni_vap, "%s: called; fc=0x%.2x/0x%.2x",
- __func__,
- wh->i_fc[0],
- wh->i_fc[1]);
+ __func__, wh->i_fc[0], wh->i_fc[1]);
#endif
return (0);
}
@@ -107,9 +105,7 @@ vht_send_action_placeholder(struct ieee80211_node *ni,
#ifdef IEEE80211_DEBUG
ieee80211_note(ni->ni_vap, "%s: called; category=%d, action=%d",
- __func__,
- category,
- action);
+ __func__, category, action);
#endif
return (EINVAL);
}
@@ -161,7 +157,13 @@ ieee80211_vht_vattach(struct ieee80211vap *vap)
IEEE80211_FVHT_VHT
| IEEE80211_FVHT_USEVHT40
| IEEE80211_FVHT_USEVHT80;
+#if 0
/* XXX TODO: enable VHT80+80, VHT160 capabilities */
+ if (XXX TODO FIXME)
+ vap->iv_flags_vht |= IEEE80211_FVHT_USEVHT160;
+ if (XXX TODO FIXME)
+ vap->iv_flags_vht |= IEEE80211_FVHT_USEVHT80P80;
+#endif
memcpy(&vap->iv_vht_mcsinfo, &ic->ic_vht_mcsinfo,
sizeof(struct ieee80211_vht_mcs_info));
@@ -205,10 +207,10 @@ ieee80211_vht_announce(struct ieee80211com *ic)
/* Channel width */
ic_printf(ic, "[VHT] Channel Widths: 20MHz, 40MHz, 80MHz");
- if (MS(ic->ic_vhtcaps, IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) == 2)
- printf(" 80+80MHz");
if (MS(ic->ic_vhtcaps, IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) >= 1)
printf(" 160MHz");
+ if (MS(ic->ic_vhtcaps, IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) == 2)
+ printf(" 80+80MHz");
printf("\n");
/* Features */
@@ -216,16 +218,14 @@ ieee80211_vht_announce(struct ieee80211com *ic)
IEEE80211_VHTCAP_BITS);
/* For now, just 5GHz VHT. Worry about 2GHz VHT later */
- for (i = 0; i < 7; i++) {
+ for (i = 0; i < 8; i++) {
/* Each stream is 2 bits */
tx = (ic->ic_vht_mcsinfo.tx_mcs_map >> (2*i)) & 0x3;
rx = (ic->ic_vht_mcsinfo.rx_mcs_map >> (2*i)) & 0x3;
if (tx == 3 && rx == 3)
continue;
ic_printf(ic, "[VHT] NSS %d: TX MCS 0..%d, RX MCS 0..%d\n",
- i + 1,
- vht_mcs_to_num(tx),
- vht_mcs_to_num(rx));
+ i + 1, vht_mcs_to_num(tx), vht_mcs_to_num(rx));
}
}
@@ -263,10 +263,7 @@ ieee80211_parse_vhtopmode(struct ieee80211_node *ni, const uint8_t *ie)
#if 0
printf("%s: chan1=%d, chan2=%d, chanwidth=%d, basicmcs=0x%04x\n",
- __func__,
- ni->ni_vht_chan1,
- ni->ni_vht_chan2,
- ni->ni_vht_chanwidth,
+ __func__, ni->ni_vht_chan1, ni->ni_vht_chan2, ni->ni_vht_chanwidth,
ni->ni_vht_basicmcs);
#endif
}
@@ -312,7 +309,7 @@ ieee80211_setup_vht_rates(struct ieee80211_node *ni,
}
void
-ieee80211_vht_timeout(struct ieee80211com *ic)
+ieee80211_vht_timeout(struct ieee80211vap *vap)
{
}
@@ -696,27 +693,20 @@ ieee80211_vht_get_chwidth_ie(struct ieee80211_channel *c)
* well?
*/
- if (IEEE80211_IS_CHAN_VHT160(c)) {
- return IEEE80211_VHT_CHANWIDTH_160MHZ;
- }
- if (IEEE80211_IS_CHAN_VHT80_80(c)) {
+ if (IEEE80211_IS_CHAN_VHT80P80(c))
return IEEE80211_VHT_CHANWIDTH_80P80MHZ;
- }
- if (IEEE80211_IS_CHAN_VHT80(c)) {
+ if (IEEE80211_IS_CHAN_VHT160(c))
+ return IEEE80211_VHT_CHANWIDTH_160MHZ;
+ if (IEEE80211_IS_CHAN_VHT80(c))
return IEEE80211_VHT_CHANWIDTH_80MHZ;
- }
- if (IEEE80211_IS_CHAN_VHT40(c)) {
+ if (IEEE80211_IS_CHAN_VHT40(c))
return IEEE80211_VHT_CHANWIDTH_USE_HT;
- }
- if (IEEE80211_IS_CHAN_VHT20(c)) {
+ if (IEEE80211_IS_CHAN_VHT20(c))
return IEEE80211_VHT_CHANWIDTH_USE_HT;
- }
/* We shouldn't get here */
printf("%s: called on a non-VHT channel (freq=%d, flags=0x%08x\n",
- __func__,
- (int) c->ic_freq,
- c->ic_flags);
+ __func__, (int) c->ic_freq, c->ic_flags);
return IEEE80211_VHT_CHANWIDTH_USE_HT;
}
@@ -811,7 +801,7 @@ ieee80211_vht_adjust_channel(struct ieee80211com *ic,
c = findvhtchan(ic, chan, IEEE80211_CHAN_VHT80);
if ((c == NULL) && (flags & IEEE80211_FVHT_USEVHT80P80))
- c = findvhtchan(ic, chan, IEEE80211_CHAN_VHT80_80);
+ c = findvhtchan(ic, chan, IEEE80211_CHAN_VHT80P80);
if ((c == NULL) && (flags & IEEE80211_FVHT_USEVHT80))
c = findvhtchan(ic, chan, IEEE80211_CHAN_VHT80);
diff --git a/sys/net80211/ieee80211_vht.h b/sys/net80211/ieee80211_vht.h
index 791762b14a31..cbbd5a4c9dba 100644
--- a/sys/net80211/ieee80211_vht.h
+++ b/sys/net80211/ieee80211_vht.h
@@ -45,7 +45,7 @@ int ieee80211_vht_updateparams(struct ieee80211_node *,
void ieee80211_setup_vht_rates(struct ieee80211_node *,
const uint8_t *, const uint8_t *);
-void ieee80211_vht_timeout(struct ieee80211com *ic);
+void ieee80211_vht_timeout(struct ieee80211vap *vap);
void ieee80211_vht_node_join(struct ieee80211_node *ni);
void ieee80211_vht_node_leave(struct ieee80211_node *ni);
diff --git a/sys/sys/priv.h b/sys/sys/priv.h
index 9c9964eaa180..948a6c28bb69 100644
--- a/sys/sys/priv.h
+++ b/sys/sys/priv.h
@@ -350,8 +350,10 @@
/*
* 802.11-related privileges.
*/
-#define PRIV_NET80211_GETKEY 440 /* Query 802.11 keys. */
-#define PRIV_NET80211_MANAGE 441 /* Administer 802.11. */
+#define PRIV_NET80211_VAP_GETKEY 440 /* Query VAP 802.11 keys. */
+#define PRIV_NET80211_VAP_MANAGE 441 /* Administer 802.11 VAP */
+#define PRIV_NET80211_VAP_SETMAC 442 /* Set VAP MAC address */
+#define PRIV_NET80211_CREATE_VAP 443 /* Create a new VAP */
/*
* Placeholder for AppleTalk privileges, not supported anymore.
diff --git a/tools/tools/ath/Makefile b/tools/tools/ath/Makefile
index b17f4c4b2dcc..1b5543909b63 100644
--- a/tools/tools/ath/Makefile
+++ b/tools/tools/ath/Makefile
@@ -3,6 +3,6 @@
SUBDIR= arcode athdebug athdecode athkey athpoke athprom athrd athregs athalq
SUBDIR+= athstats ath_prom_read athradar athaggrstats
SUBDIR+= ath_ee_v14_print ath_ee_v4k_print ath_ee_9287_print ath_ee_9300_print
-SUBDIR+= athsurvey athratestats athspectral
+SUBDIR+= athsurvey athratestats athspectral athani
.include <bsd.subdir.mk>
diff --git a/tools/tools/ath/ath_ee_9300_print/main.c b/tools/tools/ath/ath_ee_9300_print/main.c
index df278e18f888..38dd879b55a1 100644
--- a/tools/tools/ath/ath_ee_9300_print/main.c
+++ b/tools/tools/ath/ath_ee_9300_print/main.c
@@ -37,6 +37,34 @@ struct ath_hal;
#include "ar9300/ar9300eep.h"
+static const char *
+eeprom_9300_ctl_idx_to_mode(uint8_t idx)
+{
+ switch (idx & 0xf) {
+ /* 2G CTLs */
+ case 1: return "CCK";
+ case 2: return "OFDM";
+ case 5: return "HT20";
+ case 7: return "HT40";
+ /* 5G CTLs */
+ case 0: return "OFDM";
+ case 6: return "HT20";
+ case 8: return "HT40";
+ default: return "";
+ }
+}
+
+static const char *
+eeprom_9300_ctl_idx_to_regdomain(uint8_t idx)
+{
+ switch (idx & 0xf0) {
+ case 0x10: return "FCC";
+ case 0x30: return "ETSI";
+ case 0x40: return "JP";
+ default: return "";
+ }
+}
+
static void
eeprom_9300_hdr_print(const uint16_t *buf)
{
@@ -156,6 +184,246 @@ eeprom_9300_modal_print(const OSPREY_MODAL_EEP_HEADER *m)
}
static void
+eeprom_9300_print_2g_target_cck(const ar9300_eeprom_t *ee)
+{
+ int i;
+
+ for (i = 0; i < OSPREY_NUM_2G_CCK_TARGET_POWERS; i++) {
+ printf("| Freq %u CCK: pow2x 1/5L %u 5S %u 11L %u 11S %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_cck[i], 1),
+ ee->cal_target_power_cck[i].t_pow2x[LEGACY_TARGET_RATE_1L_5L],
+ ee->cal_target_power_cck[i].t_pow2x[LEGACY_TARGET_RATE_5S],
+ ee->cal_target_power_cck[i].t_pow2x[LEGACY_TARGET_RATE_11L],
+ ee->cal_target_power_cck[i].t_pow2x[LEGACY_TARGET_RATE_11S]);
+ }
+}
+
+static void
+eeprom_9300_print_2g_target_ofdm(const ar9300_eeprom_t *ee)
+{
+ int i;
+
+ for (i = 0; i < OSPREY_NUM_2G_20_TARGET_POWERS; i++) {
+ printf("| Freq %u OFDM: pow2x 6/12/18/24M %u 36M %u 48M %u 54M %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_2g[i], 1),
+ ee->cal_target_power_2g[i].t_pow2x[LEGACY_TARGET_RATE_6_24],
+ ee->cal_target_power_2g[i].t_pow2x[LEGACY_TARGET_RATE_36],
+ ee->cal_target_power_2g[i].t_pow2x[LEGACY_TARGET_RATE_48],
+ ee->cal_target_power_2g[i].t_pow2x[LEGACY_TARGET_RATE_54]);
+ }
+}
+
+static void
+eeprom_9300_print_2g_target_ht20(const ar9300_eeprom_t *ee)
+{
+ int i;
+
+ for (i = 0; i < OSPREY_NUM_2G_20_TARGET_POWERS; i++) {
+ printf("| Freq %u HT20 MCS0-7 pow2x %u %u %u %u %u %u %u %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_2g_ht20[i], 1),
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_0_8_16],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_4],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_5],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_6],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_7]);
+ printf("| Freq %u HT20 MCS8-15 pow2x %u %u %u %u %u %u %u %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_2g_ht20[i], 1),
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_0_8_16],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_12],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_13],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_14],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_15]);
+ printf("| Freq %u HT20 MCS16-23 pow2x %u %u %u %u %u %u %u %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_2g_ht20[i], 1),
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_0_8_16],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_20],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_21],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_22],
+ ee->cal_target_power_2g_ht20[i].t_pow2x[HT_TARGET_RATE_23]);
+ }
+}
+
+static void
+eeprom_9300_print_2g_target_ht40(const ar9300_eeprom_t *ee)
+{
+ int i;
+
+ for (i = 0; i < OSPREY_NUM_2G_40_TARGET_POWERS; i++) {
+ printf("| Freq %u HT40 MCS0-7 pow2x %u %u %u %u %u %u %u %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_2g_ht40[i], 1),
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_0_8_16],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_4],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_5],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_6],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_7]);
+ printf("| Freq %u HT40 MCS8-15 pow2x %u %u %u %u %u %u %u %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_2g_ht40[i], 1),
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_0_8_16],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_12],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_13],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_14],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_15]);
+ printf("| Freq %u HT40 MCS16-23 pow2x %u %u %u %u %u %u %u %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_2g_ht40[i], 1),
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_0_8_16],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_20],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_21],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_22],
+ ee->cal_target_power_2g_ht40[i].t_pow2x[HT_TARGET_RATE_23]);
+ }
+}
+
+static void
+eeprom_9300_print_2g_ctls(const ar9300_eeprom_t *ee)
+{
+ int i, j;
+
+ for (i = 0; i < OSPREY_NUM_CTLS_2G; i++) {
+ printf("| CTL index 0x%.02x (%s %s)\n",
+ ee->ctl_index_2g[i],
+ eeprom_9300_ctl_idx_to_regdomain(ee->ctl_index_2g[i]),
+ eeprom_9300_ctl_idx_to_mode(ee->ctl_index_2g[i]));
+ for (j = 0; j < OSPREY_NUM_BAND_EDGES_2G; j++) {
+ printf("| Freq %u pow2x %u flags 0x%x\n",
+ FBIN2FREQ(ee->ctl_freqbin_2G[i][j], 1),
+ ee->ctl_power_data_2g[i].ctl_edges[j].t_power,
+ ee->ctl_power_data_2g[i].ctl_edges[j].flag);
+ }
+ printf("\n");
+ }
+}
+
+static void
+eeprom_9300_print_5g_target_ofdm(const ar9300_eeprom_t *ee)
+{
+ int i;
+
+ for (i = 0; i < OSPREY_NUM_5G_20_TARGET_POWERS; i++) {
+ printf("| Freq %u OFDM: pow2x 6/12/18/24M %u 36M %u 48M %u 54M %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_5g[i], 0),
+ ee->cal_target_power_5g[i].t_pow2x[LEGACY_TARGET_RATE_6_24],
+ ee->cal_target_power_5g[i].t_pow2x[LEGACY_TARGET_RATE_36],
+ ee->cal_target_power_5g[i].t_pow2x[LEGACY_TARGET_RATE_48],
+ ee->cal_target_power_5g[i].t_pow2x[LEGACY_TARGET_RATE_54]);
+ }
+}
+
+static void
+eeprom_9300_print_5g_target_ht20(const ar9300_eeprom_t *ee)
+{
+ int i;
+
+ for (i = 0; i < OSPREY_NUM_5G_20_TARGET_POWERS; i++) {
+ printf("| Freq %u HT20 MCS0-7 pow2x %u %u %u %u %u %u %u %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_5g_ht20[i], 0),
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_0_8_16],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_4],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_5],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_6],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_7]);
+ printf("| Freq %u HT20 MCS8-15 pow2x %u %u %u %u %u %u %u %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_5g_ht20[i], 0),
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_0_8_16],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_12],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_13],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_14],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_15]);
+ printf("| Freq %u HT20 MCS16-23 pow2x %u %u %u %u %u %u %u %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_5g_ht20[i], 0),
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_0_8_16],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_20],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_21],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_22],
+ ee->cal_target_power_5g_ht20[i].t_pow2x[HT_TARGET_RATE_23]);
+ }
+}
+
+static void
+eeprom_9300_print_5g_target_ht40(const ar9300_eeprom_t *ee)
+{
+ int i;
+
+ for (i = 0; i < OSPREY_NUM_5G_40_TARGET_POWERS; i++) {
+ printf("| Freq %u HT40 MCS0-7 pow2x %u %u %u %u %u %u %u %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_5g_ht40[i], 0),
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_0_8_16],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_4],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_5],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_6],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_7]);
+ printf("| Freq %u HT40 MCS8-15 pow2x %u %u %u %u %u %u %u %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_5g_ht40[i], 0),
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_0_8_16],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_12],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_13],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_14],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_15]);
+ printf("| Freq %u HT40 MCS16-23 pow2x %u %u %u %u %u %u %u %u\n",
+ FBIN2FREQ(ee->cal_target_freqbin_5g_ht40[i], 0),
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_0_8_16],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_1_3_9_11_17_19],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_20],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_21],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_22],
+ ee->cal_target_power_5g_ht40[i].t_pow2x[HT_TARGET_RATE_23]);
+ }
+}
+
+static void
+eeprom_9300_print_5g_ctls(const ar9300_eeprom_t *ee)
+{
+ int i, j;
+
+ for (i = 0; i < OSPREY_NUM_CTLS_5G; i++) {
+ printf("| CTL index 0x%.02x (%s %s)\n", ee->ctl_index_5g[i],
+ eeprom_9300_ctl_idx_to_regdomain(ee->ctl_index_5g[i]),
+ eeprom_9300_ctl_idx_to_mode(ee->ctl_index_5g[i]));
+ for (j = 0; j < OSPREY_NUM_BAND_EDGES_5G; j++) {
+ printf("| Freq %u pow2x %u Flags 0x%x\n",
+ FBIN2FREQ(ee->ctl_freqbin_5G[i][j], 0),
+ ee->ctl_power_data_5g[i].ctl_edges[j].t_power,
+ ee->ctl_power_data_5g[i].ctl_edges[j].flag);
+ }
+ printf("\n");
+ }
+}
+
+static void
load_eeprom_dump(const char *file, uint16_t *buf)
{
unsigned int r[8];
@@ -222,9 +490,19 @@ main(int argc, char *argv[])
printf("\n2GHz modal:\n");
eeprom_9300_modal_print(&ee->modal_header_2g);
+ // TODO: open-loop calibration
+ eeprom_9300_print_2g_target_cck(ee);
+ eeprom_9300_print_2g_target_ofdm(ee);
+ eeprom_9300_print_2g_target_ht20(ee);
+ eeprom_9300_print_2g_target_ht40(ee);
+ eeprom_9300_print_2g_ctls(ee);
printf("\n5GHz modal:\n");
eeprom_9300_modal_print(&ee->modal_header_5g);
+ eeprom_9300_print_5g_target_ofdm(ee);
+ eeprom_9300_print_5g_target_ht20(ee);
+ eeprom_9300_print_5g_target_ht40(ee);
+ eeprom_9300_print_5g_ctls(ee);
free(eep);
exit(0);
diff --git a/tools/tools/ath/athani/Makefile b/tools/tools/ath/athani/Makefile
new file mode 100644
index 000000000000..b475a6b0ed63
--- /dev/null
+++ b/tools/tools/ath/athani/Makefile
@@ -0,0 +1,23 @@
+# $FreeBSD$
+
+PROG= athani
+MAN=
+
+CFLAGS+= -I../../../../sys/contrib
+
+SRCS= main.c
+
+.include <../Makefile.inc>
+
+CFLAGS+= -I${.CURDIR}/../common/
+.PATH.c: ${.CURDIR}/../common/
+SRCS+= ctrl.c
+
+CLEANFILES+= opt_ah.h
+
+opt_ah.h:
+ echo "#define AH_DEBUG 1" > opt_ah.h
+ echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h
+ echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/athani/main.c b/tools/tools/ath/athani/main.c
new file mode 100644
index 000000000000..e2147091780d
--- /dev/null
+++ b/tools/tools/ath/athani/main.c
@@ -0,0 +1,226 @@
+/*-
+ * Copyright (c) 2019 Adrian Chadd <adrian@FreeBSD.org>.
+ * 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.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "diag.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <err.h>
+
+#include "../common/ctrl.h"
+
+/*
+ * This is a simple wrapper program around the ANI diagnostic interface.
+ * It is for fetching and setting the live ANI configuration when trying
+ * to diagnose a noisy environment.
+ */
+
+/*
+ * HAL_DIAG_ANI_CMD is used to set the ANI configuration.
+ * HAL_DIAG_ANI_CURRENT is used to fetch the current ANI configuration.
+ */
+
+struct ani_var {
+ const char *name;
+ int id;
+};
+
+static struct ani_var ani_labels[] = {
+ { "ofdm_noise_immunity_level", 1, },
+ { "noise_immunity_level", 1, },
+ { "ofdm_weak_signal_detect", 2, },
+ { "cck_weak_signal_threshold", 3, },
+ { "firstep_level", 4, },
+ { "spur_immunity_level", 5, },
+ { "mrc_cck", 8, },
+ { "cck_noise_immunity_level", 9, },
+ { NULL, -1, },
+};
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: athani [-i interface] [-l]\n");
+ fprintf(stderr, " -i: interface\n");
+ fprintf(stderr, " -l: list ANI labels\n");
+ fprintf(stderr, " If no args are given after flags, the ANI state will be listed.\n");
+ fprintf(stderr, " To set, use '<label> <value>' to set the state\n");
+ exit(-1);
+}
+
+static void
+list_labels(void)
+{
+ int i;
+
+ for (i = 0; ani_labels[i].name != NULL; i++) {
+ printf("%s (%d)\n", ani_labels[i].name, ani_labels[i].id);
+ }
+}
+
+static int
+ani_write_state(struct ath_driver_req *req, const char *ifname,
+ const char *label, const char *value)
+{
+ struct ath_diag atd;
+ uint32_t args[2];
+ uint32_t cmd, val;
+ size_t sl;
+ int i;
+
+ /* Find the label */
+ sl = strlen(label);
+ for (i = 0; ani_labels[i].name != NULL; i++) {
+ if ((strlen(ani_labels[i].name) == sl) &&
+ (strcmp(label, ani_labels[i].name) == 0)) {
+ cmd = ani_labels[i].id;
+ break;
+ }
+ }
+ if (ani_labels[i].name == NULL) {
+ fprintf(stderr, "%s: couldn't find ANI label (%s)\n",
+ __func__, label);
+ return (-1);
+ }
+
+ val = strtoul(value, NULL, 0);
+
+ /*
+ * Whilst we're doing the ath_diag pieces, we have to set this
+ * ourselves.
+ */
+ strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
+
+ /*
+ * Populate HAL_DIAG_ANI_CMD fields.
+ */
+ args[0] = cmd;
+ args[1] = val;
+
+ atd.ad_id = HAL_DIAG_ANI_CMD | ATH_DIAG_IN;
+ atd.ad_out_data = NULL;
+ atd.ad_out_size = 0;
+ atd.ad_in_data = (void *) &args;
+ atd.ad_in_size = sizeof(args);
+
+ if (ath_driver_req_fetch_diag(req, SIOCGATHDIAG, &atd) < 0) {
+ warn("SIOCGATHDIAG HAL_DIAG_ANI_CMD (%s)", atd.ad_name);
+ return (-1);
+ }
+
+ return (0);
+}
+
+static void
+ani_read_state(struct ath_driver_req *req, const char *ifname)
+{
+ struct ath_diag atd;
+ HAL_ANI_STATE state;
+
+ /*
+ * Whilst we're doing the ath_diag pieces, we have to set this
+ * ourselves.
+ */
+ strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
+
+ atd.ad_id = HAL_DIAG_ANI_CURRENT; /* XXX | DIAG_DYN? */
+ atd.ad_out_data = (caddr_t) &state;
+ atd.ad_out_size = sizeof(state);
+
+ if (ath_driver_req_fetch_diag(req, SIOCGATHDIAG, &atd) < 0)
+ err(1, "%s", atd.ad_name);
+
+
+ printf(" ofdm_noise_immunity_level=%d\n", state.noiseImmunityLevel);
+ printf(" cck_noise_immunity_level=%d\n", state.cckNoiseImmunityLevel);
+ printf(" spur_immunity_level=%d\n", state.spurImmunityLevel);
+ printf(" firstep_level=%d\n", state.firstepLevel);
+ printf(" ofdm_weak_signal_detect=%d\n", state.ofdmWeakSigDetectOff);
+ printf(" cck_weak_signal_threshold=%d\n", state.cckWeakSigThreshold);
+ printf(" mrc_cck=%d\n", state.mrcCckOff);
+ /* XXX TODO: cycle counts? */
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct ath_diag atd;
+ const char *ifname;
+ struct ath_driver_req req;
+ int what, c;
+
+ ath_driver_req_init(&req);
+
+ ifname = getenv("ATH");
+ if (!ifname)
+ ifname = ATH_DEFAULT;
+
+ what = 0;
+ while ((c = getopt(argc, argv, "i:l")) != -1)
+ switch (c) {
+ case 'i':
+ ifname = optarg;
+ break;
+ case 'l':
+ list_labels();
+ exit(0);
+ default:
+ usage();
+ /*NOTREACHED*/
+ }
+
+ /* Initialise the driver interface */
+ if (ath_driver_req_open(&req, ifname) < 0) {
+ exit(127);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 0) {
+ ani_read_state(&req, ifname);
+ exit(0);
+ }
+
+ if (argc < 2) {
+ usage();
+ /*NOTREACHED*/
+ }
+
+ if (ani_write_state(&req, ifname, argv[0], argv[1]) != 0)
+ exit(1);
+
+ exit(0);
+}
diff --git a/tools/tools/ath/athratestats/main.c b/tools/tools/ath/athratestats/main.c
index b3f85f758577..317b025c1854 100644
--- a/tools/tools/ath/athratestats/main.c
+++ b/tools/tools/ath/athratestats/main.c
@@ -64,7 +64,7 @@ static int do_loop = 0;
* This needs to be big enough to fit the two TLVs, the rate table
* and the rate statistics table for a single node.
*/
-#define STATS_BUF_SIZE 8192
+#define STATS_BUF_SIZE 65536
#define PRINTMSG(...) do { \
if (do_loop == 0) \
@@ -122,53 +122,53 @@ ath_sample_stats(struct ath_ratestats *r, struct ath_rateioctl_rt *rt,
(long long) sn->ratemask);
for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
- PRINTATTR_ON(COLOR_PAIR(y+4) | A_BOLD);
+ PRINTATTR_ON(COLOR_PAIR(2 + (y % 4)) | A_BOLD);
PRINTMSG("[%4u] cur rate %d %s since switch: "
- "packets %d ticks %u\n",
+ "packets %d ticks %u ",
bin_to_size(y),
dot11rate(rt, sn->current_rix[y]),
dot11str(rt, sn->current_rix[y]),
sn->packets_since_switch[y],
sn->ticks_since_switch[y]);
- PRINTMSG("[%4u] last sample (%d %s) cur sample (%d %s) "
- "packets sent %d\n",
- bin_to_size(y),
+ PRINTMSG("last sample (%d %s) cur sample (%d %s) "
+ "packets sent %d ",
dot11rate(rt, sn->last_sample_rix[y]),
dot11str(rt, sn->last_sample_rix[y]),
dot11rate(rt, sn->current_sample_rix[y]),
dot11str(rt, sn->current_sample_rix[y]),
sn->packets_sent[y]);
- PRINTATTR_OFF(COLOR_PAIR(y+4) | A_BOLD);
+ PRINTATTR_OFF(COLOR_PAIR(2 + (y % 4)) | A_BOLD);
- PRINTATTR_ON(COLOR_PAIR(3) | A_BOLD);
- PRINTMSG("[%4u] packets since sample %d sample tt %u\n",
- bin_to_size(y),
+ PRINTATTR_ON(COLOR_PAIR(1) | A_BOLD);
+ PRINTMSG("packets since sample %d sample tt %u\n",
sn->packets_since_sample[y],
sn->sample_tt[y]);
PRINTATTR_OFF(COLOR_PAIR(3) | A_BOLD);
- PRINTMSG("\n");
}
- PRINTMSG(" TX Rate TXTOTAL:TXOK EWMA T/ F"
+ PRINTMSG(" TX Rate TXTOTAL:TXOK EWMA T/ F"
+ " avg last xmit ");
+ PRINTMSG(" TX Rate TXTOTAL:TXOK EWMA T/ F"
" avg last xmit\n");
for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) {
+ int c = 0;
if ((mask & 1) == 0)
continue;
for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
if (sn->stats[y][rix].total_packets == 0)
continue;
if (rix == sn->current_rix[y])
- PRINTATTR_ON(COLOR_PAIR(y+4) | A_BOLD);
+ PRINTATTR_ON(COLOR_PAIR(2 + (y % 4)) | A_BOLD);
else if (rix == sn->last_sample_rix[y])
- PRINTATTR_ON(COLOR_PAIR(3) | A_BOLD);
+ PRINTATTR_ON(COLOR_PAIR(1) | A_BOLD);
#if 0
else if (sn->stats[y][rix].ewma_pct / 10 < 50)
PRINTATTR_ON(COLOR_PAIR(2) | A_BOLD);
else if (sn->stats[y][rix].ewma_pct / 10 < 75)
PRINTATTR_ON(COLOR_PAIR(1) | A_BOLD);
#endif
- PRINTMSG("[%2u %s:%4u] %8ju:%-8ju "
- "(%3d.%1d%%) %8ju/%4d %5uuS %u\n",
+ PRINTMSG("[%2u %s:%5u] %8ju:%-8ju "
+ "(%3d.%1d%%) %8ju/%4d %5uuS %u ",
dot11rate(rt, rix),
dot11str(rt, rix),
bin_to_size(y),
@@ -181,16 +181,23 @@ ath_sample_stats(struct ath_ratestats *r, struct ath_rateioctl_rt *rt,
sn->stats[y][rix].average_tx_time,
sn->stats[y][rix].last_tx);
if (rix == sn->current_rix[y])
- PRINTATTR_OFF(COLOR_PAIR(y+4) | A_BOLD);
+ PRINTATTR_OFF(COLOR_PAIR(2 + (y % 4)) | A_BOLD);
else if (rix == sn->last_sample_rix[y])
- PRINTATTR_OFF(COLOR_PAIR(3) | A_BOLD);
+ PRINTATTR_OFF(COLOR_PAIR(1) | A_BOLD);
#if 0
else if (sn->stats[y][rix].ewma_pct / 10 < 50)
PRINTATTR_OFF(COLOR_PAIR(2) | A_BOLD);
else if (sn->stats[y][rix].ewma_pct / 10 < 75)
PRINTATTR_OFF(COLOR_PAIR(1) | A_BOLD);
#endif
+ c++;
+ if (c == 2) {
+ PRINTMSG("\n");
+ c = 0;
+ }
}
+ if (c != 0)
+ PRINTMSG("\n");
}
}
diff --git a/tools/tools/net80211/wlanstats/main.c b/tools/tools/net80211/wlanstats/main.c
index 38dd10eda1b2..bd73053be976 100644
--- a/tools/tools/net80211/wlanstats/main.c
+++ b/tools/tools/net80211/wlanstats/main.c
@@ -63,7 +63,7 @@ static struct {
},
{
"amsdu",
- "input,output,amsdu_tooshort,amsdu_split,amsdu_decap,amsdu_encap,rssi,rate"
+ "input,output,amsdu_tooshort,amsdu_split,amsdu_decap,amsdu_encap,rx_amsdu_more,rx_amsdu_more_end,rssi,rate"
},
};
diff --git a/tools/tools/net80211/wlanstats/wlanstats.c b/tools/tools/net80211/wlanstats/wlanstats.c
index 0e5556848dae..b42d7312e519 100644
--- a/tools/tools/net80211/wlanstats/wlanstats.c
+++ b/tools/tools/net80211/wlanstats/wlanstats.c
@@ -276,7 +276,11 @@ static const struct fmt wlanstats[] = {
{ 8, "amsdu_decap", "decap", "A-MSDU frames received" },
#define S_AMSDU_ENCAP AFTER(S_AMSDU_DECAP)
{ 8, "amsdu_encap", "encap", "A-MSDU frames transmitted" },
-#define S_AMPDU_REORDER AFTER(S_AMSDU_ENCAP)
+#define S_AMSDU_RX_MORE AFTER(S_AMSDU_ENCAP)
+ { 13, "rx_amsdu_more", "rx_amsdu_more", "A-MSDU HW intermediary decap'ed received" },
+#define S_AMSDU_RX_MORE_END AFTER(S_AMSDU_RX_MORE)
+ { 17, "rx_amsdu_more_end", "rx_amsdu_more_end", "A-MSDU HW end decap'ed received" },
+#define S_AMPDU_REORDER AFTER(S_AMSDU_RX_MORE_END)
{ 8, "ampdu_reorder", "reorder","A-MPDU frames held in reorder q" },
#define S_AMPDU_FLUSH AFTER(S_AMPDU_REORDER)
{ 8, "ampdu_flush", "flush", "A-MPDU frames sent up from reorder q" },
@@ -778,6 +782,8 @@ wlan_get_curstat(struct bsdstat *sf, int s, char b[], size_t bs)
case S_AMSDU_SPLIT: STAT(amsdu_split);
case S_AMSDU_DECAP: STAT(amsdu_decap);
case S_AMSDU_ENCAP: STAT(amsdu_encap);
+ case S_AMSDU_RX_MORE: NSTAT(rx_amsdu_more);
+ case S_AMSDU_RX_MORE_END: NSTAT(rx_amsdu_more_end);
case S_AMPDU_REORDER: STAT(ampdu_rx_reorder);
case S_AMPDU_FLUSH: STAT(ampdu_rx_flush);
case S_AMPDU_BARBAD: STAT(ampdu_bar_bad);
@@ -941,6 +947,8 @@ wlan_get_totstat(struct bsdstat *sf, int s, char b[], size_t bs)
case S_AMSDU_SPLIT: STAT(amsdu_split);
case S_AMSDU_DECAP: STAT(amsdu_decap);
case S_AMSDU_ENCAP: STAT(amsdu_encap);
+ case S_AMSDU_RX_MORE: NSTAT(rx_amsdu_more);
+ case S_AMSDU_RX_MORE_END: NSTAT(rx_amsdu_more_end);
case S_AMPDU_REORDER: STAT(ampdu_rx_reorder);
case S_AMPDU_FLUSH: STAT(ampdu_rx_flush);
case S_AMPDU_BARBAD: STAT(ampdu_bar_bad);