aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bcma/Kconfig13
-rw-r--r--drivers/bcma/Makefile2
-rw-r--r--drivers/bcma/bcma_private.h16
-rw-r--r--drivers/bcma/core.c2
-rw-r--r--drivers/bcma/driver_chipcommon.c53
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c133
-rw-r--r--drivers/bcma/driver_mips.c256
-rw-r--r--drivers/bcma/driver_pci.c16
-rw-r--r--drivers/bcma/host_soc.c183
-rw-r--r--drivers/bcma/main.c70
-rw-r--r--drivers/bcma/scan.c348
-rw-r--r--drivers/net/wireless/ath/Kconfig1
-rw-r--r--drivers/net/wireless/ath/Makefile1
-rw-r--r--drivers/net/wireless/ath/ath5k/ahb.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.h4
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h98
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c18
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c31
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h55
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c2
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c15
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c10
-rw-r--r--drivers/net/wireless/ath/ath5k/gpio.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/initvals.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c5
-rw-r--r--drivers/net/wireless/ath/ath5k/pci.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c5
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c91
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c10
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c79
-rw-r--r--drivers/net/wireless/ath/ath5k/rfkill.c2
-rw-r--r--drivers/net/wireless/ath/ath5k/sysfs.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/trace.h3
-rw-r--r--drivers/net/wireless/ath/ath6kl/Kconfig15
-rw-r--r--drivers/net/wireless/ath/ath6kl/Makefile35
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.c692
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.h250
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c1538
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.h39
-rw-r--r--drivers/net/wireless/ath/ath6kl/common.h180
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h544
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c150
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.h105
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif-ops.h72
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.h207
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc.c2457
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc.h607
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_hif.c641
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_hif.h92
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c1303
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c1337
-rw-r--r--drivers/net/wireless/ath/ath6kl/node.c234
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c912
-rw-r--r--drivers/net/wireless/ath/ath6kl/target.h331
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c1457
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c2743
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h2018
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h190
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c150
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c60
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c135
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c122
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c150
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h9
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c12
-rw-r--r--drivers/net/wireless/ath/regd.h2
-rw-r--r--drivers/net/wireless/ath/regd_common.h2
-rw-r--r--drivers/net/wireless/b43/Kconfig6
-rw-r--r--drivers/net/wireless/b43/main.c2
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h1
-rw-r--r--drivers/net/wireless/b43legacy/dma.c374
-rw-r--r--drivers/net/wireless/b43legacy/dma.h107
-rw-r--r--drivers/net/wireless/b43legacy/main.c4
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c1
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-3945-led.c1
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-3945-rs.c1
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-3945.c1
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-4965-led.c1
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-4965-rs.c1
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-4965.c1
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-led.c1
-rw-r--r--drivers/net/wireless/iwlegacy/iwl3945-base.c1
-rw-r--r--drivers/net/wireless/iwlegacy/iwl4965-base.c1
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c30
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c388
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h34
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.c10
-rw-r--r--drivers/net/wireless/libertas/cfg.c69
-rw-r--r--drivers/net/wireless/libertas/cfg.h1
-rw-r--r--drivers/net/wireless/libertas/cmd.c6
-rw-r--r--drivers/net/wireless/libertas/decl.h4
-rw-r--r--drivers/net/wireless/libertas/dev.h28
-rw-r--r--drivers/net/wireless/libertas/ethtool.c1
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c277
-rw-r--r--drivers/net/wireless/libertas/if_spi.c4
-rw-r--r--drivers/net/wireless/libertas/if_usb.c13
-rw-r--r--drivers/net/wireless/libertas/main.c180
-rw-r--r--drivers/net/wireless/libertas/mesh.c77
-rw-r--r--drivers/net/wireless/libertas/mesh.h27
-rw-r--r--drivers/net/wireless/libertas/rx.c1
-rw-r--r--drivers/net/wireless/libertas/tx.c1
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c6
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c209
-rw-r--r--drivers/net/wireless/mwifiex/fw.h15
-rw-r--r--drivers/net/wireless/mwifiex/init.c21
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h5
-rw-r--r--drivers/net/wireless/mwifiex/join.c32
-rw-r--r--drivers/net/wireless/mwifiex/main.c4
-rw-r--r--drivers/net/wireless/mwifiex/main.h55
-rw-r--r--drivers/net/wireless/mwifiex/scan.c1578
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c9
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c230
-rw-r--r--drivers/net/wireless/orinoco/wext.c1
-rw-r--r--drivers/net/wireless/rndis_wlan.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c39
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c39
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c46
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c34
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c37
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h26
-rw-r--r--drivers/net/wireless/wl1251/cmd.h2
-rw-r--r--drivers/net/wireless/wl1251/wl12xx_80211.h2
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h4
-rw-r--r--drivers/net/wireless/wl12xx/main.c2
-rw-r--r--drivers/net/wireless/wl12xx/scan.h6
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h4
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx_80211.h2
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/ath6kl/Kconfig158
-rw-r--r--drivers/staging/ath6kl/Makefile122
-rw-r--r--drivers/staging/ath6kl/TODO25
-rw-r--r--drivers/staging/ath6kl/bmi/include/bmi_internal.h54
-rw-r--r--drivers/staging/ath6kl/bmi/src/bmi.c1010
-rw-r--r--drivers/staging/ath6kl/hif/common/hif_sdio_common.h87
-rw-r--r--drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h131
-rw-r--r--drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c1273
-rw-r--r--drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c393
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k.c1479
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k.h401
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c783
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c755
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c1284
-rw-r--r--drivers/staging/ath6kl/htc2/htc.c575
-rw-r--r--drivers/staging/ath6kl/htc2/htc_debug.h38
-rw-r--r--drivers/staging/ath6kl/htc2/htc_internal.h211
-rw-r--r--drivers/staging/ath6kl/htc2/htc_recv.c1572
-rw-r--r--drivers/staging/ath6kl/htc2/htc_send.c1018
-rw-r--r--drivers/staging/ath6kl/htc2/htc_services.c450
-rw-r--r--drivers/staging/ath6kl/include/a_config.h31
-rw-r--r--drivers/staging/ath6kl/include/a_debug.h195
-rw-r--r--drivers/staging/ath6kl/include/a_drv.h32
-rw-r--r--drivers/staging/ath6kl/include/a_drv_api.h204
-rw-r--r--drivers/staging/ath6kl/include/a_osapi.h32
-rw-r--r--drivers/staging/ath6kl/include/aggr_recv_api.h140
-rw-r--r--drivers/staging/ath6kl/include/ar3kconfig.h65
-rw-r--r--drivers/staging/ath6kl/include/ar6000_api.h32
-rw-r--r--drivers/staging/ath6kl/include/ar6000_diag.h48
-rw-r--r--drivers/staging/ath6kl/include/ar6kap_common.h44
-rw-r--r--drivers/staging/ath6kl/include/athbtfilter.h135
-rw-r--r--drivers/staging/ath6kl/include/bmi.h134
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h52
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/addrs.h90
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h40
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h40
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h24
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h552
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h471
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h589
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h187
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h162
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h40
-rw-r--r--drivers/staging/ath6kl/include/common/athdefs.h75
-rw-r--r--drivers/staging/ath6kl/include/common/bmi_msg.h233
-rw-r--r--drivers/staging/ath6kl/include/common/cnxmgmt.h36
-rw-r--r--drivers/staging/ath6kl/include/common/dbglog.h126
-rw-r--r--drivers/staging/ath6kl/include/common/dbglog_id.h558
-rw-r--r--drivers/staging/ath6kl/include/common/discovery.h75
-rw-r--r--drivers/staging/ath6kl/include/common/epping_test.h111
-rw-r--r--drivers/staging/ath6kl/include/common/gmboxif.h70
-rw-r--r--drivers/staging/ath6kl/include/common/gpio_reg.h9
-rw-r--r--drivers/staging/ath6kl/include/common/htc.h227
-rw-r--r--drivers/staging/ath6kl/include/common/htc_services.h52
-rw-r--r--drivers/staging/ath6kl/include/common/pkt_log.h45
-rw-r--r--drivers/staging/ath6kl/include/common/roaming.h41
-rw-r--r--drivers/staging/ath6kl/include/common/targaddrs.h395
-rw-r--r--drivers/staging/ath6kl/include/common/testcmd.h185
-rw-r--r--drivers/staging/ath6kl/include/common/tlpm.h38
-rw-r--r--drivers/staging/ath6kl/include/common/wlan_defs.h79
-rw-r--r--drivers/staging/ath6kl/include/common/wmi.h3220
-rw-r--r--drivers/staging/ath6kl/include/common/wmix.h271
-rw-r--r--drivers/staging/ath6kl/include/common_drv.h104
-rw-r--r--drivers/staging/ath6kl/include/dbglog_api.h52
-rw-r--r--drivers/staging/ath6kl/include/dl_list.h153
-rw-r--r--drivers/staging/ath6kl/include/dset_api.h65
-rw-r--r--drivers/staging/ath6kl/include/hci_transport_api.h259
-rw-r--r--drivers/staging/ath6kl/include/hif.h456
-rw-r--r--drivers/staging/ath6kl/include/host_version.h52
-rw-r--r--drivers/staging/ath6kl/include/htc_api.h575
-rw-r--r--drivers/staging/ath6kl/include/htc_packet.h227
-rw-r--r--drivers/staging/ath6kl/include/wlan_api.h128
-rw-r--r--drivers/staging/ath6kl/include/wmi_api.h441
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kconfig.c565
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c572
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h75
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c969
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h113
-rw-r--r--drivers/staging/ath6kl/miscdrv/common_drv.c910
-rw-r--r--drivers/staging/ath6kl/miscdrv/credit_dist.c417
-rw-r--r--drivers/staging/ath6kl/miscdrv/miscdrv.h42
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_drv.c6267
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_pm.c626
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_raw_if.c455
-rw-r--r--drivers/staging/ath6kl/os/linux/cfg80211.c1892
-rw-r--r--drivers/staging/ath6kl/os/linux/export_hci_transport.c124
-rw-r--r--drivers/staging/ath6kl/os/linux/hci_bridge.c1141
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ar6000_drv.h776
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ar6k_pal.h36
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h190
-rw-r--r--drivers/staging/ath6kl/os/linux/include/athdrv_linux.h1217
-rw-r--r--drivers/staging/ath6kl/os/linux/include/cfg80211.h61
-rw-r--r--drivers/staging/ath6kl/os/linux/include/config_linux.h51
-rw-r--r--drivers/staging/ath6kl/os/linux/include/debug_linux.h50
-rw-r--r--drivers/staging/ath6kl/os/linux/include/export_hci_transport.h76
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h177
-rw-r--r--drivers/staging/ath6kl/os/linux/include/osapi_linux.h339
-rw-r--r--drivers/staging/ath6kl/os/linux/include/wlan_config.h108
-rw-r--r--drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h300
-rw-r--r--drivers/staging/ath6kl/os/linux/netbuf.c231
-rw-r--r--drivers/staging/ath6kl/reorder/aggr_rx_internal.h117
-rw-r--r--drivers/staging/ath6kl/reorder/rcv_aggr.c661
-rw-r--r--drivers/staging/ath6kl/wlan/include/ieee80211.h397
-rw-r--r--drivers/staging/ath6kl/wlan/include/ieee80211_node.h93
-rw-r--r--drivers/staging/ath6kl/wlan/src/wlan_node.c636
-rw-r--r--drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c199
-rw-r--r--drivers/staging/ath6kl/wlan/src/wlan_utils.c58
-rw-r--r--drivers/staging/ath6kl/wmi/wmi.c6444
-rw-r--r--drivers/staging/ath6kl/wmi/wmi_host.h102
-rw-r--r--drivers/watchdog/bcm47xx_wdt.c27
279 files changed, 21356 insertions, 53502 deletions
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index ae0a02e1b80..c1172dafdff 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -33,6 +33,19 @@ config BCMA_DRIVER_PCI_HOSTMODE
33 help 33 help
34 PCI core hostmode operation (external PCI bus). 34 PCI core hostmode operation (external PCI bus).
35 35
36config BCMA_HOST_SOC
37 bool
38 depends on BCMA_DRIVER_MIPS
39
40config BCMA_DRIVER_MIPS
41 bool "BCMA Broadcom MIPS core driver"
42 depends on BCMA && MIPS
43 help
44 Driver for the Broadcom MIPS core attached to Broadcom specific
45 Advanced Microcontroller Bus.
46
47 If unsure, say N
48
36config BCMA_DEBUG 49config BCMA_DEBUG
37 bool "BCMA debugging" 50 bool "BCMA debugging"
38 depends on BCMA 51 depends on BCMA
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
index a2161cceafb..82de24e5340 100644
--- a/drivers/bcma/Makefile
+++ b/drivers/bcma/Makefile
@@ -2,7 +2,9 @@ bcma-y += main.o scan.o core.o sprom.o
2bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o 2bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
3bcma-y += driver_pci.o 3bcma-y += driver_pci.o
4bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o 4bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
5bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
5bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o 6bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
7bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
6obj-$(CONFIG_BCMA) += bcma.o 8obj-$(CONFIG_BCMA) += bcma.o
7 9
8ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG 10ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index e02ff21835c..30a3085d335 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -15,13 +15,29 @@ struct bcma_bus;
15/* main.c */ 15/* main.c */
16int bcma_bus_register(struct bcma_bus *bus); 16int bcma_bus_register(struct bcma_bus *bus);
17void bcma_bus_unregister(struct bcma_bus *bus); 17void bcma_bus_unregister(struct bcma_bus *bus);
18int __init bcma_bus_early_register(struct bcma_bus *bus,
19 struct bcma_device *core_cc,
20 struct bcma_device *core_mips);
18 21
19/* scan.c */ 22/* scan.c */
20int bcma_bus_scan(struct bcma_bus *bus); 23int bcma_bus_scan(struct bcma_bus *bus);
24int __init bcma_bus_scan_early(struct bcma_bus *bus,
25 struct bcma_device_id *match,
26 struct bcma_device *core);
27void bcma_init_bus(struct bcma_bus *bus);
21 28
22/* sprom.c */ 29/* sprom.c */
23int bcma_sprom_get(struct bcma_bus *bus); 30int bcma_sprom_get(struct bcma_bus *bus);
24 31
32/* driver_chipcommon.c */
33#ifdef CONFIG_BCMA_DRIVER_MIPS
34void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
35#endif /* CONFIG_BCMA_DRIVER_MIPS */
36
37/* driver_chipcommon_pmu.c */
38u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
39u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
40
25#ifdef CONFIG_BCMA_HOST_PCI 41#ifdef CONFIG_BCMA_HOST_PCI
26/* host_pci.c */ 42/* host_pci.c */
27extern int __init bcma_host_pci_init(void); 43extern int __init bcma_host_pci_init(void);
diff --git a/drivers/bcma/core.c b/drivers/bcma/core.c
index 4a04a49cc06..189a97b51be 100644
--- a/drivers/bcma/core.c
+++ b/drivers/bcma/core.c
@@ -110,6 +110,8 @@ EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
110u32 bcma_core_dma_translation(struct bcma_device *core) 110u32 bcma_core_dma_translation(struct bcma_device *core)
111{ 111{
112 switch (core->bus->hosttype) { 112 switch (core->bus->hosttype) {
113 case BCMA_HOSTTYPE_SOC:
114 return 0;
113 case BCMA_HOSTTYPE_PCI: 115 case BCMA_HOSTTYPE_PCI:
114 if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64) 116 if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
115 return BCMA_DMA_TRANSLATION_DMA64_CMT; 117 return BCMA_DMA_TRANSLATION_DMA64_CMT;
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index 851e05bc948..47cce9d6963 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -26,6 +26,9 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
26 u32 leddc_on = 10; 26 u32 leddc_on = 10;
27 u32 leddc_off = 90; 27 u32 leddc_off = 90;
28 28
29 if (cc->setup_done)
30 return;
31
29 if (cc->core->id.rev >= 11) 32 if (cc->core->id.rev >= 11)
30 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); 33 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
31 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP); 34 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
@@ -52,6 +55,8 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
52 ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) | 55 ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
53 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT))); 56 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
54 } 57 }
58
59 cc->setup_done = true;
55} 60}
56 61
57/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ 62/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
@@ -101,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
101{ 106{
102 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value); 107 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
103} 108}
109
110#ifdef CONFIG_BCMA_DRIVER_MIPS
111void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
112{
113 unsigned int irq;
114 u32 baud_base;
115 u32 i;
116 unsigned int ccrev = cc->core->id.rev;
117 struct bcma_serial_port *ports = cc->serial_ports;
118
119 if (ccrev >= 11 && ccrev != 15) {
120 /* Fixed ALP clock */
121 baud_base = bcma_pmu_alp_clock(cc);
122 if (ccrev >= 21) {
123 /* Turn off UART clock before switching clocksource. */
124 bcma_cc_write32(cc, BCMA_CC_CORECTL,
125 bcma_cc_read32(cc, BCMA_CC_CORECTL)
126 & ~BCMA_CC_CORECTL_UARTCLKEN);
127 }
128 /* Set the override bit so we don't divide it */
129 bcma_cc_write32(cc, BCMA_CC_CORECTL,
130 bcma_cc_read32(cc, BCMA_CC_CORECTL)
131 | BCMA_CC_CORECTL_UARTCLK0);
132 if (ccrev >= 21) {
133 /* Re-enable the UART clock. */
134 bcma_cc_write32(cc, BCMA_CC_CORECTL,
135 bcma_cc_read32(cc, BCMA_CC_CORECTL)
136 | BCMA_CC_CORECTL_UARTCLKEN);
137 }
138 } else {
139 pr_err("serial not supported on this device ccrev: 0x%x\n",
140 ccrev);
141 return;
142 }
143
144 irq = bcma_core_mips_irq(cc->core);
145
146 /* Determine the registers of the UARTs */
147 cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
148 for (i = 0; i < cc->nr_serial_ports; i++) {
149 ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
150 (i * 256);
151 ports[i].irq = irq;
152 ports[i].baud_base = baud_base;
153 ports[i].reg_shift = 0;
154 }
155}
156#endif /* CONFIG_BCMA_DRIVER_MIPS */
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index fcc63db0ce7..5940c81e7e1 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -11,6 +11,13 @@
11#include "bcma_private.h" 11#include "bcma_private.h"
12#include <linux/bcma/bcma.h> 12#include <linux/bcma/bcma.h>
13 13
14static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
15{
16 bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
17 bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
18 return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
19}
20
14static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc, 21static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
15 u32 offset, u32 mask, u32 set) 22 u32 offset, u32 mask, u32 set)
16{ 23{
@@ -136,3 +143,129 @@ void bcma_pmu_init(struct bcma_drv_cc *cc)
136 bcma_pmu_swreg_init(cc); 143 bcma_pmu_swreg_init(cc);
137 bcma_pmu_workarounds(cc); 144 bcma_pmu_workarounds(cc);
138} 145}
146
147u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
148{
149 struct bcma_bus *bus = cc->core->bus;
150
151 switch (bus->chipinfo.id) {
152 case 0x4716:
153 case 0x4748:
154 case 47162:
155 case 0x4313:
156 case 0x5357:
157 case 0x4749:
158 case 53572:
159 /* always 20Mhz */
160 return 20000 * 1000;
161 case 0x5356:
162 case 0x5300:
163 /* always 25Mhz */
164 return 25000 * 1000;
165 default:
166 pr_warn("No ALP clock specified for %04X device, "
167 "pmu rev. %d, using default %d Hz\n",
168 bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
169 }
170 return BCMA_CC_PMU_ALP_CLOCK;
171}
172
173/* Find the output of the "m" pll divider given pll controls that start with
174 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
175 */
176static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
177{
178 u32 tmp, div, ndiv, p1, p2, fc;
179 struct bcma_bus *bus = cc->core->bus;
180
181 BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
182
183 BUG_ON(!m || m > 4);
184
185 if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
186 /* Detect failure in clock setting */
187 tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
188 if (tmp & 0x40000)
189 return 133 * 1000000;
190 }
191
192 tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
193 p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
194 p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
195
196 tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
197 div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
198 BCMA_CC_PPL_MDIV_MASK;
199
200 tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
201 ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
202
203 /* Do calculation in Mhz */
204 fc = bcma_pmu_alp_clock(cc) / 1000000;
205 fc = (p1 * ndiv * fc) / p2;
206
207 /* Return clock in Hertz */
208 return (fc / div) * 1000000;
209}
210
211/* query bus clock frequency for PMU-enabled chipcommon */
212u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
213{
214 struct bcma_bus *bus = cc->core->bus;
215
216 switch (bus->chipinfo.id) {
217 case 0x4716:
218 case 0x4748:
219 case 47162:
220 return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
221 BCMA_CC_PMU5_MAINPLL_SSB);
222 case 0x5356:
223 return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
224 BCMA_CC_PMU5_MAINPLL_SSB);
225 case 0x5357:
226 case 0x4749:
227 return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
228 BCMA_CC_PMU5_MAINPLL_SSB);
229 case 0x5300:
230 return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
231 BCMA_CC_PMU5_MAINPLL_SSB);
232 case 53572:
233 return 75000000;
234 default:
235 pr_warn("No backplane clock specified for %04X device, "
236 "pmu rev. %d, using default %d Hz\n",
237 bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
238 }
239 return BCMA_CC_PMU_HT_CLOCK;
240}
241
242/* query cpu clock frequency for PMU-enabled chipcommon */
243u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
244{
245 struct bcma_bus *bus = cc->core->bus;
246
247 if (bus->chipinfo.id == 53572)
248 return 300000000;
249
250 if (cc->pmu.rev >= 5) {
251 u32 pll;
252 switch (bus->chipinfo.id) {
253 case 0x5356:
254 pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
255 break;
256 case 0x5357:
257 case 0x4749:
258 pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
259 break;
260 default:
261 pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
262 break;
263 }
264
265 /* TODO: if (bus->chipinfo.id == 0x5300)
266 return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
267 return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
268 }
269
270 return bcma_pmu_get_clockcontrol(cc);
271}
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c
new file mode 100644
index 00000000000..c3e9dff4224
--- /dev/null
+++ b/drivers/bcma/driver_mips.c
@@ -0,0 +1,256 @@
1/*
2 * Broadcom specific AMBA
3 * Broadcom MIPS32 74K core driver
4 *
5 * Copyright 2009, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
7 * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
8 * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
9 *
10 * Licensed under the GNU/GPL. See COPYING for details.
11 */
12
13#include "bcma_private.h"
14
15#include <linux/bcma/bcma.h>
16
17#include <linux/serial.h>
18#include <linux/serial_core.h>
19#include <linux/serial_reg.h>
20#include <linux/time.h>
21
22/* The 47162a0 hangs when reading MIPS DMP registers registers */
23static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
24{
25 return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
26 dev->id.id == BCMA_CORE_MIPS_74K;
27}
28
29/* The 5357b0 hangs when reading USB20H DMP registers */
30static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
31{
32 return (dev->bus->chipinfo.id == 0x5357 ||
33 dev->bus->chipinfo.id == 0x4749) &&
34 dev->bus->chipinfo.pkg == 11 &&
35 dev->id.id == BCMA_CORE_USB20_HOST;
36}
37
38static inline u32 mips_read32(struct bcma_drv_mips *mcore,
39 u16 offset)
40{
41 return bcma_read32(mcore->core, offset);
42}
43
44static inline void mips_write32(struct bcma_drv_mips *mcore,
45 u16 offset,
46 u32 value)
47{
48 bcma_write32(mcore->core, offset, value);
49}
50
51static const u32 ipsflag_irq_mask[] = {
52 0,
53 BCMA_MIPS_IPSFLAG_IRQ1,
54 BCMA_MIPS_IPSFLAG_IRQ2,
55 BCMA_MIPS_IPSFLAG_IRQ3,
56 BCMA_MIPS_IPSFLAG_IRQ4,
57};
58
59static const u32 ipsflag_irq_shift[] = {
60 0,
61 BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
62 BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
63 BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
64 BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
65};
66
67static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
68{
69 u32 flag;
70
71 if (bcma_core_mips_bcm47162a0_quirk(dev))
72 return dev->core_index;
73 if (bcma_core_mips_bcm5357b0_quirk(dev))
74 return dev->core_index;
75 flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
76
77 return flag & 0x1F;
78}
79
80/* Get the MIPS IRQ assignment for a specified device.
81 * If unassigned, 0 is returned.
82 */
83unsigned int bcma_core_mips_irq(struct bcma_device *dev)
84{
85 struct bcma_device *mdev = dev->bus->drv_mips.core;
86 u32 irqflag;
87 unsigned int irq;
88
89 irqflag = bcma_core_mips_irqflag(dev);
90
91 for (irq = 1; irq <= 4; irq++)
92 if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
93 (1 << irqflag))
94 return irq;
95
96 return 0;
97}
98EXPORT_SYMBOL(bcma_core_mips_irq);
99
100static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
101{
102 unsigned int oldirq = bcma_core_mips_irq(dev);
103 struct bcma_bus *bus = dev->bus;
104 struct bcma_device *mdev = bus->drv_mips.core;
105 u32 irqflag;
106
107 irqflag = bcma_core_mips_irqflag(dev);
108 BUG_ON(oldirq == 6);
109
110 dev->irq = irq + 2;
111
112 /* clear the old irq */
113 if (oldirq == 0)
114 bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
115 bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
116 ~(1 << irqflag));
117 else
118 bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
119
120 /* assign the new one */
121 if (irq == 0) {
122 bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
123 bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
124 (1 << irqflag));
125 } else {
126 u32 oldirqflag = bcma_read32(mdev,
127 BCMA_MIPS_MIPS74K_INTMASK(irq));
128 if (oldirqflag) {
129 struct bcma_device *core;
130
131 /* backplane irq line is in use, find out who uses
132 * it and set user to irq 0
133 */
134 list_for_each_entry_reverse(core, &bus->cores, list) {
135 if ((1 << bcma_core_mips_irqflag(core)) ==
136 oldirqflag) {
137 bcma_core_mips_set_irq(core, 0);
138 break;
139 }
140 }
141 }
142 bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
143 1 << irqflag);
144 }
145
146 pr_info("set_irq: core 0x%04x, irq %d => %d\n",
147 dev->id.id, oldirq + 2, irq + 2);
148}
149
150static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
151{
152 int i;
153 static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
154 printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
155 for (i = 0; i <= 6; i++)
156 printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
157 printk("\n");
158}
159
160static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
161{
162 struct bcma_device *core;
163
164 list_for_each_entry_reverse(core, &bus->cores, list) {
165 bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
166 }
167}
168
169u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
170{
171 struct bcma_bus *bus = mcore->core->bus;
172
173 if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
174 return bcma_pmu_get_clockcpu(&bus->drv_cc);
175
176 pr_err("No PMU available, need this to get the cpu clock\n");
177 return 0;
178}
179EXPORT_SYMBOL(bcma_cpu_clock);
180
181static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
182{
183 struct bcma_bus *bus = mcore->core->bus;
184
185 switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
186 case BCMA_CC_FLASHT_STSER:
187 case BCMA_CC_FLASHT_ATSER:
188 pr_err("Serial flash not supported.\n");
189 break;
190 case BCMA_CC_FLASHT_PARA:
191 pr_info("found parallel flash.\n");
192 bus->drv_cc.pflash.window = 0x1c000000;
193 bus->drv_cc.pflash.window_size = 0x02000000;
194
195 if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
196 BCMA_CC_FLASH_CFG_DS) == 0)
197 bus->drv_cc.pflash.buswidth = 1;
198 else
199 bus->drv_cc.pflash.buswidth = 2;
200 break;
201 default:
202 pr_err("flash not supported.\n");
203 }
204}
205
206void bcma_core_mips_init(struct bcma_drv_mips *mcore)
207{
208 struct bcma_bus *bus;
209 struct bcma_device *core;
210 bus = mcore->core->bus;
211
212 pr_info("Initializing MIPS core...\n");
213
214 if (!mcore->setup_done)
215 mcore->assigned_irqs = 1;
216
217 /* Assign IRQs to all cores on the bus */
218 list_for_each_entry_reverse(core, &bus->cores, list) {
219 int mips_irq;
220 if (core->irq)
221 continue;
222
223 mips_irq = bcma_core_mips_irq(core);
224 if (mips_irq > 4)
225 core->irq = 0;
226 else
227 core->irq = mips_irq + 2;
228 if (core->irq > 5)
229 continue;
230 switch (core->id.id) {
231 case BCMA_CORE_PCI:
232 case BCMA_CORE_PCIE:
233 case BCMA_CORE_ETHERNET:
234 case BCMA_CORE_ETHERNET_GBIT:
235 case BCMA_CORE_MAC_GBIT:
236 case BCMA_CORE_80211:
237 case BCMA_CORE_USB20_HOST:
238 /* These devices get their own IRQ line if available,
239 * the rest goes on IRQ0
240 */
241 if (mcore->assigned_irqs <= 4)
242 bcma_core_mips_set_irq(core,
243 mcore->assigned_irqs++);
244 break;
245 }
246 }
247 pr_info("IRQ reconfiguration done\n");
248 bcma_core_mips_dump_irq(bus);
249
250 if (mcore->setup_done)
251 return;
252
253 bcma_chipco_serial_init(&bus->drv_cc);
254 bcma_core_mips_flash_detect(mcore);
255 mcore->setup_done = true;
256}
diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
index 25f3ddf3382..81f3d0a4b85 100644
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -173,7 +173,7 @@ static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
173 return false; 173 return false;
174 174
175#ifdef CONFIG_SSB_DRIVER_PCICORE 175#ifdef CONFIG_SSB_DRIVER_PCICORE
176 if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI) 176 if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
177 return false; 177 return false;
178#endif /* CONFIG_SSB_DRIVER_PCICORE */ 178#endif /* CONFIG_SSB_DRIVER_PCICORE */
179 179
@@ -189,6 +189,9 @@ static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
189 189
190void bcma_core_pci_init(struct bcma_drv_pci *pc) 190void bcma_core_pci_init(struct bcma_drv_pci *pc)
191{ 191{
192 if (pc->setup_done)
193 return;
194
192 if (bcma_core_pci_is_in_hostmode(pc)) { 195 if (bcma_core_pci_is_in_hostmode(pc)) {
193#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE 196#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
194 bcma_core_pci_hostmode_init(pc); 197 bcma_core_pci_hostmode_init(pc);
@@ -198,6 +201,8 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc)
198 } else { 201 } else {
199 bcma_core_pci_clientmode_init(pc); 202 bcma_core_pci_clientmode_init(pc);
200 } 203 }
204
205 pc->setup_done = true;
201} 206}
202 207
203int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, 208int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
@@ -205,7 +210,14 @@ int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
205{ 210{
206 struct pci_dev *pdev = pc->core->bus->host_pci; 211 struct pci_dev *pdev = pc->core->bus->host_pci;
207 u32 coremask, tmp; 212 u32 coremask, tmp;
208 int err; 213 int err = 0;
214
215 if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
216 /* This bcma device is not on a PCI host-bus. So the IRQs are
217 * not routed through the PCI core.
218 * So we must not enable routing through the PCI core. */
219 goto out;
220 }
209 221
210 err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp); 222 err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
211 if (err) 223 if (err)
diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c
new file mode 100644
index 00000000000..3c381fb8f9c
--- /dev/null
+++ b/drivers/bcma/host_soc.c
@@ -0,0 +1,183 @@
1/*
2 * Broadcom specific AMBA
3 * System on Chip (SoC) Host
4 *
5 * Licensed under the GNU/GPL. See COPYING for details.
6 */
7
8#include "bcma_private.h"
9#include "scan.h"
10#include <linux/bcma/bcma.h>
11#include <linux/bcma/bcma_soc.h>
12
13static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
14{
15 return readb(core->io_addr + offset);
16}
17
18static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
19{
20 return readw(core->io_addr + offset);
21}
22
23static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
24{
25 return readl(core->io_addr + offset);
26}
27
28static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
29 u8 value)
30{
31 writeb(value, core->io_addr + offset);
32}
33
34static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
35 u16 value)
36{
37 writew(value, core->io_addr + offset);
38}
39
40static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
41 u32 value)
42{
43 writel(value, core->io_addr + offset);
44}
45
46#ifdef CONFIG_BCMA_BLOCKIO
47static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
48 size_t count, u16 offset, u8 reg_width)
49{
50 void __iomem *addr = core->io_addr + offset;
51
52 switch (reg_width) {
53 case sizeof(u8): {
54 u8 *buf = buffer;
55
56 while (count) {
57 *buf = __raw_readb(addr);
58 buf++;
59 count--;
60 }
61 break;
62 }
63 case sizeof(u16): {
64 __le16 *buf = buffer;
65
66 WARN_ON(count & 1);
67 while (count) {
68 *buf = (__force __le16)__raw_readw(addr);
69 buf++;
70 count -= 2;
71 }
72 break;
73 }
74 case sizeof(u32): {
75 __le32 *buf = buffer;
76
77 WARN_ON(count & 3);
78 while (count) {
79 *buf = (__force __le32)__raw_readl(addr);
80 buf++;
81 count -= 4;
82 }
83 break;
84 }
85 default:
86 WARN_ON(1);
87 }
88}
89
90static void bcma_host_soc_block_write(struct bcma_device *core,
91 const void *buffer,
92 size_t count, u16 offset, u8 reg_width)
93{
94 void __iomem *addr = core->io_addr + offset;
95
96 switch (reg_width) {
97 case sizeof(u8): {
98 const u8 *buf = buffer;
99
100 while (count) {
101 __raw_writeb(*buf, addr);
102 buf++;
103 count--;
104 }
105 break;
106 }
107 case sizeof(u16): {
108 const __le16 *buf = buffer;
109
110 WARN_ON(count & 1);
111 while (count) {
112 __raw_writew((__force u16)(*buf), addr);
113 buf++;
114 count -= 2;
115 }
116 break;
117 }
118 case sizeof(u32): {
119 const __le32 *buf = buffer;
120
121 WARN_ON(count & 3);
122 while (count) {
123 __raw_writel((__force u32)(*buf), addr);
124 buf++;
125 count -= 4;
126 }
127 break;
128 }
129 default:
130 WARN_ON(1);
131 }
132}
133#endif /* CONFIG_BCMA_BLOCKIO */
134
135static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
136{
137 return readl(core->io_wrap + offset);
138}
139
140static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
141 u32 value)
142{
143 writel(value, core->io_wrap + offset);
144}
145
146const struct bcma_host_ops bcma_host_soc_ops = {
147 .read8 = bcma_host_soc_read8,
148 .read16 = bcma_host_soc_read16,
149 .read32 = bcma_host_soc_read32,
150 .write8 = bcma_host_soc_write8,
151 .write16 = bcma_host_soc_write16,
152 .write32 = bcma_host_soc_write32,
153#ifdef CONFIG_BCMA_BLOCKIO
154 .block_read = bcma_host_soc_block_read,
155 .block_write = bcma_host_soc_block_write,
156#endif
157 .aread32 = bcma_host_soc_aread32,
158 .awrite32 = bcma_host_soc_awrite32,
159};
160
161int __init bcma_host_soc_register(struct bcma_soc *soc)
162{
163 struct bcma_bus *bus = &soc->bus;
164 int err;
165
166 /* iomap only first core. We have to read some register on this core
167 * to scan the bus.
168 */
169 bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
170 if (!bus->mmio)
171 return -ENOMEM;
172
173 /* Host specific */
174 bus->hosttype = BCMA_HOSTTYPE_SOC;
175 bus->ops = &bcma_host_soc_ops;
176
177 /* Register */
178 err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
179 if (err)
180 iounmap(bus->mmio);
181
182 return err;
183}
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 873e2e4ac55..7072216a2a3 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -66,6 +66,10 @@ static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
66static void bcma_release_core_dev(struct device *dev) 66static void bcma_release_core_dev(struct device *dev)
67{ 67{
68 struct bcma_device *core = container_of(dev, struct bcma_device, dev); 68 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
69 if (core->io_addr)
70 iounmap(core->io_addr);
71 if (core->io_wrap)
72 iounmap(core->io_wrap);
69 kfree(core); 73 kfree(core);
70} 74}
71 75
@@ -80,6 +84,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
80 case BCMA_CORE_CHIPCOMMON: 84 case BCMA_CORE_CHIPCOMMON:
81 case BCMA_CORE_PCI: 85 case BCMA_CORE_PCI:
82 case BCMA_CORE_PCIE: 86 case BCMA_CORE_PCIE:
87 case BCMA_CORE_MIPS_74K:
83 continue; 88 continue;
84 } 89 }
85 90
@@ -93,7 +98,10 @@ static int bcma_register_cores(struct bcma_bus *bus)
93 core->dma_dev = &bus->host_pci->dev; 98 core->dma_dev = &bus->host_pci->dev;
94 core->irq = bus->host_pci->irq; 99 core->irq = bus->host_pci->irq;
95 break; 100 break;
96 case BCMA_HOSTTYPE_NONE: 101 case BCMA_HOSTTYPE_SOC:
102 core->dev.dma_mask = &core->dev.coherent_dma_mask;
103 core->dma_dev = &core->dev;
104 break;
97 case BCMA_HOSTTYPE_SDIO: 105 case BCMA_HOSTTYPE_SDIO:
98 break; 106 break;
99 } 107 }
@@ -140,6 +148,13 @@ int bcma_bus_register(struct bcma_bus *bus)
140 bcma_core_chipcommon_init(&bus->drv_cc); 148 bcma_core_chipcommon_init(&bus->drv_cc);
141 } 149 }
142 150
151 /* Init MIPS core */
152 core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
153 if (core) {
154 bus->drv_mips.core = core;
155 bcma_core_mips_init(&bus->drv_mips);
156 }
157
143 /* Init PCIE core */ 158 /* Init PCIE core */
144 core = bcma_find_core(bus, BCMA_CORE_PCIE); 159 core = bcma_find_core(bus, BCMA_CORE_PCIE);
145 if (core) { 160 if (core) {
@@ -169,6 +184,59 @@ void bcma_bus_unregister(struct bcma_bus *bus)
169 bcma_unregister_cores(bus); 184 bcma_unregister_cores(bus);
170} 185}
171 186
187int __init bcma_bus_early_register(struct bcma_bus *bus,
188 struct bcma_device *core_cc,
189 struct bcma_device *core_mips)
190{
191 int err;
192 struct bcma_device *core;
193 struct bcma_device_id match;
194
195 bcma_init_bus(bus);
196
197 match.manuf = BCMA_MANUF_BCM;
198 match.id = BCMA_CORE_CHIPCOMMON;
199 match.class = BCMA_CL_SIM;
200 match.rev = BCMA_ANY_REV;
201
202 /* Scan for chip common core */
203 err = bcma_bus_scan_early(bus, &match, core_cc);
204 if (err) {
205 pr_err("Failed to scan for common core: %d\n", err);
206 return -1;
207 }
208
209 match.manuf = BCMA_MANUF_MIPS;
210 match.id = BCMA_CORE_MIPS_74K;
211 match.class = BCMA_CL_SIM;
212 match.rev = BCMA_ANY_REV;
213
214 /* Scan for mips core */
215 err = bcma_bus_scan_early(bus, &match, core_mips);
216 if (err) {
217 pr_err("Failed to scan for mips core: %d\n", err);
218 return -1;
219 }
220
221 /* Init CC core */
222 core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
223 if (core) {
224 bus->drv_cc.core = core;
225 bcma_core_chipcommon_init(&bus->drv_cc);
226 }
227
228 /* Init MIPS core */
229 core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
230 if (core) {
231 bus->drv_mips.core = core;
232 bcma_core_mips_init(&bus->drv_mips);
233 }
234
235 pr_info("Early bus registered\n");
236
237 return 0;
238}
239
172int __bcma_driver_register(struct bcma_driver *drv, struct module *owner) 240int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
173{ 241{
174 drv->drv.name = drv->name; 242 drv->drv.name = drv->name;
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 40d7dcce893..0ea390f9aa9 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -200,18 +200,162 @@ static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
200 return addrl; 200 return addrl;
201} 201}
202 202
203int bcma_bus_scan(struct bcma_bus *bus) 203static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
204 u16 index)
204{ 205{
205 u32 erombase; 206 struct bcma_device *core;
206 u32 __iomem *eromptr, *eromend;
207 207
208 list_for_each_entry(core, &bus->cores, list) {
209 if (core->core_index == index)
210 return core;
211 }
212 return NULL;
213}
214
215static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
216 struct bcma_device_id *match, int core_num,
217 struct bcma_device *core)
218{
219 s32 tmp;
220 u8 i, j;
208 s32 cia, cib; 221 s32 cia, cib;
209 u8 ports[2], wrappers[2]; 222 u8 ports[2], wrappers[2];
210 223
224 /* get CIs */
225 cia = bcma_erom_get_ci(bus, eromptr);
226 if (cia < 0) {
227 bcma_erom_push_ent(eromptr);
228 if (bcma_erom_is_end(bus, eromptr))
229 return -ESPIPE;
230 return -EILSEQ;
231 }
232 cib = bcma_erom_get_ci(bus, eromptr);
233 if (cib < 0)
234 return -EILSEQ;
235
236 /* parse CIs */
237 core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
238 core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
239 core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
240 ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
241 ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
242 wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
243 wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
244 core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
245
246 if (((core->id.manuf == BCMA_MANUF_ARM) &&
247 (core->id.id == 0xFFF)) ||
248 (ports[1] == 0)) {
249 bcma_erom_skip_component(bus, eromptr);
250 return -ENXIO;
251 }
252
253 /* check if component is a core at all */
254 if (wrappers[0] + wrappers[1] == 0) {
255 /* we could save addrl of the router
256 if (cid == BCMA_CORE_OOB_ROUTER)
257 */
258 bcma_erom_skip_component(bus, eromptr);
259 return -ENXIO;
260 }
261
262 if (bcma_erom_is_bridge(bus, eromptr)) {
263 bcma_erom_skip_component(bus, eromptr);
264 return -ENXIO;
265 }
266
267 if (bcma_find_core_by_index(bus, core_num)) {
268 bcma_erom_skip_component(bus, eromptr);
269 return -ENODEV;
270 }
271
272 if (match && ((match->manuf != BCMA_ANY_MANUF &&
273 match->manuf != core->id.manuf) ||
274 (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
275 (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
276 (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
277 )) {
278 bcma_erom_skip_component(bus, eromptr);
279 return -ENODEV;
280 }
281
282 /* get & parse master ports */
283 for (i = 0; i < ports[0]; i++) {
284 u32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
285 if (mst_port_d < 0)
286 return -EILSEQ;
287 }
288
289 /* get & parse slave ports */
290 for (i = 0; i < ports[1]; i++) {
291 for (j = 0; ; j++) {
292 tmp = bcma_erom_get_addr_desc(bus, eromptr,
293 SCAN_ADDR_TYPE_SLAVE, i);
294 if (tmp < 0) {
295 /* no more entries for port _i_ */
296 /* pr_debug("erom: slave port %d "
297 * "has %d descriptors\n", i, j); */
298 break;
299 } else {
300 if (i == 0 && j == 0)
301 core->addr = tmp;
302 }
303 }
304 }
305
306 /* get & parse master wrappers */
307 for (i = 0; i < wrappers[0]; i++) {
308 for (j = 0; ; j++) {
309 tmp = bcma_erom_get_addr_desc(bus, eromptr,
310 SCAN_ADDR_TYPE_MWRAP, i);
311 if (tmp < 0) {
312 /* no more entries for port _i_ */
313 /* pr_debug("erom: master wrapper %d "
314 * "has %d descriptors\n", i, j); */
315 break;
316 } else {
317 if (i == 0 && j == 0)
318 core->wrap = tmp;
319 }
320 }
321 }
322
323 /* get & parse slave wrappers */
324 for (i = 0; i < wrappers[1]; i++) {
325 u8 hack = (ports[1] == 1) ? 0 : 1;
326 for (j = 0; ; j++) {
327 tmp = bcma_erom_get_addr_desc(bus, eromptr,
328 SCAN_ADDR_TYPE_SWRAP, i + hack);
329 if (tmp < 0) {
330 /* no more entries for port _i_ */
331 /* pr_debug("erom: master wrapper %d "
332 * has %d descriptors\n", i, j); */
333 break;
334 } else {
335 if (wrappers[0] == 0 && !i && !j)
336 core->wrap = tmp;
337 }
338 }
339 }
340 if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
341 core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
342 if (!core->io_addr)
343 return -ENOMEM;
344 core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
345 if (!core->io_wrap) {
346 iounmap(core->io_addr);
347 return -ENOMEM;
348 }
349 }
350 return 0;
351}
352
353void bcma_init_bus(struct bcma_bus *bus)
354{
211 s32 tmp; 355 s32 tmp;
212 u8 i, j;
213 356
214 int err; 357 if (bus->init_done)
358 return;
215 359
216 INIT_LIST_HEAD(&bus->cores); 360 INIT_LIST_HEAD(&bus->cores);
217 bus->nr_cores = 0; 361 bus->nr_cores = 0;
@@ -222,9 +366,27 @@ int bcma_bus_scan(struct bcma_bus *bus)
222 bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT; 366 bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
223 bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT; 367 bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
224 bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT; 368 bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
369 bus->init_done = true;
370}
371
372int bcma_bus_scan(struct bcma_bus *bus)
373{
374 u32 erombase;
375 u32 __iomem *eromptr, *eromend;
376
377 int err, core_num = 0;
378
379 bcma_init_bus(bus);
225 380
226 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM); 381 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
227 eromptr = bus->mmio; 382 if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
383 eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
384 if (!eromptr)
385 return -ENOMEM;
386 } else {
387 eromptr = bus->mmio;
388 }
389
228 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32); 390 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
229 391
230 bcma_scan_switch_core(bus, erombase); 392 bcma_scan_switch_core(bus, erombase);
@@ -236,125 +398,89 @@ int bcma_bus_scan(struct bcma_bus *bus)
236 INIT_LIST_HEAD(&core->list); 398 INIT_LIST_HEAD(&core->list);
237 core->bus = bus; 399 core->bus = bus;
238 400
239 /* get CIs */ 401 err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
240 cia = bcma_erom_get_ci(bus, &eromptr); 402 if (err == -ENODEV) {
241 if (cia < 0) { 403 core_num++;
242 bcma_erom_push_ent(&eromptr);
243 if (bcma_erom_is_end(bus, &eromptr))
244 break;
245 err= -EILSEQ;
246 goto out;
247 }
248 cib = bcma_erom_get_ci(bus, &eromptr);
249 if (cib < 0) {
250 err= -EILSEQ;
251 goto out;
252 }
253
254 /* parse CIs */
255 core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
256 core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
257 core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
258 ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
259 ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
260 wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
261 wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
262 core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
263
264 if (((core->id.manuf == BCMA_MANUF_ARM) &&
265 (core->id.id == 0xFFF)) ||
266 (ports[1] == 0)) {
267 bcma_erom_skip_component(bus, &eromptr);
268 continue; 404 continue;
269 } 405 } else if (err == -ENXIO)
270
271 /* check if component is a core at all */
272 if (wrappers[0] + wrappers[1] == 0) {
273 /* we could save addrl of the router
274 if (cid == BCMA_CORE_OOB_ROUTER)
275 */
276 bcma_erom_skip_component(bus, &eromptr);
277 continue; 406 continue;
278 } 407 else if (err == -ESPIPE)
408 break;
409 else if (err < 0)
410 return err;
279 411
280 if (bcma_erom_is_bridge(bus, &eromptr)) { 412 core->core_index = core_num++;
281 bcma_erom_skip_component(bus, &eromptr); 413 bus->nr_cores++;
282 continue;
283 }
284 414
285 /* get & parse master ports */ 415 pr_info("Core %d found: %s "
286 for (i = 0; i < ports[0]; i++) { 416 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
287 u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr); 417 core->core_index, bcma_device_name(&core->id),
288 if (mst_port_d < 0) { 418 core->id.manuf, core->id.id, core->id.rev,
289 err= -EILSEQ; 419 core->id.class);
290 goto out;
291 }
292 }
293 420
294 /* get & parse slave ports */ 421 list_add(&core->list, &bus->cores);
295 for (i = 0; i < ports[1]; i++) { 422 }
296 for (j = 0; ; j++) {
297 tmp = bcma_erom_get_addr_desc(bus, &eromptr,
298 SCAN_ADDR_TYPE_SLAVE, i);
299 if (tmp < 0) {
300 /* no more entries for port _i_ */
301 /* pr_debug("erom: slave port %d "
302 * "has %d descriptors\n", i, j); */
303 break;
304 } else {
305 if (i == 0 && j == 0)
306 core->addr = tmp;
307 }
308 }
309 }
310 423
311 /* get & parse master wrappers */ 424 if (bus->hosttype == BCMA_HOSTTYPE_SOC)
312 for (i = 0; i < wrappers[0]; i++) { 425 iounmap(eromptr);
313 for (j = 0; ; j++) {
314 tmp = bcma_erom_get_addr_desc(bus, &eromptr,
315 SCAN_ADDR_TYPE_MWRAP, i);
316 if (tmp < 0) {
317 /* no more entries for port _i_ */
318 /* pr_debug("erom: master wrapper %d "
319 * "has %d descriptors\n", i, j); */
320 break;
321 } else {
322 if (i == 0 && j == 0)
323 core->wrap = tmp;
324 }
325 }
326 }
327 426
328 /* get & parse slave wrappers */ 427 return 0;
329 for (i = 0; i < wrappers[1]; i++) { 428}
330 u8 hack = (ports[1] == 1) ? 0 : 1; 429
331 for (j = 0; ; j++) { 430int __init bcma_bus_scan_early(struct bcma_bus *bus,
332 tmp = bcma_erom_get_addr_desc(bus, &eromptr, 431 struct bcma_device_id *match,
333 SCAN_ADDR_TYPE_SWRAP, i + hack); 432 struct bcma_device *core)
334 if (tmp < 0) { 433{
335 /* no more entries for port _i_ */ 434 u32 erombase;
336 /* pr_debug("erom: master wrapper %d " 435 u32 __iomem *eromptr, *eromend;
337 * has %d descriptors\n", i, j); */ 436
338 break; 437 int err = -ENODEV;
339 } else { 438 int core_num = 0;
340 if (wrappers[0] == 0 && !i && !j) 439
341 core->wrap = tmp; 440 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
342 } 441 if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
343 } 442 eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
344 } 443 if (!eromptr)
444 return -ENOMEM;
445 } else {
446 eromptr = bus->mmio;
447 }
448
449 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
450
451 bcma_scan_switch_core(bus, erombase);
452
453 while (eromptr < eromend) {
454 memset(core, 0, sizeof(*core));
455 INIT_LIST_HEAD(&core->list);
456 core->bus = bus;
345 457
458 err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
459 if (err == -ENODEV) {
460 core_num++;
461 continue;
462 } else if (err == -ENXIO)
463 continue;
464 else if (err == -ESPIPE)
465 break;
466 else if (err < 0)
467 return err;
468
469 core->core_index = core_num++;
470 bus->nr_cores++;
346 pr_info("Core %d found: %s " 471 pr_info("Core %d found: %s "
347 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n", 472 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
348 bus->nr_cores, bcma_device_name(&core->id), 473 core->core_index, bcma_device_name(&core->id),
349 core->id.manuf, core->id.id, core->id.rev, 474 core->id.manuf, core->id.id, core->id.rev,
350 core->id.class); 475 core->id.class);
351 476
352 core->core_index = bus->nr_cores++;
353 list_add(&core->list, &bus->cores); 477 list_add(&core->list, &bus->cores);
354 continue; 478 err = 0;
355out: 479 break;
356 return err;
357 } 480 }
358 481
359 return 0; 482 if (bus->hosttype == BCMA_HOSTTYPE_SOC)
483 iounmap(eromptr);
484
485 return err;
360} 486}
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index d1b23067619..07354883641 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -25,5 +25,6 @@ config ATH_DEBUG
25source "drivers/net/wireless/ath/ath5k/Kconfig" 25source "drivers/net/wireless/ath/ath5k/Kconfig"
26source "drivers/net/wireless/ath/ath9k/Kconfig" 26source "drivers/net/wireless/ath/ath9k/Kconfig"
27source "drivers/net/wireless/ath/carl9170/Kconfig" 27source "drivers/net/wireless/ath/carl9170/Kconfig"
28source "drivers/net/wireless/ath/ath6kl/Kconfig"
28 29
29endif 30endif
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile
index 0e8f528c81c..d1214696a35 100644
--- a/drivers/net/wireless/ath/Makefile
+++ b/drivers/net/wireless/ath/Makefile
@@ -1,6 +1,7 @@
1obj-$(CONFIG_ATH5K) += ath5k/ 1obj-$(CONFIG_ATH5K) += ath5k/
2obj-$(CONFIG_ATH9K_HW) += ath9k/ 2obj-$(CONFIG_ATH9K_HW) += ath9k/
3obj-$(CONFIG_CARL9170) += carl9170/ 3obj-$(CONFIG_CARL9170) += carl9170/
4obj-$(CONFIG_ATH6KL) += ath6kl/
4 5
5obj-$(CONFIG_ATH_COMMON) += ath.o 6obj-$(CONFIG_ATH_COMMON) += ath.o
6 7
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
index a2a167363db..e5be7e70181 100644
--- a/drivers/net/wireless/ath/ath5k/ahb.c
+++ b/drivers/net/wireless/ath/ath5k/ahb.c
@@ -169,7 +169,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
169 __set_bit(ATH_STAT_2G_DISABLED, ah->status); 169 __set_bit(ATH_STAT_2G_DISABLED, ah->status);
170 } 170 }
171 171
172 ret = ath5k_init_softc(ah, &ath_ahb_bus_ops); 172 ret = ath5k_init_ah(ah, &ath_ahb_bus_ops);
173 if (ret != 0) { 173 if (ret != 0) {
174 dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret); 174 dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
175 ret = -ENODEV; 175 ret = -ENODEV;
@@ -214,7 +214,7 @@ static int ath_ahb_remove(struct platform_device *pdev)
214 __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); 214 __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
215 } 215 }
216 216
217 ath5k_deinit_softc(ah); 217 ath5k_deinit_ah(ah);
218 platform_set_drvdata(pdev, NULL); 218 platform_set_drvdata(pdev, NULL);
219 ieee80211_free_hw(hw); 219 ieee80211_free_hw(hw);
220 220
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
index 603ae15f139..bea90e6be70 100644
--- a/drivers/net/wireless/ath/ath5k/ani.c
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -15,7 +15,6 @@
15 */ 15 */
16 16
17#include "ath5k.h" 17#include "ath5k.h"
18#include "base.h"
19#include "reg.h" 18#include "reg.h"
20#include "debug.h" 19#include "debug.h"
21#include "ani.h" 20#include "ani.h"
diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h
index 03401539709..7358b6c83c6 100644
--- a/drivers/net/wireless/ath/ath5k/ani.h
+++ b/drivers/net/wireless/ath/ath5k/ani.h
@@ -16,6 +16,10 @@
16#ifndef ANI_H 16#ifndef ANI_H
17#define ANI_H 17#define ANI_H
18 18
19#include "../ath.h"
20
21enum ath5k_phy_error_code;
22
19/* these thresholds are relative to the ATH5K_ANI_LISTEN_PERIOD */ 23/* these thresholds are relative to the ATH5K_ANI_LISTEN_PERIOD */
20#define ATH5K_ANI_LISTEN_PERIOD 100 24#define ATH5K_ANI_LISTEN_PERIOD 100
21#define ATH5K_ANI_OFDM_TRIG_HIGH 500 25#define ATH5K_ANI_OFDM_TRIG_HIGH 500
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 277d5cbe006..fecbcd9a425 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -131,13 +131,6 @@
131#define AR5K_REG_DISABLE_BITS(ah, _reg, _flags) \ 131#define AR5K_REG_DISABLE_BITS(ah, _reg, _flags) \
132 ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg) 132 ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg)
133 133
134/* Access to PHY registers */
135#define AR5K_PHY_READ(ah, _reg) \
136 ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2))
137
138#define AR5K_PHY_WRITE(ah, _reg, _val) \
139 ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2))
140
141/* Access QCU registers per queue */ 134/* Access QCU registers per queue */
142#define AR5K_REG_READ_Q(ah, _reg, _queue) \ 135#define AR5K_REG_READ_Q(ah, _reg, _queue) \
143 (ath5k_hw_reg_read(ah, _reg) & (1 << _queue)) \ 136 (ath5k_hw_reg_read(ah, _reg) & (1 << _queue)) \
@@ -166,7 +159,6 @@
166#define AR5K_TUNE_DMA_BEACON_RESP 2 159#define AR5K_TUNE_DMA_BEACON_RESP 2
167#define AR5K_TUNE_SW_BEACON_RESP 10 160#define AR5K_TUNE_SW_BEACON_RESP 10
168#define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0 161#define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0
169#define AR5K_TUNE_RADAR_ALERT false
170#define AR5K_TUNE_MIN_TX_FIFO_THRES 1 162#define AR5K_TUNE_MIN_TX_FIFO_THRES 1
171#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_FRAME_LEN / 64) + 1) 163#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_FRAME_LEN / 64) + 1)
172#define AR5K_TUNE_REGISTER_TIMEOUT 20000 164#define AR5K_TUNE_REGISTER_TIMEOUT 20000
@@ -295,17 +287,6 @@ enum ath5k_radio {
295 * Common silicon revision/version values 287 * Common silicon revision/version values
296 */ 288 */
297 289
298enum ath5k_srev_type {
299 AR5K_VERSION_MAC,
300 AR5K_VERSION_RAD,
301};
302
303struct ath5k_srev_name {
304 const char *sr_name;
305 enum ath5k_srev_type sr_type;
306 u_int sr_val;
307};
308
309#define AR5K_SREV_UNKNOWN 0xffff 290#define AR5K_SREV_UNKNOWN 0xffff
310 291
311#define AR5K_SREV_AR5210 0x00 /* Crete */ 292#define AR5K_SREV_AR5210 0x00 /* Crete */
@@ -424,7 +405,6 @@ enum ath5k_driver_mode {
424 AR5K_MODE_11A = 0, 405 AR5K_MODE_11A = 0,
425 AR5K_MODE_11B = 1, 406 AR5K_MODE_11B = 1,
426 AR5K_MODE_11G = 2, 407 AR5K_MODE_11G = 2,
427 AR5K_MODE_XR = 0,
428 AR5K_MODE_MAX = 3 408 AR5K_MODE_MAX = 3
429}; 409};
430 410
@@ -694,33 +674,6 @@ struct ath5k_gain {
694#define AR5K_SLOT_TIME_20 880 674#define AR5K_SLOT_TIME_20 880
695#define AR5K_SLOT_TIME_MAX 0xffff 675#define AR5K_SLOT_TIME_MAX 0xffff
696 676
697/* channel_flags */
698#define CHANNEL_CW_INT 0x0008 /* Contention Window interference detected */
699#define CHANNEL_CCK 0x0020 /* CCK channel */
700#define CHANNEL_OFDM 0x0040 /* OFDM channel */
701#define CHANNEL_2GHZ 0x0080 /* 2GHz channel. */
702#define CHANNEL_5GHZ 0x0100 /* 5GHz channel */
703#define CHANNEL_PASSIVE 0x0200 /* Only passive scan allowed */
704#define CHANNEL_DYN 0x0400 /* Dynamic CCK-OFDM channel (for g operation) */
705#define CHANNEL_XR 0x0800 /* XR channel */
706
707#define CHANNEL_A (CHANNEL_5GHZ | CHANNEL_OFDM)
708#define CHANNEL_B (CHANNEL_2GHZ | CHANNEL_CCK)
709#define CHANNEL_G (CHANNEL_2GHZ | CHANNEL_OFDM)
710#define CHANNEL_X (CHANNEL_5GHZ | CHANNEL_OFDM | CHANNEL_XR)
711
712#define CHANNEL_ALL (CHANNEL_OFDM | CHANNEL_CCK | \
713 CHANNEL_2GHZ | CHANNEL_5GHZ)
714
715#define CHANNEL_MODES CHANNEL_ALL
716
717/*
718 * Used internally for ath5k_hw_reset_tx_queue().
719 * Also see struct struct ieee80211_channel.
720 */
721#define IS_CHAN_XR(_c) ((_c->hw_value & CHANNEL_XR) != 0)
722#define IS_CHAN_B(_c) ((_c->hw_value & CHANNEL_B) != 0)
723
724/* 677/*
725 * The following structure is used to map 2GHz channels to 678 * The following structure is used to map 2GHz channels to
726 * 5GHz Atheros channels. 679 * 5GHz Atheros channels.
@@ -977,7 +930,7 @@ enum ath5k_power_mode {
977struct ath5k_capabilities { 930struct ath5k_capabilities {
978 /* 931 /*
979 * Supported PHY modes 932 * Supported PHY modes
980 * (ie. CHANNEL_A, CHANNEL_B, ...) 933 * (ie. AR5K_MODE_11A, AR5K_MODE_11B, ...)
981 */ 934 */
982 DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX); 935 DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX);
983 936
@@ -1013,16 +966,6 @@ struct ath5k_nfcal_hist {
1013 s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */ 966 s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */
1014}; 967};
1015 968
1016/**
1017 * struct avg_val - Helper structure for average calculation
1018 * @avg: contains the actual average value
1019 * @avg_weight: is used internally during calculation to prevent rounding errors
1020 */
1021struct ath5k_avg_val {
1022 int avg;
1023 int avg_weight;
1024};
1025
1026#define ATH5K_LED_MAX_NAME_LEN 31 969#define ATH5K_LED_MAX_NAME_LEN 31
1027 970
1028/* 971/*
@@ -1148,7 +1091,6 @@ struct ath5k_hw {
1148 bool rx_pending; /* rx tasklet pending */ 1091 bool rx_pending; /* rx tasklet pending */
1149 bool tx_pending; /* tx tasklet pending */ 1092 bool tx_pending; /* tx tasklet pending */
1150 1093
1151 u8 lladdr[ETH_ALEN];
1152 u8 bssidmask[ETH_ALEN]; 1094 u8 bssidmask[ETH_ALEN];
1153 1095
1154 unsigned int led_pin, /* GPIO pin for driving LED */ 1096 unsigned int led_pin, /* GPIO pin for driving LED */
@@ -1156,7 +1098,6 @@ struct ath5k_hw {
1156 1098
1157 struct work_struct reset_work; /* deferred chip reset */ 1099 struct work_struct reset_work; /* deferred chip reset */
1158 1100
1159 unsigned int rxbufsize; /* rx size based on mtu */
1160 struct list_head rxbuf; /* receive buffer */ 1101 struct list_head rxbuf; /* receive buffer */
1161 spinlock_t rxbuflock; 1102 spinlock_t rxbuflock;
1162 u32 *rxlink; /* link ptr in last RX desc */ 1103 u32 *rxlink; /* link ptr in last RX desc */
@@ -1208,10 +1149,8 @@ struct ath5k_hw {
1208 1149
1209 enum ath5k_version ah_version; 1150 enum ath5k_version ah_version;
1210 enum ath5k_radio ah_radio; 1151 enum ath5k_radio ah_radio;
1211 u32 ah_phy;
1212 u32 ah_mac_srev; 1152 u32 ah_mac_srev;
1213 u16 ah_mac_version; 1153 u16 ah_mac_version;
1214 u16 ah_mac_revision;
1215 u16 ah_phy_revision; 1154 u16 ah_phy_revision;
1216 u16 ah_radio_5ghz_revision; 1155 u16 ah_radio_5ghz_revision;
1217 u16 ah_radio_2ghz_revision; 1156 u16 ah_radio_2ghz_revision;
@@ -1279,12 +1218,6 @@ struct ath5k_hw {
1279 bool txp_setup; 1218 bool txp_setup;
1280 } ah_txpower; 1219 } ah_txpower;
1281 1220
1282 struct {
1283 bool r_enabled;
1284 int r_last_alert;
1285 struct ieee80211_channel r_last_channel;
1286 } ah_radar;
1287
1288 struct ath5k_nfcal_hist ah_nfcal_hist; 1221 struct ath5k_nfcal_hist ah_nfcal_hist;
1289 1222
1290 /* average beacon RSSI in our BSS (used by ANI) */ 1223 /* average beacon RSSI in our BSS (used by ANI) */
@@ -1327,36 +1260,13 @@ struct ath_bus_ops {
1327extern const struct ieee80211_ops ath5k_hw_ops; 1260extern const struct ieee80211_ops ath5k_hw_ops;
1328 1261
1329/* Initialization and detach functions */ 1262/* Initialization and detach functions */
1330int ath5k_init_softc(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops);
1331void ath5k_deinit_softc(struct ath5k_hw *ah);
1332int ath5k_hw_init(struct ath5k_hw *ah); 1263int ath5k_hw_init(struct ath5k_hw *ah);
1333void ath5k_hw_deinit(struct ath5k_hw *ah); 1264void ath5k_hw_deinit(struct ath5k_hw *ah);
1334 1265
1335int ath5k_sysfs_register(struct ath5k_hw *ah); 1266int ath5k_sysfs_register(struct ath5k_hw *ah);
1336void ath5k_sysfs_unregister(struct ath5k_hw *ah); 1267void ath5k_sysfs_unregister(struct ath5k_hw *ah);
1337 1268
1338/* base.c */
1339struct ath5k_buf;
1340struct ath5k_txq;
1341
1342void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable);
1343bool ath5k_any_vif_assoc(struct ath5k_hw *ah);
1344void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
1345 struct ath5k_txq *txq);
1346int ath5k_start(struct ieee80211_hw *hw);
1347void ath5k_stop(struct ieee80211_hw *hw);
1348void ath5k_mode_setup(struct ath5k_hw *ah, struct ieee80211_vif *vif);
1349void ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
1350 struct ieee80211_vif *vif);
1351int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan);
1352void ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf);
1353int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
1354void ath5k_beacon_config(struct ath5k_hw *ah);
1355void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
1356void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
1357
1358/*Chip id helper functions */ 1269/*Chip id helper functions */
1359const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
1360int ath5k_hw_read_srev(struct ath5k_hw *ah); 1270int ath5k_hw_read_srev(struct ath5k_hw *ah);
1361 1271
1362/* LED functions */ 1272/* LED functions */
@@ -1367,7 +1277,7 @@ void ath5k_unregister_leds(struct ath5k_hw *ah);
1367 1277
1368 1278
1369/* Reset Functions */ 1279/* Reset Functions */
1370int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); 1280int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1371int ath5k_hw_on_hold(struct ath5k_hw *ah); 1281int ath5k_hw_on_hold(struct ath5k_hw *ah);
1372int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, 1282int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1373 struct ieee80211_channel *channel, bool fast, bool skip_pcu); 1283 struct ieee80211_channel *channel, bool fast, bool skip_pcu);
@@ -1487,13 +1397,13 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
1487 1397
1488/* PHY functions */ 1398/* PHY functions */
1489/* Misc PHY functions */ 1399/* Misc PHY functions */
1490u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); 1400u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band);
1491int ath5k_hw_phy_disable(struct ath5k_hw *ah); 1401int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1492/* Gain_F optimization */ 1402/* Gain_F optimization */
1493enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); 1403enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
1494int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); 1404int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
1495/* PHY/RF channel functions */ 1405/* PHY/RF channel functions */
1496bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); 1406bool ath5k_channel_ok(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1497/* PHY calibration */ 1407/* PHY calibration */
1498void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); 1408void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
1499int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, 1409int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index f8a6b380d96..91627dd2c26 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -25,7 +25,6 @@
25#include "ath5k.h" 25#include "ath5k.h"
26#include "reg.h" 26#include "reg.h"
27#include "debug.h" 27#include "debug.h"
28#include "base.h"
29 28
30/** 29/**
31 * ath5k_hw_post - Power On Self Test helper function 30 * ath5k_hw_post - Power On Self Test helper function
@@ -95,7 +94,7 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
95/** 94/**
96 * ath5k_hw_init - Check if hw is supported and init the needed structs 95 * ath5k_hw_init - Check if hw is supported and init the needed structs
97 * 96 *
98 * @ah: The &struct ath5k_hw we got from the driver's init_softc function 97 * @ah: The &struct ath5k_hw associated with the device
99 * 98 *
100 * Check if the device is supported, perform a POST and initialize the needed 99 * Check if the device is supported, perform a POST and initialize the needed
101 * structs. Returns -ENOMEM if we don't have memory for the needed structs, 100 * structs. Returns -ENOMEM if we don't have memory for the needed structs,
@@ -114,7 +113,6 @@ int ath5k_hw_init(struct ath5k_hw *ah)
114 /* 113 /*
115 * HW information 114 * HW information
116 */ 115 */
117 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
118 ah->ah_bwmode = AR5K_BWMODE_DEFAULT; 116 ah->ah_bwmode = AR5K_BWMODE_DEFAULT;
119 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; 117 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
120 ah->ah_imr = 0; 118 ah->ah_imr = 0;
@@ -137,9 +135,8 @@ int ath5k_hw_init(struct ath5k_hw *ah)
137 else 135 else
138 ah->ah_version = AR5K_AR5212; 136 ah->ah_version = AR5K_AR5212;
139 137
140 /* Get the MAC revision */ 138 /* Get the MAC version */
141 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); 139 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
142 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
143 140
144 /* Fill the ath5k_hw struct with the needed functions */ 141 /* Fill the ath5k_hw struct with the needed functions */
145 ret = ath5k_hw_init_desc_functions(ah); 142 ret = ath5k_hw_init_desc_functions(ah);
@@ -147,7 +144,7 @@ int ath5k_hw_init(struct ath5k_hw *ah)
147 goto err; 144 goto err;
148 145
149 /* Bring device out of sleep and reset its units */ 146 /* Bring device out of sleep and reset its units */
150 ret = ath5k_hw_nic_wakeup(ah, 0, true); 147 ret = ath5k_hw_nic_wakeup(ah, NULL);
151 if (ret) 148 if (ret)
152 goto err; 149 goto err;
153 150
@@ -155,8 +152,7 @@ int ath5k_hw_init(struct ath5k_hw *ah)
155 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & 152 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
156 0xffffffff; 153 0xffffffff;
157 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, 154 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
158 CHANNEL_5GHZ); 155 IEEE80211_BAND_5GHZ);
159 ah->ah_phy = AR5K_PHY(0);
160 156
161 /* Try to identify radio chip based on its srev */ 157 /* Try to identify radio chip based on its srev */
162 switch (ah->ah_radio_5ghz_revision & 0xf0) { 158 switch (ah->ah_radio_5ghz_revision & 0xf0) {
@@ -164,14 +160,14 @@ int ath5k_hw_init(struct ath5k_hw *ah)
164 ah->ah_radio = AR5K_RF5111; 160 ah->ah_radio = AR5K_RF5111;
165 ah->ah_single_chip = false; 161 ah->ah_single_chip = false;
166 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, 162 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
167 CHANNEL_2GHZ); 163 IEEE80211_BAND_2GHZ);
168 break; 164 break;
169 case AR5K_SREV_RAD_5112: 165 case AR5K_SREV_RAD_5112:
170 case AR5K_SREV_RAD_2112: 166 case AR5K_SREV_RAD_2112:
171 ah->ah_radio = AR5K_RF5112; 167 ah->ah_radio = AR5K_RF5112;
172 ah->ah_single_chip = false; 168 ah->ah_single_chip = false;
173 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, 169 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
174 CHANNEL_2GHZ); 170 IEEE80211_BAND_2GHZ);
175 break; 171 break;
176 case AR5K_SREV_RAD_2413: 172 case AR5K_SREV_RAD_2413:
177 ah->ah_radio = AR5K_RF2413; 173 ah->ah_radio = AR5K_RF2413;
@@ -208,7 +204,7 @@ int ath5k_hw_init(struct ath5k_hw *ah)
208 ah->ah_radio = AR5K_RF5111; 204 ah->ah_radio = AR5K_RF5111;
209 ah->ah_single_chip = false; 205 ah->ah_single_chip = false;
210 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, 206 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
211 CHANNEL_2GHZ); 207 IEEE80211_BAND_2GHZ);
212 } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) || 208 } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) ||
213 ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) || 209 ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) ||
214 ah->ah_phy_revision == AR5K_SREV_PHY_2425) { 210 ah->ah_phy_revision == AR5K_SREV_PHY_2425) {
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index c3119a6caac..e9ea38d0fff 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -52,6 +52,7 @@
52#include <linux/uaccess.h> 52#include <linux/uaccess.h>
53#include <linux/slab.h> 53#include <linux/slab.h>
54#include <linux/etherdevice.h> 54#include <linux/etherdevice.h>
55#include <linux/nl80211.h>
55 56
56#include <net/ieee80211_radiotap.h> 57#include <net/ieee80211_radiotap.h>
57 58
@@ -61,6 +62,8 @@
61#include "reg.h" 62#include "reg.h"
62#include "debug.h" 63#include "debug.h"
63#include "ani.h" 64#include "ani.h"
65#include "ath5k.h"
66#include "../regd.h"
64 67
65#define CREATE_TRACE_POINTS 68#define CREATE_TRACE_POINTS
66#include "trace.h" 69#include "trace.h"
@@ -272,20 +275,18 @@ static unsigned int
272ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels, 275ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels,
273 unsigned int mode, unsigned int max) 276 unsigned int mode, unsigned int max)
274{ 277{
275 unsigned int count, size, chfreq, freq, ch; 278 unsigned int count, size, freq, ch;
276 enum ieee80211_band band; 279 enum ieee80211_band band;
277 280
278 switch (mode) { 281 switch (mode) {
279 case AR5K_MODE_11A: 282 case AR5K_MODE_11A:
280 /* 1..220, but 2GHz frequencies are filtered by check_channel */ 283 /* 1..220, but 2GHz frequencies are filtered by check_channel */
281 size = 220; 284 size = 220;
282 chfreq = CHANNEL_5GHZ;
283 band = IEEE80211_BAND_5GHZ; 285 band = IEEE80211_BAND_5GHZ;
284 break; 286 break;
285 case AR5K_MODE_11B: 287 case AR5K_MODE_11B:
286 case AR5K_MODE_11G: 288 case AR5K_MODE_11G:
287 size = 26; 289 size = 26;
288 chfreq = CHANNEL_2GHZ;
289 band = IEEE80211_BAND_2GHZ; 290 band = IEEE80211_BAND_2GHZ;
290 break; 291 break;
291 default: 292 default:
@@ -300,26 +301,19 @@ ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels,
300 if (freq == 0) /* mapping failed - not a standard channel */ 301 if (freq == 0) /* mapping failed - not a standard channel */
301 continue; 302 continue;
302 303
304 /* Write channel info, needed for ath5k_channel_ok() */
305 channels[count].center_freq = freq;
306 channels[count].band = band;
307 channels[count].hw_value = mode;
308
303 /* Check if channel is supported by the chipset */ 309 /* Check if channel is supported by the chipset */
304 if (!ath5k_channel_ok(ah, freq, chfreq)) 310 if (!ath5k_channel_ok(ah, &channels[count]))
305 continue; 311 continue;
306 312
307 if (!modparam_all_channels && 313 if (!modparam_all_channels &&
308 !ath5k_is_standard_channel(ch, band)) 314 !ath5k_is_standard_channel(ch, band))
309 continue; 315 continue;
310 316
311 /* Write channel info and increment counter */
312 channels[count].center_freq = freq;
313 channels[count].band = band;
314 switch (mode) {
315 case AR5K_MODE_11A:
316 case AR5K_MODE_11G:
317 channels[count].hw_value = chfreq | CHANNEL_OFDM;
318 break;
319 case AR5K_MODE_11B:
320 channels[count].hw_value = CHANNEL_B;
321 }
322
323 count++; 317 count++;
324 } 318 }
325 319
@@ -2349,7 +2343,7 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
2349\*************************/ 2343\*************************/
2350 2344
2351int __devinit 2345int __devinit
2352ath5k_init_softc(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) 2346ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
2353{ 2347{
2354 struct ieee80211_hw *hw = ah->hw; 2348 struct ieee80211_hw *hw = ah->hw;
2355 struct ath_common *common; 2349 struct ath_common *common;
@@ -2867,7 +2861,6 @@ ath5k_init(struct ieee80211_hw *hw)
2867 } 2861 }
2868 2862
2869 SET_IEEE80211_PERM_ADDR(hw, mac); 2863 SET_IEEE80211_PERM_ADDR(hw, mac);
2870 memcpy(&ah->lladdr, mac, ETH_ALEN);
2871 /* All MAC address bits matter for ACKs */ 2864 /* All MAC address bits matter for ACKs */
2872 ath5k_update_bssid_mask_and_opmode(ah, NULL); 2865 ath5k_update_bssid_mask_and_opmode(ah, NULL);
2873 2866
@@ -2903,7 +2896,7 @@ err:
2903} 2896}
2904 2897
2905void 2898void
2906ath5k_deinit_softc(struct ath5k_hw *ah) 2899ath5k_deinit_ah(struct ath5k_hw *ah)
2907{ 2900{
2908 struct ieee80211_hw *hw = ah->hw; 2901 struct ieee80211_hw *hw = ah->hw;
2909 2902
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index a81f28d5bdd..6c94c7ff235 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -38,19 +38,27 @@
38/* 38/*
39 * Definitions for the Atheros Wireless LAN controller driver. 39 * Definitions for the Atheros Wireless LAN controller driver.
40 */ 40 */
41#ifndef _DEV_ATH_ATHVAR_H 41#ifndef _DEV_ATH5K_BASE_H
42#define _DEV_ATH_ATHVAR_H 42#define _DEV_ATH5K_BASE_H
43 43
44#include <linux/interrupt.h> 44struct ieee80211_vif;
45#include <linux/list.h> 45struct ieee80211_hw;
46#include <linux/wireless.h> 46struct ath5k_hw;
47#include <linux/if_ether.h> 47struct ath5k_txq;
48#include <linux/rfkill.h> 48struct ieee80211_channel;
49#include <linux/workqueue.h> 49struct ath_bus_ops;
50enum nl80211_iftype;
50 51
51#include "ath5k.h" 52enum ath5k_srev_type {
52#include "../regd.h" 53 AR5K_VERSION_MAC,
53#include "../ath.h" 54 AR5K_VERSION_RAD,
55};
56
57struct ath5k_srev_name {
58 const char *sr_name;
59 enum ath5k_srev_type sr_type;
60 u_int sr_val;
61};
54 62
55struct ath5k_buf { 63struct ath5k_buf {
56 struct list_head list; 64 struct list_head list;
@@ -65,7 +73,6 @@ struct ath5k_vif {
65 enum nl80211_iftype opmode; 73 enum nl80211_iftype opmode;
66 int bslot; 74 int bslot;
67 struct ath5k_buf *bbuf; /* beacon buffer */ 75 struct ath5k_buf *bbuf; /* beacon buffer */
68 u8 lladdr[ETH_ALEN];
69}; 76};
70 77
71struct ath5k_vif_iter_data { 78struct ath5k_vif_iter_data {
@@ -78,8 +85,30 @@ struct ath5k_vif_iter_data {
78 enum nl80211_iftype opmode; 85 enum nl80211_iftype opmode;
79 int n_stas; 86 int n_stas;
80}; 87};
88
81void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif); 89void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif);
90bool ath5k_any_vif_assoc(struct ath5k_hw *ah);
91
92int ath5k_start(struct ieee80211_hw *hw);
93void ath5k_stop(struct ieee80211_hw *hw);
94
95void ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf);
96int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
97void ath5k_beacon_config(struct ath5k_hw *ah);
98void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable);
99
100void ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
101 struct ieee80211_vif *vif);
102int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan);
103void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
104void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
105void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
106 struct ath5k_txq *txq);
107
108const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
82 109
110int ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops);
111void ath5k_deinit_ah(struct ath5k_hw *ah);
83 112
84/* Check whether BSSID mask is supported */ 113/* Check whether BSSID mask is supported */
85#define ath5k_hw_hasbssidmask(_ah) (ah->ah_version == AR5K_AR5212) 114#define ath5k_hw_hasbssidmask(_ah) (ah->ah_version == AR5K_AR5212)
@@ -87,4 +116,4 @@ void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif);
87/* Check whether virtual EOL is supported */ 116/* Check whether virtual EOL is supported */
88#define ath5k_hw_hasveol(_ah) (ah->ah_version != AR5K_AR5210) 117#define ath5k_hw_hasveol(_ah) (ah->ah_version != AR5K_AR5210)
89 118
90#endif 119#endif /* _DEV_ATH5K_BASE_H */
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
index eefe670e28a..810fba96702 100644
--- a/drivers/net/wireless/ath/ath5k/caps.c
+++ b/drivers/net/wireless/ath/ath5k/caps.c
@@ -24,7 +24,7 @@
24#include "ath5k.h" 24#include "ath5k.h"
25#include "reg.h" 25#include "reg.h"
26#include "debug.h" 26#include "debug.h"
27#include "base.h" 27#include "../regd.h"
28 28
29/* 29/*
30 * Fill the capabilities struct 30 * Fill the capabilities struct
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index ccca724de17..fce8c904eea 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -58,19 +58,18 @@
58 * THE POSSIBILITY OF SUCH DAMAGES. 58 * THE POSSIBILITY OF SUCH DAMAGES.
59 */ 59 */
60 60
61#include "base.h" 61#include <linux/module.h>
62#include <linux/seq_file.h>
63#include <linux/list.h>
62#include "debug.h" 64#include "debug.h"
65#include "ath5k.h"
66#include "reg.h"
67#include "base.h"
63 68
64static unsigned int ath5k_debug; 69static unsigned int ath5k_debug;
65module_param_named(debug, ath5k_debug, uint, 0); 70module_param_named(debug, ath5k_debug, uint, 0);
66 71
67 72
68#ifdef CONFIG_ATH5K_DEBUG
69
70#include <linux/seq_file.h>
71#include "reg.h"
72#include "ani.h"
73
74static int ath5k_debugfs_open(struct inode *inode, struct file *file) 73static int ath5k_debugfs_open(struct inode *inode, struct file *file)
75{ 74{
76 file->private_data = inode->i_private; 75 file->private_data = inode->i_private;
@@ -1031,5 +1030,3 @@ ath5k_debug_printtxbuf(struct ath5k_hw *ah, struct ath5k_buf *bf)
1031 td->tx_stat.tx_status_0, td->tx_stat.tx_status_1, 1030 td->tx_stat.tx_status_0, td->tx_stat.tx_status_1,
1032 done ? ' ' : (ts.ts_status == 0) ? '*' : '!'); 1031 done ? ' ' : (ts.ts_status == 0) ? '*' : '!');
1033} 1032}
1034
1035#endif /* ifdef CONFIG_ATH5K_DEBUG */
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
index 846535f59ef..7e88dda8222 100644
--- a/drivers/net/wireless/ath/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
@@ -24,7 +24,6 @@
24#include "ath5k.h" 24#include "ath5k.h"
25#include "reg.h" 25#include "reg.h"
26#include "debug.h" 26#include "debug.h"
27#include "base.h"
28 27
29 28
30/************************\ 29/************************\
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
index 0d5d4033f12..2481f9c7f4b 100644
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -35,7 +35,6 @@
35#include "ath5k.h" 35#include "ath5k.h"
36#include "reg.h" 36#include "reg.h"
37#include "debug.h" 37#include "debug.h"
38#include "base.h"
39 38
40 39
41/*********\ 40/*********\
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 9068b916526..cd708c15b77 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -26,7 +26,6 @@
26#include "ath5k.h" 26#include "ath5k.h"
27#include "reg.h" 27#include "reg.h"
28#include "debug.h" 28#include "debug.h"
29#include "base.h"
30 29
31 30
32/******************\ 31/******************\
@@ -1780,13 +1779,12 @@ ath5k_eeprom_detach(struct ath5k_hw *ah)
1780int 1779int
1781ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel) 1780ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel)
1782{ 1781{
1783 switch (channel->hw_value & CHANNEL_MODES) { 1782 switch (channel->hw_value) {
1784 case CHANNEL_A: 1783 case AR5K_MODE_11A:
1785 case CHANNEL_XR:
1786 return AR5K_EEPROM_MODE_11A; 1784 return AR5K_EEPROM_MODE_11A;
1787 case CHANNEL_G: 1785 case AR5K_MODE_11G:
1788 return AR5K_EEPROM_MODE_11G; 1786 return AR5K_EEPROM_MODE_11G;
1789 case CHANNEL_B: 1787 case AR5K_MODE_11B:
1790 return AR5K_EEPROM_MODE_11B; 1788 return AR5K_EEPROM_MODE_11B;
1791 default: 1789 default:
1792 return -1; 1790 return -1;
diff --git a/drivers/net/wireless/ath/ath5k/gpio.c b/drivers/net/wireless/ath/ath5k/gpio.c
index bc90503f4b7..85929781191 100644
--- a/drivers/net/wireless/ath/ath5k/gpio.c
+++ b/drivers/net/wireless/ath/ath5k/gpio.c
@@ -23,7 +23,6 @@
23#include "ath5k.h" 23#include "ath5k.h"
24#include "reg.h" 24#include "reg.h"
25#include "debug.h" 25#include "debug.h"
26#include "base.h"
27 26
28/* 27/*
29 * Set led state 28 * Set led state
diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c
index 5ab607f40e0..1ffecc0fd3e 100644
--- a/drivers/net/wireless/ath/ath5k/initvals.c
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
@@ -22,7 +22,6 @@
22#include "ath5k.h" 22#include "ath5k.h"
23#include "reg.h" 23#include "reg.h"
24#include "debug.h" 24#include "debug.h"
25#include "base.h"
26 25
27/* 26/*
28 * Mode-independent initial register writes 27 * Mode-independent initial register writes
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index 8c17a00f7da..c1151c72371 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -41,7 +41,6 @@
41 41
42#include <linux/pci.h> 42#include <linux/pci.h>
43#include "ath5k.h" 43#include "ath5k.h"
44#include "base.h"
45 44
46#define ATH_SDEVICE(subv, subd) \ 45#define ATH_SDEVICE(subv, subd) \
47 .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \ 46 .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 2a715ca0c5e..0560234ec3f 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -41,8 +41,10 @@
41 * 41 *
42 */ 42 */
43 43
44#include <net/mac80211.h>
44#include <asm/unaligned.h> 45#include <asm/unaligned.h>
45 46
47#include "ath5k.h"
46#include "base.h" 48#include "base.h"
47#include "reg.h" 49#include "reg.h"
48 50
@@ -137,11 +139,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
137 /* Any MAC address is fine, all others are included through the 139 /* Any MAC address is fine, all others are included through the
138 * filter. 140 * filter.
139 */ 141 */
140 memcpy(&ah->lladdr, vif->addr, ETH_ALEN);
141 ath5k_hw_set_lladdr(ah, vif->addr); 142 ath5k_hw_set_lladdr(ah, vif->addr);
142 143
143 memcpy(&avf->lladdr, vif->addr, ETH_ALEN);
144
145 ath5k_update_bssid_mask_and_opmode(ah, vif); 144 ath5k_update_bssid_mask_and_opmode(ah, vif);
146 ret = 0; 145 ret = 0;
147end: 146end:
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
index eaf79b49341..c1dff2ced04 100644
--- a/drivers/net/wireless/ath/ath5k/pci.c
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -261,7 +261,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
261 ah->iobase = mem; /* So we can unmap it on detach */ 261 ah->iobase = mem; /* So we can unmap it on detach */
262 262
263 /* Initialize */ 263 /* Initialize */
264 ret = ath5k_init_softc(ah, &ath_pci_bus_ops); 264 ret = ath5k_init_ah(ah, &ath_pci_bus_ops);
265 if (ret) 265 if (ret)
266 goto err_free; 266 goto err_free;
267 267
@@ -287,7 +287,7 @@ ath5k_pci_remove(struct pci_dev *pdev)
287 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 287 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
288 struct ath5k_hw *ah = hw->priv; 288 struct ath5k_hw *ah = hw->priv;
289 289
290 ath5k_deinit_softc(ah); 290 ath5k_deinit_ah(ah);
291 pci_iounmap(pdev, ah->iobase); 291 pci_iounmap(pdev, ah->iobase);
292 pci_release_region(pdev, 0); 292 pci_release_region(pdev, 0);
293 pci_disable_device(pdev); 293 pci_disable_device(pdev);
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 06731384506..a7eafa3edc2 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -29,7 +29,6 @@
29#include "ath5k.h" 29#include "ath5k.h"
30#include "reg.h" 30#include "reg.h"
31#include "debug.h" 31#include "debug.h"
32#include "base.h"
33 32
34/* 33/*
35 * AR5212+ can use higher rates for ack transmission 34 * AR5212+ can use higher rates for ack transmission
@@ -152,7 +151,7 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
152 case AR5K_BWMODE_DEFAULT: 151 case AR5K_BWMODE_DEFAULT:
153 default: 152 default:
154 slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; 153 slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
155 if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot) 154 if ((channel->hw_value == AR5K_MODE_11B) && !ah->ah_short_slot)
156 slot_time = AR5K_INIT_SLOT_TIME_B; 155 slot_time = AR5K_INIT_SLOT_TIME_B;
157 break; 156 break;
158 } 157 }
@@ -183,7 +182,7 @@ unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
183 case AR5K_BWMODE_DEFAULT: 182 case AR5K_BWMODE_DEFAULT:
184 sifs = AR5K_INIT_SIFS_DEFAULT_BG; 183 sifs = AR5K_INIT_SIFS_DEFAULT_BG;
185 default: 184 default:
186 if (channel->hw_value & CHANNEL_5GHZ) 185 if (channel->band == IEEE80211_BAND_5GHZ)
187 sifs = AR5K_INIT_SIFS_DEFAULT_A; 186 sifs = AR5K_INIT_SIFS_DEFAULT_A;
188 break; 187 break;
189 } 188 }
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 81e465e7017..01cb72de44c 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -26,9 +26,9 @@
26 26
27#include "ath5k.h" 27#include "ath5k.h"
28#include "reg.h" 28#include "reg.h"
29#include "base.h"
30#include "rfbuffer.h" 29#include "rfbuffer.h"
31#include "rfgain.h" 30#include "rfgain.h"
31#include "../regd.h"
32 32
33 33
34/******************\ 34/******************\
@@ -38,7 +38,7 @@
38/* 38/*
39 * Get the PHY Chip revision 39 * Get the PHY Chip revision
40 */ 40 */
41u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) 41u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band)
42{ 42{
43 unsigned int i; 43 unsigned int i;
44 u32 srev; 44 u32 srev;
@@ -47,11 +47,11 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
47 /* 47 /*
48 * Set the radio chip access register 48 * Set the radio chip access register
49 */ 49 */
50 switch (chan) { 50 switch (band) {
51 case CHANNEL_2GHZ: 51 case IEEE80211_BAND_2GHZ:
52 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0)); 52 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
53 break; 53 break;
54 case CHANNEL_5GHZ: 54 case IEEE80211_BAND_5GHZ:
55 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); 55 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
56 break; 56 break;
57 default: 57 default:
@@ -84,14 +84,16 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
84/* 84/*
85 * Check if a channel is supported 85 * Check if a channel is supported
86 */ 86 */
87bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags) 87bool ath5k_channel_ok(struct ath5k_hw *ah, struct ieee80211_channel *channel)
88{ 88{
89 u16 freq = channel->center_freq;
90
89 /* Check if the channel is in our supported range */ 91 /* Check if the channel is in our supported range */
90 if (flags & CHANNEL_2GHZ) { 92 if (channel->band == IEEE80211_BAND_2GHZ) {
91 if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) && 93 if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
92 (freq <= ah->ah_capabilities.cap_range.range_2ghz_max)) 94 (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
93 return true; 95 return true;
94 } else if (flags & CHANNEL_5GHZ) 96 } else if (channel->band == IEEE80211_BAND_5GHZ)
95 if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) && 97 if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
96 (freq <= ah->ah_capabilities.cap_range.range_5ghz_max)) 98 (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
97 return true; 99 return true;
@@ -224,7 +226,7 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
224 ds_coef_exp, ds_coef_man, clock; 226 ds_coef_exp, ds_coef_man, clock;
225 227
226 BUG_ON(!(ah->ah_version == AR5K_AR5212) || 228 BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
227 !(channel->hw_value & CHANNEL_OFDM)); 229 (channel->hw_value == AR5K_MODE_11B));
228 230
229 /* Get coefficient 231 /* Get coefficient
230 * ALGO: coef = (5 * clock / carrier_freq) / 2 232 * ALGO: coef = (5 * clock / carrier_freq) / 2
@@ -298,7 +300,7 @@ static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah,
298 u32 delay; 300 u32 delay;
299 delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & 301 delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
300 AR5K_PHY_RX_DELAY_M; 302 AR5K_PHY_RX_DELAY_M;
301 delay = (channel->hw_value & CHANNEL_CCK) ? 303 delay = (channel->hw_value == AR5K_MODE_11B) ?
302 ((delay << 2) / 22) : (delay / 10); 304 ((delay << 2) / 22) : (delay / 10);
303 if (ah->ah_bwmode == AR5K_BWMODE_10MHZ) 305 if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
304 delay = delay << 1; 306 delay = delay << 1;
@@ -798,9 +800,9 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
798 } 800 }
799 801
800 /* Set Output and Driver bias current (OB/DB) */ 802 /* Set Output and Driver bias current (OB/DB) */
801 if (channel->hw_value & CHANNEL_2GHZ) { 803 if (channel->band == IEEE80211_BAND_2GHZ) {
802 804
803 if (channel->hw_value & CHANNEL_CCK) 805 if (channel->hw_value == AR5K_MODE_11B)
804 ee_mode = AR5K_EEPROM_MODE_11B; 806 ee_mode = AR5K_EEPROM_MODE_11B;
805 else 807 else
806 ee_mode = AR5K_EEPROM_MODE_11G; 808 ee_mode = AR5K_EEPROM_MODE_11G;
@@ -825,7 +827,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
825 AR5K_RF_DB_2GHZ, true); 827 AR5K_RF_DB_2GHZ, true);
826 828
827 /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */ 829 /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
828 } else if ((channel->hw_value & CHANNEL_5GHZ) || 830 } else if ((channel->band == IEEE80211_BAND_5GHZ) ||
829 (ah->ah_radio == AR5K_RF5111)) { 831 (ah->ah_radio == AR5K_RF5111)) {
830 832
831 /* For 11a, Turbo and XR we need to choose 833 /* For 11a, Turbo and XR we need to choose
@@ -857,7 +859,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
857 if (ah->ah_radio == AR5K_RF5111) { 859 if (ah->ah_radio == AR5K_RF5111) {
858 860
859 /* Set gain_F settings according to current step */ 861 /* Set gain_F settings according to current step */
860 if (channel->hw_value & CHANNEL_OFDM) { 862 if (channel->hw_value != AR5K_MODE_11B) {
861 863
862 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL, 864 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
863 AR5K_PHY_FRAME_CTL_TX_CLIP, 865 AR5K_PHY_FRAME_CTL_TX_CLIP,
@@ -914,7 +916,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
914 if (ah->ah_radio == AR5K_RF5112) { 916 if (ah->ah_radio == AR5K_RF5112) {
915 917
916 /* Set gain_F settings according to current step */ 918 /* Set gain_F settings according to current step */
917 if (channel->hw_value & CHANNEL_OFDM) { 919 if (channel->hw_value != AR5K_MODE_11B) {
918 920
919 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0], 921 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
920 AR5K_RF_MIXGAIN_OVR, true); 922 AR5K_RF_MIXGAIN_OVR, true);
@@ -1026,7 +1028,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
1026 } 1028 }
1027 1029
1028 if (ah->ah_radio == AR5K_RF5413 && 1030 if (ah->ah_radio == AR5K_RF5413 &&
1029 channel->hw_value & CHANNEL_2GHZ) { 1031 channel->band == IEEE80211_BAND_2GHZ) {
1030 1032
1031 ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE, 1033 ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
1032 true); 1034 true);
@@ -1138,7 +1140,7 @@ static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah,
1138 */ 1140 */
1139 data0 = data1 = 0; 1141 data0 = data1 = 0;
1140 1142
1141 if (channel->hw_value & CHANNEL_2GHZ) { 1143 if (channel->band == IEEE80211_BAND_2GHZ) {
1142 /* Map 2GHz channel to 5GHz Atheros channel ID */ 1144 /* Map 2GHz channel to 5GHz Atheros channel ID */
1143 ret = ath5k_hw_rf5111_chan2athchan( 1145 ret = ath5k_hw_rf5111_chan2athchan(
1144 ieee80211_frequency_to_channel(channel->center_freq), 1146 ieee80211_frequency_to_channel(channel->center_freq),
@@ -1265,10 +1267,9 @@ static int ath5k_hw_channel(struct ath5k_hw *ah,
1265 int ret; 1267 int ret;
1266 /* 1268 /*
1267 * Check bounds supported by the PHY (we don't care about regulatory 1269 * Check bounds supported by the PHY (we don't care about regulatory
1268 * restrictions at this point). Note: hw_value already has the band 1270 * restrictions at this point).
1269 * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok() 1271 */
1270 * of the band by that */ 1272 if (!ath5k_channel_ok(ah, channel)) {
1271 if (!ath5k_channel_ok(ah, channel->center_freq, channel->hw_value)) {
1272 ATH5K_ERR(ah, 1273 ATH5K_ERR(ah,
1273 "channel frequency (%u MHz) out of supported " 1274 "channel frequency (%u MHz) out of supported "
1274 "band range\n", 1275 "band range\n",
@@ -1614,7 +1615,7 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1614 ret = ath5k_hw_rf511x_iq_calibrate(ah); 1615 ret = ath5k_hw_rf511x_iq_calibrate(ah);
1615 1616
1616 if ((ah->ah_radio == AR5K_RF5111 || ah->ah_radio == AR5K_RF5112) && 1617 if ((ah->ah_radio == AR5K_RF5111 || ah->ah_radio == AR5K_RF5112) &&
1617 (channel->hw_value & CHANNEL_OFDM)) 1618 (channel->hw_value != AR5K_MODE_11B))
1618 ath5k_hw_request_rfgain_probe(ah); 1619 ath5k_hw_request_rfgain_probe(ah);
1619 1620
1620 return ret; 1621 return ret;
@@ -1641,7 +1642,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1641 /* Convert current frequency to fbin value (the same way channels 1642 /* Convert current frequency to fbin value (the same way channels
1642 * are stored on EEPROM, check out ath5k_eeprom_bin2freq) and scale 1643 * are stored on EEPROM, check out ath5k_eeprom_bin2freq) and scale
1643 * up by 2 so we can compare it later */ 1644 * up by 2 so we can compare it later */
1644 if (channel->hw_value & CHANNEL_2GHZ) { 1645 if (channel->band == IEEE80211_BAND_2GHZ) {
1645 chan_fbin = (channel->center_freq - 2300) * 10; 1646 chan_fbin = (channel->center_freq - 2300) * 10;
1646 freq_band = AR5K_EEPROM_BAND_2GHZ; 1647 freq_band = AR5K_EEPROM_BAND_2GHZ;
1647 } else { 1648 } else {
@@ -1703,7 +1704,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1703 spur_freq_sigma_delta = (spur_delta_phase >> 10); 1704 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1704 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4; 1705 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4;
1705 default: 1706 default:
1706 if (channel->hw_value == CHANNEL_A) { 1707 if (channel->band == IEEE80211_BAND_5GHZ) {
1707 /* Both sample_freq and chip_freq are 40MHz */ 1708 /* Both sample_freq and chip_freq are 40MHz */
1708 spur_delta_phase = (spur_offset << 17) / 25; 1709 spur_delta_phase = (spur_offset << 17) / 25;
1709 spur_freq_sigma_delta = 1710 spur_freq_sigma_delta =
@@ -2226,15 +2227,20 @@ ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
2226 idx_l = 0; 2227 idx_l = 0;
2227 idx_r = 0; 2228 idx_r = 0;
2228 2229
2229 if (!(channel->hw_value & CHANNEL_OFDM)) { 2230 switch (channel->hw_value) {
2231 case AR5K_EEPROM_MODE_11A:
2232 pcinfo = ee->ee_pwr_cal_a;
2233 mode = AR5K_EEPROM_MODE_11A;
2234 break;
2235 case AR5K_EEPROM_MODE_11B:
2230 pcinfo = ee->ee_pwr_cal_b; 2236 pcinfo = ee->ee_pwr_cal_b;
2231 mode = AR5K_EEPROM_MODE_11B; 2237 mode = AR5K_EEPROM_MODE_11B;
2232 } else if (channel->hw_value & CHANNEL_2GHZ) { 2238 break;
2239 case AR5K_EEPROM_MODE_11G:
2240 default:
2233 pcinfo = ee->ee_pwr_cal_g; 2241 pcinfo = ee->ee_pwr_cal_g;
2234 mode = AR5K_EEPROM_MODE_11G; 2242 mode = AR5K_EEPROM_MODE_11G;
2235 } else { 2243 break;
2236 pcinfo = ee->ee_pwr_cal_a;
2237 mode = AR5K_EEPROM_MODE_11A;
2238 } 2244 }
2239 max = ee->ee_n_piers[mode] - 1; 2245 max = ee->ee_n_piers[mode] - 1;
2240 2246
@@ -2303,15 +2309,20 @@ ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
2303 idx_l = 0; 2309 idx_l = 0;
2304 idx_r = 0; 2310 idx_r = 0;
2305 2311
2306 if (!(channel->hw_value & CHANNEL_OFDM)) { 2312 switch (channel->hw_value) {
2313 case AR5K_MODE_11A:
2314 rpinfo = ee->ee_rate_tpwr_a;
2315 mode = AR5K_EEPROM_MODE_11A;
2316 break;
2317 case AR5K_MODE_11B:
2307 rpinfo = ee->ee_rate_tpwr_b; 2318 rpinfo = ee->ee_rate_tpwr_b;
2308 mode = AR5K_EEPROM_MODE_11B; 2319 mode = AR5K_EEPROM_MODE_11B;
2309 } else if (channel->hw_value & CHANNEL_2GHZ) { 2320 break;
2321 case AR5K_MODE_11G:
2322 default:
2310 rpinfo = ee->ee_rate_tpwr_g; 2323 rpinfo = ee->ee_rate_tpwr_g;
2311 mode = AR5K_EEPROM_MODE_11G; 2324 mode = AR5K_EEPROM_MODE_11G;
2312 } else { 2325 break;
2313 rpinfo = ee->ee_rate_tpwr_a;
2314 mode = AR5K_EEPROM_MODE_11A;
2315 } 2326 }
2316 max = ee->ee_rate_target_pwr_num[mode] - 1; 2327 max = ee->ee_rate_target_pwr_num[mode] - 1;
2317 2328
@@ -2392,24 +2403,22 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
2392 2403
2393 ctl_mode = ath_regd_get_band_ctl(regulatory, channel->band); 2404 ctl_mode = ath_regd_get_band_ctl(regulatory, channel->band);
2394 2405
2395 switch (channel->hw_value & CHANNEL_MODES) { 2406 switch (channel->hw_value) {
2396 case CHANNEL_A: 2407 case AR5K_MODE_11A:
2397 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) 2408 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
2398 ctl_mode |= AR5K_CTL_TURBO; 2409 ctl_mode |= AR5K_CTL_TURBO;
2399 else 2410 else
2400 ctl_mode |= AR5K_CTL_11A; 2411 ctl_mode |= AR5K_CTL_11A;
2401 break; 2412 break;
2402 case CHANNEL_G: 2413 case AR5K_MODE_11G:
2403 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) 2414 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
2404 ctl_mode |= AR5K_CTL_TURBOG; 2415 ctl_mode |= AR5K_CTL_TURBOG;
2405 else 2416 else
2406 ctl_mode |= AR5K_CTL_11G; 2417 ctl_mode |= AR5K_CTL_11G;
2407 break; 2418 break;
2408 case CHANNEL_B: 2419 case AR5K_MODE_11B:
2409 ctl_mode |= AR5K_CTL_11B; 2420 ctl_mode |= AR5K_CTL_11B;
2410 break; 2421 break;
2411 case CHANNEL_XR:
2412 /* Fall through */
2413 default: 2422 default:
2414 return; 2423 return;
2415 } 2424 }
@@ -3292,7 +3301,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3292 3301
3293 /* Write OFDM timings on 5212*/ 3302 /* Write OFDM timings on 5212*/
3294 if (ah->ah_version == AR5K_AR5212 && 3303 if (ah->ah_version == AR5K_AR5212 &&
3295 channel->hw_value & CHANNEL_OFDM) { 3304 channel->hw_value != AR5K_MODE_11B) {
3296 3305
3297 ret = ath5k_hw_write_ofdm_timings(ah, channel); 3306 ret = ath5k_hw_write_ofdm_timings(ah, channel);
3298 if (ret) 3307 if (ret)
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 65f10398999..776654228ea 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -23,7 +23,6 @@ Queue Control Unit, DFS Control Unit Functions
23#include "ath5k.h" 23#include "ath5k.h"
24#include "reg.h" 24#include "reg.h"
25#include "debug.h" 25#include "debug.h"
26#include "base.h"
27 26
28 27
29/******************\ 28/******************\
@@ -185,13 +184,6 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
185 case AR5K_TX_QUEUE_CAB: 184 case AR5K_TX_QUEUE_CAB:
186 queue = AR5K_TX_QUEUE_ID_CAB; 185 queue = AR5K_TX_QUEUE_ID_CAB;
187 break; 186 break;
188 case AR5K_TX_QUEUE_XR_DATA:
189 if (ah->ah_version != AR5K_AR5212)
190 ATH5K_ERR(ah,
191 "XR data queues only supported in"
192 " 5212!\n");
193 queue = AR5K_TX_QUEUE_ID_XR_DATA;
194 break;
195 default: 187 default:
196 return -EINVAL; 188 return -EINVAL;
197 } 189 }
@@ -544,7 +536,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
544 * 536 *
545 * Also we have different lowest rate for 802.11a 537 * Also we have different lowest rate for 802.11a
546 */ 538 */
547 if (channel->hw_value & CHANNEL_5GHZ) 539 if (channel->band == IEEE80211_BAND_5GHZ)
548 rate = &ah->sbands[IEEE80211_BAND_5GHZ].bitrates[0]; 540 rate = &ah->sbands[IEEE80211_BAND_5GHZ].bitrates[0];
549 else 541 else
550 rate = &ah->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; 542 rate = &ah->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 0686c5d8d56..2abac257b4b 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -30,7 +30,6 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include "ath5k.h" 31#include "ath5k.h"
32#include "reg.h" 32#include "reg.h"
33#include "base.h"
34#include "debug.h" 33#include "debug.h"
35 34
36 35
@@ -102,12 +101,18 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
102 /* 101 /*
103 * Set core clock frequency 102 * Set core clock frequency
104 */ 103 */
105 if (channel->hw_value & CHANNEL_5GHZ) 104 switch (channel->hw_value) {
106 clock = 40; /* 802.11a */ 105 case AR5K_MODE_11A:
107 else if (channel->hw_value & CHANNEL_CCK) 106 clock = 40;
108 clock = 22; /* 802.11b */ 107 break;
109 else 108 case AR5K_MODE_11B:
110 clock = 44; /* 802.11g */ 109 clock = 22;
110 break;
111 case AR5K_MODE_11G:
112 default:
113 clock = 44;
114 break;
115 }
111 116
112 /* Use clock multiplier for non-default 117 /* Use clock multiplier for non-default
113 * bwmode */ 118 * bwmode */
@@ -581,8 +586,9 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
581 586
582/* 587/*
583 * Bring up MAC + PHY Chips and program PLL 588 * Bring up MAC + PHY Chips and program PLL
589 * Channel is NULL for the initial wakeup.
584 */ 590 */
585int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) 591int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel)
586{ 592{
587 struct pci_dev *pdev = ah->pdev; 593 struct pci_dev *pdev = ah->pdev;
588 u32 turbo, mode, clock, bus_flags; 594 u32 turbo, mode, clock, bus_flags;
@@ -592,7 +598,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
592 mode = 0; 598 mode = 0;
593 clock = 0; 599 clock = 0;
594 600
595 if ((ath5k_get_bus_type(ah) != ATH_AHB) || !initial) { 601 if ((ath5k_get_bus_type(ah) != ATH_AHB) || channel) {
596 /* Wakeup the device */ 602 /* Wakeup the device */
597 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); 603 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
598 if (ret) { 604 if (ret) {
@@ -652,7 +658,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
652 658
653 /* On initialization skip PLL programming since we don't have 659 /* On initialization skip PLL programming since we don't have
654 * a channel / mode set yet */ 660 * a channel / mode set yet */
655 if (initial) 661 if (!channel)
656 return 0; 662 return 0;
657 663
658 if (ah->ah_version != AR5K_AR5210) { 664 if (ah->ah_version != AR5K_AR5210) {
@@ -668,13 +674,13 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
668 clock = AR5K_PHY_PLL_RF5111; /*Zero*/ 674 clock = AR5K_PHY_PLL_RF5111; /*Zero*/
669 } 675 }
670 676
671 if (flags & CHANNEL_2GHZ) { 677 if (channel->band == IEEE80211_BAND_2GHZ) {
672 mode |= AR5K_PHY_MODE_FREQ_2GHZ; 678 mode |= AR5K_PHY_MODE_FREQ_2GHZ;
673 clock |= AR5K_PHY_PLL_44MHZ; 679 clock |= AR5K_PHY_PLL_44MHZ;
674 680
675 if (flags & CHANNEL_CCK) { 681 if (channel->hw_value == AR5K_MODE_11B) {
676 mode |= AR5K_PHY_MODE_MOD_CCK; 682 mode |= AR5K_PHY_MODE_MOD_CCK;
677 } else if (flags & CHANNEL_OFDM) { 683 } else {
678 /* XXX Dynamic OFDM/CCK is not supported by the 684 /* XXX Dynamic OFDM/CCK is not supported by the
679 * AR5211 so we set MOD_OFDM for plain g (no 685 * AR5211 so we set MOD_OFDM for plain g (no
680 * CCK headers) operation. We need to test 686 * CCK headers) operation. We need to test
@@ -686,27 +692,16 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
686 mode |= AR5K_PHY_MODE_MOD_OFDM; 692 mode |= AR5K_PHY_MODE_MOD_OFDM;
687 else 693 else
688 mode |= AR5K_PHY_MODE_MOD_DYN; 694 mode |= AR5K_PHY_MODE_MOD_DYN;
689 } else {
690 ATH5K_ERR(ah,
691 "invalid radio modulation mode\n");
692 return -EINVAL;
693 } 695 }
694 } else if (flags & CHANNEL_5GHZ) { 696 } else if (channel->band == IEEE80211_BAND_5GHZ) {
695 mode |= AR5K_PHY_MODE_FREQ_5GHZ; 697 mode |= (AR5K_PHY_MODE_FREQ_5GHZ |
698 AR5K_PHY_MODE_MOD_OFDM);
696 699
697 /* Different PLL setting for 5413 */ 700 /* Different PLL setting for 5413 */
698 if (ah->ah_radio == AR5K_RF5413) 701 if (ah->ah_radio == AR5K_RF5413)
699 clock = AR5K_PHY_PLL_40MHZ_5413; 702 clock = AR5K_PHY_PLL_40MHZ_5413;
700 else 703 else
701 clock |= AR5K_PHY_PLL_40MHZ; 704 clock |= AR5K_PHY_PLL_40MHZ;
702
703 if (flags & CHANNEL_OFDM)
704 mode |= AR5K_PHY_MODE_MOD_OFDM;
705 else {
706 ATH5K_ERR(ah,
707 "invalid radio modulation mode\n");
708 return -EINVAL;
709 }
710 } else { 705 } else {
711 ATH5K_ERR(ah, "invalid radio frequency mode\n"); 706 ATH5K_ERR(ah, "invalid radio frequency mode\n");
712 return -EINVAL; 707 return -EINVAL;
@@ -822,7 +817,7 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
822 u32 data; 817 u32 data;
823 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, 818 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
824 AR5K_PHY_CCKTXCTL); 819 AR5K_PHY_CCKTXCTL);
825 if (channel->hw_value & CHANNEL_5GHZ) 820 if (channel->band == IEEE80211_BAND_5GHZ)
826 data = 0xffb81020; 821 data = 0xffb81020;
827 else 822 else
828 data = 0xffb80d20; 823 data = 0xffb80d20;
@@ -905,7 +900,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
905 /* Set CCK to OFDM power delta on tx power 900 /* Set CCK to OFDM power delta on tx power
906 * adjustment register */ 901 * adjustment register */
907 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { 902 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
908 if (channel->hw_value == CHANNEL_G) 903 if (channel->hw_value == AR5K_MODE_11G)
909 ath5k_hw_reg_write(ah, 904 ath5k_hw_reg_write(ah,
910 AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1), 905 AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
911 AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) | 906 AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
@@ -1084,37 +1079,23 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1084 ret = 0; 1079 ret = 0;
1085 } 1080 }
1086 1081
1087 switch (channel->hw_value & CHANNEL_MODES) { 1082 mode = channel->hw_value;
1088 case CHANNEL_A: 1083 switch (mode) {
1089 mode = AR5K_MODE_11A; 1084 case AR5K_MODE_11A:
1090 break; 1085 break;
1091 case CHANNEL_G: 1086 case AR5K_MODE_11G:
1092
1093 if (ah->ah_version <= AR5K_AR5211) { 1087 if (ah->ah_version <= AR5K_AR5211) {
1094 ATH5K_ERR(ah, 1088 ATH5K_ERR(ah,
1095 "G mode not available on 5210/5211"); 1089 "G mode not available on 5210/5211");
1096 return -EINVAL; 1090 return -EINVAL;
1097 } 1091 }
1098
1099 mode = AR5K_MODE_11G;
1100 break; 1092 break;
1101 case CHANNEL_B: 1093 case AR5K_MODE_11B:
1102
1103 if (ah->ah_version < AR5K_AR5211) { 1094 if (ah->ah_version < AR5K_AR5211) {
1104 ATH5K_ERR(ah, 1095 ATH5K_ERR(ah,
1105 "B mode not available on 5210"); 1096 "B mode not available on 5210");
1106 return -EINVAL; 1097 return -EINVAL;
1107 } 1098 }
1108
1109 mode = AR5K_MODE_11B;
1110 break;
1111 case CHANNEL_XR:
1112 if (ah->ah_version == AR5K_AR5211) {
1113 ATH5K_ERR(ah,
1114 "XR mode not available on 5211");
1115 return -EINVAL;
1116 }
1117 mode = AR5K_MODE_XR;
1118 break; 1099 break;
1119 default: 1100 default:
1120 ATH5K_ERR(ah, 1101 ATH5K_ERR(ah,
@@ -1200,7 +1181,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1200 } 1181 }
1201 1182
1202 /* Wakeup the device */ 1183 /* Wakeup the device */
1203 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); 1184 ret = ath5k_hw_nic_wakeup(ah, channel);
1204 if (ret) 1185 if (ret)
1205 return ret; 1186 return ret;
1206 1187
diff --git a/drivers/net/wireless/ath/ath5k/rfkill.c b/drivers/net/wireless/ath/ath5k/rfkill.c
index 945fc9f21e7..270a319f3ae 100644
--- a/drivers/net/wireless/ath/ath5k/rfkill.c
+++ b/drivers/net/wireless/ath/ath5k/rfkill.c
@@ -33,7 +33,7 @@
33 * THE POSSIBILITY OF SUCH DAMAGES. 33 * THE POSSIBILITY OF SUCH DAMAGES.
34 */ 34 */
35 35
36#include "base.h" 36#include "ath5k.h"
37 37
38 38
39static inline void ath5k_rfkill_disable(struct ath5k_hw *ah) 39static inline void ath5k_rfkill_disable(struct ath5k_hw *ah)
diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c
index 0244a36ba95..9364da7bd13 100644
--- a/drivers/net/wireless/ath/ath5k/sysfs.c
+++ b/drivers/net/wireless/ath/ath5k/sysfs.c
@@ -1,7 +1,6 @@
1#include <linux/device.h> 1#include <linux/device.h>
2#include <linux/pci.h> 2#include <linux/pci.h>
3 3
4#include "base.h"
5#include "ath5k.h" 4#include "ath5k.h"
6#include "reg.h" 5#include "reg.h"
7 6
diff --git a/drivers/net/wireless/ath/ath5k/trace.h b/drivers/net/wireless/ath/ath5k/trace.h
index c741c871f4e..39f002ed4a8 100644
--- a/drivers/net/wireless/ath/ath5k/trace.h
+++ b/drivers/net/wireless/ath/ath5k/trace.h
@@ -2,7 +2,6 @@
2#define __TRACE_ATH5K_H 2#define __TRACE_ATH5K_H
3 3
4#include <linux/tracepoint.h> 4#include <linux/tracepoint.h>
5#include "base.h"
6 5
7#ifndef CONFIG_ATH5K_TRACER 6#ifndef CONFIG_ATH5K_TRACER
8#undef TRACE_EVENT 7#undef TRACE_EVENT
@@ -11,6 +10,8 @@ static inline void trace_ ## name(proto) {}
11#endif 10#endif
12 11
13struct sk_buff; 12struct sk_buff;
13struct ath5k_txq;
14struct ath5k_tx_status;
14 15
15#undef TRACE_SYSTEM 16#undef TRACE_SYSTEM
16#define TRACE_SYSTEM ath5k 17#define TRACE_SYSTEM ath5k
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig
new file mode 100644
index 00000000000..3d5f8be20ea
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/Kconfig
@@ -0,0 +1,15 @@
1config ATH6KL
2 tristate "Atheros ath6kl support"
3 depends on MMC
4 depends on CFG80211
5 ---help---
6 This module adds support for wireless adapters based on
7 Atheros AR6003 chipset running over SDIO. If you choose to
8 build it as a module, it will be called ath6kl. Pls note
9 that AR6002 and AR6001 are not supported by this driver.
10
11config ATH6KL_DEBUG
12 bool "Atheros ath6kl debugging"
13 depends on ATH6KL
14 ---help---
15 Enables debug support
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
new file mode 100644
index 00000000000..e1bb07ea8e8
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/Makefile
@@ -0,0 +1,35 @@
1#------------------------------------------------------------------------------
2# Copyright (c) 2004-2010 Atheros Communications Inc.
3# All rights reserved.
4#
5#
6#
7# Permission to use, copy, modify, and/or distribute this software for any
8# purpose with or without fee is hereby granted, provided that the above
9# copyright notice and this permission notice appear in all copies.
10#
11# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18#
19#
20#
21# Author(s): ="Atheros"
22#------------------------------------------------------------------------------
23
24obj-$(CONFIG_ATH6KL) := ath6kl.o
25ath6kl-y += debug.o
26ath6kl-y += htc_hif.o
27ath6kl-y += htc.o
28ath6kl-y += bmi.o
29ath6kl-y += cfg80211.o
30ath6kl-y += init.o
31ath6kl-y += main.o
32ath6kl-y += txrx.o
33ath6kl-y += wmi.o
34ath6kl-y += node.o
35ath6kl-y += sdio.o
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
new file mode 100644
index 00000000000..84676697d7e
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/bmi.c
@@ -0,0 +1,692 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
18#include "hif-ops.h"
19#include "target.h"
20#include "debug.h"
21
22static int ath6kl_get_bmi_cmd_credits(struct ath6kl *ar)
23{
24 u32 addr;
25 unsigned long timeout;
26 int ret;
27
28 ar->bmi.cmd_credits = 0;
29
30 /* Read the counter register to get the command credits */
31 addr = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
32
33 timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
34 while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) {
35
36 /*
37 * Hit the credit counter with a 4-byte access, the first byte
38 * read will hit the counter and cause a decrement, while the
39 * remaining 3 bytes has no effect. The rationale behind this
40 * is to make all HIF accesses 4-byte aligned.
41 */
42 ret = hif_read_write_sync(ar, addr,
43 (u8 *)&ar->bmi.cmd_credits, 4,
44 HIF_RD_SYNC_BYTE_INC);
45 if (ret) {
46 ath6kl_err("Unable to decrement the command credit count register: %d\n",
47 ret);
48 return ret;
49 }
50
51 /* The counter is only 8 bits.
52 * Ignore anything in the upper 3 bytes
53 */
54 ar->bmi.cmd_credits &= 0xFF;
55 }
56
57 if (!ar->bmi.cmd_credits) {
58 ath6kl_err("bmi communication timeout\n");
59 return -ETIMEDOUT;
60 }
61
62 return 0;
63}
64
65static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar, bool need_timeout)
66{
67 unsigned long timeout;
68 u32 rx_word = 0;
69 int ret = 0;
70
71 timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
72 while ((!need_timeout || time_before(jiffies, timeout)) && !rx_word) {
73 ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS,
74 (u8 *)&rx_word, sizeof(rx_word),
75 HIF_RD_SYNC_BYTE_INC);
76 if (ret) {
77 ath6kl_err("unable to read RX_LOOKAHEAD_VALID\n");
78 return ret;
79 }
80
81 /* all we really want is one bit */
82 rx_word &= (1 << ENDPOINT1);
83 }
84
85 if (!rx_word) {
86 ath6kl_err("bmi_recv_buf FIFO empty\n");
87 return -EINVAL;
88 }
89
90 return ret;
91}
92
93static int ath6kl_bmi_send_buf(struct ath6kl *ar, u8 *buf, u32 len)
94{
95 int ret;
96 u32 addr;
97
98 ret = ath6kl_get_bmi_cmd_credits(ar);
99 if (ret)
100 return ret;
101
102 addr = ar->mbox_info.htc_addr;
103
104 ret = hif_read_write_sync(ar, addr, buf, len,
105 HIF_WR_SYNC_BYTE_INC);
106 if (ret)
107 ath6kl_err("unable to send the bmi data to the device\n");
108
109 return ret;
110}
111
112static int ath6kl_bmi_recv_buf(struct ath6kl *ar,
113 u8 *buf, u32 len, bool want_timeout)
114{
115 int ret;
116 u32 addr;
117
118 /*
119 * During normal bootup, small reads may be required.
120 * Rather than issue an HIF Read and then wait as the Target
121 * adds successive bytes to the FIFO, we wait here until
122 * we know that response data is available.
123 *
124 * This allows us to cleanly timeout on an unexpected
125 * Target failure rather than risk problems at the HIF level.
126 * In particular, this avoids SDIO timeouts and possibly garbage
127 * data on some host controllers. And on an interconnect
128 * such as Compact Flash (as well as some SDIO masters) which
129 * does not provide any indication on data timeout, it avoids
130 * a potential hang or garbage response.
131 *
132 * Synchronization is more difficult for reads larger than the
133 * size of the MBOX FIFO (128B), because the Target is unable
134 * to push the 129th byte of data until AFTER the Host posts an
135 * HIF Read and removes some FIFO data. So for large reads the
136 * Host proceeds to post an HIF Read BEFORE all the data is
137 * actually available to read. Fortunately, large BMI reads do
138 * not occur in practice -- they're supported for debug/development.
139 *
140 * So Host/Target BMI synchronization is divided into these cases:
141 * CASE 1: length < 4
142 * Should not happen
143 *
144 * CASE 2: 4 <= length <= 128
145 * Wait for first 4 bytes to be in FIFO
146 * If CONSERVATIVE_BMI_READ is enabled, also wait for
147 * a BMI command credit, which indicates that the ENTIRE
148 * response is available in the the FIFO
149 *
150 * CASE 3: length > 128
151 * Wait for the first 4 bytes to be in FIFO
152 *
153 * For most uses, a small timeout should be sufficient and we will
154 * usually see a response quickly; but there may be some unusual
155 * (debug) cases of BMI_EXECUTE where we want an larger timeout.
156 * For now, we use an unbounded busy loop while waiting for
157 * BMI_EXECUTE.
158 *
159 * If BMI_EXECUTE ever needs to support longer-latency execution,
160 * especially in production, this code needs to be enhanced to sleep
161 * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently
162 * a function of Host processor speed.
163 */
164 if (len >= 4) { /* NB: Currently, always true */
165 ret = ath6kl_bmi_get_rx_lkahd(ar, want_timeout);
166 if (ret)
167 return ret;
168 }
169
170 addr = ar->mbox_info.htc_addr;
171 ret = hif_read_write_sync(ar, addr, buf, len,
172 HIF_RD_SYNC_BYTE_INC);
173 if (ret) {
174 ath6kl_err("Unable to read the bmi data from the device: %d\n",
175 ret);
176 return ret;
177 }
178
179 return 0;
180}
181
182int ath6kl_bmi_done(struct ath6kl *ar)
183{
184 int ret;
185 u32 cid = BMI_DONE;
186
187 if (ar->bmi.done_sent) {
188 ath6kl_dbg(ATH6KL_DBG_BMI, "bmi done skipped\n");
189 return 0;
190 }
191
192 ar->bmi.done_sent = true;
193
194 ret = ath6kl_bmi_send_buf(ar, (u8 *)&cid, sizeof(cid));
195 if (ret) {
196 ath6kl_err("Unable to send bmi done: %d\n", ret);
197 return ret;
198 }
199
200 ath6kl_bmi_cleanup(ar);
201
202 return 0;
203}
204
205int ath6kl_bmi_get_target_info(struct ath6kl *ar,
206 struct ath6kl_bmi_target_info *targ_info)
207{
208 int ret;
209 u32 cid = BMI_GET_TARGET_INFO;
210
211 if (ar->bmi.done_sent) {
212 ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
213 return -EACCES;
214 }
215
216 ret = ath6kl_bmi_send_buf(ar, (u8 *)&cid, sizeof(cid));
217 if (ret) {
218 ath6kl_err("Unable to send get target info: %d\n", ret);
219 return ret;
220 }
221
222 ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version,
223 sizeof(targ_info->version), true);
224 if (ret) {
225 ath6kl_err("Unable to recv target info: %d\n", ret);
226 return ret;
227 }
228
229 if (le32_to_cpu(targ_info->version) == TARGET_VERSION_SENTINAL) {
230 /* Determine how many bytes are in the Target's targ_info */
231 ret = ath6kl_bmi_recv_buf(ar,
232 (u8 *)&targ_info->byte_count,
233 sizeof(targ_info->byte_count),
234 true);
235 if (ret) {
236 ath6kl_err("unable to read target info byte count: %d\n",
237 ret);
238 return ret;
239 }
240
241 /*
242 * The target's targ_info doesn't match the host's targ_info.
243 * We need to do some backwards compatibility to make this work.
244 */
245 if (le32_to_cpu(targ_info->byte_count) != sizeof(*targ_info)) {
246 WARN_ON(1);
247 return -EINVAL;
248 }
249
250 /* Read the remainder of the targ_info */
251 ret = ath6kl_bmi_recv_buf(ar,
252 ((u8 *)targ_info) +
253 sizeof(targ_info->byte_count),
254 sizeof(*targ_info) -
255 sizeof(targ_info->byte_count),
256 true);
257
258 if (ret) {
259 ath6kl_err("Unable to read target info (%d bytes): %d\n",
260 targ_info->byte_count, ret);
261 return ret;
262 }
263 }
264
265 ath6kl_dbg(ATH6KL_DBG_BMI, "target info (ver: 0x%x type: 0x%x)\n",
266 targ_info->version, targ_info->type);
267
268 return 0;
269}
270
271int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
272{
273 u32 cid = BMI_READ_MEMORY;
274 int ret;
275 u32 offset;
276 u32 len_remain, rx_len;
277 u16 size;
278
279 if (ar->bmi.done_sent) {
280 ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
281 return -EACCES;
282 }
283
284 size = BMI_DATASZ_MAX + sizeof(cid) + sizeof(addr) + sizeof(len);
285 if (size > MAX_BMI_CMDBUF_SZ) {
286 WARN_ON(1);
287 return -EINVAL;
288 }
289 memset(ar->bmi.cmd_buf, 0, size);
290
291 ath6kl_dbg(ATH6KL_DBG_BMI,
292 "bmi read memory: device: addr: 0x%x, len: %d\n",
293 addr, len);
294
295 len_remain = len;
296
297 while (len_remain) {
298 rx_len = (len_remain < BMI_DATASZ_MAX) ?
299 len_remain : BMI_DATASZ_MAX;
300 offset = 0;
301 memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
302 offset += sizeof(cid);
303 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
304 offset += sizeof(addr);
305 memcpy(&(ar->bmi.cmd_buf[offset]), &rx_len, sizeof(rx_len));
306 offset += sizeof(len);
307
308 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
309 if (ret) {
310 ath6kl_err("Unable to write to the device: %d\n",
311 ret);
312 return ret;
313 }
314 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len, true);
315 if (ret) {
316 ath6kl_err("Unable to read from the device: %d\n",
317 ret);
318 return ret;
319 }
320 memcpy(&buf[len - len_remain], ar->bmi.cmd_buf, rx_len);
321 len_remain -= rx_len; addr += rx_len;
322 }
323
324 return 0;
325}
326
327int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
328{
329 u32 cid = BMI_WRITE_MEMORY;
330 int ret;
331 u32 offset;
332 u32 len_remain, tx_len;
333 const u32 header = sizeof(cid) + sizeof(addr) + sizeof(len);
334 u8 aligned_buf[BMI_DATASZ_MAX];
335 u8 *src;
336
337 if (ar->bmi.done_sent) {
338 ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
339 return -EACCES;
340 }
341
342 if ((BMI_DATASZ_MAX + header) > MAX_BMI_CMDBUF_SZ) {
343 WARN_ON(1);
344 return -EINVAL;
345 }
346
347 memset(ar->bmi.cmd_buf, 0, BMI_DATASZ_MAX + header);
348
349 ath6kl_dbg(ATH6KL_DBG_BMI,
350 "bmi write memory: addr: 0x%x, len: %d\n", addr, len);
351
352 len_remain = len;
353 while (len_remain) {
354 src = &buf[len - len_remain];
355
356 if (len_remain < (BMI_DATASZ_MAX - header)) {
357 if (len_remain & 3) {
358 /* align it with 4 bytes */
359 len_remain = len_remain +
360 (4 - (len_remain & 3));
361 memcpy(aligned_buf, src, len_remain);
362 src = aligned_buf;
363 }
364 tx_len = len_remain;
365 } else {
366 tx_len = (BMI_DATASZ_MAX - header);
367 }
368
369 offset = 0;
370 memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
371 offset += sizeof(cid);
372 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
373 offset += sizeof(addr);
374 memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len));
375 offset += sizeof(tx_len);
376 memcpy(&(ar->bmi.cmd_buf[offset]), src, tx_len);
377 offset += tx_len;
378
379 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
380 if (ret) {
381 ath6kl_err("Unable to write to the device: %d\n",
382 ret);
383 return ret;
384 }
385 len_remain -= tx_len; addr += tx_len;
386 }
387
388 return 0;
389}
390
391int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
392{
393 u32 cid = BMI_EXECUTE;
394 int ret;
395 u32 offset;
396 u16 size;
397
398 if (ar->bmi.done_sent) {
399 ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
400 return -EACCES;
401 }
402
403 size = sizeof(cid) + sizeof(addr) + sizeof(param);
404 if (size > MAX_BMI_CMDBUF_SZ) {
405 WARN_ON(1);
406 return -EINVAL;
407 }
408 memset(ar->bmi.cmd_buf, 0, size);
409
410 ath6kl_dbg(ATH6KL_DBG_BMI, "bmi execute: addr: 0x%x, param: %d)\n",
411 addr, *param);
412
413 offset = 0;
414 memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
415 offset += sizeof(cid);
416 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
417 offset += sizeof(addr);
418 memcpy(&(ar->bmi.cmd_buf[offset]), param, sizeof(*param));
419 offset += sizeof(*param);
420
421 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
422 if (ret) {
423 ath6kl_err("Unable to write to the device: %d\n", ret);
424 return ret;
425 }
426
427 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), false);
428 if (ret) {
429 ath6kl_err("Unable to read from the device: %d\n", ret);
430 return ret;
431 }
432
433 memcpy(param, ar->bmi.cmd_buf, sizeof(*param));
434
435 return 0;
436}
437
438int ath6kl_bmi_set_app_start(struct ath6kl *ar, u32 addr)
439{
440 u32 cid = BMI_SET_APP_START;
441 int ret;
442 u32 offset;
443 u16 size;
444
445 if (ar->bmi.done_sent) {
446 ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
447 return -EACCES;
448 }
449
450 size = sizeof(cid) + sizeof(addr);
451 if (size > MAX_BMI_CMDBUF_SZ) {
452 WARN_ON(1);
453 return -EINVAL;
454 }
455 memset(ar->bmi.cmd_buf, 0, size);
456
457 ath6kl_dbg(ATH6KL_DBG_BMI, "bmi set app start: addr: 0x%x\n", addr);
458
459 offset = 0;
460 memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
461 offset += sizeof(cid);
462 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
463 offset += sizeof(addr);
464
465 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
466 if (ret) {
467 ath6kl_err("Unable to write to the device: %d\n", ret);
468 return ret;
469 }
470
471 return 0;
472}
473
474int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
475{
476 u32 cid = BMI_READ_SOC_REGISTER;
477 int ret;
478 u32 offset;
479 u16 size;
480
481 if (ar->bmi.done_sent) {
482 ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
483 return -EACCES;
484 }
485
486 size = sizeof(cid) + sizeof(addr);
487 if (size > MAX_BMI_CMDBUF_SZ) {
488 WARN_ON(1);
489 return -EINVAL;
490 }
491 memset(ar->bmi.cmd_buf, 0, size);
492
493 ath6kl_dbg(ATH6KL_DBG_BMI, "bmi read SOC reg: addr: 0x%x\n", addr);
494
495 offset = 0;
496 memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
497 offset += sizeof(cid);
498 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
499 offset += sizeof(addr);
500
501 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
502 if (ret) {
503 ath6kl_err("Unable to write to the device: %d\n", ret);
504 return ret;
505 }
506
507 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), true);
508 if (ret) {
509 ath6kl_err("Unable to read from the device: %d\n", ret);
510 return ret;
511 }
512 memcpy(param, ar->bmi.cmd_buf, sizeof(*param));
513
514 return 0;
515}
516
517int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param)
518{
519 u32 cid = BMI_WRITE_SOC_REGISTER;
520 int ret;
521 u32 offset;
522 u16 size;
523
524 if (ar->bmi.done_sent) {
525 ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
526 return -EACCES;
527 }
528
529 size = sizeof(cid) + sizeof(addr) + sizeof(param);
530 if (size > MAX_BMI_CMDBUF_SZ) {
531 WARN_ON(1);
532 return -EINVAL;
533 }
534 memset(ar->bmi.cmd_buf, 0, size);
535
536 ath6kl_dbg(ATH6KL_DBG_BMI,
537 "bmi write SOC reg: addr: 0x%x, param: %d\n",
538 addr, param);
539
540 offset = 0;
541 memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
542 offset += sizeof(cid);
543 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
544 offset += sizeof(addr);
545 memcpy(&(ar->bmi.cmd_buf[offset]), &param, sizeof(param));
546 offset += sizeof(param);
547
548 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
549 if (ret) {
550 ath6kl_err("Unable to write to the device: %d\n", ret);
551 return ret;
552 }
553
554 return 0;
555}
556
557int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len)
558{
559 u32 cid = BMI_LZ_DATA;
560 int ret;
561 u32 offset;
562 u32 len_remain, tx_len;
563 const u32 header = sizeof(cid) + sizeof(len);
564 u16 size;
565
566 if (ar->bmi.done_sent) {
567 ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
568 return -EACCES;
569 }
570
571 size = BMI_DATASZ_MAX + header;
572 if (size > MAX_BMI_CMDBUF_SZ) {
573 WARN_ON(1);
574 return -EINVAL;
575 }
576 memset(ar->bmi.cmd_buf, 0, size);
577
578 ath6kl_dbg(ATH6KL_DBG_BMI, "bmi send LZ data: len: %d)\n",
579 len);
580
581 len_remain = len;
582 while (len_remain) {
583 tx_len = (len_remain < (BMI_DATASZ_MAX - header)) ?
584 len_remain : (BMI_DATASZ_MAX - header);
585
586 offset = 0;
587 memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
588 offset += sizeof(cid);
589 memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len));
590 offset += sizeof(tx_len);
591 memcpy(&(ar->bmi.cmd_buf[offset]), &buf[len - len_remain],
592 tx_len);
593 offset += tx_len;
594
595 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
596 if (ret) {
597 ath6kl_err("Unable to write to the device: %d\n",
598 ret);
599 return ret;
600 }
601
602 len_remain -= tx_len;
603 }
604
605 return 0;
606}
607
608int ath6kl_bmi_lz_stream_start(struct ath6kl *ar, u32 addr)
609{
610 u32 cid = BMI_LZ_STREAM_START;
611 int ret;
612 u32 offset;
613 u16 size;
614
615 if (ar->bmi.done_sent) {
616 ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
617 return -EACCES;
618 }
619
620 size = sizeof(cid) + sizeof(addr);
621 if (size > MAX_BMI_CMDBUF_SZ) {
622 WARN_ON(1);
623 return -EINVAL;
624 }
625 memset(ar->bmi.cmd_buf, 0, size);
626
627 ath6kl_dbg(ATH6KL_DBG_BMI,
628 "bmi LZ stream start: addr: 0x%x)\n",
629 addr);
630
631 offset = 0;
632 memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
633 offset += sizeof(cid);
634 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
635 offset += sizeof(addr);
636
637 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
638 if (ret) {
639 ath6kl_err("Unable to start LZ stream to the device: %d\n",
640 ret);
641 return ret;
642 }
643
644 return 0;
645}
646
647int ath6kl_bmi_fast_download(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
648{
649 int ret;
650 u32 last_word = 0;
651 u32 last_word_offset = len & ~0x3;
652 u32 unaligned_bytes = len & 0x3;
653
654 ret = ath6kl_bmi_lz_stream_start(ar, addr);
655 if (ret)
656 return ret;
657
658 if (unaligned_bytes) {
659 /* copy the last word into a zero padded buffer */
660 memcpy(&last_word, &buf[last_word_offset], unaligned_bytes);
661 }
662
663 ret = ath6kl_bmi_lz_data(ar, buf, last_word_offset);
664 if (ret)
665 return ret;
666
667 if (unaligned_bytes)
668 ret = ath6kl_bmi_lz_data(ar, (u8 *)&last_word, 4);
669
670 if (!ret) {
671 /* Close compressed stream and open a new (fake) one.
672 * This serves mainly to flush Target caches. */
673 ret = ath6kl_bmi_lz_stream_start(ar, 0x00);
674 }
675 return ret;
676}
677
678int ath6kl_bmi_init(struct ath6kl *ar)
679{
680 ar->bmi.cmd_buf = kzalloc(MAX_BMI_CMDBUF_SZ, GFP_ATOMIC);
681
682 if (!ar->bmi.cmd_buf)
683 return -ENOMEM;
684
685 return 0;
686}
687
688void ath6kl_bmi_cleanup(struct ath6kl *ar)
689{
690 kfree(ar->bmi.cmd_buf);
691 ar->bmi.cmd_buf = NULL;
692}
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h
new file mode 100644
index 00000000000..83546d76d97
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/bmi.h
@@ -0,0 +1,250 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef BMI_H
18#define BMI_H
19
20/*
21 * Bootloader Messaging Interface (BMI)
22 *
23 * BMI is a very simple messaging interface used during initialization
24 * to read memory, write memory, execute code, and to define an
25 * application entry PC.
26 *
27 * It is used to download an application to ATH6KL, to provide
28 * patches to code that is already resident on ATH6KL, and generally
29 * to examine and modify state. The Host has an opportunity to use
30 * BMI only once during bootup. Once the Host issues a BMI_DONE
31 * command, this opportunity ends.
32 *
33 * The Host writes BMI requests to mailbox0, and reads BMI responses
34 * from mailbox0. BMI requests all begin with a command
35 * (see below for specific commands), and are followed by
36 * command-specific data.
37 *
38 * Flow control:
39 * The Host can only issue a command once the Target gives it a
40 * "BMI Command Credit", using ATH6KL Counter #4. As soon as the
41 * Target has completed a command, it issues another BMI Command
42 * Credit (so the Host can issue the next command).
43 *
44 * BMI handles all required Target-side cache flushing.
45 */
46
47#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \
48 (sizeof(u32) * 3 /* cmd + addr + len */))
49
50/* Maximum data size used for BMI transfers */
51#define BMI_DATASZ_MAX 256
52
53/* BMI Commands */
54
55#define BMI_NO_COMMAND 0
56
57#define BMI_DONE 1
58/*
59 * Semantics: Host is done using BMI
60 * Request format:
61 * u32 command (BMI_DONE)
62 * Response format: none
63 */
64
65#define BMI_READ_MEMORY 2
66/*
67 * Semantics: Host reads ATH6KL memory
68 * Request format:
69 * u32 command (BMI_READ_MEMORY)
70 * u32 address
71 * u32 length, at most BMI_DATASZ_MAX
72 * Response format:
73 * u8 data[length]
74 */
75
76#define BMI_WRITE_MEMORY 3
77/*
78 * Semantics: Host writes ATH6KL memory
79 * Request format:
80 * u32 command (BMI_WRITE_MEMORY)
81 * u32 address
82 * u32 length, at most BMI_DATASZ_MAX
83 * u8 data[length]
84 * Response format: none
85 */
86
87#define BMI_EXECUTE 4
88/*
89 * Semantics: Causes ATH6KL to execute code
90 * Request format:
91 * u32 command (BMI_EXECUTE)
92 * u32 address
93 * u32 parameter
94 * Response format:
95 * u32 return value
96 */
97
98#define BMI_SET_APP_START 5
99/*
100 * Semantics: Set Target application starting address
101 * Request format:
102 * u32 command (BMI_SET_APP_START)
103 * u32 address
104 * Response format: none
105 */
106
107#define BMI_READ_SOC_REGISTER 6
108/*
109 * Semantics: Read a 32-bit Target SOC register.
110 * Request format:
111 * u32 command (BMI_READ_REGISTER)
112 * u32 address
113 * Response format:
114 * u32 value
115 */
116
117#define BMI_WRITE_SOC_REGISTER 7
118/*
119 * Semantics: Write a 32-bit Target SOC register.
120 * Request format:
121 * u32 command (BMI_WRITE_REGISTER)
122 * u32 address
123 * u32 value
124 *
125 * Response format: none
126 */
127
128#define BMI_GET_TARGET_ID 8
129#define BMI_GET_TARGET_INFO 8
130/*
131 * Semantics: Fetch the 4-byte Target information
132 * Request format:
133 * u32 command (BMI_GET_TARGET_ID/INFO)
134 * Response format1 (old firmware):
135 * u32 TargetVersionID
136 * Response format2 (newer firmware):
137 * u32 TARGET_VERSION_SENTINAL
138 * struct bmi_target_info;
139 */
140
141#define TARGET_VERSION_SENTINAL 0xffffffff
142#define TARGET_TYPE_AR6003 3
143
144#define BMI_ROMPATCH_INSTALL 9
145/*
146 * Semantics: Install a ROM Patch.
147 * Request format:
148 * u32 command (BMI_ROMPATCH_INSTALL)
149 * u32 Target ROM Address
150 * u32 Target RAM Address or Value (depending on Target Type)
151 * u32 Size, in bytes
152 * u32 Activate? 1-->activate;
153 * 0-->install but do not activate
154 * Response format:
155 * u32 PatchID
156 */
157
158#define BMI_ROMPATCH_UNINSTALL 10
159/*
160 * Semantics: Uninstall a previously-installed ROM Patch,
161 * automatically deactivating, if necessary.
162 * Request format:
163 * u32 command (BMI_ROMPATCH_UNINSTALL)
164 * u32 PatchID
165 *
166 * Response format: none
167 */
168
169#define BMI_ROMPATCH_ACTIVATE 11
170/*
171 * Semantics: Activate a list of previously-installed ROM Patches.
172 * Request format:
173 * u32 command (BMI_ROMPATCH_ACTIVATE)
174 * u32 rompatch_count
175 * u32 PatchID[rompatch_count]
176 *
177 * Response format: none
178 */
179
180#define BMI_ROMPATCH_DEACTIVATE 12
181/*
182 * Semantics: Deactivate a list of active ROM Patches.
183 * Request format:
184 * u32 command (BMI_ROMPATCH_DEACTIVATE)
185 * u32 rompatch_count
186 * u32 PatchID[rompatch_count]
187 *
188 * Response format: none
189 */
190
191
192#define BMI_LZ_STREAM_START 13
193/*
194 * Semantics: Begin an LZ-compressed stream of input
195 * which is to be uncompressed by the Target to an
196 * output buffer at address. The output buffer must
197 * be sufficiently large to hold the uncompressed
198 * output from the compressed input stream. This BMI
199 * command should be followed by a series of 1 or more
200 * BMI_LZ_DATA commands.
201 * u32 command (BMI_LZ_STREAM_START)
202 * u32 address
203 * Note: Not supported on all versions of ROM firmware.
204 */
205
206#define BMI_LZ_DATA 14
207/*
208 * Semantics: Host writes ATH6KL memory with LZ-compressed
209 * data which is uncompressed by the Target. This command
210 * must be preceded by a BMI_LZ_STREAM_START command. A series
211 * of BMI_LZ_DATA commands are considered part of a single
212 * input stream until another BMI_LZ_STREAM_START is issued.
213 * Request format:
214 * u32 command (BMI_LZ_DATA)
215 * u32 length (of compressed data),
216 * at most BMI_DATASZ_MAX
217 * u8 CompressedData[length]
218 * Response format: none
219 * Note: Not supported on all versions of ROM firmware.
220 */
221
222#define BMI_COMMUNICATION_TIMEOUT 1000 /* in msec */
223
224struct ath6kl;
225struct ath6kl_bmi_target_info {
226 __le32 byte_count; /* size of this structure */
227 __le32 version; /* target version id */
228 __le32 type; /* target type */
229} __packed;
230
231int ath6kl_bmi_init(struct ath6kl *ar);
232void ath6kl_bmi_cleanup(struct ath6kl *ar);
233int ath6kl_bmi_done(struct ath6kl *ar);
234int ath6kl_bmi_get_target_info(struct ath6kl *ar,
235 struct ath6kl_bmi_target_info *targ_info);
236int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len);
237int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len);
238int ath6kl_bmi_execute(struct ath6kl *ar,
239 u32 addr, u32 *param);
240int ath6kl_bmi_set_app_start(struct ath6kl *ar,
241 u32 addr);
242int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param);
243int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param);
244int ath6kl_bmi_lz_data(struct ath6kl *ar,
245 u8 *buf, u32 len);
246int ath6kl_bmi_lz_stream_start(struct ath6kl *ar,
247 u32 addr);
248int ath6kl_bmi_fast_download(struct ath6kl *ar,
249 u32 addr, u8 *buf, u32 len);
250#endif
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
new file mode 100644
index 00000000000..14559ffb145
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -0,0 +1,1538 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
18#include "cfg80211.h"
19#include "debug.h"
20
21#define RATETAB_ENT(_rate, _rateid, _flags) { \
22 .bitrate = (_rate), \
23 .flags = (_flags), \
24 .hw_value = (_rateid), \
25}
26
27#define CHAN2G(_channel, _freq, _flags) { \
28 .band = IEEE80211_BAND_2GHZ, \
29 .hw_value = (_channel), \
30 .center_freq = (_freq), \
31 .flags = (_flags), \
32 .max_antenna_gain = 0, \
33 .max_power = 30, \
34}
35
36#define CHAN5G(_channel, _flags) { \
37 .band = IEEE80211_BAND_5GHZ, \
38 .hw_value = (_channel), \
39 .center_freq = 5000 + (5 * (_channel)), \
40 .flags = (_flags), \
41 .max_antenna_gain = 0, \
42 .max_power = 30, \
43}
44
45static struct ieee80211_rate ath6kl_rates[] = {
46 RATETAB_ENT(10, 0x1, 0),
47 RATETAB_ENT(20, 0x2, 0),
48 RATETAB_ENT(55, 0x4, 0),
49 RATETAB_ENT(110, 0x8, 0),
50 RATETAB_ENT(60, 0x10, 0),
51 RATETAB_ENT(90, 0x20, 0),
52 RATETAB_ENT(120, 0x40, 0),
53 RATETAB_ENT(180, 0x80, 0),
54 RATETAB_ENT(240, 0x100, 0),
55 RATETAB_ENT(360, 0x200, 0),
56 RATETAB_ENT(480, 0x400, 0),
57 RATETAB_ENT(540, 0x800, 0),
58};
59
60#define ath6kl_a_rates (ath6kl_rates + 4)
61#define ath6kl_a_rates_size 8
62#define ath6kl_g_rates (ath6kl_rates + 0)
63#define ath6kl_g_rates_size 12
64
65static struct ieee80211_channel ath6kl_2ghz_channels[] = {
66 CHAN2G(1, 2412, 0),
67 CHAN2G(2, 2417, 0),
68 CHAN2G(3, 2422, 0),
69 CHAN2G(4, 2427, 0),
70 CHAN2G(5, 2432, 0),
71 CHAN2G(6, 2437, 0),
72 CHAN2G(7, 2442, 0),
73 CHAN2G(8, 2447, 0),
74 CHAN2G(9, 2452, 0),
75 CHAN2G(10, 2457, 0),
76 CHAN2G(11, 2462, 0),
77 CHAN2G(12, 2467, 0),
78 CHAN2G(13, 2472, 0),
79 CHAN2G(14, 2484, 0),
80};
81
82static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
83 CHAN5G(34, 0), CHAN5G(36, 0),
84 CHAN5G(38, 0), CHAN5G(40, 0),
85 CHAN5G(42, 0), CHAN5G(44, 0),
86 CHAN5G(46, 0), CHAN5G(48, 0),
87 CHAN5G(52, 0), CHAN5G(56, 0),
88 CHAN5G(60, 0), CHAN5G(64, 0),
89 CHAN5G(100, 0), CHAN5G(104, 0),
90 CHAN5G(108, 0), CHAN5G(112, 0),
91 CHAN5G(116, 0), CHAN5G(120, 0),
92 CHAN5G(124, 0), CHAN5G(128, 0),
93 CHAN5G(132, 0), CHAN5G(136, 0),
94 CHAN5G(140, 0), CHAN5G(149, 0),
95 CHAN5G(153, 0), CHAN5G(157, 0),
96 CHAN5G(161, 0), CHAN5G(165, 0),
97 CHAN5G(184, 0), CHAN5G(188, 0),
98 CHAN5G(192, 0), CHAN5G(196, 0),
99 CHAN5G(200, 0), CHAN5G(204, 0),
100 CHAN5G(208, 0), CHAN5G(212, 0),
101 CHAN5G(216, 0),
102};
103
104static struct ieee80211_supported_band ath6kl_band_2ghz = {
105 .n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
106 .channels = ath6kl_2ghz_channels,
107 .n_bitrates = ath6kl_g_rates_size,
108 .bitrates = ath6kl_g_rates,
109};
110
111static struct ieee80211_supported_band ath6kl_band_5ghz = {
112 .n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
113 .channels = ath6kl_5ghz_a_channels,
114 .n_bitrates = ath6kl_a_rates_size,
115 .bitrates = ath6kl_a_rates,
116};
117
118static int ath6kl_set_wpa_version(struct ath6kl *ar,
119 enum nl80211_wpa_versions wpa_version)
120{
121 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
122
123 if (!wpa_version) {
124 ar->auth_mode = NONE_AUTH;
125 } else if (wpa_version & NL80211_WPA_VERSION_2) {
126 ar->auth_mode = WPA2_AUTH;
127 } else if (wpa_version & NL80211_WPA_VERSION_1) {
128 ar->auth_mode = WPA_AUTH;
129 } else {
130 ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
131 return -ENOTSUPP;
132 }
133
134 return 0;
135}
136
137static int ath6kl_set_auth_type(struct ath6kl *ar,
138 enum nl80211_auth_type auth_type)
139{
140
141 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
142
143 switch (auth_type) {
144 case NL80211_AUTHTYPE_OPEN_SYSTEM:
145 ar->dot11_auth_mode = OPEN_AUTH;
146 break;
147 case NL80211_AUTHTYPE_SHARED_KEY:
148 ar->dot11_auth_mode = SHARED_AUTH;
149 break;
150 case NL80211_AUTHTYPE_NETWORK_EAP:
151 ar->dot11_auth_mode = LEAP_AUTH;
152 break;
153
154 case NL80211_AUTHTYPE_AUTOMATIC:
155 ar->dot11_auth_mode = OPEN_AUTH;
156 ar->auto_auth_stage = AUTH_OPEN_IN_PROGRESS;
157 break;
158
159 default:
160 ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type);
161 return -ENOTSUPP;
162 }
163
164 return 0;
165}
166
167static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)
168{
169 u8 *ar_cipher = ucast ? &ar->prwise_crypto : &ar->grp_crypto;
170 u8 *ar_cipher_len = ucast ? &ar->prwise_crypto_len : &ar->grp_crpto_len;
171
172 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
173 __func__, cipher, ucast);
174
175 switch (cipher) {
176 case 0:
177 /* our own hack to use value 0 as no crypto used */
178 *ar_cipher = NONE_CRYPT;
179 *ar_cipher_len = 0;
180 break;
181 case WLAN_CIPHER_SUITE_WEP40:
182 *ar_cipher = WEP_CRYPT;
183 *ar_cipher_len = 5;
184 break;
185 case WLAN_CIPHER_SUITE_WEP104:
186 *ar_cipher = WEP_CRYPT;
187 *ar_cipher_len = 13;
188 break;
189 case WLAN_CIPHER_SUITE_TKIP:
190 *ar_cipher = TKIP_CRYPT;
191 *ar_cipher_len = 0;
192 break;
193 case WLAN_CIPHER_SUITE_CCMP:
194 *ar_cipher = AES_CRYPT;
195 *ar_cipher_len = 0;
196 break;
197 default:
198 ath6kl_err("cipher 0x%x not supported\n", cipher);
199 return -ENOTSUPP;
200 }
201
202 return 0;
203}
204
205static void ath6kl_set_key_mgmt(struct ath6kl *ar, u32 key_mgmt)
206{
207 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
208
209 if (key_mgmt == WLAN_AKM_SUITE_PSK) {
210 if (ar->auth_mode == WPA_AUTH)
211 ar->auth_mode = WPA_PSK_AUTH;
212 else if (ar->auth_mode == WPA2_AUTH)
213 ar->auth_mode = WPA2_PSK_AUTH;
214 } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
215 ar->auth_mode = NONE_AUTH;
216 }
217}
218
219static bool ath6kl_cfg80211_ready(struct ath6kl *ar)
220{
221 if (!test_bit(WMI_READY, &ar->flag)) {
222 ath6kl_err("wmi is not ready\n");
223 return false;
224 }
225
226 if (!test_bit(WLAN_ENABLED, &ar->flag)) {
227 ath6kl_err("wlan disabled\n");
228 return false;
229 }
230
231 return true;
232}
233
234static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
235 struct cfg80211_connect_params *sme)
236{
237 struct ath6kl *ar = ath6kl_priv(dev);
238 int status;
239
240 ar->sme_state = SME_CONNECTING;
241
242 if (!ath6kl_cfg80211_ready(ar))
243 return -EIO;
244
245 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
246 ath6kl_err("destroy in progress\n");
247 return -EBUSY;
248 }
249
250 if (test_bit(SKIP_SCAN, &ar->flag) &&
251 ((sme->channel && sme->channel->center_freq == 0) ||
252 (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
253 ath6kl_err("SkipScan: channel or bssid invalid\n");
254 return -EINVAL;
255 }
256
257 if (down_interruptible(&ar->sem)) {
258 ath6kl_err("busy, couldn't get access\n");
259 return -ERESTARTSYS;
260 }
261
262 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
263 ath6kl_err("busy, destroy in progress\n");
264 up(&ar->sem);
265 return -EBUSY;
266 }
267
268 if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
269 /*
270 * sleep until the command queue drains
271 */
272 wait_event_interruptible_timeout(ar->event_wq,
273 ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0,
274 WMI_TIMEOUT);
275 if (signal_pending(current)) {
276 ath6kl_err("cmd queue drain timeout\n");
277 up(&ar->sem);
278 return -EINTR;
279 }
280 }
281
282 if (test_bit(CONNECTED, &ar->flag) &&
283 ar->ssid_len == sme->ssid_len &&
284 !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
285 ar->reconnect_flag = true;
286 status = ath6kl_wmi_reconnect_cmd(ar->wmi, ar->req_bssid,
287 ar->ch_hint);
288
289 up(&ar->sem);
290 if (status) {
291 ath6kl_err("wmi_reconnect_cmd failed\n");
292 return -EIO;
293 }
294 return 0;
295 } else if (ar->ssid_len == sme->ssid_len &&
296 !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
297 ath6kl_disconnect(ar);
298 }
299
300 memset(ar->ssid, 0, sizeof(ar->ssid));
301 ar->ssid_len = sme->ssid_len;
302 memcpy(ar->ssid, sme->ssid, sme->ssid_len);
303
304 if (sme->channel)
305 ar->ch_hint = sme->channel->center_freq;
306
307 memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
308 if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
309 memcpy(ar->req_bssid, sme->bssid, sizeof(ar->req_bssid));
310
311 ath6kl_set_wpa_version(ar, sme->crypto.wpa_versions);
312
313 status = ath6kl_set_auth_type(ar, sme->auth_type);
314 if (status) {
315 up(&ar->sem);
316 return status;
317 }
318
319 if (sme->crypto.n_ciphers_pairwise)
320 ath6kl_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
321 else
322 ath6kl_set_cipher(ar, 0, true);
323
324 ath6kl_set_cipher(ar, sme->crypto.cipher_group, false);
325
326 if (sme->crypto.n_akm_suites)
327 ath6kl_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
328
329 if ((sme->key_len) &&
330 (ar->auth_mode == NONE_AUTH) && (ar->prwise_crypto == WEP_CRYPT)) {
331 struct ath6kl_key *key = NULL;
332
333 if (sme->key_idx < WMI_MIN_KEY_INDEX ||
334 sme->key_idx > WMI_MAX_KEY_INDEX) {
335 ath6kl_err("key index %d out of bounds\n",
336 sme->key_idx);
337 up(&ar->sem);
338 return -ENOENT;
339 }
340
341 key = &ar->keys[sme->key_idx];
342 key->key_len = sme->key_len;
343 memcpy(key->key, sme->key, key->key_len);
344 key->cipher = ar->prwise_crypto;
345 ar->def_txkey_index = sme->key_idx;
346
347 ath6kl_wmi_addkey_cmd(ar->wmi, sme->key_idx,
348 ar->prwise_crypto,
349 GROUP_USAGE | TX_USAGE,
350 key->key_len,
351 NULL,
352 key->key, KEY_OP_INIT_VAL, NULL,
353 NO_SYNC_WMIFLAG);
354 }
355
356 if (!ar->usr_bss_filter) {
357 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) {
358 ath6kl_err("couldn't set bss filtering\n");
359 up(&ar->sem);
360 return -EIO;
361 }
362 }
363
364 ar->nw_type = ar->next_mode;
365
366 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
367 "%s: connect called with authmode %d dot11 auth %d"
368 " PW crypto %d PW crypto len %d GRP crypto %d"
369 " GRP crypto len %d channel hint %u\n",
370 __func__,
371 ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
372 ar->prwise_crypto_len, ar->grp_crypto,
373 ar->grp_crpto_len, ar->ch_hint);
374
375 ar->reconnect_flag = 0;
376 status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
377 ar->dot11_auth_mode, ar->auth_mode,
378 ar->prwise_crypto,
379 ar->prwise_crypto_len,
380 ar->grp_crypto, ar->grp_crpto_len,
381 ar->ssid_len, ar->ssid,
382 ar->req_bssid, ar->ch_hint,
383 ar->connect_ctrl_flags);
384
385 up(&ar->sem);
386
387 if (status == -EINVAL) {
388 memset(ar->ssid, 0, sizeof(ar->ssid));
389 ar->ssid_len = 0;
390 ath6kl_err("invalid request\n");
391 return -ENOENT;
392 } else if (status) {
393 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
394 return -EIO;
395 }
396
397 if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
398 ((ar->auth_mode == WPA_PSK_AUTH)
399 || (ar->auth_mode == WPA2_PSK_AUTH))) {
400 mod_timer(&ar->disconnect_timer,
401 jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
402 }
403
404 ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
405 set_bit(CONNECT_PEND, &ar->flag);
406
407 return 0;
408}
409
410void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
411 u8 *bssid, u16 listen_intvl,
412 u16 beacon_intvl,
413 enum network_type nw_type,
414 u8 beacon_ie_len, u8 assoc_req_len,
415 u8 assoc_resp_len, u8 *assoc_info)
416{
417 u16 size = 0;
418 u16 capability = 0;
419 struct cfg80211_bss *bss = NULL;
420 struct ieee80211_mgmt *mgmt = NULL;
421 struct ieee80211_channel *ibss_ch = NULL;
422 s32 signal = 50 * 100;
423 u8 ie_buf_len = 0;
424 unsigned char ie_buf[256];
425 unsigned char *ptr_ie_buf = ie_buf;
426 unsigned char *ieeemgmtbuf = NULL;
427 u8 source_mac[ETH_ALEN];
428 u16 capa_mask;
429 u16 capa_val;
430
431 /* capinfo + listen interval */
432 u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
433
434 /* capinfo + status code + associd */
435 u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
436
437 u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
438 u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
439 assoc_resp_ie_offset;
440
441 assoc_req_len -= assoc_req_ie_offset;
442 assoc_resp_len -= assoc_resp_ie_offset;
443
444 ar->auto_auth_stage = AUTH_IDLE;
445
446 if (nw_type & ADHOC_NETWORK) {
447 if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
448 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
449 "%s: ath6k not in ibss mode\n", __func__);
450 return;
451 }
452 }
453
454 if (nw_type & INFRA_NETWORK) {
455 if (ar->wdev->iftype != NL80211_IFTYPE_STATION) {
456 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
457 "%s: ath6k not in station mode\n", __func__);
458 return;
459 }
460 }
461
462 if (nw_type & ADHOC_NETWORK) {
463 capa_mask = WLAN_CAPABILITY_IBSS;
464 capa_val = WLAN_CAPABILITY_IBSS;
465 } else {
466 capa_mask = WLAN_CAPABILITY_ESS;
467 capa_val = WLAN_CAPABILITY_ESS;
468 }
469
470 /* Before informing the join/connect event, make sure that
471 * bss entry is present in scan list, if it not present
472 * construct and insert into scan list, otherwise that
473 * event will be dropped on the way by cfg80211, due to
474 * this keys will not be plumbed in case of WEP and
475 * application will not be aware of join/connect status. */
476 bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
477 ar->wdev->ssid, ar->wdev->ssid_len,
478 capa_mask, capa_val);
479
480 /*
481 * Earlier we were updating the cfg about bss by making a beacon frame
482 * only if the entry for bss is not there. This can have some issue if
483 * ROAM event is generated and a heavy traffic is ongoing. The ROAM
484 * event is handled through a work queue and by the time it really gets
485 * handled, BSS would have been aged out. So it is better to update the
486 * cfg about BSS irrespective of its entry being present right now or
487 * not.
488 */
489
490 if (nw_type & ADHOC_NETWORK) {
491 /* construct 802.11 mgmt beacon */
492 if (ptr_ie_buf) {
493 *ptr_ie_buf++ = WLAN_EID_SSID;
494 *ptr_ie_buf++ = ar->ssid_len;
495 memcpy(ptr_ie_buf, ar->ssid, ar->ssid_len);
496 ptr_ie_buf += ar->ssid_len;
497
498 *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
499 *ptr_ie_buf++ = 2; /* length */
500 *ptr_ie_buf++ = 0; /* ATIM window */
501 *ptr_ie_buf++ = 0; /* ATIM window */
502
503 /* TODO: update ibss params and include supported rates,
504 * DS param set, extened support rates, wmm. */
505
506 ie_buf_len = ptr_ie_buf - ie_buf;
507 }
508
509 capability |= WLAN_CAPABILITY_IBSS;
510
511 if (ar->prwise_crypto == WEP_CRYPT)
512 capability |= WLAN_CAPABILITY_PRIVACY;
513
514 memcpy(source_mac, ar->net_dev->dev_addr, ETH_ALEN);
515 ptr_ie_buf = ie_buf;
516 } else {
517 capability = *(u16 *) (&assoc_info[beacon_ie_len]);
518 memcpy(source_mac, bssid, ETH_ALEN);
519 ptr_ie_buf = assoc_req_ie;
520 ie_buf_len = assoc_req_len;
521 }
522
523 size = offsetof(struct ieee80211_mgmt, u)
524 + sizeof(mgmt->u.beacon)
525 + ie_buf_len;
526
527 ieeemgmtbuf = kzalloc(size, GFP_ATOMIC);
528 if (!ieeemgmtbuf) {
529 ath6kl_err("ieee mgmt buf alloc error\n");
530 cfg80211_put_bss(bss);
531 return;
532 }
533
534 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
535 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
536 IEEE80211_STYPE_BEACON);
537 memset(mgmt->da, 0xff, ETH_ALEN); /* broadcast addr */
538 memcpy(mgmt->sa, source_mac, ETH_ALEN);
539 memcpy(mgmt->bssid, bssid, ETH_ALEN);
540 mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_intvl);
541 mgmt->u.beacon.capab_info = cpu_to_le16(capability);
542 memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
543
544 ibss_ch = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
545
546 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
547 "%s: inform bss with bssid %pM channel %d beacon_intvl %d capability 0x%x\n",
548 __func__, mgmt->bssid, ibss_ch->hw_value,
549 beacon_intvl, capability);
550
551 bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
552 ibss_ch, mgmt,
553 size, signal, GFP_KERNEL);
554 kfree(ieeemgmtbuf);
555 cfg80211_put_bss(bss);
556
557 if (nw_type & ADHOC_NETWORK) {
558 cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
559 return;
560 }
561
562 if (ar->sme_state == SME_CONNECTING) {
563 /* inform connect result to cfg80211 */
564 ar->sme_state = SME_CONNECTED;
565 cfg80211_connect_result(ar->net_dev, bssid,
566 assoc_req_ie, assoc_req_len,
567 assoc_resp_ie, assoc_resp_len,
568 WLAN_STATUS_SUCCESS, GFP_KERNEL);
569 } else if (ar->sme_state == SME_CONNECTED) {
570 /* inform roam event to cfg80211 */
571 cfg80211_roamed(ar->net_dev, ibss_ch, bssid,
572 assoc_req_ie, assoc_req_len,
573 assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
574 }
575}
576
577static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
578 struct net_device *dev, u16 reason_code)
579{
580 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
581
582 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
583 reason_code);
584
585 if (!ath6kl_cfg80211_ready(ar))
586 return -EIO;
587
588 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
589 ath6kl_err("busy, destroy in progress\n");
590 return -EBUSY;
591 }
592
593 if (down_interruptible(&ar->sem)) {
594 ath6kl_err("busy, couldn't get access\n");
595 return -ERESTARTSYS;
596 }
597
598 ar->reconnect_flag = 0;
599 ath6kl_disconnect(ar);
600 memset(ar->ssid, 0, sizeof(ar->ssid));
601 ar->ssid_len = 0;
602
603 if (!test_bit(SKIP_SCAN, &ar->flag))
604 memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
605
606 up(&ar->sem);
607
608 return 0;
609}
610
611void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
612 u8 *bssid, u8 assoc_resp_len,
613 u8 *assoc_info, u16 proto_reason)
614{
615 struct ath6kl_key *key = NULL;
616 u16 status;
617
618 if (ar->scan_req) {
619 cfg80211_scan_done(ar->scan_req, true);
620 ar->scan_req = NULL;
621 }
622
623 if (ar->nw_type & ADHOC_NETWORK) {
624 if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
625 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
626 "%s: ath6k not in ibss mode\n", __func__);
627 return;
628 }
629 memset(bssid, 0, ETH_ALEN);
630 cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
631 return;
632 }
633
634 if (ar->nw_type & INFRA_NETWORK) {
635 if (ar->wdev->iftype != NL80211_IFTYPE_STATION) {
636 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
637 "%s: ath6k not in station mode\n", __func__);
638 return;
639 }
640 }
641
642 if (!test_bit(CONNECT_PEND, &ar->flag)) {
643 if (reason != DISCONNECT_CMD)
644 ath6kl_wmi_disconnect_cmd(ar->wmi);
645
646 return;
647 }
648
649 if (reason == NO_NETWORK_AVAIL) {
650 /* connect cmd failed */
651 ath6kl_wmi_disconnect_cmd(ar->wmi);
652 return;
653 }
654
655 if (reason != DISCONNECT_CMD)
656 return;
657
658 if (!ar->auto_auth_stage) {
659 clear_bit(CONNECT_PEND, &ar->flag);
660
661 if (ar->sme_state == SME_CONNECTING) {
662 cfg80211_connect_result(ar->net_dev,
663 bssid, NULL, 0,
664 NULL, 0,
665 WLAN_STATUS_UNSPECIFIED_FAILURE,
666 GFP_KERNEL);
667 } else {
668 cfg80211_disconnected(ar->net_dev, reason,
669 NULL, 0, GFP_KERNEL);
670 }
671
672 ar->sme_state = SME_DISCONNECTED;
673 return;
674 }
675
676 if (ar->dot11_auth_mode != OPEN_AUTH)
677 return;
678
679 /*
680 * If the current auth algorithm is open, try shared and
681 * make autoAuthStage idle. We do not make it leap for now
682 * being.
683 */
684 key = &ar->keys[ar->def_txkey_index];
685 if (down_interruptible(&ar->sem)) {
686 ath6kl_err("busy, couldn't get access\n");
687 return;
688 }
689
690 ar->dot11_auth_mode = SHARED_AUTH;
691 ar->auto_auth_stage = AUTH_IDLE;
692
693 ath6kl_wmi_addkey_cmd(ar->wmi,
694 ar->def_txkey_index,
695 ar->prwise_crypto,
696 GROUP_USAGE | TX_USAGE,
697 key->key_len, NULL,
698 key->key,
699 KEY_OP_INIT_VAL, NULL,
700 NO_SYNC_WMIFLAG);
701
702 status = ath6kl_wmi_connect_cmd(ar->wmi,
703 ar->nw_type,
704 ar->dot11_auth_mode,
705 ar->auth_mode,
706 ar->prwise_crypto,
707 ar->prwise_crypto_len,
708 ar->grp_crypto,
709 ar->grp_crpto_len,
710 ar->ssid_len,
711 ar->ssid,
712 ar->req_bssid,
713 ar->ch_hint,
714 ar->connect_ctrl_flags);
715 up(&ar->sem);
716}
717
718static inline bool is_ch_11a(u16 ch)
719{
720 return (!((ch >= 2412) && (ch <= 2484)));
721}
722
723/* struct ath6kl_node_table::nt_nodelock is locked when calling this */
724void ath6kl_cfg80211_scan_node(struct wiphy *wiphy, struct bss *ni)
725{
726 u16 size;
727 unsigned char *ieeemgmtbuf = NULL;
728 struct ieee80211_mgmt *mgmt;
729 struct ieee80211_channel *channel;
730 struct ieee80211_supported_band *band;
731 struct ath6kl_common_ie *cie;
732 s32 signal;
733 int freq;
734
735 cie = &ni->ni_cie;
736
737 if (is_ch_11a(cie->ie_chan))
738 band = wiphy->bands[IEEE80211_BAND_5GHZ]; /* 11a */
739 else if ((cie->ie_erp) || (cie->ie_xrates))
740 band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11g */
741 else
742 band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11b */
743
744 size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
745 ieeemgmtbuf = kmalloc(size, GFP_ATOMIC);
746 if (!ieeemgmtbuf) {
747 ath6kl_err("ieee mgmt buf alloc error\n");
748 return;
749 }
750
751 /*
752 * TODO: Update target to include 802.11 mac header while sending
753 * bss info. Target removes 802.11 mac header while sending the bss
754 * info to host, cfg80211 needs it, for time being just filling the
755 * da, sa and bssid fields alone.
756 */
757 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
758 memset(mgmt->da, 0xff, ETH_ALEN); /*broadcast addr */
759 memcpy(mgmt->sa, ni->ni_macaddr, ETH_ALEN);
760 memcpy(mgmt->bssid, ni->ni_macaddr, ETH_ALEN);
761 memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
762 ni->ni_buf, ni->ni_framelen);
763
764 freq = cie->ie_chan;
765 channel = ieee80211_get_channel(wiphy, freq);
766 signal = ni->ni_snr * 100;
767
768 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
769 "%s: bssid %pM ch %d freq %d size %d\n", __func__,
770 mgmt->bssid, channel->hw_value, freq, size);
771 cfg80211_inform_bss_frame(wiphy, channel, mgmt,
772 size, signal, GFP_ATOMIC);
773
774 kfree(ieeemgmtbuf);
775}
776
777static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
778 struct cfg80211_scan_request *request)
779{
780 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
781 int ret = 0;
782
783 if (!ath6kl_cfg80211_ready(ar))
784 return -EIO;
785
786 if (!ar->usr_bss_filter) {
787 if (ath6kl_wmi_bssfilter_cmd(ar->wmi,
788 (test_bit(CONNECTED, &ar->flag) ?
789 ALL_BUT_BSS_FILTER :
790 ALL_BSS_FILTER), 0) != 0) {
791 ath6kl_err("couldn't set bss filtering\n");
792 return -EIO;
793 }
794 }
795
796 if (request->n_ssids && request->ssids[0].ssid_len) {
797 u8 i;
798
799 if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
800 request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
801
802 for (i = 0; i < request->n_ssids; i++)
803 ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
804 SPECIFIC_SSID_FLAG,
805 request->ssids[i].ssid_len,
806 request->ssids[i].ssid);
807 }
808
809 if (ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, 0,
810 false, 0, 0, 0, NULL) != 0) {
811 ath6kl_err("wmi_startscan_cmd failed\n");
812 ret = -EIO;
813 }
814
815 ar->scan_req = request;
816
817 return ret;
818}
819
820void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
821{
822 int i;
823
824 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status %d\n", __func__, status);
825
826 if (!ar->scan_req)
827 return;
828
829 if ((status == -ECANCELED) || (status == -EBUSY)) {
830 cfg80211_scan_done(ar->scan_req, true);
831 goto out;
832 }
833
834 /* Translate data to cfg80211 mgmt format */
835 wlan_iterate_nodes(&ar->scan_table, ar->wdev->wiphy);
836
837 cfg80211_scan_done(ar->scan_req, false);
838
839 if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) {
840 for (i = 0; i < ar->scan_req->n_ssids; i++) {
841 ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
842 DISABLE_SSID_FLAG,
843 0, NULL);
844 }
845 }
846
847out:
848 ar->scan_req = NULL;
849}
850
851static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
852 u8 key_index, bool pairwise,
853 const u8 *mac_addr,
854 struct key_params *params)
855{
856 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
857 struct ath6kl_key *key = NULL;
858 u8 key_usage;
859 u8 key_type;
860 int status = 0;
861
862 if (!ath6kl_cfg80211_ready(ar))
863 return -EIO;
864
865 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
866 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
867 "%s: key index %d out of bounds\n", __func__,
868 key_index);
869 return -ENOENT;
870 }
871
872 key = &ar->keys[key_index];
873 memset(key, 0, sizeof(struct ath6kl_key));
874
875 if (pairwise)
876 key_usage = PAIRWISE_USAGE;
877 else
878 key_usage = GROUP_USAGE;
879
880 if (params) {
881 if (params->key_len > WLAN_MAX_KEY_LEN ||
882 params->seq_len > sizeof(key->seq))
883 return -EINVAL;
884
885 key->key_len = params->key_len;
886 memcpy(key->key, params->key, key->key_len);
887 key->seq_len = params->seq_len;
888 memcpy(key->seq, params->seq, key->seq_len);
889 key->cipher = params->cipher;
890 }
891
892 switch (key->cipher) {
893 case WLAN_CIPHER_SUITE_WEP40:
894 case WLAN_CIPHER_SUITE_WEP104:
895 key_type = WEP_CRYPT;
896 break;
897
898 case WLAN_CIPHER_SUITE_TKIP:
899 key_type = TKIP_CRYPT;
900 break;
901
902 case WLAN_CIPHER_SUITE_CCMP:
903 key_type = AES_CRYPT;
904 break;
905
906 default:
907 return -ENOTSUPP;
908 }
909
910 if (((ar->auth_mode == WPA_PSK_AUTH)
911 || (ar->auth_mode == WPA2_PSK_AUTH))
912 && (key_usage & GROUP_USAGE))
913 del_timer(&ar->disconnect_timer);
914
915 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
916 "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
917 __func__, key_index, key->key_len, key_type,
918 key_usage, key->seq_len);
919
920 ar->def_txkey_index = key_index;
921 status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
922 key_type, key_usage, key->key_len,
923 key->seq, key->key, KEY_OP_INIT_VAL,
924 (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
925
926 if (status)
927 return -EIO;
928
929 return 0;
930}
931
932static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
933 u8 key_index, bool pairwise,
934 const u8 *mac_addr)
935{
936 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
937
938 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
939
940 if (!ath6kl_cfg80211_ready(ar))
941 return -EIO;
942
943 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
944 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
945 "%s: key index %d out of bounds\n", __func__,
946 key_index);
947 return -ENOENT;
948 }
949
950 if (!ar->keys[key_index].key_len) {
951 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
952 "%s: index %d is empty\n", __func__, key_index);
953 return 0;
954 }
955
956 ar->keys[key_index].key_len = 0;
957
958 return ath6kl_wmi_deletekey_cmd(ar->wmi, key_index);
959}
960
961static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
962 u8 key_index, bool pairwise,
963 const u8 *mac_addr, void *cookie,
964 void (*callback) (void *cookie,
965 struct key_params *))
966{
967 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
968 struct ath6kl_key *key = NULL;
969 struct key_params params;
970
971 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
972
973 if (!ath6kl_cfg80211_ready(ar))
974 return -EIO;
975
976 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
977 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
978 "%s: key index %d out of bounds\n", __func__,
979 key_index);
980 return -ENOENT;
981 }
982
983 key = &ar->keys[key_index];
984 memset(&params, 0, sizeof(params));
985 params.cipher = key->cipher;
986 params.key_len = key->key_len;
987 params.seq_len = key->seq_len;
988 params.seq = key->seq;
989 params.key = key->key;
990
991 callback(cookie, &params);
992
993 return key->key_len ? 0 : -ENOENT;
994}
995
996static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
997 struct net_device *ndev,
998 u8 key_index, bool unicast,
999 bool multicast)
1000{
1001 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
1002 struct ath6kl_key *key = NULL;
1003 int status = 0;
1004 u8 key_usage;
1005
1006 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1007
1008 if (!ath6kl_cfg80211_ready(ar))
1009 return -EIO;
1010
1011 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1012 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1013 "%s: key index %d out of bounds\n",
1014 __func__, key_index);
1015 return -ENOENT;
1016 }
1017
1018 if (!ar->keys[key_index].key_len) {
1019 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1020 __func__, key_index);
1021 return -EINVAL;
1022 }
1023
1024 ar->def_txkey_index = key_index;
1025 key = &ar->keys[ar->def_txkey_index];
1026 key_usage = GROUP_USAGE;
1027 if (ar->prwise_crypto == WEP_CRYPT)
1028 key_usage |= TX_USAGE;
1029
1030 status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
1031 ar->prwise_crypto, key_usage,
1032 key->key_len, key->seq, key->key,
1033 KEY_OP_INIT_VAL, NULL,
1034 SYNC_BOTH_WMIFLAG);
1035 if (status)
1036 return -EIO;
1037
1038 return 0;
1039}
1040
1041void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
1042 bool ismcast)
1043{
1044 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1045 "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1046
1047 cfg80211_michael_mic_failure(ar->net_dev, ar->bssid,
1048 (ismcast ? NL80211_KEYTYPE_GROUP :
1049 NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1050 GFP_KERNEL);
1051}
1052
1053static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1054{
1055 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1056 int ret;
1057
1058 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1059 changed);
1060
1061 if (!ath6kl_cfg80211_ready(ar))
1062 return -EIO;
1063
1064 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1065 ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1066 if (ret != 0) {
1067 ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1068 return -EIO;
1069 }
1070 }
1071
1072 return 0;
1073}
1074
1075/*
1076 * The type nl80211_tx_power_setting replaces the following
1077 * data type from 2.6.36 onwards
1078*/
1079static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1080 enum nl80211_tx_power_setting type,
1081 int dbm)
1082{
1083 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1084 u8 ath6kl_dbm;
1085
1086 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1087 type, dbm);
1088
1089 if (!ath6kl_cfg80211_ready(ar))
1090 return -EIO;
1091
1092 switch (type) {
1093 case NL80211_TX_POWER_AUTOMATIC:
1094 return 0;
1095 case NL80211_TX_POWER_LIMITED:
1096 ar->tx_pwr = ath6kl_dbm = dbm;
1097 break;
1098 default:
1099 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1100 __func__, type);
1101 return -EOPNOTSUPP;
1102 }
1103
1104 ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, ath6kl_dbm);
1105
1106 return 0;
1107}
1108
1109static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1110{
1111 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1112
1113 if (!ath6kl_cfg80211_ready(ar))
1114 return -EIO;
1115
1116 if (test_bit(CONNECTED, &ar->flag)) {
1117 ar->tx_pwr = 0;
1118
1119 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi) != 0) {
1120 ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1121 return -EIO;
1122 }
1123
1124 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1125 5 * HZ);
1126
1127 if (signal_pending(current)) {
1128 ath6kl_err("target did not respond\n");
1129 return -EINTR;
1130 }
1131 }
1132
1133 *dbm = ar->tx_pwr;
1134 return 0;
1135}
1136
1137static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1138 struct net_device *dev,
1139 bool pmgmt, int timeout)
1140{
1141 struct ath6kl *ar = ath6kl_priv(dev);
1142 struct wmi_power_mode_cmd mode;
1143
1144 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1145 __func__, pmgmt, timeout);
1146
1147 if (!ath6kl_cfg80211_ready(ar))
1148 return -EIO;
1149
1150 if (pmgmt) {
1151 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1152 mode.pwr_mode = REC_POWER;
1153 } else {
1154 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1155 mode.pwr_mode = MAX_PERF_POWER;
1156 }
1157
1158 if (ath6kl_wmi_powermode_cmd(ar->wmi, mode.pwr_mode) != 0) {
1159 ath6kl_err("wmi_powermode_cmd failed\n");
1160 return -EIO;
1161 }
1162
1163 return 0;
1164}
1165
1166static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1167 struct net_device *ndev,
1168 enum nl80211_iftype type, u32 *flags,
1169 struct vif_params *params)
1170{
1171 struct ath6kl *ar = ath6kl_priv(ndev);
1172 struct wireless_dev *wdev = ar->wdev;
1173
1174 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1175
1176 if (!ath6kl_cfg80211_ready(ar))
1177 return -EIO;
1178
1179 switch (type) {
1180 case NL80211_IFTYPE_STATION:
1181 ar->next_mode = INFRA_NETWORK;
1182 break;
1183 case NL80211_IFTYPE_ADHOC:
1184 ar->next_mode = ADHOC_NETWORK;
1185 break;
1186 default:
1187 ath6kl_err("invalid interface type %u\n", type);
1188 return -EOPNOTSUPP;
1189 }
1190
1191 wdev->iftype = type;
1192
1193 return 0;
1194}
1195
1196static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1197 struct net_device *dev,
1198 struct cfg80211_ibss_params *ibss_param)
1199{
1200 struct ath6kl *ar = ath6kl_priv(dev);
1201 int status;
1202
1203 if (!ath6kl_cfg80211_ready(ar))
1204 return -EIO;
1205
1206 ar->ssid_len = ibss_param->ssid_len;
1207 memcpy(ar->ssid, ibss_param->ssid, ar->ssid_len);
1208
1209 if (ibss_param->channel)
1210 ar->ch_hint = ibss_param->channel->center_freq;
1211
1212 if (ibss_param->channel_fixed) {
1213 /*
1214 * TODO: channel_fixed: The channel should be fixed, do not
1215 * search for IBSSs to join on other channels. Target
1216 * firmware does not support this feature, needs to be
1217 * updated.
1218 */
1219 return -EOPNOTSUPP;
1220 }
1221
1222 memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
1223 if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1224 memcpy(ar->req_bssid, ibss_param->bssid, sizeof(ar->req_bssid));
1225
1226 ath6kl_set_wpa_version(ar, 0);
1227
1228 status = ath6kl_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1229 if (status)
1230 return status;
1231
1232 if (ibss_param->privacy) {
1233 ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1234 ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1235 } else {
1236 ath6kl_set_cipher(ar, 0, true);
1237 ath6kl_set_cipher(ar, 0, false);
1238 }
1239
1240 ar->nw_type = ar->next_mode;
1241
1242 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1243 "%s: connect called with authmode %d dot11 auth %d"
1244 " PW crypto %d PW crypto len %d GRP crypto %d"
1245 " GRP crypto len %d channel hint %u\n",
1246 __func__,
1247 ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
1248 ar->prwise_crypto_len, ar->grp_crypto,
1249 ar->grp_crpto_len, ar->ch_hint);
1250
1251 status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
1252 ar->dot11_auth_mode, ar->auth_mode,
1253 ar->prwise_crypto,
1254 ar->prwise_crypto_len,
1255 ar->grp_crypto, ar->grp_crpto_len,
1256 ar->ssid_len, ar->ssid,
1257 ar->req_bssid, ar->ch_hint,
1258 ar->connect_ctrl_flags);
1259 set_bit(CONNECT_PEND, &ar->flag);
1260
1261 return 0;
1262}
1263
1264static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1265 struct net_device *dev)
1266{
1267 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
1268
1269 if (!ath6kl_cfg80211_ready(ar))
1270 return -EIO;
1271
1272 ath6kl_disconnect(ar);
1273 memset(ar->ssid, 0, sizeof(ar->ssid));
1274 ar->ssid_len = 0;
1275
1276 return 0;
1277}
1278
1279static const u32 cipher_suites[] = {
1280 WLAN_CIPHER_SUITE_WEP40,
1281 WLAN_CIPHER_SUITE_WEP104,
1282 WLAN_CIPHER_SUITE_TKIP,
1283 WLAN_CIPHER_SUITE_CCMP,
1284};
1285
1286static bool is_rate_legacy(s32 rate)
1287{
1288 static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1289 6000, 9000, 12000, 18000, 24000,
1290 36000, 48000, 54000
1291 };
1292 u8 i;
1293
1294 for (i = 0; i < ARRAY_SIZE(legacy); i++)
1295 if (rate == legacy[i])
1296 return true;
1297
1298 return false;
1299}
1300
1301static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1302{
1303 static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1304 52000, 58500, 65000, 72200
1305 };
1306 u8 i;
1307
1308 for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1309 if (rate == ht20[i]) {
1310 if (i == ARRAY_SIZE(ht20) - 1)
1311 /* last rate uses sgi */
1312 *sgi = true;
1313 else
1314 *sgi = false;
1315
1316 *mcs = i;
1317 return true;
1318 }
1319 }
1320 return false;
1321}
1322
1323static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1324{
1325 static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1326 81000, 108000, 121500, 135000,
1327 150000
1328 };
1329 u8 i;
1330
1331 for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1332 if (rate == ht40[i]) {
1333 if (i == ARRAY_SIZE(ht40) - 1)
1334 /* last rate uses sgi */
1335 *sgi = true;
1336 else
1337 *sgi = false;
1338
1339 *mcs = i;
1340 return true;
1341 }
1342 }
1343
1344 return false;
1345}
1346
1347static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1348 u8 *mac, struct station_info *sinfo)
1349{
1350 struct ath6kl *ar = ath6kl_priv(dev);
1351 long left;
1352 bool sgi;
1353 s32 rate;
1354 int ret;
1355 u8 mcs;
1356
1357 if (memcmp(mac, ar->bssid, ETH_ALEN) != 0)
1358 return -ENOENT;
1359
1360 if (down_interruptible(&ar->sem))
1361 return -EBUSY;
1362
1363 set_bit(STATS_UPDATE_PEND, &ar->flag);
1364
1365 ret = ath6kl_wmi_get_stats_cmd(ar->wmi);
1366
1367 if (ret != 0) {
1368 up(&ar->sem);
1369 return -EIO;
1370 }
1371
1372 left = wait_event_interruptible_timeout(ar->event_wq,
1373 !test_bit(STATS_UPDATE_PEND,
1374 &ar->flag),
1375 WMI_TIMEOUT);
1376
1377 up(&ar->sem);
1378
1379 if (left == 0)
1380 return -ETIMEDOUT;
1381 else if (left < 0)
1382 return left;
1383
1384 if (ar->target_stats.rx_byte) {
1385 sinfo->rx_bytes = ar->target_stats.rx_byte;
1386 sinfo->filled |= STATION_INFO_RX_BYTES;
1387 sinfo->rx_packets = ar->target_stats.rx_pkt;
1388 sinfo->filled |= STATION_INFO_RX_PACKETS;
1389 }
1390
1391 if (ar->target_stats.tx_byte) {
1392 sinfo->tx_bytes = ar->target_stats.tx_byte;
1393 sinfo->filled |= STATION_INFO_TX_BYTES;
1394 sinfo->tx_packets = ar->target_stats.tx_pkt;
1395 sinfo->filled |= STATION_INFO_TX_PACKETS;
1396 }
1397
1398 sinfo->signal = ar->target_stats.cs_rssi;
1399 sinfo->filled |= STATION_INFO_SIGNAL;
1400
1401 rate = ar->target_stats.tx_ucast_rate;
1402
1403 if (is_rate_legacy(rate)) {
1404 sinfo->txrate.legacy = rate / 100;
1405 } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1406 if (sgi) {
1407 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1408 sinfo->txrate.mcs = mcs - 1;
1409 } else {
1410 sinfo->txrate.mcs = mcs;
1411 }
1412
1413 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1414 } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1415 if (sgi) {
1416 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1417 sinfo->txrate.mcs = mcs - 1;
1418 } else {
1419 sinfo->txrate.mcs = mcs;
1420 }
1421
1422 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1423 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1424 } else {
1425 ath6kl_warn("invalid rate: %d\n", rate);
1426 return 0;
1427 }
1428
1429 sinfo->filled |= STATION_INFO_TX_BITRATE;
1430
1431 return 0;
1432}
1433
1434static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1435 struct cfg80211_pmksa *pmksa)
1436{
1437 struct ath6kl *ar = ath6kl_priv(netdev);
1438 return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
1439 pmksa->pmkid, true);
1440}
1441
1442static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1443 struct cfg80211_pmksa *pmksa)
1444{
1445 struct ath6kl *ar = ath6kl_priv(netdev);
1446 return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
1447 pmksa->pmkid, false);
1448}
1449
1450static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1451{
1452 struct ath6kl *ar = ath6kl_priv(netdev);
1453 if (test_bit(CONNECTED, &ar->flag))
1454 return ath6kl_wmi_setpmkid_cmd(ar->wmi, ar->bssid, NULL, false);
1455 return 0;
1456}
1457
1458static struct cfg80211_ops ath6kl_cfg80211_ops = {
1459 .change_virtual_intf = ath6kl_cfg80211_change_iface,
1460 .scan = ath6kl_cfg80211_scan,
1461 .connect = ath6kl_cfg80211_connect,
1462 .disconnect = ath6kl_cfg80211_disconnect,
1463 .add_key = ath6kl_cfg80211_add_key,
1464 .get_key = ath6kl_cfg80211_get_key,
1465 .del_key = ath6kl_cfg80211_del_key,
1466 .set_default_key = ath6kl_cfg80211_set_default_key,
1467 .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
1468 .set_tx_power = ath6kl_cfg80211_set_txpower,
1469 .get_tx_power = ath6kl_cfg80211_get_txpower,
1470 .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
1471 .join_ibss = ath6kl_cfg80211_join_ibss,
1472 .leave_ibss = ath6kl_cfg80211_leave_ibss,
1473 .get_station = ath6kl_get_station,
1474 .set_pmksa = ath6kl_set_pmksa,
1475 .del_pmksa = ath6kl_del_pmksa,
1476 .flush_pmksa = ath6kl_flush_pmksa,
1477};
1478
1479struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
1480{
1481 int ret = 0;
1482 struct wireless_dev *wdev;
1483
1484 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1485 if (!wdev) {
1486 ath6kl_err("couldn't allocate wireless device\n");
1487 return NULL;
1488 }
1489
1490 /* create a new wiphy for use with cfg80211 */
1491 wdev->wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
1492 if (!wdev->wiphy) {
1493 ath6kl_err("couldn't allocate wiphy device\n");
1494 kfree(wdev);
1495 return NULL;
1496 }
1497
1498 /* set device pointer for wiphy */
1499 set_wiphy_dev(wdev->wiphy, dev);
1500
1501 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1502 BIT(NL80211_IFTYPE_ADHOC);
1503 /* max num of ssids that can be probed during scanning */
1504 wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1505 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
1506 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
1507 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1508
1509 wdev->wiphy->cipher_suites = cipher_suites;
1510 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1511
1512 ret = wiphy_register(wdev->wiphy);
1513 if (ret < 0) {
1514 ath6kl_err("couldn't register wiphy device\n");
1515 wiphy_free(wdev->wiphy);
1516 kfree(wdev);
1517 return NULL;
1518 }
1519
1520 return wdev;
1521}
1522
1523void ath6kl_cfg80211_deinit(struct ath6kl *ar)
1524{
1525 struct wireless_dev *wdev = ar->wdev;
1526
1527 if (ar->scan_req) {
1528 cfg80211_scan_done(ar->scan_req, true);
1529 ar->scan_req = NULL;
1530 }
1531
1532 if (!wdev)
1533 return;
1534
1535 wiphy_unregister(wdev->wiphy);
1536 wiphy_free(wdev->wiphy);
1537 kfree(wdev);
1538}
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
new file mode 100644
index 00000000000..a84adc249c6
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h
@@ -0,0 +1,39 @@
1/*
2 * Copyright (c) 2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef ATH6KL_CFG80211_H
18#define ATH6KL_CFG80211_H
19
20struct wireless_dev *ath6kl_cfg80211_init(struct device *dev);
21void ath6kl_cfg80211_deinit(struct ath6kl *ar);
22
23void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status);
24
25void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
26 u8 *bssid, u16 listen_intvl,
27 u16 beacon_intvl,
28 enum network_type nw_type,
29 u8 beacon_ie_len, u8 assoc_req_len,
30 u8 assoc_resp_len, u8 *assoc_info);
31
32void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
33 u8 *bssid, u8 assoc_resp_len,
34 u8 *assoc_info, u16 proto_reason);
35
36void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
37 bool ismcast);
38
39#endif /* ATH6KL_CFG80211_H */
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
new file mode 100644
index 00000000000..6b0d45642fe
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/common.h
@@ -0,0 +1,180 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef COMMON_H
18#define COMMON_H
19
20#include <linux/netdevice.h>
21
22#define ATH6KL_MAX_IE 256
23
24extern int ath6kl_printk(const char *level, const char *fmt, ...);
25
26#define A_CACHE_LINE_PAD 128
27
28/*
29 * Reflects the version of binary interface exposed by ATH6KL target
30 * firmware. Needs to be incremented by 1 for any change in the firmware
31 * that requires upgrade of the driver on the host side for the change to
32 * work correctly
33 */
34#define ATH6KL_ABI_VERSION 1
35
36#define SIGNAL_QUALITY_METRICS_NUM_MAX 2
37
38enum {
39 SIGNAL_QUALITY_METRICS_SNR = 0,
40 SIGNAL_QUALITY_METRICS_RSSI,
41 SIGNAL_QUALITY_METRICS_ALL,
42};
43
44/*
45 * Data Path
46 */
47
48#define WMI_MAX_TX_DATA_FRAME_LENGTH \
49 (1500 + sizeof(struct wmi_data_hdr) + \
50 sizeof(struct ethhdr) + \
51 sizeof(struct ath6kl_llc_snap_hdr))
52
53/* An AMSDU frame */ /* The MAX AMSDU length of AR6003 is 3839 */
54#define WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH \
55 (3840 + sizeof(struct wmi_data_hdr) + \
56 sizeof(struct ethhdr) + \
57 sizeof(struct ath6kl_llc_snap_hdr))
58
59#define EPPING_ALIGNMENT_PAD \
60 (((sizeof(struct htc_frame_hdr) + 3) & (~0x3)) \
61 - sizeof(struct htc_frame_hdr))
62
63struct ath6kl_llc_snap_hdr {
64 u8 dsap;
65 u8 ssap;
66 u8 cntl;
67 u8 org_code[3];
68 __be16 eth_type;
69} __packed;
70
71enum crypto_type {
72 NONE_CRYPT = 0x01,
73 WEP_CRYPT = 0x02,
74 TKIP_CRYPT = 0x04,
75 AES_CRYPT = 0x08,
76};
77
78#define ATH6KL_NODE_HASHSIZE 32
79/* simple hash is enough for variation of macaddr */
80#define ATH6KL_NODE_HASH(addr) \
81 (((const u8 *)(addr))[ETH_ALEN - 1] % \
82 ATH6KL_NODE_HASHSIZE)
83
84/*
85 * Table of ath6kl_node instances. Each ieee80211com
86 * has at least one for holding the scan candidates.
87 * When operating as an access point or in ibss mode there
88 * is a second table for associated stations or neighbors.
89 */
90struct ath6kl_node_table {
91 spinlock_t nt_nodelock; /* on node table */
92 struct bss *nt_node_first; /* information of all nodes */
93 struct bss *nt_node_last; /* information of all nodes */
94 struct bss *nt_hash[ATH6KL_NODE_HASHSIZE];
95 const char *nt_name; /* for debugging */
96 u32 nt_node_age; /* node aging time */
97};
98
99#define WLAN_NODE_INACT_TIMEOUT_MSEC 120000
100#define WLAN_NODE_INACT_CNT 4
101
102struct ath6kl_common_ie {
103 u16 ie_chan;
104 u8 *ie_tstamp;
105 u8 *ie_ssid;
106 u8 *ie_rates;
107 u8 *ie_xrates;
108 u8 *ie_country;
109 u8 *ie_wpa;
110 u8 *ie_rsn;
111 u8 *ie_wmm;
112 u8 *ie_ath;
113 u16 ie_capInfo;
114 u16 ie_beaconInt;
115 u8 *ie_tim;
116 u8 *ie_chswitch;
117 u8 ie_erp;
118 u8 *ie_wsc;
119 u8 *ie_htcap;
120 u8 *ie_htop;
121};
122
123struct bss {
124 u8 ni_macaddr[ETH_ALEN];
125 u8 ni_snr;
126 s16 ni_rssi;
127 struct bss *ni_list_next;
128 struct bss *ni_list_prev;
129 struct bss *ni_hash_next;
130 struct bss *ni_hash_prev;
131 struct ath6kl_common_ie ni_cie;
132 u8 *ni_buf;
133 u16 ni_framelen;
134 struct ath6kl_node_table *ni_table;
135 u32 ni_refcnt;
136
137 u32 ni_tstamp;
138 u32 ni_actcnt;
139};
140
141struct htc_endpoint_credit_dist;
142struct ath6kl;
143enum htc_credit_dist_reason;
144struct htc_credit_state_info;
145
146struct bss *wlan_node_alloc(int wh_size);
147void wlan_node_free(struct bss *ni);
148void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
149 const u8 *mac_addr);
150struct bss *wlan_find_node(struct ath6kl_node_table *nt,
151 const u8 *mac_addr);
152void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni);
153void wlan_free_allnodes(struct ath6kl_node_table *nt);
154void wlan_iterate_nodes(struct ath6kl_node_table *nt, void *arg);
155
156void wlan_node_table_init(struct ath6kl_node_table *nt);
157void wlan_node_table_cleanup(struct ath6kl_node_table *nt);
158
159void wlan_refresh_inactive_nodes(struct ath6kl *ar);
160
161struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 *ssid,
162 u32 ssid_len, bool is_wpa2, bool match_ssid);
163
164void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni);
165
166int ath6k_setup_credit_dist(void *htc_handle,
167 struct htc_credit_state_info *cred_info);
168void ath6k_credit_distribute(struct htc_credit_state_info *cred_inf,
169 struct list_head *epdist_list,
170 enum htc_credit_dist_reason reason);
171void ath6k_credit_init(struct htc_credit_state_info *cred_inf,
172 struct list_head *ep_list,
173 int tot_credits);
174void ath6k_seek_credits(struct htc_credit_state_info *cred_inf,
175 struct htc_endpoint_credit_dist *ep_dist);
176struct ath6kl *ath6kl_core_alloc(struct device *sdev);
177int ath6kl_core_init(struct ath6kl *ar);
178int ath6kl_unavail_ev(struct ath6kl *ar);
179struct sk_buff *ath6kl_buf_alloc(int size);
180#endif /* COMMON_H */
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
new file mode 100644
index 00000000000..74170229523
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -0,0 +1,544 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef CORE_H
18#define CORE_H
19
20#include <linux/etherdevice.h>
21#include <linux/rtnetlink.h>
22#include <linux/firmware.h>
23#include <linux/sched.h>
24#include <net/cfg80211.h>
25#include "htc.h"
26#include "wmi.h"
27#include "bmi.h"
28
29#define MAX_ATH6KL 1
30#define ATH6KL_MAX_RX_BUFFERS 16
31#define ATH6KL_BUFFER_SIZE 1664
32#define ATH6KL_MAX_AMSDU_RX_BUFFERS 4
33#define ATH6KL_AMSDU_REFILL_THRESHOLD 3
34#define ATH6KL_AMSDU_BUFFER_SIZE (WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH + 128)
35#define MAX_MSDU_SUBFRAME_PAYLOAD_LEN 1508
36#define MIN_MSDU_SUBFRAME_PAYLOAD_LEN 46
37
38#define USER_SAVEDKEYS_STAT_INIT 0
39#define USER_SAVEDKEYS_STAT_RUN 1
40
41#define ATH6KL_TX_TIMEOUT 10
42#define ATH6KL_MAX_ENDPOINTS 4
43#define MAX_NODE_NUM 15
44
45/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
46#define MAX_DEF_COOKIE_NUM 180
47#define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */
48#define MAX_COOKIE_NUM (MAX_DEF_COOKIE_NUM + MAX_HI_COOKIE_NUM)
49
50#define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
51
52#define DISCON_TIMER_INTVAL 10000 /* in msec */
53#define A_DEFAULT_LISTEN_INTERVAL 100
54#define A_MAX_WOW_LISTEN_INTERVAL 1000
55
56/* AR6003 1.0 definitions */
57#define AR6003_REV1_VERSION 0x300002ba
58
59/* AR6003 2.0 definitions */
60#define AR6003_REV2_VERSION 0x30000384
61#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910
62#define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77"
63#define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77"
64#define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin"
65#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin"
66#define AR6003_REV2_DEFAULT_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin"
67
68/* AR6003 3.0 definitions */
69#define AR6003_REV3_VERSION 0x30000582
70#define AR6003_REV3_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin"
71#define AR6003_REV3_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin"
72#define AR6003_REV3_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin"
73#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin"
74#define AR6003_REV3_DEFAULT_BOARD_DATA_FILE \
75 "ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
76
77/* Per STA data, used in AP mode */
78#define STA_PS_AWAKE BIT(0)
79#define STA_PS_SLEEP BIT(1)
80#define STA_PS_POLLED BIT(2)
81
82/* HTC TX packet tagging definitions */
83#define ATH6KL_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED
84#define ATH6KL_DATA_PKT_TAG (ATH6KL_CONTROL_PKT_TAG + 1)
85
86#define AR6003_CUST_DATA_SIZE 16
87
88#define AGGR_WIN_IDX(x, y) ((x) % (y))
89#define AGGR_INCR_IDX(x, y) AGGR_WIN_IDX(((x) + 1), (y))
90#define AGGR_DCRM_IDX(x, y) AGGR_WIN_IDX(((x) - 1), (y))
91#define ATH6KL_MAX_SEQ_NO 0xFFF
92#define ATH6KL_NEXT_SEQ_NO(x) (((x) + 1) & ATH6KL_MAX_SEQ_NO)
93
94#define NUM_OF_TIDS 8
95#define AGGR_SZ_DEFAULT 8
96
97#define AGGR_WIN_SZ_MIN 2
98#define AGGR_WIN_SZ_MAX 8
99
100#define TID_WINDOW_SZ(_x) ((_x) << 1)
101
102#define AGGR_NUM_OF_FREE_NETBUFS 16
103
104#define AGGR_RX_TIMEOUT 400 /* in ms */
105
106#define WMI_TIMEOUT (2 * HZ)
107
108#define MBOX_YIELD_LIMIT 99
109
110/* configuration lags */
111/*
112 * ATH6KL_CONF_IGNORE_ERP_BARKER: Ignore the barker premable in
113 * ERP IE of beacon to determine the short premable support when
114 * sending (Re)Assoc req.
115 * ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN: Don't send the power
116 * module state transition failure events which happen during
117 * scan, to the host.
118 */
119#define ATH6KL_CONF_IGNORE_ERP_BARKER BIT(0)
120#define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN BIT(1)
121#define ATH6KL_CONF_ENABLE_11N BIT(2)
122#define ATH6KL_CONF_ENABLE_TX_BURST BIT(3)
123
124enum wlan_low_pwr_state {
125 WLAN_POWER_STATE_ON,
126 WLAN_POWER_STATE_CUT_PWR,
127 WLAN_POWER_STATE_DEEP_SLEEP,
128 WLAN_POWER_STATE_WOW
129};
130
131enum sme_state {
132 SME_DISCONNECTED,
133 SME_CONNECTING,
134 SME_CONNECTED
135};
136
137struct skb_hold_q {
138 struct sk_buff *skb;
139 bool is_amsdu;
140 u16 seq_no;
141};
142
143struct rxtid {
144 bool aggr;
145 bool progress;
146 bool timer_mon;
147 u16 win_sz;
148 u16 seq_next;
149 u32 hold_q_sz;
150 struct skb_hold_q *hold_q;
151 struct sk_buff_head q;
152 spinlock_t lock;
153};
154
155struct rxtid_stats {
156 u32 num_into_aggr;
157 u32 num_dups;
158 u32 num_oow;
159 u32 num_mpdu;
160 u32 num_amsdu;
161 u32 num_delivered;
162 u32 num_timeouts;
163 u32 num_hole;
164 u32 num_bar;
165};
166
167struct aggr_info {
168 u8 aggr_sz;
169 u8 timer_scheduled;
170 struct timer_list timer;
171 struct net_device *dev;
172 struct rxtid rx_tid[NUM_OF_TIDS];
173 struct sk_buff_head free_q;
174 struct rxtid_stats stat[NUM_OF_TIDS];
175};
176
177struct ath6kl_wep_key {
178 u8 key_index;
179 u8 key_len;
180 u8 key[64];
181};
182
183#define ATH6KL_KEY_SEQ_LEN 8
184
185struct ath6kl_key {
186 u8 key[WLAN_MAX_KEY_LEN];
187 u8 key_len;
188 u8 seq[ATH6KL_KEY_SEQ_LEN];
189 u8 seq_len;
190 u32 cipher;
191};
192
193struct ath6kl_node_mapping {
194 u8 mac_addr[ETH_ALEN];
195 u8 ep_id;
196 u8 tx_pend;
197};
198
199struct ath6kl_cookie {
200 struct sk_buff *skb;
201 u32 map_no;
202 struct htc_packet htc_pkt;
203 struct ath6kl_cookie *arc_list_next;
204};
205
206struct ath6kl_sta {
207 u16 sta_flags;
208 u8 mac[ETH_ALEN];
209 u8 aid;
210 u8 keymgmt;
211 u8 ucipher;
212 u8 auth;
213 u8 wpa_ie[ATH6KL_MAX_IE];
214 struct sk_buff_head psq;
215 spinlock_t psq_lock;
216};
217
218struct ath6kl_version {
219 u32 target_ver;
220 u32 wlan_ver;
221 u32 abi_ver;
222};
223
224struct ath6kl_bmi {
225 u32 cmd_credits;
226 bool done_sent;
227 u8 *cmd_buf;
228};
229
230struct target_stats {
231 u64 tx_pkt;
232 u64 tx_byte;
233 u64 tx_ucast_pkt;
234 u64 tx_ucast_byte;
235 u64 tx_mcast_pkt;
236 u64 tx_mcast_byte;
237 u64 tx_bcast_pkt;
238 u64 tx_bcast_byte;
239 u64 tx_rts_success_cnt;
240 u64 tx_pkt_per_ac[4];
241
242 u64 tx_err;
243 u64 tx_fail_cnt;
244 u64 tx_retry_cnt;
245 u64 tx_mult_retry_cnt;
246 u64 tx_rts_fail_cnt;
247
248 u64 rx_pkt;
249 u64 rx_byte;
250 u64 rx_ucast_pkt;
251 u64 rx_ucast_byte;
252 u64 rx_mcast_pkt;
253 u64 rx_mcast_byte;
254 u64 rx_bcast_pkt;
255 u64 rx_bcast_byte;
256 u64 rx_frgment_pkt;
257
258 u64 rx_err;
259 u64 rx_crc_err;
260 u64 rx_key_cache_miss;
261 u64 rx_decrypt_err;
262 u64 rx_dupl_frame;
263
264 u64 tkip_local_mic_fail;
265 u64 tkip_cnter_measures_invoked;
266 u64 tkip_replays;
267 u64 tkip_fmt_err;
268 u64 ccmp_fmt_err;
269 u64 ccmp_replays;
270
271 u64 pwr_save_fail_cnt;
272
273 u64 cs_bmiss_cnt;
274 u64 cs_low_rssi_cnt;
275 u64 cs_connect_cnt;
276 u64 cs_discon_cnt;
277
278 s32 tx_ucast_rate;
279 s32 rx_ucast_rate;
280
281 u32 lq_val;
282
283 u32 wow_pkt_dropped;
284 u16 wow_evt_discarded;
285
286 s16 noise_floor_calib;
287 s16 cs_rssi;
288 s16 cs_ave_beacon_rssi;
289 u8 cs_ave_beacon_snr;
290 u8 cs_last_roam_msec;
291 u8 cs_snr;
292
293 u8 wow_host_pkt_wakeups;
294 u8 wow_host_evt_wakeups;
295
296 u32 arp_received;
297 u32 arp_matched;
298 u32 arp_replied;
299};
300
301struct ath6kl_mbox_info {
302 u32 htc_addr;
303 u32 htc_ext_addr;
304 u32 htc_ext_sz;
305
306 u32 block_size;
307
308 u32 gmbox_addr;
309
310 u32 gmbox_sz;
311};
312
313/*
314 * 802.11i defines an extended IV for use with non-WEP ciphers.
315 * When the EXTIV bit is set in the key id byte an additional
316 * 4 bytes immediately follow the IV for TKIP. For CCMP the
317 * EXTIV bit is likewise set but the 8 bytes represent the
318 * CCMP header rather than IV+extended-IV.
319 */
320
321#define ATH6KL_KEYBUF_SIZE 16
322#define ATH6KL_MICBUF_SIZE (8+8) /* space for both tx and rx */
323
324#define ATH6KL_KEY_XMIT 0x01
325#define ATH6KL_KEY_RECV 0x02
326#define ATH6KL_KEY_DEFAULT 0x80 /* default xmit key */
327
328/*
329 * WPA/RSN get/set key request. Specify the key/cipher
330 * type and whether the key is to be used for sending and/or
331 * receiving. The key index should be set only when working
332 * with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
333 * Otherwise a unicast/pairwise key is specified by the bssid
334 * (on a station) or mac address (on an ap). They key length
335 * must include any MIC key data; otherwise it should be no
336 * more than ATH6KL_KEYBUF_SIZE.
337 */
338struct ath6kl_req_key {
339 u8 ik_type; /* key/cipher type */
340 u8 ik_pad;
341 u16 ik_keyix; /* key index */
342 u8 ik_keylen; /* key length in bytes */
343 u8 ik_flags;
344 u8 ik_macaddr[ETH_ALEN];
345 u64 ik_keyrsc; /* key receive sequence counter */
346 u64 ik_keytsc; /* key transmit sequence counter */
347 u8 ik_keydata[ATH6KL_KEYBUF_SIZE + ATH6KL_MICBUF_SIZE];
348};
349
350/* Flag info */
351#define WMI_ENABLED 0
352#define WMI_READY 1
353#define CONNECTED 2
354#define STATS_UPDATE_PEND 3
355#define CONNECT_PEND 4
356#define WMM_ENABLED 5
357#define NETQ_STOPPED 6
358#define WMI_CTRL_EP_FULL 7
359#define DTIM_EXPIRED 8
360#define DESTROY_IN_PROGRESS 9
361#define NETDEV_REGISTERED 10
362#define SKIP_SCAN 11
363#define WLAN_ENABLED 12
364
365struct ath6kl {
366 struct device *dev;
367 struct net_device *net_dev;
368 struct ath6kl_bmi bmi;
369 const struct ath6kl_hif_ops *hif_ops;
370 struct wmi *wmi;
371 int tx_pending[ENDPOINT_MAX];
372 int total_tx_data_pend;
373 struct htc_target *htc_target;
374 void *hif_priv;
375 spinlock_t lock;
376 struct semaphore sem;
377 int ssid_len;
378 u8 ssid[IEEE80211_MAX_SSID_LEN];
379 u8 next_mode;
380 u8 nw_type;
381 u8 dot11_auth_mode;
382 u8 auth_mode;
383 u8 prwise_crypto;
384 u8 prwise_crypto_len;
385 u8 grp_crypto;
386 u8 grp_crpto_len;
387 u8 def_txkey_index;
388 struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
389 u8 bssid[ETH_ALEN];
390 u8 req_bssid[ETH_ALEN];
391 u16 ch_hint;
392 u16 bss_ch;
393 u16 listen_intvl_b;
394 u16 listen_intvl_t;
395 struct ath6kl_version version;
396 u32 target_type;
397 u8 tx_pwr;
398 struct net_device_stats net_stats;
399 struct target_stats target_stats;
400 struct ath6kl_node_mapping node_map[MAX_NODE_NUM];
401 u8 ibss_ps_enable;
402 u8 node_num;
403 u8 next_ep_id;
404 struct ath6kl_cookie *cookie_list;
405 u32 cookie_count;
406 enum htc_endpoint_id ac2ep_map[WMM_NUM_AC];
407 bool ac_stream_active[WMM_NUM_AC];
408 u8 ac_stream_pri_map[WMM_NUM_AC];
409 u8 hiac_stream_active_pri;
410 u8 ep2ac_map[ENDPOINT_MAX];
411 enum htc_endpoint_id ctrl_ep;
412 struct htc_credit_state_info credit_state_info;
413 u32 connect_ctrl_flags;
414 u32 user_key_ctrl;
415 u8 usr_bss_filter;
416 struct ath6kl_sta sta_list[AP_MAX_NUM_STA];
417 u8 sta_list_index;
418 struct ath6kl_req_key ap_mode_bkey;
419 struct sk_buff_head mcastpsq;
420 spinlock_t mcastpsq_lock;
421 u8 intra_bss;
422 struct aggr_info *aggr_cntxt;
423 struct wmi_ap_mode_stat ap_stats;
424 u8 ap_country_code[3];
425 struct list_head amsdu_rx_buffer_queue;
426 struct timer_list disconnect_timer;
427 u8 rx_meta_ver;
428 struct wireless_dev *wdev;
429 struct cfg80211_scan_request *scan_req;
430 struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
431 enum sme_state sme_state;
432 enum wlan_low_pwr_state wlan_pwr_state;
433 struct wmi_scan_params_cmd sc_params;
434#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4
435 u8 auto_auth_stage;
436
437 u16 conf_flags;
438 wait_queue_head_t event_wq;
439 struct ath6kl_mbox_info mbox_info;
440
441 struct ath6kl_cookie cookie_mem[MAX_COOKIE_NUM];
442 int reconnect_flag;
443 unsigned long flag;
444
445 u8 *fw_board;
446 size_t fw_board_len;
447
448 u8 *fw_otp;
449 size_t fw_otp_len;
450
451 u8 *fw;
452 size_t fw_len;
453
454 u8 *fw_patch;
455 size_t fw_patch_len;
456
457 struct workqueue_struct *ath6kl_wq;
458
459 struct ath6kl_node_table scan_table;
460};
461
462static inline void *ath6kl_priv(struct net_device *dev)
463{
464 return wdev_priv(dev->ieee80211_ptr);
465}
466
467static inline void ath6kl_deposit_credit_to_ep(struct htc_credit_state_info
468 *cred_info,
469 struct htc_endpoint_credit_dist
470 *ep_dist, int credits)
471{
472 ep_dist->credits += credits;
473 ep_dist->cred_assngd += credits;
474 cred_info->cur_free_credits -= credits;
475}
476
477void ath6kl_destroy(struct net_device *dev, unsigned int unregister);
478int ath6kl_configure_target(struct ath6kl *ar);
479void ath6kl_detect_error(unsigned long ptr);
480void disconnect_timer_handler(unsigned long ptr);
481void init_netdev(struct net_device *dev);
482void ath6kl_cookie_init(struct ath6kl *ar);
483void ath6kl_cookie_cleanup(struct ath6kl *ar);
484void ath6kl_rx(struct htc_target *target, struct htc_packet *packet);
485void ath6kl_tx_complete(void *context, struct list_head *packet_queue);
486enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
487 struct htc_packet *packet);
488void ath6kl_stop_txrx(struct ath6kl *ar);
489void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar);
490int ath6kl_access_datadiag(struct ath6kl *ar, u32 address,
491 u8 *data, u32 length, bool read);
492int ath6kl_read_reg_diag(struct ath6kl *ar, u32 *address, u32 *data);
493void ath6kl_init_profile_info(struct ath6kl *ar);
494void ath6kl_tx_data_cleanup(struct ath6kl *ar);
495void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
496 bool get_dbglogs);
497
498struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar);
499void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie);
500int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev);
501
502struct aggr_info *aggr_init(struct net_device *dev);
503void ath6kl_rx_refill(struct htc_target *target,
504 enum htc_endpoint_id endpoint);
505void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count);
506struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
507 enum htc_endpoint_id endpoint,
508 int len);
509void aggr_module_destroy(struct aggr_info *aggr_info);
510void aggr_reset_state(struct aggr_info *aggr_info);
511
512struct ath6kl_sta *ath6kl_find_sta(struct ath6kl *ar, u8 * node_addr);
513struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
514
515void ath6kl_ready_event(void *devt, u8 * datap, u32 sw_ver, u32 abi_ver);
516int ath6kl_control_tx(void *devt, struct sk_buff *skb,
517 enum htc_endpoint_id eid);
518void ath6kl_connect_event(struct ath6kl *ar, u16 channel,
519 u8 *bssid, u16 listen_int,
520 u16 beacon_int, enum network_type net_type,
521 u8 beacon_ie_len, u8 assoc_req_len,
522 u8 assoc_resp_len, u8 *assoc_info);
523void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason,
524 u8 *bssid, u8 assoc_resp_len,
525 u8 *assoc_info, u16 prot_reason_status);
526void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast);
527void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr);
528void ath6kl_scan_complete_evt(struct ath6kl *ar, int status);
529void ath6kl_tgt_stats_event(struct ath6kl *ar, u8 *ptr, u32 len);
530void ath6kl_indicate_tx_activity(void *devt, u8 traffic_class, bool active);
531enum htc_endpoint_id ath6kl_ac2_endpoint_id(void *devt, u8 ac);
532
533void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid);
534
535void ath6kl_dtimexpiry_event(struct ath6kl *ar);
536void ath6kl_disconnect(struct ath6kl *ar);
537void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid);
538void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no,
539 u8 win_sz);
540void ath6kl_wakeup_event(void *dev);
541void ath6kl_target_failure(struct ath6kl *ar);
542
543void ath6kl_cfg80211_scan_node(struct wiphy *wiphy, struct bss *ni);
544#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
new file mode 100644
index 00000000000..316136c8b90
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -0,0 +1,150 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
18#include "debug.h"
19
20int ath6kl_printk(const char *level, const char *fmt, ...)
21{
22 struct va_format vaf;
23 va_list args;
24 int rtn;
25
26 va_start(args, fmt);
27
28 vaf.fmt = fmt;
29 vaf.va = &args;
30
31 rtn = printk("%sath6kl: %pV", level, &vaf);
32
33 va_end(args);
34
35 return rtn;
36}
37
38#ifdef CONFIG_ATH6KL_DEBUG
39void ath6kl_dump_registers(struct ath6kl_device *dev,
40 struct ath6kl_irq_proc_registers *irq_proc_reg,
41 struct ath6kl_irq_enable_reg *irq_enable_reg)
42{
43
44 ath6kl_dbg(ATH6KL_DBG_ANY, ("<------- Register Table -------->\n"));
45
46 if (irq_proc_reg != NULL) {
47 ath6kl_dbg(ATH6KL_DBG_ANY,
48 "Host Int status: 0x%x\n",
49 irq_proc_reg->host_int_status);
50 ath6kl_dbg(ATH6KL_DBG_ANY,
51 "CPU Int status: 0x%x\n",
52 irq_proc_reg->cpu_int_status);
53 ath6kl_dbg(ATH6KL_DBG_ANY,
54 "Error Int status: 0x%x\n",
55 irq_proc_reg->error_int_status);
56 ath6kl_dbg(ATH6KL_DBG_ANY,
57 "Counter Int status: 0x%x\n",
58 irq_proc_reg->counter_int_status);
59 ath6kl_dbg(ATH6KL_DBG_ANY,
60 "Mbox Frame: 0x%x\n",
61 irq_proc_reg->mbox_frame);
62 ath6kl_dbg(ATH6KL_DBG_ANY,
63 "Rx Lookahead Valid: 0x%x\n",
64 irq_proc_reg->rx_lkahd_valid);
65 ath6kl_dbg(ATH6KL_DBG_ANY,
66 "Rx Lookahead 0: 0x%x\n",
67 irq_proc_reg->rx_lkahd[0]);
68 ath6kl_dbg(ATH6KL_DBG_ANY,
69 "Rx Lookahead 1: 0x%x\n",
70 irq_proc_reg->rx_lkahd[1]);
71
72 if (dev->ar->mbox_info.gmbox_addr != 0) {
73 /*
74 * If the target supports GMBOX hardware, dump some
75 * additional state.
76 */
77 ath6kl_dbg(ATH6KL_DBG_ANY,
78 "GMBOX Host Int status 2: 0x%x\n",
79 irq_proc_reg->host_int_status2);
80 ath6kl_dbg(ATH6KL_DBG_ANY,
81 "GMBOX RX Avail: 0x%x\n",
82 irq_proc_reg->gmbox_rx_avail);
83 ath6kl_dbg(ATH6KL_DBG_ANY,
84 "GMBOX lookahead alias 0: 0x%x\n",
85 irq_proc_reg->rx_gmbox_lkahd_alias[0]);
86 ath6kl_dbg(ATH6KL_DBG_ANY,
87 "GMBOX lookahead alias 1: 0x%x\n",
88 irq_proc_reg->rx_gmbox_lkahd_alias[1]);
89 }
90
91 }
92
93 if (irq_enable_reg != NULL) {
94 ath6kl_dbg(ATH6KL_DBG_ANY,
95 "Int status Enable: 0x%x\n",
96 irq_enable_reg->int_status_en);
97 ath6kl_dbg(ATH6KL_DBG_ANY, "Counter Int status Enable: 0x%x\n",
98 irq_enable_reg->cntr_int_status_en);
99 }
100 ath6kl_dbg(ATH6KL_DBG_ANY, "<------------------------------->\n");
101}
102
103static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist)
104{
105 ath6kl_dbg(ATH6KL_DBG_ANY,
106 "--- endpoint: %d svc_id: 0x%X ---\n",
107 ep_dist->endpoint, ep_dist->svc_id);
108 ath6kl_dbg(ATH6KL_DBG_ANY, " dist_flags : 0x%X\n",
109 ep_dist->dist_flags);
110 ath6kl_dbg(ATH6KL_DBG_ANY, " cred_norm : %d\n",
111 ep_dist->cred_norm);
112 ath6kl_dbg(ATH6KL_DBG_ANY, " cred_min : %d\n",
113 ep_dist->cred_min);
114 ath6kl_dbg(ATH6KL_DBG_ANY, " credits : %d\n",
115 ep_dist->credits);
116 ath6kl_dbg(ATH6KL_DBG_ANY, " cred_assngd : %d\n",
117 ep_dist->cred_assngd);
118 ath6kl_dbg(ATH6KL_DBG_ANY, " seek_cred : %d\n",
119 ep_dist->seek_cred);
120 ath6kl_dbg(ATH6KL_DBG_ANY, " cred_sz : %d\n",
121 ep_dist->cred_sz);
122 ath6kl_dbg(ATH6KL_DBG_ANY, " cred_per_msg : %d\n",
123 ep_dist->cred_per_msg);
124 ath6kl_dbg(ATH6KL_DBG_ANY, " cred_to_dist : %d\n",
125 ep_dist->cred_to_dist);
126 ath6kl_dbg(ATH6KL_DBG_ANY, " txq_depth : %d\n",
127 get_queue_depth(&((struct htc_endpoint *)
128 ep_dist->htc_rsvd)->txq));
129 ath6kl_dbg(ATH6KL_DBG_ANY,
130 "----------------------------------\n");
131}
132
133void dump_cred_dist_stats(struct htc_target *target)
134{
135 struct htc_endpoint_credit_dist *ep_list;
136
137 if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_TRC))
138 return;
139
140 list_for_each_entry(ep_list, &target->cred_dist_list, list)
141 dump_cred_dist(ep_list);
142
143 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:%p dist:%p\n",
144 target->cred_dist_cntxt, NULL);
145 ath6kl_dbg(ATH6KL_DBG_TRC, "credit distribution, total : %d, free : %d\n",
146 target->cred_dist_cntxt->total_avail_credits,
147 target->cred_dist_cntxt->cur_free_credits);
148}
149
150#endif
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
new file mode 100644
index 00000000000..66b399962f0
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -0,0 +1,105 @@
1/*
2 * Copyright (c) 2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef DEBUG_H
18#define DEBUG_H
19
20#include "htc_hif.h"
21
22enum ATH6K_DEBUG_MASK {
23 ATH6KL_DBG_WLAN_CONNECT = BIT(0), /* wlan connect */
24 ATH6KL_DBG_WLAN_SCAN = BIT(1), /* wlan scan */
25 ATH6KL_DBG_WLAN_TX = BIT(2), /* wlan tx */
26 ATH6KL_DBG_WLAN_RX = BIT(3), /* wlan rx */
27 ATH6KL_DBG_BMI = BIT(4), /* bmi tracing */
28 ATH6KL_DBG_HTC_SEND = BIT(5), /* htc send */
29 ATH6KL_DBG_HTC_RECV = BIT(6), /* htc recv */
30 ATH6KL_DBG_IRQ = BIT(7), /* interrupt processing */
31 ATH6KL_DBG_PM = BIT(8), /* power management */
32 ATH6KL_DBG_WLAN_NODE = BIT(9), /* general wlan node tracing */
33 ATH6KL_DBG_WMI = BIT(10), /* wmi tracing */
34 ATH6KL_DBG_TRC = BIT(11), /* generic func tracing */
35 ATH6KL_DBG_SCATTER = BIT(12), /* hif scatter tracing */
36 ATH6KL_DBG_WLAN_CFG = BIT(13), /* cfg80211 i/f file tracing */
37 ATH6KL_DBG_RAW_BYTES = BIT(14), /* dump tx/rx and wmi frames */
38 ATH6KL_DBG_AGGR = BIT(15), /* aggregation */
39 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */
40};
41
42extern unsigned int debug_mask;
43extern int ath6kl_printk(const char *level, const char *fmt, ...)
44 __attribute__ ((format (printf, 2, 3)));
45
46#define ath6kl_info(fmt, ...) \
47 ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__)
48#define ath6kl_err(fmt, ...) \
49 ath6kl_printk(KERN_ERR, fmt, ##__VA_ARGS__)
50#define ath6kl_warn(fmt, ...) \
51 ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__)
52
53#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask)
54
55#ifdef CONFIG_ATH6KL_DEBUG
56#define ath6kl_dbg(mask, fmt, ...) \
57 ({ \
58 int rtn; \
59 if (debug_mask & mask) \
60 rtn = ath6kl_printk(KERN_DEBUG, fmt, ##__VA_ARGS__); \
61 else \
62 rtn = 0; \
63 \
64 rtn; \
65 })
66
67static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
68 const char *msg, const void *buf,
69 size_t len)
70{
71 if (debug_mask & mask) {
72 ath6kl_dbg(mask, "%s\n", msg);
73 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len);
74 }
75}
76
77void ath6kl_dump_registers(struct ath6kl_device *dev,
78 struct ath6kl_irq_proc_registers *irq_proc_reg,
79 struct ath6kl_irq_enable_reg *irq_en_reg);
80void dump_cred_dist_stats(struct htc_target *target);
81#else
82static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask,
83 const char *fmt, ...)
84{
85 return 0;
86}
87
88static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
89 const char *msg, const void *buf,
90 size_t len)
91{
92}
93
94static inline void ath6kl_dump_registers(struct ath6kl_device *dev,
95 struct ath6kl_irq_proc_registers *irq_proc_reg,
96 struct ath6kl_irq_enable_reg *irq_en_reg)
97{
98
99}
100static inline void dump_cred_dist_stats(struct htc_target *target)
101{
102}
103#endif
104
105#endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h
new file mode 100644
index 00000000000..c923979776a
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HIF_OPS_H
18#define HIF_OPS_H
19
20#include "hif.h"
21
22static inline int hif_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf,
23 u32 len, u32 request)
24{
25 return ar->hif_ops->read_write_sync(ar, addr, buf, len, request);
26}
27
28static inline int hif_write_async(struct ath6kl *ar, u32 address, u8 *buffer,
29 u32 length, u32 request,
30 struct htc_packet *packet)
31{
32 return ar->hif_ops->write_async(ar, address, buffer, length,
33 request, packet);
34}
35static inline void ath6kl_hif_irq_enable(struct ath6kl *ar)
36{
37 return ar->hif_ops->irq_enable(ar);
38}
39
40static inline void ath6kl_hif_irq_disable(struct ath6kl *ar)
41{
42 return ar->hif_ops->irq_disable(ar);
43}
44
45static inline struct hif_scatter_req *hif_scatter_req_get(struct ath6kl *ar)
46{
47 return ar->hif_ops->scatter_req_get(ar);
48}
49
50static inline void hif_scatter_req_add(struct ath6kl *ar,
51 struct hif_scatter_req *s_req)
52{
53 return ar->hif_ops->scatter_req_add(ar, s_req);
54}
55
56static inline int ath6kl_hif_enable_scatter(struct ath6kl *ar)
57{
58 return ar->hif_ops->enable_scatter(ar);
59}
60
61static inline int ath6kl_hif_scat_req_rw(struct ath6kl *ar,
62 struct hif_scatter_req *scat_req)
63{
64 return ar->hif_ops->scat_req_rw(ar, scat_req);
65}
66
67static inline void ath6kl_hif_cleanup_scatter(struct ath6kl *ar)
68{
69 return ar->hif_ops->cleanup_scatter(ar);
70}
71
72#endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h
new file mode 100644
index 00000000000..5ceff54775a
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/hif.h
@@ -0,0 +1,207 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HIF_H
18#define HIF_H
19
20#include "common.h"
21#include "core.h"
22
23#include <linux/scatterlist.h>
24
25#define BUS_REQUEST_MAX_NUM 64
26#define HIF_MBOX_BLOCK_SIZE 128
27#define HIF_MBOX0_BLOCK_SIZE 1
28
29#define HIF_DMA_BUFFER_SIZE (32 * 1024)
30#define CMD53_FIXED_ADDRESS 1
31#define CMD53_INCR_ADDRESS 2
32
33#define MAX_SCATTER_REQUESTS 4
34#define MAX_SCATTER_ENTRIES_PER_REQ 16
35#define MAX_SCATTER_REQ_TRANSFER_SIZE (32 * 1024)
36
37#define MANUFACTURER_ID_AR6003_BASE 0x300
38 /* SDIO manufacturer ID and Codes */
39#define MANUFACTURER_ID_ATH6KL_BASE_MASK 0xFF00
40#define MANUFACTURER_CODE 0x271 /* Atheros */
41
42/* Mailbox address in SDIO address space */
43#define HIF_MBOX_BASE_ADDR 0x800
44#define HIF_MBOX_WIDTH 0x800
45
46#define HIF_MBOX_END_ADDR (HTC_MAILBOX_NUM_MAX * HIF_MBOX_WIDTH - 1)
47
48/* version 1 of the chip has only a 12K extended mbox range */
49#define HIF_MBOX0_EXT_BASE_ADDR 0x4000
50#define HIF_MBOX0_EXT_WIDTH (12*1024)
51
52/* GMBOX addresses */
53#define HIF_GMBOX_BASE_ADDR 0x7000
54#define HIF_GMBOX_WIDTH 0x4000
55
56/* interrupt mode register */
57#define CCCR_SDIO_IRQ_MODE_REG 0xF0
58
59/* mode to enable special 4-bit interrupt assertion without clock */
60#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ (1 << 0)
61
62struct bus_request {
63 struct list_head list;
64
65 /* request data */
66 u32 address;
67
68 u8 *buffer;
69 u32 length;
70 u32 request;
71 struct htc_packet *packet;
72 int status;
73
74 /* this is a scatter request */
75 struct hif_scatter_req *scat_req;
76};
77
78/* direction of transfer (read/write) */
79#define HIF_READ 0x00000001
80#define HIF_WRITE 0x00000002
81#define HIF_DIR_MASK (HIF_READ | HIF_WRITE)
82
83/*
84 * emode - This indicates the whether the command is to be executed in a
85 * blocking or non-blocking fashion (HIF_SYNCHRONOUS/
86 * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been
87 * implemented using the asynchronous mode allowing the the bus
88 * driver to indicate the completion of operation through the
89 * registered callback routine. The requirement primarily comes
90 * from the contexts these operations get called from (a driver's
91 * transmit context or the ISR context in case of receive).
92 * Support for both of these modes is essential.
93 */
94#define HIF_SYNCHRONOUS 0x00000010
95#define HIF_ASYNCHRONOUS 0x00000020
96#define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)
97
98/*
99 * dmode - An interface may support different kinds of commands based on
100 * the tradeoff between the amount of data it can carry and the
101 * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/
102 * HIF_BLOCK_BASIS). In case of latter, the data is rounded off
103 * to the nearest block size by padding. The size of the block is
104 * configurable at compile time using the HIF_BLOCK_SIZE and is
105 * negotiated with the target during initialization after the
106 * ATH6KL interrupts are enabled.
107 */
108#define HIF_BYTE_BASIS 0x00000040
109#define HIF_BLOCK_BASIS 0x00000080
110#define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)
111
112/*
113 * amode - This indicates if the address has to be incremented on ATH6KL
114 * after every read/write operation (HIF?FIXED_ADDRESS/
115 * HIF_INCREMENTAL_ADDRESS).
116 */
117#define HIF_FIXED_ADDRESS 0x00000100
118#define HIF_INCREMENTAL_ADDRESS 0x00000200
119#define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS)
120
121#define HIF_WR_ASYNC_BYTE_INC \
122 (HIF_WRITE | HIF_ASYNCHRONOUS | \
123 HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
124
125#define HIF_WR_ASYNC_BLOCK_INC \
126 (HIF_WRITE | HIF_ASYNCHRONOUS | \
127 HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
128
129#define HIF_WR_SYNC_BYTE_FIX \
130 (HIF_WRITE | HIF_SYNCHRONOUS | \
131 HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
132
133#define HIF_WR_SYNC_BYTE_INC \
134 (HIF_WRITE | HIF_SYNCHRONOUS | \
135 HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
136
137#define HIF_WR_SYNC_BLOCK_INC \
138 (HIF_WRITE | HIF_SYNCHRONOUS | \
139 HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
140
141#define HIF_RD_SYNC_BYTE_INC \
142 (HIF_READ | HIF_SYNCHRONOUS | \
143 HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
144
145#define HIF_RD_SYNC_BYTE_FIX \
146 (HIF_READ | HIF_SYNCHRONOUS | \
147 HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
148
149#define HIF_RD_ASYNC_BLOCK_FIX \
150 (HIF_READ | HIF_ASYNCHRONOUS | \
151 HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
152
153#define HIF_RD_SYNC_BLOCK_FIX \
154 (HIF_READ | HIF_SYNCHRONOUS | \
155 HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
156
157struct hif_scatter_item {
158 u8 *buf;
159 int len;
160 struct htc_packet *packet;
161};
162
163struct hif_scatter_req {
164 struct list_head list;
165 /* address for the read/write operation */
166 u32 addr;
167
168 /* request flags */
169 u32 req;
170
171 /* total length of entire transfer */
172 u32 len;
173
174 bool virt_scat;
175
176 void (*complete) (struct htc_target *, struct hif_scatter_req *);
177 int status;
178 int scat_entries;
179
180 struct bus_request *busrequest;
181 struct scatterlist *sgentries;
182
183 /* bounce buffer for upper layers to copy to/from */
184 u8 *virt_dma_buf;
185
186 struct hif_scatter_item scat_list[1];
187};
188
189struct ath6kl_hif_ops {
190 int (*read_write_sync)(struct ath6kl *ar, u32 addr, u8 *buf,
191 u32 len, u32 request);
192 int (*write_async)(struct ath6kl *ar, u32 address, u8 *buffer,
193 u32 length, u32 request, struct htc_packet *packet);
194
195 void (*irq_enable)(struct ath6kl *ar);
196 void (*irq_disable)(struct ath6kl *ar);
197
198 struct hif_scatter_req *(*scatter_req_get)(struct ath6kl *ar);
199 void (*scatter_req_add)(struct ath6kl *ar,
200 struct hif_scatter_req *s_req);
201 int (*enable_scatter)(struct ath6kl *ar);
202 int (*scat_req_rw) (struct ath6kl *ar,
203 struct hif_scatter_req *scat_req);
204 void (*cleanup_scatter)(struct ath6kl *ar);
205};
206
207#endif
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
new file mode 100644
index 00000000000..a8dc5c3ea56
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -0,0 +1,2457 @@
1/*
2 * Copyright (c) 2007-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
18#include "htc_hif.h"
19#include "debug.h"
20#include "hif-ops.h"
21#include <asm/unaligned.h>
22
23#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
24
25static void htc_prep_send_pkt(struct htc_packet *packet, u8 flags, int ctrl0,
26 int ctrl1)
27{
28 struct htc_frame_hdr *hdr;
29
30 packet->buf -= HTC_HDR_LENGTH;
31 hdr = (struct htc_frame_hdr *)packet->buf;
32
33 /* Endianess? */
34 put_unaligned((u16)packet->act_len, &hdr->payld_len);
35 hdr->flags = flags;
36 hdr->eid = packet->endpoint;
37 hdr->ctrl[0] = ctrl0;
38 hdr->ctrl[1] = ctrl1;
39}
40
41static void htc_reclaim_txctrl_buf(struct htc_target *target,
42 struct htc_packet *pkt)
43{
44 spin_lock_bh(&target->htc_lock);
45 list_add_tail(&pkt->list, &target->free_ctrl_txbuf);
46 spin_unlock_bh(&target->htc_lock);
47}
48
49static struct htc_packet *htc_get_control_buf(struct htc_target *target,
50 bool tx)
51{
52 struct htc_packet *packet = NULL;
53 struct list_head *buf_list;
54
55 buf_list = tx ? &target->free_ctrl_txbuf : &target->free_ctrl_rxbuf;
56
57 spin_lock_bh(&target->htc_lock);
58
59 if (list_empty(buf_list)) {
60 spin_unlock_bh(&target->htc_lock);
61 return NULL;
62 }
63
64 packet = list_first_entry(buf_list, struct htc_packet, list);
65 list_del(&packet->list);
66 spin_unlock_bh(&target->htc_lock);
67
68 if (tx)
69 packet->buf = packet->buf_start + HTC_HDR_LENGTH;
70
71 return packet;
72}
73
74static void htc_tx_comp_update(struct htc_target *target,
75 struct htc_endpoint *endpoint,
76 struct htc_packet *packet)
77{
78 packet->completion = NULL;
79 packet->buf += HTC_HDR_LENGTH;
80
81 if (!packet->status)
82 return;
83
84 ath6kl_err("req failed (status:%d, ep:%d, len:%d creds:%d)\n",
85 packet->status, packet->endpoint, packet->act_len,
86 packet->info.tx.cred_used);
87
88 /* on failure to submit, reclaim credits for this packet */
89 spin_lock_bh(&target->tx_lock);
90 endpoint->cred_dist.cred_to_dist +=
91 packet->info.tx.cred_used;
92 endpoint->cred_dist.txq_depth = get_queue_depth(&endpoint->txq);
93
94 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
95 target->cred_dist_cntxt, &target->cred_dist_list);
96
97 ath6k_credit_distribute(target->cred_dist_cntxt,
98 &target->cred_dist_list,
99 HTC_CREDIT_DIST_SEND_COMPLETE);
100
101 spin_unlock_bh(&target->tx_lock);
102}
103
104static void htc_tx_complete(struct htc_endpoint *endpoint,
105 struct list_head *txq)
106{
107 if (list_empty(txq))
108 return;
109
110 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
111 "send complete ep %d, (%d pkts)\n",
112 endpoint->eid, get_queue_depth(txq));
113
114 ath6kl_tx_complete(endpoint->target->dev->ar, txq);
115}
116
117static void htc_tx_comp_handler(struct htc_target *target,
118 struct htc_packet *packet)
119{
120 struct htc_endpoint *endpoint = &target->endpoint[packet->endpoint];
121 struct list_head container;
122
123 htc_tx_comp_update(target, endpoint, packet);
124 INIT_LIST_HEAD(&container);
125 list_add_tail(&packet->list, &container);
126 /* do completion */
127 htc_tx_complete(endpoint, &container);
128}
129
130static void htc_async_tx_scat_complete(struct htc_target *target,
131 struct hif_scatter_req *scat_req)
132{
133 struct htc_endpoint *endpoint;
134 struct htc_packet *packet;
135 struct list_head tx_compq;
136 int i;
137
138 INIT_LIST_HEAD(&tx_compq);
139
140 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
141 "htc_async_tx_scat_complete total len: %d entries: %d\n",
142 scat_req->len, scat_req->scat_entries);
143
144 if (scat_req->status)
145 ath6kl_err("send scatter req failed: %d\n", scat_req->status);
146
147 packet = scat_req->scat_list[0].packet;
148 endpoint = &target->endpoint[packet->endpoint];
149
150 /* walk through the scatter list and process */
151 for (i = 0; i < scat_req->scat_entries; i++) {
152 packet = scat_req->scat_list[i].packet;
153 if (!packet) {
154 WARN_ON(1);
155 return;
156 }
157
158 packet->status = scat_req->status;
159 htc_tx_comp_update(target, endpoint, packet);
160 list_add_tail(&packet->list, &tx_compq);
161 }
162
163 /* free scatter request */
164 hif_scatter_req_add(target->dev->ar, scat_req);
165
166 /* complete all packets */
167 htc_tx_complete(endpoint, &tx_compq);
168}
169
170static int htc_issue_send(struct htc_target *target, struct htc_packet *packet)
171{
172 int status;
173 bool sync = false;
174 u32 padded_len, send_len;
175
176 if (!packet->completion)
177 sync = true;
178
179 send_len = packet->act_len + HTC_HDR_LENGTH;
180
181 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "%s: transmit len : %d (%s)\n",
182 __func__, send_len, sync ? "sync" : "async");
183
184 padded_len = CALC_TXRX_PADDED_LEN(target, send_len);
185
186 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
187 "DevSendPacket, padded len: %d mbox:0x%X (mode:%s)\n",
188 padded_len,
189 target->dev->ar->mbox_info.htc_addr,
190 sync ? "sync" : "async");
191
192 if (sync) {
193 status = hif_read_write_sync(target->dev->ar,
194 target->dev->ar->mbox_info.htc_addr,
195 packet->buf, padded_len,
196 HIF_WR_SYNC_BLOCK_INC);
197
198 packet->status = status;
199 packet->buf += HTC_HDR_LENGTH;
200 } else
201 status = hif_write_async(target->dev->ar,
202 target->dev->ar->mbox_info.htc_addr,
203 packet->buf, padded_len,
204 HIF_WR_ASYNC_BLOCK_INC, packet);
205
206 return status;
207}
208
209static int htc_check_credits(struct htc_target *target,
210 struct htc_endpoint *ep, u8 *flags,
211 enum htc_endpoint_id eid, unsigned int len,
212 int *req_cred)
213{
214
215 *req_cred = (len > target->tgt_cred_sz) ?
216 DIV_ROUND_UP(len, target->tgt_cred_sz) : 1;
217
218 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "creds required:%d got:%d\n",
219 *req_cred, ep->cred_dist.credits);
220
221 if (ep->cred_dist.credits < *req_cred) {
222 if (eid == ENDPOINT_0)
223 return -EINVAL;
224
225 /* Seek more credits */
226 ep->cred_dist.seek_cred = *req_cred - ep->cred_dist.credits;
227
228 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
229 target->cred_dist_cntxt, &ep->cred_dist);
230
231 ath6k_seek_credits(target->cred_dist_cntxt, &ep->cred_dist);
232
233 ep->cred_dist.seek_cred = 0;
234
235 if (ep->cred_dist.credits < *req_cred) {
236 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
237 "not enough credits for ep %d - leaving packet in queue\n",
238 eid);
239 return -EINVAL;
240 }
241 }
242
243 ep->cred_dist.credits -= *req_cred;
244 ep->ep_st.cred_cosumd += *req_cred;
245
246 /* When we are getting low on credits, ask for more */
247 if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
248 ep->cred_dist.seek_cred =
249 ep->cred_dist.cred_per_msg - ep->cred_dist.credits;
250
251 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
252 target->cred_dist_cntxt, &ep->cred_dist);
253
254 ath6k_seek_credits(target->cred_dist_cntxt, &ep->cred_dist);
255
256 /* see if we were successful in getting more */
257 if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
258 /* tell the target we need credits ASAP! */
259 *flags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
260 ep->ep_st.cred_low_indicate += 1;
261 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "host needs credits\n");
262 }
263 }
264
265 return 0;
266}
267
268static void htc_tx_pkts_get(struct htc_target *target,
269 struct htc_endpoint *endpoint,
270 struct list_head *queue)
271{
272 int req_cred;
273 u8 flags;
274 struct htc_packet *packet;
275 unsigned int len;
276
277 while (true) {
278
279 flags = 0;
280
281 if (list_empty(&endpoint->txq))
282 break;
283 packet = list_first_entry(&endpoint->txq, struct htc_packet,
284 list);
285
286 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
287 "got head pkt:0x%p , queue depth: %d\n",
288 packet, get_queue_depth(&endpoint->txq));
289
290 len = CALC_TXRX_PADDED_LEN(target,
291 packet->act_len + HTC_HDR_LENGTH);
292
293 if (htc_check_credits(target, endpoint, &flags,
294 packet->endpoint, len, &req_cred))
295 break;
296
297 /* now we can fully move onto caller's queue */
298 packet = list_first_entry(&endpoint->txq, struct htc_packet,
299 list);
300 list_move_tail(&packet->list, queue);
301
302 /* save the number of credits this packet consumed */
303 packet->info.tx.cred_used = req_cred;
304
305 /* all TX packets are handled asynchronously */
306 packet->completion = htc_tx_comp_handler;
307 packet->context = target;
308 endpoint->ep_st.tx_issued += 1;
309
310 /* save send flags */
311 packet->info.tx.flags = flags;
312 packet->info.tx.seqno = endpoint->seqno;
313 endpoint->seqno++;
314 }
315}
316
317/* See if the padded tx length falls on a credit boundary */
318static int htc_get_credit_padding(unsigned int cred_sz, int *len,
319 struct htc_endpoint *ep)
320{
321 int rem_cred, cred_pad;
322
323 rem_cred = *len % cred_sz;
324
325 /* No padding needed */
326 if (!rem_cred)
327 return 0;
328
329 if (!(ep->conn_flags & HTC_FLGS_TX_BNDL_PAD_EN))
330 return -1;
331
332 /*
333 * The transfer consumes a "partial" credit, this
334 * packet cannot be bundled unless we add
335 * additional "dummy" padding (max 255 bytes) to
336 * consume the entire credit.
337 */
338 cred_pad = *len < cred_sz ? (cred_sz - *len) : rem_cred;
339
340 if ((cred_pad > 0) && (cred_pad <= 255))
341 *len += cred_pad;
342 else
343 /* The amount of padding is too large, send as non-bundled */
344 return -1;
345
346 return cred_pad;
347}
348
349static int htc_setup_send_scat_list(struct htc_target *target,
350 struct htc_endpoint *endpoint,
351 struct hif_scatter_req *scat_req,
352 int n_scat,
353 struct list_head *queue)
354{
355 struct htc_packet *packet;
356 int i, len, rem_scat, cred_pad;
357 int status = 0;
358
359 rem_scat = target->max_tx_bndl_sz;
360
361 for (i = 0; i < n_scat; i++) {
362 scat_req->scat_list[i].packet = NULL;
363
364 if (list_empty(queue))
365 break;
366
367 packet = list_first_entry(queue, struct htc_packet, list);
368 len = CALC_TXRX_PADDED_LEN(target,
369 packet->act_len + HTC_HDR_LENGTH);
370
371 cred_pad = htc_get_credit_padding(target->tgt_cred_sz,
372 &len, endpoint);
373 if (cred_pad < 0) {
374 status = -EINVAL;
375 break;
376 }
377
378 if (rem_scat < len) {
379 /* exceeds what we can transfer */
380 status = -ENOSPC;
381 break;
382 }
383
384 rem_scat -= len;
385 /* now remove it from the queue */
386 packet = list_first_entry(queue, struct htc_packet, list);
387 list_del(&packet->list);
388
389 scat_req->scat_list[i].packet = packet;
390 /* prepare packet and flag message as part of a send bundle */
391 htc_prep_send_pkt(packet,
392 packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE,
393 cred_pad, packet->info.tx.seqno);
394 scat_req->scat_list[i].buf = packet->buf;
395 scat_req->scat_list[i].len = len;
396
397 scat_req->len += len;
398 scat_req->scat_entries++;
399 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
400 "%d, adding pkt : 0x%p len:%d (remaining space:%d)\n",
401 i, packet, len, rem_scat);
402 }
403
404 /* Roll back scatter setup in case of any failure */
405 if (status || (scat_req->scat_entries < HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
406 for (i = scat_req->scat_entries - 1; i >= 0; i--) {
407 packet = scat_req->scat_list[i].packet;
408 if (packet) {
409 packet->buf += HTC_HDR_LENGTH;
410 list_add(&packet->list, queue);
411 }
412 }
413 return -EINVAL;
414 }
415
416 return 0;
417}
418
419/*
420 * htc_issue_send_bundle: drain a queue and send as bundles
421 * this function may return without fully draining the queue
422 * when
423 *
424 * 1. scatter resources are exhausted
425 * 2. a message that will consume a partial credit will stop the
426 * bundling process early
427 * 3. we drop below the minimum number of messages for a bundle
428 */
429static void htc_issue_send_bundle(struct htc_endpoint *endpoint,
430 struct list_head *queue,
431 int *sent_bundle, int *n_bundle_pkts)
432{
433 struct htc_target *target = endpoint->target;
434 struct hif_scatter_req *scat_req = NULL;
435 int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0;
436
437 while (true) {
438 n_scat = get_queue_depth(queue);
439 n_scat = min(n_scat, target->msg_per_bndl_max);
440
441 if (n_scat < HTC_MIN_HTC_MSGS_TO_BUNDLE)
442 /* not enough to bundle */
443 break;
444
445 scat_req = hif_scatter_req_get(target->dev->ar);
446
447 if (!scat_req) {
448 /* no scatter resources */
449 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
450 "no more scatter resources\n");
451 break;
452 }
453
454 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "pkts to scatter: %d\n",
455 n_scat);
456
457 scat_req->len = 0;
458 scat_req->scat_entries = 0;
459
460 if (htc_setup_send_scat_list(target, endpoint, scat_req,
461 n_scat, queue)) {
462 hif_scatter_req_add(target->dev->ar, scat_req);
463 break;
464 }
465
466 /* send path is always asynchronous */
467 scat_req->complete = htc_async_tx_scat_complete;
468 n_sent_bundle++;
469 tot_pkts_bundle += scat_req->scat_entries;
470
471 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
472 "send scatter total bytes: %d , entries: %d\n",
473 scat_req->len, scat_req->scat_entries);
474 ath6kldev_submit_scat_req(target->dev, scat_req, false);
475 }
476
477 *sent_bundle = n_sent_bundle;
478 *n_bundle_pkts = tot_pkts_bundle;
479 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "htc_issue_send_bundle (sent:%d)\n",
480 n_sent_bundle);
481
482 return;
483}
484
485static void htc_tx_from_ep_txq(struct htc_target *target,
486 struct htc_endpoint *endpoint)
487{
488 struct list_head txq;
489 struct htc_packet *packet;
490 int bundle_sent;
491 int n_pkts_bundle;
492
493 spin_lock_bh(&target->tx_lock);
494
495 endpoint->tx_proc_cnt++;
496 if (endpoint->tx_proc_cnt > 1) {
497 endpoint->tx_proc_cnt--;
498 spin_unlock_bh(&target->tx_lock);
499 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "htc_try_send (busy)\n");
500 return;
501 }
502
503 /*
504 * drain the endpoint TX queue for transmission as long
505 * as we have enough credits.
506 */
507 INIT_LIST_HEAD(&txq);
508
509 while (true) {
510
511 if (list_empty(&endpoint->txq))
512 break;
513
514 htc_tx_pkts_get(target, endpoint, &txq);
515
516 if (list_empty(&txq))
517 break;
518
519 spin_unlock_bh(&target->tx_lock);
520
521 bundle_sent = 0;
522 n_pkts_bundle = 0;
523
524 while (true) {
525 /* try to send a bundle on each pass */
526 if ((target->tx_bndl_enable) &&
527 (get_queue_depth(&txq) >=
528 HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
529 int temp1 = 0, temp2 = 0;
530
531 htc_issue_send_bundle(endpoint, &txq,
532 &temp1, &temp2);
533 bundle_sent += temp1;
534 n_pkts_bundle += temp2;
535 }
536
537 if (list_empty(&txq))
538 break;
539
540 packet = list_first_entry(&txq, struct htc_packet,
541 list);
542 list_del(&packet->list);
543
544 htc_prep_send_pkt(packet, packet->info.tx.flags,
545 0, packet->info.tx.seqno);
546 htc_issue_send(target, packet);
547 }
548
549 spin_lock_bh(&target->tx_lock);
550
551 endpoint->ep_st.tx_bundles += bundle_sent;
552 endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle;
553 }
554
555 endpoint->tx_proc_cnt = 0;
556 spin_unlock_bh(&target->tx_lock);
557}
558
559static bool htc_try_send(struct htc_target *target,
560 struct htc_endpoint *endpoint,
561 struct htc_packet *tx_pkt)
562{
563 struct htc_ep_callbacks ep_cb;
564 int txq_depth;
565 bool overflow = false;
566
567 ep_cb = endpoint->ep_cb;
568
569 spin_lock_bh(&target->tx_lock);
570 txq_depth = get_queue_depth(&endpoint->txq);
571 spin_unlock_bh(&target->tx_lock);
572
573 if (txq_depth >= endpoint->max_txq_depth)
574 overflow = true;
575
576 if (overflow)
577 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
578 "ep %d, tx queue will overflow :%d , tx depth:%d, max:%d\n",
579 endpoint->eid, overflow, txq_depth,
580 endpoint->max_txq_depth);
581
582 if (overflow && ep_cb.tx_full) {
583 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
584 "indicating overflowed tx packet: 0x%p\n", tx_pkt);
585
586 if (ep_cb.tx_full(endpoint->target, tx_pkt) ==
587 HTC_SEND_FULL_DROP) {
588 endpoint->ep_st.tx_dropped += 1;
589 return false;
590 }
591 }
592
593 spin_lock_bh(&target->tx_lock);
594 list_add_tail(&tx_pkt->list, &endpoint->txq);
595 spin_unlock_bh(&target->tx_lock);
596
597 htc_tx_from_ep_txq(target, endpoint);
598
599 return true;
600}
601
602static void htc_chk_ep_txq(struct htc_target *target)
603{
604 struct htc_endpoint *endpoint;
605 struct htc_endpoint_credit_dist *cred_dist;
606
607 /*
608 * Run through the credit distribution list to see if there are
609 * packets queued. NOTE: no locks need to be taken since the
610 * distribution list is not dynamic (cannot be re-ordered) and we
611 * are not modifying any state.
612 */
613 list_for_each_entry(cred_dist, &target->cred_dist_list, list) {
614 endpoint = (struct htc_endpoint *)cred_dist->htc_rsvd;
615
616 spin_lock_bh(&target->tx_lock);
617 if (!list_empty(&endpoint->txq)) {
618 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
619 "ep %d has %d credits and %d packets in tx queue\n",
620 cred_dist->endpoint,
621 endpoint->cred_dist.credits,
622 get_queue_depth(&endpoint->txq));
623 spin_unlock_bh(&target->tx_lock);
624 /*
625 * Try to start the stalled queue, this list is
626 * ordered by priority. If there are credits
627 * available the highest priority queue will get a
628 * chance to reclaim credits from lower priority
629 * ones.
630 */
631 htc_tx_from_ep_txq(target, endpoint);
632 spin_lock_bh(&target->tx_lock);
633 }
634 spin_unlock_bh(&target->tx_lock);
635 }
636}
637
638static int htc_setup_tx_complete(struct htc_target *target)
639{
640 struct htc_packet *send_pkt = NULL;
641 int status;
642
643 send_pkt = htc_get_control_buf(target, true);
644
645 if (!send_pkt)
646 return -ENOMEM;
647
648 if (target->htc_tgt_ver >= HTC_VERSION_2P1) {
649 struct htc_setup_comp_ext_msg *setup_comp_ext;
650 u32 flags = 0;
651
652 setup_comp_ext =
653 (struct htc_setup_comp_ext_msg *)send_pkt->buf;
654 memset(setup_comp_ext, 0, sizeof(*setup_comp_ext));
655 setup_comp_ext->msg_id =
656 cpu_to_le16(HTC_MSG_SETUP_COMPLETE_EX_ID);
657
658 if (target->msg_per_bndl_max > 0) {
659 /* Indicate HTC bundling to the target */
660 flags |= HTC_SETUP_COMP_FLG_RX_BNDL_EN;
661 setup_comp_ext->msg_per_rxbndl =
662 target->msg_per_bndl_max;
663 }
664
665 memcpy(&setup_comp_ext->flags, &flags,
666 sizeof(setup_comp_ext->flags));
667 set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp_ext,
668 sizeof(struct htc_setup_comp_ext_msg),
669 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
670
671 } else {
672 struct htc_setup_comp_msg *setup_comp;
673 setup_comp = (struct htc_setup_comp_msg *)send_pkt->buf;
674 memset(setup_comp, 0, sizeof(struct htc_setup_comp_msg));
675 setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID);
676 set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp,
677 sizeof(struct htc_setup_comp_msg),
678 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
679 }
680
681 /* we want synchronous operation */
682 send_pkt->completion = NULL;
683 htc_prep_send_pkt(send_pkt, 0, 0, 0);
684 status = htc_issue_send(target, send_pkt);
685
686 if (send_pkt != NULL)
687 htc_reclaim_txctrl_buf(target, send_pkt);
688
689 return status;
690}
691
692void ath6kl_htc_set_credit_dist(struct htc_target *target,
693 struct htc_credit_state_info *cred_dist_cntxt,
694 u16 srvc_pri_order[], int list_len)
695{
696 struct htc_endpoint *endpoint;
697 int i, ep;
698
699 target->cred_dist_cntxt = cred_dist_cntxt;
700
701 list_add_tail(&target->endpoint[ENDPOINT_0].cred_dist.list,
702 &target->cred_dist_list);
703
704 for (i = 0; i < list_len; i++) {
705 for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) {
706 endpoint = &target->endpoint[ep];
707 if (endpoint->svc_id == srvc_pri_order[i]) {
708 list_add_tail(&endpoint->cred_dist.list,
709 &target->cred_dist_list);
710 break;
711 }
712 }
713 if (ep >= ENDPOINT_MAX) {
714 WARN_ON(1);
715 return;
716 }
717 }
718}
719
720int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet)
721{
722 struct htc_endpoint *endpoint;
723 struct list_head queue;
724
725 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
726 "htc_tx: ep id: %d, buf: 0x%p, len: %d\n",
727 packet->endpoint, packet->buf, packet->act_len);
728
729 if (packet->endpoint >= ENDPOINT_MAX) {
730 WARN_ON(1);
731 return -EINVAL;
732 }
733
734 endpoint = &target->endpoint[packet->endpoint];
735
736 if (!htc_try_send(target, endpoint, packet)) {
737 packet->status = (target->htc_flags & HTC_OP_STATE_STOPPING) ?
738 -ECANCELED : -ENOSPC;
739 INIT_LIST_HEAD(&queue);
740 list_add(&packet->list, &queue);
741 htc_tx_complete(endpoint, &queue);
742 }
743
744 return 0;
745}
746
747/* flush endpoint TX queue */
748void ath6kl_htc_flush_txep(struct htc_target *target,
749 enum htc_endpoint_id eid, u16 tag)
750{
751 struct htc_packet *packet, *tmp_pkt;
752 struct list_head discard_q, container;
753 struct htc_endpoint *endpoint = &target->endpoint[eid];
754
755 if (!endpoint->svc_id) {
756 WARN_ON(1);
757 return;
758 }
759
760 /* initialize the discard queue */
761 INIT_LIST_HEAD(&discard_q);
762
763 spin_lock_bh(&target->tx_lock);
764
765 list_for_each_entry_safe(packet, tmp_pkt, &endpoint->txq, list) {
766 if ((tag == HTC_TX_PACKET_TAG_ALL) ||
767 (tag == packet->info.tx.tag))
768 list_move_tail(&packet->list, &discard_q);
769 }
770
771 spin_unlock_bh(&target->tx_lock);
772
773 list_for_each_entry_safe(packet, tmp_pkt, &discard_q, list) {
774 packet->status = -ECANCELED;
775 list_del(&packet->list);
776 ath6kl_dbg(ATH6KL_DBG_TRC,
777 "flushing tx pkt:0x%p, len:%d, ep:%d tag:0x%X\n",
778 packet, packet->act_len,
779 packet->endpoint, packet->info.tx.tag);
780
781 INIT_LIST_HEAD(&container);
782 list_add_tail(&packet->list, &container);
783 htc_tx_complete(endpoint, &container);
784 }
785
786}
787
788static void ath6kl_htc_flush_txep_all(struct htc_target *target)
789{
790 struct htc_endpoint *endpoint;
791 int i;
792
793 dump_cred_dist_stats(target);
794
795 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
796 endpoint = &target->endpoint[i];
797 if (endpoint->svc_id == 0)
798 /* not in use.. */
799 continue;
800 ath6kl_htc_flush_txep(target, i, HTC_TX_PACKET_TAG_ALL);
801 }
802}
803
804void ath6kl_htc_indicate_activity_change(struct htc_target *target,
805 enum htc_endpoint_id eid, bool active)
806{
807 struct htc_endpoint *endpoint = &target->endpoint[eid];
808 bool dist = false;
809
810 if (endpoint->svc_id == 0) {
811 WARN_ON(1);
812 return;
813 }
814
815 spin_lock_bh(&target->tx_lock);
816
817 if (active) {
818 if (!(endpoint->cred_dist.dist_flags & HTC_EP_ACTIVE)) {
819 endpoint->cred_dist.dist_flags |= HTC_EP_ACTIVE;
820 dist = true;
821 }
822 } else {
823 if (endpoint->cred_dist.dist_flags & HTC_EP_ACTIVE) {
824 endpoint->cred_dist.dist_flags &= ~HTC_EP_ACTIVE;
825 dist = true;
826 }
827 }
828
829 if (dist) {
830 endpoint->cred_dist.txq_depth =
831 get_queue_depth(&endpoint->txq);
832
833 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
834 target->cred_dist_cntxt, &target->cred_dist_list);
835
836 ath6k_credit_distribute(target->cred_dist_cntxt,
837 &target->cred_dist_list,
838 HTC_CREDIT_DIST_ACTIVITY_CHANGE);
839 }
840
841 spin_unlock_bh(&target->tx_lock);
842
843 if (dist && !active)
844 htc_chk_ep_txq(target);
845}
846
847/* HTC Rx */
848
849static inline void htc_update_rx_stats(struct htc_endpoint *endpoint,
850 int n_look_ahds)
851{
852 endpoint->ep_st.rx_pkts++;
853 if (n_look_ahds == 1)
854 endpoint->ep_st.rx_lkahds++;
855 else if (n_look_ahds > 1)
856 endpoint->ep_st.rx_bundle_lkahd++;
857}
858
859static inline bool htc_valid_rx_frame_len(struct htc_target *target,
860 enum htc_endpoint_id eid, int len)
861{
862 return (eid == target->dev->ar->ctrl_ep) ?
863 len <= ATH6KL_BUFFER_SIZE : len <= ATH6KL_AMSDU_BUFFER_SIZE;
864}
865
866static int htc_add_rxbuf(struct htc_target *target, struct htc_packet *packet)
867{
868 struct list_head queue;
869
870 INIT_LIST_HEAD(&queue);
871 list_add_tail(&packet->list, &queue);
872 return ath6kl_htc_add_rxbuf_multiple(target, &queue);
873}
874
875static void htc_reclaim_rxbuf(struct htc_target *target,
876 struct htc_packet *packet,
877 struct htc_endpoint *ep)
878{
879 if (packet->info.rx.rx_flags & HTC_RX_PKT_NO_RECYCLE) {
880 htc_rxpkt_reset(packet);
881 packet->status = -ECANCELED;
882 ep->ep_cb.rx(ep->target, packet);
883 } else {
884 htc_rxpkt_reset(packet);
885 htc_add_rxbuf((void *)(target), packet);
886 }
887}
888
889static void reclaim_rx_ctrl_buf(struct htc_target *target,
890 struct htc_packet *packet)
891{
892 spin_lock_bh(&target->htc_lock);
893 list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
894 spin_unlock_bh(&target->htc_lock);
895}
896
897static int dev_rx_pkt(struct htc_target *target, struct htc_packet *packet,
898 u32 rx_len)
899{
900 struct ath6kl_device *dev = target->dev;
901 u32 padded_len;
902 int status;
903
904 padded_len = CALC_TXRX_PADDED_LEN(target, rx_len);
905
906 if (padded_len > packet->buf_len) {
907 ath6kl_err("not enough receive space for packet - padlen:%d recvlen:%d bufferlen:%d\n",
908 padded_len, rx_len, packet->buf_len);
909 return -ENOMEM;
910 }
911
912 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
913 "dev_rx_pkt (0x%p : hdr:0x%X) padded len: %d mbox:0x%X (mode:%s)\n",
914 packet, packet->info.rx.exp_hdr,
915 padded_len, dev->ar->mbox_info.htc_addr, "sync");
916
917 status = hif_read_write_sync(dev->ar,
918 dev->ar->mbox_info.htc_addr,
919 packet->buf, padded_len,
920 HIF_RD_SYNC_BLOCK_FIX);
921
922 packet->status = status;
923
924 return status;
925}
926
927/*
928 * optimization for recv packets, we can indicate a
929 * "hint" that there are more single-packets to fetch
930 * on this endpoint.
931 */
932static void set_rxpkt_indication_flag(u32 lk_ahd,
933 struct htc_endpoint *endpoint,
934 struct htc_packet *packet)
935{
936 struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)&lk_ahd;
937
938 if (htc_hdr->eid == packet->endpoint) {
939 if (!list_empty(&endpoint->rx_bufq))
940 packet->info.rx.indicat_flags |=
941 HTC_RX_FLAGS_INDICATE_MORE_PKTS;
942 }
943}
944
945static void chk_rx_water_mark(struct htc_endpoint *endpoint)
946{
947 struct htc_ep_callbacks ep_cb = endpoint->ep_cb;
948
949 if (ep_cb.rx_refill_thresh > 0) {
950 spin_lock_bh(&endpoint->target->rx_lock);
951 if (get_queue_depth(&endpoint->rx_bufq)
952 < ep_cb.rx_refill_thresh) {
953 spin_unlock_bh(&endpoint->target->rx_lock);
954 ep_cb.rx_refill(endpoint->target, endpoint->eid);
955 return;
956 }
957 spin_unlock_bh(&endpoint->target->rx_lock);
958 }
959}
960
961/* This function is called with rx_lock held */
962static int htc_setup_rxpkts(struct htc_target *target, struct htc_endpoint *ep,
963 u32 *lk_ahds, struct list_head *queue, int n_msg)
964{
965 struct htc_packet *packet;
966 /* FIXME: type of lk_ahds can't be right */
967 struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)lk_ahds;
968 struct htc_ep_callbacks ep_cb;
969 int status = 0, j, full_len;
970 bool no_recycle;
971
972 full_len = CALC_TXRX_PADDED_LEN(target,
973 le16_to_cpu(htc_hdr->payld_len) +
974 sizeof(*htc_hdr));
975
976 if (!htc_valid_rx_frame_len(target, ep->eid, full_len)) {
977 ath6kl_warn("Rx buffer requested with invalid length\n");
978 return -EINVAL;
979 }
980
981 ep_cb = ep->ep_cb;
982 for (j = 0; j < n_msg; j++) {
983
984 /*
985 * Reset flag, any packets allocated using the
986 * rx_alloc() API cannot be recycled on
987 * cleanup,they must be explicitly returned.
988 */
989 no_recycle = false;
990
991 if (ep_cb.rx_allocthresh &&
992 (full_len > ep_cb.rx_alloc_thresh)) {
993 ep->ep_st.rx_alloc_thresh_hit += 1;
994 ep->ep_st.rxalloc_thresh_byte +=
995 le16_to_cpu(htc_hdr->payld_len);
996
997 spin_unlock_bh(&target->rx_lock);
998 no_recycle = true;
999
1000 packet = ep_cb.rx_allocthresh(ep->target, ep->eid,
1001 full_len);
1002 spin_lock_bh(&target->rx_lock);
1003 } else {
1004 /* refill handler is being used */
1005 if (list_empty(&ep->rx_bufq)) {
1006 if (ep_cb.rx_refill) {
1007 spin_unlock_bh(&target->rx_lock);
1008 ep_cb.rx_refill(ep->target, ep->eid);
1009 spin_lock_bh(&target->rx_lock);
1010 }
1011 }
1012
1013 if (list_empty(&ep->rx_bufq))
1014 packet = NULL;
1015 else {
1016 packet = list_first_entry(&ep->rx_bufq,
1017 struct htc_packet, list);
1018 list_del(&packet->list);
1019 }
1020 }
1021
1022 if (!packet) {
1023 target->rx_st_flags |= HTC_RECV_WAIT_BUFFERS;
1024 target->ep_waiting = ep->eid;
1025 return -ENOSPC;
1026 }
1027
1028 /* clear flags */
1029 packet->info.rx.rx_flags = 0;
1030 packet->info.rx.indicat_flags = 0;
1031 packet->status = 0;
1032
1033 if (no_recycle)
1034 /*
1035 * flag that these packets cannot be
1036 * recycled, they have to be returned to
1037 * the user
1038 */
1039 packet->info.rx.rx_flags |= HTC_RX_PKT_NO_RECYCLE;
1040
1041 /* Caller needs to free this upon any failure */
1042 list_add_tail(&packet->list, queue);
1043
1044 if (target->htc_flags & HTC_OP_STATE_STOPPING) {
1045 status = -ECANCELED;
1046 break;
1047 }
1048
1049 if (j) {
1050 packet->info.rx.rx_flags |= HTC_RX_PKT_REFRESH_HDR;
1051 packet->info.rx.exp_hdr = 0xFFFFFFFF;
1052 } else
1053 /* set expected look ahead */
1054 packet->info.rx.exp_hdr = *lk_ahds;
1055
1056 packet->act_len = le16_to_cpu(htc_hdr->payld_len) +
1057 HTC_HDR_LENGTH;
1058 }
1059
1060 return status;
1061}
1062
1063static int alloc_and_prep_rxpkts(struct htc_target *target,
1064 u32 lk_ahds[], int msg,
1065 struct htc_endpoint *endpoint,
1066 struct list_head *queue)
1067{
1068 int status = 0;
1069 struct htc_packet *packet, *tmp_pkt;
1070 struct htc_frame_hdr *htc_hdr;
1071 int i, n_msg;
1072
1073 spin_lock_bh(&target->rx_lock);
1074
1075 for (i = 0; i < msg; i++) {
1076
1077 htc_hdr = (struct htc_frame_hdr *)&lk_ahds[i];
1078
1079 if (htc_hdr->eid >= ENDPOINT_MAX) {
1080 ath6kl_err("invalid ep in look-ahead: %d\n",
1081 htc_hdr->eid);
1082 status = -ENOMEM;
1083 break;
1084 }
1085
1086 if (htc_hdr->eid != endpoint->eid) {
1087 ath6kl_err("invalid ep in look-ahead: %d should be : %d (index:%d)\n",
1088 htc_hdr->eid, endpoint->eid, i);
1089 status = -ENOMEM;
1090 break;
1091 }
1092
1093 if (le16_to_cpu(htc_hdr->payld_len) > HTC_MAX_PAYLOAD_LENGTH) {
1094 ath6kl_err("payload len %d exceeds max htc : %d !\n",
1095 htc_hdr->payld_len,
1096 (u32) HTC_MAX_PAYLOAD_LENGTH);
1097 status = -ENOMEM;
1098 break;
1099 }
1100
1101 if (endpoint->svc_id == 0) {
1102 ath6kl_err("ep %d is not connected !\n", htc_hdr->eid);
1103 status = -ENOMEM;
1104 break;
1105 }
1106
1107 if (htc_hdr->flags & HTC_FLG_RX_BNDL_CNT) {
1108 /*
1109 * HTC header indicates that every packet to follow
1110 * has the same padded length so that it can be
1111 * optimally fetched as a full bundle.
1112 */
1113 n_msg = (htc_hdr->flags & HTC_FLG_RX_BNDL_CNT) >>
1114 HTC_FLG_RX_BNDL_CNT_S;
1115
1116 /* the count doesn't include the starter frame */
1117 n_msg++;
1118 if (n_msg > target->msg_per_bndl_max) {
1119 status = -ENOMEM;
1120 break;
1121 }
1122
1123 endpoint->ep_st.rx_bundle_from_hdr += 1;
1124 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
1125 "htc hdr indicates :%d msg can be fetched as a bundle\n",
1126 n_msg);
1127 } else
1128 /* HTC header only indicates 1 message to fetch */
1129 n_msg = 1;
1130
1131 /* Setup packet buffers for each message */
1132 status = htc_setup_rxpkts(target, endpoint, &lk_ahds[i], queue,
1133 n_msg);
1134
1135 /*
1136 * This is due to unavailabilty of buffers to rx entire data.
1137 * Return no error so that free buffers from queue can be used
1138 * to receive partial data.
1139 */
1140 if (status == -ENOSPC) {
1141 spin_unlock_bh(&target->rx_lock);
1142 return 0;
1143 }
1144
1145 if (status)
1146 break;
1147 }
1148
1149 spin_unlock_bh(&target->rx_lock);
1150
1151 if (status) {
1152 list_for_each_entry_safe(packet, tmp_pkt, queue, list) {
1153 list_del(&packet->list);
1154 htc_reclaim_rxbuf(target, packet,
1155 &target->endpoint[packet->endpoint]);
1156 }
1157 }
1158
1159 return status;
1160}
1161
1162static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets)
1163{
1164 if (packets->endpoint != ENDPOINT_0) {
1165 WARN_ON(1);
1166 return;
1167 }
1168
1169 if (packets->status == -ECANCELED) {
1170 reclaim_rx_ctrl_buf(context, packets);
1171 return;
1172 }
1173
1174 if (packets->act_len > 0) {
1175 ath6kl_err("htc_ctrl_rx, got message with len:%zu\n",
1176 packets->act_len + HTC_HDR_LENGTH);
1177
1178 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES,
1179 "Unexpected ENDPOINT 0 Message",
1180 packets->buf - HTC_HDR_LENGTH,
1181 packets->act_len + HTC_HDR_LENGTH);
1182 }
1183
1184 htc_reclaim_rxbuf(context, packets, &context->endpoint[0]);
1185}
1186
1187static void htc_proc_cred_rpt(struct htc_target *target,
1188 struct htc_credit_report *rpt,
1189 int n_entries,
1190 enum htc_endpoint_id from_ep)
1191{
1192 struct htc_endpoint *endpoint;
1193 int tot_credits = 0, i;
1194 bool dist = false;
1195
1196 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
1197 "htc_proc_cred_rpt, credit report entries:%d\n", n_entries);
1198
1199 spin_lock_bh(&target->tx_lock);
1200
1201 for (i = 0; i < n_entries; i++, rpt++) {
1202 if (rpt->eid >= ENDPOINT_MAX) {
1203 WARN_ON(1);
1204 spin_unlock_bh(&target->tx_lock);
1205 return;
1206 }
1207
1208 endpoint = &target->endpoint[rpt->eid];
1209
1210 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, " ep %d got %d credits\n",
1211 rpt->eid, rpt->credits);
1212
1213 endpoint->ep_st.tx_cred_rpt += 1;
1214 endpoint->ep_st.cred_retnd += rpt->credits;
1215
1216 if (from_ep == rpt->eid) {
1217 /*
1218 * This credit report arrived on the same endpoint
1219 * indicating it arrived in an RX packet.
1220 */
1221 endpoint->ep_st.cred_from_rx += rpt->credits;
1222 endpoint->ep_st.cred_rpt_from_rx += 1;
1223 } else if (from_ep == ENDPOINT_0) {
1224 /* credit arrived on endpoint 0 as a NULL message */
1225 endpoint->ep_st.cred_from_ep0 += rpt->credits;
1226 endpoint->ep_st.cred_rpt_ep0 += 1;
1227 } else {
1228 endpoint->ep_st.cred_from_other += rpt->credits;
1229 endpoint->ep_st.cred_rpt_from_other += 1;
1230 }
1231
1232 if (rpt->eid == ENDPOINT_0)
1233 /* always give endpoint 0 credits back */
1234 endpoint->cred_dist.credits += rpt->credits;
1235 else {
1236 endpoint->cred_dist.cred_to_dist += rpt->credits;
1237 dist = true;
1238 }
1239
1240 /*
1241 * Refresh tx depth for distribution function that will
1242 * recover these credits NOTE: this is only valid when
1243 * there are credits to recover!
1244 */
1245 endpoint->cred_dist.txq_depth =
1246 get_queue_depth(&endpoint->txq);
1247
1248 tot_credits += rpt->credits;
1249 }
1250
1251 ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
1252 "report indicated %d credits to distribute\n",
1253 tot_credits);
1254
1255 if (dist) {
1256 /*
1257 * This was a credit return based on a completed send
1258 * operations note, this is done with the lock held
1259 */
1260 ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
1261 target->cred_dist_cntxt, &target->cred_dist_list);
1262
1263 ath6k_credit_distribute(target->cred_dist_cntxt,
1264 &target->cred_dist_list,
1265 HTC_CREDIT_DIST_SEND_COMPLETE);
1266 }
1267
1268 spin_unlock_bh(&target->tx_lock);
1269
1270 if (tot_credits)
1271 htc_chk_ep_txq(target);
1272}
1273
1274static int htc_parse_trailer(struct htc_target *target,
1275 struct htc_record_hdr *record,
1276 u8 *record_buf, u32 *next_lk_ahds,
1277 enum htc_endpoint_id endpoint,
1278 int *n_lk_ahds)
1279{
1280 struct htc_bundle_lkahd_rpt *bundle_lkahd_rpt;
1281 struct htc_lookahead_report *lk_ahd;
1282 int len;
1283
1284 switch (record->rec_id) {
1285 case HTC_RECORD_CREDITS:
1286 len = record->len / sizeof(struct htc_credit_report);
1287 if (!len) {
1288 WARN_ON(1);
1289 return -EINVAL;
1290 }
1291
1292 htc_proc_cred_rpt(target,
1293 (struct htc_credit_report *) record_buf,
1294 len, endpoint);
1295 break;
1296 case HTC_RECORD_LOOKAHEAD:
1297 len = record->len / sizeof(*lk_ahd);
1298 if (!len) {
1299 WARN_ON(1);
1300 return -EINVAL;
1301 }
1302
1303 lk_ahd = (struct htc_lookahead_report *) record_buf;
1304 if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF))
1305 && next_lk_ahds) {
1306
1307 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
1308 "lk_ahd report found (pre valid:0x%X, post valid:0x%X)\n",
1309 lk_ahd->pre_valid, lk_ahd->post_valid);
1310
1311 /* look ahead bytes are valid, copy them over */
1312 memcpy((u8 *)&next_lk_ahds[0], lk_ahd->lk_ahd, 4);
1313
1314 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Next Look Ahead",
1315 next_lk_ahds, 4);
1316
1317 *n_lk_ahds = 1;
1318 }
1319 break;
1320 case HTC_RECORD_LOOKAHEAD_BUNDLE:
1321 len = record->len / sizeof(*bundle_lkahd_rpt);
1322 if (!len || (len > HTC_HOST_MAX_MSG_PER_BUNDLE)) {
1323 WARN_ON(1);
1324 return -EINVAL;
1325 }
1326
1327 if (next_lk_ahds) {
1328 int i;
1329
1330 bundle_lkahd_rpt =
1331 (struct htc_bundle_lkahd_rpt *) record_buf;
1332
1333 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Bundle lk_ahd",
1334 record_buf, record->len);
1335
1336 for (i = 0; i < len; i++) {
1337 memcpy((u8 *)&next_lk_ahds[i],
1338 bundle_lkahd_rpt->lk_ahd, 4);
1339 bundle_lkahd_rpt++;
1340 }
1341
1342 *n_lk_ahds = i;
1343 }
1344 break;
1345 default:
1346 ath6kl_err("unhandled record: id:%d len:%d\n",
1347 record->rec_id, record->len);
1348 break;
1349 }
1350
1351 return 0;
1352
1353}
1354
1355static int htc_proc_trailer(struct htc_target *target,
1356 u8 *buf, int len, u32 *next_lk_ahds,
1357 int *n_lk_ahds, enum htc_endpoint_id endpoint)
1358{
1359 struct htc_record_hdr *record;
1360 int orig_len;
1361 int status;
1362 u8 *record_buf;
1363 u8 *orig_buf;
1364
1365 ath6kl_dbg(ATH6KL_DBG_HTC_RECV, "+htc_proc_trailer (len:%d)\n", len);
1366
1367 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Recv Trailer", buf, len);
1368
1369 orig_buf = buf;
1370 orig_len = len;
1371 status = 0;
1372
1373 while (len > 0) {
1374
1375 if (len < sizeof(struct htc_record_hdr)) {
1376 status = -ENOMEM;
1377 break;
1378 }
1379 /* these are byte aligned structs */
1380 record = (struct htc_record_hdr *) buf;
1381 len -= sizeof(struct htc_record_hdr);
1382 buf += sizeof(struct htc_record_hdr);
1383
1384 if (record->len > len) {
1385 ath6kl_err("invalid record len: %d (id:%d) buf has: %d bytes left\n",
1386 record->len, record->rec_id, len);
1387 status = -ENOMEM;
1388 break;
1389 }
1390 record_buf = buf;
1391
1392 status = htc_parse_trailer(target, record, record_buf,
1393 next_lk_ahds, endpoint, n_lk_ahds);
1394
1395 if (status)
1396 break;
1397
1398 /* advance buffer past this record for next time around */
1399 buf += record->len;
1400 len -= record->len;
1401 }
1402
1403 if (status)
1404 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD Recv Trailer",
1405 orig_buf, orig_len);
1406
1407 return status;
1408}
1409
1410static int htc_proc_rxhdr(struct htc_target *target,
1411 struct htc_packet *packet,
1412 u32 *next_lkahds, int *n_lkahds)
1413{
1414 int status = 0;
1415 u16 payload_len;
1416 u32 lk_ahd;
1417 struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)packet->buf;
1418
1419 if (n_lkahds != NULL)
1420 *n_lkahds = 0;
1421
1422 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "HTC Recv PKT", packet->buf,
1423 packet->act_len);
1424
1425 /*
1426 * NOTE: we cannot assume the alignment of buf, so we use the safe
1427 * macros to retrieve 16 bit fields.
1428 */
1429 payload_len = le16_to_cpu(get_unaligned(&htc_hdr->payld_len));
1430
1431 memcpy((u8 *)&lk_ahd, packet->buf, sizeof(lk_ahd));
1432
1433 if (packet->info.rx.rx_flags & HTC_RX_PKT_REFRESH_HDR) {
1434 /*
1435 * Refresh the expected header and the actual length as it
1436 * was unknown when this packet was grabbed as part of the
1437 * bundle.
1438 */
1439 packet->info.rx.exp_hdr = lk_ahd;
1440 packet->act_len = payload_len + HTC_HDR_LENGTH;
1441
1442 /* validate the actual header that was refreshed */
1443 if (packet->act_len > packet->buf_len) {
1444 ath6kl_err("refreshed hdr payload len (%d) in bundled recv is invalid (hdr: 0x%X)\n",
1445 payload_len, lk_ahd);
1446 /*
1447 * Limit this to max buffer just to print out some
1448 * of the buffer.
1449 */
1450 packet->act_len = min(packet->act_len, packet->buf_len);
1451 status = -ENOMEM;
1452 goto fail_rx;
1453 }
1454
1455 if (packet->endpoint != htc_hdr->eid) {
1456 ath6kl_err("refreshed hdr ep (%d) does not match expected ep (%d)\n",
1457 htc_hdr->eid, packet->endpoint);
1458 status = -ENOMEM;
1459 goto fail_rx;
1460 }
1461 }
1462
1463 if (lk_ahd != packet->info.rx.exp_hdr) {
1464 ath6kl_err("htc_proc_rxhdr, lk_ahd mismatch! (pPkt:0x%p flags:0x%X)\n",
1465 packet, packet->info.rx.rx_flags);
1466 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Expected Message lk_ahd",
1467 &packet->info.rx.exp_hdr, 4);
1468 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Current Frame Header",
1469 (u8 *)&lk_ahd, sizeof(lk_ahd));
1470 status = -ENOMEM;
1471 goto fail_rx;
1472 }
1473
1474 if (htc_hdr->flags & HTC_FLG_RX_TRAILER) {
1475 if (htc_hdr->ctrl[0] < sizeof(struct htc_record_hdr) ||
1476 htc_hdr->ctrl[0] > payload_len) {
1477 ath6kl_err("htc_proc_rxhdr, invalid hdr (payload len should be :%d, CB[0] is:%d)\n",
1478 payload_len, htc_hdr->ctrl[0]);
1479 status = -ENOMEM;
1480 goto fail_rx;
1481 }
1482
1483 if (packet->info.rx.rx_flags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
1484 next_lkahds = NULL;
1485 n_lkahds = NULL;
1486 }
1487
1488 status = htc_proc_trailer(target, packet->buf + HTC_HDR_LENGTH
1489 + payload_len - htc_hdr->ctrl[0],
1490 htc_hdr->ctrl[0], next_lkahds,
1491 n_lkahds, packet->endpoint);
1492
1493 if (status)
1494 goto fail_rx;
1495
1496 packet->act_len -= htc_hdr->ctrl[0];
1497 }
1498
1499 packet->buf += HTC_HDR_LENGTH;
1500 packet->act_len -= HTC_HDR_LENGTH;
1501
1502fail_rx:
1503 if (status)
1504 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD HTC Recv PKT",
1505 packet->buf,
1506 packet->act_len < 256 ? packet->act_len : 256);
1507 else {
1508 if (packet->act_len > 0)
1509 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES,
1510 "HTC - Application Msg",
1511 packet->buf, packet->act_len);
1512 }
1513
1514 return status;
1515}
1516
1517static void do_rx_completion(struct htc_endpoint *endpoint,
1518 struct htc_packet *packet)
1519{
1520 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
1521 "htc calling ep %d recv callback on packet 0x%p\n",
1522 endpoint->eid, packet);
1523 endpoint->ep_cb.rx(endpoint->target, packet);
1524}
1525
1526static int htc_issue_rxpkt_bundle(struct htc_target *target,
1527 struct list_head *rxq,
1528 struct list_head *sync_compq,
1529 int *n_pkt_fetched, bool part_bundle)
1530{
1531 struct hif_scatter_req *scat_req;
1532 struct htc_packet *packet;
1533 int rem_space = target->max_rx_bndl_sz;
1534 int n_scat_pkt, status = 0, i, len;
1535
1536 n_scat_pkt = get_queue_depth(rxq);
1537 n_scat_pkt = min(n_scat_pkt, target->msg_per_bndl_max);
1538
1539 if ((get_queue_depth(rxq) - n_scat_pkt) > 0) {
1540 /*
1541 * We were forced to split this bundle receive operation
1542 * all packets in this partial bundle must have their
1543 * lookaheads ignored.
1544 */
1545 part_bundle = true;
1546
1547 /*
1548 * This would only happen if the target ignored our max
1549 * bundle limit.
1550 */
1551 ath6kl_warn("htc_issue_rxpkt_bundle : partial bundle detected num:%d , %d\n",
1552 get_queue_depth(rxq), n_scat_pkt);
1553 }
1554
1555 len = 0;
1556
1557 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
1558 "htc_issue_rxpkt_bundle (numpackets: %d , actual : %d)\n",
1559 get_queue_depth(rxq), n_scat_pkt);
1560
1561 scat_req = hif_scatter_req_get(target->dev->ar);
1562
1563 if (scat_req == NULL)
1564 goto fail_rx_pkt;
1565
1566 for (i = 0; i < n_scat_pkt; i++) {
1567 int pad_len;
1568
1569 packet = list_first_entry(rxq, struct htc_packet, list);
1570 list_del(&packet->list);
1571
1572 pad_len = CALC_TXRX_PADDED_LEN(target,
1573 packet->act_len);
1574
1575 if ((rem_space - pad_len) < 0) {
1576 list_add(&packet->list, rxq);
1577 break;
1578 }
1579
1580 rem_space -= pad_len;
1581
1582 if (part_bundle || (i < (n_scat_pkt - 1)))
1583 /*
1584 * Packet 0..n-1 cannot be checked for look-aheads
1585 * since we are fetching a bundle the last packet
1586 * however can have it's lookahead used
1587 */
1588 packet->info.rx.rx_flags |=
1589 HTC_RX_PKT_IGNORE_LOOKAHEAD;
1590
1591 /* NOTE: 1 HTC packet per scatter entry */
1592 scat_req->scat_list[i].buf = packet->buf;
1593 scat_req->scat_list[i].len = pad_len;
1594
1595 packet->info.rx.rx_flags |= HTC_RX_PKT_PART_OF_BUNDLE;
1596
1597 list_add_tail(&packet->list, sync_compq);
1598
1599 WARN_ON(!scat_req->scat_list[i].len);
1600 len += scat_req->scat_list[i].len;
1601 }
1602
1603 scat_req->len = len;
1604 scat_req->scat_entries = i;
1605
1606 status = ath6kldev_submit_scat_req(target->dev, scat_req, true);
1607
1608 if (!status)
1609 *n_pkt_fetched = i;
1610
1611 /* free scatter request */
1612 hif_scatter_req_add(target->dev->ar, scat_req);
1613
1614fail_rx_pkt:
1615
1616 return status;
1617}
1618
1619static int htc_proc_fetched_rxpkts(struct htc_target *target,
1620 struct list_head *comp_pktq, u32 lk_ahds[],
1621 int *n_lk_ahd)
1622{
1623 struct htc_packet *packet, *tmp_pkt;
1624 struct htc_endpoint *ep;
1625 int status = 0;
1626
1627 list_for_each_entry_safe(packet, tmp_pkt, comp_pktq, list) {
1628 list_del(&packet->list);
1629 ep = &target->endpoint[packet->endpoint];
1630
1631 /* process header for each of the recv packet */
1632 status = htc_proc_rxhdr(target, packet, lk_ahds, n_lk_ahd);
1633 if (status)
1634 return status;
1635
1636 if (list_empty(comp_pktq)) {
1637 /*
1638 * Last packet's more packet flag is set
1639 * based on the lookahead.
1640 */
1641 if (*n_lk_ahd > 0)
1642 set_rxpkt_indication_flag(lk_ahds[0],
1643 ep, packet);
1644 } else
1645 /*
1646 * Packets in a bundle automatically have
1647 * this flag set.
1648 */
1649 packet->info.rx.indicat_flags |=
1650 HTC_RX_FLAGS_INDICATE_MORE_PKTS;
1651
1652 htc_update_rx_stats(ep, *n_lk_ahd);
1653
1654 if (packet->info.rx.rx_flags & HTC_RX_PKT_PART_OF_BUNDLE)
1655 ep->ep_st.rx_bundl += 1;
1656
1657 do_rx_completion(ep, packet);
1658 }
1659
1660 return status;
1661}
1662
1663static int htc_fetch_rxpkts(struct htc_target *target,
1664 struct list_head *rx_pktq,
1665 struct list_head *comp_pktq)
1666{
1667 int fetched_pkts;
1668 bool part_bundle = false;
1669 int status = 0;
1670
1671 /* now go fetch the list of HTC packets */
1672 while (!list_empty(rx_pktq)) {
1673 fetched_pkts = 0;
1674
1675 if (target->rx_bndl_enable && (get_queue_depth(rx_pktq) > 1)) {
1676 /*
1677 * There are enough packets to attempt a
1678 * bundle transfer and recv bundling is
1679 * allowed.
1680 */
1681 status = htc_issue_rxpkt_bundle(target, rx_pktq,
1682 comp_pktq,
1683 &fetched_pkts,
1684 part_bundle);
1685 if (status)
1686 return status;
1687
1688 if (!list_empty(rx_pktq))
1689 part_bundle = true;
1690 }
1691
1692 if (!fetched_pkts) {
1693 struct htc_packet *packet;
1694
1695 packet = list_first_entry(rx_pktq, struct htc_packet,
1696 list);
1697
1698 list_del(&packet->list);
1699
1700 /* fully synchronous */
1701 packet->completion = NULL;
1702
1703 if (!list_empty(rx_pktq))
1704 /*
1705 * look_aheads in all packet
1706 * except the last one in the
1707 * bundle must be ignored
1708 */
1709 packet->info.rx.rx_flags |=
1710 HTC_RX_PKT_IGNORE_LOOKAHEAD;
1711
1712 /* go fetch the packet */
1713 status = dev_rx_pkt(target, packet, packet->act_len);
1714 if (status)
1715 return status;
1716
1717 list_add_tail(&packet->list, comp_pktq);
1718 }
1719 }
1720
1721 return status;
1722}
1723
1724int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
1725 u32 msg_look_ahead[], int *num_pkts)
1726{
1727 struct htc_packet *packets, *tmp_pkt;
1728 struct htc_endpoint *endpoint;
1729 struct list_head rx_pktq, comp_pktq;
1730 int status = 0;
1731 u32 look_aheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
1732 int num_look_ahead = 1;
1733 enum htc_endpoint_id id;
1734 int n_fetched = 0;
1735
1736 *num_pkts = 0;
1737
1738 /*
1739 * On first entry copy the look_aheads into our temp array for
1740 * processing
1741 */
1742 memcpy(look_aheads, msg_look_ahead, sizeof(look_aheads));
1743
1744 while (true) {
1745
1746 /*
1747 * First lookahead sets the expected endpoint IDs for all
1748 * packets in a bundle.
1749 */
1750 id = ((struct htc_frame_hdr *)&look_aheads[0])->eid;
1751 endpoint = &target->endpoint[id];
1752
1753 if (id >= ENDPOINT_MAX) {
1754 ath6kl_err("MsgPend, invalid endpoint in look-ahead: %d\n",
1755 id);
1756 status = -ENOMEM;
1757 break;
1758 }
1759
1760 INIT_LIST_HEAD(&rx_pktq);
1761 INIT_LIST_HEAD(&comp_pktq);
1762
1763 /*
1764 * Try to allocate as many HTC RX packets indicated by the
1765 * look_aheads.
1766 */
1767 status = alloc_and_prep_rxpkts(target, look_aheads,
1768 num_look_ahead, endpoint,
1769 &rx_pktq);
1770 if (status)
1771 break;
1772
1773 if (get_queue_depth(&rx_pktq) >= 2)
1774 /*
1775 * A recv bundle was detected, force IRQ status
1776 * re-check again
1777 */
1778 target->chk_irq_status_cnt = 1;
1779
1780 n_fetched += get_queue_depth(&rx_pktq);
1781
1782 num_look_ahead = 0;
1783
1784 status = htc_fetch_rxpkts(target, &rx_pktq, &comp_pktq);
1785
1786 if (!status)
1787 chk_rx_water_mark(endpoint);
1788
1789 /* Process fetched packets */
1790 status = htc_proc_fetched_rxpkts(target, &comp_pktq,
1791 look_aheads, &num_look_ahead);
1792
1793 if (!num_look_ahead || status)
1794 break;
1795
1796 /*
1797 * For SYNCH processing, if we get here, we are running
1798 * through the loop again due to a detected lookahead. Set
1799 * flag that we should re-check IRQ status registers again
1800 * before leaving IRQ processing, this can net better
1801 * performance in high throughput situations.
1802 */
1803 target->chk_irq_status_cnt = 1;
1804 }
1805
1806 if (status) {
1807 ath6kl_err("failed to get pending recv messages: %d\n",
1808 status);
1809 /*
1810 * Cleanup any packets we allocated but didn't use to
1811 * actually fetch any packets.
1812 */
1813 list_for_each_entry_safe(packets, tmp_pkt, &rx_pktq, list) {
1814 list_del(&packets->list);
1815 htc_reclaim_rxbuf(target, packets,
1816 &target->endpoint[packets->endpoint]);
1817 }
1818
1819 /* cleanup any packets in sync completion queue */
1820 list_for_each_entry_safe(packets, tmp_pkt, &comp_pktq, list) {
1821 list_del(&packets->list);
1822 htc_reclaim_rxbuf(target, packets,
1823 &target->endpoint[packets->endpoint]);
1824 }
1825
1826 if (target->htc_flags & HTC_OP_STATE_STOPPING) {
1827 ath6kl_warn("host is going to stop blocking receiver for htc_stop\n");
1828 ath6kldev_rx_control(target->dev, false);
1829 }
1830 }
1831
1832 /*
1833 * Before leaving, check to see if host ran out of buffers and
1834 * needs to stop the receiver.
1835 */
1836 if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) {
1837 ath6kl_warn("host has no rx buffers blocking receiver to prevent overrun\n");
1838 ath6kldev_rx_control(target->dev, false);
1839 }
1840 *num_pkts = n_fetched;
1841
1842 return status;
1843}
1844
1845/*
1846 * Synchronously wait for a control message from the target,
1847 * This function is used at initialization time ONLY. At init messages
1848 * on ENDPOINT 0 are expected.
1849 */
1850static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
1851{
1852 struct htc_packet *packet = NULL;
1853 struct htc_frame_hdr *htc_hdr;
1854 u32 look_ahead;
1855
1856 if (ath6kldev_poll_mboxmsg_rx(target->dev, &look_ahead,
1857 HTC_TARGET_RESPONSE_TIMEOUT))
1858 return NULL;
1859
1860 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
1861 "htc_wait_for_ctrl_msg: look_ahead : 0x%X\n", look_ahead);
1862
1863 htc_hdr = (struct htc_frame_hdr *)&look_ahead;
1864
1865 if (htc_hdr->eid != ENDPOINT_0)
1866 return NULL;
1867
1868 packet = htc_get_control_buf(target, false);
1869
1870 if (!packet)
1871 return NULL;
1872
1873 packet->info.rx.rx_flags = 0;
1874 packet->info.rx.exp_hdr = look_ahead;
1875 packet->act_len = le16_to_cpu(htc_hdr->payld_len) + HTC_HDR_LENGTH;
1876
1877 if (packet->act_len > packet->buf_len)
1878 goto fail_ctrl_rx;
1879
1880 /* we want synchronous operation */
1881 packet->completion = NULL;
1882
1883 /* get the message from the device, this will block */
1884 if (dev_rx_pkt(target, packet, packet->act_len))
1885 goto fail_ctrl_rx;
1886
1887 /* process receive header */
1888 packet->status = htc_proc_rxhdr(target, packet, NULL, NULL);
1889
1890 if (packet->status) {
1891 ath6kl_err("htc_wait_for_ctrl_msg, htc_proc_rxhdr failed (status = %d)\n",
1892 packet->status);
1893 goto fail_ctrl_rx;
1894 }
1895
1896 return packet;
1897
1898fail_ctrl_rx:
1899 if (packet != NULL) {
1900 htc_rxpkt_reset(packet);
1901 reclaim_rx_ctrl_buf(target, packet);
1902 }
1903
1904 return NULL;
1905}
1906
1907int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
1908 struct list_head *pkt_queue)
1909{
1910 struct htc_endpoint *endpoint;
1911 struct htc_packet *first_pkt;
1912 bool rx_unblock = false;
1913 int status = 0, depth;
1914
1915 if (list_empty(pkt_queue))
1916 return -ENOMEM;
1917
1918 first_pkt = list_first_entry(pkt_queue, struct htc_packet, list);
1919
1920 if (first_pkt->endpoint >= ENDPOINT_MAX)
1921 return status;
1922
1923 depth = get_queue_depth(pkt_queue);
1924
1925 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
1926 "htc_add_rxbuf_multiple: ep id: %d, cnt:%d, len: %d\n",
1927 first_pkt->endpoint, depth, first_pkt->buf_len);
1928
1929 endpoint = &target->endpoint[first_pkt->endpoint];
1930
1931 if (target->htc_flags & HTC_OP_STATE_STOPPING) {
1932 struct htc_packet *packet, *tmp_pkt;
1933
1934 /* walk through queue and mark each one canceled */
1935 list_for_each_entry_safe(packet, tmp_pkt, pkt_queue, list) {
1936 packet->status = -ECANCELED;
1937 list_del(&packet->list);
1938 do_rx_completion(endpoint, packet);
1939 }
1940
1941 return status;
1942 }
1943
1944 spin_lock_bh(&target->rx_lock);
1945
1946 list_splice_tail_init(pkt_queue, &endpoint->rx_bufq);
1947
1948 /* check if we are blocked waiting for a new buffer */
1949 if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) {
1950 if (target->ep_waiting == first_pkt->endpoint) {
1951 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
1952 "receiver was blocked on ep:%d, unblocking.\n",
1953 target->ep_waiting);
1954 target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS;
1955 target->ep_waiting = ENDPOINT_MAX;
1956 rx_unblock = true;
1957 }
1958 }
1959
1960 spin_unlock_bh(&target->rx_lock);
1961
1962 if (rx_unblock && !(target->htc_flags & HTC_OP_STATE_STOPPING))
1963 /* TODO : implement a buffer threshold count? */
1964 ath6kldev_rx_control(target->dev, true);
1965
1966 return status;
1967}
1968
1969void ath6kl_htc_flush_rx_buf(struct htc_target *target)
1970{
1971 struct htc_endpoint *endpoint;
1972 struct htc_packet *packet, *tmp_pkt;
1973 int i;
1974
1975 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
1976 endpoint = &target->endpoint[i];
1977 if (!endpoint->svc_id)
1978 /* not in use.. */
1979 continue;
1980
1981 spin_lock_bh(&target->rx_lock);
1982 list_for_each_entry_safe(packet, tmp_pkt,
1983 &endpoint->rx_bufq, list) {
1984 list_del(&packet->list);
1985 spin_unlock_bh(&target->rx_lock);
1986 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
1987 "flushing rx pkt:0x%p, len:%d, ep:%d\n",
1988 packet, packet->buf_len,
1989 packet->endpoint);
1990 dev_kfree_skb(packet->pkt_cntxt);
1991 spin_lock_bh(&target->rx_lock);
1992 }
1993 spin_unlock_bh(&target->rx_lock);
1994 }
1995}
1996
1997int ath6kl_htc_conn_service(struct htc_target *target,
1998 struct htc_service_connect_req *conn_req,
1999 struct htc_service_connect_resp *conn_resp)
2000{
2001 struct htc_packet *rx_pkt = NULL;
2002 struct htc_packet *tx_pkt = NULL;
2003 struct htc_conn_service_resp *resp_msg;
2004 struct htc_conn_service_msg *conn_msg;
2005 struct htc_endpoint *endpoint;
2006 enum htc_endpoint_id assigned_ep = ENDPOINT_MAX;
2007 unsigned int max_msg_sz = 0;
2008 int status = 0;
2009
2010 ath6kl_dbg(ATH6KL_DBG_TRC,
2011 "htc_conn_service, target:0x%p service id:0x%X\n",
2012 target, conn_req->svc_id);
2013
2014 if (conn_req->svc_id == HTC_CTRL_RSVD_SVC) {
2015 /* special case for pseudo control service */
2016 assigned_ep = ENDPOINT_0;
2017 max_msg_sz = HTC_MAX_CTRL_MSG_LEN;
2018 } else {
2019 /* allocate a packet to send to the target */
2020 tx_pkt = htc_get_control_buf(target, true);
2021
2022 if (!tx_pkt)
2023 return -ENOMEM;
2024
2025 conn_msg = (struct htc_conn_service_msg *)tx_pkt->buf;
2026 memset(conn_msg, 0, sizeof(*conn_msg));
2027 conn_msg->msg_id = cpu_to_le16(HTC_MSG_CONN_SVC_ID);
2028 conn_msg->svc_id = cpu_to_le16(conn_req->svc_id);
2029 conn_msg->conn_flags = cpu_to_le16(conn_req->conn_flags);
2030
2031 set_htc_pkt_info(tx_pkt, NULL, (u8 *) conn_msg,
2032 sizeof(*conn_msg) + conn_msg->svc_meta_len,
2033 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
2034
2035 /* we want synchronous operation */
2036 tx_pkt->completion = NULL;
2037 htc_prep_send_pkt(tx_pkt, 0, 0, 0);
2038 status = htc_issue_send(target, tx_pkt);
2039
2040 if (status)
2041 goto fail_tx;
2042
2043 /* wait for response */
2044 rx_pkt = htc_wait_for_ctrl_msg(target);
2045
2046 if (!rx_pkt) {
2047 status = -ENOMEM;
2048 goto fail_tx;
2049 }
2050
2051 resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf;
2052
2053 if ((le16_to_cpu(resp_msg->msg_id) != HTC_MSG_CONN_SVC_RESP_ID)
2054 || (rx_pkt->act_len < sizeof(*resp_msg))) {
2055 status = -ENOMEM;
2056 goto fail_tx;
2057 }
2058
2059 conn_resp->resp_code = resp_msg->status;
2060 /* check response status */
2061 if (resp_msg->status != HTC_SERVICE_SUCCESS) {
2062 ath6kl_err("target failed service 0x%X connect request (status:%d)\n",
2063 resp_msg->svc_id, resp_msg->status);
2064 status = -ENOMEM;
2065 goto fail_tx;
2066 }
2067
2068 assigned_ep = (enum htc_endpoint_id)resp_msg->eid;
2069 max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz);
2070 }
2071
2072 if (assigned_ep >= ENDPOINT_MAX || !max_msg_sz) {
2073 status = -ENOMEM;
2074 goto fail_tx;
2075 }
2076
2077 endpoint = &target->endpoint[assigned_ep];
2078 endpoint->eid = assigned_ep;
2079 if (endpoint->svc_id) {
2080 status = -ENOMEM;
2081 goto fail_tx;
2082 }
2083
2084 /* return assigned endpoint to caller */
2085 conn_resp->endpoint = assigned_ep;
2086 conn_resp->len_max = max_msg_sz;
2087
2088 /* setup the endpoint */
2089
2090 /* this marks the endpoint in use */
2091 endpoint->svc_id = conn_req->svc_id;
2092
2093 endpoint->max_txq_depth = conn_req->max_txq_depth;
2094 endpoint->len_max = max_msg_sz;
2095 endpoint->ep_cb = conn_req->ep_cb;
2096 endpoint->cred_dist.svc_id = conn_req->svc_id;
2097 endpoint->cred_dist.htc_rsvd = endpoint;
2098 endpoint->cred_dist.endpoint = assigned_ep;
2099 endpoint->cred_dist.cred_sz = target->tgt_cred_sz;
2100
2101 if (conn_req->max_rxmsg_sz) {
2102 /*
2103 * Override cred_per_msg calculation, this optimizes
2104 * the credit-low indications since the host will actually
2105 * issue smaller messages in the Send path.
2106 */
2107 if (conn_req->max_rxmsg_sz > max_msg_sz) {
2108 status = -ENOMEM;
2109 goto fail_tx;
2110 }
2111 endpoint->cred_dist.cred_per_msg =
2112 conn_req->max_rxmsg_sz / target->tgt_cred_sz;
2113 } else
2114 endpoint->cred_dist.cred_per_msg =
2115 max_msg_sz / target->tgt_cred_sz;
2116
2117 if (!endpoint->cred_dist.cred_per_msg)
2118 endpoint->cred_dist.cred_per_msg = 1;
2119
2120 /* save local connection flags */
2121 endpoint->conn_flags = conn_req->flags;
2122
2123fail_tx:
2124 if (tx_pkt)
2125 htc_reclaim_txctrl_buf(target, tx_pkt);
2126
2127 if (rx_pkt) {
2128 htc_rxpkt_reset(rx_pkt);
2129 reclaim_rx_ctrl_buf(target, rx_pkt);
2130 }
2131
2132 return status;
2133}
2134
2135static void reset_ep_state(struct htc_target *target)
2136{
2137 struct htc_endpoint *endpoint;
2138 int i;
2139
2140 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
2141 endpoint = &target->endpoint[i];
2142 memset(&endpoint->cred_dist, 0, sizeof(endpoint->cred_dist));
2143 endpoint->svc_id = 0;
2144 endpoint->len_max = 0;
2145 endpoint->max_txq_depth = 0;
2146 memset(&endpoint->ep_st, 0,
2147 sizeof(endpoint->ep_st));
2148 INIT_LIST_HEAD(&endpoint->rx_bufq);
2149 INIT_LIST_HEAD(&endpoint->txq);
2150 endpoint->target = target;
2151 }
2152
2153 /* reset distribution list */
2154 INIT_LIST_HEAD(&target->cred_dist_list);
2155}
2156
2157int ath6kl_htc_get_rxbuf_num(struct htc_target *target,
2158 enum htc_endpoint_id endpoint)
2159{
2160 int num;
2161
2162 spin_lock_bh(&target->rx_lock);
2163 num = get_queue_depth(&(target->endpoint[endpoint].rx_bufq));
2164 spin_unlock_bh(&target->rx_lock);
2165 return num;
2166}
2167
2168static void htc_setup_msg_bndl(struct htc_target *target)
2169{
2170 /* limit what HTC can handle */
2171 target->msg_per_bndl_max = min(HTC_HOST_MAX_MSG_PER_BUNDLE,
2172 target->msg_per_bndl_max);
2173
2174 if (ath6kl_hif_enable_scatter(target->dev->ar)) {
2175 target->msg_per_bndl_max = 0;
2176 return;
2177 }
2178
2179 /* limit bundle what the device layer can handle */
2180 target->msg_per_bndl_max = min(target->max_scat_entries,
2181 target->msg_per_bndl_max);
2182
2183 ath6kl_dbg(ATH6KL_DBG_TRC,
2184 "htc bundling allowed. max msg per htc bundle: %d\n",
2185 target->msg_per_bndl_max);
2186
2187 /* Max rx bundle size is limited by the max tx bundle size */
2188 target->max_rx_bndl_sz = target->max_xfer_szper_scatreq;
2189 /* Max tx bundle size if limited by the extended mbox address range */
2190 target->max_tx_bndl_sz = min(HIF_MBOX0_EXT_WIDTH,
2191 target->max_xfer_szper_scatreq);
2192
2193 ath6kl_dbg(ATH6KL_DBG_ANY, "max recv: %d max send: %d\n",
2194 target->max_rx_bndl_sz, target->max_tx_bndl_sz);
2195
2196 if (target->max_tx_bndl_sz)
2197 target->tx_bndl_enable = true;
2198
2199 if (target->max_rx_bndl_sz)
2200 target->rx_bndl_enable = true;
2201
2202 if ((target->tgt_cred_sz % target->block_sz) != 0) {
2203 ath6kl_warn("credit size: %d is not block aligned! Disabling send bundling\n",
2204 target->tgt_cred_sz);
2205
2206 /*
2207 * Disallow send bundling since the credit size is
2208 * not aligned to a block size the I/O block
2209 * padding will spill into the next credit buffer
2210 * which is fatal.
2211 */
2212 target->tx_bndl_enable = false;
2213 }
2214}
2215
2216int ath6kl_htc_wait_target(struct htc_target *target)
2217{
2218 struct htc_packet *packet = NULL;
2219 struct htc_ready_ext_msg *rdy_msg;
2220 struct htc_service_connect_req connect;
2221 struct htc_service_connect_resp resp;
2222 int status;
2223
2224 /* we should be getting 1 control message that the target is ready */
2225 packet = htc_wait_for_ctrl_msg(target);
2226
2227 if (!packet)
2228 return -ENOMEM;
2229
2230 /* we controlled the buffer creation so it's properly aligned */
2231 rdy_msg = (struct htc_ready_ext_msg *)packet->buf;
2232
2233 if ((le16_to_cpu(rdy_msg->ver2_0_info.msg_id) != HTC_MSG_READY_ID) ||
2234 (packet->act_len < sizeof(struct htc_ready_msg))) {
2235 status = -ENOMEM;
2236 goto fail_wait_target;
2237 }
2238
2239 if (!rdy_msg->ver2_0_info.cred_cnt || !rdy_msg->ver2_0_info.cred_sz) {
2240 status = -ENOMEM;
2241 goto fail_wait_target;
2242 }
2243
2244 target->tgt_creds = le16_to_cpu(rdy_msg->ver2_0_info.cred_cnt);
2245 target->tgt_cred_sz = le16_to_cpu(rdy_msg->ver2_0_info.cred_sz);
2246
2247 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
2248 "target ready: credits: %d credit size: %d\n",
2249 target->tgt_creds, target->tgt_cred_sz);
2250
2251 /* check if this is an extended ready message */
2252 if (packet->act_len >= sizeof(struct htc_ready_ext_msg)) {
2253 /* this is an extended message */
2254 target->htc_tgt_ver = rdy_msg->htc_ver;
2255 target->msg_per_bndl_max = rdy_msg->msg_per_htc_bndl;
2256 } else {
2257 /* legacy */
2258 target->htc_tgt_ver = HTC_VERSION_2P0;
2259 target->msg_per_bndl_max = 0;
2260 }
2261
2262 ath6kl_dbg(ATH6KL_DBG_TRC, "using htc protocol version : %s (%d)\n",
2263 (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
2264 target->htc_tgt_ver);
2265
2266 if (target->msg_per_bndl_max > 0)
2267 htc_setup_msg_bndl(target);
2268
2269 /* setup our pseudo HTC control endpoint connection */
2270 memset(&connect, 0, sizeof(connect));
2271 memset(&resp, 0, sizeof(resp));
2272 connect.ep_cb.rx = htc_ctrl_rx;
2273 connect.ep_cb.rx_refill = NULL;
2274 connect.ep_cb.tx_full = NULL;
2275 connect.max_txq_depth = NUM_CONTROL_BUFFERS;
2276 connect.svc_id = HTC_CTRL_RSVD_SVC;
2277
2278 /* connect fake service */
2279 status = ath6kl_htc_conn_service((void *)target, &connect, &resp);
2280
2281 if (status)
2282 ath6kl_hif_cleanup_scatter(target->dev->ar);
2283
2284fail_wait_target:
2285 if (packet) {
2286 htc_rxpkt_reset(packet);
2287 reclaim_rx_ctrl_buf(target, packet);
2288 }
2289
2290 return status;
2291}
2292
2293/*
2294 * Start HTC, enable interrupts and let the target know
2295 * host has finished setup.
2296 */
2297int ath6kl_htc_start(struct htc_target *target)
2298{
2299 struct htc_packet *packet;
2300 int status;
2301
2302 /* Disable interrupts at the chip level */
2303 ath6kldev_disable_intrs(target->dev);
2304
2305 target->htc_flags = 0;
2306 target->rx_st_flags = 0;
2307
2308 /* Push control receive buffers into htc control endpoint */
2309 while ((packet = htc_get_control_buf(target, false)) != NULL) {
2310 status = htc_add_rxbuf(target, packet);
2311 if (status)
2312 return status;
2313 }
2314
2315 /* NOTE: the first entry in the distribution list is ENDPOINT_0 */
2316 ath6k_credit_init(target->cred_dist_cntxt, &target->cred_dist_list,
2317 target->tgt_creds);
2318
2319 dump_cred_dist_stats(target);
2320
2321 /* Indicate to the target of the setup completion */
2322 status = htc_setup_tx_complete(target);
2323
2324 if (status)
2325 return status;
2326
2327 /* unmask interrupts */
2328 status = ath6kldev_unmask_intrs(target->dev);
2329
2330 if (status)
2331 ath6kl_htc_stop(target);
2332
2333 return status;
2334}
2335
2336/* htc_stop: stop interrupt reception, and flush all queued buffers */
2337void ath6kl_htc_stop(struct htc_target *target)
2338{
2339 spin_lock_bh(&target->htc_lock);
2340 target->htc_flags |= HTC_OP_STATE_STOPPING;
2341 spin_unlock_bh(&target->htc_lock);
2342
2343 /*
2344 * Masking interrupts is a synchronous operation, when this
2345 * function returns all pending HIF I/O has completed, we can
2346 * safely flush the queues.
2347 */
2348 ath6kldev_mask_intrs(target->dev);
2349
2350 ath6kl_htc_flush_txep_all(target);
2351
2352 ath6kl_htc_flush_rx_buf(target);
2353
2354 reset_ep_state(target);
2355}
2356
2357void *ath6kl_htc_create(struct ath6kl *ar)
2358{
2359 struct htc_target *target = NULL;
2360 struct htc_packet *packet;
2361 int status = 0, i = 0;
2362 u32 block_size, ctrl_bufsz;
2363
2364 target = kzalloc(sizeof(*target), GFP_KERNEL);
2365 if (!target) {
2366 ath6kl_err("unable to allocate memory\n");
2367 return NULL;
2368 }
2369
2370 target->dev = kzalloc(sizeof(*target->dev), GFP_KERNEL);
2371 if (!target->dev) {
2372 ath6kl_err("unable to allocate memory\n");
2373 status = -ENOMEM;
2374 goto fail_create_htc;
2375 }
2376
2377 spin_lock_init(&target->htc_lock);
2378 spin_lock_init(&target->rx_lock);
2379 spin_lock_init(&target->tx_lock);
2380
2381 INIT_LIST_HEAD(&target->free_ctrl_txbuf);
2382 INIT_LIST_HEAD(&target->free_ctrl_rxbuf);
2383 INIT_LIST_HEAD(&target->cred_dist_list);
2384
2385 target->dev->ar = ar;
2386 target->dev->htc_cnxt = target;
2387 target->ep_waiting = ENDPOINT_MAX;
2388
2389 reset_ep_state(target);
2390
2391 status = ath6kldev_setup(target->dev);
2392
2393 if (status)
2394 goto fail_create_htc;
2395
2396 block_size = ar->mbox_info.block_size;
2397
2398 ctrl_bufsz = (block_size > HTC_MAX_CTRL_MSG_LEN) ?
2399 (block_size + HTC_HDR_LENGTH) :
2400 (HTC_MAX_CTRL_MSG_LEN + HTC_HDR_LENGTH);
2401
2402 for (i = 0; i < NUM_CONTROL_BUFFERS; i++) {
2403 packet = kzalloc(sizeof(*packet), GFP_KERNEL);
2404 if (!packet)
2405 break;
2406
2407 packet->buf_start = kzalloc(ctrl_bufsz, GFP_KERNEL);
2408 if (!packet->buf_start) {
2409 kfree(packet);
2410 break;
2411 }
2412
2413 packet->buf_len = ctrl_bufsz;
2414 if (i < NUM_CONTROL_RX_BUFFERS) {
2415 packet->act_len = 0;
2416 packet->buf = packet->buf_start;
2417 packet->endpoint = ENDPOINT_0;
2418 list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
2419 } else
2420 list_add_tail(&packet->list, &target->free_ctrl_txbuf);
2421 }
2422
2423fail_create_htc:
2424 if (i != NUM_CONTROL_BUFFERS || status) {
2425 if (target) {
2426 ath6kl_htc_cleanup(target);
2427 target = NULL;
2428 }
2429 }
2430
2431 return target;
2432}
2433
2434/* cleanup the HTC instance */
2435void ath6kl_htc_cleanup(struct htc_target *target)
2436{
2437 struct htc_packet *packet, *tmp_packet;
2438
2439 ath6kl_hif_cleanup_scatter(target->dev->ar);
2440
2441 list_for_each_entry_safe(packet, tmp_packet,
2442 &target->free_ctrl_txbuf, list) {
2443 list_del(&packet->list);
2444 kfree(packet->buf_start);
2445 kfree(packet);
2446 }
2447
2448 list_for_each_entry_safe(packet, tmp_packet,
2449 &target->free_ctrl_rxbuf, list) {
2450 list_del(&packet->list);
2451 kfree(packet->buf_start);
2452 kfree(packet);
2453 }
2454
2455 kfree(target->dev);
2456 kfree(target);
2457}
diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h
new file mode 100644
index 00000000000..8ce0c2c07de
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/htc.h
@@ -0,0 +1,607 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_H
18#define HTC_H
19
20#include "common.h"
21
22/* frame header flags */
23
24/* send direction */
25#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0)
26#define HTC_FLAGS_SEND_BUNDLE (1 << 1)
27
28/* receive direction */
29#define HTC_FLG_RX_UNUSED (1 << 0)
30#define HTC_FLG_RX_TRAILER (1 << 1)
31/* Bundle count maske and shift */
32#define HTC_FLG_RX_BNDL_CNT (0xF0)
33#define HTC_FLG_RX_BNDL_CNT_S 4
34
35#define HTC_HDR_LENGTH (sizeof(struct htc_frame_hdr))
36#define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(struct htc_frame_hdr))
37
38/* HTC control message IDs */
39
40#define HTC_MSG_READY_ID 1
41#define HTC_MSG_CONN_SVC_ID 2
42#define HTC_MSG_CONN_SVC_RESP_ID 3
43#define HTC_MSG_SETUP_COMPLETE_ID 4
44#define HTC_MSG_SETUP_COMPLETE_EX_ID 5
45
46#define HTC_MAX_CTRL_MSG_LEN 256
47
48#define HTC_VERSION_2P0 0x00
49#define HTC_VERSION_2P1 0x01
50
51#define HTC_SERVICE_META_DATA_MAX_LENGTH 128
52
53#define HTC_CONN_FLGS_THRESH_LVL_QUAT 0x0
54#define HTC_CONN_FLGS_THRESH_LVL_HALF 0x1
55#define HTC_CONN_FLGS_THRESH_LVL_THREE_QUAT 0x2
56#define HTC_CONN_FLGS_REDUCE_CRED_DRIB 0x4
57#define HTC_CONN_FLGS_THRESH_MASK 0x3
58
59/* connect response status codes */
60#define HTC_SERVICE_SUCCESS 0
61#define HTC_SERVICE_NOT_FOUND 1
62#define HTC_SERVICE_FAILED 2
63
64/* no resources (i.e. no more endpoints) */
65#define HTC_SERVICE_NO_RESOURCES 3
66
67/* specific service is not allowing any more endpoints */
68#define HTC_SERVICE_NO_MORE_EP 4
69
70/* report record IDs */
71#define HTC_RECORD_NULL 0
72#define HTC_RECORD_CREDITS 1
73#define HTC_RECORD_LOOKAHEAD 2
74#define HTC_RECORD_LOOKAHEAD_BUNDLE 3
75
76#define HTC_SETUP_COMP_FLG_RX_BNDL_EN (1 << 0)
77
78#define MAKE_SERVICE_ID(group, index) \
79 (int)(((int)group << 8) | (int)(index))
80
81/* NOTE: service ID of 0x0000 is reserved and should never be used */
82#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1)
83#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0)
84#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1)
85#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2)
86#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3)
87#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4)
88#define WMI_MAX_SERVICES 5
89
90/* reserved and used to flush ALL packets */
91#define HTC_TX_PACKET_TAG_ALL 0
92#define HTC_SERVICE_TX_PACKET_TAG 1
93#define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_SERVICE_TX_PACKET_TAG + 9)
94
95/* more packets on this endpoint are being fetched */
96#define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0)
97
98/* TODO.. for BMI */
99#define ENDPOINT1 0
100/* TODO -remove me, but we have to fix BMI first */
101#define HTC_MAILBOX_NUM_MAX 4
102
103/* enable send bundle padding for this endpoint */
104#define HTC_FLGS_TX_BNDL_PAD_EN (1 << 0)
105#define HTC_EP_ACTIVE ((u32) (1u << 31))
106
107/* HTC operational parameters */
108#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */
109#define HTC_TARGET_DEBUG_INTR_MASK 0x01
110#define HTC_TARGET_CREDIT_INTR_MASK 0xF0
111
112#define HTC_HOST_MAX_MSG_PER_BUNDLE 8
113#define HTC_MIN_HTC_MSGS_TO_BUNDLE 2
114
115/* packet flags */
116
117#define HTC_RX_PKT_IGNORE_LOOKAHEAD (1 << 0)
118#define HTC_RX_PKT_REFRESH_HDR (1 << 1)
119#define HTC_RX_PKT_PART_OF_BUNDLE (1 << 2)
120#define HTC_RX_PKT_NO_RECYCLE (1 << 3)
121
122#define NUM_CONTROL_BUFFERS 8
123#define NUM_CONTROL_TX_BUFFERS 2
124#define NUM_CONTROL_RX_BUFFERS (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS)
125
126#define HTC_RECV_WAIT_BUFFERS (1 << 0)
127#define HTC_OP_STATE_STOPPING (1 << 0)
128
129/*
130 * The frame header length and message formats defined herein were selected
131 * to accommodate optimal alignment for target processing. This reduces
132 * code size and improves performance. Any changes to the header length may
133 * alter the alignment and cause exceptions on the target. When adding to
134 * the messagestructures insure that fields are properly aligned.
135 */
136
137/* HTC frame header
138 *
139 * NOTE: do not remove or re-arrange the fields, these are minimally
140 * required to take advantage of 4-byte lookaheads in some hardware
141 * implementations.
142 */
143struct htc_frame_hdr {
144 u8 eid;
145 u8 flags;
146
147 /* length of data (including trailer) that follows the header */
148 __le16 payld_len;
149
150 /* end of 4-byte lookahead */
151
152 u8 ctrl[2];
153} __packed;
154
155/* HTC ready message */
156struct htc_ready_msg {
157 __le16 msg_id;
158 __le16 cred_cnt;
159 __le16 cred_sz;
160 u8 max_ep;
161 u8 pad;
162} __packed;
163
164/* extended HTC ready message */
165struct htc_ready_ext_msg {
166 struct htc_ready_msg ver2_0_info;
167 u8 htc_ver;
168 u8 msg_per_htc_bndl;
169} __packed;
170
171/* connect service */
172struct htc_conn_service_msg {
173 __le16 msg_id;
174 __le16 svc_id;
175 __le16 conn_flags;
176 u8 svc_meta_len;
177 u8 pad;
178} __packed;
179
180/* connect response */
181struct htc_conn_service_resp {
182 __le16 msg_id;
183 __le16 svc_id;
184 u8 status;
185 u8 eid;
186 __le16 max_msg_sz;
187 u8 svc_meta_len;
188 u8 pad;
189} __packed;
190
191struct htc_setup_comp_msg {
192 __le16 msg_id;
193} __packed;
194
195/* extended setup completion message */
196struct htc_setup_comp_ext_msg {
197 __le16 msg_id;
198 __le32 flags;
199 u8 msg_per_rxbndl;
200 u8 Rsvd[3];
201} __packed;
202
203struct htc_record_hdr {
204 u8 rec_id;
205 u8 len;
206} __packed;
207
208struct htc_credit_report {
209 u8 eid;
210 u8 credits;
211} __packed;
212
213/*
214 * NOTE: The lk_ahd array is guarded by a pre_valid
215 * and Post Valid guard bytes. The pre_valid bytes must
216 * equal the inverse of the post_valid byte.
217 */
218struct htc_lookahead_report {
219 u8 pre_valid;
220 u8 lk_ahd[4];
221 u8 post_valid;
222} __packed;
223
224struct htc_bundle_lkahd_rpt {
225 u8 lk_ahd[4];
226} __packed;
227
228/* Current service IDs */
229
230enum htc_service_grp_ids {
231 RSVD_SERVICE_GROUP = 0,
232 WMI_SERVICE_GROUP = 1,
233
234 HTC_TEST_GROUP = 254,
235 HTC_SERVICE_GROUP_LAST = 255
236};
237
238/* ------ endpoint IDS ------ */
239
240enum htc_endpoint_id {
241 ENDPOINT_UNUSED = -1,
242 ENDPOINT_0 = 0,
243 ENDPOINT_1 = 1,
244 ENDPOINT_2 = 2,
245 ENDPOINT_3,
246 ENDPOINT_4,
247 ENDPOINT_5,
248 ENDPOINT_6,
249 ENDPOINT_7,
250 ENDPOINT_8,
251 ENDPOINT_MAX,
252};
253
254struct htc_tx_packet_info {
255 u16 tag;
256 int cred_used;
257 u8 flags;
258 int seqno;
259};
260
261struct htc_rx_packet_info {
262 u32 exp_hdr;
263 u32 rx_flags;
264 u32 indicat_flags;
265};
266
267struct htc_target;
268
269/* wrapper around endpoint-specific packets */
270struct htc_packet {
271 struct list_head list;
272
273 /* caller's per packet specific context */
274 void *pkt_cntxt;
275
276 /*
277 * the true buffer start , the caller can store the real
278 * buffer start here. In receive callbacks, the HTC layer
279 * sets buf to the start of the payload past the header.
280 * This field allows the caller to reset buf when it recycles
281 * receive packets back to HTC.
282 */
283 u8 *buf_start;
284
285 /*
286 * Pointer to the start of the buffer. In the transmit
287 * direction this points to the start of the payload. In the
288 * receive direction, however, the buffer when queued up
289 * points to the start of the HTC header but when returned
290 * to the caller points to the start of the payload
291 */
292 u8 *buf;
293 u32 buf_len;
294
295 /* actual length of payload */
296 u32 act_len;
297
298 /* endpoint that this packet was sent/recv'd from */
299 enum htc_endpoint_id endpoint;
300
301 /* completion status */
302
303 int status;
304 union {
305 struct htc_tx_packet_info tx;
306 struct htc_rx_packet_info rx;
307 } info;
308
309 void (*completion) (struct htc_target *, struct htc_packet *);
310 struct htc_target *context;
311};
312
313enum htc_send_full_action {
314 HTC_SEND_FULL_KEEP = 0,
315 HTC_SEND_FULL_DROP = 1,
316};
317
318struct htc_ep_callbacks {
319 void (*rx) (struct htc_target *, struct htc_packet *);
320 void (*rx_refill) (struct htc_target *, enum htc_endpoint_id endpoint);
321 enum htc_send_full_action (*tx_full) (struct htc_target *,
322 struct htc_packet *);
323 struct htc_packet *(*rx_allocthresh) (struct htc_target *,
324 enum htc_endpoint_id, int);
325 int rx_alloc_thresh;
326 int rx_refill_thresh;
327};
328
329/* service connection information */
330struct htc_service_connect_req {
331 u16 svc_id;
332 u16 conn_flags;
333 struct htc_ep_callbacks ep_cb;
334 int max_txq_depth;
335 u32 flags;
336 unsigned int max_rxmsg_sz;
337};
338
339/* service connection response information */
340struct htc_service_connect_resp {
341 u8 buf_len;
342 u8 act_len;
343 enum htc_endpoint_id endpoint;
344 unsigned int len_max;
345 u8 resp_code;
346};
347
348/* endpoint distributionstructure */
349struct htc_endpoint_credit_dist {
350 struct list_head list;
351
352 /* Service ID (set by HTC) */
353 u16 svc_id;
354
355 /* endpoint for this distributionstruct (set by HTC) */
356 enum htc_endpoint_id endpoint;
357
358 u32 dist_flags;
359
360 /*
361 * credits for normal operation, anything above this
362 * indicates the endpoint is over-subscribed.
363 */
364 int cred_norm;
365
366 /* floor for credit distribution */
367 int cred_min;
368
369 int cred_assngd;
370
371 /* current credits available */
372 int credits;
373
374 /*
375 * pending credits to distribute on this endpoint, this
376 * is set by HTC when credit reports arrive. The credit
377 * distribution functions sets this to zero when it distributes
378 * the credits.
379 */
380 int cred_to_dist;
381
382 /*
383 * the number of credits that the current pending TX packet needs
384 * to transmit. This is set by HTC when endpoint needs credits in
385 * order to transmit.
386 */
387 int seek_cred;
388
389 /* size in bytes of each credit */
390 int cred_sz;
391
392 /* credits required for a maximum sized messages */
393 int cred_per_msg;
394
395 /* reserved for HTC use */
396 void *htc_rsvd;
397
398 /*
399 * current depth of TX queue , i.e. messages waiting for credits
400 * This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE
401 * or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint
402 * that has non-zero credits to recover.
403 */
404 int txq_depth;
405};
406
407/*
408 * credit distibution code that is passed into the distrbution function,
409 * there are mandatory and optional codes that must be handled
410 */
411enum htc_credit_dist_reason {
412 HTC_CREDIT_DIST_SEND_COMPLETE = 0,
413 HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1,
414 HTC_CREDIT_DIST_SEEK_CREDITS,
415};
416
417struct htc_credit_state_info {
418 int total_avail_credits;
419 int cur_free_credits;
420 struct list_head lowestpri_ep_dist;
421};
422
423/* endpoint statistics */
424struct htc_endpoint_stats {
425 /*
426 * number of times the host set the credit-low flag in a send
427 * message on this endpoint
428 */
429 u32 cred_low_indicate;
430
431 u32 tx_issued;
432 u32 tx_pkt_bundled;
433 u32 tx_bundles;
434 u32 tx_dropped;
435
436 /* running count of total credit reports received for this endpoint */
437 u32 tx_cred_rpt;
438
439 /* credit reports received from this endpoint's RX packets */
440 u32 cred_rpt_from_rx;
441
442 /* credit reports received from RX packets of other endpoints */
443 u32 cred_rpt_from_other;
444
445 /* credit reports received from endpoint 0 RX packets */
446 u32 cred_rpt_ep0;
447
448 /* count of credits received via Rx packets on this endpoint */
449 u32 cred_from_rx;
450
451 /* count of credits received via another endpoint */
452 u32 cred_from_other;
453
454 /* count of credits received via another endpoint */
455 u32 cred_from_ep0;
456
457 /* count of consummed credits */
458 u32 cred_cosumd;
459
460 /* count of credits returned */
461 u32 cred_retnd;
462
463 u32 rx_pkts;
464
465 /* count of lookahead records found in Rx msg */
466 u32 rx_lkahds;
467
468 /* count of recv packets received in a bundle */
469 u32 rx_bundl;
470
471 /* count of number of bundled lookaheads */
472 u32 rx_bundle_lkahd;
473
474 /* count of the number of bundle indications from the HTC header */
475 u32 rx_bundle_from_hdr;
476
477 /* the number of times the recv allocation threshold was hit */
478 u32 rx_alloc_thresh_hit;
479
480 /* total number of bytes */
481 u32 rxalloc_thresh_byte;
482};
483
484struct htc_endpoint {
485 enum htc_endpoint_id eid;
486 u16 svc_id;
487 struct list_head txq;
488 struct list_head rx_bufq;
489 struct htc_endpoint_credit_dist cred_dist;
490 struct htc_ep_callbacks ep_cb;
491 int max_txq_depth;
492 int len_max;
493 int tx_proc_cnt;
494 int rx_proc_cnt;
495 struct htc_target *target;
496 u8 seqno;
497 u32 conn_flags;
498 struct htc_endpoint_stats ep_st;
499};
500
501struct htc_control_buffer {
502 struct htc_packet packet;
503 u8 *buf;
504};
505
506struct ath6kl_device;
507
508/* our HTC target state */
509struct htc_target {
510 struct htc_endpoint endpoint[ENDPOINT_MAX];
511 struct list_head cred_dist_list;
512 struct list_head free_ctrl_txbuf;
513 struct list_head free_ctrl_rxbuf;
514 struct htc_credit_state_info *cred_dist_cntxt;
515 int tgt_creds;
516 unsigned int tgt_cred_sz;
517 spinlock_t htc_lock;
518 spinlock_t rx_lock;
519 spinlock_t tx_lock;
520 struct ath6kl_device *dev;
521 u32 htc_flags;
522 u32 rx_st_flags;
523 enum htc_endpoint_id ep_waiting;
524 u8 htc_tgt_ver;
525
526 /* max messages per bundle for HTC */
527 int msg_per_bndl_max;
528
529 bool tx_bndl_enable;
530 int rx_bndl_enable;
531 int max_rx_bndl_sz;
532 int max_tx_bndl_sz;
533
534 u32 block_sz;
535 u32 block_mask;
536
537 int max_scat_entries;
538 int max_xfer_szper_scatreq;
539
540 int chk_irq_status_cnt;
541};
542
543void *ath6kl_htc_create(struct ath6kl *ar);
544void ath6kl_htc_set_credit_dist(struct htc_target *target,
545 struct htc_credit_state_info *cred_info,
546 u16 svc_pri_order[], int len);
547int ath6kl_htc_wait_target(struct htc_target *target);
548int ath6kl_htc_start(struct htc_target *target);
549int ath6kl_htc_conn_service(struct htc_target *target,
550 struct htc_service_connect_req *req,
551 struct htc_service_connect_resp *resp);
552int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet);
553void ath6kl_htc_stop(struct htc_target *target);
554void ath6kl_htc_cleanup(struct htc_target *target);
555void ath6kl_htc_flush_txep(struct htc_target *target,
556 enum htc_endpoint_id endpoint, u16 tag);
557void ath6kl_htc_flush_rx_buf(struct htc_target *target);
558void ath6kl_htc_indicate_activity_change(struct htc_target *target,
559 enum htc_endpoint_id endpoint,
560 bool active);
561int ath6kl_htc_get_rxbuf_num(struct htc_target *target,
562 enum htc_endpoint_id endpoint);
563int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
564 struct list_head *pktq);
565int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
566 u32 msg_look_ahead[], int *n_pkts);
567
568static inline void set_htc_pkt_info(struct htc_packet *packet, void *context,
569 u8 *buf, unsigned int len,
570 enum htc_endpoint_id eid, u16 tag)
571{
572 packet->pkt_cntxt = context;
573 packet->buf = buf;
574 packet->act_len = len;
575 packet->endpoint = eid;
576 packet->info.tx.tag = tag;
577}
578
579static inline void htc_rxpkt_reset(struct htc_packet *packet)
580{
581 packet->buf = packet->buf_start;
582 packet->act_len = 0;
583}
584
585static inline void set_htc_rxpkt_info(struct htc_packet *packet, void *context,
586 u8 *buf, unsigned long len,
587 enum htc_endpoint_id eid)
588{
589 packet->pkt_cntxt = context;
590 packet->buf = buf;
591 packet->buf_start = buf;
592 packet->buf_len = len;
593 packet->endpoint = eid;
594}
595
596static inline int get_queue_depth(struct list_head *queue)
597{
598 struct list_head *tmp_list;
599 int depth = 0;
600
601 list_for_each(tmp_list, queue)
602 depth++;
603
604 return depth;
605}
606
607#endif
diff --git a/drivers/net/wireless/ath/ath6kl/htc_hif.c b/drivers/net/wireless/ath/ath6kl/htc_hif.c
new file mode 100644
index 00000000000..86b1cc7409c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/htc_hif.c
@@ -0,0 +1,641 @@
1/*
2 * Copyright (c) 2007-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
18#include "target.h"
19#include "hif-ops.h"
20#include "htc_hif.h"
21#include "debug.h"
22
23#define MAILBOX_FOR_BLOCK_SIZE 1
24
25#define ATH6KL_TIME_QUANTUM 10 /* in ms */
26
27static int ath6kldev_cp_scat_dma_buf(struct hif_scatter_req *req, bool from_dma)
28{
29 u8 *buf;
30 int i;
31
32 buf = req->virt_dma_buf;
33
34 for (i = 0; i < req->scat_entries; i++) {
35
36 if (from_dma)
37 memcpy(req->scat_list[i].buf, buf,
38 req->scat_list[i].len);
39 else
40 memcpy(buf, req->scat_list[i].buf,
41 req->scat_list[i].len);
42
43 buf += req->scat_list[i].len;
44 }
45
46 return 0;
47}
48
49int ath6kldev_rw_comp_handler(void *context, int status)
50{
51 struct htc_packet *packet = context;
52
53 ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
54 "ath6kldev_rw_comp_handler (pkt:0x%p , status: %d\n",
55 packet, status);
56
57 packet->status = status;
58 packet->completion(packet->context, packet);
59
60 return 0;
61}
62
63static int ath6kldev_proc_dbg_intr(struct ath6kl_device *dev)
64{
65 u32 dummy;
66 int status;
67
68 ath6kl_err("target debug interrupt\n");
69
70 ath6kl_target_failure(dev->ar);
71
72 /*
73 * read counter to clear the interrupt, the debug error interrupt is
74 * counter 0.
75 */
76 status = hif_read_write_sync(dev->ar, COUNT_DEC_ADDRESS,
77 (u8 *)&dummy, 4, HIF_RD_SYNC_BYTE_INC);
78 if (status)
79 WARN_ON(1);
80
81 return status;
82}
83
84/* mailbox recv message polling */
85int ath6kldev_poll_mboxmsg_rx(struct ath6kl_device *dev, u32 *lk_ahd,
86 int timeout)
87{
88 struct ath6kl_irq_proc_registers *rg;
89 int status = 0, i;
90 u8 htc_mbox = 1 << HTC_MAILBOX;
91
92 for (i = timeout / ATH6KL_TIME_QUANTUM; i > 0; i--) {
93 /* this is the standard HIF way, load the reg table */
94 status = hif_read_write_sync(dev->ar, HOST_INT_STATUS_ADDRESS,
95 (u8 *) &dev->irq_proc_reg,
96 sizeof(dev->irq_proc_reg),
97 HIF_RD_SYNC_BYTE_INC);
98
99 if (status) {
100 ath6kl_err("failed to read reg table\n");
101 return status;
102 }
103
104 /* check for MBOX data and valid lookahead */
105 if (dev->irq_proc_reg.host_int_status & htc_mbox) {
106 if (dev->irq_proc_reg.rx_lkahd_valid &
107 htc_mbox) {
108 /*
109 * Mailbox has a message and the look ahead
110 * is valid.
111 */
112 rg = &dev->irq_proc_reg;
113 *lk_ahd =
114 le32_to_cpu(rg->rx_lkahd[HTC_MAILBOX]);
115 break;
116 }
117 }
118
119 /* delay a little */
120 mdelay(ATH6KL_TIME_QUANTUM);
121 ath6kl_dbg(ATH6KL_DBG_HTC_RECV, "retry mbox poll : %d\n", i);
122 }
123
124 if (i == 0) {
125 ath6kl_err("timeout waiting for recv message\n");
126 status = -ETIME;
127 /* check if the target asserted */
128 if (dev->irq_proc_reg.counter_int_status &
129 ATH6KL_TARGET_DEBUG_INTR_MASK)
130 /*
131 * Target failure handler will be called in case of
132 * an assert.
133 */
134 ath6kldev_proc_dbg_intr(dev);
135 }
136
137 return status;
138}
139
140/*
141 * Disable packet reception (used in case the host runs out of buffers)
142 * using the interrupt enable registers through the host I/F
143 */
144int ath6kldev_rx_control(struct ath6kl_device *dev, bool enable_rx)
145{
146 struct ath6kl_irq_enable_reg regs;
147 int status = 0;
148
149 /* take the lock to protect interrupt enable shadows */
150 spin_lock_bh(&dev->lock);
151
152 if (enable_rx)
153 dev->irq_en_reg.int_status_en |=
154 SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
155 else
156 dev->irq_en_reg.int_status_en &=
157 ~SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
158
159 memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
160
161 spin_unlock_bh(&dev->lock);
162
163 status = hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
164 &regs.int_status_en,
165 sizeof(struct ath6kl_irq_enable_reg),
166 HIF_WR_SYNC_BYTE_INC);
167
168 return status;
169}
170
171int ath6kldev_submit_scat_req(struct ath6kl_device *dev,
172 struct hif_scatter_req *scat_req, bool read)
173{
174 int status = 0;
175
176 if (read) {
177 scat_req->req = HIF_RD_SYNC_BLOCK_FIX;
178 scat_req->addr = dev->ar->mbox_info.htc_addr;
179 } else {
180 scat_req->req = HIF_WR_ASYNC_BLOCK_INC;
181
182 scat_req->addr =
183 (scat_req->len > HIF_MBOX_WIDTH) ?
184 dev->ar->mbox_info.htc_ext_addr :
185 dev->ar->mbox_info.htc_addr;
186 }
187
188 ath6kl_dbg((ATH6KL_DBG_HTC_RECV | ATH6KL_DBG_HTC_SEND),
189 "ath6kldev_submit_scat_req, entries: %d, total len: %d mbox:0x%X (mode: %s : %s)\n",
190 scat_req->scat_entries, scat_req->len,
191 scat_req->addr, !read ? "async" : "sync",
192 (read) ? "rd" : "wr");
193
194 if (!read && scat_req->virt_scat) {
195 status = ath6kldev_cp_scat_dma_buf(scat_req, false);
196 if (status) {
197 scat_req->status = status;
198 scat_req->complete(dev->ar->htc_target, scat_req);
199 return 0;
200 }
201 }
202
203 status = ath6kl_hif_scat_req_rw(dev->ar, scat_req);
204
205 if (read) {
206 /* in sync mode, we can touch the scatter request */
207 scat_req->status = status;
208 if (!status && scat_req->virt_scat)
209 scat_req->status =
210 ath6kldev_cp_scat_dma_buf(scat_req, true);
211 }
212
213 return status;
214}
215
216static int ath6kldev_proc_counter_intr(struct ath6kl_device *dev)
217{
218 u8 counter_int_status;
219
220 ath6kl_dbg(ATH6KL_DBG_IRQ, "counter interrupt\n");
221
222 counter_int_status = dev->irq_proc_reg.counter_int_status &
223 dev->irq_en_reg.cntr_int_status_en;
224
225 ath6kl_dbg(ATH6KL_DBG_IRQ,
226 "valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
227 counter_int_status);
228
229 /*
230 * NOTE: other modules like GMBOX may use the counter interrupt for
231 * credit flow control on other counters, we only need to check for
232 * the debug assertion counter interrupt.
233 */
234 if (counter_int_status & ATH6KL_TARGET_DEBUG_INTR_MASK)
235 return ath6kldev_proc_dbg_intr(dev);
236
237 return 0;
238}
239
240static int ath6kldev_proc_err_intr(struct ath6kl_device *dev)
241{
242 int status;
243 u8 error_int_status;
244 u8 reg_buf[4];
245
246 ath6kl_dbg(ATH6KL_DBG_IRQ, "error interrupt\n");
247
248 error_int_status = dev->irq_proc_reg.error_int_status & 0x0F;
249 if (!error_int_status) {
250 WARN_ON(1);
251 return -EIO;
252 }
253
254 ath6kl_dbg(ATH6KL_DBG_IRQ,
255 "valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
256 error_int_status);
257
258 if (MS(ERROR_INT_STATUS_WAKEUP, error_int_status))
259 ath6kl_dbg(ATH6KL_DBG_IRQ, "error : wakeup\n");
260
261 if (MS(ERROR_INT_STATUS_RX_UNDERFLOW, error_int_status))
262 ath6kl_err("rx underflow\n");
263
264 if (MS(ERROR_INT_STATUS_TX_OVERFLOW, error_int_status))
265 ath6kl_err("tx overflow\n");
266
267 /* Clear the interrupt */
268 dev->irq_proc_reg.error_int_status &= ~error_int_status;
269
270 /* set W1C value to clear the interrupt, this hits the register first */
271 reg_buf[0] = error_int_status;
272 reg_buf[1] = 0;
273 reg_buf[2] = 0;
274 reg_buf[3] = 0;
275
276 status = hif_read_write_sync(dev->ar, ERROR_INT_STATUS_ADDRESS,
277 reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);
278
279 if (status)
280 WARN_ON(1);
281
282 return status;
283}
284
285static int ath6kldev_proc_cpu_intr(struct ath6kl_device *dev)
286{
287 int status;
288 u8 cpu_int_status;
289 u8 reg_buf[4];
290
291 ath6kl_dbg(ATH6KL_DBG_IRQ, "cpu interrupt\n");
292
293 cpu_int_status = dev->irq_proc_reg.cpu_int_status &
294 dev->irq_en_reg.cpu_int_status_en;
295 if (!cpu_int_status) {
296 WARN_ON(1);
297 return -EIO;
298 }
299
300 ath6kl_dbg(ATH6KL_DBG_IRQ,
301 "valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
302 cpu_int_status);
303
304 /* Clear the interrupt */
305 dev->irq_proc_reg.cpu_int_status &= ~cpu_int_status;
306
307 /*
308 * Set up the register transfer buffer to hit the register 4 times ,
309 * this is done to make the access 4-byte aligned to mitigate issues
310 * with host bus interconnects that restrict bus transfer lengths to
311 * be a multiple of 4-bytes.
312 */
313
314 /* set W1C value to clear the interrupt, this hits the register first */
315 reg_buf[0] = cpu_int_status;
316 /* the remaining are set to zero which have no-effect */
317 reg_buf[1] = 0;
318 reg_buf[2] = 0;
319 reg_buf[3] = 0;
320
321 status = hif_read_write_sync(dev->ar, CPU_INT_STATUS_ADDRESS,
322 reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);
323
324 if (status)
325 WARN_ON(1);
326
327 return status;
328}
329
330/* process pending interrupts synchronously */
331static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
332{
333 struct ath6kl_irq_proc_registers *rg;
334 int status = 0;
335 u8 host_int_status = 0;
336 u32 lk_ahd = 0;
337 u8 htc_mbox = 1 << HTC_MAILBOX;
338
339 ath6kl_dbg(ATH6KL_DBG_IRQ, "proc_pending_irqs: (dev: 0x%p)\n", dev);
340
341 /*
342 * NOTE: HIF implementation guarantees that the context of this
343 * call allows us to perform SYNCHRONOUS I/O, that is we can block,
344 * sleep or call any API that can block or switch thread/task
345 * contexts. This is a fully schedulable context.
346 */
347
348 /*
349 * Process pending intr only when int_status_en is clear, it may
350 * result in unnecessary bus transaction otherwise. Target may be
351 * unresponsive at the time.
352 */
353 if (dev->irq_en_reg.int_status_en) {
354 /*
355 * Read the first 28 bytes of the HTC register table. This
356 * will yield us the value of different int status
357 * registers and the lookahead registers.
358 *
359 * length = sizeof(int_status) + sizeof(cpu_int_status)
360 * + sizeof(error_int_status) +
361 * sizeof(counter_int_status) +
362 * sizeof(mbox_frame) + sizeof(rx_lkahd_valid)
363 * + sizeof(hole) + sizeof(rx_lkahd) +
364 * sizeof(int_status_en) +
365 * sizeof(cpu_int_status_en) +
366 * sizeof(err_int_status_en) +
367 * sizeof(cntr_int_status_en);
368 */
369 status = hif_read_write_sync(dev->ar, HOST_INT_STATUS_ADDRESS,
370 (u8 *) &dev->irq_proc_reg,
371 sizeof(dev->irq_proc_reg),
372 HIF_RD_SYNC_BYTE_INC);
373 if (status)
374 goto out;
375
376 if (AR_DBG_LVL_CHECK(ATH6KL_DBG_IRQ))
377 ath6kl_dump_registers(dev, &dev->irq_proc_reg,
378 &dev->irq_en_reg);
379
380 /* Update only those registers that are enabled */
381 host_int_status = dev->irq_proc_reg.host_int_status &
382 dev->irq_en_reg.int_status_en;
383
384 /* Look at mbox status */
385 if (host_int_status & htc_mbox) {
386 /*
387 * Mask out pending mbox value, we use "lookAhead as
388 * the real flag for mbox processing.
389 */
390 host_int_status &= ~htc_mbox;
391 if (dev->irq_proc_reg.rx_lkahd_valid &
392 htc_mbox) {
393 rg = &dev->irq_proc_reg;
394 lk_ahd = le32_to_cpu(rg->rx_lkahd[HTC_MAILBOX]);
395 if (!lk_ahd)
396 ath6kl_err("lookAhead is zero!\n");
397 }
398 }
399 }
400
401 if (!host_int_status && !lk_ahd) {
402 *done = true;
403 goto out;
404 }
405
406 if (lk_ahd) {
407 int fetched = 0;
408
409 ath6kl_dbg(ATH6KL_DBG_IRQ,
410 "pending mailbox msg, lk_ahd: 0x%X\n", lk_ahd);
411 /*
412 * Mailbox Interrupt, the HTC layer may issue async
413 * requests to empty the mailbox. When emptying the recv
414 * mailbox we use the async handler above called from the
415 * completion routine of the callers read request. This can
416 * improve performance by reducing context switching when
417 * we rapidly pull packets.
418 */
419 status = ath6kl_htc_rxmsg_pending_handler(dev->htc_cnxt,
420 &lk_ahd, &fetched);
421 if (status)
422 goto out;
423
424 if (!fetched)
425 /*
426 * HTC could not pull any messages out due to lack
427 * of resources.
428 */
429 dev->htc_cnxt->chk_irq_status_cnt = 0;
430 }
431
432 /* now handle the rest of them */
433 ath6kl_dbg(ATH6KL_DBG_IRQ,
434 "valid interrupt source(s) for other interrupts: 0x%x\n",
435 host_int_status);
436
437 if (MS(HOST_INT_STATUS_CPU, host_int_status)) {
438 /* CPU Interrupt */
439 status = ath6kldev_proc_cpu_intr(dev);
440 if (status)
441 goto out;
442 }
443
444 if (MS(HOST_INT_STATUS_ERROR, host_int_status)) {
445 /* Error Interrupt */
446 status = ath6kldev_proc_err_intr(dev);
447 if (status)
448 goto out;
449 }
450
451 if (MS(HOST_INT_STATUS_COUNTER, host_int_status))
452 /* Counter Interrupt */
453 status = ath6kldev_proc_counter_intr(dev);
454
455out:
456 /*
457 * An optimization to bypass reading the IRQ status registers
458 * unecessarily which can re-wake the target, if upper layers
459 * determine that we are in a low-throughput mode, we can rely on
460 * taking another interrupt rather than re-checking the status
461 * registers which can re-wake the target.
462 *
463 * NOTE : for host interfaces that makes use of detecting pending
464 * mbox messages at hif can not use this optimization due to
465 * possible side effects, SPI requires the host to drain all
466 * messages from the mailbox before exiting the ISR routine.
467 */
468
469 ath6kl_dbg(ATH6KL_DBG_IRQ,
470 "bypassing irq status re-check, forcing done\n");
471
472 if (!dev->htc_cnxt->chk_irq_status_cnt)
473 *done = true;
474
475 ath6kl_dbg(ATH6KL_DBG_IRQ,
476 "proc_pending_irqs: (done:%d, status=%d\n", *done, status);
477
478 return status;
479}
480
481/* interrupt handler, kicks off all interrupt processing */
482int ath6kldev_intr_bh_handler(struct ath6kl *ar)
483{
484 struct ath6kl_device *dev = ar->htc_target->dev;
485 int status = 0;
486 bool done = false;
487
488 /*
489 * Reset counter used to flag a re-scan of IRQ status registers on
490 * the target.
491 */
492 dev->htc_cnxt->chk_irq_status_cnt = 0;
493
494 /*
495 * IRQ processing is synchronous, interrupt status registers can be
496 * re-read.
497 */
498 while (!done) {
499 status = proc_pending_irqs(dev, &done);
500 if (status)
501 break;
502 }
503
504 return status;
505}
506
507static int ath6kldev_enable_intrs(struct ath6kl_device *dev)
508{
509 struct ath6kl_irq_enable_reg regs;
510 int status;
511
512 spin_lock_bh(&dev->lock);
513
514 /* Enable all but ATH6KL CPU interrupts */
515 dev->irq_en_reg.int_status_en =
516 SM(INT_STATUS_ENABLE_ERROR, 0x01) |
517 SM(INT_STATUS_ENABLE_CPU, 0x01) |
518 SM(INT_STATUS_ENABLE_COUNTER, 0x01);
519
520 /*
521 * NOTE: There are some cases where HIF can do detection of
522 * pending mbox messages which is disabled now.
523 */
524 dev->irq_en_reg.int_status_en |= SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
525
526 /* Set up the CPU Interrupt status Register */
527 dev->irq_en_reg.cpu_int_status_en = 0;
528
529 /* Set up the Error Interrupt status Register */
530 dev->irq_en_reg.err_int_status_en =
531 SM(ERROR_STATUS_ENABLE_RX_UNDERFLOW, 0x01) |
532 SM(ERROR_STATUS_ENABLE_TX_OVERFLOW, 0x1);
533
534 /*
535 * Enable Counter interrupt status register to get fatal errors for
536 * debugging.
537 */
538 dev->irq_en_reg.cntr_int_status_en = SM(COUNTER_INT_STATUS_ENABLE_BIT,
539 ATH6KL_TARGET_DEBUG_INTR_MASK);
540 memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
541
542 spin_unlock_bh(&dev->lock);
543
544 status = hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
545 &regs.int_status_en, sizeof(regs),
546 HIF_WR_SYNC_BYTE_INC);
547
548 if (status)
549 ath6kl_err("failed to update interrupt ctl reg err: %d\n",
550 status);
551
552 return status;
553}
554
555int ath6kldev_disable_intrs(struct ath6kl_device *dev)
556{
557 struct ath6kl_irq_enable_reg regs;
558
559 spin_lock_bh(&dev->lock);
560 /* Disable all interrupts */
561 dev->irq_en_reg.int_status_en = 0;
562 dev->irq_en_reg.cpu_int_status_en = 0;
563 dev->irq_en_reg.err_int_status_en = 0;
564 dev->irq_en_reg.cntr_int_status_en = 0;
565 memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
566 spin_unlock_bh(&dev->lock);
567
568 return hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
569 &regs.int_status_en, sizeof(regs),
570 HIF_WR_SYNC_BYTE_INC);
571}
572
573/* enable device interrupts */
574int ath6kldev_unmask_intrs(struct ath6kl_device *dev)
575{
576 int status = 0;
577
578 /*
579 * Make sure interrupt are disabled before unmasking at the HIF
580 * layer. The rationale here is that between device insertion
581 * (where we clear the interrupts the first time) and when HTC
582 * is finally ready to handle interrupts, other software can perform
583 * target "soft" resets. The ATH6KL interrupt enables reset back to an
584 * "enabled" state when this happens.
585 */
586 ath6kldev_disable_intrs(dev);
587
588 /* unmask the host controller interrupts */
589 ath6kl_hif_irq_enable(dev->ar);
590 status = ath6kldev_enable_intrs(dev);
591
592 return status;
593}
594
595/* disable all device interrupts */
596int ath6kldev_mask_intrs(struct ath6kl_device *dev)
597{
598 /*
599 * Mask the interrupt at the HIF layer to avoid any stray interrupt
600 * taken while we zero out our shadow registers in
601 * ath6kldev_disable_intrs().
602 */
603 ath6kl_hif_irq_disable(dev->ar);
604
605 return ath6kldev_disable_intrs(dev);
606}
607
608int ath6kldev_setup(struct ath6kl_device *dev)
609{
610 int status = 0;
611
612 spin_lock_init(&dev->lock);
613
614 /*
615 * NOTE: we actually get the block size of a mailbox other than 0,
616 * for SDIO the block size on mailbox 0 is artificially set to 1.
617 * So we use the block size that is set for the other 3 mailboxes.
618 */
619 dev->htc_cnxt->block_sz = dev->ar->mbox_info.block_size;
620
621 /* must be a power of 2 */
622 if ((dev->htc_cnxt->block_sz & (dev->htc_cnxt->block_sz - 1)) != 0) {
623 WARN_ON(1);
624 goto fail_setup;
625 }
626
627 /* assemble mask, used for padding to a block */
628 dev->htc_cnxt->block_mask = dev->htc_cnxt->block_sz - 1;
629
630 ath6kl_dbg(ATH6KL_DBG_TRC, "block size: %d, mbox addr:0x%X\n",
631 dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr);
632
633 ath6kl_dbg(ATH6KL_DBG_TRC,
634 "hif interrupt processing is sync only\n");
635
636 status = ath6kldev_disable_intrs(dev);
637
638fail_setup:
639 return status;
640
641}
diff --git a/drivers/net/wireless/ath/ath6kl/htc_hif.h b/drivers/net/wireless/ath/ath6kl/htc_hif.h
new file mode 100644
index 00000000000..171ad63d89b
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/htc_hif.h
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 2007-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_HIF_H
18#define HTC_HIF_H
19
20#include "htc.h"
21#include "hif.h"
22
23#define ATH6KL_MAILBOXES 4
24
25/* HTC runs over mailbox 0 */
26#define HTC_MAILBOX 0
27
28#define ATH6KL_TARGET_DEBUG_INTR_MASK 0x01
29
30#define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK | \
31 INT_STATUS_ENABLE_CPU_MASK | \
32 INT_STATUS_ENABLE_COUNTER_MASK)
33
34#define ATH6KL_REG_IO_BUFFER_SIZE 32
35#define ATH6KL_MAX_REG_IO_BUFFERS 8
36#define ATH6KL_SCATTER_ENTRIES_PER_REQ 16
37#define ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER (16 * 1024)
38#define ATH6KL_SCATTER_REQS 4
39
40#ifndef A_CACHE_LINE_PAD
41#define A_CACHE_LINE_PAD 128
42#endif
43#define ATH6KL_MIN_SCATTER_ENTRIES_PER_REQ 2
44#define ATH6KL_MIN_TRANSFER_SIZE_PER_SCATTER (4 * 1024)
45
46struct ath6kl_irq_proc_registers {
47 u8 host_int_status;
48 u8 cpu_int_status;
49 u8 error_int_status;
50 u8 counter_int_status;
51 u8 mbox_frame;
52 u8 rx_lkahd_valid;
53 u8 host_int_status2;
54 u8 gmbox_rx_avail;
55 __le32 rx_lkahd[2];
56 __le32 rx_gmbox_lkahd_alias[2];
57} __packed;
58
59struct ath6kl_irq_enable_reg {
60 u8 int_status_en;
61 u8 cpu_int_status_en;
62 u8 err_int_status_en;
63 u8 cntr_int_status_en;
64} __packed;
65
66struct ath6kl_device {
67 spinlock_t lock;
68 u8 pad1[A_CACHE_LINE_PAD];
69 struct ath6kl_irq_proc_registers irq_proc_reg;
70 u8 pad2[A_CACHE_LINE_PAD];
71 struct ath6kl_irq_enable_reg irq_en_reg;
72 u8 pad3[A_CACHE_LINE_PAD];
73 struct htc_target *htc_cnxt;
74 struct ath6kl *ar;
75};
76
77int ath6kldev_setup(struct ath6kl_device *dev);
78int ath6kldev_unmask_intrs(struct ath6kl_device *dev);
79int ath6kldev_mask_intrs(struct ath6kl_device *dev);
80int ath6kldev_poll_mboxmsg_rx(struct ath6kl_device *dev,
81 u32 *lk_ahd, int timeout);
82int ath6kldev_rx_control(struct ath6kl_device *dev, bool enable_rx);
83int ath6kldev_disable_intrs(struct ath6kl_device *dev);
84
85int ath6kldev_rw_comp_handler(void *context, int status);
86int ath6kldev_intr_bh_handler(struct ath6kl *ar);
87
88/* Scatter Function and Definitions */
89int ath6kldev_submit_scat_req(struct ath6kl_device *dev,
90 struct hif_scatter_req *scat_req, bool read);
91
92#endif /*ATH6KL_H_ */
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
new file mode 100644
index 00000000000..9d10322eac4
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -0,0 +1,1303 @@
1
2/*
3 * Copyright (c) 2011 Atheros Communications Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <linux/mmc/sdio_func.h>
19#include "core.h"
20#include "cfg80211.h"
21#include "target.h"
22#include "debug.h"
23#include "hif-ops.h"
24
25unsigned int debug_mask;
26
27module_param(debug_mask, uint, 0644);
28
29/*
30 * Include definitions here that can be used to tune the WLAN module
31 * behavior. Different customers can tune the behavior as per their needs,
32 * here.
33 */
34
35/*
36 * This configuration item enable/disable keepalive support.
37 * Keepalive support: In the absence of any data traffic to AP, null
38 * frames will be sent to the AP at periodic interval, to keep the association
39 * active. This configuration item defines the periodic interval.
40 * Use value of zero to disable keepalive support
41 * Default: 60 seconds
42 */
43#define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60
44
45/*
46 * This configuration item sets the value of disconnect timeout
47 * Firmware delays sending the disconnec event to the host for this
48 * timeout after is gets disconnected from the current AP.
49 * If the firmware successly roams within the disconnect timeout
50 * it sends a new connect event
51 */
52#define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
53
54#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
55
56enum addr_type {
57 DATASET_PATCH_ADDR,
58 APP_LOAD_ADDR,
59 APP_START_OVERRIDE_ADDR,
60};
61
62#define ATH6KL_DATA_OFFSET 64
63struct sk_buff *ath6kl_buf_alloc(int size)
64{
65 struct sk_buff *skb;
66 u16 reserved;
67
68 /* Add chacheline space at front and back of buffer */
69 reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
70 sizeof(struct htc_packet);
71 skb = dev_alloc_skb(size + reserved);
72
73 if (skb)
74 skb_reserve(skb, reserved - L1_CACHE_BYTES);
75 return skb;
76}
77
78void ath6kl_init_profile_info(struct ath6kl *ar)
79{
80 ar->ssid_len = 0;
81 memset(ar->ssid, 0, sizeof(ar->ssid));
82
83 ar->dot11_auth_mode = OPEN_AUTH;
84 ar->auth_mode = NONE_AUTH;
85 ar->prwise_crypto = NONE_CRYPT;
86 ar->prwise_crypto_len = 0;
87 ar->grp_crypto = NONE_CRYPT;
88 ar->grp_crpto_len = 0;
89 memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
90 memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
91 memset(ar->bssid, 0, sizeof(ar->bssid));
92 ar->bss_ch = 0;
93 ar->nw_type = ar->next_mode = INFRA_NETWORK;
94}
95
96static u8 ath6kl_get_fw_iftype(struct ath6kl *ar)
97{
98 switch (ar->nw_type) {
99 case INFRA_NETWORK:
100 return HI_OPTION_FW_MODE_BSS_STA;
101 case ADHOC_NETWORK:
102 return HI_OPTION_FW_MODE_IBSS;
103 case AP_NETWORK:
104 return HI_OPTION_FW_MODE_AP;
105 default:
106 ath6kl_err("Unsupported interface type :%d\n", ar->nw_type);
107 return 0xff;
108 }
109}
110
111static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
112 u32 item_offset)
113{
114 u32 addr = 0;
115
116 if (ar->target_type == TARGET_TYPE_AR6003)
117 addr = ATH6KL_HI_START_ADDR + item_offset;
118
119 return addr;
120}
121
122static int ath6kl_set_host_app_area(struct ath6kl *ar)
123{
124 u32 address, data;
125 struct host_app_area host_app_area;
126
127 /* Fetch the address of the host_app_area_s
128 * instance in the host interest area */
129 address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_app_host_interest));
130 address = TARG_VTOP(address);
131
132 if (ath6kl_read_reg_diag(ar, &address, &data))
133 return -EIO;
134
135 address = TARG_VTOP(data);
136 host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
137 if (ath6kl_access_datadiag(ar, address,
138 (u8 *)&host_app_area,
139 sizeof(struct host_app_area), false))
140 return -EIO;
141
142 return 0;
143}
144
145static inline void set_ac2_ep_map(struct ath6kl *ar,
146 u8 ac,
147 enum htc_endpoint_id ep)
148{
149 ar->ac2ep_map[ac] = ep;
150 ar->ep2ac_map[ep] = ac;
151}
152
153/* connect to a service */
154static int ath6kl_connectservice(struct ath6kl *ar,
155 struct htc_service_connect_req *con_req,
156 char *desc)
157{
158 int status;
159 struct htc_service_connect_resp response;
160
161 memset(&response, 0, sizeof(response));
162
163 status = ath6kl_htc_conn_service(ar->htc_target, con_req, &response);
164 if (status) {
165 ath6kl_err("failed to connect to %s service status:%d\n",
166 desc, status);
167 return status;
168 }
169
170 switch (con_req->svc_id) {
171 case WMI_CONTROL_SVC:
172 if (test_bit(WMI_ENABLED, &ar->flag))
173 ath6kl_wmi_set_control_ep(ar->wmi, response.endpoint);
174 ar->ctrl_ep = response.endpoint;
175 break;
176 case WMI_DATA_BE_SVC:
177 set_ac2_ep_map(ar, WMM_AC_BE, response.endpoint);
178 break;
179 case WMI_DATA_BK_SVC:
180 set_ac2_ep_map(ar, WMM_AC_BK, response.endpoint);
181 break;
182 case WMI_DATA_VI_SVC:
183 set_ac2_ep_map(ar, WMM_AC_VI, response.endpoint);
184 break;
185 case WMI_DATA_VO_SVC:
186 set_ac2_ep_map(ar, WMM_AC_VO, response.endpoint);
187 break;
188 default:
189 ath6kl_err("service id is not mapped %d\n", con_req->svc_id);
190 return -EINVAL;
191 }
192
193 return 0;
194}
195
196static int ath6kl_init_service_ep(struct ath6kl *ar)
197{
198 struct htc_service_connect_req connect;
199
200 memset(&connect, 0, sizeof(connect));
201
202 /* these fields are the same for all service endpoints */
203 connect.ep_cb.rx = ath6kl_rx;
204 connect.ep_cb.rx_refill = ath6kl_rx_refill;
205 connect.ep_cb.tx_full = ath6kl_tx_queue_full;
206
207 /*
208 * Set the max queue depth so that our ath6kl_tx_queue_full handler
209 * gets called.
210 */
211 connect.max_txq_depth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
212 connect.ep_cb.rx_refill_thresh = ATH6KL_MAX_RX_BUFFERS / 4;
213 if (!connect.ep_cb.rx_refill_thresh)
214 connect.ep_cb.rx_refill_thresh++;
215
216 /* connect to control service */
217 connect.svc_id = WMI_CONTROL_SVC;
218 if (ath6kl_connectservice(ar, &connect, "WMI CONTROL"))
219 return -EIO;
220
221 connect.flags |= HTC_FLGS_TX_BNDL_PAD_EN;
222
223 /*
224 * Limit the HTC message size on the send path, although e can
225 * receive A-MSDU frames of 4K, we will only send ethernet-sized
226 * (802.3) frames on the send path.
227 */
228 connect.max_rxmsg_sz = WMI_MAX_TX_DATA_FRAME_LENGTH;
229
230 /*
231 * To reduce the amount of committed memory for larger A_MSDU
232 * frames, use the recv-alloc threshold mechanism for larger
233 * packets.
234 */
235 connect.ep_cb.rx_alloc_thresh = ATH6KL_BUFFER_SIZE;
236 connect.ep_cb.rx_allocthresh = ath6kl_alloc_amsdu_rxbuf;
237
238 /*
239 * For the remaining data services set the connection flag to
240 * reduce dribbling, if configured to do so.
241 */
242 connect.conn_flags |= HTC_CONN_FLGS_REDUCE_CRED_DRIB;
243 connect.conn_flags &= ~HTC_CONN_FLGS_THRESH_MASK;
244 connect.conn_flags |= HTC_CONN_FLGS_THRESH_LVL_HALF;
245
246 connect.svc_id = WMI_DATA_BE_SVC;
247
248 if (ath6kl_connectservice(ar, &connect, "WMI DATA BE"))
249 return -EIO;
250
251 /* connect to back-ground map this to WMI LOW_PRI */
252 connect.svc_id = WMI_DATA_BK_SVC;
253 if (ath6kl_connectservice(ar, &connect, "WMI DATA BK"))
254 return -EIO;
255
256 /* connect to Video service, map this to to HI PRI */
257 connect.svc_id = WMI_DATA_VI_SVC;
258 if (ath6kl_connectservice(ar, &connect, "WMI DATA VI"))
259 return -EIO;
260
261 /*
262 * Connect to VO service, this is currently not mapped to a WMI
263 * priority stream due to historical reasons. WMI originally
264 * defined 3 priorities over 3 mailboxes We can change this when
265 * WMI is reworked so that priorities are not dependent on
266 * mailboxes.
267 */
268 connect.svc_id = WMI_DATA_VO_SVC;
269 if (ath6kl_connectservice(ar, &connect, "WMI DATA VO"))
270 return -EIO;
271
272 return 0;
273}
274
275static void ath6kl_init_control_info(struct ath6kl *ar)
276{
277 u8 ctr;
278
279 clear_bit(WMI_ENABLED, &ar->flag);
280 ath6kl_init_profile_info(ar);
281 ar->def_txkey_index = 0;
282 memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
283 ar->ch_hint = 0;
284 ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL;
285 ar->listen_intvl_b = 0;
286 ar->tx_pwr = 0;
287 clear_bit(SKIP_SCAN, &ar->flag);
288 set_bit(WMM_ENABLED, &ar->flag);
289 ar->intra_bss = 1;
290 memset(&ar->sc_params, 0, sizeof(ar->sc_params));
291 ar->sc_params.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT;
292 ar->sc_params.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS;
293
294 memset((u8 *)ar->sta_list, 0,
295 AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
296
297 spin_lock_init(&ar->mcastpsq_lock);
298
299 /* Init the PS queues */
300 for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
301 spin_lock_init(&ar->sta_list[ctr].psq_lock);
302 skb_queue_head_init(&ar->sta_list[ctr].psq);
303 }
304
305 skb_queue_head_init(&ar->mcastpsq);
306
307 memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
308}
309
310/*
311 * Set HTC/Mbox operational parameters, this can only be called when the
312 * target is in the BMI phase.
313 */
314static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val,
315 u8 htc_ctrl_buf)
316{
317 int status;
318 u32 blk_size;
319
320 blk_size = ar->mbox_info.block_size;
321
322 if (htc_ctrl_buf)
323 blk_size |= ((u32)htc_ctrl_buf) << 16;
324
325 /* set the host interest area for the block size */
326 status = ath6kl_bmi_write(ar,
327 ath6kl_get_hi_item_addr(ar,
328 HI_ITEM(hi_mbox_io_block_sz)),
329 (u8 *)&blk_size,
330 4);
331 if (status) {
332 ath6kl_err("bmi_write_memory for IO block size failed\n");
333 goto out;
334 }
335
336 ath6kl_dbg(ATH6KL_DBG_TRC, "block size set: %d (target addr:0x%X)\n",
337 blk_size,
338 ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_mbox_io_block_sz)));
339
340 if (mbox_isr_yield_val) {
341 /* set the host interest area for the mbox ISR yield limit */
342 status = ath6kl_bmi_write(ar,
343 ath6kl_get_hi_item_addr(ar,
344 HI_ITEM(hi_mbox_isr_yield_limit)),
345 (u8 *)&mbox_isr_yield_val,
346 4);
347 if (status) {
348 ath6kl_err("bmi_write_memory for yield limit failed\n");
349 goto out;
350 }
351 }
352
353out:
354 return status;
355}
356
357#define REG_DUMP_COUNT_AR6003 60
358#define REGISTER_DUMP_LEN_MAX 60
359
360static void ath6kl_dump_target_assert_info(struct ath6kl *ar)
361{
362 u32 address;
363 u32 regdump_loc = 0;
364 int status;
365 u32 regdump_val[REGISTER_DUMP_LEN_MAX];
366 u32 i;
367
368 if (ar->target_type != TARGET_TYPE_AR6003)
369 return;
370
371 /* the reg dump pointer is copied to the host interest area */
372 address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state));
373 address = TARG_VTOP(address);
374
375 /* read RAM location through diagnostic window */
376 status = ath6kl_read_reg_diag(ar, &address, &regdump_loc);
377
378 if (status || !regdump_loc) {
379 ath6kl_err("failed to get ptr to register dump area\n");
380 return;
381 }
382
383 ath6kl_dbg(ATH6KL_DBG_TRC, "location of register dump data: 0x%X\n",
384 regdump_loc);
385
386 regdump_loc = TARG_VTOP(regdump_loc);
387
388 /* fetch register dump data */
389 status = ath6kl_access_datadiag(ar,
390 regdump_loc,
391 (u8 *)&regdump_val[0],
392 REG_DUMP_COUNT_AR6003 * (sizeof(u32)),
393 true);
394
395 if (status) {
396 ath6kl_err("failed to get register dump\n");
397 return;
398 }
399 ath6kl_dbg(ATH6KL_DBG_TRC, "Register Dump:\n");
400
401 for (i = 0; i < REG_DUMP_COUNT_AR6003; i++)
402 ath6kl_dbg(ATH6KL_DBG_TRC, " %d : 0x%8.8X\n",
403 i, regdump_val[i]);
404
405}
406
407void ath6kl_target_failure(struct ath6kl *ar)
408{
409 ath6kl_err("target asserted\n");
410
411 /* try dumping target assertion information (if any) */
412 ath6kl_dump_target_assert_info(ar);
413
414}
415
416static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
417{
418 int status = 0;
419
420 /*
421 * Configure the device for rx dot11 header rules. "0,0" are the
422 * default values. Required if checksum offload is needed. Set
423 * RxMetaVersion to 2.
424 */
425 if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
426 ar->rx_meta_ver, 0, 0)) {
427 ath6kl_err("unable to set the rx frame format\n");
428 status = -EIO;
429 }
430
431 if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN)
432 if ((ath6kl_wmi_pmparams_cmd(ar->wmi, 0, 1, 0, 0, 1,
433 IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
434 ath6kl_err("unable to set power save fail event policy\n");
435 status = -EIO;
436 }
437
438 if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER))
439 if ((ath6kl_wmi_set_lpreamble_cmd(ar->wmi, 0,
440 WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) {
441 ath6kl_err("unable to set barker preamble policy\n");
442 status = -EIO;
443 }
444
445 if (ath6kl_wmi_set_keepalive_cmd(ar->wmi,
446 WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) {
447 ath6kl_err("unable to set keep alive interval\n");
448 status = -EIO;
449 }
450
451 if (ath6kl_wmi_disctimeout_cmd(ar->wmi,
452 WLAN_CONFIG_DISCONNECT_TIMEOUT)) {
453 ath6kl_err("unable to set disconnect timeout\n");
454 status = -EIO;
455 }
456
457 if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST))
458 if (ath6kl_wmi_set_wmm_txop(ar->wmi, WMI_TXOP_DISABLED)) {
459 ath6kl_err("unable to set txop bursting\n");
460 status = -EIO;
461 }
462
463 return status;
464}
465
466int ath6kl_configure_target(struct ath6kl *ar)
467{
468 u32 param, ram_reserved_size;
469 u8 fw_iftype;
470
471 fw_iftype = ath6kl_get_fw_iftype(ar);
472 if (fw_iftype == 0xff)
473 return -EINVAL;
474
475 /* Tell target which HTC version it is used*/
476 param = HTC_PROTOCOL_VERSION;
477 if (ath6kl_bmi_write(ar,
478 ath6kl_get_hi_item_addr(ar,
479 HI_ITEM(hi_app_host_interest)),
480 (u8 *)&param, 4) != 0) {
481 ath6kl_err("bmi_write_memory for htc version failed\n");
482 return -EIO;
483 }
484
485 /* set the firmware mode to STA/IBSS/AP */
486 param = 0;
487
488 if (ath6kl_bmi_read(ar,
489 ath6kl_get_hi_item_addr(ar,
490 HI_ITEM(hi_option_flag)),
491 (u8 *)&param, 4) != 0) {
492 ath6kl_err("bmi_read_memory for setting fwmode failed\n");
493 return -EIO;
494 }
495
496 param |= (1 << HI_OPTION_NUM_DEV_SHIFT);
497 param |= (fw_iftype << HI_OPTION_FW_MODE_SHIFT);
498 param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
499 param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
500
501 if (ath6kl_bmi_write(ar,
502 ath6kl_get_hi_item_addr(ar,
503 HI_ITEM(hi_option_flag)),
504 (u8 *)&param,
505 4) != 0) {
506 ath6kl_err("bmi_write_memory for setting fwmode failed\n");
507 return -EIO;
508 }
509
510 ath6kl_dbg(ATH6KL_DBG_TRC, "firmware mode set\n");
511
512 /*
513 * Hardcode the address use for the extended board data
514 * Ideally this should be pre-allocate by the OS at boot time
515 * But since it is a new feature and board data is loaded
516 * at init time, we have to workaround this from host.
517 * It is difficult to patch the firmware boot code,
518 * but possible in theory.
519 */
520
521 if (ar->target_type == TARGET_TYPE_AR6003) {
522 if (ar->version.target_ver == AR6003_REV2_VERSION) {
523 param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
524 ram_reserved_size = AR6003_REV2_RAM_RESERVE_SIZE;
525 } else {
526 param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
527 ram_reserved_size = AR6003_REV3_RAM_RESERVE_SIZE;
528 }
529
530 if (ath6kl_bmi_write(ar,
531 ath6kl_get_hi_item_addr(ar,
532 HI_ITEM(hi_board_ext_data)),
533 (u8 *)&param, 4) != 0) {
534 ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
535 return -EIO;
536 }
537 if (ath6kl_bmi_write(ar,
538 ath6kl_get_hi_item_addr(ar,
539 HI_ITEM(hi_end_ram_reserve_sz)),
540 (u8 *)&ram_reserved_size, 4) != 0) {
541 ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
542 return -EIO;
543 }
544 }
545
546 /* set the block size for the target */
547 if (ath6kl_set_htc_params(ar, MBOX_YIELD_LIMIT, 0))
548 /* use default number of control buffers */
549 return -EIO;
550
551 return 0;
552}
553
554struct ath6kl *ath6kl_core_alloc(struct device *sdev)
555{
556 struct net_device *dev;
557 struct ath6kl *ar;
558 struct wireless_dev *wdev;
559
560 wdev = ath6kl_cfg80211_init(sdev);
561 if (!wdev) {
562 ath6kl_err("ath6kl_cfg80211_init failed\n");
563 return NULL;
564 }
565
566 ar = wdev_priv(wdev);
567 ar->dev = sdev;
568 ar->wdev = wdev;
569 wdev->iftype = NL80211_IFTYPE_STATION;
570
571 dev = alloc_netdev(0, "wlan%d", ether_setup);
572 if (!dev) {
573 ath6kl_err("no memory for network device instance\n");
574 ath6kl_cfg80211_deinit(ar);
575 return NULL;
576 }
577
578 dev->ieee80211_ptr = wdev;
579 SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
580 wdev->netdev = dev;
581 ar->sme_state = SME_DISCONNECTED;
582 ar->auto_auth_stage = AUTH_IDLE;
583
584 init_netdev(dev);
585
586 ar->net_dev = dev;
587 set_bit(WLAN_ENABLED, &ar->flag);
588
589 ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
590
591 spin_lock_init(&ar->lock);
592
593 ath6kl_init_control_info(ar);
594 init_waitqueue_head(&ar->event_wq);
595 sema_init(&ar->sem, 1);
596 clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
597
598 INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
599
600 setup_timer(&ar->disconnect_timer, disconnect_timer_handler,
601 (unsigned long) dev);
602
603 return ar;
604}
605
606int ath6kl_unavail_ev(struct ath6kl *ar)
607{
608 ath6kl_destroy(ar->net_dev, 1);
609
610 return 0;
611}
612
613/* firmware upload */
614static u32 ath6kl_get_load_address(u32 target_ver, enum addr_type type)
615{
616 WARN_ON(target_ver != AR6003_REV2_VERSION &&
617 target_ver != AR6003_REV3_VERSION);
618
619 switch (type) {
620 case DATASET_PATCH_ADDR:
621 return (target_ver == AR6003_REV2_VERSION) ?
622 AR6003_REV2_DATASET_PATCH_ADDRESS :
623 AR6003_REV3_DATASET_PATCH_ADDRESS;
624 case APP_LOAD_ADDR:
625 return (target_ver == AR6003_REV2_VERSION) ?
626 AR6003_REV2_APP_LOAD_ADDRESS :
627 0x1234;
628 case APP_START_OVERRIDE_ADDR:
629 return (target_ver == AR6003_REV2_VERSION) ?
630 AR6003_REV2_APP_START_OVERRIDE :
631 AR6003_REV3_APP_START_OVERRIDE;
632 default:
633 return 0;
634 }
635}
636
637static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
638 u8 **fw, size_t *fw_len)
639{
640 const struct firmware *fw_entry;
641 int ret;
642
643 ret = request_firmware(&fw_entry, filename, ar->dev);
644 if (ret)
645 return ret;
646
647 *fw_len = fw_entry->size;
648 *fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
649
650 if (*fw == NULL)
651 ret = -ENOMEM;
652
653 release_firmware(fw_entry);
654
655 return ret;
656}
657
658static int ath6kl_fetch_board_file(struct ath6kl *ar)
659{
660 const char *filename;
661 int ret;
662
663 switch (ar->version.target_ver) {
664 case AR6003_REV2_VERSION:
665 filename = AR6003_REV2_BOARD_DATA_FILE;
666 break;
667 default:
668 filename = AR6003_REV3_BOARD_DATA_FILE;
669 break;
670 }
671
672 ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
673 &ar->fw_board_len);
674 if (ret == 0) {
675 /* managed to get proper board file */
676 return 0;
677 }
678
679 /* there was no proper board file, try to use default instead */
680 ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n",
681 filename, ret);
682
683 switch (ar->version.target_ver) {
684 case AR6003_REV2_VERSION:
685 filename = AR6003_REV2_DEFAULT_BOARD_DATA_FILE;
686 break;
687 default:
688 filename = AR6003_REV3_DEFAULT_BOARD_DATA_FILE;
689 break;
690 }
691
692 ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
693 &ar->fw_board_len);
694 if (ret) {
695 ath6kl_err("Failed to get default board file %s: %d\n",
696 filename, ret);
697 return ret;
698 }
699
700 ath6kl_warn("WARNING! No proper board file was not found, instead using a default board file.\n");
701 ath6kl_warn("Most likely your hardware won't work as specified. Install correct board file!\n");
702
703 return 0;
704}
705
706
707static int ath6kl_upload_board_file(struct ath6kl *ar)
708{
709 u32 board_address, board_ext_address, param;
710 int ret;
711
712 if (ar->fw_board == NULL) {
713 ret = ath6kl_fetch_board_file(ar);
714 if (ret)
715 return ret;
716 }
717
718 /* Determine where in Target RAM to write Board Data */
719 ath6kl_bmi_read(ar,
720 ath6kl_get_hi_item_addr(ar,
721 HI_ITEM(hi_board_data)),
722 (u8 *) &board_address, 4);
723 ath6kl_dbg(ATH6KL_DBG_TRC, "board data download addr: 0x%x\n",
724 board_address);
725
726 /* determine where in target ram to write extended board data */
727 ath6kl_bmi_read(ar,
728 ath6kl_get_hi_item_addr(ar,
729 HI_ITEM(hi_board_ext_data)),
730 (u8 *) &board_ext_address, 4);
731
732 ath6kl_dbg(ATH6KL_DBG_TRC, "board file download addr: 0x%x\n",
733 board_ext_address);
734
735 if (board_ext_address == 0) {
736 ath6kl_err("Failed to get board file target address.\n");
737 return -EINVAL;
738 }
739
740 if (ar->fw_board_len == (AR6003_BOARD_DATA_SZ +
741 AR6003_BOARD_EXT_DATA_SZ)) {
742 /* write extended board data */
743 ret = ath6kl_bmi_write(ar, board_ext_address,
744 ar->fw_board + AR6003_BOARD_DATA_SZ,
745 AR6003_BOARD_EXT_DATA_SZ);
746
747 if (ret) {
748 ath6kl_err("Failed to write extended board data: %d\n",
749 ret);
750 return ret;
751 }
752
753 /* record that extended board data is initialized */
754 param = (AR6003_BOARD_EXT_DATA_SZ << 16) | 1;
755 ath6kl_bmi_write(ar,
756 ath6kl_get_hi_item_addr(ar,
757 HI_ITEM(hi_board_ext_data_config)),
758 (unsigned char *) &param, 4);
759 }
760
761 if (ar->fw_board_len < AR6003_BOARD_DATA_SZ) {
762 ath6kl_err("Too small board file: %zu\n", ar->fw_board_len);
763 ret = -EINVAL;
764 return ret;
765 }
766
767 ret = ath6kl_bmi_write(ar, board_address, ar->fw_board,
768 AR6003_BOARD_DATA_SZ);
769
770 if (ret) {
771 ath6kl_err("Board file bmi write failed: %d\n", ret);
772 return ret;
773 }
774
775 /* record the fact that Board Data IS initialized */
776 param = 1;
777 ath6kl_bmi_write(ar,
778 ath6kl_get_hi_item_addr(ar,
779 HI_ITEM(hi_board_data_initialized)),
780 (u8 *)&param, 4);
781
782 return ret;
783}
784
785static int ath6kl_upload_otp(struct ath6kl *ar)
786{
787 const char *filename;
788 u32 address, param;
789 int ret;
790
791 switch (ar->version.target_ver) {
792 case AR6003_REV2_VERSION:
793 filename = AR6003_REV2_OTP_FILE;
794 break;
795 default:
796 filename = AR6003_REV3_OTP_FILE;
797 break;
798 }
799
800 if (ar->fw_otp == NULL) {
801 ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
802 &ar->fw_otp_len);
803 if (ret) {
804 ath6kl_err("Failed to get OTP file %s: %d\n",
805 filename, ret);
806 return ret;
807 }
808 }
809
810 address = ath6kl_get_load_address(ar->version.target_ver,
811 APP_LOAD_ADDR);
812
813 ret = ath6kl_bmi_fast_download(ar, address, ar->fw_otp,
814 ar->fw_otp_len);
815 if (ret) {
816 ath6kl_err("Failed to upload OTP file: %d\n", ret);
817 return ret;
818 }
819
820 /* execute the OTP code */
821 param = 0;
822 address = ath6kl_get_load_address(ar->version.target_ver,
823 APP_START_OVERRIDE_ADDR);
824 ath6kl_bmi_execute(ar, address, &param);
825
826 return ret;
827}
828
829static int ath6kl_upload_firmware(struct ath6kl *ar)
830{
831 const char *filename;
832 u32 address;
833 int ret;
834
835 switch (ar->version.target_ver) {
836 case AR6003_REV2_VERSION:
837 filename = AR6003_REV2_FIRMWARE_FILE;
838 break;
839 default:
840 filename = AR6003_REV3_FIRMWARE_FILE;
841 break;
842 }
843
844 if (ar->fw == NULL) {
845 ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
846 if (ret) {
847 ath6kl_err("Failed to get firmware file %s: %d\n",
848 filename, ret);
849 return ret;
850 }
851 }
852
853 address = ath6kl_get_load_address(ar->version.target_ver,
854 APP_LOAD_ADDR);
855
856 ret = ath6kl_bmi_fast_download(ar, address, ar->fw, ar->fw_len);
857
858 if (ret) {
859 ath6kl_err("Failed to write firmware: %d\n", ret);
860 return ret;
861 }
862
863 /* Set starting address for firmware */
864 address = ath6kl_get_load_address(ar->version.target_ver,
865 APP_START_OVERRIDE_ADDR);
866 ath6kl_bmi_set_app_start(ar, address);
867
868 return ret;
869}
870
871static int ath6kl_upload_patch(struct ath6kl *ar)
872{
873 const char *filename;
874 u32 address, param;
875 int ret;
876
877 switch (ar->version.target_ver) {
878 case AR6003_REV2_VERSION:
879 filename = AR6003_REV2_PATCH_FILE;
880 break;
881 default:
882 filename = AR6003_REV3_PATCH_FILE;
883 break;
884 }
885
886 if (ar->fw_patch == NULL) {
887 ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
888 &ar->fw_patch_len);
889 if (ret) {
890 ath6kl_err("Failed to get patch file %s: %d\n",
891 filename, ret);
892 return ret;
893 }
894 }
895
896 address = ath6kl_get_load_address(ar->version.target_ver,
897 DATASET_PATCH_ADDR);
898
899 ret = ath6kl_bmi_write(ar, address, ar->fw_patch, ar->fw_patch_len);
900 if (ret) {
901 ath6kl_err("Failed to write patch file: %d\n", ret);
902 return ret;
903 }
904
905 param = address;
906 ath6kl_bmi_write(ar,
907 ath6kl_get_hi_item_addr(ar,
908 HI_ITEM(hi_dset_list_head)),
909 (unsigned char *) &param, 4);
910
911 return 0;
912}
913
914static int ath6kl_init_upload(struct ath6kl *ar)
915{
916 u32 param, options, sleep, address;
917 int status = 0;
918
919 if (ar->target_type != TARGET_TYPE_AR6003)
920 return -EINVAL;
921
922 /* temporarily disable system sleep */
923 address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
924 status = ath6kl_bmi_reg_read(ar, address, &param);
925 if (status)
926 return status;
927
928 options = param;
929
930 param |= ATH6KL_OPTION_SLEEP_DISABLE;
931 status = ath6kl_bmi_reg_write(ar, address, param);
932 if (status)
933 return status;
934
935 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
936 status = ath6kl_bmi_reg_read(ar, address, &param);
937 if (status)
938 return status;
939
940 sleep = param;
941
942 param |= SM(SYSTEM_SLEEP_DISABLE, 1);
943 status = ath6kl_bmi_reg_write(ar, address, param);
944 if (status)
945 return status;
946
947 ath6kl_dbg(ATH6KL_DBG_TRC, "old options: %d, old sleep: %d\n",
948 options, sleep);
949
950 /* program analog PLL register */
951 status = ath6kl_bmi_reg_write(ar, ATH6KL_ANALOG_PLL_REGISTER,
952 0xF9104001);
953 if (status)
954 return status;
955
956 /* Run at 80/88MHz by default */
957 param = SM(CPU_CLOCK_STANDARD, 1);
958
959 address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
960 status = ath6kl_bmi_reg_write(ar, address, param);
961 if (status)
962 return status;
963
964 param = 0;
965 address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
966 param = SM(LPO_CAL_ENABLE, 1);
967 status = ath6kl_bmi_reg_write(ar, address, param);
968 if (status)
969 return status;
970
971 /* WAR to avoid SDIO CRC err */
972 if (ar->version.target_ver == AR6003_REV2_VERSION) {
973 ath6kl_err("temporary war to avoid sdio crc error\n");
974
975 param = 0x20;
976
977 address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
978 status = ath6kl_bmi_reg_write(ar, address, param);
979 if (status)
980 return status;
981
982 address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
983 status = ath6kl_bmi_reg_write(ar, address, param);
984 if (status)
985 return status;
986
987 address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
988 status = ath6kl_bmi_reg_write(ar, address, param);
989 if (status)
990 return status;
991
992 address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
993 status = ath6kl_bmi_reg_write(ar, address, param);
994 if (status)
995 return status;
996 }
997
998 /* write EEPROM data to Target RAM */
999 status = ath6kl_upload_board_file(ar);
1000 if (status)
1001 return status;
1002
1003 /* transfer One time Programmable data */
1004 status = ath6kl_upload_otp(ar);
1005 if (status)
1006 return status;
1007
1008 /* Download Target firmware */
1009 status = ath6kl_upload_firmware(ar);
1010 if (status)
1011 return status;
1012
1013 status = ath6kl_upload_patch(ar);
1014 if (status)
1015 return status;
1016
1017 /* Restore system sleep */
1018 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1019 status = ath6kl_bmi_reg_write(ar, address, sleep);
1020 if (status)
1021 return status;
1022
1023 address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1024 param = options | 0x20;
1025 status = ath6kl_bmi_reg_write(ar, address, param);
1026 if (status)
1027 return status;
1028
1029 /* Configure GPIO AR6003 UART */
1030 param = CONFIG_AR600x_DEBUG_UART_TX_PIN;
1031 status = ath6kl_bmi_write(ar,
1032 ath6kl_get_hi_item_addr(ar,
1033 HI_ITEM(hi_dbg_uart_txpin)),
1034 (u8 *)&param, 4);
1035
1036 return status;
1037}
1038
1039static int ath6kl_init(struct net_device *dev)
1040{
1041 struct ath6kl *ar = ath6kl_priv(dev);
1042 int status = 0;
1043 s32 timeleft;
1044
1045 if (!ar)
1046 return -EIO;
1047
1048 /* Do we need to finish the BMI phase */
1049 if (ath6kl_bmi_done(ar)) {
1050 status = -EIO;
1051 goto ath6kl_init_done;
1052 }
1053
1054 /* Indicate that WMI is enabled (although not ready yet) */
1055 set_bit(WMI_ENABLED, &ar->flag);
1056 ar->wmi = ath6kl_wmi_init(ar);
1057 if (!ar->wmi) {
1058 ath6kl_err("failed to initialize wmi\n");
1059 status = -EIO;
1060 goto ath6kl_init_done;
1061 }
1062
1063 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
1064
1065 wlan_node_table_init(&ar->scan_table);
1066
1067 /*
1068 * The reason we have to wait for the target here is that the
1069 * driver layer has to init BMI in order to set the host block
1070 * size.
1071 */
1072 if (ath6kl_htc_wait_target(ar->htc_target)) {
1073 status = -EIO;
1074 goto err_node_cleanup;
1075 }
1076
1077 if (ath6kl_init_service_ep(ar)) {
1078 status = -EIO;
1079 goto err_cleanup_scatter;
1080 }
1081
1082 /* setup access class priority mappings */
1083 ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */
1084 ar->ac_stream_pri_map[WMM_AC_BE] = 1;
1085 ar->ac_stream_pri_map[WMM_AC_VI] = 2;
1086 ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
1087
1088 /* give our connected endpoints some buffers */
1089 ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
1090 ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
1091
1092 /* allocate some buffers that handle larger AMSDU frames */
1093 ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
1094
1095 /* setup credit distribution */
1096 ath6k_setup_credit_dist(ar->htc_target, &ar->credit_state_info);
1097
1098 ath6kl_cookie_init(ar);
1099
1100 /* start HTC */
1101 status = ath6kl_htc_start(ar->htc_target);
1102
1103 if (status) {
1104 ath6kl_cookie_cleanup(ar);
1105 goto err_rxbuf_cleanup;
1106 }
1107
1108 /* Wait for Wmi event to be ready */
1109 timeleft = wait_event_interruptible_timeout(ar->event_wq,
1110 test_bit(WMI_READY,
1111 &ar->flag),
1112 WMI_TIMEOUT);
1113
1114 if (ar->version.abi_ver != ATH6KL_ABI_VERSION) {
1115 ath6kl_err("abi version mismatch: host(0x%x), target(0x%x)\n",
1116 ATH6KL_ABI_VERSION, ar->version.abi_ver);
1117 status = -EIO;
1118 goto err_htc_stop;
1119 }
1120
1121 if (!timeleft || signal_pending(current)) {
1122 ath6kl_err("wmi is not ready or wait was interrupted\n");
1123 status = -EIO;
1124 goto err_htc_stop;
1125 }
1126
1127 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: wmi is ready\n", __func__);
1128
1129 /* communicate the wmi protocol verision to the target */
1130 if ((ath6kl_set_host_app_area(ar)) != 0)
1131 ath6kl_err("unable to set the host app area\n");
1132
1133 ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
1134 ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
1135
1136 status = ath6kl_target_config_wlan_params(ar);
1137 if (!status)
1138 goto ath6kl_init_done;
1139
1140err_htc_stop:
1141 ath6kl_htc_stop(ar->htc_target);
1142err_rxbuf_cleanup:
1143 ath6kl_htc_flush_rx_buf(ar->htc_target);
1144 ath6kl_cleanup_amsdu_rxbufs(ar);
1145err_cleanup_scatter:
1146 ath6kl_hif_cleanup_scatter(ar);
1147err_node_cleanup:
1148 wlan_node_table_cleanup(&ar->scan_table);
1149 ath6kl_wmi_shutdown(ar->wmi);
1150 clear_bit(WMI_ENABLED, &ar->flag);
1151 ar->wmi = NULL;
1152
1153ath6kl_init_done:
1154 return status;
1155}
1156
1157int ath6kl_core_init(struct ath6kl *ar)
1158{
1159 int ret = 0;
1160 struct ath6kl_bmi_target_info targ_info;
1161
1162 ar->ath6kl_wq = create_singlethread_workqueue("ath6kl");
1163 if (!ar->ath6kl_wq)
1164 return -ENOMEM;
1165
1166 ret = ath6kl_bmi_init(ar);
1167 if (ret)
1168 goto err_wq;
1169
1170 ret = ath6kl_bmi_get_target_info(ar, &targ_info);
1171 if (ret)
1172 goto err_bmi_cleanup;
1173
1174 ar->version.target_ver = le32_to_cpu(targ_info.version);
1175 ar->target_type = le32_to_cpu(targ_info.type);
1176 ar->wdev->wiphy->hw_version = le32_to_cpu(targ_info.version);
1177
1178 ret = ath6kl_configure_target(ar);
1179 if (ret)
1180 goto err_bmi_cleanup;
1181
1182 ar->htc_target = ath6kl_htc_create(ar);
1183
1184 if (!ar->htc_target) {
1185 ret = -ENOMEM;
1186 goto err_bmi_cleanup;
1187 }
1188
1189 ar->aggr_cntxt = aggr_init(ar->net_dev);
1190 if (!ar->aggr_cntxt) {
1191 ath6kl_err("failed to initialize aggr\n");
1192 ret = -ENOMEM;
1193 goto err_htc_cleanup;
1194 }
1195
1196 ret = ath6kl_init_upload(ar);
1197 if (ret)
1198 goto err_htc_cleanup;
1199
1200 ret = ath6kl_init(ar->net_dev);
1201 if (ret)
1202 goto err_htc_cleanup;
1203
1204 /* This runs the init function if registered */
1205 ret = register_netdev(ar->net_dev);
1206 if (ret) {
1207 ath6kl_err("register_netdev failed\n");
1208 ath6kl_destroy(ar->net_dev, 0);
1209 return ret;
1210 }
1211
1212 set_bit(NETDEV_REGISTERED, &ar->flag);
1213
1214 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
1215 __func__, ar->net_dev->name, ar->net_dev, ar);
1216
1217 return ret;
1218
1219err_htc_cleanup:
1220 ath6kl_htc_cleanup(ar->htc_target);
1221err_bmi_cleanup:
1222 ath6kl_bmi_cleanup(ar);
1223err_wq:
1224 destroy_workqueue(ar->ath6kl_wq);
1225 return ret;
1226}
1227
1228void ath6kl_stop_txrx(struct ath6kl *ar)
1229{
1230 struct net_device *ndev = ar->net_dev;
1231
1232 if (!ndev)
1233 return;
1234
1235 set_bit(DESTROY_IN_PROGRESS, &ar->flag);
1236
1237 if (down_interruptible(&ar->sem)) {
1238 ath6kl_err("down_interruptible failed\n");
1239 return;
1240 }
1241
1242 if (ar->wlan_pwr_state != WLAN_POWER_STATE_CUT_PWR)
1243 ath6kl_stop_endpoint(ndev, false, true);
1244
1245 clear_bit(WLAN_ENABLED, &ar->flag);
1246}
1247
1248/*
1249 * We need to differentiate between the surprise and planned removal of the
1250 * device because of the following consideration:
1251 *
1252 * - In case of surprise removal, the hcd already frees up the pending
1253 * for the device and hence there is no need to unregister the function
1254 * driver inorder to get these requests. For planned removal, the function
1255 * driver has to explicitly unregister itself to have the hcd return all the
1256 * pending requests before the data structures for the devices are freed up.
1257 * Note that as per the current implementation, the function driver will
1258 * end up releasing all the devices since there is no API to selectively
1259 * release a particular device.
1260 *
1261 * - Certain commands issued to the target can be skipped for surprise
1262 * removal since they will anyway not go through.
1263 */
1264void ath6kl_destroy(struct net_device *dev, unsigned int unregister)
1265{
1266 struct ath6kl *ar;
1267
1268 if (!dev || !ath6kl_priv(dev)) {
1269 ath6kl_err("failed to get device structure\n");
1270 return;
1271 }
1272
1273 ar = ath6kl_priv(dev);
1274
1275 destroy_workqueue(ar->ath6kl_wq);
1276
1277 if (ar->htc_target)
1278 ath6kl_htc_cleanup(ar->htc_target);
1279
1280 aggr_module_destroy(ar->aggr_cntxt);
1281
1282 ath6kl_cookie_cleanup(ar);
1283
1284 ath6kl_cleanup_amsdu_rxbufs(ar);
1285
1286 ath6kl_bmi_cleanup(ar);
1287
1288 if (unregister && test_bit(NETDEV_REGISTERED, &ar->flag)) {
1289 unregister_netdev(dev);
1290 clear_bit(NETDEV_REGISTERED, &ar->flag);
1291 }
1292
1293 free_netdev(dev);
1294
1295 wlan_node_table_cleanup(&ar->scan_table);
1296
1297 kfree(ar->fw_board);
1298 kfree(ar->fw_otp);
1299 kfree(ar->fw);
1300 kfree(ar->fw_patch);
1301
1302 ath6kl_cfg80211_deinit(ar);
1303}
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
new file mode 100644
index 00000000000..c336eae0cf4
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -0,0 +1,1337 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
18#include "hif-ops.h"
19#include "cfg80211.h"
20#include "target.h"
21#include "debug.h"
22
23struct ath6kl_sta *ath6kl_find_sta(struct ath6kl *ar, u8 *node_addr)
24{
25 struct ath6kl_sta *conn = NULL;
26 u8 i, max_conn;
27
28 max_conn = (ar->nw_type == AP_NETWORK) ? AP_MAX_NUM_STA : 0;
29
30 for (i = 0; i < max_conn; i++) {
31 if (memcmp(node_addr, ar->sta_list[i].mac, ETH_ALEN) == 0) {
32 conn = &ar->sta_list[i];
33 break;
34 }
35 }
36
37 return conn;
38}
39
40struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid)
41{
42 struct ath6kl_sta *conn = NULL;
43 u8 ctr;
44
45 for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
46 if (ar->sta_list[ctr].aid == aid) {
47 conn = &ar->sta_list[ctr];
48 break;
49 }
50 }
51 return conn;
52}
53
54static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
55 u8 ielen, u8 keymgmt, u8 ucipher, u8 auth)
56{
57 struct ath6kl_sta *sta;
58 u8 free_slot;
59
60 free_slot = aid - 1;
61
62 sta = &ar->sta_list[free_slot];
63 memcpy(sta->mac, mac, ETH_ALEN);
64 memcpy(sta->wpa_ie, wpaie, ielen);
65 sta->aid = aid;
66 sta->keymgmt = keymgmt;
67 sta->ucipher = ucipher;
68 sta->auth = auth;
69
70 ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
71 ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid);
72}
73
74static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
75{
76 struct ath6kl_sta *sta = &ar->sta_list[i];
77
78 /* empty the queued pkts in the PS queue if any */
79 spin_lock_bh(&sta->psq_lock);
80 skb_queue_purge(&sta->psq);
81 spin_unlock_bh(&sta->psq_lock);
82
83 memset(&ar->ap_stats.sta[sta->aid - 1], 0,
84 sizeof(struct wmi_per_sta_stat));
85 memset(sta->mac, 0, ETH_ALEN);
86 memset(sta->wpa_ie, 0, ATH6KL_MAX_IE);
87 sta->aid = 0;
88 sta->sta_flags = 0;
89
90 ar->sta_list_index = ar->sta_list_index & ~(1 << i);
91
92}
93
94static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason)
95{
96 u8 i, removed = 0;
97
98 if (is_zero_ether_addr(mac))
99 return removed;
100
101 if (is_broadcast_ether_addr(mac)) {
102 ath6kl_dbg(ATH6KL_DBG_TRC, "deleting all station\n");
103
104 for (i = 0; i < AP_MAX_NUM_STA; i++) {
105 if (!is_zero_ether_addr(ar->sta_list[i].mac)) {
106 ath6kl_sta_cleanup(ar, i);
107 removed = 1;
108 }
109 }
110 } else {
111 for (i = 0; i < AP_MAX_NUM_STA; i++) {
112 if (memcmp(ar->sta_list[i].mac, mac, ETH_ALEN) == 0) {
113 ath6kl_dbg(ATH6KL_DBG_TRC,
114 "deleting station %pM aid=%d reason=%d\n",
115 mac, ar->sta_list[i].aid, reason);
116 ath6kl_sta_cleanup(ar, i);
117 removed = 1;
118 break;
119 }
120 }
121 }
122
123 return removed;
124}
125
126enum htc_endpoint_id ath6kl_ac2_endpoint_id(void *devt, u8 ac)
127{
128 struct ath6kl *ar = devt;
129 return ar->ac2ep_map[ac];
130}
131
132struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar)
133{
134 struct ath6kl_cookie *cookie;
135
136 cookie = ar->cookie_list;
137 if (cookie != NULL) {
138 ar->cookie_list = cookie->arc_list_next;
139 ar->cookie_count--;
140 }
141
142 return cookie;
143}
144
145void ath6kl_cookie_init(struct ath6kl *ar)
146{
147 u32 i;
148
149 ar->cookie_list = NULL;
150 ar->cookie_count = 0;
151
152 memset(ar->cookie_mem, 0, sizeof(ar->cookie_mem));
153
154 for (i = 0; i < MAX_COOKIE_NUM; i++)
155 ath6kl_free_cookie(ar, &ar->cookie_mem[i]);
156}
157
158void ath6kl_cookie_cleanup(struct ath6kl *ar)
159{
160 ar->cookie_list = NULL;
161 ar->cookie_count = 0;
162}
163
164void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie)
165{
166 /* Insert first */
167
168 if (!ar || !cookie)
169 return;
170
171 cookie->arc_list_next = ar->cookie_list;
172 ar->cookie_list = cookie;
173 ar->cookie_count++;
174}
175
176/* set the window address register (using 4-byte register access ). */
177static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
178{
179 int status;
180 u8 addr_val[4];
181 s32 i;
182
183 /*
184 * Write bytes 1,2,3 of the register to set the upper address bytes,
185 * the LSB is written last to initiate the access cycle
186 */
187
188 for (i = 1; i <= 3; i++) {
189 /*
190 * Fill the buffer with the address byte value we want to
191 * hit 4 times.
192 */
193 memset(addr_val, ((u8 *)&addr)[i], 4);
194
195 /*
196 * Hit each byte of the register address with a 4-byte
197 * write operation to the same address, this is a harmless
198 * operation.
199 */
200 status = hif_read_write_sync(ar, reg_addr + i, addr_val,
201 4, HIF_WR_SYNC_BYTE_FIX);
202 if (status)
203 break;
204 }
205
206 if (status) {
207 ath6kl_err("failed to write initial bytes of 0x%x to window reg: 0x%X\n",
208 addr, reg_addr);
209 return status;
210 }
211
212 /*
213 * Write the address register again, this time write the whole
214 * 4-byte value. The effect here is that the LSB write causes the
215 * cycle to start, the extra 3 byte write to bytes 1,2,3 has no
216 * effect since we are writing the same values again
217 */
218 status = hif_read_write_sync(ar, reg_addr, (u8 *)(&addr),
219 4, HIF_WR_SYNC_BYTE_INC);
220
221 if (status) {
222 ath6kl_err("failed to write 0x%x to window reg: 0x%X\n",
223 addr, reg_addr);
224 return status;
225 }
226
227 return 0;
228}
229
230/*
231 * Read from the ATH6KL through its diagnostic window. No cooperation from
232 * the Target is required for this.
233 */
234int ath6kl_read_reg_diag(struct ath6kl *ar, u32 *address, u32 *data)
235{
236 int status;
237
238 /* set window register to start read cycle */
239 status = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS,
240 *address);
241
242 if (status)
243 return status;
244
245 /* read the data */
246 status = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *)data,
247 sizeof(u32), HIF_RD_SYNC_BYTE_INC);
248 if (status) {
249 ath6kl_err("failed to read from window data addr\n");
250 return status;
251 }
252
253 return status;
254}
255
256
257/*
258 * Write to the ATH6KL through its diagnostic window. No cooperation from
259 * the Target is required for this.
260 */
261static int ath6kl_write_reg_diag(struct ath6kl *ar, u32 *address, u32 *data)
262{
263 int status;
264
265 /* set write data */
266 status = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *)data,
267 sizeof(u32), HIF_WR_SYNC_BYTE_INC);
268 if (status) {
269 ath6kl_err("failed to write 0x%x to window data addr\n", *data);
270 return status;
271 }
272
273 /* set window register, which starts the write cycle */
274 return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS,
275 *address);
276}
277
278int ath6kl_access_datadiag(struct ath6kl *ar, u32 address,
279 u8 *data, u32 length, bool read)
280{
281 u32 count;
282 int status = 0;
283
284 for (count = 0; count < length; count += 4, address += 4) {
285 if (read) {
286 status = ath6kl_read_reg_diag(ar, &address,
287 (u32 *) &data[count]);
288 if (status)
289 break;
290 } else {
291 status = ath6kl_write_reg_diag(ar, &address,
292 (u32 *) &data[count]);
293 if (status)
294 break;
295 }
296 }
297
298 return status;
299}
300
301static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
302 bool wait_fot_compltn, bool cold_reset)
303{
304 int status = 0;
305 u32 address;
306 u32 data;
307
308 if (target_type != TARGET_TYPE_AR6003)
309 return;
310
311 data = cold_reset ? RESET_CONTROL_COLD_RST : RESET_CONTROL_MBOX_RST;
312
313 address = RTC_BASE_ADDRESS;
314 status = ath6kl_write_reg_diag(ar, &address, &data);
315
316 if (status)
317 ath6kl_err("failed to reset target\n");
318}
319
320void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
321 bool get_dbglogs)
322{
323 struct ath6kl *ar = ath6kl_priv(dev);
324 static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
325 bool discon_issued;
326
327 netif_stop_queue(dev);
328
329 /* disable the target and the interrupts associated with it */
330 if (test_bit(WMI_READY, &ar->flag)) {
331 discon_issued = (test_bit(CONNECTED, &ar->flag) ||
332 test_bit(CONNECT_PEND, &ar->flag));
333 ath6kl_disconnect(ar);
334 if (!keep_profile)
335 ath6kl_init_profile_info(ar);
336
337 del_timer(&ar->disconnect_timer);
338
339 clear_bit(WMI_READY, &ar->flag);
340 ath6kl_wmi_shutdown(ar->wmi);
341 clear_bit(WMI_ENABLED, &ar->flag);
342 ar->wmi = NULL;
343
344 /*
345 * After wmi_shudown all WMI events will be dropped. We
346 * need to cleanup the buffers allocated in AP mode and
347 * give disconnect notification to stack, which usually
348 * happens in the disconnect_event. Simulate the disconnect
349 * event by calling the function directly. Sometimes
350 * disconnect_event will be received when the debug logs
351 * are collected.
352 */
353 if (discon_issued)
354 ath6kl_disconnect_event(ar, DISCONNECT_CMD,
355 (ar->nw_type & AP_NETWORK) ?
356 bcast_mac : ar->bssid,
357 0, NULL, 0);
358
359 ar->user_key_ctrl = 0;
360
361 } else {
362 ath6kl_dbg(ATH6KL_DBG_TRC,
363 "%s: wmi is not ready 0x%p 0x%p\n",
364 __func__, ar, ar->wmi);
365
366 /* Shut down WMI if we have started it */
367 if (test_bit(WMI_ENABLED, &ar->flag)) {
368 ath6kl_dbg(ATH6KL_DBG_TRC,
369 "%s: shut down wmi\n", __func__);
370 ath6kl_wmi_shutdown(ar->wmi);
371 clear_bit(WMI_ENABLED, &ar->flag);
372 ar->wmi = NULL;
373 }
374 }
375
376 if (ar->htc_target) {
377 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: shut down htc\n", __func__);
378 ath6kl_htc_stop(ar->htc_target);
379 }
380
381 /*
382 * Try to reset the device if we can. The driver may have been
383 * configure NOT to reset the target during a debug session.
384 */
385 ath6kl_dbg(ATH6KL_DBG_TRC,
386 "attempting to reset target on instance destroy\n");
387 ath6kl_reset_device(ar, ar->target_type, true, true);
388}
389
390static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
391{
392 u8 index;
393 u8 keyusage;
394
395 for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
396 if (ar->wep_key_list[index].key_len) {
397 keyusage = GROUP_USAGE;
398 if (index == ar->def_txkey_index)
399 keyusage |= TX_USAGE;
400
401 ath6kl_wmi_addkey_cmd(ar->wmi,
402 index,
403 WEP_CRYPT,
404 keyusage,
405 ar->wep_key_list[index].key_len,
406 NULL,
407 ar->wep_key_list[index].key,
408 KEY_OP_INIT_VAL, NULL,
409 NO_SYNC_WMIFLAG);
410 }
411 }
412}
413
414static void ath6kl_connect_ap_mode(struct ath6kl *ar, u16 channel, u8 *bssid,
415 u16 listen_int, u16 beacon_int,
416 u8 assoc_resp_len, u8 *assoc_info)
417{
418 struct net_device *dev = ar->net_dev;
419 struct station_info sinfo;
420 struct ath6kl_req_key *ik;
421 enum crypto_type keyType = NONE_CRYPT;
422
423 if (memcmp(dev->dev_addr, bssid, ETH_ALEN) == 0) {
424 ik = &ar->ap_mode_bkey;
425
426 switch (ar->auth_mode) {
427 case NONE_AUTH:
428 if (ar->prwise_crypto == WEP_CRYPT)
429 ath6kl_install_static_wep_keys(ar);
430 break;
431 case WPA_PSK_AUTH:
432 case WPA2_PSK_AUTH:
433 case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
434 switch (ik->ik_type) {
435 case ATH6KL_CIPHER_TKIP:
436 keyType = TKIP_CRYPT;
437 break;
438 case ATH6KL_CIPHER_AES_CCM:
439 keyType = AES_CRYPT;
440 break;
441 default:
442 goto skip_key;
443 }
444 ath6kl_wmi_addkey_cmd(ar->wmi, ik->ik_keyix, keyType,
445 GROUP_USAGE, ik->ik_keylen,
446 (u8 *)&ik->ik_keyrsc,
447 ik->ik_keydata,
448 KEY_OP_INIT_VAL, ik->ik_macaddr,
449 SYNC_BOTH_WMIFLAG);
450 break;
451 }
452skip_key:
453 set_bit(CONNECTED, &ar->flag);
454 return;
455 }
456
457 ath6kl_dbg(ATH6KL_DBG_TRC, "new station %pM aid=%d\n",
458 bssid, channel);
459
460 ath6kl_add_new_sta(ar, bssid, channel, assoc_info, assoc_resp_len,
461 listen_int & 0xFF, beacon_int,
462 (listen_int >> 8) & 0xFF);
463
464 /* send event to application */
465 memset(&sinfo, 0, sizeof(sinfo));
466
467 /* TODO: sinfo.generation */
468 /* TODO: need to deliver (Re)AssocReq IEs somehow.. change in
469 * cfg80211 needed, e.g., by adding those into sinfo
470 */
471 cfg80211_new_sta(ar->net_dev, bssid, &sinfo, GFP_KERNEL);
472
473 netif_wake_queue(ar->net_dev);
474
475 return;
476}
477
478/* Functions for Tx credit handling */
479void ath6k_credit_init(struct htc_credit_state_info *cred_info,
480 struct list_head *ep_list,
481 int tot_credits)
482{
483 struct htc_endpoint_credit_dist *cur_ep_dist;
484 int count;
485
486 cred_info->cur_free_credits = tot_credits;
487 cred_info->total_avail_credits = tot_credits;
488
489 list_for_each_entry(cur_ep_dist, ep_list, list) {
490 if (cur_ep_dist->endpoint == ENDPOINT_0)
491 continue;
492
493 cur_ep_dist->cred_min = cur_ep_dist->cred_per_msg;
494
495 if (tot_credits > 4)
496 if ((cur_ep_dist->svc_id == WMI_DATA_BK_SVC) ||
497 (cur_ep_dist->svc_id == WMI_DATA_BE_SVC)) {
498 ath6kl_deposit_credit_to_ep(cred_info,
499 cur_ep_dist,
500 cur_ep_dist->cred_min);
501 cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
502 }
503
504 if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) {
505 ath6kl_deposit_credit_to_ep(cred_info, cur_ep_dist,
506 cur_ep_dist->cred_min);
507 /*
508 * Control service is always marked active, it
509 * never goes inactive EVER.
510 */
511 cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
512 } else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC)
513 /* this is the lowest priority data endpoint */
514 cred_info->lowestpri_ep_dist = cur_ep_dist->list;
515
516 /*
517 * Streams have to be created (explicit | implicit) for all
518 * kinds of traffic. BE endpoints are also inactive in the
519 * beginning. When BE traffic starts it creates implicit
520 * streams that redistributes credits.
521 *
522 * Note: all other endpoints have minimums set but are
523 * initially given NO credits. credits will be distributed
524 * as traffic activity demands
525 */
526 }
527
528 WARN_ON(cred_info->cur_free_credits <= 0);
529
530 list_for_each_entry(cur_ep_dist, ep_list, list) {
531 if (cur_ep_dist->endpoint == ENDPOINT_0)
532 continue;
533
534 if (cur_ep_dist->svc_id == WMI_CONTROL_SVC)
535 cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg;
536 else {
537 /*
538 * For the remaining data endpoints, we assume that
539 * each cred_per_msg are the same. We use a simple
540 * calculation here, we take the remaining credits
541 * and determine how many max messages this can
542 * cover and then set each endpoint's normal value
543 * equal to 3/4 this amount.
544 */
545 count = (cred_info->cur_free_credits /
546 cur_ep_dist->cred_per_msg)
547 * cur_ep_dist->cred_per_msg;
548 count = (count * 3) >> 2;
549 count = max(count, cur_ep_dist->cred_per_msg);
550 cur_ep_dist->cred_norm = count;
551
552 }
553 }
554}
555
556/* initialize and setup credit distribution */
557int ath6k_setup_credit_dist(void *htc_handle,
558 struct htc_credit_state_info *cred_info)
559{
560 u16 servicepriority[5];
561
562 memset(cred_info, 0, sizeof(struct htc_credit_state_info));
563
564 servicepriority[0] = WMI_CONTROL_SVC; /* highest */
565 servicepriority[1] = WMI_DATA_VO_SVC;
566 servicepriority[2] = WMI_DATA_VI_SVC;
567 servicepriority[3] = WMI_DATA_BE_SVC;
568 servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */
569
570 /* set priority list */
571 ath6kl_htc_set_credit_dist(htc_handle, cred_info, servicepriority, 5);
572
573 return 0;
574}
575
576/* reduce an ep's credits back to a set limit */
577static void ath6k_reduce_credits(struct htc_credit_state_info *cred_info,
578 struct htc_endpoint_credit_dist *ep_dist,
579 int limit)
580{
581 int credits;
582
583 ep_dist->cred_assngd = limit;
584
585 if (ep_dist->credits <= limit)
586 return;
587
588 credits = ep_dist->credits - limit;
589 ep_dist->credits -= credits;
590 cred_info->cur_free_credits += credits;
591}
592
593static void ath6k_credit_update(struct htc_credit_state_info *cred_info,
594 struct list_head *epdist_list)
595{
596 struct htc_endpoint_credit_dist *cur_dist_list;
597
598 list_for_each_entry(cur_dist_list, epdist_list, list) {
599 if (cur_dist_list->endpoint == ENDPOINT_0)
600 continue;
601
602 if (cur_dist_list->cred_to_dist > 0) {
603 cur_dist_list->credits +=
604 cur_dist_list->cred_to_dist;
605 cur_dist_list->cred_to_dist = 0;
606 if (cur_dist_list->credits >
607 cur_dist_list->cred_assngd)
608 ath6k_reduce_credits(cred_info,
609 cur_dist_list,
610 cur_dist_list->cred_assngd);
611
612 if (cur_dist_list->credits >
613 cur_dist_list->cred_norm)
614 ath6k_reduce_credits(cred_info, cur_dist_list,
615 cur_dist_list->cred_norm);
616
617 if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) {
618 if (cur_dist_list->txq_depth == 0)
619 ath6k_reduce_credits(cred_info,
620 cur_dist_list, 0);
621 }
622 }
623 }
624}
625
626/*
627 * HTC has an endpoint that needs credits, ep_dist is the endpoint in
628 * question.
629 */
630void ath6k_seek_credits(struct htc_credit_state_info *cred_info,
631 struct htc_endpoint_credit_dist *ep_dist)
632{
633 struct htc_endpoint_credit_dist *curdist_list;
634 int credits = 0;
635 int need;
636
637 if (ep_dist->svc_id == WMI_CONTROL_SVC)
638 goto out;
639
640 if ((ep_dist->svc_id == WMI_DATA_VI_SVC) ||
641 (ep_dist->svc_id == WMI_DATA_VO_SVC))
642 if ((ep_dist->cred_assngd >= ep_dist->cred_norm))
643 goto out;
644
645 /*
646 * For all other services, we follow a simple algorithm of:
647 *
648 * 1. checking the free pool for credits
649 * 2. checking lower priority endpoints for credits to take
650 */
651
652 credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);
653
654 if (credits >= ep_dist->seek_cred)
655 goto out;
656
657 /*
658 * We don't have enough in the free pool, try taking away from
659 * lower priority services The rule for taking away credits:
660 *
661 * 1. Only take from lower priority endpoints
662 * 2. Only take what is allocated above the minimum (never
663 * starve an endpoint completely)
664 * 3. Only take what you need.
665 */
666
667 list_for_each_entry_reverse(curdist_list,
668 &cred_info->lowestpri_ep_dist,
669 list) {
670 if (curdist_list == ep_dist)
671 break;
672
673 need = ep_dist->seek_cred - cred_info->cur_free_credits;
674
675 if ((curdist_list->cred_assngd - need) >=
676 curdist_list->cred_min) {
677 /*
678 * The current one has been allocated more than
679 * it's minimum and it has enough credits assigned
680 * above it's minimum to fulfill our need try to
681 * take away just enough to fulfill our need.
682 */
683 ath6k_reduce_credits(cred_info, curdist_list,
684 curdist_list->cred_assngd - need);
685
686 if (cred_info->cur_free_credits >=
687 ep_dist->seek_cred)
688 break;
689 }
690
691 if (curdist_list->endpoint == ENDPOINT_0)
692 break;
693 }
694
695 credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);
696
697out:
698 /* did we find some credits? */
699 if (credits)
700 ath6kl_deposit_credit_to_ep(cred_info, ep_dist, credits);
701
702 ep_dist->seek_cred = 0;
703}
704
705/* redistribute credits based on activity change */
706static void ath6k_redistribute_credits(struct htc_credit_state_info *info,
707 struct list_head *ep_dist_list)
708{
709 struct htc_endpoint_credit_dist *curdist_list;
710
711 list_for_each_entry(curdist_list, ep_dist_list, list) {
712 if (curdist_list->endpoint == ENDPOINT_0)
713 continue;
714
715 if ((curdist_list->svc_id == WMI_DATA_BK_SVC) ||
716 (curdist_list->svc_id == WMI_DATA_BE_SVC))
717 curdist_list->dist_flags |= HTC_EP_ACTIVE;
718
719 if ((curdist_list->svc_id != WMI_CONTROL_SVC) &&
720 !(curdist_list->dist_flags & HTC_EP_ACTIVE)) {
721 if (curdist_list->txq_depth == 0)
722 ath6k_reduce_credits(info,
723 curdist_list, 0);
724 else
725 ath6k_reduce_credits(info,
726 curdist_list,
727 curdist_list->cred_min);
728 }
729 }
730}
731
732/*
733 *
734 * This function is invoked whenever endpoints require credit
735 * distributions. A lock is held while this function is invoked, this
736 * function shall NOT block. The ep_dist_list is a list of distribution
737 * structures in prioritized order as defined by the call to the
738 * htc_set_credit_dist() api.
739 */
740void ath6k_credit_distribute(struct htc_credit_state_info *cred_info,
741 struct list_head *ep_dist_list,
742 enum htc_credit_dist_reason reason)
743{
744 switch (reason) {
745 case HTC_CREDIT_DIST_SEND_COMPLETE:
746 ath6k_credit_update(cred_info, ep_dist_list);
747 break;
748 case HTC_CREDIT_DIST_ACTIVITY_CHANGE:
749 ath6k_redistribute_credits(cred_info, ep_dist_list);
750 break;
751 default:
752 break;
753 }
754
755 WARN_ON(cred_info->cur_free_credits > cred_info->total_avail_credits);
756 WARN_ON(cred_info->cur_free_credits < 0);
757}
758
759void disconnect_timer_handler(unsigned long ptr)
760{
761 struct net_device *dev = (struct net_device *)ptr;
762 struct ath6kl *ar = ath6kl_priv(dev);
763
764 ath6kl_init_profile_info(ar);
765 ath6kl_disconnect(ar);
766}
767
768void ath6kl_disconnect(struct ath6kl *ar)
769{
770 if (test_bit(CONNECTED, &ar->flag) ||
771 test_bit(CONNECT_PEND, &ar->flag)) {
772 ath6kl_wmi_disconnect_cmd(ar->wmi);
773 /*
774 * Disconnect command is issued, clear the connect pending
775 * flag. The connected flag will be cleared in
776 * disconnect event notification.
777 */
778 clear_bit(CONNECT_PEND, &ar->flag);
779 }
780}
781
782/* WMI Event handlers */
783
784static const char *get_hw_id_string(u32 id)
785{
786 switch (id) {
787 case AR6003_REV1_VERSION:
788 return "1.0";
789 case AR6003_REV2_VERSION:
790 return "2.0";
791 case AR6003_REV3_VERSION:
792 return "2.1.1";
793 default:
794 return "unknown";
795 }
796}
797
798void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
799{
800 struct ath6kl *ar = devt;
801 struct net_device *dev = ar->net_dev;
802
803 memcpy(dev->dev_addr, datap, ETH_ALEN);
804 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %pM\n",
805 __func__, dev->dev_addr);
806
807 ar->version.wlan_ver = sw_ver;
808 ar->version.abi_ver = abi_ver;
809
810 snprintf(ar->wdev->wiphy->fw_version,
811 sizeof(ar->wdev->wiphy->fw_version),
812 "%u.%u.%u.%u",
813 (ar->version.wlan_ver & 0xf0000000) >> 28,
814 (ar->version.wlan_ver & 0x0f000000) >> 24,
815 (ar->version.wlan_ver & 0x00ff0000) >> 16,
816 (ar->version.wlan_ver & 0x0000ffff));
817
818 /* indicate to the waiting thread that the ready event was received */
819 set_bit(WMI_READY, &ar->flag);
820 wake_up(&ar->event_wq);
821
822 ath6kl_info("hw %s fw %s\n",
823 get_hw_id_string(ar->wdev->wiphy->hw_version),
824 ar->wdev->wiphy->fw_version);
825}
826
827void ath6kl_scan_complete_evt(struct ath6kl *ar, int status)
828{
829 ath6kl_cfg80211_scan_complete_event(ar, status);
830
831 if (!ar->usr_bss_filter)
832 ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
833
834 ath6kl_dbg(ATH6KL_DBG_WLAN_SCAN, "scan complete: %d\n", status);
835}
836
837void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
838 u16 listen_int, u16 beacon_int,
839 enum network_type net_type, u8 beacon_ie_len,
840 u8 assoc_req_len, u8 assoc_resp_len,
841 u8 *assoc_info)
842{
843 unsigned long flags;
844
845 if (ar->nw_type == AP_NETWORK) {
846 ath6kl_connect_ap_mode(ar, channel, bssid, listen_int,
847 beacon_int, assoc_resp_len,
848 assoc_info);
849 return;
850 }
851
852 ath6kl_cfg80211_connect_event(ar, channel, bssid,
853 listen_int, beacon_int,
854 net_type, beacon_ie_len,
855 assoc_req_len, assoc_resp_len,
856 assoc_info);
857
858 memcpy(ar->bssid, bssid, sizeof(ar->bssid));
859 ar->bss_ch = channel;
860
861 if ((ar->nw_type == INFRA_NETWORK))
862 ath6kl_wmi_listeninterval_cmd(ar->wmi, ar->listen_intvl_t,
863 ar->listen_intvl_b);
864
865 netif_wake_queue(ar->net_dev);
866
867 /* Update connect & link status atomically */
868 spin_lock_irqsave(&ar->lock, flags);
869 set_bit(CONNECTED, &ar->flag);
870 clear_bit(CONNECT_PEND, &ar->flag);
871 netif_carrier_on(ar->net_dev);
872 spin_unlock_irqrestore(&ar->lock, flags);
873
874 aggr_reset_state(ar->aggr_cntxt);
875 ar->reconnect_flag = 0;
876
877 if ((ar->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {
878 memset(ar->node_map, 0, sizeof(ar->node_map));
879 ar->node_num = 0;
880 ar->next_ep_id = ENDPOINT_2;
881 }
882
883 if (!ar->usr_bss_filter)
884 ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
885}
886
887void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast)
888{
889 struct ath6kl_sta *sta;
890 u8 tsc[6];
891 /*
892 * For AP case, keyid will have aid of STA which sent pkt with
893 * MIC error. Use this aid to get MAC & send it to hostapd.
894 */
895 if (ar->nw_type == AP_NETWORK) {
896 sta = ath6kl_find_sta_by_aid(ar, (keyid >> 2));
897 if (!sta)
898 return;
899
900 ath6kl_dbg(ATH6KL_DBG_TRC,
901 "ap tkip mic error received from aid=%d\n", keyid);
902
903 memset(tsc, 0, sizeof(tsc)); /* FIX: get correct TSC */
904 cfg80211_michael_mic_failure(ar->net_dev, sta->mac,
905 NL80211_KEYTYPE_PAIRWISE, keyid,
906 tsc, GFP_KERNEL);
907 } else
908 ath6kl_cfg80211_tkip_micerr_event(ar, keyid, ismcast);
909
910}
911
912static void ath6kl_update_target_stats(struct ath6kl *ar, u8 *ptr, u32 len)
913{
914 struct wmi_target_stats *tgt_stats =
915 (struct wmi_target_stats *) ptr;
916 struct target_stats *stats = &ar->target_stats;
917 struct tkip_ccmp_stats *ccmp_stats;
918 struct bss *conn_bss = NULL;
919 struct cserv_stats *c_stats;
920 u8 ac;
921
922 if (len < sizeof(*tgt_stats))
923 return;
924
925 /* update the RSSI of the connected bss */
926 if (test_bit(CONNECTED, &ar->flag)) {
927 conn_bss = ath6kl_wmi_find_node(ar->wmi, ar->bssid);
928 if (conn_bss) {
929 c_stats = &tgt_stats->cserv_stats;
930 conn_bss->ni_rssi =
931 a_sle16_to_cpu(c_stats->cs_ave_beacon_rssi);
932 conn_bss->ni_snr =
933 tgt_stats->cserv_stats.cs_ave_beacon_snr;
934 ath6kl_wmi_node_return(ar->wmi, conn_bss);
935 }
936 }
937
938 ath6kl_dbg(ATH6KL_DBG_TRC, "updating target stats\n");
939
940 stats->tx_pkt += le32_to_cpu(tgt_stats->stats.tx.pkt);
941 stats->tx_byte += le32_to_cpu(tgt_stats->stats.tx.byte);
942 stats->tx_ucast_pkt += le32_to_cpu(tgt_stats->stats.tx.ucast_pkt);
943 stats->tx_ucast_byte += le32_to_cpu(tgt_stats->stats.tx.ucast_byte);
944 stats->tx_mcast_pkt += le32_to_cpu(tgt_stats->stats.tx.mcast_pkt);
945 stats->tx_mcast_byte += le32_to_cpu(tgt_stats->stats.tx.mcast_byte);
946 stats->tx_bcast_pkt += le32_to_cpu(tgt_stats->stats.tx.bcast_pkt);
947 stats->tx_bcast_byte += le32_to_cpu(tgt_stats->stats.tx.bcast_byte);
948 stats->tx_rts_success_cnt +=
949 le32_to_cpu(tgt_stats->stats.tx.rts_success_cnt);
950
951 for (ac = 0; ac < WMM_NUM_AC; ac++)
952 stats->tx_pkt_per_ac[ac] +=
953 le32_to_cpu(tgt_stats->stats.tx.pkt_per_ac[ac]);
954
955 stats->tx_err += le32_to_cpu(tgt_stats->stats.tx.err);
956 stats->tx_fail_cnt += le32_to_cpu(tgt_stats->stats.tx.fail_cnt);
957 stats->tx_retry_cnt += le32_to_cpu(tgt_stats->stats.tx.retry_cnt);
958 stats->tx_mult_retry_cnt +=
959 le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt);
960 stats->tx_rts_fail_cnt +=
961 le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt);
962 stats->tx_ucast_rate =
963 ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate));
964
965 stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt);
966 stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte);
967 stats->rx_ucast_pkt += le32_to_cpu(tgt_stats->stats.rx.ucast_pkt);
968 stats->rx_ucast_byte += le32_to_cpu(tgt_stats->stats.rx.ucast_byte);
969 stats->rx_mcast_pkt += le32_to_cpu(tgt_stats->stats.rx.mcast_pkt);
970 stats->rx_mcast_byte += le32_to_cpu(tgt_stats->stats.rx.mcast_byte);
971 stats->rx_bcast_pkt += le32_to_cpu(tgt_stats->stats.rx.bcast_pkt);
972 stats->rx_bcast_byte += le32_to_cpu(tgt_stats->stats.rx.bcast_byte);
973 stats->rx_frgment_pkt += le32_to_cpu(tgt_stats->stats.rx.frgment_pkt);
974 stats->rx_err += le32_to_cpu(tgt_stats->stats.rx.err);
975 stats->rx_crc_err += le32_to_cpu(tgt_stats->stats.rx.crc_err);
976 stats->rx_key_cache_miss +=
977 le32_to_cpu(tgt_stats->stats.rx.key_cache_miss);
978 stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err);
979 stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame);
980 stats->rx_ucast_rate =
981 ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate));
982
983 ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats;
984
985 stats->tkip_local_mic_fail +=
986 le32_to_cpu(ccmp_stats->tkip_local_mic_fail);
987 stats->tkip_cnter_measures_invoked +=
988 le32_to_cpu(ccmp_stats->tkip_cnter_measures_invoked);
989 stats->tkip_fmt_err += le32_to_cpu(ccmp_stats->tkip_fmt_err);
990
991 stats->ccmp_fmt_err += le32_to_cpu(ccmp_stats->ccmp_fmt_err);
992 stats->ccmp_replays += le32_to_cpu(ccmp_stats->ccmp_replays);
993
994 stats->pwr_save_fail_cnt +=
995 le32_to_cpu(tgt_stats->pm_stats.pwr_save_failure_cnt);
996 stats->noise_floor_calib =
997 a_sle32_to_cpu(tgt_stats->noise_floor_calib);
998
999 stats->cs_bmiss_cnt +=
1000 le32_to_cpu(tgt_stats->cserv_stats.cs_bmiss_cnt);
1001 stats->cs_low_rssi_cnt +=
1002 le32_to_cpu(tgt_stats->cserv_stats.cs_low_rssi_cnt);
1003 stats->cs_connect_cnt +=
1004 le16_to_cpu(tgt_stats->cserv_stats.cs_connect_cnt);
1005 stats->cs_discon_cnt +=
1006 le16_to_cpu(tgt_stats->cserv_stats.cs_discon_cnt);
1007
1008 stats->cs_ave_beacon_rssi =
1009 a_sle16_to_cpu(tgt_stats->cserv_stats.cs_ave_beacon_rssi);
1010
1011 stats->cs_last_roam_msec =
1012 tgt_stats->cserv_stats.cs_last_roam_msec;
1013 stats->cs_snr = tgt_stats->cserv_stats.cs_snr;
1014 stats->cs_rssi = a_sle16_to_cpu(tgt_stats->cserv_stats.cs_rssi);
1015
1016 stats->lq_val = le32_to_cpu(tgt_stats->lq_val);
1017
1018 stats->wow_pkt_dropped +=
1019 le32_to_cpu(tgt_stats->wow_stats.wow_pkt_dropped);
1020 stats->wow_host_pkt_wakeups +=
1021 tgt_stats->wow_stats.wow_host_pkt_wakeups;
1022 stats->wow_host_evt_wakeups +=
1023 tgt_stats->wow_stats.wow_host_evt_wakeups;
1024 stats->wow_evt_discarded +=
1025 le16_to_cpu(tgt_stats->wow_stats.wow_evt_discarded);
1026
1027 if (test_bit(STATS_UPDATE_PEND, &ar->flag)) {
1028 clear_bit(STATS_UPDATE_PEND, &ar->flag);
1029 wake_up(&ar->event_wq);
1030 }
1031}
1032
1033static void ath6kl_add_le32(__le32 *var, __le32 val)
1034{
1035 *var = cpu_to_le32(le32_to_cpu(*var) + le32_to_cpu(val));
1036}
1037
1038void ath6kl_tgt_stats_event(struct ath6kl *ar, u8 *ptr, u32 len)
1039{
1040 struct wmi_ap_mode_stat *p = (struct wmi_ap_mode_stat *) ptr;
1041 struct wmi_ap_mode_stat *ap = &ar->ap_stats;
1042 struct wmi_per_sta_stat *st_ap, *st_p;
1043 u8 ac;
1044
1045 if (ar->nw_type == AP_NETWORK) {
1046 if (len < sizeof(*p))
1047 return;
1048
1049 for (ac = 0; ac < AP_MAX_NUM_STA; ac++) {
1050 st_ap = &ap->sta[ac];
1051 st_p = &p->sta[ac];
1052
1053 ath6kl_add_le32(&st_ap->tx_bytes, st_p->tx_bytes);
1054 ath6kl_add_le32(&st_ap->tx_pkts, st_p->tx_pkts);
1055 ath6kl_add_le32(&st_ap->tx_error, st_p->tx_error);
1056 ath6kl_add_le32(&st_ap->tx_discard, st_p->tx_discard);
1057 ath6kl_add_le32(&st_ap->rx_bytes, st_p->rx_bytes);
1058 ath6kl_add_le32(&st_ap->rx_pkts, st_p->rx_pkts);
1059 ath6kl_add_le32(&st_ap->rx_error, st_p->rx_error);
1060 ath6kl_add_le32(&st_ap->rx_discard, st_p->rx_discard);
1061 }
1062
1063 } else {
1064 ath6kl_update_target_stats(ar, ptr, len);
1065 }
1066}
1067
1068void ath6kl_wakeup_event(void *dev)
1069{
1070 struct ath6kl *ar = (struct ath6kl *) dev;
1071
1072 wake_up(&ar->event_wq);
1073}
1074
1075void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr)
1076{
1077 struct ath6kl *ar = (struct ath6kl *) devt;
1078
1079 ar->tx_pwr = tx_pwr;
1080 wake_up(&ar->event_wq);
1081}
1082
1083void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid)
1084{
1085 struct ath6kl_sta *conn;
1086 struct sk_buff *skb;
1087 bool psq_empty = false;
1088
1089 conn = ath6kl_find_sta_by_aid(ar, aid);
1090
1091 if (!conn)
1092 return;
1093 /*
1094 * Send out a packet queued on ps queue. When the ps queue
1095 * becomes empty update the PVB for this station.
1096 */
1097 spin_lock_bh(&conn->psq_lock);
1098 psq_empty = skb_queue_empty(&conn->psq);
1099 spin_unlock_bh(&conn->psq_lock);
1100
1101 if (psq_empty)
1102 /* TODO: Send out a NULL data frame */
1103 return;
1104
1105 spin_lock_bh(&conn->psq_lock);
1106 skb = skb_dequeue(&conn->psq);
1107 spin_unlock_bh(&conn->psq_lock);
1108
1109 conn->sta_flags |= STA_PS_POLLED;
1110 ath6kl_data_tx(skb, ar->net_dev);
1111 conn->sta_flags &= ~STA_PS_POLLED;
1112
1113 spin_lock_bh(&conn->psq_lock);
1114 psq_empty = skb_queue_empty(&conn->psq);
1115 spin_unlock_bh(&conn->psq_lock);
1116
1117 if (psq_empty)
1118 ath6kl_wmi_set_pvb_cmd(ar->wmi, conn->aid, 0);
1119}
1120
1121void ath6kl_dtimexpiry_event(struct ath6kl *ar)
1122{
1123 bool mcastq_empty = false;
1124 struct sk_buff *skb;
1125
1126 /*
1127 * If there are no associated STAs, ignore the DTIM expiry event.
1128 * There can be potential race conditions where the last associated
1129 * STA may disconnect & before the host could clear the 'Indicate
1130 * DTIM' request to the firmware, the firmware would have just
1131 * indicated a DTIM expiry event. The race is between 'clear DTIM
1132 * expiry cmd' going from the host to the firmware & the DTIM
1133 * expiry event happening from the firmware to the host.
1134 */
1135 if (!ar->sta_list_index)
1136 return;
1137
1138 spin_lock_bh(&ar->mcastpsq_lock);
1139 mcastq_empty = skb_queue_empty(&ar->mcastpsq);
1140 spin_unlock_bh(&ar->mcastpsq_lock);
1141
1142 if (mcastq_empty)
1143 return;
1144
1145 /* set the STA flag to dtim_expired for the frame to go out */
1146 set_bit(DTIM_EXPIRED, &ar->flag);
1147
1148 spin_lock_bh(&ar->mcastpsq_lock);
1149 while ((skb = skb_dequeue(&ar->mcastpsq)) != NULL) {
1150 spin_unlock_bh(&ar->mcastpsq_lock);
1151
1152 ath6kl_data_tx(skb, ar->net_dev);
1153
1154 spin_lock_bh(&ar->mcastpsq_lock);
1155 }
1156 spin_unlock_bh(&ar->mcastpsq_lock);
1157
1158 clear_bit(DTIM_EXPIRED, &ar->flag);
1159
1160 /* clear the LSB of the BitMapCtl field of the TIM IE */
1161 ath6kl_wmi_set_pvb_cmd(ar->wmi, MCAST_AID, 0);
1162}
1163
1164void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
1165 u8 assoc_resp_len, u8 *assoc_info,
1166 u16 prot_reason_status)
1167{
1168 struct bss *wmi_ssid_node = NULL;
1169 unsigned long flags;
1170
1171 if (ar->nw_type == AP_NETWORK) {
1172 if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
1173 return;
1174
1175 /* if no more associated STAs, empty the mcast PS q */
1176 if (ar->sta_list_index == 0) {
1177 spin_lock_bh(&ar->mcastpsq_lock);
1178 skb_queue_purge(&ar->mcastpsq);
1179 spin_unlock_bh(&ar->mcastpsq_lock);
1180
1181 /* clear the LSB of the TIM IE's BitMapCtl field */
1182 if (test_bit(WMI_READY, &ar->flag))
1183 ath6kl_wmi_set_pvb_cmd(ar->wmi, MCAST_AID, 0);
1184 }
1185
1186 if (!is_broadcast_ether_addr(bssid)) {
1187 /* send event to application */
1188 cfg80211_del_sta(ar->net_dev, bssid, GFP_KERNEL);
1189 }
1190
1191 clear_bit(CONNECTED, &ar->flag);
1192 return;
1193 }
1194
1195 ath6kl_cfg80211_disconnect_event(ar, reason, bssid,
1196 assoc_resp_len, assoc_info,
1197 prot_reason_status);
1198
1199 aggr_reset_state(ar->aggr_cntxt);
1200
1201 del_timer(&ar->disconnect_timer);
1202
1203 ath6kl_dbg(ATH6KL_DBG_WLAN_CONNECT,
1204 "disconnect reason is %d\n", reason);
1205
1206 /*
1207 * If the event is due to disconnect cmd from the host, only they
1208 * the target would stop trying to connect. Under any other
1209 * condition, target would keep trying to connect.
1210 */
1211 if (reason == DISCONNECT_CMD) {
1212 if (!ar->usr_bss_filter && test_bit(WMI_READY, &ar->flag))
1213 ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
1214 } else {
1215 set_bit(CONNECT_PEND, &ar->flag);
1216 if (((reason == ASSOC_FAILED) &&
1217 (prot_reason_status == 0x11)) ||
1218 ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0)
1219 && (ar->reconnect_flag == 1))) {
1220 set_bit(CONNECTED, &ar->flag);
1221 return;
1222 }
1223 }
1224
1225 if ((reason == NO_NETWORK_AVAIL) && test_bit(WMI_READY, &ar->flag)) {
1226 ath6kl_wmi_node_free(ar->wmi, bssid);
1227
1228 /*
1229 * In case any other same SSID nodes are present remove it,
1230 * since those nodes also not available now.
1231 */
1232 do {
1233 /*
1234 * Find the nodes based on SSID and remove it
1235 *
1236 * Note: This case will not work out for
1237 * Hidden-SSID
1238 */
1239 wmi_ssid_node = ath6kl_wmi_find_ssid_node(ar->wmi,
1240 ar->ssid,
1241 ar->ssid_len,
1242 false,
1243 true);
1244
1245 if (wmi_ssid_node)
1246 ath6kl_wmi_node_free(ar->wmi,
1247 wmi_ssid_node->ni_macaddr);
1248
1249 } while (wmi_ssid_node);
1250 }
1251
1252 /* update connect & link status atomically */
1253 spin_lock_irqsave(&ar->lock, flags);
1254 clear_bit(CONNECTED, &ar->flag);
1255 netif_carrier_off(ar->net_dev);
1256 spin_unlock_irqrestore(&ar->lock, flags);
1257
1258 if ((reason != CSERV_DISCONNECT) || (ar->reconnect_flag != 1))
1259 ar->reconnect_flag = 0;
1260
1261 if (reason != CSERV_DISCONNECT)
1262 ar->user_key_ctrl = 0;
1263
1264 netif_stop_queue(ar->net_dev);
1265 memset(ar->bssid, 0, sizeof(ar->bssid));
1266 ar->bss_ch = 0;
1267
1268 ath6kl_tx_data_cleanup(ar);
1269}
1270
1271static int ath6kl_open(struct net_device *dev)
1272{
1273 struct ath6kl *ar = ath6kl_priv(dev);
1274 unsigned long flags;
1275
1276 spin_lock_irqsave(&ar->lock, flags);
1277
1278 set_bit(WLAN_ENABLED, &ar->flag);
1279
1280 if (test_bit(CONNECTED, &ar->flag)) {
1281 netif_carrier_on(dev);
1282 netif_wake_queue(dev);
1283 } else
1284 netif_carrier_off(dev);
1285
1286 spin_unlock_irqrestore(&ar->lock, flags);
1287
1288 return 0;
1289}
1290
1291static int ath6kl_close(struct net_device *dev)
1292{
1293 struct ath6kl *ar = ath6kl_priv(dev);
1294
1295 netif_stop_queue(dev);
1296
1297 ath6kl_disconnect(ar);
1298
1299 if (test_bit(WMI_READY, &ar->flag)) {
1300 if (ath6kl_wmi_scanparams_cmd(ar->wmi, 0xFFFF, 0, 0, 0, 0, 0, 0,
1301 0, 0, 0))
1302 return -EIO;
1303
1304 clear_bit(WLAN_ENABLED, &ar->flag);
1305 }
1306
1307 ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED);
1308
1309 return 0;
1310}
1311
1312static struct net_device_stats *ath6kl_get_stats(struct net_device *dev)
1313{
1314 struct ath6kl *ar = ath6kl_priv(dev);
1315
1316 return &ar->net_stats;
1317}
1318
1319static struct net_device_ops ath6kl_netdev_ops = {
1320 .ndo_open = ath6kl_open,
1321 .ndo_stop = ath6kl_close,
1322 .ndo_start_xmit = ath6kl_data_tx,
1323 .ndo_get_stats = ath6kl_get_stats,
1324};
1325
1326void init_netdev(struct net_device *dev)
1327{
1328 dev->netdev_ops = &ath6kl_netdev_ops;
1329 dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
1330
1331 dev->needed_headroom = ETH_HLEN;
1332 dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) +
1333 sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH
1334 + WMI_MAX_TX_META_SZ;
1335
1336 return;
1337}
diff --git a/drivers/net/wireless/ath/ath6kl/node.c b/drivers/net/wireless/ath/ath6kl/node.c
new file mode 100644
index 00000000000..131205c610b
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/node.c
@@ -0,0 +1,234 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18#include "wmi.h"
19#include "debug.h"
20
21struct bss *wlan_node_alloc(int wh_size)
22{
23 struct bss *ni;
24
25 ni = kzalloc(sizeof(struct bss), GFP_ATOMIC);
26
27 if ((ni != NULL) && wh_size) {
28 ni->ni_buf = kmalloc(wh_size, GFP_ATOMIC);
29 if (ni->ni_buf == NULL) {
30 kfree(ni);
31 return NULL;
32 }
33 }
34
35 return ni;
36}
37
38void wlan_node_free(struct bss *ni)
39{
40 kfree(ni->ni_buf);
41 kfree(ni);
42}
43
44void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
45 const u8 *mac_addr)
46{
47 int hash;
48
49 memcpy(ni->ni_macaddr, mac_addr, ETH_ALEN);
50 hash = ATH6KL_NODE_HASH(mac_addr);
51 ni->ni_refcnt = 1;
52
53 ni->ni_tstamp = jiffies_to_msecs(jiffies);
54 ni->ni_actcnt = WLAN_NODE_INACT_CNT;
55
56 spin_lock_bh(&nt->nt_nodelock);
57
58 /* insert at the end of the node list */
59 ni->ni_list_next = NULL;
60 ni->ni_list_prev = nt->nt_node_last;
61 if (nt->nt_node_last != NULL)
62 nt->nt_node_last->ni_list_next = ni;
63
64 nt->nt_node_last = ni;
65 if (nt->nt_node_first == NULL)
66 nt->nt_node_first = ni;
67
68 /* insert into the hash list */
69 ni->ni_hash_next = nt->nt_hash[hash];
70 if (ni->ni_hash_next != NULL)
71 nt->nt_hash[hash]->ni_hash_prev = ni;
72
73 ni->ni_hash_prev = NULL;
74 nt->nt_hash[hash] = ni;
75
76 spin_unlock_bh(&nt->nt_nodelock);
77}
78
79struct bss *wlan_find_node(struct ath6kl_node_table *nt,
80 const u8 *mac_addr)
81{
82 struct bss *ni, *found_ni = NULL;
83 int hash;
84
85 spin_lock_bh(&nt->nt_nodelock);
86
87 hash = ATH6KL_NODE_HASH(mac_addr);
88 for (ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
89 if (memcmp(ni->ni_macaddr, mac_addr, ETH_ALEN) == 0) {
90 ni->ni_refcnt++;
91 found_ni = ni;
92 break;
93 }
94 }
95
96 spin_unlock_bh(&nt->nt_nodelock);
97
98 return found_ni;
99}
100
101void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni)
102{
103 int hash;
104
105 spin_lock_bh(&nt->nt_nodelock);
106
107 if (ni->ni_list_prev == NULL)
108 /* fix list head */
109 nt->nt_node_first = ni->ni_list_next;
110 else
111 ni->ni_list_prev->ni_list_next = ni->ni_list_next;
112
113 if (ni->ni_list_next == NULL)
114 /* fix list tail */
115 nt->nt_node_last = ni->ni_list_prev;
116 else
117 ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
118
119 if (ni->ni_hash_prev == NULL) {
120 /* first in list so fix the list head */
121 hash = ATH6KL_NODE_HASH(ni->ni_macaddr);
122 nt->nt_hash[hash] = ni->ni_hash_next;
123 } else {
124 ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
125 }
126
127 if (ni->ni_hash_next != NULL)
128 ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
129
130 wlan_node_free(ni);
131
132 spin_unlock_bh(&nt->nt_nodelock);
133}
134
135static void wlan_node_dec_free(struct bss *ni)
136{
137 if ((ni->ni_refcnt--) == 1)
138 wlan_node_free(ni);
139}
140
141void wlan_free_allnodes(struct ath6kl_node_table *nt)
142{
143 struct bss *ni;
144
145 while ((ni = nt->nt_node_first) != NULL)
146 wlan_node_reclaim(nt, ni);
147}
148
149void wlan_iterate_nodes(struct ath6kl_node_table *nt, void *arg)
150{
151 struct bss *ni;
152
153 spin_lock_bh(&nt->nt_nodelock);
154 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
155 ni->ni_refcnt++;
156 ath6kl_cfg80211_scan_node(arg, ni);
157 wlan_node_dec_free(ni);
158 }
159 spin_unlock_bh(&nt->nt_nodelock);
160}
161
162void wlan_node_table_init(struct ath6kl_node_table *nt)
163{
164 ath6kl_dbg(ATH6KL_DBG_WLAN_NODE, "node table = 0x%lx\n",
165 (unsigned long)nt);
166
167 memset(nt, 0, sizeof(struct ath6kl_node_table));
168
169 spin_lock_init(&nt->nt_nodelock);
170
171 nt->nt_node_age = WLAN_NODE_INACT_TIMEOUT_MSEC;
172}
173
174void wlan_refresh_inactive_nodes(struct ath6kl *ar)
175{
176 struct ath6kl_node_table *nt = &ar->scan_table;
177 struct bss *bss;
178 u32 now;
179
180 now = jiffies_to_msecs(jiffies);
181 bss = nt->nt_node_first;
182 while (bss != NULL) {
183 /* refresh all nodes except the current bss */
184 if (memcmp(ar->bssid, bss->ni_macaddr, ETH_ALEN) != 0) {
185 if (((now - bss->ni_tstamp) > nt->nt_node_age)
186 || --bss->ni_actcnt == 0) {
187 wlan_node_reclaim(nt, bss);
188 }
189 }
190 bss = bss->ni_list_next;
191 }
192}
193
194void wlan_node_table_cleanup(struct ath6kl_node_table *nt)
195{
196 wlan_free_allnodes(nt);
197}
198
199struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 * ssid,
200 u32 ssid_len, bool is_wpa2, bool match_ssid)
201{
202 struct bss *ni, *found_ni = NULL;
203 u8 *ie_ssid;
204
205 spin_lock_bh(&nt->nt_nodelock);
206
207 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
208
209 ie_ssid = ni->ni_cie.ie_ssid;
210
211 if ((ie_ssid[1] <= IEEE80211_MAX_SSID_LEN) &&
212 (memcmp(ssid, &ie_ssid[2], ssid_len) == 0)) {
213
214 if (match_ssid ||
215 (is_wpa2 && ni->ni_cie.ie_rsn != NULL) ||
216 (!is_wpa2 && ni->ni_cie.ie_wpa != NULL)) {
217 ni->ni_refcnt++;
218 found_ni = ni;
219 break;
220 }
221 }
222 }
223
224 spin_unlock_bh(&nt->nt_nodelock);
225
226 return found_ni;
227}
228
229void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni)
230{
231 spin_lock_bh(&nt->nt_nodelock);
232 wlan_node_dec_free(ni);
233 spin_unlock_bh(&nt->nt_nodelock);
234}
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
new file mode 100644
index 00000000000..34171604cbe
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -0,0 +1,912 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/mmc/card.h>
18#include <linux/mmc/mmc.h>
19#include <linux/mmc/host.h>
20#include <linux/mmc/sdio_func.h>
21#include <linux/mmc/sdio_ids.h>
22#include <linux/mmc/sdio.h>
23#include <linux/mmc/sd.h>
24#include "htc_hif.h"
25#include "hif-ops.h"
26#include "target.h"
27#include "debug.h"
28
29struct ath6kl_sdio {
30 struct sdio_func *func;
31
32 spinlock_t lock;
33
34 /* free list */
35 struct list_head bus_req_freeq;
36
37 /* available bus requests */
38 struct bus_request bus_req[BUS_REQUEST_MAX_NUM];
39
40 struct ath6kl *ar;
41 u8 *dma_buffer;
42
43 /* scatter request list head */
44 struct list_head scat_req;
45
46 spinlock_t scat_lock;
47 bool is_disabled;
48 atomic_t irq_handling;
49 const struct sdio_device_id *id;
50 struct work_struct wr_async_work;
51 struct list_head wr_asyncq;
52 spinlock_t wr_async_lock;
53};
54
55#define CMD53_ARG_READ 0
56#define CMD53_ARG_WRITE 1
57#define CMD53_ARG_BLOCK_BASIS 1
58#define CMD53_ARG_FIXED_ADDRESS 0
59#define CMD53_ARG_INCR_ADDRESS 1
60
61static inline struct ath6kl_sdio *ath6kl_sdio_priv(struct ath6kl *ar)
62{
63 return ar->hif_priv;
64}
65
66/*
67 * Macro to check if DMA buffer is WORD-aligned and DMA-able.
68 * Most host controllers assume the buffer is DMA'able and will
69 * bug-check otherwise (i.e. buffers on the stack). virt_addr_valid
70 * check fails on stack memory.
71 */
72static inline bool buf_needs_bounce(u8 *buf)
73{
74 return ((unsigned long) buf & 0x3) || !virt_addr_valid(buf);
75}
76
77static void ath6kl_sdio_set_mbox_info(struct ath6kl *ar)
78{
79 struct ath6kl_mbox_info *mbox_info = &ar->mbox_info;
80
81 /* EP1 has an extended range */
82 mbox_info->htc_addr = HIF_MBOX_BASE_ADDR;
83 mbox_info->htc_ext_addr = HIF_MBOX0_EXT_BASE_ADDR;
84 mbox_info->htc_ext_sz = HIF_MBOX0_EXT_WIDTH;
85 mbox_info->block_size = HIF_MBOX_BLOCK_SIZE;
86 mbox_info->gmbox_addr = HIF_GMBOX_BASE_ADDR;
87 mbox_info->gmbox_sz = HIF_GMBOX_WIDTH;
88}
89
90static inline void ath6kl_sdio_set_cmd53_arg(u32 *arg, u8 rw, u8 func,
91 u8 mode, u8 opcode, u32 addr,
92 u16 blksz)
93{
94 *arg = (((rw & 1) << 31) |
95 ((func & 0x7) << 28) |
96 ((mode & 1) << 27) |
97 ((opcode & 1) << 26) |
98 ((addr & 0x1FFFF) << 9) |
99 (blksz & 0x1FF));
100}
101
102static inline void ath6kl_sdio_set_cmd52_arg(u32 *arg, u8 write, u8 raw,
103 unsigned int address,
104 unsigned char val)
105{
106 const u8 func = 0;
107
108 *arg = ((write & 1) << 31) |
109 ((func & 0x7) << 28) |
110 ((raw & 1) << 27) |
111 (1 << 26) |
112 ((address & 0x1FFFF) << 9) |
113 (1 << 8) |
114 (val & 0xFF);
115}
116
117static int ath6kl_sdio_func0_cmd52_wr_byte(struct mmc_card *card,
118 unsigned int address,
119 unsigned char byte)
120{
121 struct mmc_command io_cmd;
122
123 memset(&io_cmd, 0, sizeof(io_cmd));
124 ath6kl_sdio_set_cmd52_arg(&io_cmd.arg, 1, 0, address, byte);
125 io_cmd.opcode = SD_IO_RW_DIRECT;
126 io_cmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
127
128 return mmc_wait_for_cmd(card->host, &io_cmd, 0);
129}
130
131static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
132 u8 *buf, u32 len)
133{
134 int ret = 0;
135
136 if (request & HIF_WRITE) {
137 if (addr >= HIF_MBOX_BASE_ADDR &&
138 addr <= HIF_MBOX_END_ADDR)
139 addr += (HIF_MBOX_WIDTH - len);
140
141 if (addr == HIF_MBOX0_EXT_BASE_ADDR)
142 addr += HIF_MBOX0_EXT_WIDTH - len;
143
144 if (request & HIF_FIXED_ADDRESS)
145 ret = sdio_writesb(func, addr, buf, len);
146 else
147 ret = sdio_memcpy_toio(func, addr, buf, len);
148 } else {
149 if (request & HIF_FIXED_ADDRESS)
150 ret = sdio_readsb(func, buf, addr, len);
151 else
152 ret = sdio_memcpy_fromio(func, buf, addr, len);
153 }
154
155 return ret;
156}
157
158static struct bus_request *ath6kl_sdio_alloc_busreq(struct ath6kl_sdio *ar_sdio)
159{
160 struct bus_request *bus_req;
161 unsigned long flag;
162
163 spin_lock_irqsave(&ar_sdio->lock, flag);
164
165 if (list_empty(&ar_sdio->bus_req_freeq)) {
166 spin_unlock_irqrestore(&ar_sdio->lock, flag);
167 return NULL;
168 }
169
170 bus_req = list_first_entry(&ar_sdio->bus_req_freeq,
171 struct bus_request, list);
172 list_del(&bus_req->list);
173
174 spin_unlock_irqrestore(&ar_sdio->lock, flag);
175 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: bus request 0x%p\n", __func__, bus_req);
176
177 return bus_req;
178}
179
180static void ath6kl_sdio_free_bus_req(struct ath6kl_sdio *ar_sdio,
181 struct bus_request *bus_req)
182{
183 unsigned long flag;
184
185 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: bus request 0x%p\n", __func__, bus_req);
186
187 spin_lock_irqsave(&ar_sdio->lock, flag);
188 list_add_tail(&bus_req->list, &ar_sdio->bus_req_freeq);
189 spin_unlock_irqrestore(&ar_sdio->lock, flag);
190}
191
192static void ath6kl_sdio_setup_scat_data(struct hif_scatter_req *scat_req,
193 struct mmc_data *data)
194{
195 struct scatterlist *sg;
196 int i;
197
198 data->blksz = HIF_MBOX_BLOCK_SIZE;
199 data->blocks = scat_req->len / HIF_MBOX_BLOCK_SIZE;
200
201 ath6kl_dbg(ATH6KL_DBG_SCATTER,
202 "hif-scatter: (%s) addr: 0x%X, (block len: %d, block count: %d) , (tot:%d,sg:%d)\n",
203 (scat_req->req & HIF_WRITE) ? "WR" : "RD", scat_req->addr,
204 data->blksz, data->blocks, scat_req->len,
205 scat_req->scat_entries);
206
207 data->flags = (scat_req->req & HIF_WRITE) ? MMC_DATA_WRITE :
208 MMC_DATA_READ;
209
210 /* fill SG entries */
211 sg = scat_req->sgentries;
212 sg_init_table(sg, scat_req->scat_entries);
213
214 /* assemble SG list */
215 for (i = 0; i < scat_req->scat_entries; i++, sg++) {
216 if ((unsigned long)scat_req->scat_list[i].buf & 0x3)
217 /*
218 * Some scatter engines can handle unaligned
219 * buffers, print this as informational only.
220 */
221 ath6kl_dbg(ATH6KL_DBG_SCATTER,
222 "(%s) scatter buffer is unaligned 0x%p\n",
223 scat_req->req & HIF_WRITE ? "WR" : "RD",
224 scat_req->scat_list[i].buf);
225
226 ath6kl_dbg(ATH6KL_DBG_SCATTER, "%d: addr:0x%p, len:%d\n",
227 i, scat_req->scat_list[i].buf,
228 scat_req->scat_list[i].len);
229
230 sg_set_buf(sg, scat_req->scat_list[i].buf,
231 scat_req->scat_list[i].len);
232 }
233
234 /* set scatter-gather table for request */
235 data->sg = scat_req->sgentries;
236 data->sg_len = scat_req->scat_entries;
237}
238
239static int ath6kl_sdio_scat_rw(struct ath6kl_sdio *ar_sdio,
240 struct bus_request *req)
241{
242 struct mmc_request mmc_req;
243 struct mmc_command cmd;
244 struct mmc_data data;
245 struct hif_scatter_req *scat_req;
246 u8 opcode, rw;
247 int status, len;
248
249 scat_req = req->scat_req;
250
251 if (scat_req->virt_scat) {
252 len = scat_req->len;
253 if (scat_req->req & HIF_BLOCK_BASIS)
254 len = round_down(len, HIF_MBOX_BLOCK_SIZE);
255
256 status = ath6kl_sdio_io(ar_sdio->func, scat_req->req,
257 scat_req->addr, scat_req->virt_dma_buf,
258 len);
259 goto scat_complete;
260 }
261
262 memset(&mmc_req, 0, sizeof(struct mmc_request));
263 memset(&cmd, 0, sizeof(struct mmc_command));
264 memset(&data, 0, sizeof(struct mmc_data));
265
266 ath6kl_sdio_setup_scat_data(scat_req, &data);
267
268 opcode = (scat_req->req & HIF_FIXED_ADDRESS) ?
269 CMD53_ARG_FIXED_ADDRESS : CMD53_ARG_INCR_ADDRESS;
270
271 rw = (scat_req->req & HIF_WRITE) ? CMD53_ARG_WRITE : CMD53_ARG_READ;
272
273 /* Fixup the address so that the last byte will fall on MBOX EOM */
274 if (scat_req->req & HIF_WRITE) {
275 if (scat_req->addr == HIF_MBOX_BASE_ADDR)
276 scat_req->addr += HIF_MBOX_WIDTH - scat_req->len;
277 else
278 /* Uses extended address range */
279 scat_req->addr += HIF_MBOX0_EXT_WIDTH - scat_req->len;
280 }
281
282 /* set command argument */
283 ath6kl_sdio_set_cmd53_arg(&cmd.arg, rw, ar_sdio->func->num,
284 CMD53_ARG_BLOCK_BASIS, opcode, scat_req->addr,
285 data.blocks);
286
287 cmd.opcode = SD_IO_RW_EXTENDED;
288 cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
289
290 mmc_req.cmd = &cmd;
291 mmc_req.data = &data;
292
293 mmc_set_data_timeout(&data, ar_sdio->func->card);
294 /* synchronous call to process request */
295 mmc_wait_for_req(ar_sdio->func->card->host, &mmc_req);
296
297 status = cmd.error ? cmd.error : data.error;
298
299scat_complete:
300 scat_req->status = status;
301
302 if (scat_req->status)
303 ath6kl_err("Scatter write request failed:%d\n",
304 scat_req->status);
305
306 if (scat_req->req & HIF_ASYNCHRONOUS)
307 scat_req->complete(ar_sdio->ar->htc_target, scat_req);
308
309 return status;
310}
311
312static int ath6kl_sdio_alloc_prep_scat_req(struct ath6kl_sdio *ar_sdio,
313 int n_scat_entry, int n_scat_req,
314 bool virt_scat)
315{
316 struct hif_scatter_req *s_req;
317 struct bus_request *bus_req;
318 int i, scat_req_sz, scat_list_sz, sg_sz, buf_sz;
319 u8 *virt_buf;
320
321 scat_list_sz = (n_scat_entry - 1) * sizeof(struct hif_scatter_item);
322 scat_req_sz = sizeof(*s_req) + scat_list_sz;
323
324 if (!virt_scat)
325 sg_sz = sizeof(struct scatterlist) * n_scat_entry;
326 else
327 buf_sz = 2 * L1_CACHE_BYTES +
328 ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER;
329
330 for (i = 0; i < n_scat_req; i++) {
331 /* allocate the scatter request */
332 s_req = kzalloc(scat_req_sz, GFP_KERNEL);
333 if (!s_req)
334 return -ENOMEM;
335
336 if (virt_scat) {
337 virt_buf = kzalloc(buf_sz, GFP_KERNEL);
338 if (!virt_buf) {
339 kfree(s_req);
340 return -ENOMEM;
341 }
342
343 s_req->virt_dma_buf =
344 (u8 *)L1_CACHE_ALIGN((unsigned long)virt_buf);
345 } else {
346 /* allocate sglist */
347 s_req->sgentries = kzalloc(sg_sz, GFP_KERNEL);
348
349 if (!s_req->sgentries) {
350 kfree(s_req);
351 return -ENOMEM;
352 }
353 }
354
355 /* allocate a bus request for this scatter request */
356 bus_req = ath6kl_sdio_alloc_busreq(ar_sdio);
357 if (!bus_req) {
358 kfree(s_req->sgentries);
359 kfree(s_req->virt_dma_buf);
360 kfree(s_req);
361 return -ENOMEM;
362 }
363
364 /* assign the scatter request to this bus request */
365 bus_req->scat_req = s_req;
366 s_req->busrequest = bus_req;
367
368 s_req->virt_scat = virt_scat;
369
370 /* add it to the scatter pool */
371 hif_scatter_req_add(ar_sdio->ar, s_req);
372 }
373
374 return 0;
375}
376
377static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf,
378 u32 len, u32 request)
379{
380 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
381 u8 *tbuf = NULL;
382 int ret;
383 bool bounced = false;
384
385 if (request & HIF_BLOCK_BASIS)
386 len = round_down(len, HIF_MBOX_BLOCK_SIZE);
387
388 if (buf_needs_bounce(buf)) {
389 if (!ar_sdio->dma_buffer)
390 return -ENOMEM;
391 tbuf = ar_sdio->dma_buffer;
392 memcpy(tbuf, buf, len);
393 bounced = true;
394 } else
395 tbuf = buf;
396
397 sdio_claim_host(ar_sdio->func);
398 ret = ath6kl_sdio_io(ar_sdio->func, request, addr, tbuf, len);
399 if ((request & HIF_READ) && bounced)
400 memcpy(buf, tbuf, len);
401 sdio_release_host(ar_sdio->func);
402
403 return ret;
404}
405
406static void __ath6kl_sdio_write_async(struct ath6kl_sdio *ar_sdio,
407 struct bus_request *req)
408{
409 if (req->scat_req)
410 ath6kl_sdio_scat_rw(ar_sdio, req);
411 else {
412 void *context;
413 int status;
414
415 status = ath6kl_sdio_read_write_sync(ar_sdio->ar, req->address,
416 req->buffer, req->length,
417 req->request);
418 context = req->packet;
419 ath6kl_sdio_free_bus_req(ar_sdio, req);
420 ath6kldev_rw_comp_handler(context, status);
421 }
422}
423
424static void ath6kl_sdio_write_async_work(struct work_struct *work)
425{
426 struct ath6kl_sdio *ar_sdio;
427 unsigned long flags;
428 struct bus_request *req, *tmp_req;
429
430 ar_sdio = container_of(work, struct ath6kl_sdio, wr_async_work);
431 sdio_claim_host(ar_sdio->func);
432
433 spin_lock_irqsave(&ar_sdio->wr_async_lock, flags);
434 list_for_each_entry_safe(req, tmp_req, &ar_sdio->wr_asyncq, list) {
435 list_del(&req->list);
436 spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags);
437 __ath6kl_sdio_write_async(ar_sdio, req);
438 spin_lock_irqsave(&ar_sdio->wr_async_lock, flags);
439 }
440 spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags);
441
442 sdio_release_host(ar_sdio->func);
443}
444
445static void ath6kl_sdio_irq_handler(struct sdio_func *func)
446{
447 int status;
448 struct ath6kl_sdio *ar_sdio;
449
450 ar_sdio = sdio_get_drvdata(func);
451 atomic_set(&ar_sdio->irq_handling, 1);
452
453 /*
454 * Release the host during interrups so we can pick it back up when
455 * we process commands.
456 */
457 sdio_release_host(ar_sdio->func);
458
459 status = ath6kldev_intr_bh_handler(ar_sdio->ar);
460 sdio_claim_host(ar_sdio->func);
461 atomic_set(&ar_sdio->irq_handling, 0);
462 WARN_ON(status && status != -ECANCELED);
463}
464
465static int ath6kl_sdio_power_on(struct ath6kl_sdio *ar_sdio)
466{
467 struct sdio_func *func = ar_sdio->func;
468 int ret = 0;
469
470 if (!ar_sdio->is_disabled)
471 return 0;
472
473 sdio_claim_host(func);
474
475 ret = sdio_enable_func(func);
476 if (ret) {
477 ath6kl_err("Unable to enable sdio func: %d)\n", ret);
478 sdio_release_host(func);
479 return ret;
480 }
481
482 sdio_release_host(func);
483
484 /*
485 * Wait for hardware to initialise. It should take a lot less than
486 * 10 ms but let's be conservative here.
487 */
488 msleep(10);
489
490 ar_sdio->is_disabled = false;
491
492 return ret;
493}
494
495static int ath6kl_sdio_power_off(struct ath6kl_sdio *ar_sdio)
496{
497 int ret;
498
499 if (ar_sdio->is_disabled)
500 return 0;
501
502 /* Disable the card */
503 sdio_claim_host(ar_sdio->func);
504 ret = sdio_disable_func(ar_sdio->func);
505 sdio_release_host(ar_sdio->func);
506
507 if (ret)
508 return ret;
509
510 ar_sdio->is_disabled = true;
511
512 return ret;
513}
514
515static int ath6kl_sdio_write_async(struct ath6kl *ar, u32 address, u8 *buffer,
516 u32 length, u32 request,
517 struct htc_packet *packet)
518{
519 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
520 struct bus_request *bus_req;
521 unsigned long flags;
522
523 bus_req = ath6kl_sdio_alloc_busreq(ar_sdio);
524
525 if (!bus_req)
526 return -ENOMEM;
527
528 bus_req->address = address;
529 bus_req->buffer = buffer;
530 bus_req->length = length;
531 bus_req->request = request;
532 bus_req->packet = packet;
533
534 spin_lock_irqsave(&ar_sdio->wr_async_lock, flags);
535 list_add_tail(&bus_req->list, &ar_sdio->wr_asyncq);
536 spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags);
537 queue_work(ar->ath6kl_wq, &ar_sdio->wr_async_work);
538
539 return 0;
540}
541
542static void ath6kl_sdio_irq_enable(struct ath6kl *ar)
543{
544 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
545 int ret;
546
547 sdio_claim_host(ar_sdio->func);
548
549 /* Register the isr */
550 ret = sdio_claim_irq(ar_sdio->func, ath6kl_sdio_irq_handler);
551 if (ret)
552 ath6kl_err("Failed to claim sdio irq: %d\n", ret);
553
554 sdio_release_host(ar_sdio->func);
555}
556
557static void ath6kl_sdio_irq_disable(struct ath6kl *ar)
558{
559 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
560 int ret;
561
562 sdio_claim_host(ar_sdio->func);
563
564 /* Mask our function IRQ */
565 while (atomic_read(&ar_sdio->irq_handling)) {
566 sdio_release_host(ar_sdio->func);
567 schedule_timeout(HZ / 10);
568 sdio_claim_host(ar_sdio->func);
569 }
570
571 ret = sdio_release_irq(ar_sdio->func);
572 if (ret)
573 ath6kl_err("Failed to release sdio irq: %d\n", ret);
574
575 sdio_release_host(ar_sdio->func);
576}
577
578static struct hif_scatter_req *ath6kl_sdio_scatter_req_get(struct ath6kl *ar)
579{
580 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
581 struct hif_scatter_req *node = NULL;
582 unsigned long flag;
583
584 spin_lock_irqsave(&ar_sdio->scat_lock, flag);
585
586 if (!list_empty(&ar_sdio->scat_req)) {
587 node = list_first_entry(&ar_sdio->scat_req,
588 struct hif_scatter_req, list);
589 list_del(&node->list);
590 }
591
592 spin_unlock_irqrestore(&ar_sdio->scat_lock, flag);
593
594 return node;
595}
596
597static void ath6kl_sdio_scatter_req_add(struct ath6kl *ar,
598 struct hif_scatter_req *s_req)
599{
600 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
601 unsigned long flag;
602
603 spin_lock_irqsave(&ar_sdio->scat_lock, flag);
604
605 list_add_tail(&s_req->list, &ar_sdio->scat_req);
606
607 spin_unlock_irqrestore(&ar_sdio->scat_lock, flag);
608
609}
610
611/* scatter gather read write request */
612static int ath6kl_sdio_async_rw_scatter(struct ath6kl *ar,
613 struct hif_scatter_req *scat_req)
614{
615 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
616 u32 request = scat_req->req;
617 int status = 0;
618 unsigned long flags;
619
620 if (!scat_req->len)
621 return -EINVAL;
622
623 ath6kl_dbg(ATH6KL_DBG_SCATTER,
624 "hif-scatter: total len: %d scatter entries: %d\n",
625 scat_req->len, scat_req->scat_entries);
626
627 if (request & HIF_SYNCHRONOUS) {
628 sdio_claim_host(ar_sdio->func);
629 status = ath6kl_sdio_scat_rw(ar_sdio, scat_req->busrequest);
630 sdio_release_host(ar_sdio->func);
631 } else {
632 spin_lock_irqsave(&ar_sdio->wr_async_lock, flags);
633 list_add_tail(&scat_req->busrequest->list, &ar_sdio->wr_asyncq);
634 spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags);
635 queue_work(ar->ath6kl_wq, &ar_sdio->wr_async_work);
636 }
637
638 return status;
639}
640
641/* clean up scatter support */
642static void ath6kl_sdio_cleanup_scatter(struct ath6kl *ar)
643{
644 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
645 struct hif_scatter_req *s_req, *tmp_req;
646 unsigned long flag;
647
648 /* empty the free list */
649 spin_lock_irqsave(&ar_sdio->scat_lock, flag);
650 list_for_each_entry_safe(s_req, tmp_req, &ar_sdio->scat_req, list) {
651 list_del(&s_req->list);
652 spin_unlock_irqrestore(&ar_sdio->scat_lock, flag);
653
654 if (s_req->busrequest)
655 ath6kl_sdio_free_bus_req(ar_sdio, s_req->busrequest);
656 kfree(s_req->virt_dma_buf);
657 kfree(s_req->sgentries);
658 kfree(s_req);
659
660 spin_lock_irqsave(&ar_sdio->scat_lock, flag);
661 }
662 spin_unlock_irqrestore(&ar_sdio->scat_lock, flag);
663}
664
665/* setup of HIF scatter resources */
666static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
667{
668 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
669 struct htc_target *target = ar->htc_target;
670 int ret;
671 bool virt_scat = false;
672
673 /* check if host supports scatter and it meets our requirements */
674 if (ar_sdio->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
675 ath6kl_err("host only supports scatter of :%d entries, need: %d\n",
676 ar_sdio->func->card->host->max_segs,
677 MAX_SCATTER_ENTRIES_PER_REQ);
678 virt_scat = true;
679 }
680
681 if (!virt_scat) {
682 ret = ath6kl_sdio_alloc_prep_scat_req(ar_sdio,
683 MAX_SCATTER_ENTRIES_PER_REQ,
684 MAX_SCATTER_REQUESTS, virt_scat);
685
686 if (!ret) {
687 ath6kl_dbg(ATH6KL_DBG_ANY,
688 "hif-scatter enabled: max scatter req : %d entries: %d\n",
689 MAX_SCATTER_REQUESTS,
690 MAX_SCATTER_ENTRIES_PER_REQ);
691
692 target->max_scat_entries = MAX_SCATTER_ENTRIES_PER_REQ;
693 target->max_xfer_szper_scatreq =
694 MAX_SCATTER_REQ_TRANSFER_SIZE;
695 } else {
696 ath6kl_sdio_cleanup_scatter(ar);
697 ath6kl_warn("hif scatter resource setup failed, trying virtual scatter method\n");
698 }
699 }
700
701 if (virt_scat || ret) {
702 ret = ath6kl_sdio_alloc_prep_scat_req(ar_sdio,
703 ATH6KL_SCATTER_ENTRIES_PER_REQ,
704 ATH6KL_SCATTER_REQS, virt_scat);
705
706 if (ret) {
707 ath6kl_err("failed to alloc virtual scatter resources !\n");
708 ath6kl_sdio_cleanup_scatter(ar);
709 return ret;
710 }
711
712 ath6kl_dbg(ATH6KL_DBG_ANY,
713 "Vitual scatter enabled, max_scat_req:%d, entries:%d\n",
714 ATH6KL_SCATTER_REQS, ATH6KL_SCATTER_ENTRIES_PER_REQ);
715
716 target->max_scat_entries = ATH6KL_SCATTER_ENTRIES_PER_REQ;
717 target->max_xfer_szper_scatreq =
718 ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER;
719 }
720
721 return 0;
722}
723
724static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
725 .read_write_sync = ath6kl_sdio_read_write_sync,
726 .write_async = ath6kl_sdio_write_async,
727 .irq_enable = ath6kl_sdio_irq_enable,
728 .irq_disable = ath6kl_sdio_irq_disable,
729 .scatter_req_get = ath6kl_sdio_scatter_req_get,
730 .scatter_req_add = ath6kl_sdio_scatter_req_add,
731 .enable_scatter = ath6kl_sdio_enable_scatter,
732 .scat_req_rw = ath6kl_sdio_async_rw_scatter,
733 .cleanup_scatter = ath6kl_sdio_cleanup_scatter,
734};
735
736static int ath6kl_sdio_probe(struct sdio_func *func,
737 const struct sdio_device_id *id)
738{
739 int ret;
740 struct ath6kl_sdio *ar_sdio;
741 struct ath6kl *ar;
742 int count;
743
744 ath6kl_dbg(ATH6KL_DBG_TRC,
745 "%s: func: 0x%X, vendor id: 0x%X, dev id: 0x%X, block size: 0x%X/0x%X\n",
746 __func__, func->num, func->vendor,
747 func->device, func->max_blksize, func->cur_blksize);
748
749 ar_sdio = kzalloc(sizeof(struct ath6kl_sdio), GFP_KERNEL);
750 if (!ar_sdio)
751 return -ENOMEM;
752
753 ar_sdio->dma_buffer = kzalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
754 if (!ar_sdio->dma_buffer) {
755 ret = -ENOMEM;
756 goto err_hif;
757 }
758
759 ar_sdio->func = func;
760 sdio_set_drvdata(func, ar_sdio);
761
762 ar_sdio->id = id;
763 ar_sdio->is_disabled = true;
764
765 spin_lock_init(&ar_sdio->lock);
766 spin_lock_init(&ar_sdio->scat_lock);
767 spin_lock_init(&ar_sdio->wr_async_lock);
768
769 INIT_LIST_HEAD(&ar_sdio->scat_req);
770 INIT_LIST_HEAD(&ar_sdio->bus_req_freeq);
771 INIT_LIST_HEAD(&ar_sdio->wr_asyncq);
772
773 INIT_WORK(&ar_sdio->wr_async_work, ath6kl_sdio_write_async_work);
774
775 for (count = 0; count < BUS_REQUEST_MAX_NUM; count++)
776 ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]);
777
778 ar = ath6kl_core_alloc(&ar_sdio->func->dev);
779 if (!ar) {
780 ath6kl_err("Failed to alloc ath6kl core\n");
781 ret = -ENOMEM;
782 goto err_dma;
783 }
784
785 ar_sdio->ar = ar;
786 ar->hif_priv = ar_sdio;
787 ar->hif_ops = &ath6kl_sdio_ops;
788
789 ath6kl_sdio_set_mbox_info(ar);
790
791 sdio_claim_host(func);
792
793 if ((ar_sdio->id->device & MANUFACTURER_ID_ATH6KL_BASE_MASK) >=
794 MANUFACTURER_ID_AR6003_BASE) {
795 /* enable 4-bit ASYNC interrupt on AR6003 or later */
796 ret = ath6kl_sdio_func0_cmd52_wr_byte(func->card,
797 CCCR_SDIO_IRQ_MODE_REG,
798 SDIO_IRQ_MODE_ASYNC_4BIT_IRQ);
799 if (ret) {
800 ath6kl_err("Failed to enable 4-bit async irq mode %d\n",
801 ret);
802 sdio_release_host(func);
803 goto err_dma;
804 }
805
806 ath6kl_dbg(ATH6KL_DBG_TRC, "4-bit async irq mode enabled\n");
807 }
808
809 /* give us some time to enable, in ms */
810 func->enable_timeout = 100;
811
812 sdio_release_host(func);
813
814 ret = ath6kl_sdio_power_on(ar_sdio);
815 if (ret)
816 goto err_dma;
817
818 sdio_claim_host(func);
819
820 ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
821 if (ret) {
822 ath6kl_err("Set sdio block size %d failed: %d)\n",
823 HIF_MBOX_BLOCK_SIZE, ret);
824 sdio_release_host(func);
825 goto err_off;
826 }
827
828 sdio_release_host(func);
829
830 ret = ath6kl_core_init(ar);
831 if (ret) {
832 ath6kl_err("Failed to init ath6kl core\n");
833 goto err_off;
834 }
835
836 return ret;
837
838err_off:
839 ath6kl_sdio_power_off(ar_sdio);
840err_dma:
841 kfree(ar_sdio->dma_buffer);
842err_hif:
843 kfree(ar_sdio);
844
845 return ret;
846}
847
848static void ath6kl_sdio_remove(struct sdio_func *func)
849{
850 struct ath6kl_sdio *ar_sdio;
851
852 ar_sdio = sdio_get_drvdata(func);
853
854 ath6kl_stop_txrx(ar_sdio->ar);
855 cancel_work_sync(&ar_sdio->wr_async_work);
856
857 ath6kl_unavail_ev(ar_sdio->ar);
858
859 ath6kl_sdio_power_off(ar_sdio);
860
861 kfree(ar_sdio->dma_buffer);
862 kfree(ar_sdio);
863}
864
865static const struct sdio_device_id ath6kl_sdio_devices[] = {
866 {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0))},
867 {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1))},
868 {},
869};
870
871MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices);
872
873static struct sdio_driver ath6kl_sdio_driver = {
874 .name = "ath6kl_sdio",
875 .id_table = ath6kl_sdio_devices,
876 .probe = ath6kl_sdio_probe,
877 .remove = ath6kl_sdio_remove,
878};
879
880static int __init ath6kl_sdio_init(void)
881{
882 int ret;
883
884 ret = sdio_register_driver(&ath6kl_sdio_driver);
885 if (ret)
886 ath6kl_err("sdio driver registration failed: %d\n", ret);
887
888 return ret;
889}
890
891static void __exit ath6kl_sdio_exit(void)
892{
893 sdio_unregister_driver(&ath6kl_sdio_driver);
894}
895
896module_init(ath6kl_sdio_init);
897module_exit(ath6kl_sdio_exit);
898
899MODULE_AUTHOR("Atheros Communications, Inc.");
900MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices");
901MODULE_LICENSE("Dual BSD/GPL");
902
903MODULE_FIRMWARE(AR6003_REV2_OTP_FILE);
904MODULE_FIRMWARE(AR6003_REV2_FIRMWARE_FILE);
905MODULE_FIRMWARE(AR6003_REV2_PATCH_FILE);
906MODULE_FIRMWARE(AR6003_REV2_BOARD_DATA_FILE);
907MODULE_FIRMWARE(AR6003_REV2_DEFAULT_BOARD_DATA_FILE);
908MODULE_FIRMWARE(AR6003_REV3_OTP_FILE);
909MODULE_FIRMWARE(AR6003_REV3_FIRMWARE_FILE);
910MODULE_FIRMWARE(AR6003_REV3_PATCH_FILE);
911MODULE_FIRMWARE(AR6003_REV3_BOARD_DATA_FILE);
912MODULE_FIRMWARE(AR6003_REV3_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h
new file mode 100644
index 00000000000..519a013c999
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/target.h
@@ -0,0 +1,331 @@
1/*
2 * Copyright (c) 2004-2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef TARGET_H
18#define TARGET_H
19
20#define AR6003_BOARD_DATA_SZ 1024
21#define AR6003_BOARD_EXT_DATA_SZ 768
22
23#define RESET_CONTROL_ADDRESS 0x00000000
24#define RESET_CONTROL_COLD_RST 0x00000100
25#define RESET_CONTROL_MBOX_RST 0x00000004
26
27#define CPU_CLOCK_STANDARD_S 0
28#define CPU_CLOCK_STANDARD 0x00000003
29#define CPU_CLOCK_ADDRESS 0x00000020
30
31#define CLOCK_CONTROL_ADDRESS 0x00000028
32#define CLOCK_CONTROL_LF_CLK32_S 2
33#define CLOCK_CONTROL_LF_CLK32 0x00000004
34
35#define SYSTEM_SLEEP_ADDRESS 0x000000c4
36#define SYSTEM_SLEEP_DISABLE_S 0
37#define SYSTEM_SLEEP_DISABLE 0x00000001
38
39#define LPO_CAL_ADDRESS 0x000000e0
40#define LPO_CAL_ENABLE_S 20
41#define LPO_CAL_ENABLE 0x00100000
42
43#define GPIO_PIN10_ADDRESS 0x00000050
44#define GPIO_PIN11_ADDRESS 0x00000054
45#define GPIO_PIN12_ADDRESS 0x00000058
46#define GPIO_PIN13_ADDRESS 0x0000005c
47
48#define HOST_INT_STATUS_ADDRESS 0x00000400
49#define HOST_INT_STATUS_ERROR_S 7
50#define HOST_INT_STATUS_ERROR 0x00000080
51
52#define HOST_INT_STATUS_CPU_S 6
53#define HOST_INT_STATUS_CPU 0x00000040
54
55#define HOST_INT_STATUS_COUNTER_S 4
56#define HOST_INT_STATUS_COUNTER 0x00000010
57
58#define CPU_INT_STATUS_ADDRESS 0x00000401
59
60#define ERROR_INT_STATUS_ADDRESS 0x00000402
61#define ERROR_INT_STATUS_WAKEUP_S 2
62#define ERROR_INT_STATUS_WAKEUP 0x00000004
63
64#define ERROR_INT_STATUS_RX_UNDERFLOW_S 1
65#define ERROR_INT_STATUS_RX_UNDERFLOW 0x00000002
66
67#define ERROR_INT_STATUS_TX_OVERFLOW_S 0
68#define ERROR_INT_STATUS_TX_OVERFLOW 0x00000001
69
70#define COUNTER_INT_STATUS_ADDRESS 0x00000403
71#define COUNTER_INT_STATUS_COUNTER_S 0
72#define COUNTER_INT_STATUS_COUNTER 0x000000ff
73
74#define RX_LOOKAHEAD_VALID_ADDRESS 0x00000405
75
76#define INT_STATUS_ENABLE_ADDRESS 0x00000418
77#define INT_STATUS_ENABLE_ERROR_S 7
78#define INT_STATUS_ENABLE_ERROR 0x00000080
79
80#define INT_STATUS_ENABLE_CPU_S 6
81#define INT_STATUS_ENABLE_CPU 0x00000040
82
83#define INT_STATUS_ENABLE_INT_S 5
84#define INT_STATUS_ENABLE_INT 0x00000020
85#define INT_STATUS_ENABLE_COUNTER_S 4
86#define INT_STATUS_ENABLE_COUNTER 0x00000010
87
88#define INT_STATUS_ENABLE_MBOX_DATA_S 0
89#define INT_STATUS_ENABLE_MBOX_DATA 0x0000000f
90
91#define CPU_INT_STATUS_ENABLE_ADDRESS 0x00000419
92#define CPU_INT_STATUS_ENABLE_BIT_S 0
93#define CPU_INT_STATUS_ENABLE_BIT 0x000000ff
94
95#define ERROR_STATUS_ENABLE_ADDRESS 0x0000041a
96#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_S 1
97#define ERROR_STATUS_ENABLE_RX_UNDERFLOW 0x00000002
98
99#define ERROR_STATUS_ENABLE_TX_OVERFLOW_S 0
100#define ERROR_STATUS_ENABLE_TX_OVERFLOW 0x00000001
101
102#define COUNTER_INT_STATUS_ENABLE_ADDRESS 0x0000041b
103#define COUNTER_INT_STATUS_ENABLE_BIT_S 0
104#define COUNTER_INT_STATUS_ENABLE_BIT 0x000000ff
105
106#define COUNT_ADDRESS 0x00000420
107
108#define COUNT_DEC_ADDRESS 0x00000440
109
110#define WINDOW_DATA_ADDRESS 0x00000474
111#define WINDOW_WRITE_ADDR_ADDRESS 0x00000478
112#define WINDOW_READ_ADDR_ADDRESS 0x0000047c
113#define CPU_DBG_SEL_ADDRESS 0x00000483
114#define CPU_DBG_ADDRESS 0x00000484
115
116#define LOCAL_SCRATCH_ADDRESS 0x000000c0
117#define ATH6KL_OPTION_SLEEP_DISABLE 0x08
118
119#define RTC_BASE_ADDRESS 0x00004000
120#define GPIO_BASE_ADDRESS 0x00014000
121#define MBOX_BASE_ADDRESS 0x00018000
122#define ANALOG_INTF_BASE_ADDRESS 0x0001c000
123
124/* real name of the register is unknown */
125#define ATH6KL_ANALOG_PLL_REGISTER (ANALOG_INTF_BASE_ADDRESS + 0x284)
126
127#define SM(f, v) (((v) << f##_S) & f)
128#define MS(f, v) (((v) & f) >> f##_S)
129
130/*
131 * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the
132 * host_interest structure.
133 *
134 * Host Interest is shared between Host and Target in order to coordinate
135 * between the two, and is intended to remain constant (with additions only
136 * at the end).
137 */
138#define ATH6KL_HI_START_ADDR 0x00540600
139
140/*
141 * These are items that the Host may need to access
142 * via BMI or via the Diagnostic Window. The position
143 * of items in this structure must remain constant.
144 * across firmware revisions!
145 *
146 * Types for each item must be fixed size across target and host platforms.
147 * The structure is used only to calculate offset for each register with
148 * HI_ITEM() macro, no values are stored to it.
149 *
150 * More items may be added at the end.
151 */
152struct host_interest {
153 /*
154 * Pointer to application-defined area, if any.
155 * Set by Target application during startup.
156 */
157 u32 hi_app_host_interest; /* 0x00 */
158
159 /* Pointer to register dump area, valid after Target crash. */
160 u32 hi_failure_state; /* 0x04 */
161
162 /* Pointer to debug logging header */
163 u32 hi_dbglog_hdr; /* 0x08 */
164
165 u32 hi_unused1; /* 0x0c */
166
167 /*
168 * General-purpose flag bits, similar to ATH6KL_OPTION_* flags.
169 * Can be used by application rather than by OS.
170 */
171 u32 hi_option_flag; /* 0x10 */
172
173 /*
174 * Boolean that determines whether or not to
175 * display messages on the serial port.
176 */
177 u32 hi_serial_enable; /* 0x14 */
178
179 /* Start address of DataSet index, if any */
180 u32 hi_dset_list_head; /* 0x18 */
181
182 /* Override Target application start address */
183 u32 hi_app_start; /* 0x1c */
184
185 /* Clock and voltage tuning */
186 u32 hi_skip_clock_init; /* 0x20 */
187 u32 hi_core_clock_setting; /* 0x24 */
188 u32 hi_cpu_clock_setting; /* 0x28 */
189 u32 hi_system_sleep_setting; /* 0x2c */
190 u32 hi_xtal_control_setting; /* 0x30 */
191 u32 hi_pll_ctrl_setting_24ghz; /* 0x34 */
192 u32 hi_pll_ctrl_setting_5ghz; /* 0x38 */
193 u32 hi_ref_voltage_trim_setting; /* 0x3c */
194 u32 hi_clock_info; /* 0x40 */
195
196 /*
197 * Flash configuration overrides, used only
198 * when firmware is not executing from flash.
199 * (When using flash, modify the global variables
200 * with equivalent names.)
201 */
202 u32 hi_bank0_addr_value; /* 0x44 */
203 u32 hi_bank0_read_value; /* 0x48 */
204 u32 hi_bank0_write_value; /* 0x4c */
205 u32 hi_bank0_config_value; /* 0x50 */
206
207 /* Pointer to Board Data */
208 u32 hi_board_data; /* 0x54 */
209 u32 hi_board_data_initialized; /* 0x58 */
210
211 u32 hi_dset_ram_index_tbl; /* 0x5c */
212
213 u32 hi_desired_baud_rate; /* 0x60 */
214 u32 hi_dbglog_config; /* 0x64 */
215 u32 hi_end_ram_reserve_sz; /* 0x68 */
216 u32 hi_mbox_io_block_sz; /* 0x6c */
217
218 u32 hi_num_bpatch_streams; /* 0x70 -- unused */
219 u32 hi_mbox_isr_yield_limit; /* 0x74 */
220
221 u32 hi_refclk_hz; /* 0x78 */
222 u32 hi_ext_clk_detected; /* 0x7c */
223 u32 hi_dbg_uart_txpin; /* 0x80 */
224 u32 hi_dbg_uart_rxpin; /* 0x84 */
225 u32 hi_hci_uart_baud; /* 0x88 */
226 u32 hi_hci_uart_pin_assignments; /* 0x8C */
227 /*
228 * NOTE: byte [0] = tx pin, [1] = rx pin, [2] = rts pin, [3] = cts
229 * pin
230 */
231 u32 hi_hci_uart_baud_scale_val; /* 0x90 */
232 u32 hi_hci_uart_baud_step_val; /* 0x94 */
233
234 u32 hi_allocram_start; /* 0x98 */
235 u32 hi_allocram_sz; /* 0x9c */
236 u32 hi_hci_bridge_flags; /* 0xa0 */
237 u32 hi_hci_uart_support_pins; /* 0xa4 */
238 /*
239 * NOTE: byte [0] = RESET pin (bit 7 is polarity),
240 * bytes[1]..bytes[3] are for future use
241 */
242 u32 hi_hci_uart_pwr_mgmt_params; /* 0xa8 */
243 /*
244 * 0xa8 - [1]: 0 = UART FC active low, 1 = UART FC active high
245 * [31:16]: wakeup timeout in ms
246 */
247
248 /* Pointer to extended board data */
249 u32 hi_board_ext_data; /* 0xac */
250 u32 hi_board_ext_data_config; /* 0xb0 */
251
252 /*
253 * Bit [0] : valid
254 * Bit[31:16: size
255 */
256 /*
257 * hi_reset_flag is used to do some stuff when target reset.
258 * such as restore app_start after warm reset or
259 * preserve host Interest area, or preserve ROM data, literals etc.
260 */
261 u32 hi_reset_flag; /* 0xb4 */
262 /* indicate hi_reset_flag is valid */
263 u32 hi_reset_flag_valid; /* 0xb8 */
264 u32 hi_hci_uart_pwr_mgmt_params_ext; /* 0xbc */
265 /*
266 * 0xbc - [31:0]: idle timeout in ms
267 */
268 /* ACS flags */
269 u32 hi_acs_flags; /* 0xc0 */
270 u32 hi_console_flags; /* 0xc4 */
271 u32 hi_nvram_state; /* 0xc8 */
272 u32 hi_option_flag2; /* 0xcc */
273
274 /* If non-zero, override values sent to Host in WMI_READY event. */
275 u32 hi_sw_version_override; /* 0xd0 */
276 u32 hi_abi_version_override; /* 0xd4 */
277
278 /*
279 * Percentage of high priority RX traffic to total expected RX traffic -
280 * applicable only to ar6004
281 */
282 u32 hi_hp_rx_traffic_ratio; /* 0xd8 */
283
284 /* test applications flags */
285 u32 hi_test_apps_related ; /* 0xdc */
286 /* location of test script */
287 u32 hi_ota_testscript; /* 0xe0 */
288 /* location of CAL data */
289 u32 hi_cal_data; /* 0xe4 */
290 /* Number of packet log buffers */
291 u32 hi_pktlog_num_buffers; /* 0xe8 */
292
293} __packed;
294
295#define HI_ITEM(item) offsetof(struct host_interest, item)
296
297#define HI_OPTION_MAC_ADDR_METHOD_SHIFT 3
298
299#define HI_OPTION_FW_MODE_IBSS 0x0
300#define HI_OPTION_FW_MODE_BSS_STA 0x1
301#define HI_OPTION_FW_MODE_AP 0x2
302
303#define HI_OPTION_NUM_DEV_SHIFT 0x9
304
305#define HI_OPTION_FW_BRIDGE_SHIFT 0x04
306
307/* Fw Mode/SubMode Mask
308|------------------------------------------------------------------------------|
309| SUB | SUB | SUB | SUB | | | |
310| MODE[3] | MODE[2] | MODE[1] | MODE[0] | MODE[3] | MODE[2] | MODE[1] | MODE[0|
311| (2) | (2) | (2) | (2) | (2) | (2) | (2) | (2)
312|------------------------------------------------------------------------------|
313*/
314#define HI_OPTION_FW_MODE_SHIFT 0xC
315
316/* Convert a Target virtual address into a Target physical address */
317#define TARG_VTOP(vaddr) (vaddr & 0x001fffff)
318
319#define AR6003_REV2_APP_START_OVERRIDE 0x944C00
320#define AR6003_REV2_APP_LOAD_ADDRESS 0x543180
321#define AR6003_REV2_BOARD_EXT_DATA_ADDRESS 0x57E500
322#define AR6003_REV2_DATASET_PATCH_ADDRESS 0x57e884
323#define AR6003_REV2_RAM_RESERVE_SIZE 6912
324
325#define AR6003_REV3_APP_START_OVERRIDE 0x945d00
326#define AR6003_REV3_APP_LOAD_ADDRESS 0x545000
327#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS 0x542330
328#define AR6003_REV3_DATASET_PATCH_ADDRESS 0x57FF74
329#define AR6003_REV3_RAM_RESERVE_SIZE 512
330
331#endif
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
new file mode 100644
index 00000000000..167bdb9cf68
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -0,0 +1,1457 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
18#include "debug.h"
19
20static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev,
21 u32 *map_no)
22{
23 struct ath6kl *ar = ath6kl_priv(dev);
24 struct ethhdr *eth_hdr;
25 u32 i, ep_map = -1;
26 u8 *datap;
27
28 *map_no = 0;
29 datap = skb->data;
30 eth_hdr = (struct ethhdr *) (datap + sizeof(struct wmi_data_hdr));
31
32 if (is_multicast_ether_addr(eth_hdr->h_dest))
33 return ENDPOINT_2;
34
35 for (i = 0; i < ar->node_num; i++) {
36 if (memcmp(eth_hdr->h_dest, ar->node_map[i].mac_addr,
37 ETH_ALEN) == 0) {
38 *map_no = i + 1;
39 ar->node_map[i].tx_pend++;
40 return ar->node_map[i].ep_id;
41 }
42
43 if ((ep_map == -1) && !ar->node_map[i].tx_pend)
44 ep_map = i;
45 }
46
47 if (ep_map == -1) {
48 ep_map = ar->node_num;
49 ar->node_num++;
50 if (ar->node_num > MAX_NODE_NUM)
51 return ENDPOINT_UNUSED;
52 }
53
54 memcpy(ar->node_map[ep_map].mac_addr, eth_hdr->h_dest, ETH_ALEN);
55
56 for (i = ENDPOINT_2; i <= ENDPOINT_5; i++) {
57 if (!ar->tx_pending[i]) {
58 ar->node_map[ep_map].ep_id = i;
59 break;
60 }
61
62 /*
63 * No free endpoint is available, start redistribution on
64 * the inuse endpoints.
65 */
66 if (i == ENDPOINT_5) {
67 ar->node_map[ep_map].ep_id = ar->next_ep_id;
68 ar->next_ep_id++;
69 if (ar->next_ep_id > ENDPOINT_5)
70 ar->next_ep_id = ENDPOINT_2;
71 }
72 }
73
74 *map_no = ep_map + 1;
75 ar->node_map[ep_map].tx_pend++;
76
77 return ar->node_map[ep_map].ep_id;
78}
79
80static bool ath6kl_powersave_ap(struct ath6kl *ar, struct sk_buff *skb,
81 bool *more_data)
82{
83 struct ethhdr *datap = (struct ethhdr *) skb->data;
84 struct ath6kl_sta *conn = NULL;
85 bool ps_queued = false, is_psq_empty = false;
86
87 if (is_multicast_ether_addr(datap->h_dest)) {
88 u8 ctr = 0;
89 bool q_mcast = false;
90
91 for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
92 if (ar->sta_list[ctr].sta_flags & STA_PS_SLEEP) {
93 q_mcast = true;
94 break;
95 }
96 }
97
98 if (q_mcast) {
99 /*
100 * If this transmit is not because of a Dtim Expiry
101 * q it.
102 */
103 if (!test_bit(DTIM_EXPIRED, &ar->flag)) {
104 bool is_mcastq_empty = false;
105
106 spin_lock_bh(&ar->mcastpsq_lock);
107 is_mcastq_empty =
108 skb_queue_empty(&ar->mcastpsq);
109 skb_queue_tail(&ar->mcastpsq, skb);
110 spin_unlock_bh(&ar->mcastpsq_lock);
111
112 /*
113 * If this is the first Mcast pkt getting
114 * queued indicate to the target to set the
115 * BitmapControl LSB of the TIM IE.
116 */
117 if (is_mcastq_empty)
118 ath6kl_wmi_set_pvb_cmd(ar->wmi,
119 MCAST_AID, 1);
120
121 ps_queued = true;
122 } else {
123 /*
124 * This transmit is because of Dtim expiry.
125 * Determine if MoreData bit has to be set.
126 */
127 spin_lock_bh(&ar->mcastpsq_lock);
128 if (!skb_queue_empty(&ar->mcastpsq))
129 *more_data = true;
130 spin_unlock_bh(&ar->mcastpsq_lock);
131 }
132 }
133 } else {
134 conn = ath6kl_find_sta(ar, datap->h_dest);
135 if (!conn) {
136 dev_kfree_skb(skb);
137
138 /* Inform the caller that the skb is consumed */
139 return true;
140 }
141
142 if (conn->sta_flags & STA_PS_SLEEP) {
143 if (!(conn->sta_flags & STA_PS_POLLED)) {
144 /* Queue the frames if the STA is sleeping */
145 spin_lock_bh(&conn->psq_lock);
146 is_psq_empty = skb_queue_empty(&conn->psq);
147 skb_queue_tail(&conn->psq, skb);
148 spin_unlock_bh(&conn->psq_lock);
149
150 /*
151 * If this is the first pkt getting queued
152 * for this STA, update the PVB for this
153 * STA.
154 */
155 if (is_psq_empty)
156 ath6kl_wmi_set_pvb_cmd(ar->wmi,
157 conn->aid, 1);
158
159 ps_queued = true;
160 } else {
161 /*
162 * This tx is because of a PsPoll.
163 * Determine if MoreData bit has to be set.
164 */
165 spin_lock_bh(&conn->psq_lock);
166 if (!skb_queue_empty(&conn->psq))
167 *more_data = true;
168 spin_unlock_bh(&conn->psq_lock);
169 }
170 }
171 }
172
173 return ps_queued;
174}
175
176/* Tx functions */
177
178int ath6kl_control_tx(void *devt, struct sk_buff *skb,
179 enum htc_endpoint_id eid)
180{
181 struct ath6kl *ar = devt;
182 int status = 0;
183 struct ath6kl_cookie *cookie = NULL;
184
185 spin_lock_bh(&ar->lock);
186
187 ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
188 "%s: skb=0x%p, len=0x%x eid =%d\n", __func__,
189 skb, skb->len, eid);
190
191 if (test_bit(WMI_CTRL_EP_FULL, &ar->flag) && (eid == ar->ctrl_ep)) {
192 /*
193 * Control endpoint is full, don't allocate resources, we
194 * are just going to drop this packet.
195 */
196 cookie = NULL;
197 ath6kl_err("wmi ctrl ep full, dropping pkt : 0x%p, len:%d\n",
198 skb, skb->len);
199 } else
200 cookie = ath6kl_alloc_cookie(ar);
201
202 if (cookie == NULL) {
203 spin_unlock_bh(&ar->lock);
204 status = -ENOMEM;
205 goto fail_ctrl_tx;
206 }
207
208 ar->tx_pending[eid]++;
209
210 if (eid != ar->ctrl_ep)
211 ar->total_tx_data_pend++;
212
213 spin_unlock_bh(&ar->lock);
214
215 cookie->skb = skb;
216 cookie->map_no = 0;
217 set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,
218 eid, ATH6KL_CONTROL_PKT_TAG);
219
220 /*
221 * This interface is asynchronous, if there is an error, cleanup
222 * will happen in the TX completion callback.
223 */
224 ath6kl_htc_tx(ar->htc_target, &cookie->htc_pkt);
225
226 return 0;
227
228fail_ctrl_tx:
229 dev_kfree_skb(skb);
230 return status;
231}
232
233int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
234{
235 struct ath6kl *ar = ath6kl_priv(dev);
236 struct ath6kl_cookie *cookie = NULL;
237 enum htc_endpoint_id eid = ENDPOINT_UNUSED;
238 u32 map_no = 0;
239 u16 htc_tag = ATH6KL_DATA_PKT_TAG;
240 u8 ac = 99 ; /* initialize to unmapped ac */
241 bool chk_adhoc_ps_mapping = false, more_data = false;
242 struct wmi_tx_meta_v2 meta_v2;
243 int ret;
244
245 ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
246 "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__,
247 skb, skb->data, skb->len);
248
249 /* If target is not associated */
250 if (!test_bit(CONNECTED, &ar->flag)) {
251 dev_kfree_skb(skb);
252 return 0;
253 }
254
255 if (!test_bit(WMI_READY, &ar->flag))
256 goto fail_tx;
257
258 /* AP mode Power saving processing */
259 if (ar->nw_type == AP_NETWORK) {
260 if (ath6kl_powersave_ap(ar, skb, &more_data))
261 return 0;
262 }
263
264 if (test_bit(WMI_ENABLED, &ar->flag)) {
265 memset(&meta_v2, 0, sizeof(meta_v2));
266
267 if (skb_headroom(skb) < dev->needed_headroom) {
268 WARN_ON(1);
269 goto fail_tx;
270 }
271
272 if (ath6kl_wmi_dix_2_dot3(ar->wmi, skb)) {
273 ath6kl_err("ath6kl_wmi_dix_2_dot3 failed\n");
274 goto fail_tx;
275 }
276
277 if (ath6kl_wmi_data_hdr_add(ar->wmi, skb, DATA_MSGTYPE,
278 more_data, 0, 0, NULL)) {
279 ath6kl_err("wmi_data_hdr_add failed\n");
280 goto fail_tx;
281 }
282
283 if ((ar->nw_type == ADHOC_NETWORK) &&
284 ar->ibss_ps_enable && test_bit(CONNECTED, &ar->flag))
285 chk_adhoc_ps_mapping = true;
286 else {
287 /* get the stream mapping */
288 ret = ath6kl_wmi_implicit_create_pstream(ar->wmi, skb,
289 0, test_bit(WMM_ENABLED, &ar->flag), &ac);
290 if (ret)
291 goto fail_tx;
292 }
293 } else
294 goto fail_tx;
295
296 spin_lock_bh(&ar->lock);
297
298 if (chk_adhoc_ps_mapping)
299 eid = ath6kl_ibss_map_epid(skb, dev, &map_no);
300 else
301 eid = ar->ac2ep_map[ac];
302
303 if (eid == 0 || eid == ENDPOINT_UNUSED) {
304 ath6kl_err("eid %d is not mapped!\n", eid);
305 spin_unlock_bh(&ar->lock);
306 goto fail_tx;
307 }
308
309 /* allocate resource for this packet */
310 cookie = ath6kl_alloc_cookie(ar);
311
312 if (!cookie) {
313 spin_unlock_bh(&ar->lock);
314 goto fail_tx;
315 }
316
317 /* update counts while the lock is held */
318 ar->tx_pending[eid]++;
319 ar->total_tx_data_pend++;
320
321 spin_unlock_bh(&ar->lock);
322
323 cookie->skb = skb;
324 cookie->map_no = map_no;
325 set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,
326 eid, htc_tag);
327
328 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, skb->data, skb->len);
329
330 /*
331 * HTC interface is asynchronous, if this fails, cleanup will
332 * happen in the ath6kl_tx_complete callback.
333 */
334 ath6kl_htc_tx(ar->htc_target, &cookie->htc_pkt);
335
336 return 0;
337
338fail_tx:
339 dev_kfree_skb(skb);
340
341 ar->net_stats.tx_dropped++;
342 ar->net_stats.tx_aborted_errors++;
343
344 return 0;
345}
346
347/* indicate tx activity or inactivity on a WMI stream */
348void ath6kl_indicate_tx_activity(void *devt, u8 traffic_class, bool active)
349{
350 struct ath6kl *ar = devt;
351 enum htc_endpoint_id eid;
352 int i;
353
354 eid = ar->ac2ep_map[traffic_class];
355
356 if (!test_bit(WMI_ENABLED, &ar->flag))
357 goto notify_htc;
358
359 spin_lock_bh(&ar->lock);
360
361 ar->ac_stream_active[traffic_class] = active;
362
363 if (active) {
364 /*
365 * Keep track of the active stream with the highest
366 * priority.
367 */
368 if (ar->ac_stream_pri_map[traffic_class] >
369 ar->hiac_stream_active_pri)
370 /* set the new highest active priority */
371 ar->hiac_stream_active_pri =
372 ar->ac_stream_pri_map[traffic_class];
373
374 } else {
375 /*
376 * We may have to search for the next active stream
377 * that is the highest priority.
378 */
379 if (ar->hiac_stream_active_pri ==
380 ar->ac_stream_pri_map[traffic_class]) {
381 /*
382 * The highest priority stream just went inactive
383 * reset and search for the "next" highest "active"
384 * priority stream.
385 */
386 ar->hiac_stream_active_pri = 0;
387
388 for (i = 0; i < WMM_NUM_AC; i++) {
389 if (ar->ac_stream_active[i] &&
390 (ar->ac_stream_pri_map[i] >
391 ar->hiac_stream_active_pri))
392 /*
393 * Set the new highest active
394 * priority.
395 */
396 ar->hiac_stream_active_pri =
397 ar->ac_stream_pri_map[i];
398 }
399 }
400 }
401
402 spin_unlock_bh(&ar->lock);
403
404notify_htc:
405 /* notify HTC, this may cause credit distribution changes */
406 ath6kl_htc_indicate_activity_change(ar->htc_target, eid, active);
407}
408
409enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
410 struct htc_packet *packet)
411{
412 struct ath6kl *ar = target->dev->ar;
413 enum htc_endpoint_id endpoint = packet->endpoint;
414
415 if (endpoint == ar->ctrl_ep) {
416 /*
417 * Under normal WMI if this is getting full, then something
418 * is running rampant the host should not be exhausting the
419 * WMI queue with too many commands the only exception to
420 * this is during testing using endpointping.
421 */
422 spin_lock_bh(&ar->lock);
423 set_bit(WMI_CTRL_EP_FULL, &ar->flag);
424 spin_unlock_bh(&ar->lock);
425 ath6kl_err("wmi ctrl ep is full\n");
426 return HTC_SEND_FULL_KEEP;
427 }
428
429 if (packet->info.tx.tag == ATH6KL_CONTROL_PKT_TAG)
430 return HTC_SEND_FULL_KEEP;
431
432 if (ar->nw_type == ADHOC_NETWORK)
433 /*
434 * In adhoc mode, we cannot differentiate traffic
435 * priorities so there is no need to continue, however we
436 * should stop the network.
437 */
438 goto stop_net_queues;
439
440 /*
441 * The last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for
442 * the highest active stream.
443 */
444 if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] <
445 ar->hiac_stream_active_pri &&
446 ar->cookie_count <= MAX_HI_COOKIE_NUM)
447 /*
448 * Give preference to the highest priority stream by
449 * dropping the packets which overflowed.
450 */
451 return HTC_SEND_FULL_DROP;
452
453stop_net_queues:
454 spin_lock_bh(&ar->lock);
455 set_bit(NETQ_STOPPED, &ar->flag);
456 spin_unlock_bh(&ar->lock);
457 netif_stop_queue(ar->net_dev);
458
459 return HTC_SEND_FULL_KEEP;
460}
461
462/* TODO this needs to be looked at */
463static void ath6kl_tx_clear_node_map(struct ath6kl *ar,
464 enum htc_endpoint_id eid, u32 map_no)
465{
466 u32 i;
467
468 if (ar->nw_type != ADHOC_NETWORK)
469 return;
470
471 if (!ar->ibss_ps_enable)
472 return;
473
474 if (eid == ar->ctrl_ep)
475 return;
476
477 if (map_no == 0)
478 return;
479
480 map_no--;
481 ar->node_map[map_no].tx_pend--;
482
483 if (ar->node_map[map_no].tx_pend)
484 return;
485
486 if (map_no != (ar->node_num - 1))
487 return;
488
489 for (i = ar->node_num; i > 0; i--) {
490 if (ar->node_map[i - 1].tx_pend)
491 break;
492
493 memset(&ar->node_map[i - 1], 0,
494 sizeof(struct ath6kl_node_mapping));
495 ar->node_num--;
496 }
497}
498
499void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
500{
501 struct ath6kl *ar = context;
502 struct sk_buff_head skb_queue;
503 struct htc_packet *packet;
504 struct sk_buff *skb;
505 struct ath6kl_cookie *ath6kl_cookie;
506 u32 map_no = 0;
507 int status;
508 enum htc_endpoint_id eid;
509 bool wake_event = false;
510 bool flushing = false;
511
512 skb_queue_head_init(&skb_queue);
513
514 /* lock the driver as we update internal state */
515 spin_lock_bh(&ar->lock);
516
517 /* reap completed packets */
518 while (!list_empty(packet_queue)) {
519
520 packet = list_first_entry(packet_queue, struct htc_packet,
521 list);
522 list_del(&packet->list);
523
524 ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt;
525 if (!ath6kl_cookie)
526 goto fatal;
527
528 status = packet->status;
529 skb = ath6kl_cookie->skb;
530 eid = packet->endpoint;
531 map_no = ath6kl_cookie->map_no;
532
533 if (!skb || !skb->data)
534 goto fatal;
535
536 packet->buf = skb->data;
537
538 __skb_queue_tail(&skb_queue, skb);
539
540 if (!status && (packet->act_len != skb->len))
541 goto fatal;
542
543 ar->tx_pending[eid]--;
544
545 if (eid != ar->ctrl_ep)
546 ar->total_tx_data_pend--;
547
548 if (eid == ar->ctrl_ep) {
549 if (test_bit(WMI_CTRL_EP_FULL, &ar->flag))
550 clear_bit(WMI_CTRL_EP_FULL, &ar->flag);
551
552 if (ar->tx_pending[eid] == 0)
553 wake_event = true;
554 }
555
556 if (status) {
557 if (status == -ECANCELED)
558 /* a packet was flushed */
559 flushing = true;
560
561 ar->net_stats.tx_errors++;
562
563 if (status != -ENOSPC)
564 ath6kl_err("tx error, status: 0x%x\n", status);
565 ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
566 "%s: skb=0x%p data=0x%p len=0x%x eid=%d %s\n",
567 __func__, skb, packet->buf, packet->act_len,
568 eid, "error!");
569 } else {
570 ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
571 "%s: skb=0x%p data=0x%p len=0x%x eid=%d %s\n",
572 __func__, skb, packet->buf, packet->act_len,
573 eid, "OK");
574
575 flushing = false;
576 ar->net_stats.tx_packets++;
577 ar->net_stats.tx_bytes += skb->len;
578 }
579
580 ath6kl_tx_clear_node_map(ar, eid, map_no);
581
582 ath6kl_free_cookie(ar, ath6kl_cookie);
583
584 if (test_bit(NETQ_STOPPED, &ar->flag))
585 clear_bit(NETQ_STOPPED, &ar->flag);
586 }
587
588 spin_unlock_bh(&ar->lock);
589
590 __skb_queue_purge(&skb_queue);
591
592 if (test_bit(CONNECTED, &ar->flag)) {
593 if (!flushing)
594 netif_wake_queue(ar->net_dev);
595 }
596
597 if (wake_event)
598 wake_up(&ar->event_wq);
599
600 return;
601
602fatal:
603 WARN_ON(1);
604 spin_unlock_bh(&ar->lock);
605 return;
606}
607
608void ath6kl_tx_data_cleanup(struct ath6kl *ar)
609{
610 int i;
611
612 /* flush all the data (non-control) streams */
613 for (i = 0; i < WMM_NUM_AC; i++)
614 ath6kl_htc_flush_txep(ar->htc_target, ar->ac2ep_map[i],
615 ATH6KL_DATA_PKT_TAG);
616}
617
618/* Rx functions */
619
620static void ath6kl_deliver_frames_to_nw_stack(struct net_device *dev,
621 struct sk_buff *skb)
622{
623 if (!skb)
624 return;
625
626 skb->dev = dev;
627
628 if (!(skb->dev->flags & IFF_UP)) {
629 dev_kfree_skb(skb);
630 return;
631 }
632
633 skb->protocol = eth_type_trans(skb, skb->dev);
634
635 netif_rx_ni(skb);
636}
637
638static void ath6kl_alloc_netbufs(struct sk_buff_head *q, u16 num)
639{
640 struct sk_buff *skb;
641
642 while (num) {
643 skb = ath6kl_buf_alloc(ATH6KL_BUFFER_SIZE);
644 if (!skb) {
645 ath6kl_err("netbuf allocation failed\n");
646 return;
647 }
648 skb_queue_tail(q, skb);
649 num--;
650 }
651}
652
653static struct sk_buff *aggr_get_free_skb(struct aggr_info *p_aggr)
654{
655 struct sk_buff *skb = NULL;
656
657 if (skb_queue_len(&p_aggr->free_q) < (AGGR_NUM_OF_FREE_NETBUFS >> 2))
658 ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
659
660 skb = skb_dequeue(&p_aggr->free_q);
661
662 return skb;
663}
664
665void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
666{
667 struct ath6kl *ar = target->dev->ar;
668 struct sk_buff *skb;
669 int rx_buf;
670 int n_buf_refill;
671 struct htc_packet *packet;
672 struct list_head queue;
673
674 n_buf_refill = ATH6KL_MAX_RX_BUFFERS -
675 ath6kl_htc_get_rxbuf_num(ar->htc_target, endpoint);
676
677 if (n_buf_refill <= 0)
678 return;
679
680 INIT_LIST_HEAD(&queue);
681
682 ath6kl_dbg(ATH6KL_DBG_WLAN_RX,
683 "%s: providing htc with %d buffers at eid=%d\n",
684 __func__, n_buf_refill, endpoint);
685
686 for (rx_buf = 0; rx_buf < n_buf_refill; rx_buf++) {
687 skb = ath6kl_buf_alloc(ATH6KL_BUFFER_SIZE);
688 if (!skb)
689 break;
690
691 packet = (struct htc_packet *) skb->head;
692 set_htc_rxpkt_info(packet, skb, skb->data,
693 ATH6KL_BUFFER_SIZE, endpoint);
694 list_add_tail(&packet->list, &queue);
695 }
696
697 if (!list_empty(&queue))
698 ath6kl_htc_add_rxbuf_multiple(ar->htc_target, &queue);
699}
700
701void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count)
702{
703 struct htc_packet *packet;
704 struct sk_buff *skb;
705
706 while (count) {
707 skb = ath6kl_buf_alloc(ATH6KL_AMSDU_BUFFER_SIZE);
708 if (!skb)
709 return;
710
711 packet = (struct htc_packet *) skb->head;
712 set_htc_rxpkt_info(packet, skb, skb->data,
713 ATH6KL_AMSDU_BUFFER_SIZE, 0);
714 spin_lock_bh(&ar->lock);
715 list_add_tail(&packet->list, &ar->amsdu_rx_buffer_queue);
716 spin_unlock_bh(&ar->lock);
717 count--;
718 }
719}
720
721/*
722 * Callback to allocate a receive buffer for a pending packet. We use a
723 * pre-allocated list of buffers of maximum AMSDU size (4K).
724 */
725struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
726 enum htc_endpoint_id endpoint,
727 int len)
728{
729 struct ath6kl *ar = target->dev->ar;
730 struct htc_packet *packet = NULL;
731 struct list_head *pkt_pos;
732 int refill_cnt = 0, depth = 0;
733
734 ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: eid=%d, len:%d\n",
735 __func__, endpoint, len);
736
737 if ((len <= ATH6KL_BUFFER_SIZE) ||
738 (len > ATH6KL_AMSDU_BUFFER_SIZE))
739 return NULL;
740
741 spin_lock_bh(&ar->lock);
742
743 if (list_empty(&ar->amsdu_rx_buffer_queue)) {
744 spin_unlock_bh(&ar->lock);
745 refill_cnt = ATH6KL_MAX_AMSDU_RX_BUFFERS;
746 goto refill_buf;
747 }
748
749 packet = list_first_entry(&ar->amsdu_rx_buffer_queue,
750 struct htc_packet, list);
751 list_del(&packet->list);
752 list_for_each(pkt_pos, &ar->amsdu_rx_buffer_queue)
753 depth++;
754
755 refill_cnt = ATH6KL_MAX_AMSDU_RX_BUFFERS - depth;
756 spin_unlock_bh(&ar->lock);
757
758 /* set actual endpoint ID */
759 packet->endpoint = endpoint;
760
761refill_buf:
762 if (refill_cnt >= ATH6KL_AMSDU_REFILL_THRESHOLD)
763 ath6kl_refill_amsdu_rxbufs(ar, refill_cnt);
764
765 return packet;
766}
767
768static void aggr_slice_amsdu(struct aggr_info *p_aggr,
769 struct rxtid *rxtid, struct sk_buff *skb)
770{
771 struct sk_buff *new_skb;
772 struct ethhdr *hdr;
773 u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len;
774 u8 *framep;
775
776 mac_hdr_len = sizeof(struct ethhdr);
777 framep = skb->data + mac_hdr_len;
778 amsdu_len = skb->len - mac_hdr_len;
779
780 while (amsdu_len > mac_hdr_len) {
781 hdr = (struct ethhdr *) framep;
782 payload_8023_len = ntohs(hdr->h_proto);
783
784 if (payload_8023_len < MIN_MSDU_SUBFRAME_PAYLOAD_LEN ||
785 payload_8023_len > MAX_MSDU_SUBFRAME_PAYLOAD_LEN) {
786 ath6kl_err("802.3 AMSDU frame bound check failed. len %d\n",
787 payload_8023_len);
788 break;
789 }
790
791 frame_8023_len = payload_8023_len + mac_hdr_len;
792 new_skb = aggr_get_free_skb(p_aggr);
793 if (!new_skb) {
794 ath6kl_err("no buffer available\n");
795 break;
796 }
797
798 memcpy(new_skb->data, framep, frame_8023_len);
799 skb_put(new_skb, frame_8023_len);
800 if (ath6kl_wmi_dot3_2_dix(new_skb)) {
801 ath6kl_err("dot3_2_dix error\n");
802 dev_kfree_skb(new_skb);
803 break;
804 }
805
806 skb_queue_tail(&rxtid->q, new_skb);
807
808 /* Is this the last subframe within this aggregate ? */
809 if ((amsdu_len - frame_8023_len) == 0)
810 break;
811
812 /* Add the length of A-MSDU subframe padding bytes -
813 * Round to nearest word.
814 */
815 frame_8023_len = ALIGN(frame_8023_len + 3, 3);
816
817 framep += frame_8023_len;
818 amsdu_len -= frame_8023_len;
819 }
820
821 dev_kfree_skb(skb);
822}
823
824static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
825 u16 seq_no, u8 order)
826{
827 struct sk_buff *skb;
828 struct rxtid *rxtid;
829 struct skb_hold_q *node;
830 u16 idx, idx_end, seq_end;
831 struct rxtid_stats *stats;
832
833 if (!p_aggr)
834 return;
835
836 rxtid = &p_aggr->rx_tid[tid];
837 stats = &p_aggr->stat[tid];
838
839 idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
840
841 /*
842 * idx_end is typically the last possible frame in the window,
843 * but changes to 'the' seq_no, when BAR comes. If seq_no
844 * is non-zero, we will go up to that and stop.
845 * Note: last seq no in current window will occupy the same
846 * index position as index that is just previous to start.
847 * An imp point : if win_sz is 7, for seq_no space of 4095,
848 * then, there would be holes when sequence wrap around occurs.
849 * Target should judiciously choose the win_sz, based on
850 * this condition. For 4095, (TID_WINDOW_SZ = 2 x win_sz
851 * 2, 4, 8, 16 win_sz works fine).
852 * We must deque from "idx" to "idx_end", including both.
853 */
854 seq_end = seq_no ? seq_no : rxtid->seq_next;
855 idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);
856
857 spin_lock_bh(&rxtid->lock);
858
859 do {
860 node = &rxtid->hold_q[idx];
861 if ((order == 1) && (!node->skb))
862 break;
863
864 if (node->skb) {
865 if (node->is_amsdu)
866 aggr_slice_amsdu(p_aggr, rxtid, node->skb);
867 else
868 skb_queue_tail(&rxtid->q, node->skb);
869 node->skb = NULL;
870 } else
871 stats->num_hole++;
872
873 rxtid->seq_next = ATH6KL_NEXT_SEQ_NO(rxtid->seq_next);
874 idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
875 } while (idx != idx_end);
876
877 spin_unlock_bh(&rxtid->lock);
878
879 stats->num_delivered += skb_queue_len(&rxtid->q);
880
881 while ((skb = skb_dequeue(&rxtid->q)))
882 ath6kl_deliver_frames_to_nw_stack(p_aggr->dev, skb);
883}
884
885static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
886 u16 seq_no,
887 bool is_amsdu, struct sk_buff *frame)
888{
889 struct rxtid *rxtid;
890 struct rxtid_stats *stats;
891 struct sk_buff *skb;
892 struct skb_hold_q *node;
893 u16 idx, st, cur, end;
894 bool is_queued = false;
895 u16 extended_end;
896
897 rxtid = &agg_info->rx_tid[tid];
898 stats = &agg_info->stat[tid];
899
900 stats->num_into_aggr++;
901
902 if (!rxtid->aggr) {
903 if (is_amsdu) {
904 aggr_slice_amsdu(agg_info, rxtid, frame);
905 is_queued = true;
906 stats->num_amsdu++;
907 while ((skb = skb_dequeue(&rxtid->q)))
908 ath6kl_deliver_frames_to_nw_stack(agg_info->dev,
909 skb);
910 }
911 return is_queued;
912 }
913
914 /* Check the incoming sequence no, if it's in the window */
915 st = rxtid->seq_next;
916 cur = seq_no;
917 end = (st + rxtid->hold_q_sz-1) & ATH6KL_MAX_SEQ_NO;
918
919 if (((st < end) && (cur < st || cur > end)) ||
920 ((st > end) && (cur > end) && (cur < st))) {
921 extended_end = (end + rxtid->hold_q_sz - 1) &
922 ATH6KL_MAX_SEQ_NO;
923
924 if (((end < extended_end) &&
925 (cur < end || cur > extended_end)) ||
926 ((end > extended_end) && (cur > extended_end) &&
927 (cur < end))) {
928 aggr_deque_frms(agg_info, tid, 0, 0);
929 if (cur >= rxtid->hold_q_sz - 1)
930 rxtid->seq_next = cur - (rxtid->hold_q_sz - 1);
931 else
932 rxtid->seq_next = ATH6KL_MAX_SEQ_NO -
933 (rxtid->hold_q_sz - 2 - cur);
934 } else {
935 /*
936 * Dequeue only those frames that are outside the
937 * new shifted window.
938 */
939 if (cur >= rxtid->hold_q_sz - 1)
940 st = cur - (rxtid->hold_q_sz - 1);
941 else
942 st = ATH6KL_MAX_SEQ_NO -
943 (rxtid->hold_q_sz - 2 - cur);
944
945 aggr_deque_frms(agg_info, tid, st, 0);
946 }
947
948 stats->num_oow++;
949 }
950
951 idx = AGGR_WIN_IDX(seq_no, rxtid->hold_q_sz);
952
953 node = &rxtid->hold_q[idx];
954
955 spin_lock_bh(&rxtid->lock);
956
957 /*
958 * Is the cur frame duplicate or something beyond our window(hold_q
959 * -> which is 2x, already)?
960 *
961 * 1. Duplicate is easy - drop incoming frame.
962 * 2. Not falling in current sliding window.
963 * 2a. is the frame_seq_no preceding current tid_seq_no?
964 * -> drop the frame. perhaps sender did not get our ACK.
965 * this is taken care of above.
966 * 2b. is the frame_seq_no beyond window(st, TID_WINDOW_SZ);
967 * -> Taken care of it above, by moving window forward.
968 */
969 dev_kfree_skb(node->skb);
970 stats->num_dups++;
971
972 node->skb = frame;
973 is_queued = true;
974 node->is_amsdu = is_amsdu;
975 node->seq_no = seq_no;
976
977 if (node->is_amsdu)
978 stats->num_amsdu++;
979 else
980 stats->num_mpdu++;
981
982 spin_unlock_bh(&rxtid->lock);
983
984 aggr_deque_frms(agg_info, tid, 0, 1);
985
986 if (agg_info->timer_scheduled)
987 rxtid->progress = true;
988 else
989 for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
990 if (rxtid->hold_q[idx].skb) {
991 /*
992 * There is a frame in the queue and no
993 * timer so start a timer to ensure that
994 * the frame doesn't remain stuck
995 * forever.
996 */
997 agg_info->timer_scheduled = true;
998 mod_timer(&agg_info->timer,
999 (jiffies +
1000 HZ * (AGGR_RX_TIMEOUT) / 1000));
1001 rxtid->progress = false;
1002 rxtid->timer_mon = true;
1003 break;
1004 }
1005 }
1006
1007 return is_queued;
1008}
1009
1010void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
1011{
1012 struct ath6kl *ar = target->dev->ar;
1013 struct sk_buff *skb = packet->pkt_cntxt;
1014 struct wmi_rx_meta_v2 *meta;
1015 struct wmi_data_hdr *dhdr;
1016 int min_hdr_len;
1017 u8 meta_type, dot11_hdr = 0;
1018 int status = packet->status;
1019 enum htc_endpoint_id ept = packet->endpoint;
1020 bool is_amsdu, prev_ps, ps_state = false;
1021 struct ath6kl_sta *conn = NULL;
1022 struct sk_buff *skb1 = NULL;
1023 struct ethhdr *datap = NULL;
1024 u16 seq_no, offset;
1025 u8 tid;
1026
1027 ath6kl_dbg(ATH6KL_DBG_WLAN_RX,
1028 "%s: ar=0x%p eid=%d, skb=0x%p, data=0x%p, len=0x%x status:%d",
1029 __func__, ar, ept, skb, packet->buf,
1030 packet->act_len, status);
1031
1032 if (status || !(skb->data + HTC_HDR_LENGTH)) {
1033 ar->net_stats.rx_errors++;
1034 dev_kfree_skb(skb);
1035 return;
1036 }
1037
1038 /*
1039 * Take lock to protect buffer counts and adaptive power throughput
1040 * state.
1041 */
1042 spin_lock_bh(&ar->lock);
1043
1044 ar->net_stats.rx_packets++;
1045 ar->net_stats.rx_bytes += packet->act_len;
1046
1047 skb_put(skb, packet->act_len + HTC_HDR_LENGTH);
1048 skb_pull(skb, HTC_HDR_LENGTH);
1049
1050 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, skb->data, skb->len);
1051
1052 spin_unlock_bh(&ar->lock);
1053
1054 skb->dev = ar->net_dev;
1055
1056 if (!test_bit(WMI_ENABLED, &ar->flag)) {
1057 if (EPPING_ALIGNMENT_PAD > 0)
1058 skb_pull(skb, EPPING_ALIGNMENT_PAD);
1059 ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb);
1060 return;
1061 }
1062
1063 if (ept == ar->ctrl_ep) {
1064 ath6kl_wmi_control_rx(ar->wmi, skb);
1065 return;
1066 }
1067
1068 min_hdr_len = sizeof(struct ethhdr);
1069 min_hdr_len += sizeof(struct wmi_data_hdr) +
1070 sizeof(struct ath6kl_llc_snap_hdr);
1071
1072 dhdr = (struct wmi_data_hdr *) skb->data;
1073
1074 /*
1075 * In the case of AP mode we may receive NULL data frames
1076 * that do not have LLC hdr. They are 16 bytes in size.
1077 * Allow these frames in the AP mode.
1078 */
1079 if (ar->nw_type != AP_NETWORK &&
1080 ((packet->act_len < min_hdr_len) ||
1081 (packet->act_len > WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH))) {
1082 ath6kl_info("frame len is too short or too long\n");
1083 ar->net_stats.rx_errors++;
1084 ar->net_stats.rx_length_errors++;
1085 dev_kfree_skb(skb);
1086 return;
1087 }
1088
1089 /* Get the Power save state of the STA */
1090 if (ar->nw_type == AP_NETWORK) {
1091 meta_type = wmi_data_hdr_get_meta(dhdr);
1092
1093 ps_state = !!((dhdr->info >> WMI_DATA_HDR_PS_SHIFT) &
1094 WMI_DATA_HDR_PS_MASK);
1095
1096 offset = sizeof(struct wmi_data_hdr);
1097
1098 switch (meta_type) {
1099 case 0:
1100 break;
1101 case WMI_META_VERSION_1:
1102 offset += sizeof(struct wmi_rx_meta_v1);
1103 break;
1104 case WMI_META_VERSION_2:
1105 offset += sizeof(struct wmi_rx_meta_v2);
1106 break;
1107 default:
1108 break;
1109 }
1110
1111 datap = (struct ethhdr *) (skb->data + offset);
1112 conn = ath6kl_find_sta(ar, datap->h_source);
1113
1114 if (!conn) {
1115 dev_kfree_skb(skb);
1116 return;
1117 }
1118
1119 /*
1120 * If there is a change in PS state of the STA,
1121 * take appropriate steps:
1122 *
1123 * 1. If Sleep-->Awake, flush the psq for the STA
1124 * Clear the PVB for the STA.
1125 * 2. If Awake-->Sleep, Starting queueing frames
1126 * the STA.
1127 */
1128 prev_ps = !!(conn->sta_flags & STA_PS_SLEEP);
1129
1130 if (ps_state)
1131 conn->sta_flags |= STA_PS_SLEEP;
1132 else
1133 conn->sta_flags &= ~STA_PS_SLEEP;
1134
1135 if (prev_ps ^ !!(conn->sta_flags & STA_PS_SLEEP)) {
1136 if (!(conn->sta_flags & STA_PS_SLEEP)) {
1137 struct sk_buff *skbuff = NULL;
1138
1139 spin_lock_bh(&conn->psq_lock);
1140 while ((skbuff = skb_dequeue(&conn->psq))
1141 != NULL) {
1142 spin_unlock_bh(&conn->psq_lock);
1143 ath6kl_data_tx(skbuff, ar->net_dev);
1144 spin_lock_bh(&conn->psq_lock);
1145 }
1146 spin_unlock_bh(&conn->psq_lock);
1147 /* Clear the PVB for this STA */
1148 ath6kl_wmi_set_pvb_cmd(ar->wmi, conn->aid, 0);
1149 }
1150 }
1151
1152 /* drop NULL data frames here */
1153 if ((packet->act_len < min_hdr_len) ||
1154 (packet->act_len >
1155 WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH)) {
1156 dev_kfree_skb(skb);
1157 return;
1158 }
1159 }
1160
1161 is_amsdu = wmi_data_hdr_is_amsdu(dhdr) ? true : false;
1162 tid = wmi_data_hdr_get_up(dhdr);
1163 seq_no = wmi_data_hdr_get_seqno(dhdr);
1164 meta_type = wmi_data_hdr_get_meta(dhdr);
1165 dot11_hdr = wmi_data_hdr_get_dot11(dhdr);
1166
1167 ath6kl_wmi_data_hdr_remove(ar->wmi, skb);
1168
1169 switch (meta_type) {
1170 case WMI_META_VERSION_1:
1171 skb_pull(skb, sizeof(struct wmi_rx_meta_v1));
1172 break;
1173 case WMI_META_VERSION_2:
1174 meta = (struct wmi_rx_meta_v2 *) skb->data;
1175 if (meta->csum_flags & 0x1) {
1176 skb->ip_summed = CHECKSUM_COMPLETE;
1177 skb->csum = (__force __wsum) meta->csum;
1178 }
1179 skb_pull(skb, sizeof(struct wmi_rx_meta_v2));
1180 break;
1181 default:
1182 break;
1183 }
1184
1185 if (dot11_hdr)
1186 status = ath6kl_wmi_dot11_hdr_remove(ar->wmi, skb);
1187 else if (!is_amsdu)
1188 status = ath6kl_wmi_dot3_2_dix(skb);
1189
1190 if (status) {
1191 /*
1192 * Drop frames that could not be processed (lack of
1193 * memory, etc.)
1194 */
1195 dev_kfree_skb(skb);
1196 return;
1197 }
1198
1199 if (!(ar->net_dev->flags & IFF_UP)) {
1200 dev_kfree_skb(skb);
1201 return;
1202 }
1203
1204 if (ar->nw_type == AP_NETWORK) {
1205 datap = (struct ethhdr *) skb->data;
1206 if (is_multicast_ether_addr(datap->h_dest))
1207 /*
1208 * Bcast/Mcast frames should be sent to the
1209 * OS stack as well as on the air.
1210 */
1211 skb1 = skb_copy(skb, GFP_ATOMIC);
1212 else {
1213 /*
1214 * Search for a connected STA with dstMac
1215 * as the Mac address. If found send the
1216 * frame to it on the air else send the
1217 * frame up the stack.
1218 */
1219 struct ath6kl_sta *conn = NULL;
1220 conn = ath6kl_find_sta(ar, datap->h_dest);
1221
1222 if (conn && ar->intra_bss) {
1223 skb1 = skb;
1224 skb = NULL;
1225 } else if (conn && !ar->intra_bss) {
1226 dev_kfree_skb(skb);
1227 skb = NULL;
1228 }
1229 }
1230 if (skb1)
1231 ath6kl_data_tx(skb1, ar->net_dev);
1232 }
1233
1234 if (!aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no,
1235 is_amsdu, skb))
1236 ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb);
1237}
1238
1239static void aggr_timeout(unsigned long arg)
1240{
1241 u8 i, j;
1242 struct aggr_info *p_aggr = (struct aggr_info *) arg;
1243 struct rxtid *rxtid;
1244 struct rxtid_stats *stats;
1245
1246 for (i = 0; i < NUM_OF_TIDS; i++) {
1247 rxtid = &p_aggr->rx_tid[i];
1248 stats = &p_aggr->stat[i];
1249
1250 if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress)
1251 continue;
1252
1253 /*
1254 * FIXME: these timeouts happen quite fruently, something
1255 * line once within 60 seconds. Investigate why.
1256 */
1257 stats->num_timeouts++;
1258 ath6kl_dbg(ATH6KL_DBG_AGGR,
1259 "aggr timeout (st %d end %d)\n",
1260 rxtid->seq_next,
1261 ((rxtid->seq_next + rxtid->hold_q_sz-1) &
1262 ATH6KL_MAX_SEQ_NO));
1263 aggr_deque_frms(p_aggr, i, 0, 0);
1264 }
1265
1266 p_aggr->timer_scheduled = false;
1267
1268 for (i = 0; i < NUM_OF_TIDS; i++) {
1269 rxtid = &p_aggr->rx_tid[i];
1270
1271 if (rxtid->aggr && rxtid->hold_q) {
1272 for (j = 0; j < rxtid->hold_q_sz; j++) {
1273 if (rxtid->hold_q[j].skb) {
1274 p_aggr->timer_scheduled = true;
1275 rxtid->timer_mon = true;
1276 rxtid->progress = false;
1277 break;
1278 }
1279 }
1280
1281 if (j >= rxtid->hold_q_sz)
1282 rxtid->timer_mon = false;
1283 }
1284 }
1285
1286 if (p_aggr->timer_scheduled)
1287 mod_timer(&p_aggr->timer,
1288 jiffies + msecs_to_jiffies(AGGR_RX_TIMEOUT));
1289}
1290
1291static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
1292{
1293 struct rxtid *rxtid;
1294 struct rxtid_stats *stats;
1295
1296 if (!p_aggr || tid >= NUM_OF_TIDS)
1297 return;
1298
1299 rxtid = &p_aggr->rx_tid[tid];
1300 stats = &p_aggr->stat[tid];
1301
1302 if (rxtid->aggr)
1303 aggr_deque_frms(p_aggr, tid, 0, 0);
1304
1305 rxtid->aggr = false;
1306 rxtid->progress = false;
1307 rxtid->timer_mon = false;
1308 rxtid->win_sz = 0;
1309 rxtid->seq_next = 0;
1310 rxtid->hold_q_sz = 0;
1311
1312 kfree(rxtid->hold_q);
1313 rxtid->hold_q = NULL;
1314
1315 memset(stats, 0, sizeof(struct rxtid_stats));
1316}
1317
1318void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no, u8 win_sz)
1319{
1320 struct aggr_info *p_aggr = ar->aggr_cntxt;
1321 struct rxtid *rxtid;
1322 struct rxtid_stats *stats;
1323 u16 hold_q_size;
1324
1325 if (!p_aggr)
1326 return;
1327
1328 rxtid = &p_aggr->rx_tid[tid];
1329 stats = &p_aggr->stat[tid];
1330
1331 if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX)
1332 ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n",
1333 __func__, win_sz, tid);
1334
1335 if (rxtid->aggr)
1336 aggr_delete_tid_state(p_aggr, tid);
1337
1338 rxtid->seq_next = seq_no;
1339 hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q);
1340 rxtid->hold_q = kzalloc(hold_q_size, GFP_KERNEL);
1341 if (!rxtid->hold_q)
1342 return;
1343
1344 rxtid->win_sz = win_sz;
1345 rxtid->hold_q_sz = TID_WINDOW_SZ(win_sz);
1346 if (!skb_queue_empty(&rxtid->q))
1347 return;
1348
1349 rxtid->aggr = true;
1350}
1351
1352struct aggr_info *aggr_init(struct net_device *dev)
1353{
1354 struct aggr_info *p_aggr = NULL;
1355 struct rxtid *rxtid;
1356 u8 i;
1357
1358 p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL);
1359 if (!p_aggr) {
1360 ath6kl_err("failed to alloc memory for aggr_node\n");
1361 return NULL;
1362 }
1363
1364 p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
1365 p_aggr->dev = dev;
1366 init_timer(&p_aggr->timer);
1367 p_aggr->timer.function = aggr_timeout;
1368 p_aggr->timer.data = (unsigned long) p_aggr;
1369
1370 p_aggr->timer_scheduled = false;
1371 skb_queue_head_init(&p_aggr->free_q);
1372
1373 ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
1374
1375 for (i = 0; i < NUM_OF_TIDS; i++) {
1376 rxtid = &p_aggr->rx_tid[i];
1377 rxtid->aggr = false;
1378 rxtid->progress = false;
1379 rxtid->timer_mon = false;
1380 skb_queue_head_init(&rxtid->q);
1381 spin_lock_init(&rxtid->lock);
1382 }
1383
1384 return p_aggr;
1385}
1386
1387void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid)
1388{
1389 struct aggr_info *p_aggr = ar->aggr_cntxt;
1390 struct rxtid *rxtid;
1391
1392 if (!p_aggr)
1393 return;
1394
1395 rxtid = &p_aggr->rx_tid[tid];
1396
1397 if (rxtid->aggr)
1398 aggr_delete_tid_state(p_aggr, tid);
1399}
1400
1401void aggr_reset_state(struct aggr_info *aggr_info)
1402{
1403 u8 tid;
1404
1405 for (tid = 0; tid < NUM_OF_TIDS; tid++)
1406 aggr_delete_tid_state(aggr_info, tid);
1407}
1408
1409/* clean up our amsdu buffer list */
1410void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar)
1411{
1412 struct htc_packet *packet, *tmp_pkt;
1413
1414 spin_lock_bh(&ar->lock);
1415 if (list_empty(&ar->amsdu_rx_buffer_queue)) {
1416 spin_unlock_bh(&ar->lock);
1417 return;
1418 }
1419
1420 list_for_each_entry_safe(packet, tmp_pkt, &ar->amsdu_rx_buffer_queue,
1421 list) {
1422 list_del(&packet->list);
1423 spin_unlock_bh(&ar->lock);
1424 dev_kfree_skb(packet->pkt_cntxt);
1425 spin_lock_bh(&ar->lock);
1426 }
1427
1428 spin_unlock_bh(&ar->lock);
1429}
1430
1431void aggr_module_destroy(struct aggr_info *aggr_info)
1432{
1433 struct rxtid *rxtid;
1434 u8 i, k;
1435
1436 if (!aggr_info)
1437 return;
1438
1439 if (aggr_info->timer_scheduled) {
1440 del_timer(&aggr_info->timer);
1441 aggr_info->timer_scheduled = false;
1442 }
1443
1444 for (i = 0; i < NUM_OF_TIDS; i++) {
1445 rxtid = &aggr_info->rx_tid[i];
1446 if (rxtid->hold_q) {
1447 for (k = 0; k < rxtid->hold_q_sz; k++)
1448 dev_kfree_skb(rxtid->hold_q[k].skb);
1449 kfree(rxtid->hold_q);
1450 }
1451
1452 skb_queue_purge(&rxtid->q);
1453 }
1454
1455 skb_queue_purge(&aggr_info->free_q);
1456 kfree(aggr_info);
1457}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
new file mode 100644
index 00000000000..f5aa33dd4c4
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -0,0 +1,2743 @@
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/ip.h>
18#include "core.h"
19#include "debug.h"
20
21static int ath6kl_wmi_sync_point(struct wmi *wmi);
22
23static const s32 wmi_rate_tbl[][2] = {
24 /* {W/O SGI, with SGI} */
25 {1000, 1000},
26 {2000, 2000},
27 {5500, 5500},
28 {11000, 11000},
29 {6000, 6000},
30 {9000, 9000},
31 {12000, 12000},
32 {18000, 18000},
33 {24000, 24000},
34 {36000, 36000},
35 {48000, 48000},
36 {54000, 54000},
37 {6500, 7200},
38 {13000, 14400},
39 {19500, 21700},
40 {26000, 28900},
41 {39000, 43300},
42 {52000, 57800},
43 {58500, 65000},
44 {65000, 72200},
45 {13500, 15000},
46 {27000, 30000},
47 {40500, 45000},
48 {54000, 60000},
49 {81000, 90000},
50 {108000, 120000},
51 {121500, 135000},
52 {135000, 150000},
53 {0, 0}
54};
55
56/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
57static const u8 up_to_ac[] = {
58 WMM_AC_BE,
59 WMM_AC_BK,
60 WMM_AC_BK,
61 WMM_AC_BE,
62 WMM_AC_VI,
63 WMM_AC_VI,
64 WMM_AC_VO,
65 WMM_AC_VO,
66};
67
68void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id)
69{
70 if (WARN_ON(ep_id == ENDPOINT_UNUSED || ep_id >= ENDPOINT_MAX))
71 return;
72
73 wmi->ep_id = ep_id;
74}
75
76enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi)
77{
78 return wmi->ep_id;
79}
80
81/* Performs DIX to 802.3 encapsulation for transmit packets.
82 * Assumes the entire DIX header is contigous and that there is
83 * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
84 */
85int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb)
86{
87 struct ath6kl_llc_snap_hdr *llc_hdr;
88 struct ethhdr *eth_hdr;
89 size_t new_len;
90 __be16 type;
91 u8 *datap;
92 u16 size;
93
94 if (WARN_ON(skb == NULL))
95 return -EINVAL;
96
97 size = sizeof(struct ath6kl_llc_snap_hdr) + sizeof(struct wmi_data_hdr);
98 if (skb_headroom(skb) < size)
99 return -ENOMEM;
100
101 eth_hdr = (struct ethhdr *) skb->data;
102 type = eth_hdr->h_proto;
103
104 if (!is_ethertype(be16_to_cpu(type))) {
105 ath6kl_dbg(ATH6KL_DBG_WMI,
106 "%s: pkt is already in 802.3 format\n", __func__);
107 return 0;
108 }
109
110 new_len = skb->len - sizeof(*eth_hdr) + sizeof(*llc_hdr);
111
112 skb_push(skb, sizeof(struct ath6kl_llc_snap_hdr));
113 datap = skb->data;
114
115 eth_hdr->h_proto = cpu_to_be16(new_len);
116
117 memcpy(datap, eth_hdr, sizeof(*eth_hdr));
118
119 llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap + sizeof(*eth_hdr));
120 llc_hdr->dsap = 0xAA;
121 llc_hdr->ssap = 0xAA;
122 llc_hdr->cntl = 0x03;
123 llc_hdr->org_code[0] = 0x0;
124 llc_hdr->org_code[1] = 0x0;
125 llc_hdr->org_code[2] = 0x0;
126 llc_hdr->eth_type = type;
127
128 return 0;
129}
130
131static int ath6kl_wmi_meta_add(struct wmi *wmi, struct sk_buff *skb,
132 u8 *version, void *tx_meta_info)
133{
134 struct wmi_tx_meta_v1 *v1;
135 struct wmi_tx_meta_v2 *v2;
136
137 if (WARN_ON(skb == NULL || version == NULL))
138 return -EINVAL;
139
140 switch (*version) {
141 case WMI_META_VERSION_1:
142 skb_push(skb, WMI_MAX_TX_META_SZ);
143 v1 = (struct wmi_tx_meta_v1 *) skb->data;
144 v1->pkt_id = 0;
145 v1->rate_plcy_id = 0;
146 *version = WMI_META_VERSION_1;
147 break;
148 case WMI_META_VERSION_2:
149 skb_push(skb, WMI_MAX_TX_META_SZ);
150 v2 = (struct wmi_tx_meta_v2 *) skb->data;
151 memcpy(v2, (struct wmi_tx_meta_v2 *) tx_meta_info,
152 sizeof(struct wmi_tx_meta_v2));
153 break;
154 }
155
156 return 0;
157}
158
159int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
160 u8 msg_type, bool more_data,
161 enum wmi_data_hdr_data_type data_type,
162 u8 meta_ver, void *tx_meta_info)
163{
164 struct wmi_data_hdr *data_hdr;
165 int ret;
166
167 if (WARN_ON(skb == NULL))
168 return -EINVAL;
169
170 ret = ath6kl_wmi_meta_add(wmi, skb, &meta_ver, tx_meta_info);
171 if (ret)
172 return ret;
173
174 skb_push(skb, sizeof(struct wmi_data_hdr));
175
176 data_hdr = (struct wmi_data_hdr *)skb->data;
177 memset(data_hdr, 0, sizeof(struct wmi_data_hdr));
178
179 data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT;
180 data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT;
181
182 if (more_data)
183 data_hdr->info |=
184 WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT;
185
186 data_hdr->info2 = cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT);
187 data_hdr->info3 = 0;
188
189 return 0;
190}
191
192static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
193{
194 struct iphdr *ip_hdr = (struct iphdr *) pkt;
195 u8 ip_pri;
196
197 /*
198 * Determine IPTOS priority
199 *
200 * IP-TOS - 8bits
201 * : DSCP(6-bits) ECN(2-bits)
202 * : DSCP - P2 P1 P0 X X X
203 * where (P2 P1 P0) form 802.1D
204 */
205 ip_pri = ip_hdr->tos >> 5;
206 ip_pri &= 0x7;
207
208 if ((layer2_pri & 0x7) > ip_pri)
209 return (u8) layer2_pri & 0x7;
210 else
211 return ip_pri;
212}
213
214int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
215 u32 layer2_priority, bool wmm_enabled,
216 u8 *ac)
217{
218 struct wmi_data_hdr *data_hdr;
219 struct ath6kl_llc_snap_hdr *llc_hdr;
220 struct wmi_create_pstream_cmd cmd;
221 u32 meta_size, hdr_size;
222 u16 ip_type = IP_ETHERTYPE;
223 u8 stream_exist, usr_pri;
224 u8 traffic_class = WMM_AC_BE;
225 u8 *datap;
226
227 if (WARN_ON(skb == NULL))
228 return -EINVAL;
229
230 datap = skb->data;
231 data_hdr = (struct wmi_data_hdr *) datap;
232
233 meta_size = ((le16_to_cpu(data_hdr->info2) >> WMI_DATA_HDR_META_SHIFT) &
234 WMI_DATA_HDR_META_MASK) ? WMI_MAX_TX_META_SZ : 0;
235
236 if (!wmm_enabled) {
237 /* If WMM is disabled all traffic goes as BE traffic */
238 usr_pri = 0;
239 } else {
240 hdr_size = sizeof(struct ethhdr);
241
242 llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap +
243 sizeof(struct
244 wmi_data_hdr) +
245 meta_size + hdr_size);
246
247 if (llc_hdr->eth_type == htons(ip_type)) {
248 /*
249 * Extract the endpoint info from the TOS field
250 * in the IP header.
251 */
252 usr_pri =
253 ath6kl_wmi_determine_user_priority(((u8 *) llc_hdr) +
254 sizeof(struct ath6kl_llc_snap_hdr),
255 layer2_priority);
256 } else
257 usr_pri = layer2_priority & 0x7;
258 }
259
260 /* workaround for WMM S5 */
261 if ((wmi->traffic_class == WMM_AC_VI) &&
262 ((usr_pri == 5) || (usr_pri == 4)))
263 usr_pri = 1;
264
265 /* Convert user priority to traffic class */
266 traffic_class = up_to_ac[usr_pri & 0x7];
267
268 wmi_data_hdr_set_up(data_hdr, usr_pri);
269
270 spin_lock_bh(&wmi->lock);
271 stream_exist = wmi->fat_pipe_exist;
272 spin_unlock_bh(&wmi->lock);
273
274 if (!(stream_exist & (1 << traffic_class))) {
275 memset(&cmd, 0, sizeof(cmd));
276 cmd.traffic_class = traffic_class;
277 cmd.user_pri = usr_pri;
278 cmd.inactivity_int =
279 cpu_to_le32(WMI_IMPLICIT_PSTREAM_INACTIVITY_INT);
280 /* Implicit streams are created with TSID 0xFF */
281 cmd.tsid = WMI_IMPLICIT_PSTREAM;
282 ath6kl_wmi_create_pstream_cmd(wmi, &cmd);
283 }
284
285 *ac = traffic_class;
286
287 return 0;
288}
289
290int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb)
291{
292 struct ieee80211_hdr_3addr *pwh, wh;
293 struct ath6kl_llc_snap_hdr *llc_hdr;
294 struct ethhdr eth_hdr;
295 u32 hdr_size;
296 u8 *datap;
297 __le16 sub_type;
298
299 if (WARN_ON(skb == NULL))
300 return -EINVAL;
301
302 datap = skb->data;
303 pwh = (struct ieee80211_hdr_3addr *) datap;
304
305 sub_type = pwh->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE);
306
307 memcpy((u8 *) &wh, datap, sizeof(struct ieee80211_hdr_3addr));
308
309 /* Strip off the 802.11 header */
310 if (sub_type == cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
311 hdr_size = roundup(sizeof(struct ieee80211_qos_hdr),
312 sizeof(u32));
313 skb_pull(skb, hdr_size);
314 } else if (sub_type == cpu_to_le16(IEEE80211_STYPE_DATA))
315 skb_pull(skb, sizeof(struct ieee80211_hdr_3addr));
316
317 datap = skb->data;
318 llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap);
319
320 memset(&eth_hdr, 0, sizeof(eth_hdr));
321 eth_hdr.h_proto = llc_hdr->eth_type;
322
323 switch ((le16_to_cpu(wh.frame_control)) &
324 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
325 case 0:
326 memcpy(eth_hdr.h_dest, wh.addr1, ETH_ALEN);
327 memcpy(eth_hdr.h_source, wh.addr2, ETH_ALEN);
328 break;
329 case IEEE80211_FCTL_TODS:
330 memcpy(eth_hdr.h_dest, wh.addr3, ETH_ALEN);
331 memcpy(eth_hdr.h_source, wh.addr2, ETH_ALEN);
332 break;
333 case IEEE80211_FCTL_FROMDS:
334 memcpy(eth_hdr.h_dest, wh.addr1, ETH_ALEN);
335 memcpy(eth_hdr.h_source, wh.addr3, ETH_ALEN);
336 break;
337 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
338 break;
339 }
340
341 skb_pull(skb, sizeof(struct ath6kl_llc_snap_hdr));
342 skb_push(skb, sizeof(eth_hdr));
343
344 datap = skb->data;
345
346 memcpy(datap, &eth_hdr, sizeof(eth_hdr));
347
348 return 0;
349}
350
351/*
352 * Performs 802.3 to DIX encapsulation for received packets.
353 * Assumes the entire 802.3 header is contigous.
354 */
355int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb)
356{
357 struct ath6kl_llc_snap_hdr *llc_hdr;
358 struct ethhdr eth_hdr;
359 u8 *datap;
360
361 if (WARN_ON(skb == NULL))
362 return -EINVAL;
363
364 datap = skb->data;
365
366 memcpy(&eth_hdr, datap, sizeof(eth_hdr));
367
368 llc_hdr = (struct ath6kl_llc_snap_hdr *) (datap + sizeof(eth_hdr));
369 eth_hdr.h_proto = llc_hdr->eth_type;
370
371 skb_pull(skb, sizeof(struct ath6kl_llc_snap_hdr));
372 datap = skb->data;
373
374 memcpy(datap, &eth_hdr, sizeof(eth_hdr));
375
376 return 0;
377}
378
379int ath6kl_wmi_data_hdr_remove(struct wmi *wmi, struct sk_buff *skb)
380{
381 if (WARN_ON(skb == NULL))
382 return -EINVAL;
383
384 skb_pull(skb, sizeof(struct wmi_data_hdr));
385
386 return 0;
387}
388
389static void ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(struct sk_buff *skb,
390 u8 *datap)
391{
392 struct wmi_bss_info_hdr2 bih2;
393 struct wmi_bss_info_hdr *bih;
394
395 memcpy(&bih2, datap, sizeof(struct wmi_bss_info_hdr2));
396
397 skb_push(skb, 4);
398 bih = (struct wmi_bss_info_hdr *) skb->data;
399
400 bih->ch = bih2.ch;
401 bih->frame_type = bih2.frame_type;
402 bih->snr = bih2.snr;
403 bih->rssi = a_cpu_to_sle16(bih2.snr - 95);
404 bih->ie_mask = cpu_to_le32(le16_to_cpu(bih2.ie_mask));
405 memcpy(bih->bssid, bih2.bssid, ETH_ALEN);
406}
407
408static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
409{
410 struct tx_complete_msg_v1 *msg_v1;
411 struct wmi_tx_complete_event *evt;
412 int index;
413 u16 size;
414
415 evt = (struct wmi_tx_complete_event *) datap;
416
417 ath6kl_dbg(ATH6KL_DBG_WMI, "comp: %d %d %d\n",
418 evt->num_msg, evt->msg_len, evt->msg_type);
419
420 if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_WMI))
421 return 0;
422
423 for (index = 0; index < evt->num_msg; index++) {
424 size = sizeof(struct wmi_tx_complete_event) +
425 (index * sizeof(struct tx_complete_msg_v1));
426 msg_v1 = (struct tx_complete_msg_v1 *)(datap + size);
427
428 ath6kl_dbg(ATH6KL_DBG_WMI, "msg: %d %d %d %d\n",
429 msg_v1->status, msg_v1->pkt_id,
430 msg_v1->rate_idx, msg_v1->ack_failures);
431 }
432
433 return 0;
434}
435
436static inline struct sk_buff *ath6kl_wmi_get_new_buf(u32 size)
437{
438 struct sk_buff *skb;
439
440 skb = ath6kl_buf_alloc(size);
441 if (!skb)
442 return NULL;
443
444 skb_put(skb, size);
445 if (size)
446 memset(skb->data, 0, size);
447
448 return skb;
449}
450
451/* Send a "simple" wmi command -- one with no arguments */
452static int ath6kl_wmi_simple_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id)
453{
454 struct sk_buff *skb;
455 int ret;
456
457 skb = ath6kl_wmi_get_new_buf(0);
458 if (!skb)
459 return -ENOMEM;
460
461 ret = ath6kl_wmi_cmd_send(wmi, skb, cmd_id, NO_SYNC_WMIFLAG);
462
463 return ret;
464}
465
466static int ath6kl_wmi_ready_event_rx(struct wmi *wmi, u8 *datap, int len)
467{
468 struct wmi_ready_event_2 *ev = (struct wmi_ready_event_2 *) datap;
469
470 if (len < sizeof(struct wmi_ready_event_2))
471 return -EINVAL;
472
473 wmi->ready = true;
474 ath6kl_ready_event(wmi->parent_dev, ev->mac_addr,
475 le32_to_cpu(ev->sw_version),
476 le32_to_cpu(ev->abi_version));
477
478 return 0;
479}
480
481static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len)
482{
483 struct wmi_connect_event *ev;
484 u8 *pie, *peie;
485
486 if (len < sizeof(struct wmi_connect_event))
487 return -EINVAL;
488
489 ev = (struct wmi_connect_event *) datap;
490
491 ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %pM\n",
492 __func__, ev->ch, ev->bssid);
493
494 /* Start of assoc rsp IEs */
495 pie = ev->assoc_info + ev->beacon_ie_len +
496 ev->assoc_req_len + (sizeof(u16) * 3); /* capinfo, status, aid */
497
498 /* End of assoc rsp IEs */
499 peie = ev->assoc_info + ev->beacon_ie_len + ev->assoc_req_len +
500 ev->assoc_resp_len;
501
502 while (pie < peie) {
503 switch (*pie) {
504 case WLAN_EID_VENDOR_SPECIFIC:
505 if (pie[1] > 3 && pie[2] == 0x00 && pie[3] == 0x50 &&
506 pie[4] == 0xf2 && pie[5] == WMM_OUI_TYPE) {
507 /* WMM OUT (00:50:F2) */
508 if (pie[1] > 5
509 && pie[6] == WMM_PARAM_OUI_SUBTYPE)
510 wmi->is_wmm_enabled = true;
511 }
512 break;
513 }
514
515 if (wmi->is_wmm_enabled)
516 break;
517
518 pie += pie[1] + 2;
519 }
520
521 ath6kl_connect_event(wmi->parent_dev, le16_to_cpu(ev->ch), ev->bssid,
522 le16_to_cpu(ev->listen_intvl),
523 le16_to_cpu(ev->beacon_intvl),
524 le32_to_cpu(ev->nw_type),
525 ev->beacon_ie_len, ev->assoc_req_len,
526 ev->assoc_resp_len, ev->assoc_info);
527
528 return 0;
529}
530
531static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len)
532{
533 struct wmi_disconnect_event *ev;
534 wmi->traffic_class = 100;
535
536 if (len < sizeof(struct wmi_disconnect_event))
537 return -EINVAL;
538
539 ev = (struct wmi_disconnect_event *) datap;
540
541 wmi->is_wmm_enabled = false;
542 wmi->pair_crypto_type = NONE_CRYPT;
543 wmi->grp_crypto_type = NONE_CRYPT;
544
545 ath6kl_disconnect_event(wmi->parent_dev, ev->disconn_reason,
546 ev->bssid, ev->assoc_resp_len, ev->assoc_info,
547 le16_to_cpu(ev->proto_reason_status));
548
549 return 0;
550}
551
552static int ath6kl_wmi_peer_node_event_rx(struct wmi *wmi, u8 *datap, int len)
553{
554 struct wmi_peer_node_event *ev;
555
556 if (len < sizeof(struct wmi_peer_node_event))
557 return -EINVAL;
558
559 ev = (struct wmi_peer_node_event *) datap;
560
561 if (ev->event_code == PEER_NODE_JOIN_EVENT)
562 ath6kl_dbg(ATH6KL_DBG_WMI, "joined node with mac addr: %pM\n",
563 ev->peer_mac_addr);
564 else if (ev->event_code == PEER_NODE_LEAVE_EVENT)
565 ath6kl_dbg(ATH6KL_DBG_WMI, "left node with mac addr: %pM\n",
566 ev->peer_mac_addr);
567
568 return 0;
569}
570
571static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len)
572{
573 struct wmi_tkip_micerr_event *ev;
574
575 if (len < sizeof(struct wmi_tkip_micerr_event))
576 return -EINVAL;
577
578 ev = (struct wmi_tkip_micerr_event *) datap;
579
580 ath6kl_tkip_micerr_event(wmi->parent_dev, ev->key_id, ev->is_mcast);
581
582 return 0;
583}
584
585static int ath6kl_wlan_parse_beacon(u8 *buf, int frame_len,
586 struct ath6kl_common_ie *cie)
587{
588 u8 *frm, *efrm;
589 u8 elemid_ssid = false;
590
591 frm = buf;
592 efrm = (u8 *) (frm + frame_len);
593
594 /*
595 * beacon/probe response frame format
596 * [8] time stamp
597 * [2] beacon interval
598 * [2] capability information
599 * [tlv] ssid
600 * [tlv] supported rates
601 * [tlv] country information
602 * [tlv] parameter set (FH/DS)
603 * [tlv] erp information
604 * [tlv] extended supported rates
605 * [tlv] WMM
606 * [tlv] WPA or RSN
607 * [tlv] Atheros Advanced Capabilities
608 */
609 if ((efrm - frm) < 12)
610 return -EINVAL;
611
612 memset(cie, 0, sizeof(*cie));
613
614 cie->ie_tstamp = frm;
615 frm += 8;
616 cie->ie_beaconInt = *(u16 *) frm;
617 frm += 2;
618 cie->ie_capInfo = *(u16 *) frm;
619 frm += 2;
620 cie->ie_chan = 0;
621
622 while (frm < efrm) {
623 switch (*frm) {
624 case WLAN_EID_SSID:
625 if (!elemid_ssid) {
626 cie->ie_ssid = frm;
627 elemid_ssid = true;
628 }
629 break;
630 case WLAN_EID_SUPP_RATES:
631 cie->ie_rates = frm;
632 break;
633 case WLAN_EID_COUNTRY:
634 cie->ie_country = frm;
635 break;
636 case WLAN_EID_FH_PARAMS:
637 break;
638 case WLAN_EID_DS_PARAMS:
639 cie->ie_chan = frm[2];
640 break;
641 case WLAN_EID_TIM:
642 cie->ie_tim = frm;
643 break;
644 case WLAN_EID_IBSS_PARAMS:
645 break;
646 case WLAN_EID_EXT_SUPP_RATES:
647 cie->ie_xrates = frm;
648 break;
649 case WLAN_EID_ERP_INFO:
650 if (frm[1] != 1)
651 return -EINVAL;
652
653 cie->ie_erp = frm[2];
654 break;
655 case WLAN_EID_RSN:
656 cie->ie_rsn = frm;
657 break;
658 case WLAN_EID_HT_CAPABILITY:
659 cie->ie_htcap = frm;
660 break;
661 case WLAN_EID_HT_INFORMATION:
662 cie->ie_htop = frm;
663 break;
664 case WLAN_EID_VENDOR_SPECIFIC:
665 if (frm[1] > 3 && frm[2] == 0x00 && frm[3] == 0x50 &&
666 frm[4] == 0xf2) {
667 /* OUT Type (00:50:F2) */
668
669 if (frm[5] == WPA_OUI_TYPE) {
670 /* WPA OUT */
671 cie->ie_wpa = frm;
672 } else if (frm[5] == WMM_OUI_TYPE) {
673 /* WMM OUT */
674 cie->ie_wmm = frm;
675 } else if (frm[5] == WSC_OUT_TYPE) {
676 /* WSC OUT */
677 cie->ie_wsc = frm;
678 }
679
680 } else if (frm[1] > 3 && frm[2] == 0x00
681 && frm[3] == 0x03 && frm[4] == 0x7f
682 && frm[5] == ATH_OUI_TYPE) {
683 /* Atheros OUI (00:03:7f) */
684 cie->ie_ath = frm;
685 }
686 break;
687 default:
688 break;
689 }
690 frm += frm[1] + 2;
691 }
692
693 if ((cie->ie_rates == NULL)
694 || (cie->ie_rates[1] > ATH6KL_RATE_MAXSIZE))
695 return -EINVAL;
696
697 if ((cie->ie_ssid == NULL)
698 || (cie->ie_ssid[1] > IEEE80211_MAX_SSID_LEN))
699 return -EINVAL;
700
701 return 0;
702}
703
704static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
705{
706 struct bss *bss = NULL;
707 struct wmi_bss_info_hdr *bih;
708 u8 cached_ssid_len = 0;
709 u8 cached_ssid[IEEE80211_MAX_SSID_LEN] = { 0 };
710 u8 beacon_ssid_len = 0;
711 u8 *buf, *ie_ssid;
712 u8 *ni_buf;
713 int buf_len;
714
715 int ret;
716
717 if (len <= sizeof(struct wmi_bss_info_hdr))
718 return -EINVAL;
719
720 bih = (struct wmi_bss_info_hdr *) datap;
721 bss = wlan_find_node(&wmi->parent_dev->scan_table, bih->bssid);
722
723 if (a_sle16_to_cpu(bih->rssi) > 0) {
724 if (bss == NULL)
725 return 0;
726 else
727 bih->rssi = a_cpu_to_sle16(bss->ni_rssi);
728 }
729
730 buf = datap + sizeof(struct wmi_bss_info_hdr);
731 len -= sizeof(struct wmi_bss_info_hdr);
732
733 ath6kl_dbg(ATH6KL_DBG_WMI,
734 "bss info evt - ch %u, rssi %02x, bssid \"%pM\"\n",
735 bih->ch, a_sle16_to_cpu(bih->rssi), bih->bssid);
736
737 if (bss != NULL) {
738 /*
739 * Free up the node. We are about to allocate a new node.
740 * In case of hidden AP, beacon will not have ssid,
741 * but a directed probe response will have it,
742 * so cache the probe-resp-ssid if already present.
743 */
744 if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE)) {
745 ie_ssid = bss->ni_cie.ie_ssid;
746 if (ie_ssid && (ie_ssid[1] <= IEEE80211_MAX_SSID_LEN) &&
747 (ie_ssid[2] != 0)) {
748 cached_ssid_len = ie_ssid[1];
749 memcpy(cached_ssid, ie_ssid + 2,
750 cached_ssid_len);
751 }
752 }
753
754 /*
755 * Use the current average rssi of associated AP base on
756 * assumption
757 * 1. Most os with GUI will update RSSI by
758 * ath6kl_wmi_get_stats_cmd() periodically.
759 * 2. ath6kl_wmi_get_stats_cmd(..) will be called when calling
760 * ath6kl_wmi_startscan_cmd(...)
761 * The average value of RSSI give end-user better feeling for
762 * instance value of scan result. It also sync up RSSI info
763 * in GUI between scan result and RSSI signal icon.
764 */
765 if (memcmp(wmi->parent_dev->bssid, bih->bssid, ETH_ALEN) == 0) {
766 bih->rssi = a_cpu_to_sle16(bss->ni_rssi);
767 bih->snr = bss->ni_snr;
768 }
769
770 wlan_node_reclaim(&wmi->parent_dev->scan_table, bss);
771 }
772
773 /*
774 * beacon/probe response frame format
775 * [8] time stamp
776 * [2] beacon interval
777 * [2] capability information
778 * [tlv] ssid
779 */
780 beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
781
782 /*
783 * If ssid is cached for this hidden AP, then change
784 * buffer len accordingly.
785 */
786 if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE) &&
787 (cached_ssid_len != 0) &&
788 (beacon_ssid_len == 0 || (cached_ssid_len > beacon_ssid_len &&
789 buf[SSID_IE_LEN_INDEX + 1] == 0))) {
790
791 len += (cached_ssid_len - beacon_ssid_len);
792 }
793
794 bss = wlan_node_alloc(len);
795 if (!bss)
796 return -ENOMEM;
797
798 bss->ni_snr = bih->snr;
799 bss->ni_rssi = a_sle16_to_cpu(bih->rssi);
800
801 if (WARN_ON(!bss->ni_buf))
802 return -EINVAL;
803
804 /*
805 * In case of hidden AP, beacon will not have ssid,
806 * but a directed probe response will have it,
807 * so place the cached-ssid(probe-resp) in the bss info.
808 */
809 if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE) &&
810 (cached_ssid_len != 0) &&
811 (beacon_ssid_len == 0 || (beacon_ssid_len &&
812 buf[SSID_IE_LEN_INDEX + 1] == 0))) {
813 ni_buf = bss->ni_buf;
814 buf_len = len;
815
816 /*
817 * Copy the first 14 bytes:
818 * time-stamp(8), beacon-interval(2),
819 * cap-info(2), ssid-id(1), ssid-len(1).
820 */
821 memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
822
823 ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
824 ni_buf += (SSID_IE_LEN_INDEX + 1);
825
826 buf += (SSID_IE_LEN_INDEX + 1);
827 buf_len -= (SSID_IE_LEN_INDEX + 1);
828
829 memcpy(ni_buf, cached_ssid, cached_ssid_len);
830 ni_buf += cached_ssid_len;
831
832 buf += beacon_ssid_len;
833 buf_len -= beacon_ssid_len;
834
835 if (cached_ssid_len > beacon_ssid_len)
836 buf_len -= (cached_ssid_len - beacon_ssid_len);
837
838 memcpy(ni_buf, buf, buf_len);
839 } else
840 memcpy(bss->ni_buf, buf, len);
841
842 bss->ni_framelen = len;
843
844 ret = ath6kl_wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie);
845 if (ret) {
846 wlan_node_free(bss);
847 return -EINVAL;
848 }
849
850 /*
851 * Update the frequency in ie_chan, overwriting of channel number
852 * which is done in ath6kl_wlan_parse_beacon
853 */
854 bss->ni_cie.ie_chan = le16_to_cpu(bih->ch);
855 wlan_setup_node(&wmi->parent_dev->scan_table, bss, bih->bssid);
856
857 return 0;
858}
859
860static int ath6kl_wmi_opt_frame_event_rx(struct wmi *wmi, u8 *datap, int len)
861{
862 struct bss *bss;
863 struct wmi_opt_rx_info_hdr *bih;
864 u8 *buf;
865
866 if (len <= sizeof(struct wmi_opt_rx_info_hdr))
867 return -EINVAL;
868
869 bih = (struct wmi_opt_rx_info_hdr *) datap;
870 buf = datap + sizeof(struct wmi_opt_rx_info_hdr);
871 len -= sizeof(struct wmi_opt_rx_info_hdr);
872
873 ath6kl_dbg(ATH6KL_DBG_WMI, "opt frame event %2.2x:%2.2x\n",
874 bih->bssid[4], bih->bssid[5]);
875
876 bss = wlan_find_node(&wmi->parent_dev->scan_table, bih->bssid);
877 if (bss != NULL) {
878 /* Free up the node. We are about to allocate a new node. */
879 wlan_node_reclaim(&wmi->parent_dev->scan_table, bss);
880 }
881
882 bss = wlan_node_alloc(len);
883 if (!bss)
884 return -ENOMEM;
885
886 bss->ni_snr = bih->snr;
887 bss->ni_cie.ie_chan = le16_to_cpu(bih->ch);
888
889 if (WARN_ON(!bss->ni_buf))
890 return -EINVAL;
891
892 memcpy(bss->ni_buf, buf, len);
893 wlan_setup_node(&wmi->parent_dev->scan_table, bss, bih->bssid);
894
895 return 0;
896}
897
898/* Inactivity timeout of a fatpipe(pstream) at the target */
899static int ath6kl_wmi_pstream_timeout_event_rx(struct wmi *wmi, u8 *datap,
900 int len)
901{
902 struct wmi_pstream_timeout_event *ev;
903
904 if (len < sizeof(struct wmi_pstream_timeout_event))
905 return -EINVAL;
906
907 ev = (struct wmi_pstream_timeout_event *) datap;
908
909 /*
910 * When the pstream (fat pipe == AC) timesout, it means there were
911 * no thinStreams within this pstream & it got implicitly created
912 * due to data flow on this AC. We start the inactivity timer only
913 * for implicitly created pstream. Just reset the host state.
914 */
915 spin_lock_bh(&wmi->lock);
916 wmi->stream_exist_for_ac[ev->traffic_class] = 0;
917 wmi->fat_pipe_exist &= ~(1 << ev->traffic_class);
918 spin_unlock_bh(&wmi->lock);
919
920 /* Indicate inactivity to driver layer for this fatpipe (pstream) */
921 ath6kl_indicate_tx_activity(wmi->parent_dev, ev->traffic_class, false);
922
923 return 0;
924}
925
926static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
927{
928 struct wmi_bit_rate_reply *reply;
929 s32 rate;
930 u32 sgi, index;
931
932 if (len < sizeof(struct wmi_bit_rate_reply))
933 return -EINVAL;
934
935 reply = (struct wmi_bit_rate_reply *) datap;
936
937 ath6kl_dbg(ATH6KL_DBG_WMI, "rateindex %d\n", reply->rate_index);
938
939 if (reply->rate_index == (s8) RATE_AUTO) {
940 rate = RATE_AUTO;
941 } else {
942 index = reply->rate_index & 0x7f;
943 sgi = (reply->rate_index & 0x80) ? 1 : 0;
944 rate = wmi_rate_tbl[index][sgi];
945 }
946
947 ath6kl_wakeup_event(wmi->parent_dev);
948
949 return 0;
950}
951
952static int ath6kl_wmi_ratemask_reply_rx(struct wmi *wmi, u8 *datap, int len)
953{
954 if (len < sizeof(struct wmi_fix_rates_reply))
955 return -EINVAL;
956
957 ath6kl_wakeup_event(wmi->parent_dev);
958
959 return 0;
960}
961
962static int ath6kl_wmi_ch_list_reply_rx(struct wmi *wmi, u8 *datap, int len)
963{
964 if (len < sizeof(struct wmi_channel_list_reply))
965 return -EINVAL;
966
967 ath6kl_wakeup_event(wmi->parent_dev);
968
969 return 0;
970}
971
972static int ath6kl_wmi_tx_pwr_reply_rx(struct wmi *wmi, u8 *datap, int len)
973{
974 struct wmi_tx_pwr_reply *reply;
975
976 if (len < sizeof(struct wmi_tx_pwr_reply))
977 return -EINVAL;
978
979 reply = (struct wmi_tx_pwr_reply *) datap;
980 ath6kl_txpwr_rx_evt(wmi->parent_dev, reply->dbM);
981
982 return 0;
983}
984
985static int ath6kl_wmi_keepalive_reply_rx(struct wmi *wmi, u8 *datap, int len)
986{
987 if (len < sizeof(struct wmi_get_keepalive_cmd))
988 return -EINVAL;
989
990 ath6kl_wakeup_event(wmi->parent_dev);
991
992 return 0;
993}
994
995static int ath6kl_wmi_scan_complete_rx(struct wmi *wmi, u8 *datap, int len)
996{
997 struct wmi_scan_complete_event *ev;
998
999 ev = (struct wmi_scan_complete_event *) datap;
1000
1001 if (a_sle32_to_cpu(ev->status) == 0)
1002 wlan_refresh_inactive_nodes(wmi->parent_dev);
1003
1004 ath6kl_scan_complete_evt(wmi->parent_dev, a_sle32_to_cpu(ev->status));
1005 wmi->is_probe_ssid = false;
1006
1007 return 0;
1008}
1009
1010/*
1011 * Target is reporting a programming error. This is for
1012 * developer aid only. Target only checks a few common violations
1013 * and it is responsibility of host to do all error checking.
1014 * Behavior of target after wmi error event is undefined.
1015 * A reset is recommended.
1016 */
1017static int ath6kl_wmi_error_event_rx(struct wmi *wmi, u8 *datap, int len)
1018{
1019 const char *type = "unknown error";
1020 struct wmi_cmd_error_event *ev;
1021 ev = (struct wmi_cmd_error_event *) datap;
1022
1023 switch (ev->err_code) {
1024 case INVALID_PARAM:
1025 type = "invalid parameter";
1026 break;
1027 case ILLEGAL_STATE:
1028 type = "invalid state";
1029 break;
1030 case INTERNAL_ERROR:
1031 type = "internal error";
1032 break;
1033 }
1034
1035 ath6kl_dbg(ATH6KL_DBG_WMI, "programming error, cmd=%d %s\n",
1036 ev->cmd_id, type);
1037
1038 return 0;
1039}
1040
1041static int ath6kl_wmi_stats_event_rx(struct wmi *wmi, u8 *datap, int len)
1042{
1043 ath6kl_tgt_stats_event(wmi->parent_dev, datap, len);
1044
1045 return 0;
1046}
1047
1048static u8 ath6kl_wmi_get_upper_threshold(s16 rssi,
1049 struct sq_threshold_params *sq_thresh,
1050 u32 size)
1051{
1052 u32 index;
1053 u8 threshold = (u8) sq_thresh->upper_threshold[size - 1];
1054
1055 /* The list is already in sorted order. Get the next lower value */
1056 for (index = 0; index < size; index++) {
1057 if (rssi < sq_thresh->upper_threshold[index]) {
1058 threshold = (u8) sq_thresh->upper_threshold[index];
1059 break;
1060 }
1061 }
1062
1063 return threshold;
1064}
1065
1066static u8 ath6kl_wmi_get_lower_threshold(s16 rssi,
1067 struct sq_threshold_params *sq_thresh,
1068 u32 size)
1069{
1070 u32 index;
1071 u8 threshold = (u8) sq_thresh->lower_threshold[size - 1];
1072
1073 /* The list is already in sorted order. Get the next lower value */
1074 for (index = 0; index < size; index++) {
1075 if (rssi > sq_thresh->lower_threshold[index]) {
1076 threshold = (u8) sq_thresh->lower_threshold[index];
1077 break;
1078 }
1079 }
1080
1081 return threshold;
1082}
1083
1084static int ath6kl_wmi_send_rssi_threshold_params(struct wmi *wmi,
1085 struct wmi_rssi_threshold_params_cmd *rssi_cmd)
1086{
1087 struct sk_buff *skb;
1088 struct wmi_rssi_threshold_params_cmd *cmd;
1089
1090 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1091 if (!skb)
1092 return -ENOMEM;
1093
1094 cmd = (struct wmi_rssi_threshold_params_cmd *) skb->data;
1095 memcpy(cmd, rssi_cmd, sizeof(struct wmi_rssi_threshold_params_cmd));
1096
1097 return ath6kl_wmi_cmd_send(wmi, skb, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
1098 NO_SYNC_WMIFLAG);
1099}
1100
1101static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap,
1102 int len)
1103{
1104 struct wmi_rssi_threshold_event *reply;
1105 struct wmi_rssi_threshold_params_cmd cmd;
1106 struct sq_threshold_params *sq_thresh;
1107 enum wmi_rssi_threshold_val new_threshold;
1108 u8 upper_rssi_threshold, lower_rssi_threshold;
1109 s16 rssi;
1110 int ret;
1111
1112 if (len < sizeof(struct wmi_rssi_threshold_event))
1113 return -EINVAL;
1114
1115 reply = (struct wmi_rssi_threshold_event *) datap;
1116 new_threshold = (enum wmi_rssi_threshold_val) reply->range;
1117 rssi = a_sle16_to_cpu(reply->rssi);
1118
1119 sq_thresh = &wmi->sq_threshld[SIGNAL_QUALITY_METRICS_RSSI];
1120
1121 /*
1122 * Identify the threshold breached and communicate that to the app.
1123 * After that install a new set of thresholds based on the signal
1124 * quality reported by the target
1125 */
1126 if (new_threshold) {
1127 /* Upper threshold breached */
1128 if (rssi < sq_thresh->upper_threshold[0]) {
1129 ath6kl_dbg(ATH6KL_DBG_WMI,
1130 "spurious upper rssi threshold event: %d\n",
1131 rssi);
1132 } else if ((rssi < sq_thresh->upper_threshold[1]) &&
1133 (rssi >= sq_thresh->upper_threshold[0])) {
1134 new_threshold = WMI_RSSI_THRESHOLD1_ABOVE;
1135 } else if ((rssi < sq_thresh->upper_threshold[2]) &&
1136 (rssi >= sq_thresh->upper_threshold[1])) {
1137 new_threshold = WMI_RSSI_THRESHOLD2_ABOVE;
1138 } else if ((rssi < sq_thresh->upper_threshold[3]) &&
1139 (rssi >= sq_thresh->upper_threshold[2])) {
1140 new_threshold = WMI_RSSI_THRESHOLD3_ABOVE;
1141 } else if ((rssi < sq_thresh->upper_threshold[4]) &&
1142 (rssi >= sq_thresh->upper_threshold[3])) {
1143 new_threshold = WMI_RSSI_THRESHOLD4_ABOVE;
1144 } else if ((rssi < sq_thresh->upper_threshold[5]) &&
1145 (rssi >= sq_thresh->upper_threshold[4])) {
1146 new_threshold = WMI_RSSI_THRESHOLD5_ABOVE;
1147 } else if (rssi >= sq_thresh->upper_threshold[5]) {
1148 new_threshold = WMI_RSSI_THRESHOLD6_ABOVE;
1149 }
1150 } else {
1151 /* Lower threshold breached */
1152 if (rssi > sq_thresh->lower_threshold[0]) {
1153 ath6kl_dbg(ATH6KL_DBG_WMI,
1154 "spurious lower rssi threshold event: %d %d\n",
1155 rssi, sq_thresh->lower_threshold[0]);
1156 } else if ((rssi > sq_thresh->lower_threshold[1]) &&
1157 (rssi <= sq_thresh->lower_threshold[0])) {
1158 new_threshold = WMI_RSSI_THRESHOLD6_BELOW;
1159 } else if ((rssi > sq_thresh->lower_threshold[2]) &&
1160 (rssi <= sq_thresh->lower_threshold[1])) {
1161 new_threshold = WMI_RSSI_THRESHOLD5_BELOW;
1162 } else if ((rssi > sq_thresh->lower_threshold[3]) &&
1163 (rssi <= sq_thresh->lower_threshold[2])) {
1164 new_threshold = WMI_RSSI_THRESHOLD4_BELOW;
1165 } else if ((rssi > sq_thresh->lower_threshold[4]) &&
1166 (rssi <= sq_thresh->lower_threshold[3])) {
1167 new_threshold = WMI_RSSI_THRESHOLD3_BELOW;
1168 } else if ((rssi > sq_thresh->lower_threshold[5]) &&
1169 (rssi <= sq_thresh->lower_threshold[4])) {
1170 new_threshold = WMI_RSSI_THRESHOLD2_BELOW;
1171 } else if (rssi <= sq_thresh->lower_threshold[5]) {
1172 new_threshold = WMI_RSSI_THRESHOLD1_BELOW;
1173 }
1174 }
1175
1176 /* Calculate and install the next set of thresholds */
1177 lower_rssi_threshold = ath6kl_wmi_get_lower_threshold(rssi, sq_thresh,
1178 sq_thresh->lower_threshold_valid_count);
1179 upper_rssi_threshold = ath6kl_wmi_get_upper_threshold(rssi, sq_thresh,
1180 sq_thresh->upper_threshold_valid_count);
1181
1182 /* Issue a wmi command to install the thresholds */
1183 cmd.thresh_above1_val = a_cpu_to_sle16(upper_rssi_threshold);
1184 cmd.thresh_below1_val = a_cpu_to_sle16(lower_rssi_threshold);
1185 cmd.weight = sq_thresh->weight;
1186 cmd.poll_time = cpu_to_le32(sq_thresh->polling_interval);
1187
1188 ret = ath6kl_wmi_send_rssi_threshold_params(wmi, &cmd);
1189 if (ret) {
1190 ath6kl_err("unable to configure rssi thresholds\n");
1191 return -EIO;
1192 }
1193
1194 return 0;
1195}
1196
1197static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len)
1198{
1199 struct wmi_cac_event *reply;
1200 struct ieee80211_tspec_ie *ts;
1201 u16 active_tsids, tsinfo;
1202 u8 tsid, index;
1203 u8 ts_id;
1204
1205 if (len < sizeof(struct wmi_cac_event))
1206 return -EINVAL;
1207
1208 reply = (struct wmi_cac_event *) datap;
1209
1210 if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
1211 (reply->status_code != IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED)) {
1212
1213 ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
1214 tsinfo = le16_to_cpu(ts->tsinfo);
1215 tsid = (tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
1216 IEEE80211_WMM_IE_TSPEC_TID_MASK;
1217
1218 ath6kl_wmi_delete_pstream_cmd(wmi, reply->ac, tsid);
1219 } else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
1220 /*
1221 * Following assumes that there is only one outstanding
1222 * ADDTS request when this event is received
1223 */
1224 spin_lock_bh(&wmi->lock);
1225 active_tsids = wmi->stream_exist_for_ac[reply->ac];
1226 spin_unlock_bh(&wmi->lock);
1227
1228 for (index = 0; index < sizeof(active_tsids) * 8; index++) {
1229 if ((active_tsids >> index) & 1)
1230 break;
1231 }
1232 if (index < (sizeof(active_tsids) * 8))
1233 ath6kl_wmi_delete_pstream_cmd(wmi, reply->ac, index);
1234 }
1235
1236 /*
1237 * Clear active tsids and Add missing handling
1238 * for delete qos stream from AP
1239 */
1240 else if (reply->cac_indication == CAC_INDICATION_DELETE) {
1241
1242 ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
1243 tsinfo = le16_to_cpu(ts->tsinfo);
1244 ts_id = ((tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
1245 IEEE80211_WMM_IE_TSPEC_TID_MASK);
1246
1247 spin_lock_bh(&wmi->lock);
1248 wmi->stream_exist_for_ac[reply->ac] &= ~(1 << ts_id);
1249 active_tsids = wmi->stream_exist_for_ac[reply->ac];
1250 spin_unlock_bh(&wmi->lock);
1251
1252 /* Indicate stream inactivity to driver layer only if all tsids
1253 * within this AC are deleted.
1254 */
1255 if (!active_tsids) {
1256 ath6kl_indicate_tx_activity(wmi->parent_dev, reply->ac,
1257 false);
1258 wmi->fat_pipe_exist &= ~(1 << reply->ac);
1259 }
1260 }
1261
1262 return 0;
1263}
1264
1265static int ath6kl_wmi_send_snr_threshold_params(struct wmi *wmi,
1266 struct wmi_snr_threshold_params_cmd *snr_cmd)
1267{
1268 struct sk_buff *skb;
1269 struct wmi_snr_threshold_params_cmd *cmd;
1270
1271 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1272 if (!skb)
1273 return -ENOMEM;
1274
1275 cmd = (struct wmi_snr_threshold_params_cmd *) skb->data;
1276 memcpy(cmd, snr_cmd, sizeof(struct wmi_snr_threshold_params_cmd));
1277
1278 return ath6kl_wmi_cmd_send(wmi, skb, WMI_SNR_THRESHOLD_PARAMS_CMDID,
1279 NO_SYNC_WMIFLAG);
1280}
1281
1282static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap,
1283 int len)
1284{
1285 struct wmi_snr_threshold_event *reply;
1286 struct sq_threshold_params *sq_thresh;
1287 struct wmi_snr_threshold_params_cmd cmd;
1288 enum wmi_snr_threshold_val new_threshold;
1289 u8 upper_snr_threshold, lower_snr_threshold;
1290 s16 snr;
1291 int ret;
1292
1293 if (len < sizeof(struct wmi_snr_threshold_event))
1294 return -EINVAL;
1295
1296 reply = (struct wmi_snr_threshold_event *) datap;
1297
1298 new_threshold = (enum wmi_snr_threshold_val) reply->range;
1299 snr = reply->snr;
1300
1301 sq_thresh = &wmi->sq_threshld[SIGNAL_QUALITY_METRICS_SNR];
1302
1303 /*
1304 * Identify the threshold breached and communicate that to the app.
1305 * After that install a new set of thresholds based on the signal
1306 * quality reported by the target.
1307 */
1308 if (new_threshold) {
1309 /* Upper threshold breached */
1310 if (snr < sq_thresh->upper_threshold[0]) {
1311 ath6kl_dbg(ATH6KL_DBG_WMI,
1312 "spurious upper snr threshold event: %d\n",
1313 snr);
1314 } else if ((snr < sq_thresh->upper_threshold[1]) &&
1315 (snr >= sq_thresh->upper_threshold[0])) {
1316 new_threshold = WMI_SNR_THRESHOLD1_ABOVE;
1317 } else if ((snr < sq_thresh->upper_threshold[2]) &&
1318 (snr >= sq_thresh->upper_threshold[1])) {
1319 new_threshold = WMI_SNR_THRESHOLD2_ABOVE;
1320 } else if ((snr < sq_thresh->upper_threshold[3]) &&
1321 (snr >= sq_thresh->upper_threshold[2])) {
1322 new_threshold = WMI_SNR_THRESHOLD3_ABOVE;
1323 } else if (snr >= sq_thresh->upper_threshold[3]) {
1324 new_threshold = WMI_SNR_THRESHOLD4_ABOVE;
1325 }
1326 } else {
1327 /* Lower threshold breached */
1328 if (snr > sq_thresh->lower_threshold[0]) {
1329 ath6kl_dbg(ATH6KL_DBG_WMI,
1330 "spurious lower snr threshold event: %d\n",
1331 sq_thresh->lower_threshold[0]);
1332 } else if ((snr > sq_thresh->lower_threshold[1]) &&
1333 (snr <= sq_thresh->lower_threshold[0])) {
1334 new_threshold = WMI_SNR_THRESHOLD4_BELOW;
1335 } else if ((snr > sq_thresh->lower_threshold[2]) &&
1336 (snr <= sq_thresh->lower_threshold[1])) {
1337 new_threshold = WMI_SNR_THRESHOLD3_BELOW;
1338 } else if ((snr > sq_thresh->lower_threshold[3]) &&
1339 (snr <= sq_thresh->lower_threshold[2])) {
1340 new_threshold = WMI_SNR_THRESHOLD2_BELOW;
1341 } else if (snr <= sq_thresh->lower_threshold[3]) {
1342 new_threshold = WMI_SNR_THRESHOLD1_BELOW;
1343 }
1344 }
1345
1346 /* Calculate and install the next set of thresholds */
1347 lower_snr_threshold = ath6kl_wmi_get_lower_threshold(snr, sq_thresh,
1348 sq_thresh->lower_threshold_valid_count);
1349 upper_snr_threshold = ath6kl_wmi_get_upper_threshold(snr, sq_thresh,
1350 sq_thresh->upper_threshold_valid_count);
1351
1352 /* Issue a wmi command to install the thresholds */
1353 cmd.thresh_above1_val = upper_snr_threshold;
1354 cmd.thresh_below1_val = lower_snr_threshold;
1355 cmd.weight = sq_thresh->weight;
1356 cmd.poll_time = cpu_to_le32(sq_thresh->polling_interval);
1357
1358 ath6kl_dbg(ATH6KL_DBG_WMI,
1359 "snr: %d, threshold: %d, lower: %d, upper: %d\n",
1360 snr, new_threshold,
1361 lower_snr_threshold, upper_snr_threshold);
1362
1363 ret = ath6kl_wmi_send_snr_threshold_params(wmi, &cmd);
1364 if (ret) {
1365 ath6kl_err("unable to configure snr threshold\n");
1366 return -EIO;
1367 }
1368
1369 return 0;
1370}
1371
1372static int ath6kl_wmi_aplist_event_rx(struct wmi *wmi, u8 *datap, int len)
1373{
1374 u16 ap_info_entry_size;
1375 struct wmi_aplist_event *ev = (struct wmi_aplist_event *) datap;
1376 struct wmi_ap_info_v1 *ap_info_v1;
1377 u8 index;
1378
1379 if (len < sizeof(struct wmi_aplist_event) ||
1380 ev->ap_list_ver != APLIST_VER1)
1381 return -EINVAL;
1382
1383 ap_info_entry_size = sizeof(struct wmi_ap_info_v1);
1384 ap_info_v1 = (struct wmi_ap_info_v1 *) ev->ap_list;
1385
1386 ath6kl_dbg(ATH6KL_DBG_WMI,
1387 "number of APs in aplist event: %d\n", ev->num_ap);
1388
1389 if (len < (int) (sizeof(struct wmi_aplist_event) +
1390 (ev->num_ap - 1) * ap_info_entry_size))
1391 return -EINVAL;
1392
1393 /* AP list version 1 contents */
1394 for (index = 0; index < ev->num_ap; index++) {
1395 ath6kl_dbg(ATH6KL_DBG_WMI, "AP#%d BSSID %pM Channel %d\n",
1396 index, ap_info_v1->bssid, ap_info_v1->channel);
1397 ap_info_v1++;
1398 }
1399
1400 return 0;
1401}
1402
1403int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
1404 enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag)
1405{
1406 struct wmi_cmd_hdr *cmd_hdr;
1407 enum htc_endpoint_id ep_id = wmi->ep_id;
1408 int ret;
1409
1410 if (WARN_ON(skb == NULL))
1411 return -EINVAL;
1412
1413 if (sync_flag >= END_WMIFLAG) {
1414 dev_kfree_skb(skb);
1415 return -EINVAL;
1416 }
1417
1418 if ((sync_flag == SYNC_BEFORE_WMIFLAG) ||
1419 (sync_flag == SYNC_BOTH_WMIFLAG)) {
1420 /*
1421 * Make sure all data currently queued is transmitted before
1422 * the cmd execution. Establish a new sync point.
1423 */
1424 ath6kl_wmi_sync_point(wmi);
1425 }
1426
1427 skb_push(skb, sizeof(struct wmi_cmd_hdr));
1428
1429 cmd_hdr = (struct wmi_cmd_hdr *) skb->data;
1430 cmd_hdr->cmd_id = cpu_to_le16(cmd_id);
1431 cmd_hdr->info1 = 0; /* added for virtual interface */
1432
1433 /* Only for OPT_TX_CMD, use BE endpoint. */
1434 if (cmd_id == WMI_OPT_TX_FRAME_CMDID) {
1435 ret = ath6kl_wmi_data_hdr_add(wmi, skb, OPT_MSGTYPE,
1436 false, false, 0, NULL);
1437 if (ret) {
1438 dev_kfree_skb(skb);
1439 return ret;
1440 }
1441 ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev, WMM_AC_BE);
1442 }
1443
1444 ath6kl_control_tx(wmi->parent_dev, skb, ep_id);
1445
1446 if ((sync_flag == SYNC_AFTER_WMIFLAG) ||
1447 (sync_flag == SYNC_BOTH_WMIFLAG)) {
1448 /*
1449 * Make sure all new data queued waits for the command to
1450 * execute. Establish a new sync point.
1451 */
1452 ath6kl_wmi_sync_point(wmi);
1453 }
1454
1455 return 0;
1456}
1457
1458int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type,
1459 enum dot11_auth_mode dot11_auth_mode,
1460 enum auth_mode auth_mode,
1461 enum crypto_type pairwise_crypto,
1462 u8 pairwise_crypto_len,
1463 enum crypto_type group_crypto,
1464 u8 group_crypto_len, int ssid_len, u8 *ssid,
1465 u8 *bssid, u16 channel, u32 ctrl_flags)
1466{
1467 struct sk_buff *skb;
1468 struct wmi_connect_cmd *cc;
1469 int ret;
1470
1471 wmi->traffic_class = 100;
1472
1473 if ((pairwise_crypto == NONE_CRYPT) && (group_crypto != NONE_CRYPT))
1474 return -EINVAL;
1475
1476 if ((pairwise_crypto != NONE_CRYPT) && (group_crypto == NONE_CRYPT))
1477 return -EINVAL;
1478
1479 skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_connect_cmd));
1480 if (!skb)
1481 return -ENOMEM;
1482
1483 cc = (struct wmi_connect_cmd *) skb->data;
1484
1485 if (ssid_len)
1486 memcpy(cc->ssid, ssid, ssid_len);
1487
1488 cc->ssid_len = ssid_len;
1489 cc->nw_type = nw_type;
1490 cc->dot11_auth_mode = dot11_auth_mode;
1491 cc->auth_mode = auth_mode;
1492 cc->prwise_crypto_type = pairwise_crypto;
1493 cc->prwise_crypto_len = pairwise_crypto_len;
1494 cc->grp_crypto_type = group_crypto;
1495 cc->grp_crypto_len = group_crypto_len;
1496 cc->ch = cpu_to_le16(channel);
1497 cc->ctrl_flags = cpu_to_le32(ctrl_flags);
1498
1499 if (bssid != NULL)
1500 memcpy(cc->bssid, bssid, ETH_ALEN);
1501
1502 wmi->pair_crypto_type = pairwise_crypto;
1503 wmi->grp_crypto_type = group_crypto;
1504
1505 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG);
1506
1507 return ret;
1508}
1509
1510int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 *bssid, u16 channel)
1511{
1512 struct sk_buff *skb;
1513 struct wmi_reconnect_cmd *cc;
1514 int ret;
1515
1516 wmi->traffic_class = 100;
1517
1518 skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_reconnect_cmd));
1519 if (!skb)
1520 return -ENOMEM;
1521
1522 cc = (struct wmi_reconnect_cmd *) skb->data;
1523 cc->channel = cpu_to_le16(channel);
1524
1525 if (bssid != NULL)
1526 memcpy(cc->bssid, bssid, ETH_ALEN);
1527
1528 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_RECONNECT_CMDID,
1529 NO_SYNC_WMIFLAG);
1530
1531 return ret;
1532}
1533
1534int ath6kl_wmi_disconnect_cmd(struct wmi *wmi)
1535{
1536 int ret;
1537
1538 wmi->traffic_class = 100;
1539
1540 /* Disconnect command does not need to do a SYNC before. */
1541 ret = ath6kl_wmi_simple_cmd(wmi, WMI_DISCONNECT_CMDID);
1542
1543 return ret;
1544}
1545
1546int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
1547 u32 force_fgscan, u32 is_legacy,
1548 u32 home_dwell_time, u32 force_scan_interval,
1549 s8 num_chan, u16 *ch_list)
1550{
1551 struct sk_buff *skb;
1552 struct wmi_start_scan_cmd *sc;
1553 s8 size;
1554 int ret;
1555
1556 size = sizeof(struct wmi_start_scan_cmd);
1557
1558 if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN))
1559 return -EINVAL;
1560
1561 if (num_chan > WMI_MAX_CHANNELS)
1562 return -EINVAL;
1563
1564 if (num_chan)
1565 size += sizeof(u16) * (num_chan - 1);
1566
1567 skb = ath6kl_wmi_get_new_buf(size);
1568 if (!skb)
1569 return -ENOMEM;
1570
1571 sc = (struct wmi_start_scan_cmd *) skb->data;
1572 sc->scan_type = scan_type;
1573 sc->force_fg_scan = cpu_to_le32(force_fgscan);
1574 sc->is_legacy = cpu_to_le32(is_legacy);
1575 sc->home_dwell_time = cpu_to_le32(home_dwell_time);
1576 sc->force_scan_intvl = cpu_to_le32(force_scan_interval);
1577 sc->num_ch = num_chan;
1578
1579 if (num_chan)
1580 memcpy(sc->ch_list, ch_list, num_chan * sizeof(u16));
1581
1582 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_START_SCAN_CMDID,
1583 NO_SYNC_WMIFLAG);
1584
1585 return ret;
1586}
1587
1588int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u16 fg_start_sec,
1589 u16 fg_end_sec, u16 bg_sec,
1590 u16 minact_chdw_msec, u16 maxact_chdw_msec,
1591 u16 pas_chdw_msec, u8 short_scan_ratio,
1592 u8 scan_ctrl_flag, u32 max_dfsch_act_time,
1593 u16 maxact_scan_per_ssid)
1594{
1595 struct sk_buff *skb;
1596 struct wmi_scan_params_cmd *sc;
1597 int ret;
1598
1599 skb = ath6kl_wmi_get_new_buf(sizeof(*sc));
1600 if (!skb)
1601 return -ENOMEM;
1602
1603 sc = (struct wmi_scan_params_cmd *) skb->data;
1604 sc->fg_start_period = cpu_to_le16(fg_start_sec);
1605 sc->fg_end_period = cpu_to_le16(fg_end_sec);
1606 sc->bg_period = cpu_to_le16(bg_sec);
1607 sc->minact_chdwell_time = cpu_to_le16(minact_chdw_msec);
1608 sc->maxact_chdwell_time = cpu_to_le16(maxact_chdw_msec);
1609 sc->pas_chdwell_time = cpu_to_le16(pas_chdw_msec);
1610 sc->short_scan_ratio = short_scan_ratio;
1611 sc->scan_ctrl_flags = scan_ctrl_flag;
1612 sc->max_dfsch_act_time = cpu_to_le32(max_dfsch_act_time);
1613 sc->maxact_scan_per_ssid = cpu_to_le16(maxact_scan_per_ssid);
1614
1615 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_SCAN_PARAMS_CMDID,
1616 NO_SYNC_WMIFLAG);
1617 return ret;
1618}
1619
1620int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 filter, u32 ie_mask)
1621{
1622 struct sk_buff *skb;
1623 struct wmi_bss_filter_cmd *cmd;
1624 int ret;
1625
1626 if (filter >= LAST_BSS_FILTER)
1627 return -EINVAL;
1628
1629 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1630 if (!skb)
1631 return -ENOMEM;
1632
1633 cmd = (struct wmi_bss_filter_cmd *) skb->data;
1634 cmd->bss_filter = filter;
1635 cmd->ie_mask = cpu_to_le32(ie_mask);
1636
1637 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_BSS_FILTER_CMDID,
1638 NO_SYNC_WMIFLAG);
1639 return ret;
1640}
1641
1642int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 index, u8 flag,
1643 u8 ssid_len, u8 *ssid)
1644{
1645 struct sk_buff *skb;
1646 struct wmi_probed_ssid_cmd *cmd;
1647 int ret;
1648
1649 if (index > MAX_PROBED_SSID_INDEX)
1650 return -EINVAL;
1651
1652 if (ssid_len > sizeof(cmd->ssid))
1653 return -EINVAL;
1654
1655 if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssid_len > 0))
1656 return -EINVAL;
1657
1658 if ((flag & SPECIFIC_SSID_FLAG) && !ssid_len)
1659 return -EINVAL;
1660
1661 if (flag & SPECIFIC_SSID_FLAG)
1662 wmi->is_probe_ssid = true;
1663
1664 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1665 if (!skb)
1666 return -ENOMEM;
1667
1668 cmd = (struct wmi_probed_ssid_cmd *) skb->data;
1669 cmd->entry_index = index;
1670 cmd->flag = flag;
1671 cmd->ssid_len = ssid_len;
1672 memcpy(cmd->ssid, ssid, ssid_len);
1673
1674 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_PROBED_SSID_CMDID,
1675 NO_SYNC_WMIFLAG);
1676 return ret;
1677}
1678
1679int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u16 listen_interval,
1680 u16 listen_beacons)
1681{
1682 struct sk_buff *skb;
1683 struct wmi_listen_int_cmd *cmd;
1684 int ret;
1685
1686 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1687 if (!skb)
1688 return -ENOMEM;
1689
1690 cmd = (struct wmi_listen_int_cmd *) skb->data;
1691 cmd->listen_intvl = cpu_to_le16(listen_interval);
1692 cmd->num_beacons = cpu_to_le16(listen_beacons);
1693
1694 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_LISTEN_INT_CMDID,
1695 NO_SYNC_WMIFLAG);
1696 return ret;
1697}
1698
1699int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 pwr_mode)
1700{
1701 struct sk_buff *skb;
1702 struct wmi_power_mode_cmd *cmd;
1703 int ret;
1704
1705 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1706 if (!skb)
1707 return -ENOMEM;
1708
1709 cmd = (struct wmi_power_mode_cmd *) skb->data;
1710 cmd->pwr_mode = pwr_mode;
1711 wmi->pwr_mode = pwr_mode;
1712
1713 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_POWER_MODE_CMDID,
1714 NO_SYNC_WMIFLAG);
1715 return ret;
1716}
1717
1718int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period,
1719 u16 ps_poll_num, u16 dtim_policy,
1720 u16 tx_wakeup_policy, u16 num_tx_to_wakeup,
1721 u16 ps_fail_event_policy)
1722{
1723 struct sk_buff *skb;
1724 struct wmi_power_params_cmd *pm;
1725 int ret;
1726
1727 skb = ath6kl_wmi_get_new_buf(sizeof(*pm));
1728 if (!skb)
1729 return -ENOMEM;
1730
1731 pm = (struct wmi_power_params_cmd *)skb->data;
1732 pm->idle_period = cpu_to_le16(idle_period);
1733 pm->pspoll_number = cpu_to_le16(ps_poll_num);
1734 pm->dtim_policy = cpu_to_le16(dtim_policy);
1735 pm->tx_wakeup_policy = cpu_to_le16(tx_wakeup_policy);
1736 pm->num_tx_to_wakeup = cpu_to_le16(num_tx_to_wakeup);
1737 pm->ps_fail_event_policy = cpu_to_le16(ps_fail_event_policy);
1738
1739 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_POWER_PARAMS_CMDID,
1740 NO_SYNC_WMIFLAG);
1741 return ret;
1742}
1743
1744int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout)
1745{
1746 struct sk_buff *skb;
1747 struct wmi_disc_timeout_cmd *cmd;
1748 int ret;
1749
1750 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1751 if (!skb)
1752 return -ENOMEM;
1753
1754 cmd = (struct wmi_disc_timeout_cmd *) skb->data;
1755 cmd->discon_timeout = timeout;
1756
1757 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_DISC_TIMEOUT_CMDID,
1758 NO_SYNC_WMIFLAG);
1759 return ret;
1760}
1761
1762int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
1763 enum crypto_type key_type,
1764 u8 key_usage, u8 key_len,
1765 u8 *key_rsc, u8 *key_material,
1766 u8 key_op_ctrl, u8 *mac_addr,
1767 enum wmi_sync_flag sync_flag)
1768{
1769 struct sk_buff *skb;
1770 struct wmi_add_cipher_key_cmd *cmd;
1771 int ret;
1772
1773 if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) ||
1774 (key_material == NULL))
1775 return -EINVAL;
1776
1777 if ((WEP_CRYPT != key_type) && (NULL == key_rsc))
1778 return -EINVAL;
1779
1780 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1781 if (!skb)
1782 return -ENOMEM;
1783
1784 cmd = (struct wmi_add_cipher_key_cmd *) skb->data;
1785 cmd->key_index = key_index;
1786 cmd->key_type = key_type;
1787 cmd->key_usage = key_usage;
1788 cmd->key_len = key_len;
1789 memcpy(cmd->key, key_material, key_len);
1790
1791 if (key_rsc != NULL)
1792 memcpy(cmd->key_rsc, key_rsc, sizeof(cmd->key_rsc));
1793
1794 cmd->key_op_ctrl = key_op_ctrl;
1795
1796 if (mac_addr)
1797 memcpy(cmd->key_mac_addr, mac_addr, ETH_ALEN);
1798
1799 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_ADD_CIPHER_KEY_CMDID,
1800 sync_flag);
1801
1802 return ret;
1803}
1804
1805int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 *krk)
1806{
1807 struct sk_buff *skb;
1808 struct wmi_add_krk_cmd *cmd;
1809 int ret;
1810
1811 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1812 if (!skb)
1813 return -ENOMEM;
1814
1815 cmd = (struct wmi_add_krk_cmd *) skb->data;
1816 memcpy(cmd->krk, krk, WMI_KRK_LEN);
1817
1818 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG);
1819
1820 return ret;
1821}
1822
1823int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 key_index)
1824{
1825 struct sk_buff *skb;
1826 struct wmi_delete_cipher_key_cmd *cmd;
1827 int ret;
1828
1829 if (key_index > WMI_MAX_KEY_INDEX)
1830 return -EINVAL;
1831
1832 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1833 if (!skb)
1834 return -ENOMEM;
1835
1836 cmd = (struct wmi_delete_cipher_key_cmd *) skb->data;
1837 cmd->key_index = key_index;
1838
1839 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_DELETE_CIPHER_KEY_CMDID,
1840 NO_SYNC_WMIFLAG);
1841
1842 return ret;
1843}
1844
1845int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, const u8 *bssid,
1846 const u8 *pmkid, bool set)
1847{
1848 struct sk_buff *skb;
1849 struct wmi_setpmkid_cmd *cmd;
1850 int ret;
1851
1852 if (bssid == NULL)
1853 return -EINVAL;
1854
1855 if (set && pmkid == NULL)
1856 return -EINVAL;
1857
1858 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1859 if (!skb)
1860 return -ENOMEM;
1861
1862 cmd = (struct wmi_setpmkid_cmd *) skb->data;
1863 memcpy(cmd->bssid, bssid, ETH_ALEN);
1864 if (set) {
1865 memcpy(cmd->pmkid, pmkid, sizeof(cmd->pmkid));
1866 cmd->enable = PMKID_ENABLE;
1867 } else {
1868 memset(cmd->pmkid, 0, sizeof(cmd->pmkid));
1869 cmd->enable = PMKID_DISABLE;
1870 }
1871
1872 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_PMKID_CMDID,
1873 NO_SYNC_WMIFLAG);
1874
1875 return ret;
1876}
1877
1878static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb,
1879 enum htc_endpoint_id ep_id)
1880{
1881 struct wmi_data_hdr *data_hdr;
1882 int ret;
1883
1884 if (WARN_ON(skb == NULL || ep_id == wmi->ep_id))
1885 return -EINVAL;
1886
1887 skb_push(skb, sizeof(struct wmi_data_hdr));
1888
1889 data_hdr = (struct wmi_data_hdr *) skb->data;
1890 data_hdr->info = SYNC_MSGTYPE << WMI_DATA_HDR_MSG_TYPE_SHIFT;
1891 data_hdr->info3 = 0;
1892
1893 ret = ath6kl_control_tx(wmi->parent_dev, skb, ep_id);
1894
1895 return ret;
1896}
1897
1898static int ath6kl_wmi_sync_point(struct wmi *wmi)
1899{
1900 struct sk_buff *skb;
1901 struct wmi_sync_cmd *cmd;
1902 struct wmi_data_sync_bufs data_sync_bufs[WMM_NUM_AC];
1903 enum htc_endpoint_id ep_id;
1904 u8 index, num_pri_streams = 0;
1905 int ret = 0;
1906
1907 memset(data_sync_bufs, 0, sizeof(data_sync_bufs));
1908
1909 spin_lock_bh(&wmi->lock);
1910
1911 for (index = 0; index < WMM_NUM_AC; index++) {
1912 if (wmi->fat_pipe_exist & (1 << index)) {
1913 num_pri_streams++;
1914 data_sync_bufs[num_pri_streams - 1].traffic_class =
1915 index;
1916 }
1917 }
1918
1919 spin_unlock_bh(&wmi->lock);
1920
1921 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
1922 if (!skb) {
1923 ret = -ENOMEM;
1924 goto free_skb;
1925 }
1926
1927 cmd = (struct wmi_sync_cmd *) skb->data;
1928
1929 /*
1930 * In the SYNC cmd sent on the control Ep, send a bitmap
1931 * of the data eps on which the Data Sync will be sent
1932 */
1933 cmd->data_sync_map = wmi->fat_pipe_exist;
1934
1935 for (index = 0; index < num_pri_streams; index++) {
1936 data_sync_bufs[index].skb = ath6kl_buf_alloc(0);
1937 if (data_sync_bufs[index].skb == NULL) {
1938 ret = -ENOMEM;
1939 break;
1940 }
1941 }
1942
1943 /*
1944 * If buffer allocation for any of the dataSync fails,
1945 * then do not send the Synchronize cmd on the control ep
1946 */
1947 if (ret)
1948 goto free_skb;
1949
1950 /*
1951 * Send sync cmd followed by sync data messages on all
1952 * endpoints being used
1953 */
1954 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SYNCHRONIZE_CMDID,
1955 NO_SYNC_WMIFLAG);
1956
1957 if (ret)
1958 goto free_skb;
1959
1960 /* cmd buffer sent, we no longer own it */
1961 skb = NULL;
1962
1963 for (index = 0; index < num_pri_streams; index++) {
1964
1965 if (WARN_ON(!data_sync_bufs[index].skb))
1966 break;
1967
1968 ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev,
1969 data_sync_bufs[index].
1970 traffic_class);
1971 ret =
1972 ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb,
1973 ep_id);
1974
1975 if (ret)
1976 break;
1977
1978 data_sync_bufs[index].skb = NULL;
1979 }
1980
1981free_skb:
1982 /* free up any resources left over (possibly due to an error) */
1983 if (skb)
1984 dev_kfree_skb(skb);
1985
1986 for (index = 0; index < num_pri_streams; index++) {
1987 if (data_sync_bufs[index].skb != NULL) {
1988 dev_kfree_skb((struct sk_buff *)data_sync_bufs[index].
1989 skb);
1990 }
1991 }
1992
1993 return ret;
1994}
1995
1996int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi,
1997 struct wmi_create_pstream_cmd *params)
1998{
1999 struct sk_buff *skb;
2000 struct wmi_create_pstream_cmd *cmd;
2001 u8 fatpipe_exist_for_ac = 0;
2002 s32 min_phy = 0;
2003 s32 nominal_phy = 0;
2004 int ret;
2005
2006 if (!((params->user_pri < 8) &&
2007 (params->user_pri <= 0x7) &&
2008 (up_to_ac[params->user_pri & 0x7] == params->traffic_class) &&
2009 (params->traffic_direc == UPLINK_TRAFFIC ||
2010 params->traffic_direc == DNLINK_TRAFFIC ||
2011 params->traffic_direc == BIDIR_TRAFFIC) &&
2012 (params->traffic_type == TRAFFIC_TYPE_APERIODIC ||
2013 params->traffic_type == TRAFFIC_TYPE_PERIODIC) &&
2014 (params->voice_psc_cap == DISABLE_FOR_THIS_AC ||
2015 params->voice_psc_cap == ENABLE_FOR_THIS_AC ||
2016 params->voice_psc_cap == ENABLE_FOR_ALL_AC) &&
2017 (params->tsid == WMI_IMPLICIT_PSTREAM ||
2018 params->tsid <= WMI_MAX_THINSTREAM))) {
2019 return -EINVAL;
2020 }
2021
2022 /*
2023 * Check nominal PHY rate is >= minimalPHY,
2024 * so that DUT can allow TSRS IE
2025 */
2026
2027 /* Get the physical rate (units of bps) */
2028 min_phy = ((le32_to_cpu(params->min_phy_rate) / 1000) / 1000);
2029
2030 /* Check minimal phy < nominal phy rate */
2031 if (params->nominal_phy >= min_phy) {
2032 /* unit of 500 kbps */
2033 nominal_phy = (params->nominal_phy * 1000) / 500;
2034 ath6kl_dbg(ATH6KL_DBG_WMI,
2035 "TSRS IE enabled::MinPhy %x->NominalPhy ===> %x\n",
2036 min_phy, nominal_phy);
2037
2038 params->nominal_phy = nominal_phy;
2039 } else {
2040 params->nominal_phy = 0;
2041 }
2042
2043 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
2044 if (!skb)
2045 return -ENOMEM;
2046
2047 ath6kl_dbg(ATH6KL_DBG_WMI,
2048 "sending create_pstream_cmd: ac=%d tsid:%d\n",
2049 params->traffic_class, params->tsid);
2050
2051 cmd = (struct wmi_create_pstream_cmd *) skb->data;
2052 memcpy(cmd, params, sizeof(*cmd));
2053
2054 /* This is an implicitly created Fat pipe */
2055 if ((u32) params->tsid == (u32) WMI_IMPLICIT_PSTREAM) {
2056 spin_lock_bh(&wmi->lock);
2057 fatpipe_exist_for_ac = (wmi->fat_pipe_exist &
2058 (1 << params->traffic_class));
2059 wmi->fat_pipe_exist |= (1 << params->traffic_class);
2060 spin_unlock_bh(&wmi->lock);
2061 } else {
2062 /* explicitly created thin stream within a fat pipe */
2063 spin_lock_bh(&wmi->lock);
2064 fatpipe_exist_for_ac = (wmi->fat_pipe_exist &
2065 (1 << params->traffic_class));
2066 wmi->stream_exist_for_ac[params->traffic_class] |=
2067 (1 << params->tsid);
2068 /*
2069 * If a thinstream becomes active, the fat pipe automatically
2070 * becomes active
2071 */
2072 wmi->fat_pipe_exist |= (1 << params->traffic_class);
2073 spin_unlock_bh(&wmi->lock);
2074 }
2075
2076 /*
2077 * Indicate activty change to driver layer only if this is the
2078 * first TSID to get created in this AC explicitly or an implicit
2079 * fat pipe is getting created.
2080 */
2081 if (!fatpipe_exist_for_ac)
2082 ath6kl_indicate_tx_activity(wmi->parent_dev,
2083 params->traffic_class, true);
2084
2085 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_CREATE_PSTREAM_CMDID,
2086 NO_SYNC_WMIFLAG);
2087 return ret;
2088}
2089
2090int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 traffic_class, u8 tsid)
2091{
2092 struct sk_buff *skb;
2093 struct wmi_delete_pstream_cmd *cmd;
2094 u16 active_tsids = 0;
2095 int ret;
2096
2097 if (traffic_class > 3) {
2098 ath6kl_err("invalid traffic class: %d\n", traffic_class);
2099 return -EINVAL;
2100 }
2101
2102 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
2103 if (!skb)
2104 return -ENOMEM;
2105
2106 cmd = (struct wmi_delete_pstream_cmd *) skb->data;
2107 cmd->traffic_class = traffic_class;
2108 cmd->tsid = tsid;
2109
2110 spin_lock_bh(&wmi->lock);
2111 active_tsids = wmi->stream_exist_for_ac[traffic_class];
2112 spin_unlock_bh(&wmi->lock);
2113
2114 if (!(active_tsids & (1 << tsid))) {
2115 dev_kfree_skb(skb);
2116 ath6kl_dbg(ATH6KL_DBG_WMI,
2117 "TSID %d doesn't exist for traffic class: %d\n",
2118 tsid, traffic_class);
2119 return -ENODATA;
2120 }
2121
2122 ath6kl_dbg(ATH6KL_DBG_WMI,
2123 "sending delete_pstream_cmd: traffic class: %d tsid=%d\n",
2124 traffic_class, tsid);
2125
2126 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_DELETE_PSTREAM_CMDID,
2127 SYNC_BEFORE_WMIFLAG);
2128
2129 spin_lock_bh(&wmi->lock);
2130 wmi->stream_exist_for_ac[traffic_class] &= ~(1 << tsid);
2131 active_tsids = wmi->stream_exist_for_ac[traffic_class];
2132 spin_unlock_bh(&wmi->lock);
2133
2134 /*
2135 * Indicate stream inactivity to driver layer only if all tsids
2136 * within this AC are deleted.
2137 */
2138 if (!active_tsids) {
2139 ath6kl_indicate_tx_activity(wmi->parent_dev,
2140 traffic_class, false);
2141 wmi->fat_pipe_exist &= ~(1 << traffic_class);
2142 }
2143
2144 return ret;
2145}
2146
2147int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd)
2148{
2149 struct sk_buff *skb;
2150 struct wmi_set_ip_cmd *cmd;
2151 int ret;
2152
2153 /* Multicast address are not valid */
2154 if ((*((u8 *) &ip_cmd->ips[0]) >= 0xE0) ||
2155 (*((u8 *) &ip_cmd->ips[1]) >= 0xE0))
2156 return -EINVAL;
2157
2158 skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_ip_cmd));
2159 if (!skb)
2160 return -ENOMEM;
2161
2162 cmd = (struct wmi_set_ip_cmd *) skb->data;
2163 memcpy(cmd, ip_cmd, sizeof(struct wmi_set_ip_cmd));
2164
2165 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_IP_CMDID, NO_SYNC_WMIFLAG);
2166 return ret;
2167}
2168
2169static int ath6kl_wmi_get_wow_list_event_rx(struct wmi *wmi, u8 * datap,
2170 int len)
2171{
2172 if (len < sizeof(struct wmi_get_wow_list_reply))
2173 return -EINVAL;
2174
2175 return 0;
2176}
2177
2178static int ath6kl_wmi_cmd_send_xtnd(struct wmi *wmi, struct sk_buff *skb,
2179 enum wmix_command_id cmd_id,
2180 enum wmi_sync_flag sync_flag)
2181{
2182 struct wmix_cmd_hdr *cmd_hdr;
2183 int ret;
2184
2185 skb_push(skb, sizeof(struct wmix_cmd_hdr));
2186
2187 cmd_hdr = (struct wmix_cmd_hdr *) skb->data;
2188 cmd_hdr->cmd_id = cpu_to_le32(cmd_id);
2189
2190 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_EXTENSION_CMDID, sync_flag);
2191
2192 return ret;
2193}
2194
2195int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source)
2196{
2197 struct sk_buff *skb;
2198 struct wmix_hb_challenge_resp_cmd *cmd;
2199 int ret;
2200
2201 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
2202 if (!skb)
2203 return -ENOMEM;
2204
2205 cmd = (struct wmix_hb_challenge_resp_cmd *) skb->data;
2206 cmd->cookie = cpu_to_le32(cookie);
2207 cmd->source = cpu_to_le32(source);
2208
2209 ret = ath6kl_wmi_cmd_send_xtnd(wmi, skb, WMIX_HB_CHALLENGE_RESP_CMDID,
2210 NO_SYNC_WMIFLAG);
2211 return ret;
2212}
2213
2214int ath6kl_wmi_get_stats_cmd(struct wmi *wmi)
2215{
2216 return ath6kl_wmi_simple_cmd(wmi, WMI_GET_STATISTICS_CMDID);
2217}
2218
2219int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM)
2220{
2221 struct sk_buff *skb;
2222 struct wmi_set_tx_pwr_cmd *cmd;
2223 int ret;
2224
2225 skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_tx_pwr_cmd));
2226 if (!skb)
2227 return -ENOMEM;
2228
2229 cmd = (struct wmi_set_tx_pwr_cmd *) skb->data;
2230 cmd->dbM = dbM;
2231
2232 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_TX_PWR_CMDID,
2233 NO_SYNC_WMIFLAG);
2234
2235 return ret;
2236}
2237
2238int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi)
2239{
2240 return ath6kl_wmi_simple_cmd(wmi, WMI_GET_TX_PWR_CMDID);
2241}
2242
2243int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status, u8 preamble_policy)
2244{
2245 struct sk_buff *skb;
2246 struct wmi_set_lpreamble_cmd *cmd;
2247 int ret;
2248
2249 skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_lpreamble_cmd));
2250 if (!skb)
2251 return -ENOMEM;
2252
2253 cmd = (struct wmi_set_lpreamble_cmd *) skb->data;
2254 cmd->status = status;
2255 cmd->preamble_policy = preamble_policy;
2256
2257 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_LPREAMBLE_CMDID,
2258 NO_SYNC_WMIFLAG);
2259 return ret;
2260}
2261
2262int ath6kl_wmi_set_rts_cmd(struct wmi *wmi, u16 threshold)
2263{
2264 struct sk_buff *skb;
2265 struct wmi_set_rts_cmd *cmd;
2266 int ret;
2267
2268 skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_rts_cmd));
2269 if (!skb)
2270 return -ENOMEM;
2271
2272 cmd = (struct wmi_set_rts_cmd *) skb->data;
2273 cmd->threshold = cpu_to_le16(threshold);
2274
2275 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_RTS_CMDID, NO_SYNC_WMIFLAG);
2276 return ret;
2277}
2278
2279int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg)
2280{
2281 struct sk_buff *skb;
2282 struct wmi_set_wmm_txop_cmd *cmd;
2283 int ret;
2284
2285 if (!((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)))
2286 return -EINVAL;
2287
2288 skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_wmm_txop_cmd));
2289 if (!skb)
2290 return -ENOMEM;
2291
2292 cmd = (struct wmi_set_wmm_txop_cmd *) skb->data;
2293 cmd->txop_enable = cfg;
2294
2295 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_WMM_TXOP_CMDID,
2296 NO_SYNC_WMIFLAG);
2297 return ret;
2298}
2299
2300int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl)
2301{
2302 struct sk_buff *skb;
2303 struct wmi_set_keepalive_cmd *cmd;
2304 int ret;
2305
2306 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
2307 if (!skb)
2308 return -ENOMEM;
2309
2310 cmd = (struct wmi_set_keepalive_cmd *) skb->data;
2311 cmd->keep_alive_intvl = keep_alive_intvl;
2312 wmi->keep_alive_intvl = keep_alive_intvl;
2313
2314 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_KEEPALIVE_CMDID,
2315 NO_SYNC_WMIFLAG);
2316 return ret;
2317}
2318
2319s32 ath6kl_wmi_get_rate(s8 rate_index)
2320{
2321 if (rate_index == RATE_AUTO)
2322 return 0;
2323
2324 return wmi_rate_tbl[(u32) rate_index][0];
2325}
2326
2327void ath6kl_wmi_node_return(struct wmi *wmi, struct bss *bss)
2328{
2329 if (bss)
2330 wlan_node_return(&wmi->parent_dev->scan_table, bss);
2331}
2332
2333struct bss *ath6kl_wmi_find_ssid_node(struct wmi *wmi, u8 * ssid,
2334 u32 ssid_len, bool is_wpa2,
2335 bool match_ssid)
2336{
2337 struct bss *node = NULL;
2338
2339 node = wlan_find_ssid_node(&wmi->parent_dev->scan_table, ssid,
2340 ssid_len, is_wpa2, match_ssid);
2341 return node;
2342}
2343
2344struct bss *ath6kl_wmi_find_node(struct wmi *wmi, const u8 * mac_addr)
2345{
2346 struct bss *ni = NULL;
2347
2348 ni = wlan_find_node(&wmi->parent_dev->scan_table, mac_addr);
2349
2350 return ni;
2351}
2352
2353void ath6kl_wmi_node_free(struct wmi *wmi, const u8 * mac_addr)
2354{
2355 struct bss *ni = NULL;
2356
2357 ni = wlan_find_node(&wmi->parent_dev->scan_table, mac_addr);
2358 if (ni != NULL)
2359 wlan_node_reclaim(&wmi->parent_dev->scan_table, ni);
2360
2361 return;
2362}
2363
2364static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
2365 u32 len)
2366{
2367 struct wmi_pmkid_list_reply *reply;
2368 u32 expected_len;
2369
2370 if (len < sizeof(struct wmi_pmkid_list_reply))
2371 return -EINVAL;
2372
2373 reply = (struct wmi_pmkid_list_reply *)datap;
2374 expected_len = sizeof(reply->num_pmkid) +
2375 le32_to_cpu(reply->num_pmkid) * WMI_PMKID_LEN;
2376
2377 if (len < expected_len)
2378 return -EINVAL;
2379
2380 return 0;
2381}
2382
2383static int ath6kl_wmi_addba_req_event_rx(struct wmi *wmi, u8 *datap, int len)
2384{
2385 struct wmi_addba_req_event *cmd = (struct wmi_addba_req_event *) datap;
2386
2387 aggr_recv_addba_req_evt(wmi->parent_dev, cmd->tid,
2388 le16_to_cpu(cmd->st_seq_no), cmd->win_sz);
2389
2390 return 0;
2391}
2392
2393static int ath6kl_wmi_delba_req_event_rx(struct wmi *wmi, u8 *datap, int len)
2394{
2395 struct wmi_delba_event *cmd = (struct wmi_delba_event *) datap;
2396
2397 aggr_recv_delba_req_evt(wmi->parent_dev, cmd->tid);
2398
2399 return 0;
2400}
2401
2402/* AP mode functions */
2403static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len)
2404{
2405 struct wmi_pspoll_event *ev;
2406
2407 if (len < sizeof(struct wmi_pspoll_event))
2408 return -EINVAL;
2409
2410 ev = (struct wmi_pspoll_event *) datap;
2411
2412 ath6kl_pspoll_event(wmi->parent_dev, le16_to_cpu(ev->aid));
2413
2414 return 0;
2415}
2416
2417static int ath6kl_wmi_dtimexpiry_event_rx(struct wmi *wmi, u8 *datap, int len)
2418{
2419 ath6kl_dtimexpiry_event(wmi->parent_dev);
2420
2421 return 0;
2422}
2423
2424int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag)
2425{
2426 struct sk_buff *skb;
2427 struct wmi_ap_set_pvb_cmd *cmd;
2428 int ret;
2429
2430 skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_ap_set_pvb_cmd));
2431 if (!skb)
2432 return -ENOMEM;
2433
2434 cmd = (struct wmi_ap_set_pvb_cmd *) skb->data;
2435 cmd->aid = cpu_to_le16(aid);
2436 cmd->flag = cpu_to_le32(flag);
2437
2438 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_AP_SET_PVB_CMDID,
2439 NO_SYNC_WMIFLAG);
2440
2441 return 0;
2442}
2443
2444int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_ver,
2445 bool rx_dot11_hdr, bool defrag_on_host)
2446{
2447 struct sk_buff *skb;
2448 struct wmi_rx_frame_format_cmd *cmd;
2449 int ret;
2450
2451 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
2452 if (!skb)
2453 return -ENOMEM;
2454
2455 cmd = (struct wmi_rx_frame_format_cmd *) skb->data;
2456 cmd->dot11_hdr = rx_dot11_hdr ? 1 : 0;
2457 cmd->defrag_on_host = defrag_on_host ? 1 : 0;
2458 cmd->meta_ver = rx_meta_ver;
2459
2460 /* Delete the local aggr state, on host */
2461 ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_RX_FRAME_FORMAT_CMDID,
2462 NO_SYNC_WMIFLAG);
2463
2464 return ret;
2465}
2466
2467static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
2468{
2469 struct wmix_cmd_hdr *cmd;
2470 u32 len;
2471 u16 id;
2472 u8 *datap;
2473 int ret = 0;
2474
2475 if (skb->len < sizeof(struct wmix_cmd_hdr)) {
2476 ath6kl_err("bad packet 1\n");
2477 wmi->stat.cmd_len_err++;
2478 return -EINVAL;
2479 }
2480
2481 cmd = (struct wmix_cmd_hdr *) skb->data;
2482 id = le32_to_cpu(cmd->cmd_id);
2483
2484 skb_pull(skb, sizeof(struct wmix_cmd_hdr));
2485
2486 datap = skb->data;
2487 len = skb->len;
2488
2489 switch (id) {
2490 case WMIX_HB_CHALLENGE_RESP_EVENTID:
2491 break;
2492 case WMIX_DBGLOG_EVENTID:
2493 break;
2494 default:
2495 ath6kl_err("unknown cmd id 0x%x\n", id);
2496 wmi->stat.cmd_id_err++;
2497 ret = -EINVAL;
2498 break;
2499 }
2500
2501 return ret;
2502}
2503
2504/* Control Path */
2505int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
2506{
2507 struct wmi_cmd_hdr *cmd;
2508 u32 len;
2509 u16 id;
2510 u8 *datap;
2511 int ret = 0;
2512
2513 if (WARN_ON(skb == NULL))
2514 return -EINVAL;
2515
2516 if (skb->len < sizeof(struct wmi_cmd_hdr)) {
2517 ath6kl_err("bad packet 1\n");
2518 dev_kfree_skb(skb);
2519 wmi->stat.cmd_len_err++;
2520 return -EINVAL;
2521 }
2522
2523 cmd = (struct wmi_cmd_hdr *) skb->data;
2524 id = le16_to_cpu(cmd->cmd_id);
2525
2526 skb_pull(skb, sizeof(struct wmi_cmd_hdr));
2527
2528 datap = skb->data;
2529 len = skb->len;
2530
2531 ath6kl_dbg(ATH6KL_DBG_WMI, "%s: wmi id: %d\n", __func__, id);
2532 ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "msg payload ", datap, len);
2533
2534 switch (id) {
2535 case WMI_GET_BITRATE_CMDID:
2536 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_BITRATE_CMDID\n");
2537 ret = ath6kl_wmi_bitrate_reply_rx(wmi, datap, len);
2538 break;
2539 case WMI_GET_CHANNEL_LIST_CMDID:
2540 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_CHANNEL_LIST_CMDID\n");
2541 ret = ath6kl_wmi_ch_list_reply_rx(wmi, datap, len);
2542 break;
2543 case WMI_GET_TX_PWR_CMDID:
2544 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_TX_PWR_CMDID\n");
2545 ret = ath6kl_wmi_tx_pwr_reply_rx(wmi, datap, len);
2546 break;
2547 case WMI_READY_EVENTID:
2548 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_READY_EVENTID\n");
2549 ret = ath6kl_wmi_ready_event_rx(wmi, datap, len);
2550 break;
2551 case WMI_CONNECT_EVENTID:
2552 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n");
2553 ret = ath6kl_wmi_connect_event_rx(wmi, datap, len);
2554 break;
2555 case WMI_DISCONNECT_EVENTID:
2556 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n");
2557 ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len);
2558 break;
2559 case WMI_PEER_NODE_EVENTID:
2560 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n");
2561 ret = ath6kl_wmi_peer_node_event_rx(wmi, datap, len);
2562 break;
2563 case WMI_TKIP_MICERR_EVENTID:
2564 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n");
2565 ret = ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len);
2566 break;
2567 case WMI_BSSINFO_EVENTID:
2568 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n");
2569 ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(skb, datap);
2570 ret = ath6kl_wmi_bssinfo_event_rx(wmi, skb->data, skb->len);
2571 break;
2572 case WMI_REGDOMAIN_EVENTID:
2573 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n");
2574 break;
2575 case WMI_PSTREAM_TIMEOUT_EVENTID:
2576 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n");
2577 ret = ath6kl_wmi_pstream_timeout_event_rx(wmi, datap, len);
2578 break;
2579 case WMI_NEIGHBOR_REPORT_EVENTID:
2580 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n");
2581 break;
2582 case WMI_SCAN_COMPLETE_EVENTID:
2583 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n");
2584 ret = ath6kl_wmi_scan_complete_rx(wmi, datap, len);
2585 break;
2586 case WMI_CMDERROR_EVENTID:
2587 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n");
2588 ret = ath6kl_wmi_error_event_rx(wmi, datap, len);
2589 break;
2590 case WMI_REPORT_STATISTICS_EVENTID:
2591 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n");
2592 ret = ath6kl_wmi_stats_event_rx(wmi, datap, len);
2593 break;
2594 case WMI_RSSI_THRESHOLD_EVENTID:
2595 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n");
2596 ret = ath6kl_wmi_rssi_threshold_event_rx(wmi, datap, len);
2597 break;
2598 case WMI_ERROR_REPORT_EVENTID:
2599 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ERROR_REPORT_EVENTID\n");
2600 break;
2601 case WMI_OPT_RX_FRAME_EVENTID:
2602 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_OPT_RX_FRAME_EVENTID\n");
2603 ret = ath6kl_wmi_opt_frame_event_rx(wmi, datap, len);
2604 break;
2605 case WMI_REPORT_ROAM_TBL_EVENTID:
2606 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_TBL_EVENTID\n");
2607 break;
2608 case WMI_EXTENSION_EVENTID:
2609 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n");
2610 ret = ath6kl_wmi_control_rx_xtnd(wmi, skb);
2611 break;
2612 case WMI_CAC_EVENTID:
2613 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n");
2614 ret = ath6kl_wmi_cac_event_rx(wmi, datap, len);
2615 break;
2616 case WMI_CHANNEL_CHANGE_EVENTID:
2617 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n");
2618 break;
2619 case WMI_REPORT_ROAM_DATA_EVENTID:
2620 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_DATA_EVENTID\n");
2621 break;
2622 case WMI_GET_FIXRATES_CMDID:
2623 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n");
2624 ret = ath6kl_wmi_ratemask_reply_rx(wmi, datap, len);
2625 break;
2626 case WMI_TX_RETRY_ERR_EVENTID:
2627 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_RETRY_ERR_EVENTID\n");
2628 break;
2629 case WMI_SNR_THRESHOLD_EVENTID:
2630 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SNR_THRESHOLD_EVENTID\n");
2631 ret = ath6kl_wmi_snr_threshold_event_rx(wmi, datap, len);
2632 break;
2633 case WMI_LQ_THRESHOLD_EVENTID:
2634 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_LQ_THRESHOLD_EVENTID\n");
2635 break;
2636 case WMI_APLIST_EVENTID:
2637 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_APLIST_EVENTID\n");
2638 ret = ath6kl_wmi_aplist_event_rx(wmi, datap, len);
2639 break;
2640 case WMI_GET_KEEPALIVE_CMDID:
2641 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_KEEPALIVE_CMDID\n");
2642 ret = ath6kl_wmi_keepalive_reply_rx(wmi, datap, len);
2643 break;
2644 case WMI_GET_WOW_LIST_EVENTID:
2645 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_WOW_LIST_EVENTID\n");
2646 ret = ath6kl_wmi_get_wow_list_event_rx(wmi, datap, len);
2647 break;
2648 case WMI_GET_PMKID_LIST_EVENTID:
2649 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_PMKID_LIST_EVENTID\n");
2650 ret = ath6kl_wmi_get_pmkid_list_event_rx(wmi, datap, len);
2651 break;
2652 case WMI_PSPOLL_EVENTID:
2653 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n");
2654 ret = ath6kl_wmi_pspoll_event_rx(wmi, datap, len);
2655 break;
2656 case WMI_DTIMEXPIRY_EVENTID:
2657 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n");
2658 ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len);
2659 break;
2660 case WMI_SET_PARAMS_REPLY_EVENTID:
2661 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_PARAMS_REPLY_EVENTID\n");
2662 break;
2663 case WMI_ADDBA_REQ_EVENTID:
2664 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n");
2665 ret = ath6kl_wmi_addba_req_event_rx(wmi, datap, len);
2666 break;
2667 case WMI_ADDBA_RESP_EVENTID:
2668 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_RESP_EVENTID\n");
2669 break;
2670 case WMI_DELBA_REQ_EVENTID:
2671 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n");
2672 ret = ath6kl_wmi_delba_req_event_rx(wmi, datap, len);
2673 break;
2674 case WMI_REPORT_BTCOEX_CONFIG_EVENTID:
2675 ath6kl_dbg(ATH6KL_DBG_WMI,
2676 "WMI_REPORT_BTCOEX_CONFIG_EVENTID\n");
2677 break;
2678 case WMI_REPORT_BTCOEX_STATS_EVENTID:
2679 ath6kl_dbg(ATH6KL_DBG_WMI,
2680 "WMI_REPORT_BTCOEX_STATS_EVENTID\n");
2681 break;
2682 case WMI_TX_COMPLETE_EVENTID:
2683 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n");
2684 ret = ath6kl_wmi_tx_complete_event_rx(datap, len);
2685 break;
2686 default:
2687 ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id);
2688 wmi->stat.cmd_id_err++;
2689 ret = -EINVAL;
2690 break;
2691 }
2692
2693 dev_kfree_skb(skb);
2694
2695 return ret;
2696}
2697
2698static void ath6kl_wmi_qos_state_init(struct wmi *wmi)
2699{
2700 if (!wmi)
2701 return;
2702
2703 spin_lock_bh(&wmi->lock);
2704
2705 wmi->fat_pipe_exist = 0;
2706 memset(wmi->stream_exist_for_ac, 0, sizeof(wmi->stream_exist_for_ac));
2707
2708 spin_unlock_bh(&wmi->lock);
2709}
2710
2711void *ath6kl_wmi_init(struct ath6kl *dev)
2712{
2713 struct wmi *wmi;
2714
2715 wmi = kzalloc(sizeof(struct wmi), GFP_KERNEL);
2716 if (!wmi)
2717 return NULL;
2718
2719 spin_lock_init(&wmi->lock);
2720
2721 wmi->parent_dev = dev;
2722
2723 ath6kl_wmi_qos_state_init(wmi);
2724
2725 wmi->pwr_mode = REC_POWER;
2726 wmi->phy_mode = WMI_11G_MODE;
2727
2728 wmi->pair_crypto_type = NONE_CRYPT;
2729 wmi->grp_crypto_type = NONE_CRYPT;
2730
2731 wmi->ht_allowed[A_BAND_24GHZ] = 1;
2732 wmi->ht_allowed[A_BAND_5GHZ] = 1;
2733
2734 return wmi;
2735}
2736
2737void ath6kl_wmi_shutdown(struct wmi *wmi)
2738{
2739 if (!wmi)
2740 return;
2741
2742 kfree(wmi);
2743}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
new file mode 100644
index 00000000000..fe3ddce6408
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -0,0 +1,2018 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*
18 * This file contains the definitions of the WMI protocol specified in the
19 * Wireless Module Interface (WMI). It includes definitions of all the
20 * commands and events. Commands are messages from the host to the WM.
21 * Events and Replies are messages from the WM to the host.
22 */
23
24#ifndef WMI_H
25#define WMI_H
26
27#include <linux/ieee80211.h>
28
29#include "htc.h"
30
31#define HTC_PROTOCOL_VERSION 0x0002
32#define WMI_PROTOCOL_VERSION 0x0002
33#define WMI_CONTROL_MSG_MAX_LEN 256
34#define is_ethertype(type_or_len) ((type_or_len) >= 0x0600)
35
36#define IP_ETHERTYPE 0x0800
37
38#define WMI_IMPLICIT_PSTREAM 0xFF
39#define WMI_MAX_THINSTREAM 15
40
41#define SSID_IE_LEN_INDEX 13
42
43/* Host side link management data structures */
44#define SIG_QUALITY_THRESH_LVLS 6
45#define SIG_QUALITY_UPPER_THRESH_LVLS SIG_QUALITY_THRESH_LVLS
46#define SIG_QUALITY_LOWER_THRESH_LVLS SIG_QUALITY_THRESH_LVLS
47
48#define A_BAND_24GHZ 0
49#define A_BAND_5GHZ 1
50#define A_NUM_BANDS 2
51
52/* in ms */
53#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000
54
55/*
56 * There are no signed versions of __le16 and __le32, so for a temporary
57 * solution come up with our own version. The idea is from fs/ntfs/types.h.
58 *
59 * Use a_ prefix so that it doesn't conflict if we get proper support to
60 * linux/types.h.
61 */
62typedef __s16 __bitwise a_sle16;
63typedef __s32 __bitwise a_sle32;
64
65static inline a_sle32 a_cpu_to_sle32(s32 val)
66{
67 return (__force a_sle32) cpu_to_le32(val);
68}
69
70static inline s32 a_sle32_to_cpu(a_sle32 val)
71{
72 return le32_to_cpu((__force __le32) val);
73}
74
75static inline a_sle16 a_cpu_to_sle16(s16 val)
76{
77 return (__force a_sle16) cpu_to_le16(val);
78}
79
80static inline s16 a_sle16_to_cpu(a_sle16 val)
81{
82 return le16_to_cpu((__force __le16) val);
83}
84
85struct sq_threshold_params {
86 s16 upper_threshold[SIG_QUALITY_UPPER_THRESH_LVLS];
87 s16 lower_threshold[SIG_QUALITY_LOWER_THRESH_LVLS];
88 u32 upper_threshold_valid_count;
89 u32 lower_threshold_valid_count;
90 u32 polling_interval;
91 u8 weight;
92 u8 last_rssi;
93 u8 last_rssi_poll_event;
94};
95
96struct wmi_stats {
97 u32 cmd_len_err;
98 u32 cmd_id_err;
99};
100
101struct wmi_data_sync_bufs {
102 u8 traffic_class;
103 struct sk_buff *skb;
104};
105
106/* WMM stream classes */
107#define WMM_NUM_AC 4
108#define WMM_AC_BE 0 /* best effort */
109#define WMM_AC_BK 1 /* background */
110#define WMM_AC_VI 2 /* video */
111#define WMM_AC_VO 3 /* voice */
112
113struct wmi {
114 bool ready;
115 u16 stream_exist_for_ac[WMM_NUM_AC];
116 u8 fat_pipe_exist;
117 struct ath6kl *parent_dev;
118 struct wmi_stats stat;
119 u8 pwr_mode;
120 u8 phy_mode;
121 u8 keep_alive_intvl;
122 spinlock_t lock;
123 enum htc_endpoint_id ep_id;
124 struct sq_threshold_params
125 sq_threshld[SIGNAL_QUALITY_METRICS_NUM_MAX];
126 enum crypto_type pair_crypto_type;
127 enum crypto_type grp_crypto_type;
128 bool is_wmm_enabled;
129 u8 ht_allowed[A_NUM_BANDS];
130 u8 traffic_class;
131 bool is_probe_ssid;
132};
133
134struct host_app_area {
135 u32 wmi_protocol_ver;
136};
137
138enum wmi_msg_type {
139 DATA_MSGTYPE = 0x0,
140 CNTL_MSGTYPE,
141 SYNC_MSGTYPE,
142 OPT_MSGTYPE,
143};
144
145/*
146 * Macros for operating on WMI_DATA_HDR (info) field
147 */
148
149#define WMI_DATA_HDR_MSG_TYPE_MASK 0x03
150#define WMI_DATA_HDR_MSG_TYPE_SHIFT 0
151#define WMI_DATA_HDR_UP_MASK 0x07
152#define WMI_DATA_HDR_UP_SHIFT 2
153
154/* In AP mode, the same bit (b5) is used to indicate Power save state in
155 * the Rx dir and More data bit state in the tx direction.
156 */
157#define WMI_DATA_HDR_PS_MASK 0x1
158#define WMI_DATA_HDR_PS_SHIFT 5
159
160#define WMI_DATA_HDR_MORE_MASK 0x1
161#define WMI_DATA_HDR_MORE_SHIFT 5
162
163enum wmi_data_hdr_data_type {
164 WMI_DATA_HDR_DATA_TYPE_802_3 = 0,
165 WMI_DATA_HDR_DATA_TYPE_802_11,
166
167 /* used to be used for the PAL */
168 WMI_DATA_HDR_DATA_TYPE_ACL,
169};
170
171#define WMI_DATA_HDR_DATA_TYPE_MASK 0x3
172#define WMI_DATA_HDR_DATA_TYPE_SHIFT 6
173
174/* Macros for operating on WMI_DATA_HDR (info2) field */
175#define WMI_DATA_HDR_SEQNO_MASK 0xFFF
176#define WMI_DATA_HDR_SEQNO_SHIFT 0
177
178#define WMI_DATA_HDR_AMSDU_MASK 0x1
179#define WMI_DATA_HDR_AMSDU_SHIFT 12
180
181#define WMI_DATA_HDR_META_MASK 0x7
182#define WMI_DATA_HDR_META_SHIFT 13
183
184struct wmi_data_hdr {
185 s8 rssi;
186
187 /*
188 * usage of 'info' field(8-bit):
189 *
190 * b1:b0 - WMI_MSG_TYPE
191 * b4:b3:b2 - UP(tid)
192 * b5 - Used in AP mode.
193 * More-data in tx dir, PS in rx.
194 * b7:b6 - Dot3 header(0),
195 * Dot11 Header(1),
196 * ACL data(2)
197 */
198 u8 info;
199
200 /*
201 * usage of 'info2' field(16-bit):
202 *
203 * b11:b0 - seq_no
204 * b12 - A-MSDU?
205 * b15:b13 - META_DATA_VERSION 0 - 7
206 */
207 __le16 info2;
208 __le16 info3;
209} __packed;
210
211static inline u8 wmi_data_hdr_get_up(struct wmi_data_hdr *dhdr)
212{
213 return (dhdr->info >> WMI_DATA_HDR_UP_SHIFT) & WMI_DATA_HDR_UP_MASK;
214}
215
216static inline void wmi_data_hdr_set_up(struct wmi_data_hdr *dhdr,
217 u8 usr_pri)
218{
219 dhdr->info &= ~(WMI_DATA_HDR_UP_MASK << WMI_DATA_HDR_UP_SHIFT);
220 dhdr->info |= usr_pri << WMI_DATA_HDR_UP_SHIFT;
221}
222
223static inline u8 wmi_data_hdr_get_dot11(struct wmi_data_hdr *dhdr)
224{
225 u8 data_type;
226
227 data_type = (dhdr->info >> WMI_DATA_HDR_DATA_TYPE_SHIFT) &
228 WMI_DATA_HDR_DATA_TYPE_MASK;
229 return (data_type == WMI_DATA_HDR_DATA_TYPE_802_11);
230}
231
232static inline u16 wmi_data_hdr_get_seqno(struct wmi_data_hdr *dhdr)
233{
234 return (le16_to_cpu(dhdr->info2) >> WMI_DATA_HDR_SEQNO_SHIFT) &
235 WMI_DATA_HDR_SEQNO_MASK;
236}
237
238static inline u8 wmi_data_hdr_is_amsdu(struct wmi_data_hdr *dhdr)
239{
240 return (le16_to_cpu(dhdr->info2) >> WMI_DATA_HDR_AMSDU_SHIFT) &
241 WMI_DATA_HDR_AMSDU_MASK;
242}
243
244static inline u8 wmi_data_hdr_get_meta(struct wmi_data_hdr *dhdr)
245{
246 return (le16_to_cpu(dhdr->info2) >> WMI_DATA_HDR_META_SHIFT) &
247 WMI_DATA_HDR_META_MASK;
248}
249
250/* Tx meta version definitions */
251#define WMI_MAX_TX_META_SZ 12
252#define WMI_META_VERSION_1 0x01
253#define WMI_META_VERSION_2 0x02
254
255struct wmi_tx_meta_v1 {
256 /* packet ID to identify the tx request */
257 u8 pkt_id;
258
259 /* rate policy to be used for the tx of this frame */
260 u8 rate_plcy_id;
261} __packed;
262
263struct wmi_tx_meta_v2 {
264 /*
265 * Offset from start of the WMI header for csum calculation to
266 * begin.
267 */
268 u8 csum_start;
269
270 /* offset from start of WMI header where final csum goes */
271 u8 csum_dest;
272
273 /* no of bytes over which csum is calculated */
274 u8 csum_flags;
275} __packed;
276
277struct wmi_rx_meta_v1 {
278 u8 status;
279
280 /* rate index mapped to rate at which this packet was received. */
281 u8 rix;
282
283 /* rssi of packet */
284 u8 rssi;
285
286 /* rf channel during packet reception */
287 u8 channel;
288
289 __le16 flags;
290} __packed;
291
292struct wmi_rx_meta_v2 {
293 __le16 csum;
294
295 /* bit 0 set -partial csum valid bit 1 set -test mode */
296 u8 csum_flags;
297} __packed;
298
299/* Control Path */
300struct wmi_cmd_hdr {
301 __le16 cmd_id;
302
303 /* info1 - 16 bits
304 * b03:b00 - id
305 * b15:b04 - unused */
306 __le16 info1;
307
308 /* for alignment */
309 __le16 reserved;
310} __packed;
311
312/* List of WMI commands */
313enum wmi_cmd_id {
314 WMI_CONNECT_CMDID = 0x0001,
315 WMI_RECONNECT_CMDID,
316 WMI_DISCONNECT_CMDID,
317 WMI_SYNCHRONIZE_CMDID,
318 WMI_CREATE_PSTREAM_CMDID,
319 WMI_DELETE_PSTREAM_CMDID,
320 WMI_START_SCAN_CMDID,
321 WMI_SET_SCAN_PARAMS_CMDID,
322 WMI_SET_BSS_FILTER_CMDID,
323 WMI_SET_PROBED_SSID_CMDID, /* 10 */
324 WMI_SET_LISTEN_INT_CMDID,
325 WMI_SET_BMISS_TIME_CMDID,
326 WMI_SET_DISC_TIMEOUT_CMDID,
327 WMI_GET_CHANNEL_LIST_CMDID,
328 WMI_SET_BEACON_INT_CMDID,
329 WMI_GET_STATISTICS_CMDID,
330 WMI_SET_CHANNEL_PARAMS_CMDID,
331 WMI_SET_POWER_MODE_CMDID,
332 WMI_SET_IBSS_PM_CAPS_CMDID,
333 WMI_SET_POWER_PARAMS_CMDID, /* 20 */
334 WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
335 WMI_ADD_CIPHER_KEY_CMDID,
336 WMI_DELETE_CIPHER_KEY_CMDID,
337 WMI_ADD_KRK_CMDID,
338 WMI_DELETE_KRK_CMDID,
339 WMI_SET_PMKID_CMDID,
340 WMI_SET_TX_PWR_CMDID,
341 WMI_GET_TX_PWR_CMDID,
342 WMI_SET_ASSOC_INFO_CMDID,
343 WMI_ADD_BAD_AP_CMDID, /* 30 */
344 WMI_DELETE_BAD_AP_CMDID,
345 WMI_SET_TKIP_COUNTERMEASURES_CMDID,
346 WMI_RSSI_THRESHOLD_PARAMS_CMDID,
347 WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
348 WMI_SET_ACCESS_PARAMS_CMDID,
349 WMI_SET_RETRY_LIMITS_CMDID,
350 WMI_SET_OPT_MODE_CMDID,
351 WMI_OPT_TX_FRAME_CMDID,
352 WMI_SET_VOICE_PKT_SIZE_CMDID,
353 WMI_SET_MAX_SP_LEN_CMDID, /* 40 */
354 WMI_SET_ROAM_CTRL_CMDID,
355 WMI_GET_ROAM_TBL_CMDID,
356 WMI_GET_ROAM_DATA_CMDID,
357 WMI_ENABLE_RM_CMDID,
358 WMI_SET_MAX_OFFHOME_DURATION_CMDID,
359 WMI_EXTENSION_CMDID, /* Non-wireless extensions */
360 WMI_SNR_THRESHOLD_PARAMS_CMDID,
361 WMI_LQ_THRESHOLD_PARAMS_CMDID,
362 WMI_SET_LPREAMBLE_CMDID,
363 WMI_SET_RTS_CMDID, /* 50 */
364 WMI_CLR_RSSI_SNR_CMDID,
365 WMI_SET_FIXRATES_CMDID,
366 WMI_GET_FIXRATES_CMDID,
367 WMI_SET_AUTH_MODE_CMDID,
368 WMI_SET_REASSOC_MODE_CMDID,
369 WMI_SET_WMM_CMDID,
370 WMI_SET_WMM_TXOP_CMDID,
371 WMI_TEST_CMDID,
372
373 /* COEX AR6002 only */
374 WMI_SET_BT_STATUS_CMDID,
375 WMI_SET_BT_PARAMS_CMDID, /* 60 */
376
377 WMI_SET_KEEPALIVE_CMDID,
378 WMI_GET_KEEPALIVE_CMDID,
379 WMI_SET_APPIE_CMDID,
380 WMI_GET_APPIE_CMDID,
381 WMI_SET_WSC_STATUS_CMDID,
382
383 /* Wake on Wireless */
384 WMI_SET_HOST_SLEEP_MODE_CMDID,
385 WMI_SET_WOW_MODE_CMDID,
386 WMI_GET_WOW_LIST_CMDID,
387 WMI_ADD_WOW_PATTERN_CMDID,
388 WMI_DEL_WOW_PATTERN_CMDID, /* 70 */
389
390 WMI_SET_FRAMERATES_CMDID,
391 WMI_SET_AP_PS_CMDID,
392 WMI_SET_QOS_SUPP_CMDID,
393
394 /* WMI_THIN_RESERVED_... mark the start and end
395 * values for WMI_THIN_RESERVED command IDs. These
396 * command IDs can be found in wmi_thin.h */
397 WMI_THIN_RESERVED_START = 0x8000,
398 WMI_THIN_RESERVED_END = 0x8fff,
399
400 /* Developer commands starts at 0xF000 */
401 WMI_SET_BITRATE_CMDID = 0xF000,
402 WMI_GET_BITRATE_CMDID,
403 WMI_SET_WHALPARAM_CMDID,
404 WMI_SET_MAC_ADDRESS_CMDID,
405 WMI_SET_AKMP_PARAMS_CMDID,
406 WMI_SET_PMKID_LIST_CMDID,
407 WMI_GET_PMKID_LIST_CMDID,
408 WMI_ABORT_SCAN_CMDID,
409 WMI_SET_TARGET_EVENT_REPORT_CMDID,
410
411 /* Unused */
412 WMI_UNUSED1,
413 WMI_UNUSED2,
414
415 /* AP mode commands */
416 WMI_AP_HIDDEN_SSID_CMDID,
417 WMI_AP_SET_NUM_STA_CMDID,
418 WMI_AP_ACL_POLICY_CMDID,
419 WMI_AP_ACL_MAC_LIST_CMDID,
420 WMI_AP_CONFIG_COMMIT_CMDID,
421 WMI_AP_SET_MLME_CMDID,
422 WMI_AP_SET_PVB_CMDID,
423 WMI_AP_CONN_INACT_CMDID,
424 WMI_AP_PROT_SCAN_TIME_CMDID,
425 WMI_AP_SET_COUNTRY_CMDID,
426 WMI_AP_SET_DTIM_CMDID,
427 WMI_AP_MODE_STAT_CMDID,
428
429 WMI_SET_IP_CMDID,
430 WMI_SET_PARAMS_CMDID,
431 WMI_SET_MCAST_FILTER_CMDID,
432 WMI_DEL_MCAST_FILTER_CMDID,
433
434 WMI_ALLOW_AGGR_CMDID,
435 WMI_ADDBA_REQ_CMDID,
436 WMI_DELBA_REQ_CMDID,
437 WMI_SET_HT_CAP_CMDID,
438 WMI_SET_HT_OP_CMDID,
439 WMI_SET_TX_SELECT_RATES_CMDID,
440 WMI_SET_TX_SGI_PARAM_CMDID,
441 WMI_SET_RATE_POLICY_CMDID,
442
443 WMI_HCI_CMD_CMDID,
444 WMI_RX_FRAME_FORMAT_CMDID,
445 WMI_SET_THIN_MODE_CMDID,
446 WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
447
448 WMI_AP_SET_11BG_RATESET_CMDID,
449 WMI_SET_PMK_CMDID,
450 WMI_MCAST_FILTER_CMDID,
451
452 /* COEX CMDID AR6003 */
453 WMI_SET_BTCOEX_FE_ANT_CMDID,
454 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
455 WMI_SET_BTCOEX_SCO_CONFIG_CMDID,
456 WMI_SET_BTCOEX_A2DP_CONFIG_CMDID,
457 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID,
458 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
459 WMI_SET_BTCOEX_DEBUG_CMDID,
460 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID,
461 WMI_GET_BTCOEX_STATS_CMDID,
462 WMI_GET_BTCOEX_CONFIG_CMDID,
463
464 WMI_SET_DFS_ENABLE_CMDID, /* F034 */
465 WMI_SET_DFS_MINRSSITHRESH_CMDID,
466 WMI_SET_DFS_MAXPULSEDUR_CMDID,
467 WMI_DFS_RADAR_DETECTED_CMDID,
468
469 /* P2P commands */
470 WMI_P2P_SET_CONFIG_CMDID, /* F038 */
471 WMI_WPS_SET_CONFIG_CMDID,
472 WMI_SET_REQ_DEV_ATTR_CMDID,
473 WMI_P2P_FIND_CMDID,
474 WMI_P2P_STOP_FIND_CMDID,
475 WMI_P2P_GO_NEG_START_CMDID,
476 WMI_P2P_LISTEN_CMDID,
477
478 WMI_CONFIG_TX_MAC_RULES_CMDID, /* F040 */
479 WMI_SET_PROMISCUOUS_MODE_CMDID,
480 WMI_RX_FRAME_FILTER_CMDID,
481 WMI_SET_CHANNEL_CMDID,
482
483 /* WAC commands */
484 WMI_ENABLE_WAC_CMDID,
485 WMI_WAC_SCAN_REPLY_CMDID,
486 WMI_WAC_CTRL_REQ_CMDID,
487 WMI_SET_DIV_PARAMS_CMDID,
488
489 WMI_GET_PMK_CMDID,
490 WMI_SET_PASSPHRASE_CMDID,
491 WMI_SEND_ASSOC_RES_CMDID,
492 WMI_SET_ASSOC_REQ_RELAY_CMDID,
493 WMI_GET_RFKILL_MODE_CMDID,
494
495 /* ACS command, consists of sub-commands */
496 WMI_ACS_CTRL_CMDID,
497
498 /* Ultra low power store / recall commands */
499 WMI_STORERECALL_CONFIGURE_CMDID,
500 WMI_STORERECALL_RECALL_CMDID,
501 WMI_STORERECALL_HOST_READY_CMDID,
502 WMI_FORCE_TARGET_ASSERT_CMDID,
503 WMI_SET_EXCESS_TX_RETRY_THRES_CMDID,
504};
505
506/* WMI_CONNECT_CMDID */
507enum network_type {
508 INFRA_NETWORK = 0x01,
509 ADHOC_NETWORK = 0x02,
510 ADHOC_CREATOR = 0x04,
511 AP_NETWORK = 0x10,
512};
513
514enum dot11_auth_mode {
515 OPEN_AUTH = 0x01,
516 SHARED_AUTH = 0x02,
517
518 /* different from IEEE_AUTH_MODE definitions */
519 LEAP_AUTH = 0x04,
520};
521
522enum {
523 AUTH_IDLE,
524 AUTH_OPEN_IN_PROGRESS,
525};
526
527enum auth_mode {
528 NONE_AUTH = 0x01,
529 WPA_AUTH = 0x02,
530 WPA2_AUTH = 0x04,
531 WPA_PSK_AUTH = 0x08,
532 WPA2_PSK_AUTH = 0x10,
533 WPA_AUTH_CCKM = 0x20,
534 WPA2_AUTH_CCKM = 0x40,
535};
536
537#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT
538#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1)
539
540#define WMI_MIN_KEY_INDEX 0
541#define WMI_MAX_KEY_INDEX 3
542
543#define WMI_MAX_KEY_LEN 32
544
545/*
546 * NB: these values are ordered carefully; there are lots of
547 * of implications in any reordering. In particular beware
548 * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY.
549 */
550#define ATH6KL_CIPHER_WEP 0
551#define ATH6KL_CIPHER_TKIP 1
552#define ATH6KL_CIPHER_AES_OCB 2
553#define ATH6KL_CIPHER_AES_CCM 3
554#define ATH6KL_CIPHER_CKIP 5
555#define ATH6KL_CIPHER_CCKM_KRK 6
556#define ATH6KL_CIPHER_NONE 7 /* pseudo value */
557
558/*
559 * 802.11 rate set.
560 */
561#define ATH6KL_RATE_MAXSIZE 15 /* max rates we'll handle */
562
563#define ATH_OUI_TYPE 0x01
564#define WPA_OUI_TYPE 0x01
565#define WMM_PARAM_OUI_SUBTYPE 0x01
566#define WMM_OUI_TYPE 0x02
567#define WSC_OUT_TYPE 0x04
568
569enum wmi_connect_ctrl_flags_bits {
570 CONNECT_ASSOC_POLICY_USER = 0x0001,
571 CONNECT_SEND_REASSOC = 0x0002,
572 CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004,
573 CONNECT_PROFILE_MATCH_DONE = 0x0008,
574 CONNECT_IGNORE_AAC_BEACON = 0x0010,
575 CONNECT_CSA_FOLLOW_BSS = 0x0020,
576 CONNECT_DO_WPA_OFFLOAD = 0x0040,
577 CONNECT_DO_NOT_DEAUTH = 0x0080,
578};
579
580struct wmi_connect_cmd {
581 u8 nw_type;
582 u8 dot11_auth_mode;
583 u8 auth_mode;
584 u8 prwise_crypto_type;
585 u8 prwise_crypto_len;
586 u8 grp_crypto_type;
587 u8 grp_crypto_len;
588 u8 ssid_len;
589 u8 ssid[IEEE80211_MAX_SSID_LEN];
590 __le16 ch;
591 u8 bssid[ETH_ALEN];
592 __le32 ctrl_flags;
593} __packed;
594
595/* WMI_RECONNECT_CMDID */
596struct wmi_reconnect_cmd {
597 /* channel hint */
598 __le16 channel;
599
600 /* mandatory if set */
601 u8 bssid[ETH_ALEN];
602} __packed;
603
604/* WMI_ADD_CIPHER_KEY_CMDID */
605enum key_usage {
606 PAIRWISE_USAGE = 0x00,
607 GROUP_USAGE = 0x01,
608
609 /* default Tx Key - static WEP only */
610 TX_USAGE = 0x02,
611};
612
613/*
614 * Bit Flag
615 * Bit 0 - Initialise TSC - default is Initialize
616 */
617#define KEY_OP_INIT_TSC 0x01
618#define KEY_OP_INIT_RSC 0x02
619
620/* default initialise the TSC & RSC */
621#define KEY_OP_INIT_VAL 0x03
622#define KEY_OP_VALID_MASK 0x03
623
624struct wmi_add_cipher_key_cmd {
625 u8 key_index;
626 u8 key_type;
627
628 /* enum key_usage */
629 u8 key_usage;
630
631 u8 key_len;
632
633 /* key replay sequence counter */
634 u8 key_rsc[8];
635
636 u8 key[WLAN_MAX_KEY_LEN];
637
638 /* additional key control info */
639 u8 key_op_ctrl;
640
641 u8 key_mac_addr[ETH_ALEN];
642} __packed;
643
644/* WMI_DELETE_CIPHER_KEY_CMDID */
645struct wmi_delete_cipher_key_cmd {
646 u8 key_index;
647} __packed;
648
649#define WMI_KRK_LEN 16
650
651/* WMI_ADD_KRK_CMDID */
652struct wmi_add_krk_cmd {
653 u8 krk[WMI_KRK_LEN];
654} __packed;
655
656/* WMI_SETPMKID_CMDID */
657
658#define WMI_PMKID_LEN 16
659
660enum pmkid_enable_flg {
661 PMKID_DISABLE = 0,
662 PMKID_ENABLE = 1,
663};
664
665struct wmi_setpmkid_cmd {
666 u8 bssid[ETH_ALEN];
667
668 /* enum pmkid_enable_flg */
669 u8 enable;
670
671 u8 pmkid[WMI_PMKID_LEN];
672} __packed;
673
674/* WMI_START_SCAN_CMD */
675enum wmi_scan_type {
676 WMI_LONG_SCAN = 0,
677 WMI_SHORT_SCAN = 1,
678};
679
680struct wmi_start_scan_cmd {
681 __le32 force_fg_scan;
682
683 /* for legacy cisco AP compatibility */
684 __le32 is_legacy;
685
686 /* max duration in the home channel(msec) */
687 __le32 home_dwell_time;
688
689 /* time interval between scans (msec) */
690 __le32 force_scan_intvl;
691
692 /* enum wmi_scan_type */
693 u8 scan_type;
694
695 /* how many channels follow */
696 u8 num_ch;
697
698 /* channels in Mhz */
699 __le16 ch_list[1];
700} __packed;
701
702/* WMI_SET_SCAN_PARAMS_CMDID */
703#define WMI_SHORTSCANRATIO_DEFAULT 3
704
705/*
706 * Warning: scan control flag value of 0xFF is used to disable
707 * all flags in WMI_SCAN_PARAMS_CMD. Do not add any more
708 * flags here
709 */
710enum wmi_scan_ctrl_flags_bits {
711
712 /* set if can scan in the connect cmd */
713 CONNECT_SCAN_CTRL_FLAGS = 0x01,
714
715 /* set if scan for the SSID it is already connected to */
716 SCAN_CONNECTED_CTRL_FLAGS = 0x02,
717
718 /* set if enable active scan */
719 ACTIVE_SCAN_CTRL_FLAGS = 0x04,
720
721 /* set if enable roam scan when bmiss and lowrssi */
722 ROAM_SCAN_CTRL_FLAGS = 0x08,
723
724 /* set if follows customer BSSINFO reporting rule */
725 REPORT_BSSINFO_CTRL_FLAGS = 0x10,
726
727 /* if disabled, target doesn't scan after a disconnect event */
728 ENABLE_AUTO_CTRL_FLAGS = 0x20,
729
730 /*
731 * Scan complete event with canceled status will be generated when
732 * a scan is prempted before it gets completed.
733 */
734 ENABLE_SCAN_ABORT_EVENT = 0x40
735};
736
737#define DEFAULT_SCAN_CTRL_FLAGS \
738 (CONNECT_SCAN_CTRL_FLAGS | \
739 SCAN_CONNECTED_CTRL_FLAGS | \
740 ACTIVE_SCAN_CTRL_FLAGS | \
741 ROAM_SCAN_CTRL_FLAGS | \
742 ENABLE_AUTO_CTRL_FLAGS)
743
744struct wmi_scan_params_cmd {
745 /* sec */
746 __le16 fg_start_period;
747
748 /* sec */
749 __le16 fg_end_period;
750
751 /* sec */
752 __le16 bg_period;
753
754 /* msec */
755 __le16 maxact_chdwell_time;
756
757 /* msec */
758 __le16 pas_chdwell_time;
759
760 /* how many shorts scan for one long */
761 u8 short_scan_ratio;
762
763 u8 scan_ctrl_flags;
764
765 /* msec */
766 __le16 minact_chdwell_time;
767
768 /* max active scans per ssid */
769 __le16 maxact_scan_per_ssid;
770
771 /* msecs */
772 __le32 max_dfsch_act_time;
773} __packed;
774
775/* WMI_SET_BSS_FILTER_CMDID */
776enum wmi_bss_filter {
777 /* no beacons forwarded */
778 NONE_BSS_FILTER = 0x0,
779
780 /* all beacons forwarded */
781 ALL_BSS_FILTER,
782
783 /* only beacons matching profile */
784 PROFILE_FILTER,
785
786 /* all but beacons matching profile */
787 ALL_BUT_PROFILE_FILTER,
788
789 /* only beacons matching current BSS */
790 CURRENT_BSS_FILTER,
791
792 /* all but beacons matching BSS */
793 ALL_BUT_BSS_FILTER,
794
795 /* beacons matching probed ssid */
796 PROBED_SSID_FILTER,
797
798 /* marker only */
799 LAST_BSS_FILTER,
800};
801
802struct wmi_bss_filter_cmd {
803 /* see, enum wmi_bss_filter */
804 u8 bss_filter;
805
806 /* for alignment */
807 u8 reserved1;
808
809 /* for alignment */
810 __le16 reserved2;
811
812 __le32 ie_mask;
813} __packed;
814
815/* WMI_SET_PROBED_SSID_CMDID */
816#define MAX_PROBED_SSID_INDEX 9
817
818enum wmi_ssid_flag {
819 /* disables entry */
820 DISABLE_SSID_FLAG = 0,
821
822 /* probes specified ssid */
823 SPECIFIC_SSID_FLAG = 0x01,
824
825 /* probes for any ssid */
826 ANY_SSID_FLAG = 0x02,
827};
828
829struct wmi_probed_ssid_cmd {
830 /* 0 to MAX_PROBED_SSID_INDEX */
831 u8 entry_index;
832
833 /* see, enum wmi_ssid_flg */
834 u8 flag;
835
836 u8 ssid_len;
837 u8 ssid[IEEE80211_MAX_SSID_LEN];
838} __packed;
839
840/*
841 * WMI_SET_LISTEN_INT_CMDID
842 * The Listen interval is between 15 and 3000 TUs
843 */
844struct wmi_listen_int_cmd {
845 __le16 listen_intvl;
846 __le16 num_beacons;
847} __packed;
848
849/* WMI_SET_POWER_MODE_CMDID */
850enum wmi_power_mode {
851 REC_POWER = 0x01,
852 MAX_PERF_POWER,
853};
854
855struct wmi_power_mode_cmd {
856 /* see, enum wmi_power_mode */
857 u8 pwr_mode;
858} __packed;
859
860/*
861 * Policy to determnine whether power save failure event should be sent to
862 * host during scanning
863 */
864enum power_save_fail_event_policy {
865 SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1,
866 IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2,
867};
868
869struct wmi_power_params_cmd {
870 /* msec */
871 __le16 idle_period;
872
873 __le16 pspoll_number;
874 __le16 dtim_policy;
875 __le16 tx_wakeup_policy;
876 __le16 num_tx_to_wakeup;
877 __le16 ps_fail_event_policy;
878} __packed;
879
880/* WMI_SET_DISC_TIMEOUT_CMDID */
881struct wmi_disc_timeout_cmd {
882 /* seconds */
883 u8 discon_timeout;
884} __packed;
885
886enum dir_type {
887 UPLINK_TRAFFIC = 0,
888 DNLINK_TRAFFIC = 1,
889 BIDIR_TRAFFIC = 2,
890};
891
892enum voiceps_cap_type {
893 DISABLE_FOR_THIS_AC = 0,
894 ENABLE_FOR_THIS_AC = 1,
895 ENABLE_FOR_ALL_AC = 2,
896};
897
898enum traffic_type {
899 TRAFFIC_TYPE_APERIODIC = 0,
900 TRAFFIC_TYPE_PERIODIC = 1,
901};
902
903/* WMI_SYNCHRONIZE_CMDID */
904struct wmi_sync_cmd {
905 u8 data_sync_map;
906} __packed;
907
908/* WMI_CREATE_PSTREAM_CMDID */
909struct wmi_create_pstream_cmd {
910 /* msec */
911 __le32 min_service_int;
912
913 /* msec */
914 __le32 max_service_int;
915
916 /* msec */
917 __le32 inactivity_int;
918
919 /* msec */
920 __le32 suspension_int;
921
922 __le32 service_start_time;
923
924 /* in bps */
925 __le32 min_data_rate;
926
927 /* in bps */
928 __le32 mean_data_rate;
929
930 /* in bps */
931 __le32 peak_data_rate;
932
933 __le32 max_burst_size;
934 __le32 delay_bound;
935
936 /* in bps */
937 __le32 min_phy_rate;
938
939 __le32 sba;
940 __le32 medium_time;
941
942 /* in octects */
943 __le16 nominal_msdu;
944
945 /* in octects */
946 __le16 max_msdu;
947
948 u8 traffic_class;
949
950 /* see, enum dir_type */
951 u8 traffic_direc;
952
953 u8 rx_queue_num;
954
955 /* see, enum traffic_type */
956 u8 traffic_type;
957
958 /* see, enum voiceps_cap_type */
959 u8 voice_psc_cap;
960 u8 tsid;
961
962 /* 802.1D user priority */
963 u8 user_pri;
964
965 /* nominal phy rate */
966 u8 nominal_phy;
967} __packed;
968
969/* WMI_DELETE_PSTREAM_CMDID */
970struct wmi_delete_pstream_cmd {
971 u8 tx_queue_num;
972 u8 rx_queue_num;
973 u8 traffic_direc;
974 u8 traffic_class;
975 u8 tsid;
976} __packed;
977
978/* WMI_SET_CHANNEL_PARAMS_CMDID */
979enum wmi_phy_mode {
980 WMI_11A_MODE = 0x1,
981 WMI_11G_MODE = 0x2,
982 WMI_11AG_MODE = 0x3,
983 WMI_11B_MODE = 0x4,
984 WMI_11GONLY_MODE = 0x5,
985};
986
987#define WMI_MAX_CHANNELS 32
988
989/*
990 * WMI_RSSI_THRESHOLD_PARAMS_CMDID
991 * Setting the polltime to 0 would disable polling. Threshold values are
992 * in the ascending order, and should agree to:
993 * (lowThreshold_lowerVal < lowThreshold_upperVal < highThreshold_lowerVal
994 * < highThreshold_upperVal)
995 */
996
997struct wmi_rssi_threshold_params_cmd {
998 /* polling time as a factor of LI */
999 __le32 poll_time;
1000
1001 /* lowest of upper */
1002 a_sle16 thresh_above1_val;
1003
1004 a_sle16 thresh_above2_val;
1005 a_sle16 thresh_above3_val;
1006 a_sle16 thresh_above4_val;
1007 a_sle16 thresh_above5_val;
1008
1009 /* highest of upper */
1010 a_sle16 thresh_above6_val;
1011
1012 /* lowest of bellow */
1013 a_sle16 thresh_below1_val;
1014
1015 a_sle16 thresh_below2_val;
1016 a_sle16 thresh_below3_val;
1017 a_sle16 thresh_below4_val;
1018 a_sle16 thresh_below5_val;
1019
1020 /* highest of bellow */
1021 a_sle16 thresh_below6_val;
1022
1023 /* "alpha" */
1024 u8 weight;
1025
1026 u8 reserved[3];
1027} __packed;
1028
1029/*
1030 * WMI_SNR_THRESHOLD_PARAMS_CMDID
1031 * Setting the polltime to 0 would disable polling.
1032 */
1033
1034struct wmi_snr_threshold_params_cmd {
1035 /* polling time as a factor of LI */
1036 __le32 poll_time;
1037
1038 /* "alpha" */
1039 u8 weight;
1040
1041 /* lowest of uppper */
1042 u8 thresh_above1_val;
1043
1044 u8 thresh_above2_val;
1045 u8 thresh_above3_val;
1046
1047 /* highest of upper */
1048 u8 thresh_above4_val;
1049
1050 /* lowest of bellow */
1051 u8 thresh_below1_val;
1052
1053 u8 thresh_below2_val;
1054 u8 thresh_below3_val;
1055
1056 /* highest of bellow */
1057 u8 thresh_below4_val;
1058
1059 u8 reserved[3];
1060} __packed;
1061
1062enum wmi_preamble_policy {
1063 WMI_IGNORE_BARKER_IN_ERP = 0,
1064 WMI_DONOT_IGNORE_BARKER_IN_ERP
1065};
1066
1067struct wmi_set_lpreamble_cmd {
1068 u8 status;
1069 u8 preamble_policy;
1070} __packed;
1071
1072struct wmi_set_rts_cmd {
1073 __le16 threshold;
1074} __packed;
1075
1076/* WMI_SET_TX_PWR_CMDID */
1077struct wmi_set_tx_pwr_cmd {
1078 /* in dbM units */
1079 u8 dbM;
1080} __packed;
1081
1082struct wmi_tx_pwr_reply {
1083 /* in dbM units */
1084 u8 dbM;
1085} __packed;
1086
1087struct wmi_report_sleep_state_event {
1088 __le32 sleep_state;
1089};
1090
1091enum wmi_report_sleep_status {
1092 WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP = 0,
1093 WMI_REPORT_SLEEP_STATUS_IS_AWAKE
1094};
1095enum target_event_report_config {
1096 /* default */
1097 DISCONN_EVT_IN_RECONN = 0,
1098
1099 NO_DISCONN_EVT_IN_RECONN
1100};
1101
1102/* Command Replies */
1103
1104/* WMI_GET_CHANNEL_LIST_CMDID reply */
1105struct wmi_channel_list_reply {
1106 u8 reserved;
1107
1108 /* number of channels in reply */
1109 u8 num_ch;
1110
1111 /* channel in Mhz */
1112 __le16 ch_list[1];
1113} __packed;
1114
1115/* List of Events (target to host) */
1116enum wmi_event_id {
1117 WMI_READY_EVENTID = 0x1001,
1118 WMI_CONNECT_EVENTID,
1119 WMI_DISCONNECT_EVENTID,
1120 WMI_BSSINFO_EVENTID,
1121 WMI_CMDERROR_EVENTID,
1122 WMI_REGDOMAIN_EVENTID,
1123 WMI_PSTREAM_TIMEOUT_EVENTID,
1124 WMI_NEIGHBOR_REPORT_EVENTID,
1125 WMI_TKIP_MICERR_EVENTID,
1126 WMI_SCAN_COMPLETE_EVENTID, /* 0x100a */
1127 WMI_REPORT_STATISTICS_EVENTID,
1128 WMI_RSSI_THRESHOLD_EVENTID,
1129 WMI_ERROR_REPORT_EVENTID,
1130 WMI_OPT_RX_FRAME_EVENTID,
1131 WMI_REPORT_ROAM_TBL_EVENTID,
1132 WMI_EXTENSION_EVENTID,
1133 WMI_CAC_EVENTID,
1134 WMI_SNR_THRESHOLD_EVENTID,
1135 WMI_LQ_THRESHOLD_EVENTID,
1136 WMI_TX_RETRY_ERR_EVENTID, /* 0x1014 */
1137 WMI_REPORT_ROAM_DATA_EVENTID,
1138 WMI_TEST_EVENTID,
1139 WMI_APLIST_EVENTID,
1140 WMI_GET_WOW_LIST_EVENTID,
1141 WMI_GET_PMKID_LIST_EVENTID,
1142 WMI_CHANNEL_CHANGE_EVENTID,
1143 WMI_PEER_NODE_EVENTID,
1144 WMI_PSPOLL_EVENTID,
1145 WMI_DTIMEXPIRY_EVENTID,
1146 WMI_WLAN_VERSION_EVENTID,
1147 WMI_SET_PARAMS_REPLY_EVENTID,
1148 WMI_ADDBA_REQ_EVENTID, /*0x1020 */
1149 WMI_ADDBA_RESP_EVENTID,
1150 WMI_DELBA_REQ_EVENTID,
1151 WMI_TX_COMPLETE_EVENTID,
1152 WMI_HCI_EVENT_EVENTID,
1153 WMI_ACL_DATA_EVENTID,
1154 WMI_REPORT_SLEEP_STATE_EVENTID,
1155 WMI_REPORT_BTCOEX_STATS_EVENTID,
1156 WMI_REPORT_BTCOEX_CONFIG_EVENTID,
1157 WMI_GET_PMK_EVENTID,
1158
1159 /* DFS Events */
1160 WMI_DFS_HOST_ATTACH_EVENTID,
1161 WMI_DFS_HOST_INIT_EVENTID,
1162 WMI_DFS_RESET_DELAYLINES_EVENTID,
1163 WMI_DFS_RESET_RADARQ_EVENTID,
1164 WMI_DFS_RESET_AR_EVENTID,
1165 WMI_DFS_RESET_ARQ_EVENTID,
1166 WMI_DFS_SET_DUR_MULTIPLIER_EVENTID,
1167 WMI_DFS_SET_BANGRADAR_EVENTID,
1168 WMI_DFS_SET_DEBUGLEVEL_EVENTID,
1169 WMI_DFS_PHYERR_EVENTID,
1170
1171 /* CCX Evants */
1172 WMI_CCX_RM_STATUS_EVENTID,
1173
1174 /* P2P Events */
1175 WMI_P2P_GO_NEG_RESULT_EVENTID,
1176
1177 WMI_WAC_SCAN_DONE_EVENTID,
1178 WMI_WAC_REPORT_BSS_EVENTID,
1179 WMI_WAC_START_WPS_EVENTID,
1180 WMI_WAC_CTRL_REQ_REPLY_EVENTID,
1181
1182 /* RFKILL Events */
1183 WMI_RFKILL_STATE_CHANGE_EVENTID,
1184 WMI_RFKILL_GET_MODE_CMD_EVENTID,
1185 WMI_THIN_RESERVED_START_EVENTID = 0x8000,
1186
1187 /*
1188 * Events in this range are reserved for thinmode
1189 * See wmi_thin.h for actual definitions
1190 */
1191 WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
1192
1193 WMI_SET_CHANNEL_EVENTID,
1194 WMI_ASSOC_REQ_EVENTID,
1195
1196 /* Generic ACS event */
1197 WMI_ACS_EVENTID,
1198 WMI_REPORT_WMM_PARAMS_EVENTID
1199};
1200
1201struct wmi_ready_event_2 {
1202 __le32 sw_version;
1203 __le32 abi_version;
1204 u8 mac_addr[ETH_ALEN];
1205 u8 phy_cap;
1206} __packed;
1207
1208/* Connect Event */
1209struct wmi_connect_event {
1210 __le16 ch;
1211 u8 bssid[ETH_ALEN];
1212 __le16 listen_intvl;
1213 __le16 beacon_intvl;
1214 __le32 nw_type;
1215 u8 beacon_ie_len;
1216 u8 assoc_req_len;
1217 u8 assoc_resp_len;
1218 u8 assoc_info[1];
1219} __packed;
1220
1221/* Disconnect Event */
1222enum wmi_disconnect_reason {
1223 NO_NETWORK_AVAIL = 0x01,
1224
1225 /* bmiss */
1226 LOST_LINK = 0x02,
1227
1228 DISCONNECT_CMD = 0x03,
1229 BSS_DISCONNECTED = 0x04,
1230 AUTH_FAILED = 0x05,
1231 ASSOC_FAILED = 0x06,
1232 NO_RESOURCES_AVAIL = 0x07,
1233 CSERV_DISCONNECT = 0x08,
1234 INVALID_PROFILE = 0x0a,
1235 DOT11H_CHANNEL_SWITCH = 0x0b,
1236 PROFILE_MISMATCH = 0x0c,
1237 CONNECTION_EVICTED = 0x0d,
1238 IBSS_MERGE = 0xe,
1239};
1240
1241struct wmi_disconnect_event {
1242 /* reason code, see 802.11 spec. */
1243 __le16 proto_reason_status;
1244
1245 /* set if known */
1246 u8 bssid[ETH_ALEN];
1247
1248 /* see WMI_DISCONNECT_REASON */
1249 u8 disconn_reason;
1250
1251 u8 assoc_resp_len;
1252 u8 assoc_info[1];
1253} __packed;
1254
1255/*
1256 * BSS Info Event.
1257 * Mechanism used to inform host of the presence and characteristic of
1258 * wireless networks present. Consists of bss info header followed by
1259 * the beacon or probe-response frame body. The 802.11 header is no included.
1260 */
1261enum wmi_bi_ftype {
1262 BEACON_FTYPE = 0x1,
1263 PROBERESP_FTYPE,
1264 ACTION_MGMT_FTYPE,
1265 PROBEREQ_FTYPE,
1266};
1267
1268struct wmi_bss_info_hdr {
1269 __le16 ch;
1270
1271 /* see, enum wmi_bi_ftype */
1272 u8 frame_type;
1273
1274 u8 snr;
1275 a_sle16 rssi;
1276 u8 bssid[ETH_ALEN];
1277 __le32 ie_mask;
1278} __packed;
1279
1280/*
1281 * BSS INFO HDR version 2.0
1282 * With 6 bytes HTC header and 6 bytes of WMI header
1283 * WMI_BSS_INFO_HDR cannot be accommodated in the removed 802.11 management
1284 * header space.
1285 * - Reduce the ie_mask to 2 bytes as only two bit flags are used
1286 * - Remove rssi and compute it on the host. rssi = snr - 95
1287 */
1288struct wmi_bss_info_hdr2 {
1289 __le16 ch;
1290
1291 /* see, enum wmi_bi_ftype */
1292 u8 frame_type;
1293
1294 u8 snr;
1295 u8 bssid[ETH_ALEN];
1296 __le16 ie_mask;
1297} __packed;
1298
1299/* Command Error Event */
1300enum wmi_error_code {
1301 INVALID_PARAM = 0x01,
1302 ILLEGAL_STATE = 0x02,
1303 INTERNAL_ERROR = 0x03,
1304};
1305
1306struct wmi_cmd_error_event {
1307 __le16 cmd_id;
1308 u8 err_code;
1309} __packed;
1310
1311struct wmi_pstream_timeout_event {
1312 u8 tx_queue_num;
1313 u8 rx_queue_num;
1314 u8 traffic_direc;
1315 u8 traffic_class;
1316} __packed;
1317
1318/*
1319 * The WMI_NEIGHBOR_REPORT Event is generated by the target to inform
1320 * the host of BSS's it has found that matches the current profile.
1321 * It can be used by the host to cache PMKs and/to initiate pre-authentication
1322 * if the BSS supports it. The first bssid is always the current associated
1323 * BSS.
1324 * The bssid and bssFlags information repeats according to the number
1325 * or APs reported.
1326 */
1327enum wmi_bss_flags {
1328 WMI_DEFAULT_BSS_FLAGS = 0x00,
1329 WMI_PREAUTH_CAPABLE_BSS = 0x01,
1330 WMI_PMKID_VALID_BSS = 0x02,
1331};
1332
1333/* TKIP MIC Error Event */
1334struct wmi_tkip_micerr_event {
1335 u8 key_id;
1336 u8 is_mcast;
1337} __packed;
1338
1339/* WMI_SCAN_COMPLETE_EVENTID */
1340struct wmi_scan_complete_event {
1341 a_sle32 status;
1342} __packed;
1343
1344#define MAX_OPT_DATA_LEN 1400
1345
1346/*
1347 * Special frame receive Event.
1348 * Mechanism used to inform host of the receiption of the special frames.
1349 * Consists of special frame info header followed by special frame body.
1350 * The 802.11 header is not included.
1351 */
1352struct wmi_opt_rx_info_hdr {
1353 __le16 ch;
1354 u8 frame_type;
1355 s8 snr;
1356 u8 src_addr[ETH_ALEN];
1357 u8 bssid[ETH_ALEN];
1358} __packed;
1359
1360/* Reporting statistic */
1361struct tx_stats {
1362 __le32 pkt;
1363 __le32 byte;
1364 __le32 ucast_pkt;
1365 __le32 ucast_byte;
1366 __le32 mcast_pkt;
1367 __le32 mcast_byte;
1368 __le32 bcast_pkt;
1369 __le32 bcast_byte;
1370 __le32 rts_success_cnt;
1371 __le32 pkt_per_ac[4];
1372 __le32 err_per_ac[4];
1373
1374 __le32 err;
1375 __le32 fail_cnt;
1376 __le32 retry_cnt;
1377 __le32 mult_retry_cnt;
1378 __le32 rts_fail_cnt;
1379 a_sle32 ucast_rate;
1380} __packed;
1381
1382struct rx_stats {
1383 __le32 pkt;
1384 __le32 byte;
1385 __le32 ucast_pkt;
1386 __le32 ucast_byte;
1387 __le32 mcast_pkt;
1388 __le32 mcast_byte;
1389 __le32 bcast_pkt;
1390 __le32 bcast_byte;
1391 __le32 frgment_pkt;
1392
1393 __le32 err;
1394 __le32 crc_err;
1395 __le32 key_cache_miss;
1396 __le32 decrypt_err;
1397 __le32 dupl_frame;
1398 a_sle32 ucast_rate;
1399} __packed;
1400
1401struct tkip_ccmp_stats {
1402 __le32 tkip_local_mic_fail;
1403 __le32 tkip_cnter_measures_invoked;
1404 __le32 tkip_replays;
1405 __le32 tkip_fmt_err;
1406 __le32 ccmp_fmt_err;
1407 __le32 ccmp_replays;
1408} __packed;
1409
1410struct pm_stats {
1411 __le32 pwr_save_failure_cnt;
1412 __le16 stop_tx_failure_cnt;
1413 __le16 atim_tx_failure_cnt;
1414 __le16 atim_rx_failure_cnt;
1415 __le16 bcn_rx_failure_cnt;
1416} __packed;
1417
1418struct cserv_stats {
1419 __le32 cs_bmiss_cnt;
1420 __le32 cs_low_rssi_cnt;
1421 __le16 cs_connect_cnt;
1422 __le16 cs_discon_cnt;
1423 a_sle16 cs_ave_beacon_rssi;
1424 __le16 cs_roam_count;
1425 a_sle16 cs_rssi;
1426 u8 cs_snr;
1427 u8 cs_ave_beacon_snr;
1428 u8 cs_last_roam_msec;
1429} __packed;
1430
1431struct wlan_net_stats {
1432 struct tx_stats tx;
1433 struct rx_stats rx;
1434 struct tkip_ccmp_stats tkip_ccmp_stats;
1435} __packed;
1436
1437struct arp_stats {
1438 __le32 arp_received;
1439 __le32 arp_matched;
1440 __le32 arp_replied;
1441} __packed;
1442
1443struct wlan_wow_stats {
1444 __le32 wow_pkt_dropped;
1445 __le16 wow_evt_discarded;
1446 u8 wow_host_pkt_wakeups;
1447 u8 wow_host_evt_wakeups;
1448} __packed;
1449
1450struct wmi_target_stats {
1451 __le32 lq_val;
1452 a_sle32 noise_floor_calib;
1453 struct pm_stats pm_stats;
1454 struct wlan_net_stats stats;
1455 struct wlan_wow_stats wow_stats;
1456 struct arp_stats arp_stats;
1457 struct cserv_stats cserv_stats;
1458} __packed;
1459
1460/*
1461 * WMI_RSSI_THRESHOLD_EVENTID.
1462 * Indicate the RSSI events to host. Events are indicated when we breach a
1463 * thresold value.
1464 */
1465enum wmi_rssi_threshold_val {
1466 WMI_RSSI_THRESHOLD1_ABOVE = 0,
1467 WMI_RSSI_THRESHOLD2_ABOVE,
1468 WMI_RSSI_THRESHOLD3_ABOVE,
1469 WMI_RSSI_THRESHOLD4_ABOVE,
1470 WMI_RSSI_THRESHOLD5_ABOVE,
1471 WMI_RSSI_THRESHOLD6_ABOVE,
1472 WMI_RSSI_THRESHOLD1_BELOW,
1473 WMI_RSSI_THRESHOLD2_BELOW,
1474 WMI_RSSI_THRESHOLD3_BELOW,
1475 WMI_RSSI_THRESHOLD4_BELOW,
1476 WMI_RSSI_THRESHOLD5_BELOW,
1477 WMI_RSSI_THRESHOLD6_BELOW
1478};
1479
1480struct wmi_rssi_threshold_event {
1481 a_sle16 rssi;
1482 u8 range;
1483} __packed;
1484
1485enum wmi_snr_threshold_val {
1486 WMI_SNR_THRESHOLD1_ABOVE = 1,
1487 WMI_SNR_THRESHOLD1_BELOW,
1488 WMI_SNR_THRESHOLD2_ABOVE,
1489 WMI_SNR_THRESHOLD2_BELOW,
1490 WMI_SNR_THRESHOLD3_ABOVE,
1491 WMI_SNR_THRESHOLD3_BELOW,
1492 WMI_SNR_THRESHOLD4_ABOVE,
1493 WMI_SNR_THRESHOLD4_BELOW
1494};
1495
1496struct wmi_snr_threshold_event {
1497 /* see, enum wmi_snr_threshold_val */
1498 u8 range;
1499
1500 u8 snr;
1501} __packed;
1502
1503/* WMI_REPORT_ROAM_TBL_EVENTID */
1504#define MAX_ROAM_TBL_CAND 5
1505
1506struct wmi_bss_roam_info {
1507 a_sle32 roam_util;
1508 u8 bssid[ETH_ALEN];
1509 s8 rssi;
1510 s8 rssidt;
1511 s8 last_rssi;
1512 s8 util;
1513 s8 bias;
1514
1515 /* for alignment */
1516 u8 reserved;
1517} __packed;
1518
1519/* WMI_CAC_EVENTID */
1520enum cac_indication {
1521 CAC_INDICATION_ADMISSION = 0x00,
1522 CAC_INDICATION_ADMISSION_RESP = 0x01,
1523 CAC_INDICATION_DELETE = 0x02,
1524 CAC_INDICATION_NO_RESP = 0x03,
1525};
1526
1527#define WMM_TSPEC_IE_LEN 63
1528
1529struct wmi_cac_event {
1530 u8 ac;
1531 u8 cac_indication;
1532 u8 status_code;
1533 u8 tspec_suggestion[WMM_TSPEC_IE_LEN];
1534} __packed;
1535
1536/* WMI_APLIST_EVENTID */
1537
1538enum aplist_ver {
1539 APLIST_VER1 = 1,
1540};
1541
1542struct wmi_ap_info_v1 {
1543 u8 bssid[ETH_ALEN];
1544 __le16 channel;
1545} __packed;
1546
1547union wmi_ap_info {
1548 struct wmi_ap_info_v1 ap_info_v1;
1549} __packed;
1550
1551struct wmi_aplist_event {
1552 u8 ap_list_ver;
1553 u8 num_ap;
1554 union wmi_ap_info ap_list[1];
1555} __packed;
1556
1557/* Developer Commands */
1558
1559/*
1560 * WMI_SET_BITRATE_CMDID
1561 *
1562 * Get bit rate cmd uses same definition as set bit rate cmd
1563 */
1564enum wmi_bit_rate {
1565 RATE_AUTO = -1,
1566 RATE_1Mb = 0,
1567 RATE_2Mb = 1,
1568 RATE_5_5Mb = 2,
1569 RATE_11Mb = 3,
1570 RATE_6Mb = 4,
1571 RATE_9Mb = 5,
1572 RATE_12Mb = 6,
1573 RATE_18Mb = 7,
1574 RATE_24Mb = 8,
1575 RATE_36Mb = 9,
1576 RATE_48Mb = 10,
1577 RATE_54Mb = 11,
1578 RATE_MCS_0_20 = 12,
1579 RATE_MCS_1_20 = 13,
1580 RATE_MCS_2_20 = 14,
1581 RATE_MCS_3_20 = 15,
1582 RATE_MCS_4_20 = 16,
1583 RATE_MCS_5_20 = 17,
1584 RATE_MCS_6_20 = 18,
1585 RATE_MCS_7_20 = 19,
1586 RATE_MCS_0_40 = 20,
1587 RATE_MCS_1_40 = 21,
1588 RATE_MCS_2_40 = 22,
1589 RATE_MCS_3_40 = 23,
1590 RATE_MCS_4_40 = 24,
1591 RATE_MCS_5_40 = 25,
1592 RATE_MCS_6_40 = 26,
1593 RATE_MCS_7_40 = 27,
1594};
1595
1596struct wmi_bit_rate_reply {
1597 /* see, enum wmi_bit_rate */
1598 s8 rate_index;
1599} __packed;
1600
1601/*
1602 * WMI_SET_FIXRATES_CMDID
1603 *
1604 * Get fix rates cmd uses same definition as set fix rates cmd
1605 */
1606struct wmi_fix_rates_reply {
1607 /* see wmi_bit_rate */
1608 __le32 fix_rate_mask;
1609} __packed;
1610
1611enum roam_data_type {
1612 /* get the roam time data */
1613 ROAM_DATA_TIME = 1,
1614};
1615
1616struct wmi_target_roam_time {
1617 __le32 disassoc_time;
1618 __le32 no_txrx_time;
1619 __le32 assoc_time;
1620 __le32 allow_txrx_time;
1621 u8 disassoc_bssid[ETH_ALEN];
1622 s8 disassoc_bss_rssi;
1623 u8 assoc_bssid[ETH_ALEN];
1624 s8 assoc_bss_rssi;
1625} __packed;
1626
1627enum wmi_txop_cfg {
1628 WMI_TXOP_DISABLED = 0,
1629 WMI_TXOP_ENABLED
1630};
1631
1632struct wmi_set_wmm_txop_cmd {
1633 u8 txop_enable;
1634} __packed;
1635
1636struct wmi_set_keepalive_cmd {
1637 u8 keep_alive_intvl;
1638} __packed;
1639
1640struct wmi_get_keepalive_cmd {
1641 __le32 configured;
1642 u8 keep_alive_intvl;
1643} __packed;
1644
1645/* Notify the WSC registration status to the target */
1646#define WSC_REG_ACTIVE 1
1647#define WSC_REG_INACTIVE 0
1648
1649#define WOW_MAX_FILTER_LISTS 1
1650#define WOW_MAX_FILTERS_PER_LIST 4
1651#define WOW_PATTERN_SIZE 64
1652#define WOW_MASK_SIZE 64
1653
1654#define MAC_MAX_FILTERS_PER_LIST 4
1655
1656struct wow_filter {
1657 u8 wow_valid_filter;
1658 u8 wow_filter_id;
1659 u8 wow_filter_size;
1660 u8 wow_filter_offset;
1661 u8 wow_filter_mask[WOW_MASK_SIZE];
1662 u8 wow_filter_pattern[WOW_PATTERN_SIZE];
1663} __packed;
1664
1665#define MAX_IP_ADDRS 2
1666
1667struct wmi_set_ip_cmd {
1668 /* IP in network byte order */
1669 __le32 ips[MAX_IP_ADDRS];
1670} __packed;
1671
1672/* WMI_GET_WOW_LIST_CMD reply */
1673struct wmi_get_wow_list_reply {
1674 /* number of patterns in reply */
1675 u8 num_filters;
1676
1677 /* this is filter # x of total num_filters */
1678 u8 this_filter_num;
1679
1680 u8 wow_mode;
1681 u8 host_mode;
1682 struct wow_filter wow_filters[1];
1683} __packed;
1684
1685/* WMI_SET_AKMP_PARAMS_CMD */
1686
1687struct wmi_pmkid {
1688 u8 pmkid[WMI_PMKID_LEN];
1689} __packed;
1690
1691/* WMI_GET_PMKID_LIST_CMD Reply */
1692struct wmi_pmkid_list_reply {
1693 __le32 num_pmkid;
1694 u8 bssid_list[ETH_ALEN][1];
1695 struct wmi_pmkid pmkid_list[1];
1696} __packed;
1697
1698/* WMI_ADDBA_REQ_EVENTID */
1699struct wmi_addba_req_event {
1700 u8 tid;
1701 u8 win_sz;
1702 __le16 st_seq_no;
1703
1704 /* f/w response for ADDBA Req; OK (0) or failure (!=0) */
1705 u8 status;
1706} __packed;
1707
1708/* WMI_ADDBA_RESP_EVENTID */
1709struct wmi_addba_resp_event {
1710 u8 tid;
1711
1712 /* OK (0), failure (!=0) */
1713 u8 status;
1714
1715 /* three values: not supported(0), 3839, 8k */
1716 __le16 amsdu_sz;
1717} __packed;
1718
1719/* WMI_DELBA_EVENTID
1720 * f/w received a DELBA for peer and processed it.
1721 * Host is notified of this
1722 */
1723struct wmi_delba_event {
1724 u8 tid;
1725 u8 is_peer_initiator;
1726 __le16 reason_code;
1727} __packed;
1728
1729#define PEER_NODE_JOIN_EVENT 0x00
1730#define PEER_NODE_LEAVE_EVENT 0x01
1731#define PEER_FIRST_NODE_JOIN_EVENT 0x10
1732#define PEER_LAST_NODE_LEAVE_EVENT 0x11
1733
1734struct wmi_peer_node_event {
1735 u8 event_code;
1736 u8 peer_mac_addr[ETH_ALEN];
1737} __packed;
1738
1739/* Transmit complete event data structure(s) */
1740
1741/* version 1 of tx complete msg */
1742struct tx_complete_msg_v1 {
1743#define TX_COMPLETE_STATUS_SUCCESS 0
1744#define TX_COMPLETE_STATUS_RETRIES 1
1745#define TX_COMPLETE_STATUS_NOLINK 2
1746#define TX_COMPLETE_STATUS_TIMEOUT 3
1747#define TX_COMPLETE_STATUS_OTHER 4
1748
1749 u8 status;
1750
1751 /* packet ID to identify parent packet */
1752 u8 pkt_id;
1753
1754 /* rate index on successful transmission */
1755 u8 rate_idx;
1756
1757 /* number of ACK failures in tx attempt */
1758 u8 ack_failures;
1759} __packed;
1760
1761struct wmi_tx_complete_event {
1762 /* no of tx comp msgs following this struct */
1763 u8 num_msg;
1764
1765 /* length in bytes for each individual msg following this struct */
1766 u8 msg_len;
1767
1768 /* version of tx complete msg data following this struct */
1769 u8 msg_type;
1770
1771 /* individual messages follow this header */
1772 u8 reserved;
1773} __packed;
1774
1775/*
1776 * ------- AP Mode definitions --------------
1777 */
1778
1779/*
1780 * !!! Warning !!!
1781 * -Changing the following values needs compilation of both driver and firmware
1782 */
1783#define AP_MAX_NUM_STA 8
1784
1785/* Spl. AID used to set DTIM flag in the beacons */
1786#define MCAST_AID 0xFF
1787
1788#define DEF_AP_COUNTRY_CODE "US "
1789
1790/* Used with WMI_AP_SET_NUM_STA_CMDID */
1791
1792struct wmi_ap_set_pvb_cmd {
1793 __le32 flag;
1794 __le16 aid;
1795} __packed;
1796
1797struct wmi_rx_frame_format_cmd {
1798 /* version of meta data for rx packets <0 = default> (0-7 = valid) */
1799 u8 meta_ver;
1800
1801 /*
1802 * 1 == leave .11 header intact,
1803 * 0 == replace .11 header with .3 <default>
1804 */
1805 u8 dot11_hdr;
1806
1807 /*
1808 * 1 == defragmentation is performed by host,
1809 * 0 == performed by target <default>
1810 */
1811 u8 defrag_on_host;
1812
1813 /* for alignment */
1814 u8 reserved[1];
1815} __packed;
1816
1817/* AP mode events */
1818
1819/* WMI_PS_POLL_EVENT */
1820struct wmi_pspoll_event {
1821 __le16 aid;
1822} __packed;
1823
1824struct wmi_per_sta_stat {
1825 __le32 tx_bytes;
1826 __le32 tx_pkts;
1827 __le32 tx_error;
1828 __le32 tx_discard;
1829 __le32 rx_bytes;
1830 __le32 rx_pkts;
1831 __le32 rx_error;
1832 __le32 rx_discard;
1833 __le32 aid;
1834} __packed;
1835
1836struct wmi_ap_mode_stat {
1837 __le32 action;
1838 struct wmi_per_sta_stat sta[AP_MAX_NUM_STA + 1];
1839} __packed;
1840
1841/* End of AP mode definitions */
1842
1843/* Extended WMI (WMIX)
1844 *
1845 * Extended WMIX commands are encapsulated in a WMI message with
1846 * cmd=WMI_EXTENSION_CMD.
1847 *
1848 * Extended WMI commands are those that are needed during wireless
1849 * operation, but which are not really wireless commands. This allows,
1850 * for instance, platform-specific commands. Extended WMI commands are
1851 * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID.
1852 * Extended WMI events are similarly embedded in a WMI event message with
1853 * WMI_EVENT_ID=WMI_EXTENSION_EVENTID.
1854 */
1855struct wmix_cmd_hdr {
1856 __le32 cmd_id;
1857} __packed;
1858
1859enum wmix_command_id {
1860 WMIX_DSETOPEN_REPLY_CMDID = 0x2001,
1861 WMIX_DSETDATA_REPLY_CMDID,
1862 WMIX_GPIO_OUTPUT_SET_CMDID,
1863 WMIX_GPIO_INPUT_GET_CMDID,
1864 WMIX_GPIO_REGISTER_SET_CMDID,
1865 WMIX_GPIO_REGISTER_GET_CMDID,
1866 WMIX_GPIO_INTR_ACK_CMDID,
1867 WMIX_HB_CHALLENGE_RESP_CMDID,
1868 WMIX_DBGLOG_CFG_MODULE_CMDID,
1869 WMIX_PROF_CFG_CMDID, /* 0x200a */
1870 WMIX_PROF_ADDR_SET_CMDID,
1871 WMIX_PROF_START_CMDID,
1872 WMIX_PROF_STOP_CMDID,
1873 WMIX_PROF_COUNT_GET_CMDID,
1874};
1875
1876enum wmix_event_id {
1877 WMIX_DSETOPENREQ_EVENTID = 0x3001,
1878 WMIX_DSETCLOSE_EVENTID,
1879 WMIX_DSETDATAREQ_EVENTID,
1880 WMIX_GPIO_INTR_EVENTID,
1881 WMIX_GPIO_DATA_EVENTID,
1882 WMIX_GPIO_ACK_EVENTID,
1883 WMIX_HB_CHALLENGE_RESP_EVENTID,
1884 WMIX_DBGLOG_EVENTID,
1885 WMIX_PROF_COUNT_EVENTID,
1886};
1887
1888/*
1889 * ------Error Detection support-------
1890 */
1891
1892/*
1893 * WMIX_HB_CHALLENGE_RESP_CMDID
1894 * Heartbeat Challenge Response command
1895 */
1896struct wmix_hb_challenge_resp_cmd {
1897 __le32 cookie;
1898 __le32 source;
1899} __packed;
1900
1901/* End of Extended WMI (WMIX) */
1902
1903enum wmi_sync_flag {
1904 NO_SYNC_WMIFLAG = 0,
1905
1906 /* transmit all queued data before cmd */
1907 SYNC_BEFORE_WMIFLAG,
1908
1909 /* any new data waits until cmd execs */
1910 SYNC_AFTER_WMIFLAG,
1911
1912 SYNC_BOTH_WMIFLAG,
1913
1914 /* end marker */
1915 END_WMIFLAG
1916};
1917
1918enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi);
1919void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id);
1920int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb);
1921int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
1922 u8 msg_type, bool more_data,
1923 enum wmi_data_hdr_data_type data_type,
1924 u8 meta_ver, void *tx_meta_info);
1925
1926int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
1927int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb);
1928int ath6kl_wmi_data_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
1929int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
1930 u32 layer2_priority, bool wmm_enabled,
1931 u8 *ac);
1932
1933int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb);
1934struct bss *ath6kl_wmi_find_node(struct wmi *wmi, const u8 *mac_addr);
1935void ath6kl_wmi_node_free(struct wmi *wmi, const u8 *mac_addr);
1936
1937int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
1938 enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag);
1939
1940int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type,
1941 enum dot11_auth_mode dot11_auth_mode,
1942 enum auth_mode auth_mode,
1943 enum crypto_type pairwise_crypto,
1944 u8 pairwise_crypto_len,
1945 enum crypto_type group_crypto,
1946 u8 group_crypto_len, int ssid_len, u8 *ssid,
1947 u8 *bssid, u16 channel, u32 ctrl_flags);
1948
1949int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 *bssid, u16 channel);
1950int ath6kl_wmi_disconnect_cmd(struct wmi *wmi);
1951int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
1952 u32 force_fgscan, u32 is_legacy,
1953 u32 home_dwell_time, u32 force_scan_interval,
1954 s8 num_chan, u16 *ch_list);
1955int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u16 fg_start_sec,
1956 u16 fg_end_sec, u16 bg_sec,
1957 u16 minact_chdw_msec, u16 maxact_chdw_msec,
1958 u16 pas_chdw_msec, u8 short_scan_ratio,
1959 u8 scan_ctrl_flag, u32 max_dfsch_act_time,
1960 u16 maxact_scan_per_ssid);
1961int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 filter, u32 ie_mask);
1962int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 index, u8 flag,
1963 u8 ssid_len, u8 *ssid);
1964int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u16 listen_interval,
1965 u16 listen_beacons);
1966int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 pwr_mode);
1967int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period,
1968 u16 ps_poll_num, u16 dtim_policy,
1969 u16 tx_wakup_policy, u16 num_tx_to_wakeup,
1970 u16 ps_fail_event_policy);
1971int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout);
1972int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi,
1973 struct wmi_create_pstream_cmd *pstream);
1974int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 traffic_class, u8 tsid);
1975
1976int ath6kl_wmi_set_rts_cmd(struct wmi *wmi, u16 threshold);
1977int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status,
1978 u8 preamble_policy);
1979
1980int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
1981
1982int ath6kl_wmi_get_stats_cmd(struct wmi *wmi);
1983int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
1984 enum crypto_type key_type,
1985 u8 key_usage, u8 key_len,
1986 u8 *key_rsc, u8 *key_material,
1987 u8 key_op_ctrl, u8 *mac_addr,
1988 enum wmi_sync_flag sync_flag);
1989int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 *krk);
1990int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 key_index);
1991int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, const u8 *bssid,
1992 const u8 *pmkid, bool set);
1993int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM);
1994int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi);
1995
1996int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg);
1997int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl);
1998
1999s32 ath6kl_wmi_get_rate(s8 rate_index);
2000
2001int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd);
2002
2003struct bss *ath6kl_wmi_find_ssid_node(struct wmi *wmi, u8 *ssid,
2004 u32 ssid_len, bool is_wpa2,
2005 bool match_ssid);
2006
2007void ath6kl_wmi_node_return(struct wmi *wmi, struct bss *bss);
2008
2009/* AP mode */
2010int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag);
2011
2012int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_version,
2013 bool rx_dot11_hdr, bool defrag_on_host);
2014
2015void *ath6kl_wmi_init(struct ath6kl *devt);
2016void ath6kl_wmi_shutdown(struct wmi *wmi);
2017
2018#endif /* WMI_H */
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 0b36fcf8a28..85a54cd2b08 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -133,7 +133,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
133 goto err_free_hw; 133 goto err_free_hw;
134 } 134 }
135 135
136 ret = ath9k_init_device(id->driver_data, sc, 0x0, &ath_ahb_bus_ops); 136 ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops);
137 if (ret) { 137 if (ret) {
138 dev_err(&pdev->dev, "failed to initialize device\n"); 138 dev_err(&pdev->dev, "failed to initialize device\n");
139 goto err_irq; 139 goto err_irq;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index 2339728a730..a0aadaddd07 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -835,108 +835,108 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
835 835
836static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { 836static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
837 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 837 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
838 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 838 {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
839 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, 839 {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
840 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, 840 {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
841 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 841 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
842 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, 842 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
843 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 843 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
844 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, 844 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
845 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, 845 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
846 {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, 846 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
847 {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, 847 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
848 {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, 848 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
849 {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, 849 {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
850 {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, 850 {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
851 {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, 851 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
852 {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, 852 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
853 {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, 853 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
854 {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, 854 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
855 {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, 855 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
856 {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, 856 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
857 {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, 857 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
858 {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, 858 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
859 {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, 859 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
860 {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, 860 {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
861 {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, 861 {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
862 {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, 862 {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
863 {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, 863 {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
864 {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, 864 {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
865 {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, 865 {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
866 {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, 866 {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
867 {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, 867 {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
868 {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 868 {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
869 {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 869 {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
870 {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 870 {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
871 {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 871 {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
872 {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 872 {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
873 {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 873 {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
874 {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 874 {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
875 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, 875 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
876 {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, 876 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
877 {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, 877 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
878 {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, 878 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
879 {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, 879 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
880 {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, 880 {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
881 {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, 881 {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
882 {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, 882 {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
883 {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, 883 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
884 {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, 884 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
885 {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, 885 {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
886 {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, 886 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
887 {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, 887 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
888 {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, 888 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
889 {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, 889 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
890 {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, 890 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
891 {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, 891 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
892 {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, 892 {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
893 {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, 893 {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
894 {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, 894 {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
895 {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, 895 {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
896 {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, 896 {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
897 {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, 897 {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
898 {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, 898 {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
899 {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, 899 {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
900 {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 900 {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
901 {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 901 {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
902 {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 902 {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
903 {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 903 {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
904 {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 904 {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
905 {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 905 {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
906 {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 906 {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
907 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 907 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
908 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 908 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
909 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 909 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
910 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 910 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
911 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, 911 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
912 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, 912 {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
913 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, 913 {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
914 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, 914 {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
915 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, 915 {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
916 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, 916 {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
917 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, 917 {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
918 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 918 {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
919 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 919 {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
920 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 920 {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
921 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 921 {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
922 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 922 {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
923 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 923 {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
924 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, 924 {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
925 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, 925 {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
926 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 926 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
927 {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 927 {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
928 {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, 928 {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
929 {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, 929 {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
930 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 930 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
931 {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, 931 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
932 {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, 932 {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
933 {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, 933 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
934 {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, 934 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
935 {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, 935 {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
936 {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, 936 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
937 {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, 937 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
938 {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, 938 {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
939 {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, 939 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
940}; 940};
941 941
942static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { 942static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index c34bef1bf2b..cb8bcc4e609 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3418,6 +3418,133 @@ static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3418 return true; 3418 return true;
3419} 3419}
3420 3420
3421#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3422static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3423 struct ar9300_modal_eep_header *modal_hdr)
3424{
3425 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
3426 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
3427 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
3428 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
3429 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
3430 PR_EEP("Ant. Gain", modal_hdr->antennaGain);
3431 PR_EEP("Switch Settle", modal_hdr->switchSettling);
3432 PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
3433 PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
3434 PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
3435 PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
3436 PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
3437 PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
3438 PR_EEP("Temp Slope", modal_hdr->tempSlope);
3439 PR_EEP("Volt Slope", modal_hdr->voltSlope);
3440 PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
3441 PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
3442 PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
3443 PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
3444 PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
3445 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3446 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3447 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3448 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3449 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3450 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3451 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3452 PR_EEP("txClip", modal_hdr->txClip);
3453 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3454 PR_EEP("Chain0 ob", modal_hdr->ob[0]);
3455 PR_EEP("Chain1 ob", modal_hdr->ob[1]);
3456 PR_EEP("Chain2 ob", modal_hdr->ob[2]);
3457
3458 PR_EEP("Chain0 db_stage2", modal_hdr->db_stage2[0]);
3459 PR_EEP("Chain1 db_stage2", modal_hdr->db_stage2[1]);
3460 PR_EEP("Chain2 db_stage2", modal_hdr->db_stage2[2]);
3461 PR_EEP("Chain0 db_stage3", modal_hdr->db_stage3[0]);
3462 PR_EEP("Chain1 db_stage3", modal_hdr->db_stage3[1]);
3463 PR_EEP("Chain2 db_stage3", modal_hdr->db_stage3[2]);
3464 PR_EEP("Chain0 db_stage4", modal_hdr->db_stage4[0]);
3465 PR_EEP("Chain1 db_stage4", modal_hdr->db_stage4[1]);
3466 PR_EEP("Chain2 db_stage4", modal_hdr->db_stage4[2]);
3467
3468 return len;
3469}
3470
3471static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3472 u8 *buf, u32 len, u32 size)
3473{
3474 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3475 struct ar9300_base_eep_hdr *pBase;
3476
3477 if (!dump_base_hdr) {
3478 len += snprintf(buf + len, size - len,
3479 "%20s :\n", "2GHz modal Header");
3480 len += ar9003_dump_modal_eeprom(buf, len, size,
3481 &eep->modalHeader2G);
3482 len += snprintf(buf + len, size - len,
3483 "%20s :\n", "5GHz modal Header");
3484 len += ar9003_dump_modal_eeprom(buf, len, size,
3485 &eep->modalHeader5G);
3486 goto out;
3487 }
3488
3489 pBase = &eep->baseEepHeader;
3490
3491 PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
3492 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
3493 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
3494 PR_EEP("TX Mask", (pBase->txrxMask >> 4));
3495 PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
3496 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
3497 AR5416_OPFLAGS_11A));
3498 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
3499 AR5416_OPFLAGS_11G));
3500 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
3501 AR5416_OPFLAGS_N_2G_HT20));
3502 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
3503 AR5416_OPFLAGS_N_2G_HT40));
3504 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
3505 AR5416_OPFLAGS_N_5G_HT20));
3506 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
3507 AR5416_OPFLAGS_N_5G_HT40));
3508 PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
3509 PR_EEP("RF Silent", pBase->rfSilent);
3510 PR_EEP("BT option", pBase->blueToothOptions);
3511 PR_EEP("Device Cap", pBase->deviceCap);
3512 PR_EEP("Device Type", pBase->deviceType);
3513 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
3514 PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
3515 PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
3516 PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
3517 PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
3518 PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
3519 PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
3520 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3521 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3522 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3523 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3524 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3525 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
3526 PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
3527 PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
3528 PR_EEP("Tx Gain", pBase->txrxgain >> 4);
3529 PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
3530 PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
3531
3532 len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
3533 ah->eeprom.ar9300_eep.macAddr);
3534out:
3535 if (len > size)
3536 len = size;
3537
3538 return len;
3539}
3540#else
3541static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3542 u8 *buf, u32 len, u32 size)
3543{
3544 return 0;
3545}
3546#endif
3547
3421/* XXX: review hardware docs */ 3548/* XXX: review hardware docs */
3422static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah) 3549static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3423{ 3550{
@@ -4061,7 +4188,7 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4061 /* Write the power for duplicated frames - HT40 */ 4188 /* Write the power for duplicated frames - HT40 */
4062 4189
4063 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */ 4190 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4064 REG_WRITE(ah, 0xa3e0, 4191 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4065 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) | 4192 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4066 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) | 4193 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4067 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) | 4194 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
@@ -4922,25 +5049,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4922 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); 5049 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
4923 } 5050 }
4924 5051
4925 /* 5052 ah->txpower_limit = regulatory->max_power_level;
4926 * This is the TX power we send back to driver core,
4927 * and it can use to pass to userspace to display our
4928 * currently configured TX power setting.
4929 *
4930 * Since power is rate dependent, use one of the indices
4931 * from the AR9300_Rates enum to select an entry from
4932 * targetPowerValT2[] to report. Currently returns the
4933 * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
4934 * as CCK power is less interesting (?).
4935 */
4936 i = ALL_TARGET_LEGACY_6_24; /* legacy */
4937 if (IS_CHAN_HT40(chan))
4938 i = ALL_TARGET_HT40_0_8_16; /* ht40 */
4939 else if (IS_CHAN_HT20(chan))
4940 i = ALL_TARGET_HT20_0_8_16; /* ht20 */
4941
4942 ah->txpower_limit = targetPowerValT2[i];
4943 regulatory->max_power_level = targetPowerValT2[i];
4944 5053
4945 /* Write target power array to registers */ 5054 /* Write target power array to registers */
4946 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); 5055 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
@@ -5015,6 +5124,7 @@ const struct eeprom_ops eep_ar9300_ops = {
5015 .check_eeprom = ath9k_hw_ar9300_check_eeprom, 5124 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5016 .get_eeprom = ath9k_hw_ar9300_get_eeprom, 5125 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5017 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom, 5126 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5127 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5018 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver, 5128 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5019 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev, 5129 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5020 .set_board_values = ath9k_hw_ar9300_set_board_values, 5130 .set_board_values = ath9k_hw_ar9300_set_board_values,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 8ff0b88a29b..1aadc4757e6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -531,17 +531,18 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
531 531
532 /* TODO: byte swap on big endian for ar9300_10 */ 532 /* TODO: byte swap on big endian for ar9300_10 */
533 533
534 if ((rxsp->status11 & AR_RxDone) == 0) 534 if (!rxs) {
535 return -EINPROGRESS; 535 if ((rxsp->status11 & AR_RxDone) == 0)
536 return -EINPROGRESS;
536 537
537 if (MS(rxsp->ds_info, AR_DescId) != 0x168c) 538 if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
538 return -EINVAL; 539 return -EINVAL;
539 540
540 if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) 541 if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
541 return -EINPROGRESS; 542 return -EINPROGRESS;
542 543
543 if (!rxs)
544 return 0; 544 return 0;
545 }
545 546
546 rxs->rs_status = 0; 547 rxs->rs_status = 0;
547 rxs->rs_flags = 0; 548 rxs->rs_flags = 0;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 1baca8e4715..a0aaa685548 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -370,7 +370,7 @@ static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah,
370 else 370 else
371 spur_subchannel_sd = 0; 371 spur_subchannel_sd = 0;
372 372
373 spur_freq_sd = ((freq_offset + 10) << 9) / 11; 373 spur_freq_sd = (freq_offset << 9) / 11;
374 374
375 } else { 375 } else {
376 if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, 376 if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
@@ -379,7 +379,7 @@ static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah,
379 else 379 else
380 spur_subchannel_sd = 1; 380 spur_subchannel_sd = 1;
381 381
382 spur_freq_sd = ((freq_offset - 10) << 9) / 11; 382 spur_freq_sd = (freq_offset << 9) / 11;
383 383
384 } 384 }
385 385
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 46393f90f16..c03949eb37c 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -217,7 +217,6 @@ struct ath_buf_state {
217 u8 bf_type; 217 u8 bf_type;
218 u8 bfs_paprd; 218 u8 bfs_paprd;
219 unsigned long bfs_paprd_timestamp; 219 unsigned long bfs_paprd_timestamp;
220 enum ath9k_internal_frame_type bfs_ftype;
221}; 220};
222 221
223struct ath_buf { 222struct ath_buf {
@@ -273,8 +272,6 @@ struct ath_node {
273struct ath_tx_control { 272struct ath_tx_control {
274 struct ath_txq *txq; 273 struct ath_txq *txq;
275 struct ath_node *an; 274 struct ath_node *an;
276 int if_id;
277 enum ath9k_internal_frame_type frame_type;
278 u8 paprd; 275 u8 paprd;
279}; 276};
280 277
@@ -570,7 +567,6 @@ struct ath_ant_comb {
570#define PS_WAIT_FOR_PSPOLL_DATA BIT(2) 567#define PS_WAIT_FOR_PSPOLL_DATA BIT(2)
571#define PS_WAIT_FOR_TX_ACK BIT(3) 568#define PS_WAIT_FOR_TX_ACK BIT(3)
572#define PS_BEACON_SYNC BIT(4) 569#define PS_BEACON_SYNC BIT(4)
573#define PS_TSFOOR_SYNC BIT(5)
574 570
575struct ath_rate_table; 571struct ath_rate_table;
576 572
@@ -669,7 +665,7 @@ extern bool is_ath9k_unloaded;
669 665
670irqreturn_t ath_isr(int irq, void *dev); 666irqreturn_t ath_isr(int irq, void *dev);
671void ath9k_init_crypto(struct ath_softc *sc); 667void ath9k_init_crypto(struct ath_softc *sc);
672int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, 668int ath9k_init_device(u16 devid, struct ath_softc *sc,
673 const struct ath_bus_ops *bus_ops); 669 const struct ath_bus_ops *bus_ops);
674void ath9k_deinit_device(struct ath_softc *sc); 670void ath9k_deinit_device(struct ath_softc *sc);
675void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); 671void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 0d13ff74a68..086c9c816bf 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -522,6 +522,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
522 ath9k_beacon_init(sc, nexttbtt, intval); 522 ath9k_beacon_init(sc, nexttbtt, intval);
523 sc->beacon.bmisscnt = 0; 523 sc->beacon.bmisscnt = 0;
524 ath9k_hw_set_interrupts(ah, ah->imask); 524 ath9k_hw_set_interrupts(ah, ah->imask);
525 ath9k_hw_enable_interrupts(ah);
525} 526}
526 527
527/* 528/*
@@ -648,12 +649,8 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
648 ath9k_hw_set_sta_beacon_timers(ah, &bs); 649 ath9k_hw_set_sta_beacon_timers(ah, &bs);
649 ah->imask |= ATH9K_INT_BMISS; 650 ah->imask |= ATH9K_INT_BMISS;
650 651
651 /* 652 ath9k_hw_set_interrupts(ah, ah->imask);
652 * If the beacon config is called beacause of TSFOOR, 653 ath9k_hw_enable_interrupts(ah);
653 * Interrupts will be enabled back at the end of ath9k_tasklet
654 */
655 if (!(sc->ps_flags & PS_TSFOOR_SYNC))
656 ath9k_hw_set_interrupts(ah, ah->imask);
657} 654}
658 655
659static void ath_beacon_config_adhoc(struct ath_softc *sc, 656static void ath_beacon_config_adhoc(struct ath_softc *sc,
@@ -687,12 +684,9 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
687 ath9k_hw_disable_interrupts(ah); 684 ath9k_hw_disable_interrupts(ah);
688 ath9k_beacon_init(sc, nexttbtt, intval); 685 ath9k_beacon_init(sc, nexttbtt, intval);
689 sc->beacon.bmisscnt = 0; 686 sc->beacon.bmisscnt = 0;
690 /* 687
691 * If the beacon config is called beacause of TSFOOR, 688 ath9k_hw_set_interrupts(ah, ah->imask);
692 * Interrupts will be enabled back at the end of ath9k_tasklet 689 ath9k_hw_enable_interrupts(ah);
693 */
694 if (!(sc->ps_flags & PS_TSFOOR_SYNC))
695 ath9k_hw_set_interrupts(ah, ah->imask);
696} 690}
697 691
698static bool ath9k_allow_beacon_config(struct ath_softc *sc, 692static bool ath9k_allow_beacon_config(struct ath_softc *sc,
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index a1250c586e4..ac2da3cce78 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -63,6 +63,19 @@ static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
63 return ath9k_hw_get_nf_limits(ah, chan)->nominal; 63 return ath9k_hw_get_nf_limits(ah, chan)->nominal;
64} 64}
65 65
66s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
67{
68 s8 noise = ATH_DEFAULT_NOISE_FLOOR;
69
70 if (chan && chan->noisefloor) {
71 s8 delta = chan->noisefloor -
72 ath9k_hw_get_default_nf(ah, chan);
73 if (delta > 0)
74 noise += delta;
75 }
76 return noise;
77}
78EXPORT_SYMBOL(ath9k_hw_getchan_noise);
66 79
67static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, 80static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
68 struct ath9k_hw_cal_data *cal, 81 struct ath9k_hw_cal_data *cal,
@@ -378,6 +391,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
378 391
379 if (!caldata) { 392 if (!caldata) {
380 chan->noisefloor = nf; 393 chan->noisefloor = nf;
394 ah->noise = ath9k_hw_getchan_noise(ah, chan);
381 return false; 395 return false;
382 } 396 }
383 397
@@ -385,6 +399,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
385 caldata->nfcal_pending = false; 399 caldata->nfcal_pending = false;
386 ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray); 400 ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
387 chan->noisefloor = h[0].privNF; 401 chan->noisefloor = h[0].privNF;
402 ah->noise = ath9k_hw_getchan_noise(ah, chan);
388 return true; 403 return true;
389} 404}
390 405
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 1bef41d1b1f..05b9dbf8185 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -108,6 +108,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
108void ath9k_hw_bstuck_nfcal(struct ath_hw *ah); 108void ath9k_hw_bstuck_nfcal(struct ath_hw *ah);
109void ath9k_hw_reset_calibration(struct ath_hw *ah, 109void ath9k_hw_reset_calibration(struct ath_hw *ah,
110 struct ath9k_cal_list *currCal); 110 struct ath9k_cal_list *currCal);
111s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
111 112
112 113
113#endif /* CALIB_H */ 114#endif /* CALIB_H */
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index d1eb89611ff..9bec3b89fb6 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1163,6 +1163,62 @@ static const struct file_operations fops_regdump = {
1163 .llseek = default_llseek,/* read accesses f_pos */ 1163 .llseek = default_llseek,/* read accesses f_pos */
1164}; 1164};
1165 1165
1166static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
1167 size_t count, loff_t *ppos)
1168{
1169 struct ath_softc *sc = file->private_data;
1170 struct ath_hw *ah = sc->sc_ah;
1171 u32 len = 0, size = 1500;
1172 ssize_t retval = 0;
1173 char *buf;
1174
1175 buf = kzalloc(size, GFP_KERNEL);
1176 if (!buf)
1177 return -ENOMEM;
1178
1179 len = ah->eep_ops->dump_eeprom(ah, true, buf, len, size);
1180
1181 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1182 kfree(buf);
1183
1184 return retval;
1185}
1186
1187static const struct file_operations fops_base_eeprom = {
1188 .read = read_file_base_eeprom,
1189 .open = ath9k_debugfs_open,
1190 .owner = THIS_MODULE,
1191 .llseek = default_llseek,
1192};
1193
1194static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
1195 size_t count, loff_t *ppos)
1196{
1197 struct ath_softc *sc = file->private_data;
1198 struct ath_hw *ah = sc->sc_ah;
1199 u32 len = 0, size = 6000;
1200 char *buf;
1201 size_t retval;
1202
1203 buf = kzalloc(size, GFP_KERNEL);
1204 if (buf == NULL)
1205 return -ENOMEM;
1206
1207 len = ah->eep_ops->dump_eeprom(ah, false, buf, len, size);
1208
1209 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1210 kfree(buf);
1211
1212 return retval;
1213}
1214
1215static const struct file_operations fops_modal_eeprom = {
1216 .read = read_file_modal_eeprom,
1217 .open = ath9k_debugfs_open,
1218 .owner = THIS_MODULE,
1219 .llseek = default_llseek,
1220};
1221
1166int ath9k_init_debug(struct ath_hw *ah) 1222int ath9k_init_debug(struct ath_hw *ah)
1167{ 1223{
1168 struct ath_common *common = ath9k_hw_common(ah); 1224 struct ath_common *common = ath9k_hw_common(ah);
@@ -1206,6 +1262,10 @@ int ath9k_init_debug(struct ath_hw *ah)
1206 &ah->config.cwm_ignore_extcca); 1262 &ah->config.cwm_ignore_extcca);
1207 debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc, 1263 debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc,
1208 &fops_regdump); 1264 &fops_regdump);
1265 debugfs_create_file("base_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
1266 &fops_base_eeprom);
1267 debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
1268 &fops_modal_eeprom);
1209 1269
1210 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, 1270 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
1211 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); 1271 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index de99c0da52e..a3c7d0c247a 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -649,6 +649,8 @@ struct eeprom_ops {
649 int (*check_eeprom)(struct ath_hw *hw); 649 int (*check_eeprom)(struct ath_hw *hw);
650 u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param); 650 u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
651 bool (*fill_eeprom)(struct ath_hw *hw); 651 bool (*fill_eeprom)(struct ath_hw *hw);
652 u32 (*dump_eeprom)(struct ath_hw *hw, bool dump_base_hdr, u8 *buf,
653 u32 len, u32 size);
652 int (*get_eeprom_ver)(struct ath_hw *hw); 654 int (*get_eeprom_ver)(struct ath_hw *hw);
653 int (*get_eeprom_rev)(struct ath_hw *hw); 655 int (*get_eeprom_rev)(struct ath_hw *hw);
654 void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan); 656 void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 47cc95086e6..ea658e794cb 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -72,6 +72,117 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
72 return __ath9k_hw_4k_fill_eeprom(ah); 72 return __ath9k_hw_4k_fill_eeprom(ah);
73} 73}
74 74
75#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
76static u32 ath9k_dump_4k_modal_eeprom(char *buf, u32 len, u32 size,
77 struct modal_eep_4k_header *modal_hdr)
78{
79 PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]);
80 PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon);
81 PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
82 PR_EEP("Switch Settle", modal_hdr->switchSettling);
83 PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]);
84 PR_EEP("Chain0 RxTxMargin", modal_hdr->rxTxMarginCh[0]);
85 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
86 PR_EEP("PGA Desired size", modal_hdr->pgaDesiredSize);
87 PR_EEP("Chain0 xlna Gain", modal_hdr->xlnaGainCh[0]);
88 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
89 PR_EEP("txEndToRxOn", modal_hdr->txEndToRxOn);
90 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
91 PR_EEP("CCA Threshold)", modal_hdr->thresh62);
92 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
93 PR_EEP("xpdGain", modal_hdr->xpdGain);
94 PR_EEP("External PD", modal_hdr->xpd);
95 PR_EEP("Chain0 I Coefficient", modal_hdr->iqCalICh[0]);
96 PR_EEP("Chain0 Q Coefficient", modal_hdr->iqCalQCh[0]);
97 PR_EEP("pdGainOverlap", modal_hdr->pdGainOverlap);
98 PR_EEP("O/D Bias Version", modal_hdr->version);
99 PR_EEP("CCK OutputBias", modal_hdr->ob_0);
100 PR_EEP("BPSK OutputBias", modal_hdr->ob_1);
101 PR_EEP("QPSK OutputBias", modal_hdr->ob_2);
102 PR_EEP("16QAM OutputBias", modal_hdr->ob_3);
103 PR_EEP("64QAM OutputBias", modal_hdr->ob_4);
104 PR_EEP("CCK Driver1_Bias", modal_hdr->db1_0);
105 PR_EEP("BPSK Driver1_Bias", modal_hdr->db1_1);
106 PR_EEP("QPSK Driver1_Bias", modal_hdr->db1_2);
107 PR_EEP("16QAM Driver1_Bias", modal_hdr->db1_3);
108 PR_EEP("64QAM Driver1_Bias", modal_hdr->db1_4);
109 PR_EEP("CCK Driver2_Bias", modal_hdr->db2_0);
110 PR_EEP("BPSK Driver2_Bias", modal_hdr->db2_1);
111 PR_EEP("QPSK Driver2_Bias", modal_hdr->db2_2);
112 PR_EEP("16QAM Driver2_Bias", modal_hdr->db2_3);
113 PR_EEP("64QAM Driver2_Bias", modal_hdr->db2_4);
114 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
115 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
116 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
117 PR_EEP("HT40 Power Inc.", modal_hdr->ht40PowerIncForPdadc);
118 PR_EEP("Chain0 bswAtten", modal_hdr->bswAtten[0]);
119 PR_EEP("Chain0 bswMargin", modal_hdr->bswMargin[0]);
120 PR_EEP("HT40 Switch Settle", modal_hdr->swSettleHt40);
121 PR_EEP("Chain0 xatten2Db", modal_hdr->xatten2Db[0]);
122 PR_EEP("Chain0 xatten2Margin", modal_hdr->xatten2Margin[0]);
123 PR_EEP("Ant. Diversity ctl1", modal_hdr->antdiv_ctl1);
124 PR_EEP("Ant. Diversity ctl2", modal_hdr->antdiv_ctl2);
125 PR_EEP("TX Diversity", modal_hdr->tx_diversity);
126
127 return len;
128}
129
130static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
131 u8 *buf, u32 len, u32 size)
132{
133 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
134 struct base_eep_header_4k *pBase = &eep->baseEepHeader;
135
136 if (!dump_base_hdr) {
137 len += snprintf(buf + len, size - len,
138 "%20s :\n", "2GHz modal Header");
139 len += ath9k_dump_4k_modal_eeprom(buf, len, size,
140 &eep->modalHeader);
141 goto out;
142 }
143
144 PR_EEP("Major Version", pBase->version >> 12);
145 PR_EEP("Minor Version", pBase->version & 0xFFF);
146 PR_EEP("Checksum", pBase->checksum);
147 PR_EEP("Length", pBase->length);
148 PR_EEP("RegDomain1", pBase->regDmn[0]);
149 PR_EEP("RegDomain2", pBase->regDmn[1]);
150 PR_EEP("TX Mask", pBase->txMask);
151 PR_EEP("RX Mask", pBase->rxMask);
152 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
153 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
154 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags &
155 AR5416_OPFLAGS_N_2G_HT20));
156 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags &
157 AR5416_OPFLAGS_N_2G_HT40));
158 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags &
159 AR5416_OPFLAGS_N_5G_HT20));
160 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &
161 AR5416_OPFLAGS_N_5G_HT40));
162 PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01));
163 PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF);
164 PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF);
165 PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF);
166 PR_EEP("TX Gain type", pBase->txGainType);
167
168 len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
169 pBase->macAddr);
170
171out:
172 if (len > size)
173 len = size;
174
175 return len;
176}
177#else
178static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
179 u8 *buf, u32 len, u32 size)
180{
181 return 0;
182}
183#endif
184
185
75#undef SIZE_EEPROM_4K 186#undef SIZE_EEPROM_4K
76 187
77static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) 188static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
@@ -238,18 +349,14 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
238 case EEP_ANT_DIV_CTL1: 349 case EEP_ANT_DIV_CTL1:
239 return pModal->antdiv_ctl1; 350 return pModal->antdiv_ctl1;
240 case EEP_TXGAIN_TYPE: 351 case EEP_TXGAIN_TYPE:
241 if (ver_minor >= AR5416_EEP_MINOR_VER_19) 352 return pBase->txGainType;
242 return pBase->txGainType;
243 else
244 return AR5416_EEP_TXGAIN_ORIGINAL;
245 default: 353 default:
246 return 0; 354 return 0;
247 } 355 }
248} 356}
249 357
250static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, 358static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
251 struct ath9k_channel *chan, 359 struct ath9k_channel *chan)
252 int16_t *pTxPowerIndexOffset)
253{ 360{
254 struct ath_common *common = ath9k_hw_common(ah); 361 struct ath_common *common = ath9k_hw_common(ah);
255 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 362 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
@@ -356,8 +463,6 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
356 REGWRITE_BUFFER_FLUSH(ah); 463 REGWRITE_BUFFER_FLUSH(ah);
357 } 464 }
358 } 465 }
359
360 *pTxPowerIndexOffset = 0;
361} 466}
362 467
363static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, 468static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
@@ -580,7 +685,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
580 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 685 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
581 struct modal_eep_4k_header *pModal = &pEepData->modalHeader; 686 struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
582 int16_t ratesArray[Ar5416RateSize]; 687 int16_t ratesArray[Ar5416RateSize];
583 int16_t txPowerIndexOffset = 0;
584 u8 ht40PowerIncForPdadc = 2; 688 u8 ht40PowerIncForPdadc = 2;
585 int i; 689 int i;
586 690
@@ -597,11 +701,10 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
597 twiceMaxRegulatoryPower, 701 twiceMaxRegulatoryPower,
598 powerLimit); 702 powerLimit);
599 703
600 ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset); 704 ath9k_hw_set_4k_power_cal_table(ah, chan);
601 705
602 regulatory->max_power_level = 0; 706 regulatory->max_power_level = 0;
603 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 707 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
604 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
605 if (ratesArray[i] > MAX_RATE_POWER) 708 if (ratesArray[i] > MAX_RATE_POWER)
606 ratesArray[i] = MAX_RATE_POWER; 709 ratesArray[i] = MAX_RATE_POWER;
607 710
@@ -612,15 +715,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
612 if (test) 715 if (test)
613 return; 716 return;
614 717
615 /* Update regulatory */
616 i = rate6mb;
617 if (IS_CHAN_HT40(chan))
618 i = rateHt40_0;
619 else if (IS_CHAN_HT20(chan))
620 i = rateHt20_0;
621
622 regulatory->max_power_level = ratesArray[i];
623
624 if (AR_SREV_9280_20_OR_LATER(ah)) { 718 if (AR_SREV_9280_20_OR_LATER(ah)) {
625 for (i = 0; i < Ar5416RateSize; i++) 719 for (i = 0; i < Ar5416RateSize; i++)
626 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; 720 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
@@ -1063,6 +1157,7 @@ const struct eeprom_ops eep_4k_ops = {
1063 .check_eeprom = ath9k_hw_4k_check_eeprom, 1157 .check_eeprom = ath9k_hw_4k_check_eeprom,
1064 .get_eeprom = ath9k_hw_4k_get_eeprom, 1158 .get_eeprom = ath9k_hw_4k_get_eeprom,
1065 .fill_eeprom = ath9k_hw_4k_fill_eeprom, 1159 .fill_eeprom = ath9k_hw_4k_fill_eeprom,
1160 .dump_eeprom = ath9k_hw_4k_dump_eeprom,
1066 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver, 1161 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver,
1067 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, 1162 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
1068 .set_board_values = ath9k_hw_4k_set_board_values, 1163 .set_board_values = ath9k_hw_4k_set_board_values,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index d6f6b192f45..21f180db238 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -76,6 +76,111 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
76 return __ath9k_hw_ar9287_fill_eeprom(ah); 76 return __ath9k_hw_ar9287_fill_eeprom(ah);
77} 77}
78 78
79#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
80static u32 ar9287_dump_modal_eeprom(char *buf, u32 len, u32 size,
81 struct modal_eep_ar9287_header *modal_hdr)
82{
83 PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]);
84 PR_EEP("Chain1 Ant. Control", modal_hdr->antCtrlChain[1]);
85 PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon);
86 PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
87 PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);
88 PR_EEP("Switch Settle", modal_hdr->switchSettling);
89 PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]);
90 PR_EEP("Chain1 TxRxAtten", modal_hdr->txRxAttenCh[1]);
91 PR_EEP("Chain0 RxTxMargin", modal_hdr->rxTxMarginCh[0]);
92 PR_EEP("Chain1 RxTxMargin", modal_hdr->rxTxMarginCh[1]);
93 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
94 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
95 PR_EEP("txEndToRxOn", modal_hdr->txEndToRxOn);
96 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
97 PR_EEP("CCA Threshold)", modal_hdr->thresh62);
98 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
99 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
100 PR_EEP("xpdGain", modal_hdr->xpdGain);
101 PR_EEP("External PD", modal_hdr->xpd);
102 PR_EEP("Chain0 I Coefficient", modal_hdr->iqCalICh[0]);
103 PR_EEP("Chain1 I Coefficient", modal_hdr->iqCalICh[1]);
104 PR_EEP("Chain0 Q Coefficient", modal_hdr->iqCalQCh[0]);
105 PR_EEP("Chain1 Q Coefficient", modal_hdr->iqCalQCh[1]);
106 PR_EEP("pdGainOverlap", modal_hdr->pdGainOverlap);
107 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
108 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
109 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
110 PR_EEP("HT40 Power Inc.", modal_hdr->ht40PowerIncForPdadc);
111 PR_EEP("Chain0 bswAtten", modal_hdr->bswAtten[0]);
112 PR_EEP("Chain1 bswAtten", modal_hdr->bswAtten[1]);
113 PR_EEP("Chain0 bswMargin", modal_hdr->bswMargin[0]);
114 PR_EEP("Chain1 bswMargin", modal_hdr->bswMargin[1]);
115 PR_EEP("HT40 Switch Settle", modal_hdr->swSettleHt40);
116 PR_EEP("AR92x7 Version", modal_hdr->version);
117 PR_EEP("DriverBias1", modal_hdr->db1);
118 PR_EEP("DriverBias2", modal_hdr->db1);
119 PR_EEP("CCK OutputBias", modal_hdr->ob_cck);
120 PR_EEP("PSK OutputBias", modal_hdr->ob_psk);
121 PR_EEP("QAM OutputBias", modal_hdr->ob_qam);
122 PR_EEP("PAL_OFF OutputBias", modal_hdr->ob_pal_off);
123
124 return len;
125}
126
127static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
128 u8 *buf, u32 len, u32 size)
129{
130 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
131 struct base_eep_ar9287_header *pBase = &eep->baseEepHeader;
132
133 if (!dump_base_hdr) {
134 len += snprintf(buf + len, size - len,
135 "%20s :\n", "2GHz modal Header");
136 len += ar9287_dump_modal_eeprom(buf, len, size,
137 &eep->modalHeader);
138 goto out;
139 }
140
141 PR_EEP("Major Version", pBase->version >> 12);
142 PR_EEP("Minor Version", pBase->version & 0xFFF);
143 PR_EEP("Checksum", pBase->checksum);
144 PR_EEP("Length", pBase->length);
145 PR_EEP("RegDomain1", pBase->regDmn[0]);
146 PR_EEP("RegDomain2", pBase->regDmn[1]);
147 PR_EEP("TX Mask", pBase->txMask);
148 PR_EEP("RX Mask", pBase->rxMask);
149 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
150 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
151 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags &
152 AR5416_OPFLAGS_N_2G_HT20));
153 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags &
154 AR5416_OPFLAGS_N_2G_HT40));
155 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags &
156 AR5416_OPFLAGS_N_5G_HT20));
157 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &
158 AR5416_OPFLAGS_N_5G_HT40));
159 PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01));
160 PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF);
161 PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF);
162 PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF);
163 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
164 PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl);
165
166 len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
167 pBase->macAddr);
168
169out:
170 if (len > size)
171 len = size;
172
173 return len;
174}
175#else
176static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
177 u8 *buf, u32 len, u32 size)
178{
179 return 0;
180}
181#endif
182
183
79static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) 184static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
80{ 185{
81 u32 sum = 0, el, integer; 186 u32 sum = 0, el, integer;
@@ -307,8 +412,7 @@ static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah,
307} 412}
308 413
309static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, 414static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
310 struct ath9k_channel *chan, 415 struct ath9k_channel *chan)
311 int16_t *pTxPowerIndexOffset)
312{ 416{
313 struct cal_data_per_freq_ar9287 *pRawDataset; 417 struct cal_data_per_freq_ar9287 *pRawDataset;
314 struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop; 418 struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
@@ -444,8 +548,6 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
444 REGWRITE_BUFFER_FLUSH(ah); 548 REGWRITE_BUFFER_FLUSH(ah);
445 } 549 }
446 } 550 }
447
448 *pTxPowerIndexOffset = 0;
449} 551}
450 552
451static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah, 553static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
@@ -720,7 +822,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
720 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; 822 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
721 struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader; 823 struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
722 int16_t ratesArray[Ar5416RateSize]; 824 int16_t ratesArray[Ar5416RateSize];
723 int16_t txPowerIndexOffset = 0;
724 u8 ht40PowerIncForPdadc = 2; 825 u8 ht40PowerIncForPdadc = 2;
725 int i; 826 int i;
726 827
@@ -736,11 +837,10 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
736 twiceMaxRegulatoryPower, 837 twiceMaxRegulatoryPower,
737 powerLimit); 838 powerLimit);
738 839
739 ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset); 840 ath9k_hw_set_ar9287_power_cal_table(ah, chan);
740 841
741 regulatory->max_power_level = 0; 842 regulatory->max_power_level = 0;
742 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 843 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
743 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
744 if (ratesArray[i] > MAX_RATE_POWER) 844 if (ratesArray[i] > MAX_RATE_POWER)
745 ratesArray[i] = MAX_RATE_POWER; 845 ratesArray[i] = MAX_RATE_POWER;
746 846
@@ -751,13 +851,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
751 if (test) 851 if (test)
752 return; 852 return;
753 853
754 if (IS_CHAN_2GHZ(chan))
755 i = rate1l;
756 else
757 i = rate6mb;
758
759 regulatory->max_power_level = ratesArray[i];
760
761 if (AR_SREV_9280_20_OR_LATER(ah)) { 854 if (AR_SREV_9280_20_OR_LATER(ah)) {
762 for (i = 0; i < Ar5416RateSize; i++) 855 for (i = 0; i < Ar5416RateSize; i++)
763 ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; 856 ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
@@ -1003,6 +1096,7 @@ const struct eeprom_ops eep_ar9287_ops = {
1003 .check_eeprom = ath9k_hw_ar9287_check_eeprom, 1096 .check_eeprom = ath9k_hw_ar9287_check_eeprom,
1004 .get_eeprom = ath9k_hw_ar9287_get_eeprom, 1097 .get_eeprom = ath9k_hw_ar9287_get_eeprom,
1005 .fill_eeprom = ath9k_hw_ar9287_fill_eeprom, 1098 .fill_eeprom = ath9k_hw_ar9287_fill_eeprom,
1099 .dump_eeprom = ath9k_hw_ar9287_dump_eeprom,
1006 .get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver, 1100 .get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver,
1007 .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev, 1101 .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev,
1008 .set_board_values = ath9k_hw_ar9287_set_board_values, 1102 .set_board_values = ath9k_hw_ar9287_set_board_values,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index b9540a99261..e7e84be8bee 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -133,6 +133,136 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
133 133
134#undef SIZE_EEPROM_DEF 134#undef SIZE_EEPROM_DEF
135 135
136#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
137static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size,
138 struct modal_eep_header *modal_hdr)
139{
140 PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]);
141 PR_EEP("Chain1 Ant. Control", modal_hdr->antCtrlChain[1]);
142 PR_EEP("Chain2 Ant. Control", modal_hdr->antCtrlChain[2]);
143 PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon);
144 PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
145 PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);
146 PR_EEP("Chain2 Ant. Gain", modal_hdr->antennaGainCh[2]);
147 PR_EEP("Switch Settle", modal_hdr->switchSettling);
148 PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]);
149 PR_EEP("Chain1 TxRxAtten", modal_hdr->txRxAttenCh[1]);
150 PR_EEP("Chain2 TxRxAtten", modal_hdr->txRxAttenCh[2]);
151 PR_EEP("Chain0 RxTxMargin", modal_hdr->rxTxMarginCh[0]);
152 PR_EEP("Chain1 RxTxMargin", modal_hdr->rxTxMarginCh[1]);
153 PR_EEP("Chain2 RxTxMargin", modal_hdr->rxTxMarginCh[2]);
154 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
155 PR_EEP("PGA Desired size", modal_hdr->pgaDesiredSize);
156 PR_EEP("Chain0 xlna Gain", modal_hdr->xlnaGainCh[0]);
157 PR_EEP("Chain1 xlna Gain", modal_hdr->xlnaGainCh[1]);
158 PR_EEP("Chain2 xlna Gain", modal_hdr->xlnaGainCh[2]);
159 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
160 PR_EEP("txEndToRxOn", modal_hdr->txEndToRxOn);
161 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
162 PR_EEP("CCA Threshold)", modal_hdr->thresh62);
163 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
164 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
165 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
166 PR_EEP("xpdGain", modal_hdr->xpdGain);
167 PR_EEP("External PD", modal_hdr->xpd);
168 PR_EEP("Chain0 I Coefficient", modal_hdr->iqCalICh[0]);
169 PR_EEP("Chain1 I Coefficient", modal_hdr->iqCalICh[1]);
170 PR_EEP("Chain2 I Coefficient", modal_hdr->iqCalICh[2]);
171 PR_EEP("Chain0 Q Coefficient", modal_hdr->iqCalQCh[0]);
172 PR_EEP("Chain1 Q Coefficient", modal_hdr->iqCalQCh[1]);
173 PR_EEP("Chain2 Q Coefficient", modal_hdr->iqCalQCh[2]);
174 PR_EEP("pdGainOverlap", modal_hdr->pdGainOverlap);
175 PR_EEP("Chain0 OutputBias", modal_hdr->ob);
176 PR_EEP("Chain0 DriverBias", modal_hdr->db);
177 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
178 PR_EEP("2chain pwr decrease", modal_hdr->pwrDecreaseFor2Chain);
179 PR_EEP("3chain pwr decrease", modal_hdr->pwrDecreaseFor3Chain);
180 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
181 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
182 PR_EEP("HT40 Power Inc.", modal_hdr->ht40PowerIncForPdadc);
183 PR_EEP("Chain0 bswAtten", modal_hdr->bswAtten[0]);
184 PR_EEP("Chain1 bswAtten", modal_hdr->bswAtten[1]);
185 PR_EEP("Chain2 bswAtten", modal_hdr->bswAtten[2]);
186 PR_EEP("Chain0 bswMargin", modal_hdr->bswMargin[0]);
187 PR_EEP("Chain1 bswMargin", modal_hdr->bswMargin[1]);
188 PR_EEP("Chain2 bswMargin", modal_hdr->bswMargin[2]);
189 PR_EEP("HT40 Switch Settle", modal_hdr->swSettleHt40);
190 PR_EEP("Chain0 xatten2Db", modal_hdr->xatten2Db[0]);
191 PR_EEP("Chain1 xatten2Db", modal_hdr->xatten2Db[1]);
192 PR_EEP("Chain2 xatten2Db", modal_hdr->xatten2Db[2]);
193 PR_EEP("Chain0 xatten2Margin", modal_hdr->xatten2Margin[0]);
194 PR_EEP("Chain1 xatten2Margin", modal_hdr->xatten2Margin[1]);
195 PR_EEP("Chain2 xatten2Margin", modal_hdr->xatten2Margin[2]);
196 PR_EEP("Chain1 OutputBias", modal_hdr->ob_ch1);
197 PR_EEP("Chain1 DriverBias", modal_hdr->db_ch1);
198 PR_EEP("LNA Control", modal_hdr->lna_ctl);
199 PR_EEP("XPA Bias Freq0", modal_hdr->xpaBiasLvlFreq[0]);
200 PR_EEP("XPA Bias Freq1", modal_hdr->xpaBiasLvlFreq[1]);
201 PR_EEP("XPA Bias Freq2", modal_hdr->xpaBiasLvlFreq[2]);
202
203 return len;
204}
205
206static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
207 u8 *buf, u32 len, u32 size)
208{
209 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
210 struct base_eep_header *pBase = &eep->baseEepHeader;
211
212 if (!dump_base_hdr) {
213 len += snprintf(buf + len, size - len,
214 "%20s :\n", "2GHz modal Header");
215 len += ath9k_def_dump_modal_eeprom(buf, len, size,
216 &eep->modalHeader[0]);
217 len += snprintf(buf + len, size - len,
218 "%20s :\n", "5GHz modal Header");
219 len += ath9k_def_dump_modal_eeprom(buf, len, size,
220 &eep->modalHeader[1]);
221 goto out;
222 }
223
224 PR_EEP("Major Version", pBase->version >> 12);
225 PR_EEP("Minor Version", pBase->version & 0xFFF);
226 PR_EEP("Checksum", pBase->checksum);
227 PR_EEP("Length", pBase->length);
228 PR_EEP("RegDomain1", pBase->regDmn[0]);
229 PR_EEP("RegDomain2", pBase->regDmn[1]);
230 PR_EEP("TX Mask", pBase->txMask);
231 PR_EEP("RX Mask", pBase->rxMask);
232 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
233 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
234 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags &
235 AR5416_OPFLAGS_N_2G_HT20));
236 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags &
237 AR5416_OPFLAGS_N_2G_HT40));
238 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags &
239 AR5416_OPFLAGS_N_5G_HT20));
240 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &
241 AR5416_OPFLAGS_N_5G_HT40));
242 PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01));
243 PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF);
244 PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF);
245 PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF);
246 PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl);
247
248 len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
249 pBase->macAddr);
250
251out:
252 if (len > size)
253 len = size;
254
255 return len;
256}
257#else
258static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
259 u8 *buf, u32 len, u32 size)
260{
261 return 0;
262}
263#endif
264
265
136static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) 266static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
137{ 267{
138 struct ar5416_eeprom_def *eep = 268 struct ar5416_eeprom_def *eep =
@@ -693,8 +823,7 @@ static void ath9k_adjust_pdadc_values(struct ath_hw *ah,
693} 823}
694 824
695static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, 825static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
696 struct ath9k_channel *chan, 826 struct ath9k_channel *chan)
697 int16_t *pTxPowerIndexOffset)
698{ 827{
699#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x) 828#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
700#define SM_PDGAIN_B(x, y) \ 829#define SM_PDGAIN_B(x, y) \
@@ -855,7 +984,6 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
855 } 984 }
856 } 985 }
857 986
858 *pTxPowerIndexOffset = 0;
859#undef SM_PD_GAIN 987#undef SM_PD_GAIN
860#undef SM_PDGAIN_B 988#undef SM_PDGAIN_B
861} 989}
@@ -1143,7 +1271,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1143 struct modal_eep_header *pModal = 1271 struct modal_eep_header *pModal =
1144 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]); 1272 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
1145 int16_t ratesArray[Ar5416RateSize]; 1273 int16_t ratesArray[Ar5416RateSize];
1146 int16_t txPowerIndexOffset = 0;
1147 u8 ht40PowerIncForPdadc = 2; 1274 u8 ht40PowerIncForPdadc = 2;
1148 int i, cck_ofdm_delta = 0; 1275 int i, cck_ofdm_delta = 0;
1149 1276
@@ -1160,28 +1287,16 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1160 twiceMaxRegulatoryPower, 1287 twiceMaxRegulatoryPower,
1161 powerLimit); 1288 powerLimit);
1162 1289
1163 ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset); 1290 ath9k_hw_set_def_power_cal_table(ah, chan);
1164 1291
1165 regulatory->max_power_level = 0; 1292 regulatory->max_power_level = 0;
1166 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 1293 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
1167 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
1168 if (ratesArray[i] > MAX_RATE_POWER) 1294 if (ratesArray[i] > MAX_RATE_POWER)
1169 ratesArray[i] = MAX_RATE_POWER; 1295 ratesArray[i] = MAX_RATE_POWER;
1170 if (ratesArray[i] > regulatory->max_power_level) 1296 if (ratesArray[i] > regulatory->max_power_level)
1171 regulatory->max_power_level = ratesArray[i]; 1297 regulatory->max_power_level = ratesArray[i];
1172 } 1298 }
1173 1299
1174 if (!test) {
1175 i = rate6mb;
1176
1177 if (IS_CHAN_HT40(chan))
1178 i = rateHt40_0;
1179 else if (IS_CHAN_HT20(chan))
1180 i = rateHt20_0;
1181
1182 regulatory->max_power_level = ratesArray[i];
1183 }
1184
1185 switch(ar5416_get_ntxchains(ah->txchainmask)) { 1300 switch(ar5416_get_ntxchains(ah->txchainmask)) {
1186 case 1: 1301 case 1:
1187 break; 1302 break;
@@ -1336,6 +1451,7 @@ const struct eeprom_ops eep_def_ops = {
1336 .check_eeprom = ath9k_hw_def_check_eeprom, 1451 .check_eeprom = ath9k_hw_def_check_eeprom,
1337 .get_eeprom = ath9k_hw_def_get_eeprom, 1452 .get_eeprom = ath9k_hw_def_get_eeprom,
1338 .fill_eeprom = ath9k_hw_def_fill_eeprom, 1453 .fill_eeprom = ath9k_hw_def_fill_eeprom,
1454 .dump_eeprom = ath9k_hw_def_dump_eeprom,
1339 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver, 1455 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver,
1340 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev, 1456 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev,
1341 .set_board_values = ath9k_hw_def_set_board_values, 1457 .set_board_values = ath9k_hw_def_set_board_values,
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index bc713fc2819..5113dd80c99 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -149,6 +149,7 @@ static void ath9k_gen_timer_start(struct ath_hw *ah,
149 ath9k_hw_disable_interrupts(ah); 149 ath9k_hw_disable_interrupts(ah);
150 ah->imask |= ATH9K_INT_GENTIMER; 150 ah->imask |= ATH9K_INT_GENTIMER;
151 ath9k_hw_set_interrupts(ah, ah->imask); 151 ath9k_hw_set_interrupts(ah, ah->imask);
152 ath9k_hw_enable_interrupts(ah);
152 } 153 }
153} 154}
154 155
@@ -163,6 +164,7 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
163 ath9k_hw_disable_interrupts(ah); 164 ath9k_hw_disable_interrupts(ah);
164 ah->imask &= ~ATH9K_INT_GENTIMER; 165 ah->imask &= ~ATH9K_INT_GENTIMER;
165 ath9k_hw_set_interrupts(ah, ah->imask); 166 ath9k_hw_set_interrupts(ah, ah->imask);
167 ath9k_hw_enable_interrupts(ah);
166 } 168 }
167} 169}
168 170
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 5bc022087e6..da5596766d8 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -521,8 +521,6 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
521 521
522int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv, 522int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
523 u8 enable_coex); 523 u8 enable_coex);
524void ath9k_htc_station_work(struct work_struct *work);
525void ath9k_htc_aggr_work(struct work_struct *work);
526void ath9k_htc_ani_work(struct work_struct *work); 524void ath9k_htc_ani_work(struct work_struct *work);
527void ath9k_htc_start_ani(struct ath9k_htc_priv *priv); 525void ath9k_htc_start_ani(struct ath9k_htc_priv *priv);
528void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); 526void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv);
@@ -542,7 +540,6 @@ int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv);
542void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot); 540void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot);
543void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv); 541void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv);
544void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event); 542void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event);
545void ath9k_htc_tx_failed(struct ath9k_htc_priv *priv);
546void ath9k_tx_failed_tasklet(unsigned long data); 543void ath9k_tx_failed_tasklet(unsigned long data);
547void ath9k_htc_tx_cleanup_timer(unsigned long data); 544void ath9k_htc_tx_cleanup_timer(unsigned long data);
548 545
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 3bea7ea86f0..19aa5b72488 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -666,7 +666,6 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
666 return -ENOMEM; 666 return -ENOMEM;
667 667
668 ah->hw_version.devid = devid; 668 ah->hw_version.devid = devid;
669 ah->hw_version.subsysid = 0; /* FIXME */
670 ah->hw_version.usbdev = drv_info; 669 ah->hw_version.usbdev = drv_info;
671 ah->ah_flags |= AH_USE_EEPROM; 670 ah->ah_flags |= AH_USE_EEPROM;
672 ah->reg_ops.read = ath9k_regread; 671 ah->reg_ops.read = ath9k_regread;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8dcefe74f4c..db44e5b0c98 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1486,6 +1486,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1486 memset(caldata, 0, sizeof(*caldata)); 1486 memset(caldata, 0, sizeof(*caldata));
1487 ath9k_init_nfcal_hist_buffer(ah, chan); 1487 ath9k_init_nfcal_hist_buffer(ah, chan);
1488 } 1488 }
1489 ah->noise = ath9k_hw_getchan_noise(ah, chan);
1489 1490
1490 if (bChannelChange && 1491 if (bChannelChange &&
1491 (ah->chip_fullsleep != true) && 1492 (ah->chip_fullsleep != true) &&
@@ -2439,15 +2440,18 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
2439 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 2440 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
2440 struct ath9k_channel *chan = ah->curchan; 2441 struct ath9k_channel *chan = ah->curchan;
2441 struct ieee80211_channel *channel = chan->chan; 2442 struct ieee80211_channel *channel = chan->chan;
2443 int reg_pwr = min_t(int, MAX_RATE_POWER, regulatory->power_limit);
2444 int chan_pwr = channel->max_power * 2;
2445
2446 if (test)
2447 reg_pwr = chan_pwr = MAX_RATE_POWER;
2442 2448
2443 regulatory->power_limit = min(limit, (u32) MAX_RATE_POWER); 2449 regulatory->power_limit = min(limit, (u32) MAX_RATE_POWER);
2444 2450
2445 ah->eep_ops->set_txpower(ah, chan, 2451 ah->eep_ops->set_txpower(ah, chan,
2446 ath9k_regd_get_ctl(regulatory, chan), 2452 ath9k_regd_get_ctl(regulatory, chan),
2447 channel->max_antenna_gain * 2, 2453 channel->max_antenna_gain * 2,
2448 channel->max_power * 2, 2454 chan_pwr, reg_pwr, test);
2449 min((u32) MAX_RATE_POWER,
2450 (u32) regulatory->power_limit), test);
2451} 2455}
2452EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit); 2456EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
2453 2457
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index c79889036ec..4fbcced2828 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -93,6 +93,12 @@
93 (_ah)->reg_ops.write_flush((_ah)); \ 93 (_ah)->reg_ops.write_flush((_ah)); \
94 } while (0) 94 } while (0)
95 95
96#define PR_EEP(_s, _val) \
97 do { \
98 len += snprintf(buf + len, size - len, "%20s : %10d\n", \
99 _s, (_val)); \
100 } while (0)
101
96#define SM(_v, _f) (((_v) << _f##_S) & _f) 102#define SM(_v, _f) (((_v) << _f##_S) & _f)
97#define MS(_v, _f) (((_v) & _f) >> _f##_S) 103#define MS(_v, _f) (((_v) & _f) >> _f##_S)
98#define REG_RMW_FIELD(_a, _r, _f, _v) \ 104#define REG_RMW_FIELD(_a, _r, _f, _v) \
@@ -438,7 +444,6 @@ struct ath9k_hw_version {
438 u16 phyRev; 444 u16 phyRev;
439 u16 analog5GhzRev; 445 u16 analog5GhzRev;
440 u16 analog2GhzRev; 446 u16 analog2GhzRev;
441 u16 subsysid;
442 enum ath_usb_dev usbdev; 447 enum ath_usb_dev usbdev;
443}; 448};
444 449
@@ -690,6 +695,7 @@ struct ath_hw {
690 enum nl80211_iftype opmode; 695 enum nl80211_iftype opmode;
691 enum ath9k_power_mode power_mode; 696 enum ath9k_power_mode power_mode;
692 697
698 s8 noise;
693 struct ath9k_hw_cal_data *caldata; 699 struct ath9k_hw_cal_data *caldata;
694 struct ath9k_pacal_info pacal_info; 700 struct ath9k_pacal_info pacal_info;
695 struct ar5416Stats stats; 701 struct ar5416Stats stats;
@@ -703,6 +709,7 @@ struct ath_hw {
703 u32 txdesc_interrupt_mask; 709 u32 txdesc_interrupt_mask;
704 u32 txeol_interrupt_mask; 710 u32 txeol_interrupt_mask;
705 u32 txurn_interrupt_mask; 711 u32 txurn_interrupt_mask;
712 atomic_t intr_ref_cnt;
706 bool chip_fullsleep; 713 bool chip_fullsleep;
707 u32 atim_window; 714 u32 atim_window;
708 715
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index aa0ff7e2c92..db38a58e752 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -548,7 +548,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
548 sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; 548 sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
549} 549}
550 550
551static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, 551static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
552 const struct ath_bus_ops *bus_ops) 552 const struct ath_bus_ops *bus_ops)
553{ 553{
554 struct ath9k_platform_data *pdata = sc->dev->platform_data; 554 struct ath9k_platform_data *pdata = sc->dev->platform_data;
@@ -563,10 +563,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
563 563
564 ah->hw = sc->hw; 564 ah->hw = sc->hw;
565 ah->hw_version.devid = devid; 565 ah->hw_version.devid = devid;
566 ah->hw_version.subsysid = subsysid;
567 ah->reg_ops.read = ath9k_ioread32; 566 ah->reg_ops.read = ath9k_ioread32;
568 ah->reg_ops.write = ath9k_iowrite32; 567 ah->reg_ops.write = ath9k_iowrite32;
569 ah->reg_ops.rmw = ath9k_reg_rmw; 568 ah->reg_ops.rmw = ath9k_reg_rmw;
569 atomic_set(&ah->intr_ref_cnt, -1);
570 sc->sc_ah = ah; 570 sc->sc_ah = ah;
571 571
572 if (!pdata) { 572 if (!pdata) {
@@ -743,7 +743,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
743 SET_IEEE80211_PERM_ADDR(hw, common->macaddr); 743 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
744} 744}
745 745
746int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, 746int ath9k_init_device(u16 devid, struct ath_softc *sc,
747 const struct ath_bus_ops *bus_ops) 747 const struct ath_bus_ops *bus_ops)
748{ 748{
749 struct ieee80211_hw *hw = sc->hw; 749 struct ieee80211_hw *hw = sc->hw;
@@ -753,7 +753,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
753 struct ath_regulatory *reg; 753 struct ath_regulatory *reg;
754 754
755 /* Bring up device */ 755 /* Bring up device */
756 error = ath9k_init_softc(devid, sc, subsysid, bus_ops); 756 error = ath9k_init_softc(devid, sc, bus_ops);
757 if (error != 0) 757 if (error != 0)
758 goto error_init; 758 goto error_init;
759 759
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index b6b523a897e..0f90e1521ff 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -800,6 +800,11 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah)
800{ 800{
801 struct ath_common *common = ath9k_hw_common(ah); 801 struct ath_common *common = ath9k_hw_common(ah);
802 802
803 if (!(ah->imask & ATH9K_INT_GLOBAL))
804 atomic_set(&ah->intr_ref_cnt, -1);
805 else
806 atomic_dec(&ah->intr_ref_cnt);
807
803 ath_dbg(common, ATH_DBG_INTERRUPT, "disable IER\n"); 808 ath_dbg(common, ATH_DBG_INTERRUPT, "disable IER\n");
804 REG_WRITE(ah, AR_IER, AR_IER_DISABLE); 809 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
805 (void) REG_READ(ah, AR_IER); 810 (void) REG_READ(ah, AR_IER);
@@ -821,6 +826,13 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
821 if (!(ah->imask & ATH9K_INT_GLOBAL)) 826 if (!(ah->imask & ATH9K_INT_GLOBAL))
822 return; 827 return;
823 828
829 if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
830 ath_dbg(common, ATH_DBG_INTERRUPT,
831 "Do not enable IER ref count %d\n",
832 atomic_read(&ah->intr_ref_cnt));
833 return;
834 }
835
824 if (AR_SREV_9340(ah)) 836 if (AR_SREV_9340(ah))
825 sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; 837 sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
826 838
@@ -852,7 +864,6 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
852 864
853 ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); 865 ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
854 866
855 /* TODO: global int Ref count */
856 mask = ints & ATH9K_INT_COMMON; 867 mask = ints & ATH9K_INT_COMMON;
857 mask2 = 0; 868 mask2 = 0;
858 869
@@ -929,9 +940,6 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
929 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); 940 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
930 } 941 }
931 942
932 if (ints & ATH9K_INT_GLOBAL)
933 ath9k_hw_enable_interrupts(ah);
934
935 return; 943 return;
936} 944}
937EXPORT_SYMBOL(ath9k_hw_set_interrupts); 945EXPORT_SYMBOL(ath9k_hw_set_interrupts);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 9098aaad97a..1e7fe8c0e11 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -163,7 +163,7 @@ static void ath_update_survey_nf(struct ath_softc *sc, int channel)
163 163
164 if (chan->noisefloor) { 164 if (chan->noisefloor) {
165 survey->filled |= SURVEY_INFO_NOISE_DBM; 165 survey->filled |= SURVEY_INFO_NOISE_DBM;
166 survey->noise = chan->noisefloor; 166 survey->noise = ath9k_hw_getchan_noise(ah, chan);
167 } 167 }
168} 168}
169 169
@@ -294,6 +294,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
294 ath9k_cmn_update_txpow(ah, sc->curtxpow, 294 ath9k_cmn_update_txpow(ah, sc->curtxpow,
295 sc->config.txpowlimit, &sc->curtxpow); 295 sc->config.txpowlimit, &sc->curtxpow);
296 ath9k_hw_set_interrupts(ah, ah->imask); 296 ath9k_hw_set_interrupts(ah, ah->imask);
297 ath9k_hw_enable_interrupts(ah);
297 298
298 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { 299 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
299 if (sc->sc_flags & SC_OP_BEACONS) 300 if (sc->sc_flags & SC_OP_BEACONS)
@@ -706,8 +707,7 @@ void ath9k_tasklet(unsigned long data)
706 */ 707 */
707 ath_dbg(common, ATH_DBG_PS, 708 ath_dbg(common, ATH_DBG_PS,
708 "TSFOOR - Sync with next Beacon\n"); 709 "TSFOOR - Sync with next Beacon\n");
709 sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC | 710 sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
710 PS_TSFOOR_SYNC;
711 } 711 }
712 712
713 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) 713 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
@@ -886,6 +886,7 @@ static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
886 886
887 ath9k_ps_wakeup(sc); 887 ath9k_ps_wakeup(sc);
888 spin_lock_bh(&sc->sc_pcu_lock); 888 spin_lock_bh(&sc->sc_pcu_lock);
889 atomic_set(&ah->intr_ref_cnt, -1);
889 890
890 ath9k_hw_configpcipowersave(ah, 0, 0); 891 ath9k_hw_configpcipowersave(ah, 0, 0);
891 892
@@ -910,6 +911,7 @@ static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
910 911
911 /* Re-Enable interrupts */ 912 /* Re-Enable interrupts */
912 ath9k_hw_set_interrupts(ah, ah->imask); 913 ath9k_hw_set_interrupts(ah, ah->imask);
914 ath9k_hw_enable_interrupts(ah);
913 915
914 /* Enable LED */ 916 /* Enable LED */
915 ath9k_hw_cfg_output(ah, ah->led_pin, 917 ath9k_hw_cfg_output(ah, ah->led_pin,
@@ -1016,6 +1018,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
1016 ath_set_beacon(sc); /* restart beacons */ 1018 ath_set_beacon(sc); /* restart beacons */
1017 1019
1018 ath9k_hw_set_interrupts(ah, ah->imask); 1020 ath9k_hw_set_interrupts(ah, ah->imask);
1021 ath9k_hw_enable_interrupts(ah);
1019 1022
1020 if (retry_tx) { 1023 if (retry_tx) {
1021 int i; 1024 int i;
@@ -1130,6 +1133,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
1130 /* Disable BMISS interrupt when we're not associated */ 1133 /* Disable BMISS interrupt when we're not associated */
1131 ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); 1134 ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
1132 ath9k_hw_set_interrupts(ah, ah->imask); 1135 ath9k_hw_set_interrupts(ah, ah->imask);
1136 ath9k_hw_enable_interrupts(ah);
1133 1137
1134 ieee80211_wake_queues(hw); 1138 ieee80211_wake_queues(hw);
1135 1139
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index be4ea132981..5685cf11cfe 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -156,7 +156,6 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
156 struct ath_softc *sc; 156 struct ath_softc *sc;
157 struct ieee80211_hw *hw; 157 struct ieee80211_hw *hw;
158 u8 csz; 158 u8 csz;
159 u16 subsysid;
160 u32 val; 159 u32 val;
161 int ret = 0; 160 int ret = 0;
162 char hw_name[64]; 161 char hw_name[64];
@@ -250,8 +249,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
250 249
251 sc->irq = pdev->irq; 250 sc->irq = pdev->irq;
252 251
253 pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid); 252 ret = ath9k_init_device(id->device, sc, &ath_pci_bus_ops);
254 ret = ath9k_init_device(id->device, sc, subsysid, &ath_pci_bus_ops);
255 if (ret) { 253 if (ret) {
256 dev_err(&pdev->dev, "Failed to initialize device\n"); 254 dev_err(&pdev->dev, "Failed to initialize device\n");
257 goto err_init; 255 goto err_init;
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index c04a6c3cac7..9e3649a3d5c 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1484,7 +1484,7 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
1484 if (rc->rate_table == NULL) 1484 if (rc->rate_table == NULL)
1485 return 0; 1485 return 0;
1486 1486
1487 max = 80 + rc->rate_table->rate_cnt * 1024 + 1; 1487 max = 80 + rc->rate_table_size * 1024 + 1;
1488 buf = kmalloc(max, GFP_KERNEL); 1488 buf = kmalloc(max, GFP_KERNEL);
1489 if (buf == NULL) 1489 if (buf == NULL)
1490 return -ENOMEM; 1490 return -ENOMEM;
@@ -1494,7 +1494,7 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
1494 "HT", "MCS", "Rate", 1494 "HT", "MCS", "Rate",
1495 "Success", "Retries", "XRetries", "PER"); 1495 "Success", "Retries", "XRetries", "PER");
1496 1496
1497 for (i = 0; i < rc->rate_table->rate_cnt; i++) { 1497 for (i = 0; i < rc->rate_table_size; i++) {
1498 u32 ratekbps = rc->rate_table->info[i].ratekbps; 1498 u32 ratekbps = rc->rate_table->info[i].ratekbps;
1499 struct ath_rc_stats *stats = &rc->rcstats[i]; 1499 struct ath_rc_stats *stats = &rc->rcstats[i];
1500 char mcs[5]; 1500 char mcs[5];
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index c3d850207be..b7a4bcd3eec 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -221,12 +221,6 @@ struct ath_rate_priv {
221 struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; 221 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
222}; 222};
223 223
224enum ath9k_internal_frame_type {
225 ATH9K_IFT_NOT_INTERNAL,
226 ATH9K_IFT_PAUSE,
227 ATH9K_IFT_UNPAUSE
228};
229
230#ifdef CONFIG_ATH9K_RATE_CONTROL 224#ifdef CONFIG_ATH9K_RATE_CONTROL
231int ath_rate_control_register(void); 225int ath_rate_control_register(void);
232void ath_rate_control_unregister(void); 226void ath_rate_control_unregister(void);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 9a4850154fb..74094022b65 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -601,7 +601,6 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
601 ath_dbg(common, ATH_DBG_PS, 601 ath_dbg(common, ATH_DBG_PS,
602 "Reconfigure Beacon timers based on timestamp from the AP\n"); 602 "Reconfigure Beacon timers based on timestamp from the AP\n");
603 ath_set_beacon(sc); 603 ath_set_beacon(sc);
604 sc->ps_flags &= ~PS_TSFOOR_SYNC;
605 } 604 }
606 605
607 if (ath_beacon_dtim_pending_cab(skb)) { 606 if (ath_beacon_dtim_pending_cab(skb)) {
@@ -995,6 +994,8 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
995 struct ieee80211_rx_status *rx_status, 994 struct ieee80211_rx_status *rx_status,
996 bool *decrypt_error) 995 bool *decrypt_error)
997{ 996{
997 struct ath_hw *ah = common->ah;
998
998 memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); 999 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
999 1000
1000 /* 1001 /*
@@ -1015,7 +1016,7 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
1015 1016
1016 rx_status->band = hw->conf.channel->band; 1017 rx_status->band = hw->conf.channel->band;
1017 rx_status->freq = hw->conf.channel->center_freq; 1018 rx_status->freq = hw->conf.channel->center_freq;
1018 rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; 1019 rx_status->signal = ah->noise + rx_stats->rs_rssi;
1019 rx_status->antenna = rx_stats->rs_antenna; 1020 rx_status->antenna = rx_stats->rs_antenna;
1020 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 1021 rx_status->flag |= RX_FLAG_MACTIME_MPDU;
1021 1022
@@ -1783,11 +1784,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1783 struct ieee80211_rx_status *rxs; 1784 struct ieee80211_rx_status *rxs;
1784 struct ath_hw *ah = sc->sc_ah; 1785 struct ath_hw *ah = sc->sc_ah;
1785 struct ath_common *common = ath9k_hw_common(ah); 1786 struct ath_common *common = ath9k_hw_common(ah);
1786 /*
1787 * The hw can technically differ from common->hw when using ath9k
1788 * virtual wiphy so to account for that we iterate over the active
1789 * wiphys and find the appropriate wiphy and therefore hw.
1790 */
1791 struct ieee80211_hw *hw = sc->hw; 1787 struct ieee80211_hw *hw = sc->hw;
1792 struct ieee80211_hdr *hdr; 1788 struct ieee80211_hdr *hdr;
1793 int retval; 1789 int retval;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index cc595712f51..e1d1e903229 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -551,7 +551,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
551 if (clear_filter) 551 if (clear_filter)
552 tid->ac->clear_ps_filter = true; 552 tid->ac->clear_ps_filter = true;
553 list_splice(&bf_pending, &tid->buf_q); 553 list_splice(&bf_pending, &tid->buf_q);
554 ath_tx_queue_tid(txq, tid); 554 if (!an->sleeping)
555 ath_tx_queue_tid(txq, tid);
555 spin_unlock_bh(&txq->axq_lock); 556 spin_unlock_bh(&txq->axq_lock);
556 } 557 }
557 558
@@ -1413,7 +1414,8 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
1413 */ 1414 */
1414 TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw); 1415 TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
1415 list_add_tail(&bf->list, &tid->buf_q); 1416 list_add_tail(&bf->list, &tid->buf_q);
1416 ath_tx_queue_tid(txctl->txq, tid); 1417 if (!txctl->an || !txctl->an->sleeping)
1418 ath_tx_queue_tid(txctl->txq, tid);
1417 return; 1419 return;
1418 } 1420 }
1419 1421
@@ -1777,7 +1779,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
1777 INIT_LIST_HEAD(&bf_head); 1779 INIT_LIST_HEAD(&bf_head);
1778 list_add_tail(&bf->list, &bf_head); 1780 list_add_tail(&bf->list, &bf_head);
1779 1781
1780 bf->bf_state.bfs_ftype = txctl->frame_type;
1781 bf->bf_state.bfs_paprd = txctl->paprd; 1782 bf->bf_state.bfs_paprd = txctl->paprd;
1782 1783
1783 if (bf->bf_state.bfs_paprd) 1784 if (bf->bf_state.bfs_paprd)
@@ -1876,7 +1877,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1876/*****************/ 1877/*****************/
1877 1878
1878static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, 1879static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1879 int tx_flags, int ftype, struct ath_txq *txq) 1880 int tx_flags, struct ath_txq *txq)
1880{ 1881{
1881 struct ieee80211_hw *hw = sc->hw; 1882 struct ieee80211_hw *hw = sc->hw;
1882 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1883 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -1961,8 +1962,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1961 complete(&sc->paprd_complete); 1962 complete(&sc->paprd_complete);
1962 } else { 1963 } else {
1963 ath_debug_stat_tx(sc, bf, ts, txq); 1964 ath_debug_stat_tx(sc, bf, ts, txq);
1964 ath_tx_complete(sc, skb, tx_flags, 1965 ath_tx_complete(sc, skb, tx_flags, txq);
1965 bf->bf_state.bfs_ftype, txq);
1966 } 1966 }
1967 /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't 1967 /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
1968 * accidentally reference it later. 1968 * accidentally reference it later.
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h
index 172f63f671c..03a8268ccf2 100644
--- a/drivers/net/wireless/ath/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -101,7 +101,7 @@ enum CountryCode {
101 CTRY_GERMANY = 276, 101 CTRY_GERMANY = 276,
102 CTRY_GREECE = 300, 102 CTRY_GREECE = 300,
103 CTRY_GREENLAND = 304, 103 CTRY_GREENLAND = 304,
104 CTRY_GRENEDA = 308, 104 CTRY_GRENADA = 308,
105 CTRY_GUAM = 316, 105 CTRY_GUAM = 316,
106 CTRY_GUATEMALA = 320, 106 CTRY_GUATEMALA = 320,
107 CTRY_HAITI = 332, 107 CTRY_HAITI = 332,
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h
index 24b53839fc3..bdd2b4d61f2 100644
--- a/drivers/net/wireless/ath/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
@@ -332,7 +332,7 @@ static struct country_code_to_enum_rd allCountries[] = {
332 {CTRY_GERMANY, ETSI1_WORLD, "DE"}, 332 {CTRY_GERMANY, ETSI1_WORLD, "DE"},
333 {CTRY_GREECE, ETSI1_WORLD, "GR"}, 333 {CTRY_GREECE, ETSI1_WORLD, "GR"},
334 {CTRY_GREENLAND, ETSI1_WORLD, "GL"}, 334 {CTRY_GREENLAND, ETSI1_WORLD, "GL"},
335 {CTRY_GRENEDA, FCC3_FCCA, "GD"}, 335 {CTRY_GRENADA, FCC3_FCCA, "GD"},
336 {CTRY_GUAM, FCC1_FCCA, "GU"}, 336 {CTRY_GUAM, FCC1_FCCA, "GU"},
337 {CTRY_GUATEMALA, FCC1_FCCA, "GT"}, 337 {CTRY_GUATEMALA, FCC1_FCCA, "GT"},
338 {CTRY_HAITI, ETSI1_WORLD, "HT"}, 338 {CTRY_HAITI, ETSI1_WORLD, "HT"},
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 3cab843afb0..b81a2a1c261 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -114,13 +114,13 @@ config B43_PHY_N
114 affect other devices support and may provide support for basic needs. 114 affect other devices support and may provide support for basic needs.
115 115
116config B43_PHY_LP 116config B43_PHY_LP
117 bool "Support for low-power (LP-PHY) devices (EXPERIMENTAL)" 117 bool "Support for low-power (LP-PHY) devices"
118 depends on B43 && EXPERIMENTAL 118 depends on B43
119 default y 119 default y
120 ---help--- 120 ---help---
121 Support for the LP-PHY. 121 Support for the LP-PHY.
122 The LP-PHY is a low-power PHY built into some notebooks 122 The LP-PHY is a low-power PHY built into some notebooks
123 and embedded devices. It supports 802.11a/g 123 and embedded devices. It supports 802.11a/b/g
124 (802.11a support is optional, and currently disabled). 124 (802.11a support is optional, and currently disabled).
125 125
126config B43_PHY_HT 126config B43_PHY_HT
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 26f1ab840cc..d2661aaff50 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -37,7 +37,6 @@
37#include <linux/if_arp.h> 37#include <linux/if_arp.h>
38#include <linux/etherdevice.h> 38#include <linux/etherdevice.h>
39#include <linux/firmware.h> 39#include <linux/firmware.h>
40#include <linux/wireless.h>
41#include <linux/workqueue.h> 40#include <linux/workqueue.h>
42#include <linux/skbuff.h> 41#include <linux/skbuff.h>
43#include <linux/io.h> 42#include <linux/io.h>
@@ -115,6 +114,7 @@ MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
115 114
116#ifdef CONFIG_B43_BCMA 115#ifdef CONFIG_B43_BCMA
117static const struct bcma_device_id b43_bcma_tbl[] = { 116static const struct bcma_device_id b43_bcma_tbl[] = {
117 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
118 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS), 118 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
119 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS), 119 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
120 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS), 120 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index a610a352102..ad4e743e476 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -14,7 +14,6 @@
14#include <linux/ssb/ssb.h> 14#include <linux/ssb/ssb.h>
15#include <linux/ssb/ssb_driver_chipcommon.h> 15#include <linux/ssb/ssb_driver_chipcommon.h>
16 16
17#include <linux/wireless.h>
18#include <net/mac80211.h> 17#include <net/mac80211.h>
19 18
20#include "debugfs.h" 19#include "debugfs.h"
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 5010c477abd..c5535adf699 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -42,10 +42,9 @@
42 42
43/* 32bit DMA ops. */ 43/* 32bit DMA ops. */
44static 44static
45struct b43legacy_dmadesc_generic *op32_idx2desc( 45struct b43legacy_dmadesc32 *op32_idx2desc(struct b43legacy_dmaring *ring,
46 struct b43legacy_dmaring *ring, 46 int slot,
47 int slot, 47 struct b43legacy_dmadesc_meta **meta)
48 struct b43legacy_dmadesc_meta **meta)
49{ 48{
50 struct b43legacy_dmadesc32 *desc; 49 struct b43legacy_dmadesc32 *desc;
51 50
@@ -53,11 +52,11 @@ struct b43legacy_dmadesc_generic *op32_idx2desc(
53 desc = ring->descbase; 52 desc = ring->descbase;
54 desc = &(desc[slot]); 53 desc = &(desc[slot]);
55 54
56 return (struct b43legacy_dmadesc_generic *)desc; 55 return (struct b43legacy_dmadesc32 *)desc;
57} 56}
58 57
59static void op32_fill_descriptor(struct b43legacy_dmaring *ring, 58static void op32_fill_descriptor(struct b43legacy_dmaring *ring,
60 struct b43legacy_dmadesc_generic *desc, 59 struct b43legacy_dmadesc32 *desc,
61 dma_addr_t dmaaddr, u16 bufsize, 60 dma_addr_t dmaaddr, u16 bufsize,
62 int start, int end, int irq) 61 int start, int end, int irq)
63{ 62{
@@ -67,7 +66,7 @@ static void op32_fill_descriptor(struct b43legacy_dmaring *ring,
67 u32 addr; 66 u32 addr;
68 u32 addrext; 67 u32 addrext;
69 68
70 slot = (int)(&(desc->dma32) - descbase); 69 slot = (int)(desc - descbase);
71 B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); 70 B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
72 71
73 addr = (u32)(dmaaddr & ~SSB_DMA_TRANSLATION_MASK); 72 addr = (u32)(dmaaddr & ~SSB_DMA_TRANSLATION_MASK);
@@ -87,8 +86,8 @@ static void op32_fill_descriptor(struct b43legacy_dmaring *ring,
87 ctl |= (addrext << B43legacy_DMA32_DCTL_ADDREXT_SHIFT) 86 ctl |= (addrext << B43legacy_DMA32_DCTL_ADDREXT_SHIFT)
88 & B43legacy_DMA32_DCTL_ADDREXT_MASK; 87 & B43legacy_DMA32_DCTL_ADDREXT_MASK;
89 88
90 desc->dma32.control = cpu_to_le32(ctl); 89 desc->control = cpu_to_le32(ctl);
91 desc->dma32.address = cpu_to_le32(addr); 90 desc->address = cpu_to_le32(addr);
92} 91}
93 92
94static void op32_poke_tx(struct b43legacy_dmaring *ring, int slot) 93static void op32_poke_tx(struct b43legacy_dmaring *ring, int slot)
@@ -128,121 +127,6 @@ static void op32_set_current_rxslot(struct b43legacy_dmaring *ring,
128 (u32)(slot * sizeof(struct b43legacy_dmadesc32))); 127 (u32)(slot * sizeof(struct b43legacy_dmadesc32)));
129} 128}
130 129
131static const struct b43legacy_dma_ops dma32_ops = {
132 .idx2desc = op32_idx2desc,
133 .fill_descriptor = op32_fill_descriptor,
134 .poke_tx = op32_poke_tx,
135 .tx_suspend = op32_tx_suspend,
136 .tx_resume = op32_tx_resume,
137 .get_current_rxslot = op32_get_current_rxslot,
138 .set_current_rxslot = op32_set_current_rxslot,
139};
140
141/* 64bit DMA ops. */
142static
143struct b43legacy_dmadesc_generic *op64_idx2desc(
144 struct b43legacy_dmaring *ring,
145 int slot,
146 struct b43legacy_dmadesc_meta
147 **meta)
148{
149 struct b43legacy_dmadesc64 *desc;
150
151 *meta = &(ring->meta[slot]);
152 desc = ring->descbase;
153 desc = &(desc[slot]);
154
155 return (struct b43legacy_dmadesc_generic *)desc;
156}
157
158static void op64_fill_descriptor(struct b43legacy_dmaring *ring,
159 struct b43legacy_dmadesc_generic *desc,
160 dma_addr_t dmaaddr, u16 bufsize,
161 int start, int end, int irq)
162{
163 struct b43legacy_dmadesc64 *descbase = ring->descbase;
164 int slot;
165 u32 ctl0 = 0;
166 u32 ctl1 = 0;
167 u32 addrlo;
168 u32 addrhi;
169 u32 addrext;
170
171 slot = (int)(&(desc->dma64) - descbase);
172 B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
173
174 addrlo = (u32)(dmaaddr & 0xFFFFFFFF);
175 addrhi = (((u64)dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
176 addrext = (((u64)dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
177 >> SSB_DMA_TRANSLATION_SHIFT;
178 addrhi |= ring->dev->dma.translation;
179 if (slot == ring->nr_slots - 1)
180 ctl0 |= B43legacy_DMA64_DCTL0_DTABLEEND;
181 if (start)
182 ctl0 |= B43legacy_DMA64_DCTL0_FRAMESTART;
183 if (end)
184 ctl0 |= B43legacy_DMA64_DCTL0_FRAMEEND;
185 if (irq)
186 ctl0 |= B43legacy_DMA64_DCTL0_IRQ;
187 ctl1 |= (bufsize - ring->frameoffset)
188 & B43legacy_DMA64_DCTL1_BYTECNT;
189 ctl1 |= (addrext << B43legacy_DMA64_DCTL1_ADDREXT_SHIFT)
190 & B43legacy_DMA64_DCTL1_ADDREXT_MASK;
191
192 desc->dma64.control0 = cpu_to_le32(ctl0);
193 desc->dma64.control1 = cpu_to_le32(ctl1);
194 desc->dma64.address_low = cpu_to_le32(addrlo);
195 desc->dma64.address_high = cpu_to_le32(addrhi);
196}
197
198static void op64_poke_tx(struct b43legacy_dmaring *ring, int slot)
199{
200 b43legacy_dma_write(ring, B43legacy_DMA64_TXINDEX,
201 (u32)(slot * sizeof(struct b43legacy_dmadesc64)));
202}
203
204static void op64_tx_suspend(struct b43legacy_dmaring *ring)
205{
206 b43legacy_dma_write(ring, B43legacy_DMA64_TXCTL,
207 b43legacy_dma_read(ring, B43legacy_DMA64_TXCTL)
208 | B43legacy_DMA64_TXSUSPEND);
209}
210
211static void op64_tx_resume(struct b43legacy_dmaring *ring)
212{
213 b43legacy_dma_write(ring, B43legacy_DMA64_TXCTL,
214 b43legacy_dma_read(ring, B43legacy_DMA64_TXCTL)
215 & ~B43legacy_DMA64_TXSUSPEND);
216}
217
218static int op64_get_current_rxslot(struct b43legacy_dmaring *ring)
219{
220 u32 val;
221
222 val = b43legacy_dma_read(ring, B43legacy_DMA64_RXSTATUS);
223 val &= B43legacy_DMA64_RXSTATDPTR;
224
225 return (val / sizeof(struct b43legacy_dmadesc64));
226}
227
228static void op64_set_current_rxslot(struct b43legacy_dmaring *ring,
229 int slot)
230{
231 b43legacy_dma_write(ring, B43legacy_DMA64_RXINDEX,
232 (u32)(slot * sizeof(struct b43legacy_dmadesc64)));
233}
234
235static const struct b43legacy_dma_ops dma64_ops = {
236 .idx2desc = op64_idx2desc,
237 .fill_descriptor = op64_fill_descriptor,
238 .poke_tx = op64_poke_tx,
239 .tx_suspend = op64_tx_suspend,
240 .tx_resume = op64_tx_resume,
241 .get_current_rxslot = op64_get_current_rxslot,
242 .set_current_rxslot = op64_set_current_rxslot,
243};
244
245
246static inline int free_slots(struct b43legacy_dmaring *ring) 130static inline int free_slots(struct b43legacy_dmaring *ring)
247{ 131{
248 return (ring->nr_slots - ring->used_slots); 132 return (ring->nr_slots - ring->used_slots);
@@ -358,14 +242,6 @@ return 0;
358static u16 b43legacy_dmacontroller_base(enum b43legacy_dmatype type, 242static u16 b43legacy_dmacontroller_base(enum b43legacy_dmatype type,
359 int controller_idx) 243 int controller_idx)
360{ 244{
361 static const u16 map64[] = {
362 B43legacy_MMIO_DMA64_BASE0,
363 B43legacy_MMIO_DMA64_BASE1,
364 B43legacy_MMIO_DMA64_BASE2,
365 B43legacy_MMIO_DMA64_BASE3,
366 B43legacy_MMIO_DMA64_BASE4,
367 B43legacy_MMIO_DMA64_BASE5,
368 };
369 static const u16 map32[] = { 245 static const u16 map32[] = {
370 B43legacy_MMIO_DMA32_BASE0, 246 B43legacy_MMIO_DMA32_BASE0,
371 B43legacy_MMIO_DMA32_BASE1, 247 B43legacy_MMIO_DMA32_BASE1,
@@ -375,11 +251,6 @@ static u16 b43legacy_dmacontroller_base(enum b43legacy_dmatype type,
375 B43legacy_MMIO_DMA32_BASE5, 251 B43legacy_MMIO_DMA32_BASE5,
376 }; 252 };
377 253
378 if (type == B43legacy_DMA_64BIT) {
379 B43legacy_WARN_ON(!(controller_idx >= 0 &&
380 controller_idx < ARRAY_SIZE(map64)));
381 return map64[controller_idx];
382 }
383 B43legacy_WARN_ON(!(controller_idx >= 0 && 254 B43legacy_WARN_ON(!(controller_idx >= 0 &&
384 controller_idx < ARRAY_SIZE(map32))); 255 controller_idx < ARRAY_SIZE(map32)));
385 return map32[controller_idx]; 256 return map32[controller_idx];
@@ -491,25 +362,15 @@ static int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
491 362
492 might_sleep(); 363 might_sleep();
493 364
494 offset = (type == B43legacy_DMA_64BIT) ? 365 offset = B43legacy_DMA32_RXCTL;
495 B43legacy_DMA64_RXCTL : B43legacy_DMA32_RXCTL;
496 b43legacy_write32(dev, mmio_base + offset, 0); 366 b43legacy_write32(dev, mmio_base + offset, 0);
497 for (i = 0; i < 10; i++) { 367 for (i = 0; i < 10; i++) {
498 offset = (type == B43legacy_DMA_64BIT) ? 368 offset = B43legacy_DMA32_RXSTATUS;
499 B43legacy_DMA64_RXSTATUS : B43legacy_DMA32_RXSTATUS;
500 value = b43legacy_read32(dev, mmio_base + offset); 369 value = b43legacy_read32(dev, mmio_base + offset);
501 if (type == B43legacy_DMA_64BIT) { 370 value &= B43legacy_DMA32_RXSTATE;
502 value &= B43legacy_DMA64_RXSTAT; 371 if (value == B43legacy_DMA32_RXSTAT_DISABLED) {
503 if (value == B43legacy_DMA64_RXSTAT_DISABLED) { 372 i = -1;
504 i = -1; 373 break;
505 break;
506 }
507 } else {
508 value &= B43legacy_DMA32_RXSTATE;
509 if (value == B43legacy_DMA32_RXSTAT_DISABLED) {
510 i = -1;
511 break;
512 }
513 } 374 }
514 msleep(1); 375 msleep(1);
515 } 376 }
@@ -533,43 +394,24 @@ static int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
533 might_sleep(); 394 might_sleep();
534 395
535 for (i = 0; i < 10; i++) { 396 for (i = 0; i < 10; i++) {
536 offset = (type == B43legacy_DMA_64BIT) ? 397 offset = B43legacy_DMA32_TXSTATUS;
537 B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS;
538 value = b43legacy_read32(dev, mmio_base + offset); 398 value = b43legacy_read32(dev, mmio_base + offset);
539 if (type == B43legacy_DMA_64BIT) { 399 value &= B43legacy_DMA32_TXSTATE;
540 value &= B43legacy_DMA64_TXSTAT; 400 if (value == B43legacy_DMA32_TXSTAT_DISABLED ||
541 if (value == B43legacy_DMA64_TXSTAT_DISABLED || 401 value == B43legacy_DMA32_TXSTAT_IDLEWAIT ||
542 value == B43legacy_DMA64_TXSTAT_IDLEWAIT || 402 value == B43legacy_DMA32_TXSTAT_STOPPED)
543 value == B43legacy_DMA64_TXSTAT_STOPPED) 403 break;
544 break;
545 } else {
546 value &= B43legacy_DMA32_TXSTATE;
547 if (value == B43legacy_DMA32_TXSTAT_DISABLED ||
548 value == B43legacy_DMA32_TXSTAT_IDLEWAIT ||
549 value == B43legacy_DMA32_TXSTAT_STOPPED)
550 break;
551 }
552 msleep(1); 404 msleep(1);
553 } 405 }
554 offset = (type == B43legacy_DMA_64BIT) ? B43legacy_DMA64_TXCTL : 406 offset = B43legacy_DMA32_TXCTL;
555 B43legacy_DMA32_TXCTL;
556 b43legacy_write32(dev, mmio_base + offset, 0); 407 b43legacy_write32(dev, mmio_base + offset, 0);
557 for (i = 0; i < 10; i++) { 408 for (i = 0; i < 10; i++) {
558 offset = (type == B43legacy_DMA_64BIT) ? 409 offset = B43legacy_DMA32_TXSTATUS;
559 B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS;
560 value = b43legacy_read32(dev, mmio_base + offset); 410 value = b43legacy_read32(dev, mmio_base + offset);
561 if (type == B43legacy_DMA_64BIT) { 411 value &= B43legacy_DMA32_TXSTATE;
562 value &= B43legacy_DMA64_TXSTAT; 412 if (value == B43legacy_DMA32_TXSTAT_DISABLED) {
563 if (value == B43legacy_DMA64_TXSTAT_DISABLED) { 413 i = -1;
564 i = -1; 414 break;
565 break;
566 }
567 } else {
568 value &= B43legacy_DMA32_TXSTATE;
569 if (value == B43legacy_DMA32_TXSTAT_DISABLED) {
570 i = -1;
571 break;
572 }
573 } 415 }
574 msleep(1); 416 msleep(1);
575 } 417 }
@@ -601,9 +443,6 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
601 if ((u64)addr + buffersize > (1ULL << 32)) 443 if ((u64)addr + buffersize > (1ULL << 32))
602 goto address_error; 444 goto address_error;
603 break; 445 break;
604 case B43legacy_DMA_64BIT:
605 /* Currently we can't have addresses beyond 64 bits in the kernel. */
606 break;
607 } 446 }
608 447
609 /* The address is OK. */ 448 /* The address is OK. */
@@ -617,7 +456,7 @@ address_error:
617} 456}
618 457
619static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, 458static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
620 struct b43legacy_dmadesc_generic *desc, 459 struct b43legacy_dmadesc32 *desc,
621 struct b43legacy_dmadesc_meta *meta, 460 struct b43legacy_dmadesc_meta *meta,
622 gfp_t gfp_flags) 461 gfp_t gfp_flags)
623{ 462{
@@ -653,8 +492,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
653 492
654 meta->skb = skb; 493 meta->skb = skb;
655 meta->dmaaddr = dmaaddr; 494 meta->dmaaddr = dmaaddr;
656 ring->ops->fill_descriptor(ring, desc, dmaaddr, 495 op32_fill_descriptor(ring, desc, dmaaddr, ring->rx_buffersize, 0, 0, 0);
657 ring->rx_buffersize, 0, 0, 0);
658 496
659 rxhdr = (struct b43legacy_rxhdr_fw3 *)(skb->data); 497 rxhdr = (struct b43legacy_rxhdr_fw3 *)(skb->data);
660 rxhdr->frame_len = 0; 498 rxhdr->frame_len = 0;
@@ -671,11 +509,11 @@ static int alloc_initial_descbuffers(struct b43legacy_dmaring *ring)
671{ 509{
672 int i; 510 int i;
673 int err = -ENOMEM; 511 int err = -ENOMEM;
674 struct b43legacy_dmadesc_generic *desc; 512 struct b43legacy_dmadesc32 *desc;
675 struct b43legacy_dmadesc_meta *meta; 513 struct b43legacy_dmadesc_meta *meta;
676 514
677 for (i = 0; i < ring->nr_slots; i++) { 515 for (i = 0; i < ring->nr_slots; i++) {
678 desc = ring->ops->idx2desc(ring, i, &meta); 516 desc = op32_idx2desc(ring, i, &meta);
679 517
680 err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL); 518 err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
681 if (err) { 519 if (err) {
@@ -692,7 +530,7 @@ out:
692 530
693err_unwind: 531err_unwind:
694 for (i--; i >= 0; i--) { 532 for (i--; i >= 0; i--) {
695 desc = ring->ops->idx2desc(ring, i, &meta); 533 desc = op32_idx2desc(ring, i, &meta);
696 534
697 unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0); 535 unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0);
698 dev_kfree_skb(meta->skb); 536 dev_kfree_skb(meta->skb);
@@ -710,83 +548,35 @@ static int dmacontroller_setup(struct b43legacy_dmaring *ring)
710 u32 value; 548 u32 value;
711 u32 addrext; 549 u32 addrext;
712 u32 trans = ring->dev->dma.translation; 550 u32 trans = ring->dev->dma.translation;
551 u32 ringbase = (u32)(ring->dmabase);
713 552
714 if (ring->tx) { 553 if (ring->tx) {
715 if (ring->type == B43legacy_DMA_64BIT) { 554 addrext = (ringbase & SSB_DMA_TRANSLATION_MASK)
716 u64 ringbase = (u64)(ring->dmabase); 555 >> SSB_DMA_TRANSLATION_SHIFT;
717 556 value = B43legacy_DMA32_TXENABLE;
718 addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK) 557 value |= (addrext << B43legacy_DMA32_TXADDREXT_SHIFT)
719 >> SSB_DMA_TRANSLATION_SHIFT; 558 & B43legacy_DMA32_TXADDREXT_MASK;
720 value = B43legacy_DMA64_TXENABLE; 559 b43legacy_dma_write(ring, B43legacy_DMA32_TXCTL, value);
721 value |= (addrext << B43legacy_DMA64_TXADDREXT_SHIFT) 560 b43legacy_dma_write(ring, B43legacy_DMA32_TXRING,
722 & B43legacy_DMA64_TXADDREXT_MASK; 561 (ringbase & ~SSB_DMA_TRANSLATION_MASK)
723 b43legacy_dma_write(ring, B43legacy_DMA64_TXCTL, 562 | trans);
724 value);
725 b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGLO,
726 (ringbase & 0xFFFFFFFF));
727 b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGHI,
728 ((ringbase >> 32)
729 & ~SSB_DMA_TRANSLATION_MASK)
730 | trans);
731 } else {
732 u32 ringbase = (u32)(ring->dmabase);
733
734 addrext = (ringbase & SSB_DMA_TRANSLATION_MASK)
735 >> SSB_DMA_TRANSLATION_SHIFT;
736 value = B43legacy_DMA32_TXENABLE;
737 value |= (addrext << B43legacy_DMA32_TXADDREXT_SHIFT)
738 & B43legacy_DMA32_TXADDREXT_MASK;
739 b43legacy_dma_write(ring, B43legacy_DMA32_TXCTL,
740 value);
741 b43legacy_dma_write(ring, B43legacy_DMA32_TXRING,
742 (ringbase &
743 ~SSB_DMA_TRANSLATION_MASK)
744 | trans);
745 }
746 } else { 563 } else {
747 err = alloc_initial_descbuffers(ring); 564 err = alloc_initial_descbuffers(ring);
748 if (err) 565 if (err)
749 goto out; 566 goto out;
750 if (ring->type == B43legacy_DMA_64BIT) { 567
751 u64 ringbase = (u64)(ring->dmabase); 568 addrext = (ringbase & SSB_DMA_TRANSLATION_MASK)
752 569 >> SSB_DMA_TRANSLATION_SHIFT;
753 addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK) 570 value = (ring->frameoffset <<
754 >> SSB_DMA_TRANSLATION_SHIFT; 571 B43legacy_DMA32_RXFROFF_SHIFT);
755 value = (ring->frameoffset << 572 value |= B43legacy_DMA32_RXENABLE;
756 B43legacy_DMA64_RXFROFF_SHIFT); 573 value |= (addrext << B43legacy_DMA32_RXADDREXT_SHIFT)
757 value |= B43legacy_DMA64_RXENABLE; 574 & B43legacy_DMA32_RXADDREXT_MASK;
758 value |= (addrext << B43legacy_DMA64_RXADDREXT_SHIFT) 575 b43legacy_dma_write(ring, B43legacy_DMA32_RXCTL, value);
759 & B43legacy_DMA64_RXADDREXT_MASK; 576 b43legacy_dma_write(ring, B43legacy_DMA32_RXRING,
760 b43legacy_dma_write(ring, B43legacy_DMA64_RXCTL, 577 (ringbase & ~SSB_DMA_TRANSLATION_MASK)
761 value); 578 | trans);
762 b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGLO, 579 b43legacy_dma_write(ring, B43legacy_DMA32_RXINDEX, 200);
763 (ringbase & 0xFFFFFFFF));
764 b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGHI,
765 ((ringbase >> 32) &
766 ~SSB_DMA_TRANSLATION_MASK) |
767 trans);
768 b43legacy_dma_write(ring, B43legacy_DMA64_RXINDEX,
769 200);
770 } else {
771 u32 ringbase = (u32)(ring->dmabase);
772
773 addrext = (ringbase & SSB_DMA_TRANSLATION_MASK)
774 >> SSB_DMA_TRANSLATION_SHIFT;
775 value = (ring->frameoffset <<
776 B43legacy_DMA32_RXFROFF_SHIFT);
777 value |= B43legacy_DMA32_RXENABLE;
778 value |= (addrext <<
779 B43legacy_DMA32_RXADDREXT_SHIFT)
780 & B43legacy_DMA32_RXADDREXT_MASK;
781 b43legacy_dma_write(ring, B43legacy_DMA32_RXCTL,
782 value);
783 b43legacy_dma_write(ring, B43legacy_DMA32_RXRING,
784 (ringbase &
785 ~SSB_DMA_TRANSLATION_MASK)
786 | trans);
787 b43legacy_dma_write(ring, B43legacy_DMA32_RXINDEX,
788 200);
789 }
790 } 580 }
791 581
792out: 582out:
@@ -799,19 +589,11 @@ static void dmacontroller_cleanup(struct b43legacy_dmaring *ring)
799 if (ring->tx) { 589 if (ring->tx) {
800 b43legacy_dmacontroller_tx_reset(ring->dev, ring->mmio_base, 590 b43legacy_dmacontroller_tx_reset(ring->dev, ring->mmio_base,
801 ring->type); 591 ring->type);
802 if (ring->type == B43legacy_DMA_64BIT) { 592 b43legacy_dma_write(ring, B43legacy_DMA32_TXRING, 0);
803 b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGLO, 0);
804 b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGHI, 0);
805 } else
806 b43legacy_dma_write(ring, B43legacy_DMA32_TXRING, 0);
807 } else { 593 } else {
808 b43legacy_dmacontroller_rx_reset(ring->dev, ring->mmio_base, 594 b43legacy_dmacontroller_rx_reset(ring->dev, ring->mmio_base,
809 ring->type); 595 ring->type);
810 if (ring->type == B43legacy_DMA_64BIT) { 596 b43legacy_dma_write(ring, B43legacy_DMA32_RXRING, 0);
811 b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGLO, 0);
812 b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGHI, 0);
813 } else
814 b43legacy_dma_write(ring, B43legacy_DMA32_RXRING, 0);
815 } 597 }
816} 598}
817 599
@@ -823,7 +605,7 @@ static void free_all_descbuffers(struct b43legacy_dmaring *ring)
823 if (!ring->used_slots) 605 if (!ring->used_slots)
824 return; 606 return;
825 for (i = 0; i < ring->nr_slots; i++) { 607 for (i = 0; i < ring->nr_slots; i++) {
826 ring->ops->idx2desc(ring, i, &meta); 608 op32_idx2desc(ring, i, &meta);
827 609
828 if (!meta->skb) { 610 if (!meta->skb) {
829 B43legacy_WARN_ON(!ring->tx); 611 B43legacy_WARN_ON(!ring->tx);
@@ -844,9 +626,6 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev)
844 u32 tmp; 626 u32 tmp;
845 u16 mmio_base; 627 u16 mmio_base;
846 628
847 tmp = b43legacy_read32(dev, SSB_TMSHIGH);
848 if (tmp & SSB_TMSHIGH_DMA64)
849 return DMA_BIT_MASK(64);
850 mmio_base = b43legacy_dmacontroller_base(0, 0); 629 mmio_base = b43legacy_dmacontroller_base(0, 0);
851 b43legacy_write32(dev, 630 b43legacy_write32(dev,
852 mmio_base + B43legacy_DMA32_TXCTL, 631 mmio_base + B43legacy_DMA32_TXCTL,
@@ -865,8 +644,6 @@ static enum b43legacy_dmatype dma_mask_to_engine_type(u64 dmamask)
865 return B43legacy_DMA_30BIT; 644 return B43legacy_DMA_30BIT;
866 if (dmamask == DMA_BIT_MASK(32)) 645 if (dmamask == DMA_BIT_MASK(32))
867 return B43legacy_DMA_32BIT; 646 return B43legacy_DMA_32BIT;
868 if (dmamask == DMA_BIT_MASK(64))
869 return B43legacy_DMA_64BIT;
870 B43legacy_WARN_ON(1); 647 B43legacy_WARN_ON(1);
871 return B43legacy_DMA_30BIT; 648 return B43legacy_DMA_30BIT;
872} 649}
@@ -937,10 +714,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
937 ring->nr_slots = nr_slots; 714 ring->nr_slots = nr_slots;
938 ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index); 715 ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index);
939 ring->index = controller_index; 716 ring->index = controller_index;
940 if (type == B43legacy_DMA_64BIT)
941 ring->ops = &dma64_ops;
942 else
943 ring->ops = &dma32_ops;
944 if (for_tx) { 717 if (for_tx) {
945 ring->tx = 1; 718 ring->tx = 1;
946 ring->current_slot = -1; 719 ring->current_slot = -1;
@@ -1247,12 +1020,11 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
1247 struct sk_buff **in_skb) 1020 struct sk_buff **in_skb)
1248{ 1021{
1249 struct sk_buff *skb = *in_skb; 1022 struct sk_buff *skb = *in_skb;
1250 const struct b43legacy_dma_ops *ops = ring->ops;
1251 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1023 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1252 u8 *header; 1024 u8 *header;
1253 int slot, old_top_slot, old_used_slots; 1025 int slot, old_top_slot, old_used_slots;
1254 int err; 1026 int err;
1255 struct b43legacy_dmadesc_generic *desc; 1027 struct b43legacy_dmadesc32 *desc;
1256 struct b43legacy_dmadesc_meta *meta; 1028 struct b43legacy_dmadesc_meta *meta;
1257 struct b43legacy_dmadesc_meta *meta_hdr; 1029 struct b43legacy_dmadesc_meta *meta_hdr;
1258 struct sk_buff *bounce_skb; 1030 struct sk_buff *bounce_skb;
@@ -1265,7 +1037,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
1265 1037
1266 /* Get a slot for the header. */ 1038 /* Get a slot for the header. */
1267 slot = request_slot(ring); 1039 slot = request_slot(ring);
1268 desc = ops->idx2desc(ring, slot, &meta_hdr); 1040 desc = op32_idx2desc(ring, slot, &meta_hdr);
1269 memset(meta_hdr, 0, sizeof(*meta_hdr)); 1041 memset(meta_hdr, 0, sizeof(*meta_hdr));
1270 1042
1271 header = &(ring->txhdr_cache[slot * sizeof( 1043 header = &(ring->txhdr_cache[slot * sizeof(
@@ -1287,12 +1059,12 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
1287 ring->used_slots = old_used_slots; 1059 ring->used_slots = old_used_slots;
1288 return -EIO; 1060 return -EIO;
1289 } 1061 }
1290 ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr, 1062 op32_fill_descriptor(ring, desc, meta_hdr->dmaaddr,
1291 sizeof(struct b43legacy_txhdr_fw3), 1, 0, 0); 1063 sizeof(struct b43legacy_txhdr_fw3), 1, 0, 0);
1292 1064
1293 /* Get a slot for the payload. */ 1065 /* Get a slot for the payload. */
1294 slot = request_slot(ring); 1066 slot = request_slot(ring);
1295 desc = ops->idx2desc(ring, slot, &meta); 1067 desc = op32_idx2desc(ring, slot, &meta);
1296 memset(meta, 0, sizeof(*meta)); 1068 memset(meta, 0, sizeof(*meta));
1297 1069
1298 meta->skb = skb; 1070 meta->skb = skb;
@@ -1328,12 +1100,12 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
1328 } 1100 }
1329 } 1101 }
1330 1102
1331 ops->fill_descriptor(ring, desc, meta->dmaaddr, 1103 op32_fill_descriptor(ring, desc, meta->dmaaddr,
1332 skb->len, 0, 1, 1); 1104 skb->len, 0, 1, 1);
1333 1105
1334 wmb(); /* previous stuff MUST be done */ 1106 wmb(); /* previous stuff MUST be done */
1335 /* Now transfer the whole frame. */ 1107 /* Now transfer the whole frame. */
1336 ops->poke_tx(ring, next_slot(ring, slot)); 1108 op32_poke_tx(ring, next_slot(ring, slot));
1337 return 0; 1109 return 0;
1338 1110
1339out_free_bounce: 1111out_free_bounce:
@@ -1429,7 +1201,6 @@ out_unlock:
1429void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, 1201void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
1430 const struct b43legacy_txstatus *status) 1202 const struct b43legacy_txstatus *status)
1431{ 1203{
1432 const struct b43legacy_dma_ops *ops;
1433 struct b43legacy_dmaring *ring; 1204 struct b43legacy_dmaring *ring;
1434 struct b43legacy_dmadesc_meta *meta; 1205 struct b43legacy_dmadesc_meta *meta;
1435 int retry_limit; 1206 int retry_limit;
@@ -1442,10 +1213,9 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
1442 spin_lock(&ring->lock); 1213 spin_lock(&ring->lock);
1443 1214
1444 B43legacy_WARN_ON(!ring->tx); 1215 B43legacy_WARN_ON(!ring->tx);
1445 ops = ring->ops;
1446 while (1) { 1216 while (1) {
1447 B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); 1217 B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
1448 ops->idx2desc(ring, slot, &meta); 1218 op32_idx2desc(ring, slot, &meta);
1449 1219
1450 if (meta->skb) 1220 if (meta->skb)
1451 unmap_descbuffer(ring, meta->dmaaddr, 1221 unmap_descbuffer(ring, meta->dmaaddr,
@@ -1528,8 +1298,7 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
1528static void dma_rx(struct b43legacy_dmaring *ring, 1298static void dma_rx(struct b43legacy_dmaring *ring,
1529 int *slot) 1299 int *slot)
1530{ 1300{
1531 const struct b43legacy_dma_ops *ops = ring->ops; 1301 struct b43legacy_dmadesc32 *desc;
1532 struct b43legacy_dmadesc_generic *desc;
1533 struct b43legacy_dmadesc_meta *meta; 1302 struct b43legacy_dmadesc_meta *meta;
1534 struct b43legacy_rxhdr_fw3 *rxhdr; 1303 struct b43legacy_rxhdr_fw3 *rxhdr;
1535 struct sk_buff *skb; 1304 struct sk_buff *skb;
@@ -1537,7 +1306,7 @@ static void dma_rx(struct b43legacy_dmaring *ring,
1537 int err; 1306 int err;
1538 dma_addr_t dmaaddr; 1307 dma_addr_t dmaaddr;
1539 1308
1540 desc = ops->idx2desc(ring, *slot, &meta); 1309 desc = op32_idx2desc(ring, *slot, &meta);
1541 1310
1542 sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize); 1311 sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
1543 skb = meta->skb; 1312 skb = meta->skb;
@@ -1589,7 +1358,7 @@ static void dma_rx(struct b43legacy_dmaring *ring,
1589 s32 tmp = len; 1358 s32 tmp = len;
1590 1359
1591 while (1) { 1360 while (1) {
1592 desc = ops->idx2desc(ring, *slot, &meta); 1361 desc = op32_idx2desc(ring, *slot, &meta);
1593 /* recycle the descriptor buffer. */ 1362 /* recycle the descriptor buffer. */
1594 sync_descbuffer_for_device(ring, meta->dmaaddr, 1363 sync_descbuffer_for_device(ring, meta->dmaaddr,
1595 ring->rx_buffersize); 1364 ring->rx_buffersize);
@@ -1626,13 +1395,12 @@ drop:
1626 1395
1627void b43legacy_dma_rx(struct b43legacy_dmaring *ring) 1396void b43legacy_dma_rx(struct b43legacy_dmaring *ring)
1628{ 1397{
1629 const struct b43legacy_dma_ops *ops = ring->ops;
1630 int slot; 1398 int slot;
1631 int current_slot; 1399 int current_slot;
1632 int used_slots = 0; 1400 int used_slots = 0;
1633 1401
1634 B43legacy_WARN_ON(ring->tx); 1402 B43legacy_WARN_ON(ring->tx);
1635 current_slot = ops->get_current_rxslot(ring); 1403 current_slot = op32_get_current_rxslot(ring);
1636 B43legacy_WARN_ON(!(current_slot >= 0 && current_slot < 1404 B43legacy_WARN_ON(!(current_slot >= 0 && current_slot <
1637 ring->nr_slots)); 1405 ring->nr_slots));
1638 1406
@@ -1641,7 +1409,7 @@ void b43legacy_dma_rx(struct b43legacy_dmaring *ring)
1641 dma_rx(ring, &slot); 1409 dma_rx(ring, &slot);
1642 update_max_used_slots(ring, ++used_slots); 1410 update_max_used_slots(ring, ++used_slots);
1643 } 1411 }
1644 ops->set_current_rxslot(ring, slot); 1412 op32_set_current_rxslot(ring, slot);
1645 ring->current_slot = slot; 1413 ring->current_slot = slot;
1646} 1414}
1647 1415
@@ -1651,7 +1419,7 @@ static void b43legacy_dma_tx_suspend_ring(struct b43legacy_dmaring *ring)
1651 1419
1652 spin_lock_irqsave(&ring->lock, flags); 1420 spin_lock_irqsave(&ring->lock, flags);
1653 B43legacy_WARN_ON(!ring->tx); 1421 B43legacy_WARN_ON(!ring->tx);
1654 ring->ops->tx_suspend(ring); 1422 op32_tx_suspend(ring);
1655 spin_unlock_irqrestore(&ring->lock, flags); 1423 spin_unlock_irqrestore(&ring->lock, flags);
1656} 1424}
1657 1425
@@ -1661,7 +1429,7 @@ static void b43legacy_dma_tx_resume_ring(struct b43legacy_dmaring *ring)
1661 1429
1662 spin_lock_irqsave(&ring->lock, flags); 1430 spin_lock_irqsave(&ring->lock, flags);
1663 B43legacy_WARN_ON(!ring->tx); 1431 B43legacy_WARN_ON(!ring->tx);
1664 ring->ops->tx_resume(ring); 1432 op32_tx_resume(ring);
1665 spin_unlock_irqrestore(&ring->lock, flags); 1433 spin_unlock_irqrestore(&ring->lock, flags);
1666} 1434}
1667 1435
diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h
index 686941c242f..504a58767e9 100644
--- a/drivers/net/wireless/b43legacy/dma.h
+++ b/drivers/net/wireless/b43legacy/dma.h
@@ -82,90 +82,6 @@ struct b43legacy_dmadesc32 {
82#define B43legacy_DMA32_DCTL_FRAMESTART 0x80000000 82#define B43legacy_DMA32_DCTL_FRAMESTART 0x80000000
83 83
84 84
85
86/*** 64-bit DMA Engine. ***/
87
88/* 64-bit DMA controller registers. */
89#define B43legacy_DMA64_TXCTL 0x00
90#define B43legacy_DMA64_TXENABLE 0x00000001
91#define B43legacy_DMA64_TXSUSPEND 0x00000002
92#define B43legacy_DMA64_TXLOOPBACK 0x00000004
93#define B43legacy_DMA64_TXFLUSH 0x00000010
94#define B43legacy_DMA64_TXADDREXT_MASK 0x00030000
95#define B43legacy_DMA64_TXADDREXT_SHIFT 16
96#define B43legacy_DMA64_TXINDEX 0x04
97#define B43legacy_DMA64_TXRINGLO 0x08
98#define B43legacy_DMA64_TXRINGHI 0x0C
99#define B43legacy_DMA64_TXSTATUS 0x10
100#define B43legacy_DMA64_TXSTATDPTR 0x00001FFF
101#define B43legacy_DMA64_TXSTAT 0xF0000000
102#define B43legacy_DMA64_TXSTAT_DISABLED 0x00000000
103#define B43legacy_DMA64_TXSTAT_ACTIVE 0x10000000
104#define B43legacy_DMA64_TXSTAT_IDLEWAIT 0x20000000
105#define B43legacy_DMA64_TXSTAT_STOPPED 0x30000000
106#define B43legacy_DMA64_TXSTAT_SUSP 0x40000000
107#define B43legacy_DMA64_TXERROR 0x14
108#define B43legacy_DMA64_TXERRDPTR 0x0001FFFF
109#define B43legacy_DMA64_TXERR 0xF0000000
110#define B43legacy_DMA64_TXERR_NOERR 0x00000000
111#define B43legacy_DMA64_TXERR_PROT 0x10000000
112#define B43legacy_DMA64_TXERR_UNDERRUN 0x20000000
113#define B43legacy_DMA64_TXERR_TRANSFER 0x30000000
114#define B43legacy_DMA64_TXERR_DESCREAD 0x40000000
115#define B43legacy_DMA64_TXERR_CORE 0x50000000
116#define B43legacy_DMA64_RXCTL 0x20
117#define B43legacy_DMA64_RXENABLE 0x00000001
118#define B43legacy_DMA64_RXFROFF_MASK 0x000000FE
119#define B43legacy_DMA64_RXFROFF_SHIFT 1
120#define B43legacy_DMA64_RXDIRECTFIFO 0x00000100
121#define B43legacy_DMA64_RXADDREXT_MASK 0x00030000
122#define B43legacy_DMA64_RXADDREXT_SHIFT 16
123#define B43legacy_DMA64_RXINDEX 0x24
124#define B43legacy_DMA64_RXRINGLO 0x28
125#define B43legacy_DMA64_RXRINGHI 0x2C
126#define B43legacy_DMA64_RXSTATUS 0x30
127#define B43legacy_DMA64_RXSTATDPTR 0x00001FFF
128#define B43legacy_DMA64_RXSTAT 0xF0000000
129#define B43legacy_DMA64_RXSTAT_DISABLED 0x00000000
130#define B43legacy_DMA64_RXSTAT_ACTIVE 0x10000000
131#define B43legacy_DMA64_RXSTAT_IDLEWAIT 0x20000000
132#define B43legacy_DMA64_RXSTAT_STOPPED 0x30000000
133#define B43legacy_DMA64_RXSTAT_SUSP 0x40000000
134#define B43legacy_DMA64_RXERROR 0x34
135#define B43legacy_DMA64_RXERRDPTR 0x0001FFFF
136#define B43legacy_DMA64_RXERR 0xF0000000
137#define B43legacy_DMA64_RXERR_NOERR 0x00000000
138#define B43legacy_DMA64_RXERR_PROT 0x10000000
139#define B43legacy_DMA64_RXERR_UNDERRUN 0x20000000
140#define B43legacy_DMA64_RXERR_TRANSFER 0x30000000
141#define B43legacy_DMA64_RXERR_DESCREAD 0x40000000
142#define B43legacy_DMA64_RXERR_CORE 0x50000000
143
144/* 64-bit DMA descriptor. */
145struct b43legacy_dmadesc64 {
146 __le32 control0;
147 __le32 control1;
148 __le32 address_low;
149 __le32 address_high;
150} __packed;
151#define B43legacy_DMA64_DCTL0_DTABLEEND 0x10000000
152#define B43legacy_DMA64_DCTL0_IRQ 0x20000000
153#define B43legacy_DMA64_DCTL0_FRAMEEND 0x40000000
154#define B43legacy_DMA64_DCTL0_FRAMESTART 0x80000000
155#define B43legacy_DMA64_DCTL1_BYTECNT 0x00001FFF
156#define B43legacy_DMA64_DCTL1_ADDREXT_MASK 0x00030000
157#define B43legacy_DMA64_DCTL1_ADDREXT_SHIFT 16
158
159
160
161struct b43legacy_dmadesc_generic {
162 union {
163 struct b43legacy_dmadesc32 dma32;
164 struct b43legacy_dmadesc64 dma64;
165 } __packed;
166} __packed;
167
168
169/* Misc DMA constants */ 85/* Misc DMA constants */
170#define B43legacy_DMA_RINGMEMSIZE PAGE_SIZE 86#define B43legacy_DMA_RINGMEMSIZE PAGE_SIZE
171#define B43legacy_DMA0_RX_FRAMEOFFSET 30 87#define B43legacy_DMA0_RX_FRAMEOFFSET 30
@@ -197,35 +113,12 @@ struct b43legacy_dmadesc_meta {
197 bool is_last_fragment; 113 bool is_last_fragment;
198}; 114};
199 115
200struct b43legacy_dmaring;
201
202/* Lowlevel DMA operations that differ between 32bit and 64bit DMA. */
203struct b43legacy_dma_ops {
204 struct b43legacy_dmadesc_generic * (*idx2desc)
205 (struct b43legacy_dmaring *ring,
206 int slot,
207 struct b43legacy_dmadesc_meta
208 **meta);
209 void (*fill_descriptor)(struct b43legacy_dmaring *ring,
210 struct b43legacy_dmadesc_generic *desc,
211 dma_addr_t dmaaddr, u16 bufsize,
212 int start, int end, int irq);
213 void (*poke_tx)(struct b43legacy_dmaring *ring, int slot);
214 void (*tx_suspend)(struct b43legacy_dmaring *ring);
215 void (*tx_resume)(struct b43legacy_dmaring *ring);
216 int (*get_current_rxslot)(struct b43legacy_dmaring *ring);
217 void (*set_current_rxslot)(struct b43legacy_dmaring *ring, int slot);
218};
219
220enum b43legacy_dmatype { 116enum b43legacy_dmatype {
221 B43legacy_DMA_30BIT = 30, 117 B43legacy_DMA_30BIT = 30,
222 B43legacy_DMA_32BIT = 32, 118 B43legacy_DMA_32BIT = 32,
223 B43legacy_DMA_64BIT = 64,
224}; 119};
225 120
226struct b43legacy_dmaring { 121struct b43legacy_dmaring {
227 /* Lowlevel DMA ops. */
228 const struct b43legacy_dma_ops *ops;
229 /* Kernel virtual base address of the ring memory. */ 122 /* Kernel virtual base address of the ring memory. */
230 void *descbase; 123 void *descbase;
231 /* Meta data about all descriptors. */ 124 /* Meta data about all descriptors. */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 04c03b212a5..aae8dfcb852 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -35,7 +35,6 @@
35#include <linux/if_arp.h> 35#include <linux/if_arp.h>
36#include <linux/etherdevice.h> 36#include <linux/etherdevice.h>
37#include <linux/firmware.h> 37#include <linux/firmware.h>
38#include <linux/wireless.h>
39#include <linux/workqueue.h> 38#include <linux/workqueue.h>
40#include <linux/sched.h> 39#include <linux/sched.h>
41#include <linux/skbuff.h> 40#include <linux/skbuff.h>
@@ -3785,7 +3784,8 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
3785 INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work); 3784 INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work);
3786 3785
3787 ssb_set_devtypedata(dev, wl); 3786 ssb_set_devtypedata(dev, wl);
3788 b43legacyinfo(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id); 3787 b43legacyinfo(wl, "Broadcom %04X WLAN found (core revision %u)\n",
3788 dev->bus->chip_id, dev->id.revision);
3789 err = 0; 3789 err = 0;
3790out: 3790out:
3791 return err; 3791 return err;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 553f66b67c1..f303df43ed3 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -32,6 +32,7 @@
32 32
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <net/cfg80211-wext.h>
35#include "ipw2200.h" 36#include "ipw2200.h"
36 37
37 38
diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-led.c b/drivers/net/wireless/iwlegacy/iwl-3945-led.c
index abd923558d4..7a7f0f38c8a 100644
--- a/drivers/net/wireless/iwlegacy/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlegacy/iwl-3945-led.c
@@ -32,7 +32,6 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/skbuff.h> 33#include <linux/skbuff.h>
34#include <linux/netdevice.h> 34#include <linux/netdevice.h>
35#include <linux/wireless.h>
36#include <net/mac80211.h> 35#include <net/mac80211.h>
37#include <linux/etherdevice.h> 36#include <linux/etherdevice.h>
38#include <asm/unaligned.h> 37#include <asm/unaligned.h>
diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-rs.c b/drivers/net/wireless/iwlegacy/iwl-3945-rs.c
index 977bd2477c6..0cc5177d738 100644
--- a/drivers/net/wireless/iwlegacy/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlegacy/iwl-3945-rs.c
@@ -28,7 +28,6 @@
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/skbuff.h> 29#include <linux/skbuff.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/wireless.h>
32#include <net/mac80211.h> 31#include <net/mac80211.h>
33 32
34#include <linux/netdevice.h> 33#include <linux/netdevice.h>
diff --git a/drivers/net/wireless/iwlegacy/iwl-3945.c b/drivers/net/wireless/iwlegacy/iwl-3945.c
index 73fe3cdf796..f7c0a743847 100644
--- a/drivers/net/wireless/iwlegacy/iwl-3945.c
+++ b/drivers/net/wireless/iwlegacy/iwl-3945.c
@@ -34,7 +34,6 @@
34#include <linux/sched.h> 34#include <linux/sched.h>
35#include <linux/skbuff.h> 35#include <linux/skbuff.h>
36#include <linux/netdevice.h> 36#include <linux/netdevice.h>
37#include <linux/wireless.h>
38#include <linux/firmware.h> 37#include <linux/firmware.h>
39#include <linux/etherdevice.h> 38#include <linux/etherdevice.h>
40#include <asm/unaligned.h> 39#include <asm/unaligned.h>
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-led.c b/drivers/net/wireless/iwlegacy/iwl-4965-led.c
index 26d324e3069..6862fdcaee6 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965-led.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965-led.c
@@ -32,7 +32,6 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/skbuff.h> 33#include <linux/skbuff.h>
34#include <linux/netdevice.h> 34#include <linux/netdevice.h>
35#include <linux/wireless.h>
36#include <net/mac80211.h> 35#include <net/mac80211.h>
37#include <linux/etherdevice.h> 36#include <linux/etherdevice.h>
38#include <asm/unaligned.h> 37#include <asm/unaligned.h>
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
index 9b65153bdd0..57ebe214e68 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
@@ -27,7 +27,6 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/skbuff.h> 28#include <linux/skbuff.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/wireless.h>
31#include <net/mac80211.h> 30#include <net/mac80211.h>
32 31
33#include <linux/netdevice.h> 32#include <linux/netdevice.h>
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c
index ecdc6e55742..86f4fce193e 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965.c
@@ -33,7 +33,6 @@
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/skbuff.h> 34#include <linux/skbuff.h>
35#include <linux/netdevice.h> 35#include <linux/netdevice.h>
36#include <linux/wireless.h>
37#include <net/mac80211.h> 36#include <net/mac80211.h>
38#include <linux/etherdevice.h> 37#include <linux/etherdevice.h>
39#include <asm/unaligned.h> 38#include <asm/unaligned.h>
diff --git a/drivers/net/wireless/iwlegacy/iwl-led.c b/drivers/net/wireless/iwlegacy/iwl-led.c
index bda0d61b2c0..dc568a474c5 100644
--- a/drivers/net/wireless/iwlegacy/iwl-led.c
+++ b/drivers/net/wireless/iwlegacy/iwl-led.c
@@ -33,7 +33,6 @@
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/skbuff.h> 34#include <linux/skbuff.h>
35#include <linux/netdevice.h> 35#include <linux/netdevice.h>
36#include <linux/wireless.h>
37#include <net/mac80211.h> 36#include <net/mac80211.h>
38#include <linux/etherdevice.h> 37#include <linux/etherdevice.h>
39#include <asm/unaligned.h> 38#include <asm/unaligned.h>
diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c
index 795826a014e..015739d204f 100644
--- a/drivers/net/wireless/iwlegacy/iwl3945-base.c
+++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c
@@ -40,7 +40,6 @@
40#include <linux/sched.h> 40#include <linux/sched.h>
41#include <linux/skbuff.h> 41#include <linux/skbuff.h>
42#include <linux/netdevice.h> 42#include <linux/netdevice.h>
43#include <linux/wireless.h>
44#include <linux/firmware.h> 43#include <linux/firmware.h>
45#include <linux/etherdevice.h> 44#include <linux/etherdevice.h>
46#include <linux/if_arp.h> 45#include <linux/if_arp.h>
diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c
index 14334668034..6bc5575c8df 100644
--- a/drivers/net/wireless/iwlegacy/iwl4965-base.c
+++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c
@@ -40,7 +40,6 @@
40#include <linux/sched.h> 40#include <linux/sched.h>
41#include <linux/skbuff.h> 41#include <linux/skbuff.h>
42#include <linux/netdevice.h> 42#include <linux/netdevice.h>
43#include <linux/wireless.h>
44#include <linux/firmware.h> 43#include <linux/firmware.h>
45#include <linux/etherdevice.h> 44#include <linux/etherdevice.h>
46#include <linux/if_arp.h> 45#include <linux/if_arp.h>
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index ad3bdba6bee..1d7572f9887 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -111,20 +111,3 @@ config IWLWIFI_DEVICE_SVTOOL
111 NL80211_TESTMODE. svtool is a software validation tool that runs in 111 NL80211_TESTMODE. svtool is a software validation tool that runs in
112 the user space and interacts with the device in the kernel space 112 the user space and interacts with the device in the kernel space
113 through the generic netlink message via NL80211_TESTMODE channel. 113 through the generic netlink message via NL80211_TESTMODE channel.
114
115config IWL_P2P
116 bool "iwlwifi experimental P2P support"
117 depends on IWLAGN
118 help
119 This option enables experimental P2P support for some devices
120 based on microcode support. Since P2P support is still under
121 development, this option may even enable it for some devices
122 now that turn out to not support it in the future due to
123 microcode restrictions.
124
125 To determine if your microcode supports the experimental P2P
126 offered by this option, check if the driver advertises AP
127 support when it is loaded.
128
129 Say Y only if you want to experiment with P2P.
130
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 01b49eb8c8e..ccdbed56717 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -30,7 +30,6 @@
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/skbuff.h> 31#include <linux/skbuff.h>
32#include <linux/netdevice.h> 32#include <linux/netdevice.h>
33#include <linux/wireless.h>
34#include <net/mac80211.h> 33#include <net/mac80211.h>
35#include <linux/etherdevice.h> 34#include <linux/etherdevice.h>
36#include <asm/unaligned.h> 35#include <asm/unaligned.h>
@@ -46,8 +45,12 @@
46#include "iwl-agn-hw.h" 45#include "iwl-agn-hw.h"
47 46
48/* Highest firmware API version supported */ 47/* Highest firmware API version supported */
49#define IWL1000_UCODE_API_MAX 5 48#define IWL1000_UCODE_API_MAX 6
50#define IWL100_UCODE_API_MAX 5 49#define IWL100_UCODE_API_MAX 6
50
51/* Oldest version we won't warn about */
52#define IWL1000_UCODE_API_OK 5
53#define IWL100_UCODE_API_OK 5
51 54
52/* Lowest firmware API version supported */ 55/* Lowest firmware API version supported */
53#define IWL1000_UCODE_API_MIN 1 56#define IWL1000_UCODE_API_MIN 1
@@ -135,8 +138,7 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
135 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; 138 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
136 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; 139 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
137 140
138 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 141 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ);
139 BIT(IEEE80211_BAND_5GHZ);
140 142
141 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); 143 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
142 if (priv->cfg->rx_with_siso_diversity) 144 if (priv->cfg->rx_with_siso_diversity)
@@ -201,12 +203,13 @@ static struct iwl_base_params iwl1000_base_params = {
201static struct iwl_ht_params iwl1000_ht_params = { 203static struct iwl_ht_params iwl1000_ht_params = {
202 .ht_greenfield_support = true, 204 .ht_greenfield_support = true,
203 .use_rts_for_aggregation = true, /* use rts/cts protection */ 205 .use_rts_for_aggregation = true, /* use rts/cts protection */
204 .smps_mode = IEEE80211_SMPS_STATIC, 206 .smps_mode = IEEE80211_SMPS_DYNAMIC,
205}; 207};
206 208
207#define IWL_DEVICE_1000 \ 209#define IWL_DEVICE_1000 \
208 .fw_name_pre = IWL1000_FW_PRE, \ 210 .fw_name_pre = IWL1000_FW_PRE, \
209 .ucode_api_max = IWL1000_UCODE_API_MAX, \ 211 .ucode_api_max = IWL1000_UCODE_API_MAX, \
212 .ucode_api_ok = IWL1000_UCODE_API_OK, \
210 .ucode_api_min = IWL1000_UCODE_API_MIN, \ 213 .ucode_api_min = IWL1000_UCODE_API_MIN, \
211 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ 214 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
212 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ 215 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
@@ -228,6 +231,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
228#define IWL_DEVICE_100 \ 231#define IWL_DEVICE_100 \
229 .fw_name_pre = IWL100_FW_PRE, \ 232 .fw_name_pre = IWL100_FW_PRE, \
230 .ucode_api_max = IWL100_UCODE_API_MAX, \ 233 .ucode_api_max = IWL100_UCODE_API_MAX, \
234 .ucode_api_ok = IWL100_UCODE_API_OK, \
231 .ucode_api_min = IWL100_UCODE_API_MIN, \ 235 .ucode_api_min = IWL100_UCODE_API_MIN, \
232 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ 236 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
233 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ 237 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index 0e13f0bb2e1..54d931d614f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -30,7 +30,6 @@
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/skbuff.h> 31#include <linux/skbuff.h>
32#include <linux/netdevice.h> 32#include <linux/netdevice.h>
33#include <linux/wireless.h>
34#include <net/mac80211.h> 33#include <net/mac80211.h>
35#include <linux/etherdevice.h> 34#include <linux/etherdevice.h>
36#include <asm/unaligned.h> 35#include <asm/unaligned.h>
@@ -47,10 +46,16 @@
47#include "iwl-6000-hw.h" 46#include "iwl-6000-hw.h"
48 47
49/* Highest firmware API version supported */ 48/* Highest firmware API version supported */
50#define IWL2030_UCODE_API_MAX 5 49#define IWL2030_UCODE_API_MAX 6
51#define IWL2000_UCODE_API_MAX 5 50#define IWL2000_UCODE_API_MAX 6
52#define IWL105_UCODE_API_MAX 5 51#define IWL105_UCODE_API_MAX 6
53#define IWL135_UCODE_API_MAX 5 52#define IWL135_UCODE_API_MAX 6
53
54/* Oldest version we won't warn about */
55#define IWL2030_UCODE_API_OK 5
56#define IWL2000_UCODE_API_OK 5
57#define IWL105_UCODE_API_OK 5
58#define IWL135_UCODE_API_OK 5
54 59
55/* Lowest firmware API version supported */ 60/* Lowest firmware API version supported */
56#define IWL2030_UCODE_API_MIN 5 61#define IWL2030_UCODE_API_MIN 5
@@ -130,8 +135,7 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
130 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; 135 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
131 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; 136 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
132 137
133 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 138 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ);
134 BIT(IEEE80211_BAND_5GHZ);
135 139
136 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); 140 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
137 if (priv->cfg->rx_with_siso_diversity) 141 if (priv->cfg->rx_with_siso_diversity)
@@ -217,6 +221,7 @@ static struct iwl_base_params iwl2000_base_params = {
217 .wd_timeout = IWL_DEF_WD_TIMEOUT, 221 .wd_timeout = IWL_DEF_WD_TIMEOUT,
218 .max_event_log_size = 512, 222 .max_event_log_size = 512,
219 .shadow_reg_enable = true, 223 .shadow_reg_enable = true,
224 .hd_v2 = true,
220}; 225};
221 226
222 227
@@ -236,6 +241,7 @@ static struct iwl_base_params iwl2030_base_params = {
236 .wd_timeout = IWL_LONG_WD_TIMEOUT, 241 .wd_timeout = IWL_LONG_WD_TIMEOUT,
237 .max_event_log_size = 512, 242 .max_event_log_size = 512,
238 .shadow_reg_enable = true, 243 .shadow_reg_enable = true,
244 .hd_v2 = true,
239}; 245};
240 246
241static struct iwl_ht_params iwl2000_ht_params = { 247static struct iwl_ht_params iwl2000_ht_params = {
@@ -256,6 +262,7 @@ static struct iwl_bt_params iwl2030_bt_params = {
256#define IWL_DEVICE_2000 \ 262#define IWL_DEVICE_2000 \
257 .fw_name_pre = IWL2000_FW_PRE, \ 263 .fw_name_pre = IWL2000_FW_PRE, \
258 .ucode_api_max = IWL2000_UCODE_API_MAX, \ 264 .ucode_api_max = IWL2000_UCODE_API_MAX, \
265 .ucode_api_ok = IWL2000_UCODE_API_OK, \
259 .ucode_api_min = IWL2000_UCODE_API_MIN, \ 266 .ucode_api_min = IWL2000_UCODE_API_MIN, \
260 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 267 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
261 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 268 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
@@ -280,6 +287,7 @@ struct iwl_cfg iwl2000_2bg_cfg = {
280#define IWL_DEVICE_2030 \ 287#define IWL_DEVICE_2030 \
281 .fw_name_pre = IWL2030_FW_PRE, \ 288 .fw_name_pre = IWL2030_FW_PRE, \
282 .ucode_api_max = IWL2030_UCODE_API_MAX, \ 289 .ucode_api_max = IWL2030_UCODE_API_MAX, \
290 .ucode_api_ok = IWL2030_UCODE_API_OK, \
283 .ucode_api_min = IWL2030_UCODE_API_MIN, \ 291 .ucode_api_min = IWL2030_UCODE_API_MIN, \
284 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 292 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
285 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 293 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
@@ -306,6 +314,7 @@ struct iwl_cfg iwl2030_2bg_cfg = {
306#define IWL_DEVICE_105 \ 314#define IWL_DEVICE_105 \
307 .fw_name_pre = IWL105_FW_PRE, \ 315 .fw_name_pre = IWL105_FW_PRE, \
308 .ucode_api_max = IWL105_UCODE_API_MAX, \ 316 .ucode_api_max = IWL105_UCODE_API_MAX, \
317 .ucode_api_ok = IWL105_UCODE_API_OK, \
309 .ucode_api_min = IWL105_UCODE_API_MIN, \ 318 .ucode_api_min = IWL105_UCODE_API_MIN, \
310 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 319 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
311 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 320 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
@@ -332,6 +341,7 @@ struct iwl_cfg iwl105_bgn_cfg = {
332#define IWL_DEVICE_135 \ 341#define IWL_DEVICE_135 \
333 .fw_name_pre = IWL135_FW_PRE, \ 342 .fw_name_pre = IWL135_FW_PRE, \
334 .ucode_api_max = IWL135_UCODE_API_MAX, \ 343 .ucode_api_max = IWL135_UCODE_API_MAX, \
344 .ucode_api_ok = IWL135_UCODE_API_OK, \
335 .ucode_api_min = IWL135_UCODE_API_MIN, \ 345 .ucode_api_min = IWL135_UCODE_API_MIN, \
336 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 346 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
337 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 347 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index c95cefd529d..a9adee5634d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -31,7 +31,6 @@
31#include <linux/sched.h> 31#include <linux/sched.h>
32#include <linux/skbuff.h> 32#include <linux/skbuff.h>
33#include <linux/netdevice.h> 33#include <linux/netdevice.h>
34#include <linux/wireless.h>
35#include <net/mac80211.h> 34#include <net/mac80211.h>
36#include <linux/etherdevice.h> 35#include <linux/etherdevice.h>
37#include <asm/unaligned.h> 36#include <asm/unaligned.h>
@@ -84,12 +83,12 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
84} 83}
85 84
86static struct iwl_sensitivity_ranges iwl5000_sensitivity = { 85static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
87 .min_nrg_cck = 95, 86 .min_nrg_cck = 100,
88 .max_nrg_cck = 0, /* not used, set to 0 */ 87 .max_nrg_cck = 0, /* not used, set to 0 */
89 .auto_corr_min_ofdm = 90, 88 .auto_corr_min_ofdm = 90,
90 .auto_corr_min_ofdm_mrc = 170, 89 .auto_corr_min_ofdm_mrc = 170,
91 .auto_corr_min_ofdm_x1 = 120, 90 .auto_corr_min_ofdm_x1 = 105,
92 .auto_corr_min_ofdm_mrc_x1 = 240, 91 .auto_corr_min_ofdm_mrc_x1 = 220,
93 92
94 .auto_corr_max_ofdm = 120, 93 .auto_corr_max_ofdm = 120,
95 .auto_corr_max_ofdm_mrc = 210, 94 .auto_corr_max_ofdm_mrc = 210,
@@ -98,10 +97,10 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
98 97
99 .auto_corr_min_cck = 125, 98 .auto_corr_min_cck = 125,
100 .auto_corr_max_cck = 200, 99 .auto_corr_max_cck = 200,
101 .auto_corr_min_cck_mrc = 170, 100 .auto_corr_min_cck_mrc = 200,
102 .auto_corr_max_cck_mrc = 400, 101 .auto_corr_max_cck_mrc = 400,
103 .nrg_th_cck = 95, 102 .nrg_th_cck = 100,
104 .nrg_th_ofdm = 95, 103 .nrg_th_ofdm = 100,
105 104
106 .barker_corr_th_min = 190, 105 .barker_corr_th_min = 190,
107 .barker_corr_th_min_mrc = 390, 106 .barker_corr_th_min_mrc = 390,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 973d1972e8c..339de88d9ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -30,7 +30,6 @@
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/skbuff.h> 31#include <linux/skbuff.h>
32#include <linux/netdevice.h> 32#include <linux/netdevice.h>
33#include <linux/wireless.h>
34#include <net/mac80211.h> 33#include <net/mac80211.h>
35#include <linux/etherdevice.h> 34#include <linux/etherdevice.h>
36#include <asm/unaligned.h> 35#include <asm/unaligned.h>
@@ -50,7 +49,10 @@
50/* Highest firmware API version supported */ 49/* Highest firmware API version supported */
51#define IWL6000_UCODE_API_MAX 4 50#define IWL6000_UCODE_API_MAX 4
52#define IWL6050_UCODE_API_MAX 5 51#define IWL6050_UCODE_API_MAX 5
53#define IWL6000G2_UCODE_API_MAX 5 52#define IWL6000G2_UCODE_API_MAX 6
53
54/* Oldest version we won't warn about */
55#define IWL6000G2_UCODE_API_OK 5
54 56
55/* Lowest firmware API version supported */ 57/* Lowest firmware API version supported */
56#define IWL6000_UCODE_API_MIN 4 58#define IWL6000_UCODE_API_MIN 4
@@ -111,7 +113,7 @@ static void iwl6000_nic_config(struct iwl_priv *priv)
111} 113}
112 114
113static struct iwl_sensitivity_ranges iwl6000_sensitivity = { 115static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
114 .min_nrg_cck = 97, 116 .min_nrg_cck = 110,
115 .max_nrg_cck = 0, /* not used, set to 0 */ 117 .max_nrg_cck = 0, /* not used, set to 0 */
116 .auto_corr_min_ofdm = 80, 118 .auto_corr_min_ofdm = 80,
117 .auto_corr_min_ofdm_mrc = 128, 119 .auto_corr_min_ofdm_mrc = 128,
@@ -127,11 +129,11 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
127 .auto_corr_max_cck = 175, 129 .auto_corr_max_cck = 175,
128 .auto_corr_min_cck_mrc = 160, 130 .auto_corr_min_cck_mrc = 160,
129 .auto_corr_max_cck_mrc = 310, 131 .auto_corr_max_cck_mrc = 310,
130 .nrg_th_cck = 97, 132 .nrg_th_cck = 110,
131 .nrg_th_ofdm = 100, 133 .nrg_th_ofdm = 110,
132 134
133 .barker_corr_th_min = 190, 135 .barker_corr_th_min = 190,
134 .barker_corr_th_min_mrc = 390, 136 .barker_corr_th_min_mrc = 336,
135 .nrg_th_cca = 62, 137 .nrg_th_cca = 62,
136}; 138};
137 139
@@ -365,8 +367,9 @@ static struct iwl_bt_params iwl6000_bt_params = {
365}; 367};
366 368
367#define IWL_DEVICE_6005 \ 369#define IWL_DEVICE_6005 \
368 .fw_name_pre = IWL6005_FW_PRE, \ 370 .fw_name_pre = IWL6005_FW_PRE, \
369 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ 371 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
372 .ucode_api_ok = IWL6000G2_UCODE_API_OK, \
370 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ 373 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
371 .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ 374 .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \
372 .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ 375 .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
@@ -393,8 +396,9 @@ struct iwl_cfg iwl6005_2bg_cfg = {
393}; 396};
394 397
395#define IWL_DEVICE_6030 \ 398#define IWL_DEVICE_6030 \
396 .fw_name_pre = IWL6030_FW_PRE, \ 399 .fw_name_pre = IWL6030_FW_PRE, \
397 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ 400 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
401 .ucode_api_ok = IWL6000G2_UCODE_API_OK, \
398 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ 402 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
399 .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ 403 .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \
400 .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ 404 .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 72d6297602b..1789e3af810 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -505,28 +505,53 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
505 505
506 iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]); 506 iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]);
507 507
508 cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] = 508 if (priv->cfg->base_params->hd_v2) {
509 HD_INA_NON_SQUARE_DET_OFDM_DATA; 509 cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
510 cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] = 510 HD_INA_NON_SQUARE_DET_OFDM_DATA_V2;
511 HD_INA_NON_SQUARE_DET_CCK_DATA; 511 cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
512 cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] = 512 HD_INA_NON_SQUARE_DET_CCK_DATA_V2;
513 HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA; 513 cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] =
514 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] = 514 HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V2;
515 HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA; 515 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
516 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] = 516 HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V2;
517 HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA; 517 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
518 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] = 518 HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2;
519 HD_OFDM_NON_SQUARE_DET_SLOPE_DATA; 519 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] =
520 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] = 520 HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V2;
521 HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA; 521 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] =
522 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] = 522 HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V2;
523 HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA; 523 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
524 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] = 524 HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V2;
525 HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA; 525 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
526 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] = 526 HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2;
527 HD_CCK_NON_SQUARE_DET_SLOPE_DATA; 527 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] =
528 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] = 528 HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V2;
529 HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA; 529 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] =
530 HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V2;
531 } else {
532 cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
533 HD_INA_NON_SQUARE_DET_OFDM_DATA_V1;
534 cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
535 HD_INA_NON_SQUARE_DET_CCK_DATA_V1;
536 cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] =
537 HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V1;
538 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
539 HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V1;
540 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
541 HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1;
542 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] =
543 HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V1;
544 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] =
545 HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V1;
546 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
547 HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V1;
548 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
549 HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1;
550 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] =
551 HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V1;
552 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] =
553 HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V1;
554 }
530 555
531 /* Update uCode's "work" table, and copy it to DSP */ 556 /* Update uCode's "work" table, and copy it to DSP */
532 cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE; 557 cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
index 0e5b842529c..47c43042ba4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -92,8 +92,8 @@
92 92
93#define IWLAGN_CMD_FIFO_NUM 7 93#define IWLAGN_CMD_FIFO_NUM 7
94#define IWLAGN_NUM_QUEUES 20 94#define IWLAGN_NUM_QUEUES 20
95#define IWLAGN_NUM_AMPDU_QUEUES 10 95#define IWLAGN_NUM_AMPDU_QUEUES 9
96#define IWLAGN_FIRST_AMPDU_QUEUE 10 96#define IWLAGN_FIRST_AMPDU_QUEUE 11
97 97
98/* Fixed (non-configurable) rx data from phy */ 98/* Fixed (non-configurable) rx data from phy */
99 99
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 3bee0f119bc..4edb6cfc548 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -753,18 +753,6 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
753 return added; 753 return added;
754} 754}
755 755
756static int iwl_fill_offch_tx(struct iwl_priv *priv, void *data, size_t maxlen)
757{
758 struct sk_buff *skb = priv->offchan_tx_skb;
759
760 if (skb->len < maxlen)
761 maxlen = skb->len;
762
763 memcpy(data, skb->data, maxlen);
764
765 return maxlen;
766}
767
768int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) 756int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
769{ 757{
770 struct iwl_host_cmd cmd = { 758 struct iwl_host_cmd cmd = {
@@ -807,7 +795,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
807 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; 795 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
808 scan->quiet_time = IWL_ACTIVE_QUIET_TIME; 796 scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
809 797
810 if (priv->scan_type != IWL_SCAN_OFFCH_TX && 798 if (priv->scan_type != IWL_SCAN_ROC &&
811 iwl_is_any_associated(priv)) { 799 iwl_is_any_associated(priv)) {
812 u16 interval = 0; 800 u16 interval = 0;
813 u32 extra; 801 u32 extra;
@@ -816,7 +804,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
816 804
817 IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); 805 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
818 switch (priv->scan_type) { 806 switch (priv->scan_type) {
819 case IWL_SCAN_OFFCH_TX: 807 case IWL_SCAN_ROC:
820 WARN_ON(1); 808 WARN_ON(1);
821 break; 809 break;
822 case IWL_SCAN_RADIO_RESET: 810 case IWL_SCAN_RADIO_RESET:
@@ -838,10 +826,11 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
838 scan->suspend_time = cpu_to_le32(scan_suspend_time); 826 scan->suspend_time = cpu_to_le32(scan_suspend_time);
839 IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n", 827 IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
840 scan_suspend_time, interval); 828 scan_suspend_time, interval);
841 } else if (priv->scan_type == IWL_SCAN_OFFCH_TX) { 829 } else if (priv->scan_type == IWL_SCAN_ROC) {
842 scan->suspend_time = 0; 830 scan->suspend_time = 0;
843 scan->max_out_time = 831 scan->max_out_time = 0;
844 cpu_to_le32(1024 * priv->offchan_tx_timeout); 832 scan->quiet_time = 0;
833 scan->quiet_plcp_th = 0;
845 } 834 }
846 835
847 switch (priv->scan_type) { 836 switch (priv->scan_type) {
@@ -869,8 +858,8 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
869 } else 858 } else
870 IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); 859 IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
871 break; 860 break;
872 case IWL_SCAN_OFFCH_TX: 861 case IWL_SCAN_ROC:
873 IWL_DEBUG_SCAN(priv, "Start offchannel TX scan.\n"); 862 IWL_DEBUG_SCAN(priv, "Start ROC scan.\n");
874 break; 863 break;
875 } 864 }
876 865
@@ -988,19 +977,13 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
988 IWL_MAX_SCAN_SIZE - sizeof(*scan)); 977 IWL_MAX_SCAN_SIZE - sizeof(*scan));
989 break; 978 break;
990 case IWL_SCAN_RADIO_RESET: 979 case IWL_SCAN_RADIO_RESET:
980 case IWL_SCAN_ROC:
991 /* use bcast addr, will not be transmitted but must be valid */ 981 /* use bcast addr, will not be transmitted but must be valid */
992 cmd_len = iwl_fill_probe_req(priv, 982 cmd_len = iwl_fill_probe_req(priv,
993 (struct ieee80211_mgmt *)scan->data, 983 (struct ieee80211_mgmt *)scan->data,
994 iwl_bcast_addr, NULL, 0, 984 iwl_bcast_addr, NULL, 0,
995 IWL_MAX_SCAN_SIZE - sizeof(*scan)); 985 IWL_MAX_SCAN_SIZE - sizeof(*scan));
996 break; 986 break;
997 case IWL_SCAN_OFFCH_TX:
998 cmd_len = iwl_fill_offch_tx(priv, scan->data,
999 IWL_MAX_SCAN_SIZE
1000 - sizeof(*scan)
1001 - sizeof(struct iwl_scan_channel));
1002 scan->scan_flags |= IWL_SCAN_FLAGS_ACTION_FRAME_TX;
1003 break;
1004 default: 987 default:
1005 BUG(); 988 BUG();
1006 } 989 }
@@ -1021,18 +1004,18 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1021 is_active, n_probes, 1004 is_active, n_probes,
1022 (void *)&scan->data[cmd_len]); 1005 (void *)&scan->data[cmd_len]);
1023 break; 1006 break;
1024 case IWL_SCAN_OFFCH_TX: { 1007 case IWL_SCAN_ROC: {
1025 struct iwl_scan_channel *scan_ch; 1008 struct iwl_scan_channel *scan_ch;
1026 1009
1027 scan->channel_count = 1; 1010 scan->channel_count = 1;
1028 1011
1029 scan_ch = (void *)&scan->data[cmd_len]; 1012 scan_ch = (void *)&scan->data[cmd_len];
1030 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; 1013 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
1031 scan_ch->channel = 1014 scan_ch->channel =
1032 cpu_to_le16(priv->offchan_tx_chan->hw_value); 1015 cpu_to_le16(priv->hw_roc_channel->hw_value);
1033 scan_ch->active_dwell = 1016 scan_ch->active_dwell =
1034 cpu_to_le16(priv->offchan_tx_timeout); 1017 scan_ch->passive_dwell =
1035 scan_ch->passive_dwell = 0; 1018 cpu_to_le16(priv->hw_roc_duration);
1036 1019
1037 /* Set txpower levels to defaults */ 1020 /* Set txpower levels to defaults */
1038 scan_ch->dsp_atten = 110; 1021 scan_ch->dsp_atten = 110;
@@ -1041,7 +1024,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1041 * power level: 1024 * power level:
1042 * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; 1025 * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
1043 */ 1026 */
1044 if (priv->offchan_tx_chan->band == IEEE80211_BAND_5GHZ) 1027 if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ)
1045 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; 1028 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
1046 else 1029 else
1047 scan_ch->tx_gain = ((1 << 5) | (5 << 3)); 1030 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 3789ff4bf53..1fa438e20f0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -27,7 +27,6 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/skbuff.h> 28#include <linux/skbuff.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/wireless.h>
31#include <net/mac80211.h> 30#include <net/mac80211.h>
32 31
33#include <linux/netdevice.h> 32#include <linux/netdevice.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index d42ef1763a7..d562e9359d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -337,10 +337,10 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
337 cmd.slots[0].type = 0; /* BSS */ 337 cmd.slots[0].type = 0; /* BSS */
338 cmd.slots[1].type = 1; /* PAN */ 338 cmd.slots[1].type = 1; /* PAN */
339 339
340 if (priv->hw_roc_channel) { 340 if (priv->hw_roc_setup) {
341 /* both contexts must be used for this to happen */ 341 /* both contexts must be used for this to happen */
342 slot1 = priv->hw_roc_duration; 342 slot1 = IWL_MIN_SLOT_TIME;
343 slot0 = IWL_MIN_SLOT_TIME; 343 slot0 = 3000;
344 } else if (ctx_bss->vif && ctx_pan->vif) { 344 } else if (ctx_bss->vif && ctx_pan->vif) {
345 int bcnint = ctx_pan->beacon_int; 345 int bcnint = ctx_pan->beacon_int;
346 int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1; 346 int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
@@ -437,23 +437,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
437 /* always get timestamp with Rx frame */ 437 /* always get timestamp with Rx frame */
438 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; 438 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
439 439
440 if (ctx->ctxid == IWL_RXON_CTX_PAN && priv->hw_roc_channel) {
441 struct ieee80211_channel *chan = priv->hw_roc_channel;
442
443 iwl_set_rxon_channel(priv, chan, ctx);
444 iwl_set_flags_for_band(priv, ctx, chan->band, NULL);
445 ctx->staging.filter_flags |=
446 RXON_FILTER_ASSOC_MSK |
447 RXON_FILTER_PROMISC_MSK |
448 RXON_FILTER_CTL2HOST_MSK;
449 ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
450 new_assoc = true;
451
452 if (memcmp(&ctx->staging, &ctx->active,
453 sizeof(ctx->staging)) == 0)
454 return 0;
455 }
456
457 /* 440 /*
458 * force CTS-to-self frames protection if RTS-CTS is not preferred 441 * force CTS-to-self frames protection if RTS-CTS is not preferred
459 * one aggregation protection method 442 * one aggregation protection method
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 53bb59ee719..9bc26da6276 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -128,11 +128,10 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
128 * handle build REPLY_TX command notification. 128 * handle build REPLY_TX command notification.
129 */ 129 */
130static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, 130static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
131 struct sk_buff *skb, 131 struct sk_buff *skb,
132 struct iwl_tx_cmd *tx_cmd, 132 struct iwl_tx_cmd *tx_cmd,
133 struct ieee80211_tx_info *info, 133 struct ieee80211_tx_info *info,
134 struct ieee80211_hdr *hdr, 134 struct ieee80211_hdr *hdr, u8 sta_id)
135 u8 std_id)
136{ 135{
137 __le16 fc = hdr->frame_control; 136 __le16 fc = hdr->frame_control;
138 __le32 tx_flags = tx_cmd->tx_flags; 137 __le32 tx_flags = tx_cmd->tx_flags;
@@ -157,7 +156,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
157 tx_flags |= TX_CMD_FLG_IGNORE_BT; 156 tx_flags |= TX_CMD_FLG_IGNORE_BT;
158 157
159 158
160 tx_cmd->sta_id = std_id; 159 tx_cmd->sta_id = sta_id;
161 if (ieee80211_has_morefrags(fc)) 160 if (ieee80211_has_morefrags(fc))
162 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; 161 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
163 162
@@ -189,9 +188,9 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
189#define RTS_DFAULT_RETRY_LIMIT 60 188#define RTS_DFAULT_RETRY_LIMIT 60
190 189
191static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, 190static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
192 struct iwl_tx_cmd *tx_cmd, 191 struct iwl_tx_cmd *tx_cmd,
193 struct ieee80211_tx_info *info, 192 struct ieee80211_tx_info *info,
194 __le16 fc) 193 __le16 fc)
195{ 194{
196 u32 rate_flags; 195 u32 rate_flags;
197 int rate_idx; 196 int rate_idx;
@@ -334,14 +333,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
334 unsigned long flags; 333 unsigned long flags;
335 bool is_agg = false; 334 bool is_agg = false;
336 335
337 /* 336 if (info->control.vif)
338 * If the frame needs to go out off-channel, then
339 * we'll have put the PAN context to that channel,
340 * so make the frame go out there.
341 */
342 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
343 ctx = &priv->contexts[IWL_RXON_CTX_PAN];
344 else if (info->control.vif)
345 ctx = iwl_rxon_ctx_from_vif(info->control.vif); 337 ctx = iwl_rxon_ctx_from_vif(info->control.vif);
346 338
347 spin_lock_irqsave(&priv->lock, flags); 339 spin_lock_irqsave(&priv->lock, flags);
@@ -407,7 +399,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
407 */ 399 */
408 hdr->frame_control |= 400 hdr->frame_control |=
409 cpu_to_le16(IEEE80211_FCTL_MOREDATA); 401 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
410 } else 402 } else if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
403 txq_id = IWL_AUX_QUEUE;
404 else
411 txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; 405 txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
412 406
413 /* irqs already disabled/saved above when locking priv->lock */ 407 /* irqs already disabled/saved above when locking priv->lock */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index b0ae4de7f08..33894dde1ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -35,7 +35,6 @@
35#include <linux/sched.h> 35#include <linux/sched.h>
36#include <linux/skbuff.h> 36#include <linux/skbuff.h>
37#include <linux/netdevice.h> 37#include <linux/netdevice.h>
38#include <linux/wireless.h>
39#include <linux/firmware.h> 38#include <linux/firmware.h>
40#include <linux/etherdevice.h> 39#include <linux/etherdevice.h>
41#include <linux/if_arp.h> 40#include <linux/if_arp.h>
@@ -614,6 +613,87 @@ static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc,
614 return 0; 613 return 0;
615} 614}
616 615
616static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
617{
618 static const u8 iwlagn_bss_ac_to_fifo[] = {
619 IWL_TX_FIFO_VO,
620 IWL_TX_FIFO_VI,
621 IWL_TX_FIFO_BE,
622 IWL_TX_FIFO_BK,
623 };
624 static const u8 iwlagn_bss_ac_to_queue[] = {
625 0, 1, 2, 3,
626 };
627 static const u8 iwlagn_pan_ac_to_fifo[] = {
628 IWL_TX_FIFO_VO_IPAN,
629 IWL_TX_FIFO_VI_IPAN,
630 IWL_TX_FIFO_BE_IPAN,
631 IWL_TX_FIFO_BK_IPAN,
632 };
633 static const u8 iwlagn_pan_ac_to_queue[] = {
634 7, 6, 5, 4,
635 };
636 int i;
637
638 /*
639 * The default context is always valid,
640 * the PAN context depends on uCode.
641 */
642 priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
643 if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)
644 priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
645
646 for (i = 0; i < NUM_IWL_RXON_CTX; i++)
647 priv->contexts[i].ctxid = i;
648
649 priv->contexts[IWL_RXON_CTX_BSS].always_active = true;
650 priv->contexts[IWL_RXON_CTX_BSS].is_active = true;
651 priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
652 priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
653 priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
654 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
655 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
656 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
657 priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
658 priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;
659 priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
660 BIT(NL80211_IFTYPE_ADHOC);
661 priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
662 BIT(NL80211_IFTYPE_STATION);
663 priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
664 priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
665 priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
666 priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
667
668 priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON;
669 priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd =
670 REPLY_WIPAN_RXON_TIMING;
671 priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd =
672 REPLY_WIPAN_RXON_ASSOC;
673 priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM;
674 priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN;
675 priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
676 priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
677 priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
678 priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
679 priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
680 priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
681 priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
682 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
683
684 if (ucode_flags & IWL_UCODE_TLV_FLAGS_P2P)
685 priv->contexts[IWL_RXON_CTX_PAN].interface_modes |=
686 BIT(NL80211_IFTYPE_P2P_CLIENT) |
687 BIT(NL80211_IFTYPE_P2P_GO);
688
689 priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP;
690 priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA;
691 priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;
692
693 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
694}
695
696
617struct iwlagn_ucode_capabilities { 697struct iwlagn_ucode_capabilities {
618 u32 max_probe_length; 698 u32 max_probe_length;
619 u32 standard_phy_calibration_size; 699 u32 standard_phy_calibration_size;
@@ -952,6 +1032,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
952 int err; 1032 int err;
953 struct iwlagn_firmware_pieces pieces; 1033 struct iwlagn_firmware_pieces pieces;
954 const unsigned int api_max = priv->cfg->ucode_api_max; 1034 const unsigned int api_max = priv->cfg->ucode_api_max;
1035 unsigned int api_ok = priv->cfg->ucode_api_ok;
955 const unsigned int api_min = priv->cfg->ucode_api_min; 1036 const unsigned int api_min = priv->cfg->ucode_api_min;
956 u32 api_ver; 1037 u32 api_ver;
957 char buildstr[25]; 1038 char buildstr[25];
@@ -962,10 +1043,13 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
962 IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, 1043 IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE,
963 }; 1044 };
964 1045
1046 if (!api_ok)
1047 api_ok = api_max;
1048
965 memset(&pieces, 0, sizeof(pieces)); 1049 memset(&pieces, 0, sizeof(pieces));
966 1050
967 if (!ucode_raw) { 1051 if (!ucode_raw) {
968 if (priv->fw_index <= priv->cfg->ucode_api_max) 1052 if (priv->fw_index <= api_ok)
969 IWL_ERR(priv, 1053 IWL_ERR(priv,
970 "request for firmware file '%s' failed.\n", 1054 "request for firmware file '%s' failed.\n",
971 priv->firmware_name); 1055 priv->firmware_name);
@@ -1011,12 +1095,18 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1011 goto try_again; 1095 goto try_again;
1012 } 1096 }
1013 1097
1014 if (api_ver != api_max) 1098 if (api_ver < api_ok) {
1015 IWL_ERR(priv, 1099 if (api_ok != api_max)
1016 "Firmware has old API version. Expected v%u, " 1100 IWL_ERR(priv, "Firmware has old API version, "
1017 "got v%u. New firmware can be obtained " 1101 "expected v%u through v%u, got v%u.\n",
1018 "from http://www.intellinuxwireless.org.\n", 1102 api_ok, api_max, api_ver);
1019 api_max, api_ver); 1103 else
1104 IWL_ERR(priv, "Firmware has old API version, "
1105 "expected v%u, got v%u.\n",
1106 api_max, api_ver);
1107 IWL_ERR(priv, "New firmware can be obtained from "
1108 "http://www.intellinuxwireless.org/.\n");
1109 }
1020 } 1110 }
1021 1111
1022 if (build) 1112 if (build)
@@ -1143,17 +1233,23 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1143 priv->new_scan_threshold_behaviour = 1233 priv->new_scan_threshold_behaviour =
1144 !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); 1234 !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
1145 1235
1146 if ((priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE) && 1236 if (!(priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE))
1147 (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) { 1237 ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
1148 priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
1149 priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
1150 } else
1151 priv->sta_key_max_num = STA_KEY_MAX_NUM;
1152 1238
1153 if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) 1239 /*
1240 * if not PAN, then don't support P2P -- might be a uCode
1241 * packaging bug or due to the eeprom check above
1242 */
1243 if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN))
1244 ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
1245
1246 if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
1247 priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
1154 priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; 1248 priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
1155 else 1249 } else {
1250 priv->sta_key_max_num = STA_KEY_MAX_NUM;
1156 priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; 1251 priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
1252 }
1157 1253
1158 /* 1254 /*
1159 * figure out the offset of chain noise reset and gain commands 1255 * figure out the offset of chain noise reset and gain commands
@@ -1169,6 +1265,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1169 priv->phy_calib_chain_noise_gain_cmd = 1265 priv->phy_calib_chain_noise_gain_cmd =
1170 ucode_capa.standard_phy_calibration_size + 1; 1266 ucode_capa.standard_phy_calibration_size + 1;
1171 1267
1268 /* initialize all valid contexts */
1269 iwl_init_context(priv, ucode_capa.flags);
1270
1172 /************************************************** 1271 /**************************************************
1173 * This is still part of probe() in a sense... 1272 * This is still part of probe() in a sense...
1174 * 1273 *
@@ -1765,6 +1864,13 @@ static void __iwl_down(struct iwl_priv *priv)
1765 1864
1766 iwl_scan_cancel_timeout(priv, 200); 1865 iwl_scan_cancel_timeout(priv, 200);
1767 1866
1867 /*
1868 * If active, scanning won't cancel it, so say it expired.
1869 * No race since we hold the mutex here and a new one
1870 * can't come in at this time.
1871 */
1872 ieee80211_remain_on_channel_expired(priv->hw);
1873
1768 exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); 1874 exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
1769 1875
1770 /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set 1876 /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
@@ -1955,94 +2061,6 @@ static void iwl_bg_restart(struct work_struct *data)
1955 } 2061 }
1956} 2062}
1957 2063
1958static int iwl_mac_offchannel_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
1959 struct ieee80211_channel *chan,
1960 enum nl80211_channel_type channel_type,
1961 unsigned int wait)
1962{
1963 struct iwl_priv *priv = hw->priv;
1964 int ret;
1965
1966 /* Not supported if we don't have PAN */
1967 if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) {
1968 ret = -EOPNOTSUPP;
1969 goto free;
1970 }
1971
1972 /* Not supported on pre-P2P firmware */
1973 if (!(priv->contexts[IWL_RXON_CTX_PAN].interface_modes &
1974 BIT(NL80211_IFTYPE_P2P_CLIENT))) {
1975 ret = -EOPNOTSUPP;
1976 goto free;
1977 }
1978
1979 mutex_lock(&priv->mutex);
1980
1981 if (!priv->contexts[IWL_RXON_CTX_PAN].is_active) {
1982 /*
1983 * If the PAN context is free, use the normal
1984 * way of doing remain-on-channel offload + TX.
1985 */
1986 ret = 1;
1987 goto out;
1988 }
1989
1990 /* TODO: queue up if scanning? */
1991 if (test_bit(STATUS_SCANNING, &priv->status) ||
1992 priv->offchan_tx_skb) {
1993 ret = -EBUSY;
1994 goto out;
1995 }
1996
1997 /*
1998 * max_scan_ie_len doesn't include the blank SSID or the header,
1999 * so need to add that again here.
2000 */
2001 if (skb->len > hw->wiphy->max_scan_ie_len + 24 + 2) {
2002 ret = -ENOBUFS;
2003 goto out;
2004 }
2005
2006 priv->offchan_tx_skb = skb;
2007 priv->offchan_tx_timeout = wait;
2008 priv->offchan_tx_chan = chan;
2009
2010 ret = iwl_scan_initiate(priv, priv->contexts[IWL_RXON_CTX_PAN].vif,
2011 IWL_SCAN_OFFCH_TX, chan->band);
2012 if (ret)
2013 priv->offchan_tx_skb = NULL;
2014 out:
2015 mutex_unlock(&priv->mutex);
2016 free:
2017 if (ret < 0)
2018 kfree_skb(skb);
2019
2020 return ret;
2021}
2022
2023static int iwl_mac_offchannel_tx_cancel_wait(struct ieee80211_hw *hw)
2024{
2025 struct iwl_priv *priv = hw->priv;
2026 int ret;
2027
2028 mutex_lock(&priv->mutex);
2029
2030 if (!priv->offchan_tx_skb) {
2031 ret = -EINVAL;
2032 goto unlock;
2033 }
2034
2035 priv->offchan_tx_skb = NULL;
2036
2037 ret = iwl_scan_cancel_timeout(priv, 200);
2038 if (ret)
2039 ret = -EIO;
2040unlock:
2041 mutex_unlock(&priv->mutex);
2042
2043 return ret;
2044}
2045
2046/***************************************************************************** 2064/*****************************************************************************
2047 * 2065 *
2048 * mac80211 entry point functions 2066 * mac80211 entry point functions
@@ -3198,35 +3216,34 @@ done:
3198 IWL_DEBUG_MAC80211(priv, "leave\n"); 3216 IWL_DEBUG_MAC80211(priv, "leave\n");
3199} 3217}
3200 3218
3201static void iwlagn_disable_roc(struct iwl_priv *priv) 3219void iwlagn_disable_roc(struct iwl_priv *priv)
3202{ 3220{
3203 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; 3221 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
3204 struct ieee80211_channel *chan = ACCESS_ONCE(priv->hw->conf.channel);
3205 3222
3206 lockdep_assert_held(&priv->mutex); 3223 lockdep_assert_held(&priv->mutex);
3207 3224
3208 if (!ctx->is_active) 3225 if (!priv->hw_roc_setup)
3209 return; 3226 return;
3210 3227
3211 ctx->staging.dev_type = RXON_DEV_TYPE_2STA; 3228 ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
3212 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3229 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3213 iwl_set_rxon_channel(priv, chan, ctx);
3214 iwl_set_flags_for_band(priv, ctx, chan->band, NULL);
3215 3230
3216 priv->hw_roc_channel = NULL; 3231 priv->hw_roc_channel = NULL;
3217 3232
3233 memset(ctx->staging.node_addr, 0, ETH_ALEN);
3234
3218 iwlagn_commit_rxon(priv, ctx); 3235 iwlagn_commit_rxon(priv, ctx);
3219 3236
3220 ctx->is_active = false; 3237 ctx->is_active = false;
3238 priv->hw_roc_setup = false;
3221} 3239}
3222 3240
3223static void iwlagn_bg_roc_done(struct work_struct *work) 3241static void iwlagn_disable_roc_work(struct work_struct *work)
3224{ 3242{
3225 struct iwl_priv *priv = container_of(work, struct iwl_priv, 3243 struct iwl_priv *priv = container_of(work, struct iwl_priv,
3226 hw_roc_work.work); 3244 hw_roc_disable_work.work);
3227 3245
3228 mutex_lock(&priv->mutex); 3246 mutex_lock(&priv->mutex);
3229 ieee80211_remain_on_channel_expired(priv->hw);
3230 iwlagn_disable_roc(priv); 3247 iwlagn_disable_roc(priv);
3231 mutex_unlock(&priv->mutex); 3248 mutex_unlock(&priv->mutex);
3232} 3249}
@@ -3237,33 +3254,63 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
3237 int duration) 3254 int duration)
3238{ 3255{
3239 struct iwl_priv *priv = hw->priv; 3256 struct iwl_priv *priv = hw->priv;
3257 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
3240 int err = 0; 3258 int err = 0;
3241 3259
3242 if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) 3260 if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
3243 return -EOPNOTSUPP; 3261 return -EOPNOTSUPP;
3244 3262
3245 if (!(priv->contexts[IWL_RXON_CTX_PAN].interface_modes & 3263 if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)))
3246 BIT(NL80211_IFTYPE_P2P_CLIENT)))
3247 return -EOPNOTSUPP; 3264 return -EOPNOTSUPP;
3248 3265
3249 mutex_lock(&priv->mutex); 3266 mutex_lock(&priv->mutex);
3250 3267
3251 if (priv->contexts[IWL_RXON_CTX_PAN].is_active || 3268 /*
3252 test_bit(STATUS_SCAN_HW, &priv->status)) { 3269 * TODO: Remove this hack! Firmware needs to be updated
3270 * to allow longer off-channel periods in scanning for
3271 * this use case, based on a flag (and we'll need an API
3272 * flag in the firmware when it has that).
3273 */
3274 if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && duration > 80)
3275 duration = 80;
3276
3277 if (test_bit(STATUS_SCAN_HW, &priv->status)) {
3253 err = -EBUSY; 3278 err = -EBUSY;
3254 goto out; 3279 goto out;
3255 } 3280 }
3256 3281
3257 priv->contexts[IWL_RXON_CTX_PAN].is_active = true;
3258 priv->hw_roc_channel = channel; 3282 priv->hw_roc_channel = channel;
3259 priv->hw_roc_chantype = channel_type; 3283 priv->hw_roc_chantype = channel_type;
3260 priv->hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024); 3284 priv->hw_roc_duration = duration;
3261 iwlagn_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]); 3285 cancel_delayed_work(&priv->hw_roc_disable_work);
3262 queue_delayed_work(priv->workqueue, &priv->hw_roc_work, 3286
3263 msecs_to_jiffies(duration + 20)); 3287 if (!ctx->is_active) {
3288 ctx->is_active = true;
3289 ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
3290 memcpy(ctx->staging.node_addr,
3291 priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr,
3292 ETH_ALEN);
3293 memcpy(ctx->staging.bssid_addr,
3294 priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr,
3295 ETH_ALEN);
3296 err = iwlagn_commit_rxon(priv, ctx);
3297 if (err)
3298 goto out;
3299 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK |
3300 RXON_FILTER_PROMISC_MSK |
3301 RXON_FILTER_CTL2HOST_MSK;
3302
3303 err = iwlagn_commit_rxon(priv, ctx);
3304 if (err) {
3305 iwlagn_disable_roc(priv);
3306 goto out;
3307 }
3308 priv->hw_roc_setup = true;
3309 }
3264 3310
3265 msleep(IWL_MIN_SLOT_TIME); /* TU is almost ms */ 3311 err = iwl_scan_initiate(priv, ctx->vif, IWL_SCAN_ROC, channel->band);
3266 ieee80211_ready_on_channel(priv->hw); 3312 if (err)
3313 iwlagn_disable_roc(priv);
3267 3314
3268 out: 3315 out:
3269 mutex_unlock(&priv->mutex); 3316 mutex_unlock(&priv->mutex);
@@ -3278,9 +3325,8 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
3278 if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) 3325 if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
3279 return -EOPNOTSUPP; 3326 return -EOPNOTSUPP;
3280 3327
3281 cancel_delayed_work_sync(&priv->hw_roc_work);
3282
3283 mutex_lock(&priv->mutex); 3328 mutex_lock(&priv->mutex);
3329 iwl_scan_cancel_timeout(priv, priv->hw_roc_duration);
3284 iwlagn_disable_roc(priv); 3330 iwlagn_disable_roc(priv);
3285 mutex_unlock(&priv->mutex); 3331 mutex_unlock(&priv->mutex);
3286 3332
@@ -3305,7 +3351,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3305 INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); 3351 INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
3306 INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency); 3352 INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency);
3307 INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); 3353 INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config);
3308 INIT_DELAYED_WORK(&priv->hw_roc_work, iwlagn_bg_roc_done); 3354 INIT_DELAYED_WORK(&priv->hw_roc_disable_work,
3355 iwlagn_disable_roc_work);
3309 3356
3310 iwl_setup_scan_deferred_work(priv); 3357 iwl_setup_scan_deferred_work(priv);
3311 3358
@@ -3337,6 +3384,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
3337 3384
3338 cancel_work_sync(&priv->bt_full_concurrency); 3385 cancel_work_sync(&priv->bt_full_concurrency);
3339 cancel_work_sync(&priv->bt_runtime_config); 3386 cancel_work_sync(&priv->bt_runtime_config);
3387 cancel_delayed_work_sync(&priv->hw_roc_disable_work);
3340 3388
3341 del_timer_sync(&priv->statistics_periodic); 3389 del_timer_sync(&priv->statistics_periodic);
3342 del_timer_sync(&priv->ucode_trace); 3390 del_timer_sync(&priv->ucode_trace);
@@ -3489,8 +3537,6 @@ struct ieee80211_ops iwlagn_hw_ops = {
3489 .tx_last_beacon = iwl_mac_tx_last_beacon, 3537 .tx_last_beacon = iwl_mac_tx_last_beacon,
3490 .remain_on_channel = iwl_mac_remain_on_channel, 3538 .remain_on_channel = iwl_mac_remain_on_channel,
3491 .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, 3539 .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel,
3492 .offchannel_tx = iwl_mac_offchannel_tx,
3493 .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait,
3494 .rssi_callback = iwl_mac_rssi_callback, 3540 .rssi_callback = iwl_mac_rssi_callback,
3495 CFG80211_TESTMODE_CMD(iwl_testmode_cmd) 3541 CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
3496 CFG80211_TESTMODE_DUMP(iwl_testmode_dump) 3542 CFG80211_TESTMODE_DUMP(iwl_testmode_dump)
@@ -3519,28 +3565,6 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
3519 return priv->cfg->lib->set_hw_params(priv); 3565 return priv->cfg->lib->set_hw_params(priv);
3520} 3566}
3521 3567
3522static const u8 iwlagn_bss_ac_to_fifo[] = {
3523 IWL_TX_FIFO_VO,
3524 IWL_TX_FIFO_VI,
3525 IWL_TX_FIFO_BE,
3526 IWL_TX_FIFO_BK,
3527};
3528
3529static const u8 iwlagn_bss_ac_to_queue[] = {
3530 0, 1, 2, 3,
3531};
3532
3533static const u8 iwlagn_pan_ac_to_fifo[] = {
3534 IWL_TX_FIFO_VO_IPAN,
3535 IWL_TX_FIFO_VI_IPAN,
3536 IWL_TX_FIFO_BE_IPAN,
3537 IWL_TX_FIFO_BK_IPAN,
3538};
3539
3540static const u8 iwlagn_pan_ac_to_queue[] = {
3541 7, 6, 5, 4,
3542};
3543
3544/* This function both allocates and initializes hw and priv. */ 3568/* This function both allocates and initializes hw and priv. */
3545static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) 3569static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
3546{ 3570{
@@ -3563,65 +3587,6 @@ out:
3563 return hw; 3587 return hw;
3564} 3588}
3565 3589
3566static void iwl_init_context(struct iwl_priv *priv)
3567{
3568 int i;
3569
3570 /*
3571 * The default context is always valid,
3572 * more may be discovered when firmware
3573 * is loaded.
3574 */
3575 priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
3576
3577 for (i = 0; i < NUM_IWL_RXON_CTX; i++)
3578 priv->contexts[i].ctxid = i;
3579
3580 priv->contexts[IWL_RXON_CTX_BSS].always_active = true;
3581 priv->contexts[IWL_RXON_CTX_BSS].is_active = true;
3582 priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
3583 priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
3584 priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
3585 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
3586 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
3587 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
3588 priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
3589 priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;
3590 priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
3591 BIT(NL80211_IFTYPE_ADHOC);
3592 priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
3593 BIT(NL80211_IFTYPE_STATION);
3594 priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
3595 priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
3596 priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
3597 priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
3598
3599 priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON;
3600 priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd =
3601 REPLY_WIPAN_RXON_TIMING;
3602 priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd =
3603 REPLY_WIPAN_RXON_ASSOC;
3604 priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM;
3605 priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN;
3606 priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
3607 priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
3608 priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
3609 priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
3610 priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
3611 priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
3612 priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
3613 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
3614#ifdef CONFIG_IWL_P2P
3615 priv->contexts[IWL_RXON_CTX_PAN].interface_modes |=
3616 BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO);
3617#endif
3618 priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP;
3619 priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA;
3620 priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;
3621
3622 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
3623}
3624
3625int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg) 3590int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg)
3626{ 3591{
3627 int err = 0; 3592 int err = 0;
@@ -3724,9 +3689,6 @@ int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg)
3724 priv->hw->wiphy->n_addresses++; 3689 priv->hw->wiphy->n_addresses++;
3725 } 3690 }
3726 3691
3727 /* initialize all valid contexts */
3728 iwl_init_context(priv);
3729
3730 /************************ 3692 /************************
3731 * 5. Setup HW constants 3693 * 5. Setup HW constants
3732 ************************/ 3694 ************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index d941c4c98e4..df2960ae92a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -209,6 +209,7 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
209/* scan */ 209/* scan */
210int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); 210int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
211void iwlagn_post_scan(struct iwl_priv *priv); 211void iwlagn_post_scan(struct iwl_priv *priv);
212void iwlagn_disable_roc(struct iwl_priv *priv);
212 213
213/* station mgmt */ 214/* station mgmt */
214int iwlagn_manage_ibss_station(struct iwl_priv *priv, 215int iwlagn_manage_ibss_station(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index e9e9d1d1778..0016c61b300 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -3067,17 +3067,29 @@ struct iwl_missed_beacon_notif {
3067/* number of additional entries for enhanced tbl */ 3067/* number of additional entries for enhanced tbl */
3068#define ENHANCE_HD_TABLE_ENTRIES (ENHANCE_HD_TABLE_SIZE - HD_TABLE_SIZE) 3068#define ENHANCE_HD_TABLE_ENTRIES (ENHANCE_HD_TABLE_SIZE - HD_TABLE_SIZE)
3069 3069
3070#define HD_INA_NON_SQUARE_DET_OFDM_DATA cpu_to_le16(0) 3070#define HD_INA_NON_SQUARE_DET_OFDM_DATA_V1 cpu_to_le16(0)
3071#define HD_INA_NON_SQUARE_DET_CCK_DATA cpu_to_le16(0) 3071#define HD_INA_NON_SQUARE_DET_CCK_DATA_V1 cpu_to_le16(0)
3072#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA cpu_to_le16(0) 3072#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V1 cpu_to_le16(0)
3073#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA cpu_to_le16(668) 3073#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V1 cpu_to_le16(668)
3074#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA cpu_to_le16(4) 3074#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1 cpu_to_le16(4)
3075#define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA cpu_to_le16(486) 3075#define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V1 cpu_to_le16(486)
3076#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA cpu_to_le16(37) 3076#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V1 cpu_to_le16(37)
3077#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA cpu_to_le16(853) 3077#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V1 cpu_to_le16(853)
3078#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA cpu_to_le16(4) 3078#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1 cpu_to_le16(4)
3079#define HD_CCK_NON_SQUARE_DET_SLOPE_DATA cpu_to_le16(476) 3079#define HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V1 cpu_to_le16(476)
3080#define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA cpu_to_le16(99) 3080#define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V1 cpu_to_le16(99)
3081
3082#define HD_INA_NON_SQUARE_DET_OFDM_DATA_V2 cpu_to_le16(1)
3083#define HD_INA_NON_SQUARE_DET_CCK_DATA_V2 cpu_to_le16(1)
3084#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V2 cpu_to_le16(1)
3085#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V2 cpu_to_le16(600)
3086#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2 cpu_to_le16(40)
3087#define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V2 cpu_to_le16(486)
3088#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V2 cpu_to_le16(45)
3089#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V2 cpu_to_le16(853)
3090#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2 cpu_to_le16(60)
3091#define HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V2 cpu_to_le16(476)
3092#define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V2 cpu_to_le16(99)
3081 3093
3082 3094
3083/* Control field in struct iwl_sensitivity_cmd */ 3095/* Control field in struct iwl_sensitivity_cmd */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index cf376f62b2f..e269987cd64 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -40,6 +40,7 @@
40#include "iwl-io.h" 40#include "iwl-io.h"
41#include "iwl-power.h" 41#include "iwl-power.h"
42#include "iwl-sta.h" 42#include "iwl-sta.h"
43#include "iwl-agn.h"
43#include "iwl-helpers.h" 44#include "iwl-helpers.h"
44#include "iwl-agn.h" 45#include "iwl-agn.h"
45#include "iwl-trans.h" 46#include "iwl-trans.h"
@@ -1273,8 +1274,12 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1273 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", 1274 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
1274 viftype, vif->addr); 1275 viftype, vif->addr);
1275 1276
1277 cancel_delayed_work_sync(&priv->hw_roc_disable_work);
1278
1276 mutex_lock(&priv->mutex); 1279 mutex_lock(&priv->mutex);
1277 1280
1281 iwlagn_disable_roc(priv);
1282
1278 if (!iwl_is_ready_rf(priv)) { 1283 if (!iwl_is_ready_rf(priv)) {
1279 IWL_WARN(priv, "Try to add interface when device not ready\n"); 1284 IWL_WARN(priv, "Try to add interface when device not ready\n");
1280 err = -EINVAL; 1285 err = -EINVAL;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 02817a43855..42bcb469d32 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -136,6 +136,7 @@ struct iwl_mod_params {
136 * @max_event_log_size: size of event log buffer size for ucode event logging 136 * @max_event_log_size: size of event log buffer size for ucode event logging
137 * @shadow_reg_enable: HW shadhow register bit 137 * @shadow_reg_enable: HW shadhow register bit
138 * @no_idle_support: do not support idle mode 138 * @no_idle_support: do not support idle mode
139 * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
139 */ 140 */
140struct iwl_base_params { 141struct iwl_base_params {
141 int eeprom_size; 142 int eeprom_size;
@@ -158,6 +159,7 @@ struct iwl_base_params {
158 u32 max_event_log_size; 159 u32 max_event_log_size;
159 const bool shadow_reg_enable; 160 const bool shadow_reg_enable;
160 const bool no_idle_support; 161 const bool no_idle_support;
162 const bool hd_v2;
161}; 163};
162/* 164/*
163 * @advanced_bt_coexist: support advanced bt coexist 165 * @advanced_bt_coexist: support advanced bt coexist
@@ -194,6 +196,8 @@ struct iwl_ht_params {
194 * (.ucode) will be added to filename before loading from disk. The 196 * (.ucode) will be added to filename before loading from disk. The
195 * filename is constructed as fw_name_pre<api>.ucode. 197 * filename is constructed as fw_name_pre<api>.ucode.
196 * @ucode_api_max: Highest version of uCode API supported by driver. 198 * @ucode_api_max: Highest version of uCode API supported by driver.
199 * @ucode_api_ok: oldest version of the uCode API that is OK to load
200 * without a warning, for use in transitions
197 * @ucode_api_min: Lowest version of uCode API supported by driver. 201 * @ucode_api_min: Lowest version of uCode API supported by driver.
198 * @valid_tx_ant: valid transmit antenna 202 * @valid_tx_ant: valid transmit antenna
199 * @valid_rx_ant: valid receive antenna 203 * @valid_rx_ant: valid receive antenna
@@ -237,6 +241,7 @@ struct iwl_cfg {
237 const char *name; 241 const char *name;
238 const char *fw_name_pre; 242 const char *fw_name_pre;
239 const unsigned int ucode_api_max; 243 const unsigned int ucode_api_max;
244 const unsigned int ucode_api_ok;
240 const unsigned int ucode_api_min; 245 const unsigned int ucode_api_min;
241 u8 valid_tx_ant; 246 u8 valid_tx_ant;
242 u8 valid_rx_ant; 247 u8 valid_rx_ant;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 6c9790cac8d..dd34c7c502f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -230,12 +230,23 @@ struct iwl_channel_info {
230#define IWL_TX_FIFO_BE_IPAN 4 230#define IWL_TX_FIFO_BE_IPAN 4
231#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI 231#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI
232#define IWL_TX_FIFO_VO_IPAN 5 232#define IWL_TX_FIFO_VO_IPAN 5
233/* re-uses the VO FIFO, uCode will properly flush/schedule */
234#define IWL_TX_FIFO_AUX 5
233#define IWL_TX_FIFO_UNUSED -1 235#define IWL_TX_FIFO_UNUSED -1
234 236
235/* Minimum number of queues. MAX_NUM is defined in hw specific files. 237/* AUX (TX during scan dwell) queue */
236 * Set the minimum to accommodate the 4 standard TX queues, 1 command 238#define IWL_AUX_QUEUE 10
237 * queue, 2 (unused) HCCA queues, and 4 HT queues (one for each AC) */ 239
238#define IWL_MIN_NUM_QUEUES 10 240/*
241 * Minimum number of queues. MAX_NUM is defined in hw specific files.
242 * Set the minimum to accommodate
243 * - 4 standard TX queues
244 * - the command queue
245 * - 4 PAN TX queues
246 * - the PAN multicast queue, and
247 * - the AUX (TX during scan dwell) queue.
248 */
249#define IWL_MIN_NUM_QUEUES 11
239 250
240/* 251/*
241 * Command queue depends on iPAN support. 252 * Command queue depends on iPAN support.
@@ -564,11 +575,13 @@ enum iwl_ucode_tlv_type {
564 * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, 575 * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
565 * treats good CRC threshold as a boolean 576 * treats good CRC threshold as a boolean
566 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). 577 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
578 * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
567 */ 579 */
568enum iwl_ucode_tlv_flag { 580enum iwl_ucode_tlv_flag {
569 IWL_UCODE_TLV_FLAGS_PAN = BIT(0), 581 IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
570 IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), 582 IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),
571 IWL_UCODE_TLV_FLAGS_MFP = BIT(2), 583 IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
584 IWL_UCODE_TLV_FLAGS_P2P = BIT(3),
572}; 585};
573 586
574struct iwl_ucode_tlv { 587struct iwl_ucode_tlv {
@@ -1168,7 +1181,7 @@ struct iwl_rxon_context {
1168enum iwl_scan_type { 1181enum iwl_scan_type {
1169 IWL_SCAN_NORMAL, 1182 IWL_SCAN_NORMAL,
1170 IWL_SCAN_RADIO_RESET, 1183 IWL_SCAN_RADIO_RESET,
1171 IWL_SCAN_OFFCH_TX, 1184 IWL_SCAN_ROC,
1172}; 1185};
1173 1186
1174enum iwlagn_ucode_type { 1187enum iwlagn_ucode_type {
@@ -1438,15 +1451,11 @@ struct iwl_priv {
1438 1451
1439 /* remain-on-channel offload support */ 1452 /* remain-on-channel offload support */
1440 struct ieee80211_channel *hw_roc_channel; 1453 struct ieee80211_channel *hw_roc_channel;
1441 struct delayed_work hw_roc_work; 1454 struct delayed_work hw_roc_disable_work;
1442 enum nl80211_channel_type hw_roc_chantype; 1455 enum nl80211_channel_type hw_roc_chantype;
1443 int hw_roc_duration; 1456 int hw_roc_duration;
1444 bool hw_roc_setup; 1457 bool hw_roc_setup;
1445 1458
1446 struct sk_buff *offchan_tx_skb;
1447 int offchan_tx_timeout;
1448 struct ieee80211_channel *offchan_tx_chan;
1449
1450 /* bt coex */ 1459 /* bt coex */
1451 u8 bt_enable_flag; 1460 u8 bt_enable_flag;
1452 u8 bt_status; 1461 u8 bt_status;
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index a67ae56d546..1a5252d8ca7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -31,7 +31,6 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/skbuff.h> 32#include <linux/skbuff.h>
33#include <linux/netdevice.h> 33#include <linux/netdevice.h>
34#include <linux/wireless.h>
35#include <net/mac80211.h> 34#include <net/mac80211.h>
36#include <linux/etherdevice.h> 35#include <linux/etherdevice.h>
37#include <asm/unaligned.h> 36#include <asm/unaligned.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index dd6937e9705..28e59319f58 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -103,6 +103,12 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
103 ieee80211_scan_completed(priv->hw, aborted); 103 ieee80211_scan_completed(priv->hw, aborted);
104 } 104 }
105 105
106 if (priv->scan_type == IWL_SCAN_ROC) {
107 ieee80211_remain_on_channel_expired(priv->hw);
108 priv->hw_roc_channel = NULL;
109 schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ);
110 }
111
106 priv->scan_type = IWL_SCAN_NORMAL; 112 priv->scan_type = IWL_SCAN_NORMAL;
107 priv->scan_vif = NULL; 113 priv->scan_vif = NULL;
108 priv->scan_request = NULL; 114 priv->scan_request = NULL;
@@ -211,6 +217,9 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
211 le32_to_cpu(notif->tsf_high), 217 le32_to_cpu(notif->tsf_high),
212 le32_to_cpu(notif->tsf_low), 218 le32_to_cpu(notif->tsf_low),
213 notif->status, notif->beacon_timer); 219 notif->status, notif->beacon_timer);
220
221 if (priv->scan_type == IWL_SCAN_ROC)
222 ieee80211_ready_on_channel(priv->hw);
214} 223}
215 224
216/* Service SCAN_RESULTS_NOTIFICATION (0x83) */ 225/* Service SCAN_RESULTS_NOTIFICATION (0x83) */
@@ -370,7 +379,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
370 379
371 IWL_DEBUG_SCAN(priv, "Starting %sscan...\n", 380 IWL_DEBUG_SCAN(priv, "Starting %sscan...\n",
372 scan_type == IWL_SCAN_NORMAL ? "" : 381 scan_type == IWL_SCAN_NORMAL ? "" :
373 scan_type == IWL_SCAN_OFFCH_TX ? "offchan TX " : 382 scan_type == IWL_SCAN_ROC ? "remain-on-channel " :
374 "internal short "); 383 "internal short ");
375 384
376 set_bit(STATUS_SCANNING, &priv->status); 385 set_bit(STATUS_SCANNING, &priv->status);
@@ -565,10 +574,10 @@ static void iwl_bg_scan_completed(struct work_struct *work)
565 goto out_settings; 574 goto out_settings;
566 } 575 }
567 576
568 if (priv->scan_type == IWL_SCAN_OFFCH_TX && priv->offchan_tx_skb) { 577 if (priv->scan_type == IWL_SCAN_ROC) {
569 ieee80211_tx_status_irqsafe(priv->hw, 578 ieee80211_remain_on_channel_expired(priv->hw);
570 priv->offchan_tx_skb); 579 priv->hw_roc_channel = NULL;
571 priv->offchan_tx_skb = NULL; 580 schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ);
572 } 581 }
573 582
574 if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) { 583 if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
index 41f0de91400..3001bfb46e2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.c
@@ -750,6 +750,7 @@ static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = {
750 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, 750 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
751 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, 751 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
752 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, 752 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
753 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
753}; 754};
754 755
755static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = { 756static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
@@ -763,6 +764,7 @@ static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
763 { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, }, 764 { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, },
764 { IWL_TX_FIFO_BE_IPAN, 2, }, 765 { IWL_TX_FIFO_BE_IPAN, 2, },
765 { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, 766 { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
767 { IWL_TX_FIFO_AUX, IWL_AC_UNSET, },
766}; 768};
767static void iwl_trans_tx_start(struct iwl_priv *priv) 769static void iwl_trans_tx_start(struct iwl_priv *priv)
768{ 770{
@@ -848,10 +850,12 @@ static void iwl_trans_tx_start(struct iwl_priv *priv)
848 /* reset to 0 to enable all the queue first */ 850 /* reset to 0 to enable all the queue first */
849 priv->txq_ctx_active_msk = 0; 851 priv->txq_ctx_active_msk = 0;
850 852
851 BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10); 853 BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) !=
852 BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10); 854 IWLAGN_FIRST_AMPDU_QUEUE);
855 BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) !=
856 IWLAGN_FIRST_AMPDU_QUEUE);
853 857
854 for (i = 0; i < 10; i++) { 858 for (i = 0; i < IWLAGN_FIRST_AMPDU_QUEUE; i++) {
855 int fifo = queue_to_fifo[i].fifo; 859 int fifo = queue_to_fifo[i].fifo;
856 int ac = queue_to_fifo[i].ac; 860 int ac = queue_to_fifo[i].ac;
857 861
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index b456a53b64b..85b3169c40d 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -19,6 +19,7 @@
19#include "decl.h" 19#include "decl.h"
20#include "cfg.h" 20#include "cfg.h"
21#include "cmd.h" 21#include "cmd.h"
22#include "mesh.h"
22 23
23 24
24#define CHAN2G(_channel, _freq, _flags) { \ 25#define CHAN2G(_channel, _freq, _flags) { \
@@ -442,13 +443,16 @@ static int lbs_cfg_set_channel(struct wiphy *wiphy,
442 struct lbs_private *priv = wiphy_priv(wiphy); 443 struct lbs_private *priv = wiphy_priv(wiphy);
443 int ret = -ENOTSUPP; 444 int ret = -ENOTSUPP;
444 445
445 lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", 446 lbs_deb_enter_args(LBS_DEB_CFG80211, "iface %s freq %d, type %d",
446 channel->center_freq, channel_type); 447 netdev_name(netdev), channel->center_freq, channel_type);
447 448
448 if (channel_type != NL80211_CHAN_NO_HT) 449 if (channel_type != NL80211_CHAN_NO_HT)
449 goto out; 450 goto out;
450 451
451 ret = lbs_set_channel(priv, channel->hw_value); 452 if (netdev == priv->mesh_dev)
453 ret = lbs_mesh_set_channel(priv, channel->hw_value);
454 else
455 ret = lbs_set_channel(priv, channel->hw_value);
452 456
453 out: 457 out:
454 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 458 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
@@ -708,7 +712,7 @@ static void lbs_scan_worker(struct work_struct *work)
708 712
709 if (priv->scan_channel < priv->scan_req->n_channels) { 713 if (priv->scan_channel < priv->scan_req->n_channels) {
710 cancel_delayed_work(&priv->scan_work); 714 cancel_delayed_work(&priv->scan_work);
711 if (!priv->stopping) 715 if (netif_running(priv->dev))
712 queue_delayed_work(priv->work_thread, &priv->scan_work, 716 queue_delayed_work(priv->work_thread, &priv->scan_work,
713 msecs_to_jiffies(300)); 717 msecs_to_jiffies(300));
714 } 718 }
@@ -1292,6 +1296,9 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
1292 int ret = 0; 1296 int ret = 0;
1293 u8 preamble = RADIO_PREAMBLE_SHORT; 1297 u8 preamble = RADIO_PREAMBLE_SHORT;
1294 1298
1299 if (dev == priv->mesh_dev)
1300 return -EOPNOTSUPP;
1301
1295 lbs_deb_enter(LBS_DEB_CFG80211); 1302 lbs_deb_enter(LBS_DEB_CFG80211);
1296 1303
1297 if (!sme->bssid) { 1304 if (!sme->bssid) {
@@ -1402,28 +1409,23 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
1402 return ret; 1409 return ret;
1403} 1410}
1404 1411
1405static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev, 1412int lbs_disconnect(struct lbs_private *priv, u16 reason)
1406 u16 reason_code)
1407{ 1413{
1408 struct lbs_private *priv = wiphy_priv(wiphy);
1409 struct cmd_ds_802_11_deauthenticate cmd; 1414 struct cmd_ds_802_11_deauthenticate cmd;
1410 1415 int ret;
1411 lbs_deb_enter_args(LBS_DEB_CFG80211, "reason_code %d", reason_code);
1412
1413 /* store for lbs_cfg_ret_disconnect() */
1414 priv->disassoc_reason = reason_code;
1415 1416
1416 memset(&cmd, 0, sizeof(cmd)); 1417 memset(&cmd, 0, sizeof(cmd));
1417 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1418 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1418 /* Mildly ugly to use a locally store my own BSSID ... */ 1419 /* Mildly ugly to use a locally store my own BSSID ... */
1419 memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN); 1420 memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN);
1420 cmd.reasoncode = cpu_to_le16(reason_code); 1421 cmd.reasoncode = cpu_to_le16(reason);
1421 1422
1422 if (lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd)) 1423 ret = lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd);
1423 return -EFAULT; 1424 if (ret)
1425 return ret;
1424 1426
1425 cfg80211_disconnected(priv->dev, 1427 cfg80211_disconnected(priv->dev,
1426 priv->disassoc_reason, 1428 reason,
1427 NULL, 0, 1429 NULL, 0,
1428 GFP_KERNEL); 1430 GFP_KERNEL);
1429 priv->connect_status = LBS_DISCONNECTED; 1431 priv->connect_status = LBS_DISCONNECTED;
@@ -1431,6 +1433,21 @@ static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
1431 return 0; 1433 return 0;
1432} 1434}
1433 1435
1436static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
1437 u16 reason_code)
1438{
1439 struct lbs_private *priv = wiphy_priv(wiphy);
1440
1441 if (dev == priv->mesh_dev)
1442 return -EOPNOTSUPP;
1443
1444 lbs_deb_enter_args(LBS_DEB_CFG80211, "reason_code %d", reason_code);
1445
1446 /* store for lbs_cfg_ret_disconnect() */
1447 priv->disassoc_reason = reason_code;
1448
1449 return lbs_disconnect(priv, reason_code);
1450}
1434 1451
1435static int lbs_cfg_set_default_key(struct wiphy *wiphy, 1452static int lbs_cfg_set_default_key(struct wiphy *wiphy,
1436 struct net_device *netdev, 1453 struct net_device *netdev,
@@ -1439,6 +1456,9 @@ static int lbs_cfg_set_default_key(struct wiphy *wiphy,
1439{ 1456{
1440 struct lbs_private *priv = wiphy_priv(wiphy); 1457 struct lbs_private *priv = wiphy_priv(wiphy);
1441 1458
1459 if (netdev == priv->mesh_dev)
1460 return -EOPNOTSUPP;
1461
1442 lbs_deb_enter(LBS_DEB_CFG80211); 1462 lbs_deb_enter(LBS_DEB_CFG80211);
1443 1463
1444 if (key_index != priv->wep_tx_key) { 1464 if (key_index != priv->wep_tx_key) {
@@ -1460,6 +1480,9 @@ static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
1460 u16 key_type; 1480 u16 key_type;
1461 int ret = 0; 1481 int ret = 0;
1462 1482
1483 if (netdev == priv->mesh_dev)
1484 return -EOPNOTSUPP;
1485
1463 lbs_deb_enter(LBS_DEB_CFG80211); 1486 lbs_deb_enter(LBS_DEB_CFG80211);
1464 1487
1465 lbs_deb_assoc("add_key: cipher 0x%x, mac_addr %pM\n", 1488 lbs_deb_assoc("add_key: cipher 0x%x, mac_addr %pM\n",
@@ -1603,6 +1626,9 @@ static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev,
1603 s8 signal, noise; 1626 s8 signal, noise;
1604 int ret; 1627 int ret;
1605 1628
1629 if (dev == priv->mesh_dev)
1630 return -EOPNOTSUPP;
1631
1606 if (idx != 0) 1632 if (idx != 0)
1607 ret = -ENOENT; 1633 ret = -ENOENT;
1608 1634
@@ -1636,6 +1662,9 @@ static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
1636 struct lbs_private *priv = wiphy_priv(wiphy); 1662 struct lbs_private *priv = wiphy_priv(wiphy);
1637 int ret = 0; 1663 int ret = 0;
1638 1664
1665 if (dev == priv->mesh_dev)
1666 return -EOPNOTSUPP;
1667
1639 lbs_deb_enter(LBS_DEB_CFG80211); 1668 lbs_deb_enter(LBS_DEB_CFG80211);
1640 1669
1641 switch (type) { 1670 switch (type) {
@@ -1959,6 +1988,9 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1959 struct cfg80211_bss *bss; 1988 struct cfg80211_bss *bss;
1960 DECLARE_SSID_BUF(ssid_buf); 1989 DECLARE_SSID_BUF(ssid_buf);
1961 1990
1991 if (dev == priv->mesh_dev)
1992 return -EOPNOTSUPP;
1993
1962 lbs_deb_enter(LBS_DEB_CFG80211); 1994 lbs_deb_enter(LBS_DEB_CFG80211);
1963 1995
1964 if (!params->channel) { 1996 if (!params->channel) {
@@ -1995,6 +2027,9 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1995 struct cmd_ds_802_11_ad_hoc_stop cmd; 2027 struct cmd_ds_802_11_ad_hoc_stop cmd;
1996 int ret = 0; 2028 int ret = 0;
1997 2029
2030 if (dev == priv->mesh_dev)
2031 return -EOPNOTSUPP;
2032
1998 lbs_deb_enter(LBS_DEB_CFG80211); 2033 lbs_deb_enter(LBS_DEB_CFG80211);
1999 2034
2000 memset(&cmd, 0, sizeof(cmd)); 2035 memset(&cmd, 0, sizeof(cmd));
@@ -2117,6 +2152,8 @@ int lbs_cfg_register(struct lbs_private *priv)
2117 BIT(NL80211_IFTYPE_ADHOC); 2152 BIT(NL80211_IFTYPE_ADHOC);
2118 if (lbs_rtap_supported(priv)) 2153 if (lbs_rtap_supported(priv))
2119 wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); 2154 wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
2155 if (lbs_mesh_activated(priv))
2156 wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MESH_POINT);
2120 2157
2121 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &lbs_band_2ghz; 2158 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &lbs_band_2ghz;
2122 2159
diff --git a/drivers/net/wireless/libertas/cfg.h b/drivers/net/wireless/libertas/cfg.h
index 4f46bb744be..a02ee151710 100644
--- a/drivers/net/wireless/libertas/cfg.h
+++ b/drivers/net/wireless/libertas/cfg.h
@@ -17,5 +17,6 @@ void lbs_send_disconnect_notification(struct lbs_private *priv);
17void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event); 17void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
18 18
19void lbs_scan_deinit(struct lbs_private *priv); 19void lbs_scan_deinit(struct lbs_private *priv);
20int lbs_disconnect(struct lbs_private *priv, u16 reason);
20 21
21#endif 22#endif
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index dbd24a4607e..e08ab1de3d9 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1088,7 +1088,7 @@ void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
1088 if (!cmd->callback || cmd->callback == lbs_cmd_async_callback) 1088 if (!cmd->callback || cmd->callback == lbs_cmd_async_callback)
1089 __lbs_cleanup_and_insert_cmd(priv, cmd); 1089 __lbs_cleanup_and_insert_cmd(priv, cmd);
1090 priv->cur_cmd = NULL; 1090 priv->cur_cmd = NULL;
1091 wake_up_interruptible(&priv->waitq); 1091 wake_up(&priv->waitq);
1092} 1092}
1093 1093
1094void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, 1094void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
@@ -1627,7 +1627,7 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
1627 lbs_deb_host("PREP_CMD: cmdnode is NULL\n"); 1627 lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
1628 1628
1629 /* Wake up main thread to execute next command */ 1629 /* Wake up main thread to execute next command */
1630 wake_up_interruptible(&priv->waitq); 1630 wake_up(&priv->waitq);
1631 cmdnode = ERR_PTR(-ENOBUFS); 1631 cmdnode = ERR_PTR(-ENOBUFS);
1632 goto done; 1632 goto done;
1633 } 1633 }
@@ -1647,7 +1647,7 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
1647 1647
1648 cmdnode->cmdwaitqwoken = 0; 1648 cmdnode->cmdwaitqwoken = 0;
1649 lbs_queue_cmd(priv, cmdnode); 1649 lbs_queue_cmd(priv, cmdnode);
1650 wake_up_interruptible(&priv->waitq); 1650 wake_up(&priv->waitq);
1651 1651
1652 done: 1652 done:
1653 lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode); 1653 lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode);
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index da0b05bb89f..9304e6fc421 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -43,10 +43,14 @@ int lbs_start_card(struct lbs_private *priv);
43void lbs_stop_card(struct lbs_private *priv); 43void lbs_stop_card(struct lbs_private *priv);
44void lbs_host_to_card_done(struct lbs_private *priv); 44void lbs_host_to_card_done(struct lbs_private *priv);
45 45
46int lbs_start_iface(struct lbs_private *priv);
47int lbs_stop_iface(struct lbs_private *priv);
48
46int lbs_rtap_supported(struct lbs_private *priv); 49int lbs_rtap_supported(struct lbs_private *priv);
47 50
48int lbs_set_mac_address(struct net_device *dev, void *addr); 51int lbs_set_mac_address(struct net_device *dev, void *addr);
49void lbs_set_multicast_list(struct net_device *dev); 52void lbs_set_multicast_list(struct net_device *dev);
53void lbs_update_mcast(struct lbs_private *priv);
50 54
51int lbs_suspend(struct lbs_private *priv); 55int lbs_suspend(struct lbs_private *priv);
52int lbs_resume(struct lbs_private *priv); 56int lbs_resume(struct lbs_private *priv);
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index adb3490e3cf..814838916b8 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -6,7 +6,6 @@
6#ifndef _LBS_DEV_H_ 6#ifndef _LBS_DEV_H_
7#define _LBS_DEV_H_ 7#define _LBS_DEV_H_
8 8
9#include "mesh.h"
10#include "defs.h" 9#include "defs.h"
11#include "host.h" 10#include "host.h"
12 11
@@ -22,6 +21,17 @@ struct sleep_params {
22 uint16_t sp_reserved; 21 uint16_t sp_reserved;
23}; 22};
24 23
24/* Mesh statistics */
25struct lbs_mesh_stats {
26 u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */
27 u32 fwd_unicast_cnt; /* Fwd: Unicast counter */
28 u32 fwd_drop_ttl; /* Fwd: TTL zero */
29 u32 fwd_drop_rbt; /* Fwd: Recently Broadcasted */
30 u32 fwd_drop_noroute; /* Fwd: No route to Destination */
31 u32 fwd_drop_nobuf; /* Fwd: Run out of internal buffers */
32 u32 drop_blind; /* Rx: Dropped by blinding table */
33 u32 tx_failed_cnt; /* Tx: Failed transmissions */
34};
25 35
26/* Private structure for the MV device */ 36/* Private structure for the MV device */
27struct lbs_private { 37struct lbs_private {
@@ -36,7 +46,6 @@ struct lbs_private {
36 /* CFG80211 */ 46 /* CFG80211 */
37 struct wireless_dev *wdev; 47 struct wireless_dev *wdev;
38 bool wiphy_registered; 48 bool wiphy_registered;
39 bool stopping;
40 struct cfg80211_scan_request *scan_req; 49 struct cfg80211_scan_request *scan_req;
41 u8 assoc_bss[ETH_ALEN]; 50 u8 assoc_bss[ETH_ALEN];
42 u8 disassoc_reason; 51 u8 disassoc_reason;
@@ -86,11 +95,14 @@ struct lbs_private {
86 95
87 /* Hardware access */ 96 /* Hardware access */
88 void *card; 97 void *card;
98 bool iface_running;
89 u8 fw_ready; 99 u8 fw_ready;
90 u8 surpriseremoved; 100 u8 surpriseremoved;
91 u8 setup_fw_on_resume; 101 u8 setup_fw_on_resume;
92 int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb); 102 int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb);
93 void (*reset_card) (struct lbs_private *priv); 103 void (*reset_card) (struct lbs_private *priv);
104 int (*power_save) (struct lbs_private *priv);
105 int (*power_restore) (struct lbs_private *priv);
94 int (*enter_deep_sleep) (struct lbs_private *priv); 106 int (*enter_deep_sleep) (struct lbs_private *priv);
95 int (*exit_deep_sleep) (struct lbs_private *priv); 107 int (*exit_deep_sleep) (struct lbs_private *priv);
96 int (*reset_deep_sleep_wakeup) (struct lbs_private *priv); 108 int (*reset_deep_sleep_wakeup) (struct lbs_private *priv);
@@ -172,4 +184,16 @@ struct lbs_private {
172 184
173extern struct cmd_confirm_sleep confirm_sleep; 185extern struct cmd_confirm_sleep confirm_sleep;
174 186
187/* Check if there is an interface active. */
188static inline int lbs_iface_active(struct lbs_private *priv)
189{
190 int r;
191
192 r = netif_running(priv->dev);
193 if (priv->mesh_dev);
194 r |= netif_running(priv->dev);
195
196 return r;
197}
198
175#endif 199#endif
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 4dfb3bfd2cf..885ddc1c4fe 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -5,6 +5,7 @@
5 5
6#include "decl.h" 6#include "decl.h"
7#include "cmd.h" 7#include "cmd.h"
8#include "mesh.h"
8 9
9 10
10static void lbs_ethtool_get_drvinfo(struct net_device *dev, 11static void lbs_ethtool_get_drvinfo(struct net_device *dev,
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 387786e1b39..c962e21762d 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -39,6 +39,7 @@
39#include <linux/mmc/sdio_ids.h> 39#include <linux/mmc/sdio_ids.h>
40#include <linux/mmc/sdio.h> 40#include <linux/mmc/sdio.h>
41#include <linux/mmc/host.h> 41#include <linux/mmc/host.h>
42#include <linux/pm_runtime.h>
42 43
43#include "host.h" 44#include "host.h"
44#include "decl.h" 45#include "decl.h"
@@ -47,6 +48,8 @@
47#include "cmd.h" 48#include "cmd.h"
48#include "if_sdio.h" 49#include "if_sdio.h"
49 50
51static void if_sdio_interrupt(struct sdio_func *func);
52
50/* The if_sdio_remove() callback function is called when 53/* The if_sdio_remove() callback function is called when
51 * user removes this module from kernel space or ejects 54 * user removes this module from kernel space or ejects
52 * the card from the slot. The driver handles these 2 cases 55 * the card from the slot. The driver handles these 2 cases
@@ -757,6 +760,136 @@ out:
757 return ret; 760 return ret;
758} 761}
759 762
763/********************************************************************/
764/* Power management */
765/********************************************************************/
766
767static int if_sdio_power_on(struct if_sdio_card *card)
768{
769 struct sdio_func *func = card->func;
770 struct lbs_private *priv = card->priv;
771 struct mmc_host *host = func->card->host;
772 int ret;
773
774 sdio_claim_host(func);
775
776 ret = sdio_enable_func(func);
777 if (ret)
778 goto release;
779
780 /* For 1-bit transfers to the 8686 model, we need to enable the
781 * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
782 * bit to allow access to non-vendor registers. */
783 if ((card->model == MODEL_8686) &&
784 (host->caps & MMC_CAP_SDIO_IRQ) &&
785 (host->ios.bus_width == MMC_BUS_WIDTH_1)) {
786 u8 reg;
787
788 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
789 reg = sdio_f0_readb(func, SDIO_CCCR_IF, &ret);
790 if (ret)
791 goto disable;
792
793 reg |= SDIO_BUS_ECSI;
794 sdio_f0_writeb(func, reg, SDIO_CCCR_IF, &ret);
795 if (ret)
796 goto disable;
797 }
798
799 card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret);
800 if (ret)
801 goto disable;
802
803 card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 1, &ret) << 8;
804 if (ret)
805 goto disable;
806
807 card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 2, &ret) << 16;
808 if (ret)
809 goto disable;
810
811 sdio_release_host(func);
812 ret = if_sdio_prog_firmware(card);
813 sdio_claim_host(func);
814 if (ret)
815 goto disable;
816
817 /*
818 * Get rx_unit if the chip is SD8688 or newer.
819 * SD8385 & SD8686 do not have rx_unit.
820 */
821 if ((card->model != MODEL_8385)
822 && (card->model != MODEL_8686))
823 card->rx_unit = if_sdio_read_rx_unit(card);
824 else
825 card->rx_unit = 0;
826
827 /*
828 * Set up the interrupt handler late.
829 *
830 * If we set it up earlier, the (buggy) hardware generates a spurious
831 * interrupt, even before the interrupt has been enabled, with
832 * CCCR_INTx = 0.
833 *
834 * We register the interrupt handler late so that we can handle any
835 * spurious interrupts, and also to avoid generation of that known
836 * spurious interrupt in the first place.
837 */
838 ret = sdio_claim_irq(func, if_sdio_interrupt);
839 if (ret)
840 goto disable;
841
842 /*
843 * Enable interrupts now that everything is set up
844 */
845 sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret);
846 if (ret)
847 goto release_irq;
848
849 sdio_release_host(func);
850
851 /*
852 * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
853 */
854 if (card->model == MODEL_8688) {
855 struct cmd_header cmd;
856
857 memset(&cmd, 0, sizeof(cmd));
858
859 lbs_deb_sdio("send function INIT command\n");
860 if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
861 lbs_cmd_copyback, (unsigned long) &cmd))
862 netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
863 }
864
865 priv->fw_ready = 1;
866
867 return 0;
868
869release_irq:
870 sdio_release_irq(func);
871disable:
872 sdio_disable_func(func);
873release:
874 sdio_release_host(func);
875 return ret;
876}
877
878static int if_sdio_power_off(struct if_sdio_card *card)
879{
880 struct sdio_func *func = card->func;
881 struct lbs_private *priv = card->priv;
882
883 priv->fw_ready = 0;
884
885 sdio_claim_host(func);
886 sdio_release_irq(func);
887 sdio_disable_func(func);
888 sdio_release_host(func);
889 return 0;
890}
891
892
760/*******************************************************************/ 893/*******************************************************************/
761/* Libertas callbacks */ 894/* Libertas callbacks */
762/*******************************************************************/ 895/*******************************************************************/
@@ -923,6 +1056,32 @@ static void if_sdio_reset_card(struct lbs_private *priv)
923 schedule_work(&card_reset_work); 1056 schedule_work(&card_reset_work);
924} 1057}
925 1058
1059static int if_sdio_power_save(struct lbs_private *priv)
1060{
1061 struct if_sdio_card *card = priv->card;
1062 int ret;
1063
1064 flush_workqueue(card->workqueue);
1065
1066 ret = if_sdio_power_off(card);
1067
1068 /* Let runtime PM know the card is powered off */
1069 pm_runtime_put_sync(&card->func->dev);
1070
1071 return ret;
1072}
1073
1074static int if_sdio_power_restore(struct lbs_private *priv)
1075{
1076 struct if_sdio_card *card = priv->card;
1077
1078 /* Make sure the card will not be powered off by runtime PM */
1079 pm_runtime_get_sync(&card->func->dev);
1080
1081 return if_sdio_power_on(card);
1082}
1083
1084
926/*******************************************************************/ 1085/*******************************************************************/
927/* SDIO callbacks */ 1086/* SDIO callbacks */
928/*******************************************************************/ 1087/*******************************************************************/
@@ -976,7 +1135,6 @@ static int if_sdio_probe(struct sdio_func *func,
976 int ret, i; 1135 int ret, i;
977 unsigned int model; 1136 unsigned int model;
978 struct if_sdio_packet *packet; 1137 struct if_sdio_packet *packet;
979 struct mmc_host *host = func->card->host;
980 1138
981 lbs_deb_enter(LBS_DEB_SDIO); 1139 lbs_deb_enter(LBS_DEB_SDIO);
982 1140
@@ -1033,45 +1191,6 @@ static int if_sdio_probe(struct sdio_func *func,
1033 goto free; 1191 goto free;
1034 } 1192 }
1035 1193
1036 sdio_claim_host(func);
1037
1038 ret = sdio_enable_func(func);
1039 if (ret)
1040 goto release;
1041
1042 /* For 1-bit transfers to the 8686 model, we need to enable the
1043 * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
1044 * bit to allow access to non-vendor registers. */
1045 if ((card->model == MODEL_8686) &&
1046 (host->caps & MMC_CAP_SDIO_IRQ) &&
1047 (host->ios.bus_width == MMC_BUS_WIDTH_1)) {
1048 u8 reg;
1049
1050 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
1051 reg = sdio_f0_readb(func, SDIO_CCCR_IF, &ret);
1052 if (ret)
1053 goto release_int;
1054
1055 reg |= SDIO_BUS_ECSI;
1056 sdio_f0_writeb(func, reg, SDIO_CCCR_IF, &ret);
1057 if (ret)
1058 goto release_int;
1059 }
1060
1061 card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret);
1062 if (ret)
1063 goto release_int;
1064
1065 card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 1, &ret) << 8;
1066 if (ret)
1067 goto release_int;
1068
1069 card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 2, &ret) << 16;
1070 if (ret)
1071 goto release_int;
1072
1073 sdio_release_host(func);
1074
1075 sdio_set_drvdata(func, card); 1194 sdio_set_drvdata(func, card);
1076 1195
1077 lbs_deb_sdio("class = 0x%X, vendor = 0x%X, " 1196 lbs_deb_sdio("class = 0x%X, vendor = 0x%X, "
@@ -1079,14 +1198,11 @@ static int if_sdio_probe(struct sdio_func *func,
1079 func->class, func->vendor, func->device, 1198 func->class, func->vendor, func->device,
1080 model, (unsigned)card->ioport); 1199 model, (unsigned)card->ioport);
1081 1200
1082 ret = if_sdio_prog_firmware(card);
1083 if (ret)
1084 goto reclaim;
1085 1201
1086 priv = lbs_add_card(card, &func->dev); 1202 priv = lbs_add_card(card, &func->dev);
1087 if (!priv) { 1203 if (!priv) {
1088 ret = -ENOMEM; 1204 ret = -ENOMEM;
1089 goto reclaim; 1205 goto free;
1090 } 1206 }
1091 1207
1092 card->priv = priv; 1208 card->priv = priv;
@@ -1097,62 +1213,21 @@ static int if_sdio_probe(struct sdio_func *func,
1097 priv->exit_deep_sleep = if_sdio_exit_deep_sleep; 1213 priv->exit_deep_sleep = if_sdio_exit_deep_sleep;
1098 priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup; 1214 priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup;
1099 priv->reset_card = if_sdio_reset_card; 1215 priv->reset_card = if_sdio_reset_card;
1216 priv->power_save = if_sdio_power_save;
1217 priv->power_restore = if_sdio_power_restore;
1100 1218
1101 sdio_claim_host(func); 1219 ret = if_sdio_power_on(card);
1102
1103 /*
1104 * Get rx_unit if the chip is SD8688 or newer.
1105 * SD8385 & SD8686 do not have rx_unit.
1106 */
1107 if ((card->model != MODEL_8385)
1108 && (card->model != MODEL_8686))
1109 card->rx_unit = if_sdio_read_rx_unit(card);
1110 else
1111 card->rx_unit = 0;
1112
1113 /*
1114 * Set up the interrupt handler late.
1115 *
1116 * If we set it up earlier, the (buggy) hardware generates a spurious
1117 * interrupt, even before the interrupt has been enabled, with
1118 * CCCR_INTx = 0.
1119 *
1120 * We register the interrupt handler late so that we can handle any
1121 * spurious interrupts, and also to avoid generation of that known
1122 * spurious interrupt in the first place.
1123 */
1124 ret = sdio_claim_irq(func, if_sdio_interrupt);
1125 if (ret)
1126 goto disable;
1127
1128 /*
1129 * Enable interrupts now that everything is set up
1130 */
1131 sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret);
1132 sdio_release_host(func);
1133 if (ret) 1220 if (ret)
1134 goto reclaim; 1221 goto err_activate_card;
1135
1136 priv->fw_ready = 1;
1137
1138 /*
1139 * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
1140 */
1141 if (card->model == MODEL_8688) {
1142 struct cmd_header cmd;
1143
1144 memset(&cmd, 0, sizeof(cmd));
1145
1146 lbs_deb_sdio("send function INIT command\n");
1147 if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
1148 lbs_cmd_copyback, (unsigned long) &cmd))
1149 netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
1150 }
1151 1222
1152 ret = lbs_start_card(priv); 1223 ret = lbs_start_card(priv);
1224 if_sdio_power_off(card);
1153 if (ret) 1225 if (ret)
1154 goto err_activate_card; 1226 goto err_activate_card;
1155 1227
1228 /* Tell PM core that we don't need the card to be powered now */
1229 pm_runtime_put_noidle(&func->dev);
1230
1156out: 1231out:
1157 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 1232 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
1158 1233
@@ -1161,14 +1236,6 @@ out:
1161err_activate_card: 1236err_activate_card:
1162 flush_workqueue(card->workqueue); 1237 flush_workqueue(card->workqueue);
1163 lbs_remove_card(priv); 1238 lbs_remove_card(priv);
1164reclaim:
1165 sdio_claim_host(func);
1166release_int:
1167 sdio_release_irq(func);
1168disable:
1169 sdio_disable_func(func);
1170release:
1171 sdio_release_host(func);
1172free: 1239free:
1173 destroy_workqueue(card->workqueue); 1240 destroy_workqueue(card->workqueue);
1174 while (card->packets) { 1241 while (card->packets) {
@@ -1195,6 +1262,9 @@ static void if_sdio_remove(struct sdio_func *func)
1195 1262
1196 card = sdio_get_drvdata(func); 1263 card = sdio_get_drvdata(func);
1197 1264
1265 /* Undo decrement done above in if_sdio_probe */
1266 pm_runtime_get_noresume(&func->dev);
1267
1198 if (user_rmmod && (card->model == MODEL_8688)) { 1268 if (user_rmmod && (card->model == MODEL_8688)) {
1199 /* 1269 /*
1200 * FUNC_SHUTDOWN is required for SD8688 WLAN/BT 1270 * FUNC_SHUTDOWN is required for SD8688 WLAN/BT
@@ -1219,11 +1289,6 @@ static void if_sdio_remove(struct sdio_func *func)
1219 flush_workqueue(card->workqueue); 1289 flush_workqueue(card->workqueue);
1220 destroy_workqueue(card->workqueue); 1290 destroy_workqueue(card->workqueue);
1221 1291
1222 sdio_claim_host(func);
1223 sdio_release_irq(func);
1224 sdio_disable_func(func);
1225 sdio_release_host(func);
1226
1227 while (card->packets) { 1292 while (card->packets) {
1228 packet = card->packets; 1293 packet = card->packets;
1229 card->packets = card->packets->next; 1294 card->packets = card->packets->next;
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index e0286cfbc91..622ae6de0d8 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -531,10 +531,6 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card,
531 goto out; 531 goto out;
532 err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, 532 err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
533 IF_SPI_CIC_CMD_DOWNLOAD_OVER); 533 IF_SPI_CIC_CMD_DOWNLOAD_OVER);
534 goto out;
535
536 lbs_deb_spi("waiting for helper to boot...\n");
537
538out: 534out:
539 if (err) 535 if (err)
540 pr_err("failed to load helper firmware (err=%d)\n", err); 536 pr_err("failed to load helper firmware (err=%d)\n", err);
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index b5acc393a65..0c846f5a646 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -324,7 +324,7 @@ static int if_usb_probe(struct usb_interface *intf,
324 } 324 }
325 kparam_unblock_sysfs_write(fw_name); 325 kparam_unblock_sysfs_write(fw_name);
326 326
327 if (!(priv = lbs_add_card(cardp, &udev->dev))) 327 if (!(priv = lbs_add_card(cardp, &intf->dev)))
328 goto err_prog_firmware; 328 goto err_prog_firmware;
329 329
330 cardp->priv = priv; 330 cardp->priv = priv;
@@ -956,7 +956,7 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp,
956 priv->dnld_sent = DNLD_RES_RECEIVED; 956 priv->dnld_sent = DNLD_RES_RECEIVED;
957 spin_unlock_irqrestore(&priv->driver_lock, flags); 957 spin_unlock_irqrestore(&priv->driver_lock, flags);
958 958
959 wake_up_interruptible(&priv->waitq); 959 wake_up(&priv->waitq);
960 960
961 return ret; 961 return ret;
962} 962}
@@ -1112,6 +1112,15 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
1112 if (priv->psstate != PS_STATE_FULL_POWER) 1112 if (priv->psstate != PS_STATE_FULL_POWER)
1113 return -1; 1113 return -1;
1114 1114
1115#ifdef CONFIG_OLPC
1116 if (machine_is_olpc()) {
1117 if (priv->wol_criteria == EHS_REMOVE_WAKEUP)
1118 olpc_ec_wakeup_clear(EC_SCI_SRC_WLAN);
1119 else
1120 olpc_ec_wakeup_set(EC_SCI_SRC_WLAN);
1121 }
1122#endif
1123
1115 ret = lbs_suspend(priv); 1124 ret = lbs_suspend(priv);
1116 if (ret) 1125 if (ret)
1117 goto out; 1126 goto out;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 2fdeb81ce5b..d1c1d52931f 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -23,6 +23,7 @@
23#include "cfg.h" 23#include "cfg.h"
24#include "debugfs.h" 24#include "debugfs.h"
25#include "cmd.h" 25#include "cmd.h"
26#include "mesh.h"
26 27
27#define DRIVER_RELEASE_VERSION "323.p0" 28#define DRIVER_RELEASE_VERSION "323.p0"
28const char lbs_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION 29const char lbs_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
@@ -98,6 +99,37 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
98 return 0; 99 return 0;
99} 100}
100 101
102int lbs_start_iface(struct lbs_private *priv)
103{
104 struct cmd_ds_802_11_mac_address cmd;
105 int ret;
106
107 if (priv->power_restore) {
108 ret = priv->power_restore(priv);
109 if (ret)
110 return ret;
111 }
112
113 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
114 cmd.action = cpu_to_le16(CMD_ACT_SET);
115 memcpy(cmd.macadd, priv->current_addr, ETH_ALEN);
116
117 ret = lbs_cmd_with_response(priv, CMD_802_11_MAC_ADDRESS, &cmd);
118 if (ret) {
119 lbs_deb_net("set MAC address failed\n");
120 goto err;
121 }
122
123 lbs_update_channel(priv);
124
125 priv->iface_running = true;
126 return 0;
127
128err:
129 if (priv->power_save)
130 priv->power_save(priv);
131 return ret;
132}
101 133
102/** 134/**
103 * lbs_dev_open - open the ethX interface 135 * lbs_dev_open - open the ethX interface
@@ -111,23 +143,64 @@ static int lbs_dev_open(struct net_device *dev)
111 int ret = 0; 143 int ret = 0;
112 144
113 lbs_deb_enter(LBS_DEB_NET); 145 lbs_deb_enter(LBS_DEB_NET);
146 if (!priv->iface_running) {
147 ret = lbs_start_iface(priv);
148 if (ret)
149 goto out;
150 }
114 151
115 spin_lock_irq(&priv->driver_lock); 152 spin_lock_irq(&priv->driver_lock);
116 priv->stopping = false;
117 153
118 if (priv->connect_status == LBS_CONNECTED) 154 netif_carrier_off(dev);
119 netif_carrier_on(dev);
120 else
121 netif_carrier_off(dev);
122 155
123 if (!priv->tx_pending_len) 156 if (!priv->tx_pending_len)
124 netif_wake_queue(dev); 157 netif_wake_queue(dev);
125 158
126 spin_unlock_irq(&priv->driver_lock); 159 spin_unlock_irq(&priv->driver_lock);
160
161out:
127 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); 162 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
128 return ret; 163 return ret;
129} 164}
130 165
166static bool lbs_command_queue_empty(struct lbs_private *priv)
167{
168 unsigned long flags;
169 bool ret;
170 spin_lock_irqsave(&priv->driver_lock, flags);
171 ret = priv->cur_cmd == NULL && list_empty(&priv->cmdpendingq);
172 spin_unlock_irqrestore(&priv->driver_lock, flags);
173 return ret;
174}
175
176int lbs_stop_iface(struct lbs_private *priv)
177{
178 unsigned long flags;
179 int ret = 0;
180
181 lbs_deb_enter(LBS_DEB_MAIN);
182
183 spin_lock_irqsave(&priv->driver_lock, flags);
184 priv->iface_running = false;
185 kfree_skb(priv->currenttxskb);
186 priv->currenttxskb = NULL;
187 priv->tx_pending_len = 0;
188 spin_unlock_irqrestore(&priv->driver_lock, flags);
189
190 cancel_work_sync(&priv->mcast_work);
191
192 /* Disable command processing, and wait for all commands to complete */
193 lbs_deb_main("waiting for commands to complete\n");
194 wait_event(priv->waitq, lbs_command_queue_empty(priv));
195 lbs_deb_main("all commands completed\n");
196
197 if (priv->power_save)
198 ret = priv->power_save(priv);
199
200 lbs_deb_leave(LBS_DEB_MAIN);
201 return ret;
202}
203
131/** 204/**
132 * lbs_eth_stop - close the ethX interface 205 * lbs_eth_stop - close the ethX interface
133 * 206 *
@@ -140,18 +213,25 @@ static int lbs_eth_stop(struct net_device *dev)
140 213
141 lbs_deb_enter(LBS_DEB_NET); 214 lbs_deb_enter(LBS_DEB_NET);
142 215
216 if (priv->connect_status == LBS_CONNECTED)
217 lbs_disconnect(priv, WLAN_REASON_DEAUTH_LEAVING);
218
143 spin_lock_irq(&priv->driver_lock); 219 spin_lock_irq(&priv->driver_lock);
144 priv->stopping = true;
145 netif_stop_queue(dev); 220 netif_stop_queue(dev);
146 spin_unlock_irq(&priv->driver_lock); 221 spin_unlock_irq(&priv->driver_lock);
147 222
148 schedule_work(&priv->mcast_work); 223 lbs_update_mcast(priv);
149 cancel_delayed_work_sync(&priv->scan_work); 224 cancel_delayed_work_sync(&priv->scan_work);
150 if (priv->scan_req) { 225 if (priv->scan_req) {
151 cfg80211_scan_done(priv->scan_req, false); 226 cfg80211_scan_done(priv->scan_req, false);
152 priv->scan_req = NULL; 227 priv->scan_req = NULL;
153 } 228 }
154 229
230 netif_carrier_off(priv->dev);
231
232 if (!lbs_iface_active(priv))
233 lbs_stop_iface(priv);
234
155 lbs_deb_leave(LBS_DEB_NET); 235 lbs_deb_leave(LBS_DEB_NET);
156 return 0; 236 return 0;
157} 237}
@@ -169,7 +249,7 @@ void lbs_host_to_card_done(struct lbs_private *priv)
169 /* Wake main thread if commands are pending */ 249 /* Wake main thread if commands are pending */
170 if (!priv->cur_cmd || priv->tx_pending_len > 0) { 250 if (!priv->cur_cmd || priv->tx_pending_len > 0) {
171 if (!priv->wakeup_dev_required) 251 if (!priv->wakeup_dev_required)
172 wake_up_interruptible(&priv->waitq); 252 wake_up(&priv->waitq);
173 } 253 }
174 254
175 spin_unlock_irqrestore(&priv->driver_lock, flags); 255 spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -182,29 +262,24 @@ int lbs_set_mac_address(struct net_device *dev, void *addr)
182 int ret = 0; 262 int ret = 0;
183 struct lbs_private *priv = dev->ml_priv; 263 struct lbs_private *priv = dev->ml_priv;
184 struct sockaddr *phwaddr = addr; 264 struct sockaddr *phwaddr = addr;
185 struct cmd_ds_802_11_mac_address cmd;
186 265
187 lbs_deb_enter(LBS_DEB_NET); 266 lbs_deb_enter(LBS_DEB_NET);
188 267
268 /*
269 * Can only set MAC address when all interfaces are down, to be written
270 * to the hardware when one of them is brought up.
271 */
272 if (lbs_iface_active(priv))
273 return -EBUSY;
274
189 /* In case it was called from the mesh device */ 275 /* In case it was called from the mesh device */
190 dev = priv->dev; 276 dev = priv->dev;
191 277
192 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
193 cmd.action = cpu_to_le16(CMD_ACT_SET);
194 memcpy(cmd.macadd, phwaddr->sa_data, ETH_ALEN);
195
196 ret = lbs_cmd_with_response(priv, CMD_802_11_MAC_ADDRESS, &cmd);
197 if (ret) {
198 lbs_deb_net("set MAC address failed\n");
199 goto done;
200 }
201
202 memcpy(priv->current_addr, phwaddr->sa_data, ETH_ALEN); 278 memcpy(priv->current_addr, phwaddr->sa_data, ETH_ALEN);
203 memcpy(dev->dev_addr, phwaddr->sa_data, ETH_ALEN); 279 memcpy(dev->dev_addr, phwaddr->sa_data, ETH_ALEN);
204 if (priv->mesh_dev) 280 if (priv->mesh_dev)
205 memcpy(priv->mesh_dev->dev_addr, phwaddr->sa_data, ETH_ALEN); 281 memcpy(priv->mesh_dev->dev_addr, phwaddr->sa_data, ETH_ALEN);
206 282
207done:
208 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); 283 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
209 return ret; 284 return ret;
210} 285}
@@ -258,18 +333,18 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
258 return i; 333 return i;
259} 334}
260 335
261static void lbs_set_mcast_worker(struct work_struct *work) 336void lbs_update_mcast(struct lbs_private *priv)
262{ 337{
263 struct lbs_private *priv = container_of(work, struct lbs_private, mcast_work);
264 struct cmd_ds_mac_multicast_adr mcast_cmd; 338 struct cmd_ds_mac_multicast_adr mcast_cmd;
265 int dev_flags; 339 int dev_flags = 0;
266 int nr_addrs; 340 int nr_addrs;
267 int old_mac_control = priv->mac_control; 341 int old_mac_control = priv->mac_control;
268 342
269 lbs_deb_enter(LBS_DEB_NET); 343 lbs_deb_enter(LBS_DEB_NET);
270 344
271 dev_flags = priv->dev->flags; 345 if (netif_running(priv->dev))
272 if (priv->mesh_dev) 346 dev_flags |= priv->dev->flags;
347 if (priv->mesh_dev && netif_running(priv->mesh_dev))
273 dev_flags |= priv->mesh_dev->flags; 348 dev_flags |= priv->mesh_dev->flags;
274 349
275 if (dev_flags & IFF_PROMISC) { 350 if (dev_flags & IFF_PROMISC) {
@@ -315,6 +390,12 @@ static void lbs_set_mcast_worker(struct work_struct *work)
315 lbs_deb_leave(LBS_DEB_NET); 390 lbs_deb_leave(LBS_DEB_NET);
316} 391}
317 392
393static void lbs_set_mcast_worker(struct work_struct *work)
394{
395 struct lbs_private *priv = container_of(work, struct lbs_private, mcast_work);
396 lbs_update_mcast(priv);
397}
398
318void lbs_set_multicast_list(struct net_device *dev) 399void lbs_set_multicast_list(struct net_device *dev)
319{ 400{
320 struct lbs_private *priv = dev->ml_priv; 401 struct lbs_private *priv = dev->ml_priv;
@@ -647,7 +728,7 @@ static void lbs_cmd_timeout_handler(unsigned long data)
647 if (priv->dnld_sent == DNLD_CMD_SENT) 728 if (priv->dnld_sent == DNLD_CMD_SENT)
648 priv->dnld_sent = DNLD_RES_RECEIVED; 729 priv->dnld_sent = DNLD_RES_RECEIVED;
649 730
650 wake_up_interruptible(&priv->waitq); 731 wake_up(&priv->waitq);
651out: 732out:
652 spin_unlock_irqrestore(&priv->driver_lock, flags); 733 spin_unlock_irqrestore(&priv->driver_lock, flags);
653 lbs_deb_leave(LBS_DEB_CMD); 734 lbs_deb_leave(LBS_DEB_CMD);
@@ -889,10 +970,6 @@ void lbs_remove_card(struct lbs_private *priv)
889 lbs_remove_mesh(priv); 970 lbs_remove_mesh(priv);
890 lbs_scan_deinit(priv); 971 lbs_scan_deinit(priv);
891 972
892 dev = priv->dev;
893
894 cancel_work_sync(&priv->mcast_work);
895
896 /* worker thread destruction blocks on the in-flight command which 973 /* worker thread destruction blocks on the in-flight command which
897 * should have been cleared already in lbs_stop_card(). 974 * should have been cleared already in lbs_stop_card().
898 */ 975 */
@@ -950,17 +1027,18 @@ int lbs_start_card(struct lbs_private *priv)
950 if (ret) 1027 if (ret)
951 goto done; 1028 goto done;
952 1029
1030 if (!lbs_disablemesh)
1031 lbs_init_mesh(priv);
1032 else
1033 pr_info("%s: mesh disabled\n", dev->name);
1034
953 if (lbs_cfg_register(priv)) { 1035 if (lbs_cfg_register(priv)) {
954 pr_err("cannot register device\n"); 1036 pr_err("cannot register device\n");
955 goto done; 1037 goto done;
956 } 1038 }
957 1039
958 lbs_update_channel(priv); 1040 if (lbs_mesh_activated(priv))
959 1041 lbs_start_mesh(priv);
960 if (!lbs_disablemesh)
961 lbs_init_mesh(priv);
962 else
963 pr_info("%s: mesh disabled\n", dev->name);
964 1042
965 lbs_debugfs_init_one(priv, dev); 1043 lbs_debugfs_init_one(priv, dev);
966 1044
@@ -978,8 +1056,6 @@ EXPORT_SYMBOL_GPL(lbs_start_card);
978void lbs_stop_card(struct lbs_private *priv) 1056void lbs_stop_card(struct lbs_private *priv)
979{ 1057{
980 struct net_device *dev; 1058 struct net_device *dev;
981 struct cmd_ctrl_node *cmdnode;
982 unsigned long flags;
983 1059
984 lbs_deb_enter(LBS_DEB_MAIN); 1060 lbs_deb_enter(LBS_DEB_MAIN);
985 1061
@@ -992,30 +1068,6 @@ void lbs_stop_card(struct lbs_private *priv)
992 1068
993 lbs_debugfs_remove_one(priv); 1069 lbs_debugfs_remove_one(priv);
994 lbs_deinit_mesh(priv); 1070 lbs_deinit_mesh(priv);
995
996 /* Delete the timeout of the currently processing command */
997 del_timer_sync(&priv->command_timer);
998 del_timer_sync(&priv->auto_deepsleep_timer);
999
1000 /* Flush pending command nodes */
1001 spin_lock_irqsave(&priv->driver_lock, flags);
1002 lbs_deb_main("clearing pending commands\n");
1003 list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
1004 cmdnode->result = -ENOENT;
1005 cmdnode->cmdwaitqwoken = 1;
1006 wake_up(&cmdnode->cmdwait_q);
1007 }
1008
1009 /* Flush the command the card is currently processing */
1010 if (priv->cur_cmd) {
1011 lbs_deb_main("clearing current command\n");
1012 priv->cur_cmd->result = -ENOENT;
1013 priv->cur_cmd->cmdwaitqwoken = 1;
1014 wake_up(&priv->cur_cmd->cmdwait_q);
1015 }
1016 lbs_deb_main("done clearing commands\n");
1017 spin_unlock_irqrestore(&priv->driver_lock, flags);
1018
1019 unregister_netdev(dev); 1071 unregister_netdev(dev);
1020 1072
1021out: 1073out:
@@ -1036,7 +1088,7 @@ void lbs_queue_event(struct lbs_private *priv, u32 event)
1036 1088
1037 kfifo_in(&priv->event_fifo, (unsigned char *) &event, sizeof(u32)); 1089 kfifo_in(&priv->event_fifo, (unsigned char *) &event, sizeof(u32));
1038 1090
1039 wake_up_interruptible(&priv->waitq); 1091 wake_up(&priv->waitq);
1040 1092
1041 spin_unlock_irqrestore(&priv->driver_lock, flags); 1093 spin_unlock_irqrestore(&priv->driver_lock, flags);
1042 lbs_deb_leave(LBS_DEB_THREAD); 1094 lbs_deb_leave(LBS_DEB_THREAD);
@@ -1054,7 +1106,7 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
1054 BUG_ON(resp_idx > 1); 1106 BUG_ON(resp_idx > 1);
1055 priv->resp_idx = resp_idx; 1107 priv->resp_idx = resp_idx;
1056 1108
1057 wake_up_interruptible(&priv->waitq); 1109 wake_up(&priv->waitq);
1058 1110
1059 lbs_deb_leave(LBS_DEB_THREAD); 1111 lbs_deb_leave(LBS_DEB_THREAD);
1060} 1112}
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
index 8e3104d990f..e87c031b298 100644
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -129,6 +129,19 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
129 return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv); 129 return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
130} 130}
131 131
132int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel)
133{
134 return lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, channel);
135}
136
137static uint16_t lbs_mesh_get_channel(struct lbs_private *priv)
138{
139 struct wireless_dev *mesh_wdev = priv->mesh_dev->ieee80211_ptr;
140 if (mesh_wdev->channel)
141 return mesh_wdev->channel->hw_value;
142 else
143 return 1;
144}
132 145
133/*************************************************************************** 146/***************************************************************************
134 * Mesh sysfs support 147 * Mesh sysfs support
@@ -812,7 +825,6 @@ static void lbs_persist_config_remove(struct net_device *dev)
812 */ 825 */
813int lbs_init_mesh(struct lbs_private *priv) 826int lbs_init_mesh(struct lbs_private *priv)
814{ 827{
815 struct net_device *dev = priv->dev;
816 int ret = 0; 828 int ret = 0;
817 829
818 lbs_deb_enter(LBS_DEB_MESH); 830 lbs_deb_enter(LBS_DEB_MESH);
@@ -837,11 +849,9 @@ int lbs_init_mesh(struct lbs_private *priv)
837 useful */ 849 useful */
838 850
839 priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID; 851 priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
840 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 852 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1)) {
841 priv->channel)) {
842 priv->mesh_tlv = TLV_TYPE_MESH_ID; 853 priv->mesh_tlv = TLV_TYPE_MESH_ID;
843 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 854 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1))
844 priv->channel))
845 priv->mesh_tlv = 0; 855 priv->mesh_tlv = 0;
846 } 856 }
847 } else 857 } else
@@ -851,23 +861,16 @@ int lbs_init_mesh(struct lbs_private *priv)
851 * 0x100+37; Do not invoke command with old TLV. 861 * 0x100+37; Do not invoke command with old TLV.
852 */ 862 */
853 priv->mesh_tlv = TLV_TYPE_MESH_ID; 863 priv->mesh_tlv = TLV_TYPE_MESH_ID;
854 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 864 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1))
855 priv->channel))
856 priv->mesh_tlv = 0; 865 priv->mesh_tlv = 0;
857 } 866 }
858 867
859 /* Stop meshing until interface is brought up */ 868 /* Stop meshing until interface is brought up */
860 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, priv->channel); 869 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, 1);
861 870
862 if (priv->mesh_tlv) { 871 if (priv->mesh_tlv) {
863 sprintf(priv->mesh_ssid, "mesh"); 872 sprintf(priv->mesh_ssid, "mesh");
864 priv->mesh_ssid_len = 4; 873 priv->mesh_ssid_len = 4;
865
866 lbs_add_mesh(priv);
867
868 if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
869 netdev_err(dev, "cannot register lbs_mesh attribute\n");
870
871 ret = 1; 874 ret = 1;
872 } 875 }
873 876
@@ -875,6 +878,13 @@ int lbs_init_mesh(struct lbs_private *priv)
875 return ret; 878 return ret;
876} 879}
877 880
881void lbs_start_mesh(struct lbs_private *priv)
882{
883 lbs_add_mesh(priv);
884
885 if (device_create_file(&priv->dev->dev, &dev_attr_lbs_mesh))
886 netdev_err(priv->dev, "cannot register lbs_mesh attribute\n");
887}
878 888
879int lbs_deinit_mesh(struct lbs_private *priv) 889int lbs_deinit_mesh(struct lbs_private *priv)
880{ 890{
@@ -904,7 +914,8 @@ static int lbs_mesh_stop(struct net_device *dev)
904 struct lbs_private *priv = dev->ml_priv; 914 struct lbs_private *priv = dev->ml_priv;
905 915
906 lbs_deb_enter(LBS_DEB_MESH); 916 lbs_deb_enter(LBS_DEB_MESH);
907 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, priv->channel); 917 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP,
918 lbs_mesh_get_channel(priv));
908 919
909 spin_lock_irq(&priv->driver_lock); 920 spin_lock_irq(&priv->driver_lock);
910 921
@@ -913,7 +924,9 @@ static int lbs_mesh_stop(struct net_device *dev)
913 924
914 spin_unlock_irq(&priv->driver_lock); 925 spin_unlock_irq(&priv->driver_lock);
915 926
916 schedule_work(&priv->mcast_work); 927 lbs_update_mcast(priv);
928 if (!lbs_iface_active(priv))
929 lbs_stop_iface(priv);
917 930
918 lbs_deb_leave(LBS_DEB_MESH); 931 lbs_deb_leave(LBS_DEB_MESH);
919 return 0; 932 return 0;
@@ -931,6 +944,11 @@ static int lbs_mesh_dev_open(struct net_device *dev)
931 int ret = 0; 944 int ret = 0;
932 945
933 lbs_deb_enter(LBS_DEB_NET); 946 lbs_deb_enter(LBS_DEB_NET);
947 if (!priv->iface_running) {
948 ret = lbs_start_iface(priv);
949 if (ret)
950 goto out;
951 }
934 952
935 spin_lock_irq(&priv->driver_lock); 953 spin_lock_irq(&priv->driver_lock);
936 954
@@ -947,7 +965,8 @@ static int lbs_mesh_dev_open(struct net_device *dev)
947 965
948 spin_unlock_irq(&priv->driver_lock); 966 spin_unlock_irq(&priv->driver_lock);
949 967
950 ret = lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, priv->channel); 968 ret = lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
969 lbs_mesh_get_channel(priv));
951 970
952out: 971out:
953 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); 972 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
@@ -971,18 +990,32 @@ static const struct net_device_ops mesh_netdev_ops = {
971static int lbs_add_mesh(struct lbs_private *priv) 990static int lbs_add_mesh(struct lbs_private *priv)
972{ 991{
973 struct net_device *mesh_dev = NULL; 992 struct net_device *mesh_dev = NULL;
993 struct wireless_dev *mesh_wdev;
974 int ret = 0; 994 int ret = 0;
975 995
976 lbs_deb_enter(LBS_DEB_MESH); 996 lbs_deb_enter(LBS_DEB_MESH);
977 997
978 /* Allocate a virtual mesh device */ 998 /* Allocate a virtual mesh device */
999 mesh_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1000 if (!mesh_wdev) {
1001 lbs_deb_mesh("init mshX wireless device failed\n");
1002 ret = -ENOMEM;
1003 goto done;
1004 }
1005
979 mesh_dev = alloc_netdev(0, "msh%d", ether_setup); 1006 mesh_dev = alloc_netdev(0, "msh%d", ether_setup);
980 if (!mesh_dev) { 1007 if (!mesh_dev) {
981 lbs_deb_mesh("init mshX device failed\n"); 1008 lbs_deb_mesh("init mshX device failed\n");
982 ret = -ENOMEM; 1009 ret = -ENOMEM;
983 goto done; 1010 goto err_free_wdev;
984 } 1011 }
1012
1013 mesh_wdev->iftype = NL80211_IFTYPE_MESH_POINT;
1014 mesh_wdev->wiphy = priv->wdev->wiphy;
1015 mesh_wdev->netdev = mesh_dev;
1016
985 mesh_dev->ml_priv = priv; 1017 mesh_dev->ml_priv = priv;
1018 mesh_dev->ieee80211_ptr = mesh_wdev;
986 priv->mesh_dev = mesh_dev; 1019 priv->mesh_dev = mesh_dev;
987 1020
988 mesh_dev->netdev_ops = &mesh_netdev_ops; 1021 mesh_dev->netdev_ops = &mesh_netdev_ops;
@@ -996,7 +1029,7 @@ static int lbs_add_mesh(struct lbs_private *priv)
996 ret = register_netdev(mesh_dev); 1029 ret = register_netdev(mesh_dev);
997 if (ret) { 1030 if (ret) {
998 pr_err("cannot register mshX virtual interface\n"); 1031 pr_err("cannot register mshX virtual interface\n");
999 goto err_free; 1032 goto err_free_netdev;
1000 } 1033 }
1001 1034
1002 ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); 1035 ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
@@ -1012,9 +1045,12 @@ static int lbs_add_mesh(struct lbs_private *priv)
1012err_unregister: 1045err_unregister:
1013 unregister_netdev(mesh_dev); 1046 unregister_netdev(mesh_dev);
1014 1047
1015err_free: 1048err_free_netdev:
1016 free_netdev(mesh_dev); 1049 free_netdev(mesh_dev);
1017 1050
1051err_free_wdev:
1052 kfree(mesh_wdev);
1053
1018done: 1054done:
1019 lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); 1055 lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
1020 return ret; 1056 return ret;
@@ -1035,6 +1071,7 @@ void lbs_remove_mesh(struct lbs_private *priv)
1035 lbs_persist_config_remove(mesh_dev); 1071 lbs_persist_config_remove(mesh_dev);
1036 unregister_netdev(mesh_dev); 1072 unregister_netdev(mesh_dev);
1037 priv->mesh_dev = NULL; 1073 priv->mesh_dev = NULL;
1074 kfree(mesh_dev->ieee80211_ptr);
1038 free_netdev(mesh_dev); 1075 free_netdev(mesh_dev);
1039 lbs_deb_leave(LBS_DEB_MESH); 1076 lbs_deb_leave(LBS_DEB_MESH);
1040} 1077}
diff --git a/drivers/net/wireless/libertas/mesh.h b/drivers/net/wireless/libertas/mesh.h
index 50144913f2a..6603f341c87 100644
--- a/drivers/net/wireless/libertas/mesh.h
+++ b/drivers/net/wireless/libertas/mesh.h
@@ -9,30 +9,25 @@
9#include <net/lib80211.h> 9#include <net/lib80211.h>
10 10
11#include "host.h" 11#include "host.h"
12#include "dev.h"
12 13
13#ifdef CONFIG_LIBERTAS_MESH 14#ifdef CONFIG_LIBERTAS_MESH
14 15
15/* Mesh statistics */
16struct lbs_mesh_stats {
17 u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */
18 u32 fwd_unicast_cnt; /* Fwd: Unicast counter */
19 u32 fwd_drop_ttl; /* Fwd: TTL zero */
20 u32 fwd_drop_rbt; /* Fwd: Recently Broadcasted */
21 u32 fwd_drop_noroute; /* Fwd: No route to Destination */
22 u32 fwd_drop_nobuf; /* Fwd: Run out of internal buffers */
23 u32 drop_blind; /* Rx: Dropped by blinding table */
24 u32 tx_failed_cnt; /* Tx: Failed transmissions */
25};
26
27
28struct net_device; 16struct net_device;
29struct lbs_private;
30 17
31int lbs_init_mesh(struct lbs_private *priv); 18int lbs_init_mesh(struct lbs_private *priv);
19void lbs_start_mesh(struct lbs_private *priv);
32int lbs_deinit_mesh(struct lbs_private *priv); 20int lbs_deinit_mesh(struct lbs_private *priv);
33 21
34void lbs_remove_mesh(struct lbs_private *priv); 22void lbs_remove_mesh(struct lbs_private *priv);
35 23
24static inline bool lbs_mesh_activated(struct lbs_private *priv)
25{
26 /* Mesh SSID is only programmed after successful init */
27 return priv->mesh_ssid_len != 0;
28}
29
30int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel);
36 31
37/* Sending / Receiving */ 32/* Sending / Receiving */
38 33
@@ -67,11 +62,13 @@ void lbs_mesh_ethtool_get_strings(struct net_device *dev,
67 62
68#define lbs_init_mesh(priv) 63#define lbs_init_mesh(priv)
69#define lbs_deinit_mesh(priv) 64#define lbs_deinit_mesh(priv)
65#define lbs_start_mesh(priv)
70#define lbs_add_mesh(priv) 66#define lbs_add_mesh(priv)
71#define lbs_remove_mesh(priv) 67#define lbs_remove_mesh(priv)
72#define lbs_mesh_set_dev(priv, dev, rxpd) (dev) 68#define lbs_mesh_set_dev(priv, dev, rxpd) (dev)
73#define lbs_mesh_set_txpd(priv, dev, txpd) 69#define lbs_mesh_set_txpd(priv, dev, txpd)
74#define lbs_mesh_config(priv, enable, chan) 70#define lbs_mesh_set_channel(priv, channel) (0)
71#define lbs_mesh_activated(priv) (false)
75 72
76#endif 73#endif
77 74
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index bfb8898ae51..62e10eeadd7 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -15,6 +15,7 @@
15#include "radiotap.h" 15#include "radiotap.h"
16#include "decl.h" 16#include "decl.h"
17#include "dev.h" 17#include "dev.h"
18#include "mesh.h"
18 19
19struct eth803hdr { 20struct eth803hdr {
20 u8 dest_addr[6]; 21 u8 dest_addr[6];
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index a6e85134cfe..8f127520d78 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -12,6 +12,7 @@
12#include "decl.h" 12#include "decl.h"
13#include "defs.h" 13#include "defs.h"
14#include "dev.h" 14#include "dev.h"
15#include "mesh.h"
15 16
16/** 17/**
17 * convert_radiotap_rate_to_mv - converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE 18 * convert_radiotap_rate_to_mv - converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 031cd89b176..34b79fc91e3 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -612,6 +612,12 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
612 rx_status.freq = data->channel->center_freq; 612 rx_status.freq = data->channel->center_freq;
613 rx_status.band = data->channel->band; 613 rx_status.band = data->channel->band;
614 rx_status.rate_idx = info->control.rates[0].idx; 614 rx_status.rate_idx = info->control.rates[0].idx;
615 if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS)
616 rx_status.flag |= RX_FLAG_HT;
617 if (info->control.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
618 rx_status.flag |= RX_FLAG_40MHZ;
619 if (info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
620 rx_status.flag |= RX_FLAG_SHORT_GI;
615 /* TODO: simulate real signal strength (and optional packet loss) */ 621 /* TODO: simulate real signal strength (and optional packet loss) */
616 rx_status.signal = data->power_level - 50; 622 rx_status.signal = data->power_level - 50;
617 623
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 352d2c5da1f..6fd53e4e3fe 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -547,7 +547,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
547 sinfo->tx_bytes = priv->stats.tx_bytes; 547 sinfo->tx_bytes = priv->stats.tx_bytes;
548 sinfo->rx_packets = priv->stats.rx_packets; 548 sinfo->rx_packets = priv->stats.rx_packets;
549 sinfo->tx_packets = priv->stats.tx_packets; 549 sinfo->tx_packets = priv->stats.tx_packets;
550 sinfo->signal = priv->w_stats.qual.level; 550 sinfo->signal = priv->qual_level;
551 sinfo->txrate.legacy = rate.rate; 551 sinfo->txrate.legacy = rate.rate;
552 552
553 return ret; 553 return ret;
@@ -793,139 +793,6 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
793} 793}
794 794
795/* 795/*
796 * This function informs the CFG802.11 subsystem of a new BSS connection.
797 *
798 * The following information are sent to the CFG802.11 subsystem
799 * to register the new BSS connection. If we do not register the new BSS,
800 * a kernel panic will result.
801 * - MAC address
802 * - Capabilities
803 * - Beacon period
804 * - RSSI value
805 * - Channel
806 * - Supported rates IE
807 * - Extended capabilities IE
808 * - DS parameter set IE
809 * - HT Capability IE
810 * - Vendor Specific IE (221)
811 * - WPA IE
812 * - RSN IE
813 */
814static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
815 struct mwifiex_802_11_ssid *ssid)
816{
817 struct mwifiex_bssdescriptor *scan_table;
818 int i, j;
819 struct ieee80211_channel *chan;
820 u8 *ie, *ie_buf;
821 u32 ie_len;
822 u8 *beacon;
823 int beacon_size;
824 u8 element_id, element_len;
825
826#define MAX_IE_BUF 2048
827 ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL);
828 if (!ie_buf) {
829 dev_err(priv->adapter->dev, "%s: failed to alloc ie_buf\n",
830 __func__);
831 return -ENOMEM;
832 }
833
834 scan_table = priv->adapter->scan_table;
835 for (i = 0; i < priv->adapter->num_in_scan_table; i++) {
836 if (ssid) {
837 /* Inform specific BSS only */
838 if (memcmp(ssid->ssid, scan_table[i].ssid.ssid,
839 ssid->ssid_len))
840 continue;
841 }
842 memset(ie_buf, 0, MAX_IE_BUF);
843 ie_buf[0] = WLAN_EID_SSID;
844 ie_buf[1] = scan_table[i].ssid.ssid_len;
845 memcpy(&ie_buf[sizeof(struct ieee_types_header)],
846 scan_table[i].ssid.ssid, ie_buf[1]);
847
848 ie = ie_buf + ie_buf[1] + sizeof(struct ieee_types_header);
849 ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
850
851 ie[0] = WLAN_EID_SUPP_RATES;
852
853 for (j = 0; j < sizeof(scan_table[i].supported_rates); j++) {
854 if (!scan_table[i].supported_rates[j])
855 break;
856 else
857 ie[j + sizeof(struct ieee_types_header)] =
858 scan_table[i].supported_rates[j];
859 }
860
861 ie[1] = j;
862 ie_len += ie[1] + sizeof(struct ieee_types_header);
863
864 beacon = scan_table[i].beacon_buf;
865 beacon_size = scan_table[i].beacon_buf_size;
866
867 /* Skip time stamp, beacon interval and capability */
868
869 if (beacon) {
870 beacon += sizeof(scan_table[i].beacon_period)
871 + sizeof(scan_table[i].time_stamp) +
872 +sizeof(scan_table[i].cap_info_bitmap);
873
874 beacon_size -= sizeof(scan_table[i].beacon_period)
875 + sizeof(scan_table[i].time_stamp)
876 + sizeof(scan_table[i].cap_info_bitmap);
877 }
878
879 while (beacon_size >= sizeof(struct ieee_types_header)) {
880 ie = ie_buf + ie_len;
881 element_id = *beacon;
882 element_len = *(beacon + 1);
883 if (beacon_size < (int) element_len +
884 sizeof(struct ieee_types_header)) {
885 dev_err(priv->adapter->dev, "%s: in processing"
886 " IE, bytes left < IE length\n",
887 __func__);
888 break;
889 }
890 switch (element_id) {
891 case WLAN_EID_EXT_CAPABILITY:
892 case WLAN_EID_DS_PARAMS:
893 case WLAN_EID_HT_CAPABILITY:
894 case WLAN_EID_VENDOR_SPECIFIC:
895 case WLAN_EID_RSN:
896 case WLAN_EID_BSS_AC_ACCESS_DELAY:
897 ie[0] = element_id;
898 ie[1] = element_len;
899 memcpy(&ie[sizeof(struct ieee_types_header)],
900 (u8 *) beacon
901 + sizeof(struct ieee_types_header),
902 element_len);
903 ie_len += ie[1] +
904 sizeof(struct ieee_types_header);
905 break;
906 default:
907 break;
908 }
909 beacon += element_len +
910 sizeof(struct ieee_types_header);
911 beacon_size -= element_len +
912 sizeof(struct ieee_types_header);
913 }
914 chan = ieee80211_get_channel(priv->wdev->wiphy,
915 scan_table[i].freq);
916 cfg80211_inform_bss(priv->wdev->wiphy, chan,
917 scan_table[i].mac_address,
918 0, scan_table[i].cap_info_bitmap,
919 scan_table[i].beacon_period,
920 ie_buf, ie_len,
921 scan_table[i].rssi, GFP_KERNEL);
922 }
923
924 kfree(ie_buf);
925 return 0;
926}
927
928/*
929 * This function connects with a BSS. 796 * This function connects with a BSS.
930 * 797 *
931 * This function handles both Infra and Ad-Hoc modes. It also performs 798 * This function handles both Infra and Ad-Hoc modes. It also performs
@@ -937,8 +804,7 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
937 * For Infra mode, the function returns failure if the specified SSID 804 * For Infra mode, the function returns failure if the specified SSID
938 * is not found in scan table. However, for Ad-Hoc mode, it can create 805 * is not found in scan table. However, for Ad-Hoc mode, it can create
939 * the IBSS if it does not exist. On successful completion in either case, 806 * the IBSS if it does not exist. On successful completion in either case,
940 * the function notifies the CFG802.11 subsystem of the new BSS connection, 807 * the function notifies the CFG802.11 subsystem of the new BSS connection.
941 * otherwise the kernel will panic.
942 */ 808 */
943static int 809static int
944mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, 810mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
@@ -946,11 +812,11 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
946 struct cfg80211_connect_params *sme, bool privacy) 812 struct cfg80211_connect_params *sme, bool privacy)
947{ 813{
948 struct mwifiex_802_11_ssid req_ssid; 814 struct mwifiex_802_11_ssid req_ssid;
949 struct mwifiex_ssid_bssid ssid_bssid;
950 int ret, auth_type = 0; 815 int ret, auth_type = 0;
816 struct cfg80211_bss *bss = NULL;
817 u8 is_scanning_required = 0;
951 818
952 memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid)); 819 memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid));
953 memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
954 820
955 req_ssid.ssid_len = ssid_len; 821 req_ssid.ssid_len = ssid_len;
956 if (ssid_len > IEEE80211_MAX_SSID_LEN) { 822 if (ssid_len > IEEE80211_MAX_SSID_LEN) {
@@ -1028,30 +894,48 @@ done:
1028 return -EFAULT; 894 return -EFAULT;
1029 } 895 }
1030 896
897 /*
898 * Scan entries are valid for some time (15 sec). So we can save one
899 * active scan time if we just try cfg80211_get_bss first. If it fails
900 * then request scan and cfg80211_get_bss() again for final output.
901 */
902 while (1) {
903 if (is_scanning_required) {
904 /* Do specific SSID scanning */
905 if (mwifiex_request_scan(priv, &req_ssid)) {
906 dev_err(priv->adapter->dev, "scan error\n");
907 return -EFAULT;
908 }
909 }
1031 910
1032 memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); 911 /* Find the BSS we want using available scan results */
1033 912 if (mode == NL80211_IFTYPE_ADHOC)
1034 if (mode != NL80211_IFTYPE_ADHOC) { 913 bss = cfg80211_get_bss(priv->wdev->wiphy, channel,
1035 if (mwifiex_find_best_bss(priv, &ssid_bssid)) 914 bssid, ssid, ssid_len,
1036 return -EFAULT; 915 WLAN_CAPABILITY_IBSS,
1037 /* Inform the BSS information to kernel, otherwise 916 WLAN_CAPABILITY_IBSS);
1038 * kernel will give a panic after successful assoc */ 917 else
1039 if (mwifiex_inform_bss_from_scan_result(priv, &req_ssid)) 918 bss = cfg80211_get_bss(priv->wdev->wiphy, channel,
1040 return -EFAULT; 919 bssid, ssid, ssid_len,
920 WLAN_CAPABILITY_ESS,
921 WLAN_CAPABILITY_ESS);
922
923 if (!bss) {
924 if (is_scanning_required) {
925 dev_warn(priv->adapter->dev, "assoc: requested "
926 "bss not found in scan results\n");
927 break;
928 }
929 is_scanning_required = 1;
930 } else {
931 dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n",
932 (char *) req_ssid.ssid, bss->bssid);
933 memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
934 break;
935 }
1041 } 936 }
1042 937
1043 dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n", 938 if (mwifiex_bss_start(priv, bss, &req_ssid))
1044 (char *) req_ssid.ssid, ssid_bssid.bssid);
1045
1046 memcpy(&priv->cfg_bssid, ssid_bssid.bssid, 6);
1047
1048 /* Connect to BSS by ESSID */
1049 memset(&ssid_bssid.bssid, 0, ETH_ALEN);
1050
1051 if (!netif_queue_stopped(priv->netdev))
1052 netif_stop_queue(priv->netdev);
1053
1054 if (mwifiex_bss_start(priv, &ssid_bssid))
1055 return -EFAULT; 939 return -EFAULT;
1056 940
1057 if (mode == NL80211_IFTYPE_ADHOC) { 941 if (mode == NL80211_IFTYPE_ADHOC) {
@@ -1416,13 +1300,8 @@ mwifiex_cfg80211_results(struct work_struct *work)
1416 MWIFIEX_SCAN_TYPE_ACTIVE; 1300 MWIFIEX_SCAN_TYPE_ACTIVE;
1417 scan_req->chan_list[i].scan_time = 0; 1301 scan_req->chan_list[i].scan_time = 0;
1418 } 1302 }
1419 if (mwifiex_set_user_scan_ioctl(priv, scan_req)) { 1303 if (mwifiex_set_user_scan_ioctl(priv, scan_req))
1420 ret = -EFAULT; 1304 ret = -EFAULT;
1421 goto done;
1422 }
1423 if (mwifiex_inform_bss_from_scan_result(priv, NULL))
1424 ret = -EFAULT;
1425done:
1426 priv->scan_result_status = ret; 1305 priv->scan_result_status = ret;
1427 dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n", 1306 dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n",
1428 __func__); 1307 __func__);
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 4fee0993b18..f23ec72ed4f 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -821,6 +821,14 @@ struct host_cmd_ds_txpwr_cfg {
821 __le32 mode; 821 __le32 mode;
822} __packed; 822} __packed;
823 823
824struct mwifiex_bcn_param {
825 u8 bssid[ETH_ALEN];
826 u8 rssi;
827 __le32 timestamp[2];
828 __le16 beacon_period;
829 __le16 cap_info_bitmap;
830} __packed;
831
824#define MWIFIEX_USER_SCAN_CHAN_MAX 50 832#define MWIFIEX_USER_SCAN_CHAN_MAX 50
825 833
826#define MWIFIEX_MAX_SSID_LIST_LENGTH 10 834#define MWIFIEX_MAX_SSID_LIST_LENGTH 10
@@ -862,13 +870,6 @@ struct mwifiex_user_scan_ssid {
862 870
863struct mwifiex_user_scan_cfg { 871struct mwifiex_user_scan_cfg {
864 /* 872 /*
865 * Flag set to keep the previous scan table intact
866 *
867 * If set, the scan results will accumulate, replacing any previous
868 * matched entries for a BSS with the new scan data
869 */
870 u8 keep_previous_scan;
871 /*
872 * BSS mode to be sent in the firmware command 873 * BSS mode to be sent in the firmware command
873 */ 874 */
874 u8 bss_mode; 875 u8 bss_mode;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 3f1559e6132..26e685a31bc 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -152,19 +152,6 @@ static int mwifiex_init_priv(struct mwifiex_private *priv)
152static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter) 152static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
153{ 153{
154 int ret; 154 int ret;
155 u32 buf_size;
156 struct mwifiex_bssdescriptor *temp_scan_table;
157
158 /* Allocate buffer to store the BSSID list */
159 buf_size = sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP;
160 temp_scan_table = kzalloc(buf_size, GFP_KERNEL);
161 if (!temp_scan_table) {
162 dev_err(adapter->dev, "%s: failed to alloc temp_scan_table\n",
163 __func__);
164 return -ENOMEM;
165 }
166
167 adapter->scan_table = temp_scan_table;
168 155
169 /* Allocate command buffer */ 156 /* Allocate command buffer */
170 ret = mwifiex_alloc_cmd_buffer(adapter); 157 ret = mwifiex_alloc_cmd_buffer(adapter);
@@ -222,14 +209,8 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
222 adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME; 209 adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME;
223 adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME; 210 adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME;
224 211
225 adapter->num_in_scan_table = 0;
226 memset(adapter->scan_table, 0,
227 (sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP));
228 adapter->scan_probes = 1; 212 adapter->scan_probes = 1;
229 213
230 memset(adapter->bcn_buf, 0, sizeof(adapter->bcn_buf));
231 adapter->bcn_buf_end = adapter->bcn_buf;
232
233 adapter->multiple_dtim = 1; 214 adapter->multiple_dtim = 1;
234 215
235 adapter->local_listen_interval = 0; /* default value in firmware 216 adapter->local_listen_interval = 0; /* default value in firmware
@@ -326,8 +307,6 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter)
326 del_timer(&adapter->cmd_timer); 307 del_timer(&adapter->cmd_timer);
327 308
328 dev_dbg(adapter->dev, "info: free scan table\n"); 309 dev_dbg(adapter->dev, "info: free scan table\n");
329 kfree(adapter->scan_table);
330 adapter->scan_table = NULL;
331 310
332 adapter->if_ops.cleanup_if(adapter); 311 adapter->if_ops.cleanup_if(adapter);
333 312
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index f6bcc868562..e0b68e7c8ca 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -134,7 +134,6 @@ struct mwifiex_ver_ext {
134struct mwifiex_bss_info { 134struct mwifiex_bss_info {
135 u32 bss_mode; 135 u32 bss_mode;
136 struct mwifiex_802_11_ssid ssid; 136 struct mwifiex_802_11_ssid ssid;
137 u32 scan_table_idx;
138 u32 bss_chan; 137 u32 bss_chan;
139 u32 region_code; 138 u32 region_code;
140 u32 media_connected; 139 u32 media_connected;
@@ -307,10 +306,12 @@ struct mwifiex_ds_read_eeprom {
307 u8 value[MAX_EEPROM_DATA]; 306 u8 value[MAX_EEPROM_DATA];
308}; 307};
309 308
309#define IEEE_MAX_IE_SIZE 256
310
310struct mwifiex_ds_misc_gen_ie { 311struct mwifiex_ds_misc_gen_ie {
311 u32 type; 312 u32 type;
312 u32 len; 313 u32 len;
313 u8 ie_data[IW_CUSTOM_MAX]; 314 u8 ie_data[IEEE_MAX_IE_SIZE];
314}; 315};
315 316
316struct mwifiex_ds_misc_cmd { 317struct mwifiex_ds_misc_cmd {
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 644e2e405cb..5cdad92277f 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -224,32 +224,6 @@ mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv,
224} 224}
225 225
226/* 226/*
227 * This function updates the scan entry TSF timestamps to reflect
228 * a new association.
229 */
230static void
231mwifiex_update_tsf_timestamps(struct mwifiex_private *priv,
232 struct mwifiex_bssdescriptor *new_bss_desc)
233{
234 struct mwifiex_adapter *adapter = priv->adapter;
235 u32 table_idx;
236 long long new_tsf_base;
237 signed long long tsf_delta;
238
239 memcpy(&new_tsf_base, new_bss_desc->time_stamp, sizeof(new_tsf_base));
240
241 tsf_delta = new_tsf_base - new_bss_desc->network_tsf;
242
243 dev_dbg(adapter->dev, "info: TSF: update TSF timestamps, "
244 "0x%016llx -> 0x%016llx\n",
245 new_bss_desc->network_tsf, new_tsf_base);
246
247 for (table_idx = 0; table_idx < adapter->num_in_scan_table;
248 table_idx++)
249 adapter->scan_table[table_idx].network_tsf += tsf_delta;
250}
251
252/*
253 * This function appends a WAPI IE. 227 * This function appends a WAPI IE.
254 * 228 *
255 * This function is called from the network join command preparation routine. 229 * This function is called from the network join command preparation routine.
@@ -639,12 +613,6 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
639 613
640 priv->curr_bss_params.band = (u8) bss_desc->bss_band; 614 priv->curr_bss_params.band = (u8) bss_desc->bss_band;
641 615
642 /*
643 * Adjust the timestamps in the scan table to be relative to the newly
644 * associated AP's TSF
645 */
646 mwifiex_update_tsf_timestamps(priv, bss_desc);
647
648 if (bss_desc->wmm_ie.vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) 616 if (bss_desc->wmm_ie.vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC)
649 priv->curr_bss_params.wmm_enabled = true; 617 priv->curr_bss_params.wmm_enabled = true;
650 else 618 else
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 0415e3d1c31..48b4d95219f 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -849,6 +849,7 @@ mwifiex_add_card(void *card, struct semaphore *sem,
849{ 849{
850 int i; 850 int i;
851 struct mwifiex_adapter *adapter; 851 struct mwifiex_adapter *adapter;
852 char fmt[64];
852 853
853 if (down_interruptible(sem)) 854 if (down_interruptible(sem))
854 goto exit_sem_err; 855 goto exit_sem_err;
@@ -897,6 +898,9 @@ mwifiex_add_card(void *card, struct semaphore *sem,
897 898
898 up(sem); 899 up(sem);
899 900
901 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
902 dev_notice(adapter->dev, "driver_version = %s\n", fmt);
903
900 return 0; 904 return 0;
901 905
902err_add_intf: 906err_add_intf:
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 2215c3c9735..e6b6c0cfb63 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -54,6 +54,8 @@ struct mwifiex_drv_mode {
54}; 54};
55 55
56 56
57#define MWIFIEX_MAX_AP 64
58
57#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ) 59#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ)
58 60
59#define MWIFIEX_TIMER_10S 10000 61#define MWIFIEX_TIMER_10S 10000
@@ -227,27 +229,10 @@ struct ieee_types_header {
227 u8 len; 229 u8 len;
228} __packed; 230} __packed;
229 231
230struct ieee_obss_scan_param {
231 u16 obss_scan_passive_dwell;
232 u16 obss_scan_active_dwell;
233 u16 bss_chan_width_trigger_scan_int;
234 u16 obss_scan_passive_total;
235 u16 obss_scan_active_total;
236 u16 bss_width_chan_trans_delay;
237 u16 obss_scan_active_threshold;
238} __packed;
239
240struct ieee_types_obss_scan_param {
241 struct ieee_types_header ieee_hdr;
242 struct ieee_obss_scan_param obss_scan;
243} __packed;
244
245#define MWIFIEX_SUPPORTED_RATES 14 232#define MWIFIEX_SUPPORTED_RATES 14
246 233
247#define MWIFIEX_SUPPORTED_RATES_EXT 32 234#define MWIFIEX_SUPPORTED_RATES_EXT 32
248 235
249#define IEEE_MAX_IE_SIZE 256
250
251struct ieee_types_vendor_specific { 236struct ieee_types_vendor_specific {
252 struct ieee_types_vendor_header vend_hdr; 237 struct ieee_types_vendor_header vend_hdr;
253 u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_vendor_header)]; 238 u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_vendor_header)];
@@ -291,8 +276,6 @@ struct mwifiex_bssdescriptor {
291 u16 bss_co_2040_offset; 276 u16 bss_co_2040_offset;
292 u8 *bcn_ext_cap; 277 u8 *bcn_ext_cap;
293 u16 ext_cap_offset; 278 u16 ext_cap_offset;
294 struct ieee_types_obss_scan_param *bcn_obss_scan;
295 u16 overlap_bss_offset;
296 struct ieee_types_vendor_specific *bcn_wpa_ie; 279 struct ieee_types_vendor_specific *bcn_wpa_ie;
297 u16 wpa_offset; 280 u16 wpa_offset;
298 struct ieee_types_generic *bcn_rsn_ie; 281 struct ieee_types_generic *bcn_rsn_ie;
@@ -301,8 +284,6 @@ struct mwifiex_bssdescriptor {
301 u16 wapi_offset; 284 u16 wapi_offset;
302 u8 *beacon_buf; 285 u8 *beacon_buf;
303 u32 beacon_buf_size; 286 u32 beacon_buf_size;
304 u32 beacon_buf_size_max;
305
306}; 287};
307 288
308struct mwifiex_current_bss_params { 289struct mwifiex_current_bss_params {
@@ -468,7 +449,7 @@ struct mwifiex_private {
468 struct dentry *dfs_dev_dir; 449 struct dentry *dfs_dev_dir;
469#endif 450#endif
470 u8 nick_name[16]; 451 u8 nick_name[16];
471 struct iw_statistics w_stats; 452 u8 qual_level, qual_noise;
472 u16 current_key_index; 453 u16 current_key_index;
473 struct semaphore async_sem; 454 struct semaphore async_sem;
474 u8 scan_pending_on_block; 455 u8 scan_pending_on_block;
@@ -624,15 +605,11 @@ struct mwifiex_adapter {
624 u32 scan_processing; 605 u32 scan_processing;
625 u16 region_code; 606 u16 region_code;
626 struct mwifiex_802_11d_domain_reg domain_reg; 607 struct mwifiex_802_11d_domain_reg domain_reg;
627 struct mwifiex_bssdescriptor *scan_table;
628 u32 num_in_scan_table;
629 u16 scan_probes; 608 u16 scan_probes;
630 u32 scan_mode; 609 u32 scan_mode;
631 u16 specific_scan_time; 610 u16 specific_scan_time;
632 u16 active_scan_time; 611 u16 active_scan_time;
633 u16 passive_scan_time; 612 u16 passive_scan_time;
634 u8 bcn_buf[MAX_SCAN_BEACON_BUFFER];
635 u8 *bcn_buf_end;
636 u8 fw_bands; 613 u8 fw_bands;
637 u8 adhoc_start_band; 614 u8 adhoc_start_band;
638 u8 config_bands; 615 u8 config_bands;
@@ -765,13 +742,6 @@ void mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
765 struct cmd_ctrl_node *cmd_node); 742 struct cmd_ctrl_node *cmd_node);
766int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, 743int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
767 struct host_cmd_ds_command *resp); 744 struct host_cmd_ds_command *resp);
768s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv,
769 struct mwifiex_802_11_ssid *ssid, u8 *bssid,
770 u32 mode);
771s32 mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid,
772 u32 mode);
773int mwifiex_find_best_network(struct mwifiex_private *priv,
774 struct mwifiex_ssid_bssid *req_ssid_bssid);
775s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, 745s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
776 struct mwifiex_802_11_ssid *ssid2); 746 struct mwifiex_802_11_ssid *ssid2);
777int mwifiex_associate(struct mwifiex_private *priv, 747int mwifiex_associate(struct mwifiex_private *priv,
@@ -782,7 +752,6 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
782int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, 752int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
783 struct host_cmd_ds_command *resp); 753 struct host_cmd_ds_command *resp);
784void mwifiex_reset_connect_state(struct mwifiex_private *priv); 754void mwifiex_reset_connect_state(struct mwifiex_private *priv);
785void mwifiex_2040_coex_event(struct mwifiex_private *priv);
786u8 mwifiex_band_to_radio_type(u8 band); 755u8 mwifiex_band_to_radio_type(u8 band);
787int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); 756int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
788int mwifiex_adhoc_start(struct mwifiex_private *priv, 757int mwifiex_adhoc_start(struct mwifiex_private *priv,
@@ -922,8 +891,8 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
922int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, 891int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
923 struct net_device *dev); 892 struct net_device *dev);
924int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); 893int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter);
925int mwifiex_bss_start(struct mwifiex_private *priv, 894int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
926 struct mwifiex_ssid_bssid *ssid_bssid); 895 struct mwifiex_802_11_ssid *req_ssid);
927int mwifiex_set_hs_params(struct mwifiex_private *priv, 896int mwifiex_set_hs_params(struct mwifiex_private *priv,
928 u16 action, int cmd_type, 897 u16 action, int cmd_type,
929 struct mwifiex_ds_hs_cfg *hscfg); 898 struct mwifiex_ds_hs_cfg *hscfg);
@@ -934,8 +903,6 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv,
934 struct mwifiex_ds_get_signal *signal); 903 struct mwifiex_ds_get_signal *signal);
935int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, 904int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
936 struct mwifiex_rate_cfg *rate); 905 struct mwifiex_rate_cfg *rate);
937int mwifiex_find_best_bss(struct mwifiex_private *priv,
938 struct mwifiex_ssid_bssid *ssid_bssid);
939int mwifiex_request_scan(struct mwifiex_private *priv, 906int mwifiex_request_scan(struct mwifiex_private *priv,
940 struct mwifiex_802_11_ssid *req_ssid); 907 struct mwifiex_802_11_ssid *req_ssid);
941int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, 908int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
@@ -984,12 +951,20 @@ int mwifiex_main_process(struct mwifiex_adapter *);
984 951
985int mwifiex_bss_set_channel(struct mwifiex_private *, 952int mwifiex_bss_set_channel(struct mwifiex_private *,
986 struct mwifiex_chan_freq_power *cfp); 953 struct mwifiex_chan_freq_power *cfp);
987int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *,
988 struct mwifiex_ssid_bssid *);
989int mwifiex_set_radio_band_cfg(struct mwifiex_private *, 954int mwifiex_set_radio_band_cfg(struct mwifiex_private *,
990 struct mwifiex_ds_band_cfg *); 955 struct mwifiex_ds_band_cfg *);
991int mwifiex_get_bss_info(struct mwifiex_private *, 956int mwifiex_get_bss_info(struct mwifiex_private *,
992 struct mwifiex_bss_info *); 957 struct mwifiex_bss_info *);
958int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
959 u8 *bssid, s32 rssi, u8 *ie_buf,
960 size_t ie_len, u16 beacon_period,
961 u16 cap_info_bitmap,
962 struct mwifiex_bssdescriptor *bss_desc);
963int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
964 struct mwifiex_bssdescriptor *bss_entry,
965 u8 *ie_buf, u32 ie_len);
966int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
967 struct mwifiex_bssdescriptor *bss_desc);
993 968
994#ifdef CONFIG_DEBUG_FS 969#ifdef CONFIG_DEBUG_FS
995void mwifiex_debugfs_init(void); 970void mwifiex_debugfs_init(void);
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 6f88c8ab5de..b28241c6e73 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -172,36 +172,6 @@ mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
172} 172}
173 173
174/* 174/*
175 * Sends IOCTL request to get the best BSS.
176 *
177 * This function allocates the IOCTL request buffer, fills it
178 * with requisite parameters and calls the IOCTL handler.
179 */
180int mwifiex_find_best_bss(struct mwifiex_private *priv,
181 struct mwifiex_ssid_bssid *ssid_bssid)
182{
183 struct mwifiex_ssid_bssid tmp_ssid_bssid;
184 u8 *mac;
185
186 if (!ssid_bssid)
187 return -1;
188
189 memcpy(&tmp_ssid_bssid, ssid_bssid,
190 sizeof(struct mwifiex_ssid_bssid));
191
192 if (!mwifiex_bss_ioctl_find_bss(priv, &tmp_ssid_bssid)) {
193 memcpy(ssid_bssid, &tmp_ssid_bssid,
194 sizeof(struct mwifiex_ssid_bssid));
195 mac = (u8 *) &ssid_bssid->bssid;
196 dev_dbg(priv->adapter->dev, "cmd: found network: ssid=%s,"
197 " %pM\n", ssid_bssid->ssid.ssid, mac);
198 return 0;
199 }
200
201 return -1;
202}
203
204/*
205 * Sends IOCTL request to start a scan with user configurations. 175 * Sends IOCTL request to start a scan with user configurations.
206 * 176 *
207 * This function allocates the IOCTL request buffer, fills it 177 * This function allocates the IOCTL request buffer, fills it
@@ -286,8 +256,7 @@ mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv,
286 */ 256 */
287static bool 257static bool
288mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, 258mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
289 struct mwifiex_bssdescriptor *bss_desc, 259 struct mwifiex_bssdescriptor *bss_desc)
290 int index)
291{ 260{
292 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED 261 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
293 && priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled 262 && priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
@@ -298,9 +267,9 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
298 * LinkSys WRT54G && bss_desc->privacy 267 * LinkSys WRT54G && bss_desc->privacy
299 */ 268 */
300 ) { 269 ) {
301 dev_dbg(priv->adapter->dev, "info: %s: WPA: index=%d" 270 dev_dbg(priv->adapter->dev, "info: %s: WPA:"
302 " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " 271 " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
303 "EncMode=%#x privacy=%#x\n", __func__, index, 272 "EncMode=%#x privacy=%#x\n", __func__,
304 (bss_desc->bcn_wpa_ie) ? 273 (bss_desc->bcn_wpa_ie) ?
305 (*(bss_desc->bcn_wpa_ie)). 274 (*(bss_desc->bcn_wpa_ie)).
306 vend_hdr.element_id : 0, 275 vend_hdr.element_id : 0,
@@ -324,8 +293,7 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
324 */ 293 */
325static bool 294static bool
326mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, 295mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
327 struct mwifiex_bssdescriptor *bss_desc, 296 struct mwifiex_bssdescriptor *bss_desc)
328 int index)
329{ 297{
330 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED 298 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
331 && !priv->sec_info.wpa_enabled && priv->sec_info.wpa2_enabled 299 && !priv->sec_info.wpa_enabled && priv->sec_info.wpa2_enabled
@@ -336,9 +304,9 @@ mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
336 * LinkSys WRT54G && bss_desc->privacy 304 * LinkSys WRT54G && bss_desc->privacy
337 */ 305 */
338 ) { 306 ) {
339 dev_dbg(priv->adapter->dev, "info: %s: WPA2: index=%d" 307 dev_dbg(priv->adapter->dev, "info: %s: WPA2: "
340 " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " 308 " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
341 "EncMode=%#x privacy=%#x\n", __func__, index, 309 "EncMode=%#x privacy=%#x\n", __func__,
342 (bss_desc->bcn_wpa_ie) ? 310 (bss_desc->bcn_wpa_ie) ?
343 (*(bss_desc->bcn_wpa_ie)). 311 (*(bss_desc->bcn_wpa_ie)).
344 vend_hdr.element_id : 0, 312 vend_hdr.element_id : 0,
@@ -383,8 +351,7 @@ mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv,
383 */ 351 */
384static bool 352static bool
385mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv, 353mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv,
386 struct mwifiex_bssdescriptor *bss_desc, 354 struct mwifiex_bssdescriptor *bss_desc)
387 int index)
388{ 355{
389 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED 356 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
390 && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled 357 && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
@@ -395,9 +362,9 @@ mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv,
395 && priv->sec_info.encryption_mode 362 && priv->sec_info.encryption_mode
396 && bss_desc->privacy) { 363 && bss_desc->privacy) {
397 dev_dbg(priv->adapter->dev, "info: %s: dynamic " 364 dev_dbg(priv->adapter->dev, "info: %s: dynamic "
398 "WEP: index=%d wpa_ie=%#x wpa2_ie=%#x " 365 "WEP: wpa_ie=%#x wpa2_ie=%#x "
399 "EncMode=%#x privacy=%#x\n", 366 "EncMode=%#x privacy=%#x\n",
400 __func__, index, 367 __func__,
401 (bss_desc->bcn_wpa_ie) ? 368 (bss_desc->bcn_wpa_ie) ?
402 (*(bss_desc->bcn_wpa_ie)). 369 (*(bss_desc->bcn_wpa_ie)).
403 vend_hdr.element_id : 0, 370 vend_hdr.element_id : 0,
@@ -430,42 +397,41 @@ mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv,
430 * Compatibility is not matched while roaming, except for mode. 397 * Compatibility is not matched while roaming, except for mode.
431 */ 398 */
432static s32 399static s32
433mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode) 400mwifiex_is_network_compatible(struct mwifiex_private *priv,
401 struct mwifiex_bssdescriptor *bss_desc, u32 mode)
434{ 402{
435 struct mwifiex_adapter *adapter = priv->adapter; 403 struct mwifiex_adapter *adapter = priv->adapter;
436 struct mwifiex_bssdescriptor *bss_desc;
437 404
438 bss_desc = &adapter->scan_table[index];
439 bss_desc->disable_11n = false; 405 bss_desc->disable_11n = false;
440 406
441 /* Don't check for compatibility if roaming */ 407 /* Don't check for compatibility if roaming */
442 if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION) 408 if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION)
443 && (bss_desc->bss_mode == NL80211_IFTYPE_STATION)) 409 && (bss_desc->bss_mode == NL80211_IFTYPE_STATION))
444 return index; 410 return 0;
445 411
446 if (priv->wps.session_enable) { 412 if (priv->wps.session_enable) {
447 dev_dbg(adapter->dev, 413 dev_dbg(adapter->dev,
448 "info: return success directly in WPS period\n"); 414 "info: return success directly in WPS period\n");
449 return index; 415 return 0;
450 } 416 }
451 417
452 if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) { 418 if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) {
453 dev_dbg(adapter->dev, "info: return success for WAPI AP\n"); 419 dev_dbg(adapter->dev, "info: return success for WAPI AP\n");
454 return index; 420 return 0;
455 } 421 }
456 422
457 if (bss_desc->bss_mode == mode) { 423 if (bss_desc->bss_mode == mode) {
458 if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) { 424 if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) {
459 /* No security */ 425 /* No security */
460 return index; 426 return 0;
461 } else if (mwifiex_is_network_compatible_for_static_wep(priv, 427 } else if (mwifiex_is_network_compatible_for_static_wep(priv,
462 bss_desc)) { 428 bss_desc)) {
463 /* Static WEP enabled */ 429 /* Static WEP enabled */
464 dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n"); 430 dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n");
465 bss_desc->disable_11n = true; 431 bss_desc->disable_11n = true;
466 return index; 432 return 0;
467 } else if (mwifiex_is_network_compatible_for_wpa(priv, bss_desc, 433 } else if (mwifiex_is_network_compatible_for_wpa(priv,
468 index)) { 434 bss_desc)) {
469 /* WPA enabled */ 435 /* WPA enabled */
470 if (((priv->adapter->config_bands & BAND_GN 436 if (((priv->adapter->config_bands & BAND_GN
471 || priv->adapter->config_bands & BAND_AN) 437 || priv->adapter->config_bands & BAND_AN)
@@ -483,9 +449,9 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode)
483 return -1; 449 return -1;
484 } 450 }
485 } 451 }
486 return index; 452 return 0;
487 } else if (mwifiex_is_network_compatible_for_wpa2(priv, 453 } else if (mwifiex_is_network_compatible_for_wpa2(priv,
488 bss_desc, index)) { 454 bss_desc)) {
489 /* WPA2 enabled */ 455 /* WPA2 enabled */
490 if (((priv->adapter->config_bands & BAND_GN 456 if (((priv->adapter->config_bands & BAND_GN
491 || priv->adapter->config_bands & BAND_AN) 457 || priv->adapter->config_bands & BAND_AN)
@@ -503,22 +469,22 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode)
503 return -1; 469 return -1;
504 } 470 }
505 } 471 }
506 return index; 472 return 0;
507 } else if (mwifiex_is_network_compatible_for_adhoc_aes(priv, 473 } else if (mwifiex_is_network_compatible_for_adhoc_aes(priv,
508 bss_desc)) { 474 bss_desc)) {
509 /* Ad-hoc AES enabled */ 475 /* Ad-hoc AES enabled */
510 return index; 476 return 0;
511 } else if (mwifiex_is_network_compatible_for_dynamic_wep(priv, 477 } else if (mwifiex_is_network_compatible_for_dynamic_wep(priv,
512 bss_desc, index)) { 478 bss_desc)) {
513 /* Dynamic WEP enabled */ 479 /* Dynamic WEP enabled */
514 return index; 480 return 0;
515 } 481 }
516 482
517 /* Security doesn't match */ 483 /* Security doesn't match */
518 dev_dbg(adapter->dev, "info: %s: failed: index=%d " 484 dev_dbg(adapter->dev, "info: %s: failed: "
519 "wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode" 485 "wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode"
520 "=%#x privacy=%#x\n", 486 "=%#x privacy=%#x\n",
521 __func__, index, 487 __func__,
522 (bss_desc->bcn_wpa_ie) ? 488 (bss_desc->bcn_wpa_ie) ?
523 (*(bss_desc->bcn_wpa_ie)).vend_hdr. 489 (*(bss_desc->bcn_wpa_ie)).vend_hdr.
524 element_id : 0, 490 element_id : 0,
@@ -538,52 +504,6 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode)
538} 504}
539 505
540/* 506/*
541 * This function finds the best SSID in the scan list.
542 *
543 * It searches the scan table for the best SSID that also matches the current
544 * adapter network preference (mode, security etc.).
545 */
546static s32
547mwifiex_find_best_network_in_list(struct mwifiex_private *priv)
548{
549 struct mwifiex_adapter *adapter = priv->adapter;
550 u32 mode = priv->bss_mode;
551 s32 best_net = -1;
552 s32 best_rssi = 0;
553 u32 i;
554
555 dev_dbg(adapter->dev, "info: num of BSSIDs = %d\n",
556 adapter->num_in_scan_table);
557
558 for (i = 0; i < adapter->num_in_scan_table; i++) {
559 switch (mode) {
560 case NL80211_IFTYPE_STATION:
561 case NL80211_IFTYPE_ADHOC:
562 if (mwifiex_is_network_compatible(priv, i, mode) >= 0) {
563 if (SCAN_RSSI(adapter->scan_table[i].rssi) >
564 best_rssi) {
565 best_rssi = SCAN_RSSI(adapter->
566 scan_table[i].rssi);
567 best_net = i;
568 }
569 }
570 break;
571 case NL80211_IFTYPE_UNSPECIFIED:
572 default:
573 if (SCAN_RSSI(adapter->scan_table[i].rssi) >
574 best_rssi) {
575 best_rssi = SCAN_RSSI(adapter->scan_table[i].
576 rssi);
577 best_net = i;
578 }
579 break;
580 }
581 }
582
583 return best_net;
584}
585
586/*
587 * This function creates a channel list for the driver to scan, based 507 * This function creates a channel list for the driver to scan, based
588 * on region/band information. 508 * on region/band information.
589 * 509 *
@@ -1161,34 +1081,13 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter,
1161} 1081}
1162 1082
1163/* 1083/*
1164 * This function interprets a BSS scan response returned from the firmware. 1084 * This function parses provided beacon buffer and updates
1165 * 1085 * respective fields in bss descriptor structure.
1166 * The various fixed fields and IEs are parsed and passed back for a BSS
1167 * probe response or beacon from scan command. Information is recorded as
1168 * needed in the scan table for that entry.
1169 *
1170 * The following IE types are recognized and parsed -
1171 * - SSID
1172 * - Supported rates
1173 * - FH parameters set
1174 * - DS parameters set
1175 * - CF parameters set
1176 * - IBSS parameters set
1177 * - ERP information
1178 * - Extended supported rates
1179 * - Vendor specific (221)
1180 * - RSN IE
1181 * - WAPI IE
1182 * - HT capability
1183 * - HT operation
1184 * - BSS Coexistence 20/40
1185 * - Extended capability
1186 * - Overlapping BSS scan parameters
1187 */ 1086 */
1188static int 1087int
1189mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter, 1088mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1190 struct mwifiex_bssdescriptor *bss_entry, 1089 struct mwifiex_bssdescriptor *bss_entry,
1191 u8 **beacon_info, u32 *bytes_left) 1090 u8 *ie_buf, u32 ie_len)
1192{ 1091{
1193 int ret = 0; 1092 int ret = 0;
1194 u8 element_id; 1093 u8 element_id;
@@ -1196,135 +1095,43 @@ mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1196 struct ieee_types_ds_param_set *ds_param_set; 1095 struct ieee_types_ds_param_set *ds_param_set;
1197 struct ieee_types_cf_param_set *cf_param_set; 1096 struct ieee_types_cf_param_set *cf_param_set;
1198 struct ieee_types_ibss_param_set *ibss_param_set; 1097 struct ieee_types_ibss_param_set *ibss_param_set;
1199 __le16 beacon_interval;
1200 __le16 capabilities;
1201 u8 *current_ptr; 1098 u8 *current_ptr;
1202 u8 *rate; 1099 u8 *rate;
1203 u8 element_len; 1100 u8 element_len;
1204 u16 total_ie_len; 1101 u16 total_ie_len;
1205 u8 bytes_to_copy; 1102 u8 bytes_to_copy;
1206 u8 rate_size; 1103 u8 rate_size;
1207 u16 beacon_size;
1208 u8 found_data_rate_ie; 1104 u8 found_data_rate_ie;
1209 u32 bytes_left_for_current_beacon; 1105 u32 bytes_left;
1210 struct ieee_types_vendor_specific *vendor_ie; 1106 struct ieee_types_vendor_specific *vendor_ie;
1211 const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 }; 1107 const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
1212 const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 }; 1108 const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
1213 1109
1214 found_data_rate_ie = false; 1110 found_data_rate_ie = false;
1215 rate_size = 0; 1111 rate_size = 0;
1216 beacon_size = 0; 1112 current_ptr = ie_buf;
1217 1113 bytes_left = ie_len;
1218 if (*bytes_left >= sizeof(beacon_size)) { 1114 bss_entry->beacon_buf = ie_buf;
1219 /* Extract & convert beacon size from the command buffer */ 1115 bss_entry->beacon_buf_size = ie_len;
1220 memcpy(&beacon_size, *beacon_info, sizeof(beacon_size));
1221 *bytes_left -= sizeof(beacon_size);
1222 *beacon_info += sizeof(beacon_size);
1223 }
1224
1225 if (!beacon_size || beacon_size > *bytes_left) {
1226 *beacon_info += *bytes_left;
1227 *bytes_left = 0;
1228 return -1;
1229 }
1230
1231 /* Initialize the current working beacon pointer for this BSS
1232 iteration */
1233 current_ptr = *beacon_info;
1234
1235 /* Advance the return beacon pointer past the current beacon */
1236 *beacon_info += beacon_size;
1237 *bytes_left -= beacon_size;
1238
1239 bytes_left_for_current_beacon = beacon_size;
1240
1241 memcpy(bss_entry->mac_address, current_ptr, ETH_ALEN);
1242 dev_dbg(adapter->dev, "info: InterpretIE: AP MAC Addr: %pM\n",
1243 bss_entry->mac_address);
1244
1245 current_ptr += ETH_ALEN;
1246 bytes_left_for_current_beacon -= ETH_ALEN;
1247
1248 if (bytes_left_for_current_beacon < 12) {
1249 dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
1250 return -1;
1251 }
1252
1253 /*
1254 * Next 4 fields are RSSI, time stamp, beacon interval,
1255 * and capability information
1256 */
1257
1258 /* RSSI is 1 byte long */
1259 bss_entry->rssi = (s32) (*current_ptr);
1260 dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", *current_ptr);
1261 current_ptr += 1;
1262 bytes_left_for_current_beacon -= 1;
1263
1264 /*
1265 * The RSSI is not part of the beacon/probe response. After we have
1266 * advanced current_ptr past the RSSI field, save the remaining
1267 * data for use at the application layer
1268 */
1269 bss_entry->beacon_buf = current_ptr;
1270 bss_entry->beacon_buf_size = bytes_left_for_current_beacon;
1271
1272 /* Time stamp is 8 bytes long */
1273 memcpy(bss_entry->time_stamp, current_ptr, 8);
1274 current_ptr += 8;
1275 bytes_left_for_current_beacon -= 8;
1276
1277 /* Beacon interval is 2 bytes long */
1278 memcpy(&beacon_interval, current_ptr, 2);
1279 bss_entry->beacon_period = le16_to_cpu(beacon_interval);
1280 current_ptr += 2;
1281 bytes_left_for_current_beacon -= 2;
1282
1283 /* Capability information is 2 bytes long */
1284 memcpy(&capabilities, current_ptr, 2);
1285 dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
1286 capabilities);
1287 bss_entry->cap_info_bitmap = le16_to_cpu(capabilities);
1288 current_ptr += 2;
1289 bytes_left_for_current_beacon -= 2;
1290
1291 /* Rest of the current buffer are IE's */
1292 dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP = %d\n",
1293 bytes_left_for_current_beacon);
1294
1295 if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) {
1296 dev_dbg(adapter->dev, "info: InterpretIE: AP WEP enabled\n");
1297 bss_entry->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
1298 } else {
1299 bss_entry->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
1300 }
1301
1302 if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_IBSS)
1303 bss_entry->bss_mode = NL80211_IFTYPE_ADHOC;
1304 else
1305 bss_entry->bss_mode = NL80211_IFTYPE_STATION;
1306
1307 1116
1308 /* Process variable IE */ 1117 /* Process variable IE */
1309 while (bytes_left_for_current_beacon >= 2) { 1118 while (bytes_left >= 2) {
1310 element_id = *current_ptr; 1119 element_id = *current_ptr;
1311 element_len = *(current_ptr + 1); 1120 element_len = *(current_ptr + 1);
1312 total_ie_len = element_len + sizeof(struct ieee_types_header); 1121 total_ie_len = element_len + sizeof(struct ieee_types_header);
1313 1122
1314 if (bytes_left_for_current_beacon < total_ie_len) { 1123 if (bytes_left < total_ie_len) {
1315 dev_err(adapter->dev, "err: InterpretIE: in processing" 1124 dev_err(adapter->dev, "err: InterpretIE: in processing"
1316 " IE, bytes left < IE length\n"); 1125 " IE, bytes left < IE length\n");
1317 bytes_left_for_current_beacon = 0; 1126 return -1;
1318 ret = -1;
1319 continue;
1320 } 1127 }
1321 switch (element_id) { 1128 switch (element_id) {
1322 case WLAN_EID_SSID: 1129 case WLAN_EID_SSID:
1323 bss_entry->ssid.ssid_len = element_len; 1130 bss_entry->ssid.ssid_len = element_len;
1324 memcpy(bss_entry->ssid.ssid, (current_ptr + 2), 1131 memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
1325 element_len); 1132 element_len);
1326 dev_dbg(adapter->dev, "info: InterpretIE: ssid: %-32s\n", 1133 dev_dbg(adapter->dev, "info: InterpretIE: ssid: "
1327 bss_entry->ssid.ssid); 1134 "%-32s\n", bss_entry->ssid.ssid);
1328 break; 1135 break;
1329 1136
1330 case WLAN_EID_SUPP_RATES: 1137 case WLAN_EID_SUPP_RATES:
@@ -1471,13 +1278,6 @@ mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1471 sizeof(struct ieee_types_header) - 1278 sizeof(struct ieee_types_header) -
1472 bss_entry->beacon_buf); 1279 bss_entry->beacon_buf);
1473 break; 1280 break;
1474 case WLAN_EID_OVERLAP_BSS_SCAN_PARAM:
1475 bss_entry->bcn_obss_scan =
1476 (struct ieee_types_obss_scan_param *)
1477 current_ptr;
1478 bss_entry->overlap_bss_offset = (u16) (current_ptr -
1479 bss_entry->beacon_buf);
1480 break;
1481 default: 1281 default:
1482 break; 1282 break;
1483 } 1283 }
@@ -1485,577 +1285,13 @@ mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1485 current_ptr += element_len + 2; 1285 current_ptr += element_len + 2;
1486 1286
1487 /* Need to account for IE ID and IE Len */ 1287 /* Need to account for IE ID and IE Len */
1488 bytes_left_for_current_beacon -= (element_len + 2); 1288 bytes_left -= (element_len + 2);
1489 1289
1490 } /* while (bytes_left_for_current_beacon > 2) */ 1290 } /* while (bytes_left > 2) */
1491 return ret; 1291 return ret;
1492} 1292}
1493 1293
1494/* 1294/*
1495 * This function adjusts the pointers used in beacon buffers to reflect
1496 * shifts.
1497 *
1498 * The memory allocated for beacon buffers is of fixed sizes where all the
1499 * saved beacons must be stored. New beacons are added in the free portion
1500 * of this memory, space permitting; while duplicate beacon buffers are
1501 * placed at the same start location. However, since duplicate beacon
1502 * buffers may not match the size of the old one, all the following buffers
1503 * in the memory must be shifted to either make space, or to fill up freed
1504 * up space.
1505 *
1506 * This function is used to update the beacon buffer pointers that are past
1507 * an existing beacon buffer that is updated with a new one of different
1508 * size. The pointers are shifted by a fixed amount, either forward or
1509 * backward.
1510 *
1511 * the following pointers in every affected beacon buffers are changed, if
1512 * present -
1513 * - WPA IE pointer
1514 * - RSN IE pointer
1515 * - WAPI IE pointer
1516 * - HT capability IE pointer
1517 * - HT information IE pointer
1518 * - BSS coexistence 20/40 IE pointer
1519 * - Extended capability IE pointer
1520 * - Overlapping BSS scan parameter IE pointer
1521 */
1522static void
1523mwifiex_adjust_beacon_buffer_ptrs(struct mwifiex_private *priv, u8 advance,
1524 u8 *bcn_store, u32 rem_bcn_size,
1525 u32 num_of_ent)
1526{
1527 struct mwifiex_adapter *adapter = priv->adapter;
1528 u32 adj_idx;
1529 for (adj_idx = 0; adj_idx < num_of_ent; adj_idx++) {
1530 if (adapter->scan_table[adj_idx].beacon_buf > bcn_store) {
1531
1532 if (advance)
1533 adapter->scan_table[adj_idx].beacon_buf +=
1534 rem_bcn_size;
1535 else
1536 adapter->scan_table[adj_idx].beacon_buf -=
1537 rem_bcn_size;
1538
1539 if (adapter->scan_table[adj_idx].bcn_wpa_ie)
1540 adapter->scan_table[adj_idx].bcn_wpa_ie =
1541 (struct ieee_types_vendor_specific *)
1542 (adapter->scan_table[adj_idx].beacon_buf +
1543 adapter->scan_table[adj_idx].wpa_offset);
1544 if (adapter->scan_table[adj_idx].bcn_rsn_ie)
1545 adapter->scan_table[adj_idx].bcn_rsn_ie =
1546 (struct ieee_types_generic *)
1547 (adapter->scan_table[adj_idx].beacon_buf +
1548 adapter->scan_table[adj_idx].rsn_offset);
1549 if (adapter->scan_table[adj_idx].bcn_wapi_ie)
1550 adapter->scan_table[adj_idx].bcn_wapi_ie =
1551 (struct ieee_types_generic *)
1552 (adapter->scan_table[adj_idx].beacon_buf +
1553 adapter->scan_table[adj_idx].wapi_offset);
1554 if (adapter->scan_table[adj_idx].bcn_ht_cap)
1555 adapter->scan_table[adj_idx].bcn_ht_cap =
1556 (struct ieee80211_ht_cap *)
1557 (adapter->scan_table[adj_idx].beacon_buf +
1558 adapter->scan_table[adj_idx].ht_cap_offset);
1559
1560 if (adapter->scan_table[adj_idx].bcn_ht_info)
1561 adapter->scan_table[adj_idx].bcn_ht_info =
1562 (struct ieee80211_ht_info *)
1563 (adapter->scan_table[adj_idx].beacon_buf +
1564 adapter->scan_table[adj_idx].ht_info_offset);
1565 if (adapter->scan_table[adj_idx].bcn_bss_co_2040)
1566 adapter->scan_table[adj_idx].bcn_bss_co_2040 =
1567 (u8 *)
1568 (adapter->scan_table[adj_idx].beacon_buf +
1569 adapter->scan_table[adj_idx].bss_co_2040_offset);
1570 if (adapter->scan_table[adj_idx].bcn_ext_cap)
1571 adapter->scan_table[adj_idx].bcn_ext_cap =
1572 (u8 *)
1573 (adapter->scan_table[adj_idx].beacon_buf +
1574 adapter->scan_table[adj_idx].ext_cap_offset);
1575 if (adapter->scan_table[adj_idx].bcn_obss_scan)
1576 adapter->scan_table[adj_idx].bcn_obss_scan =
1577 (struct ieee_types_obss_scan_param *)
1578 (adapter->scan_table[adj_idx].beacon_buf +
1579 adapter->scan_table[adj_idx].overlap_bss_offset);
1580 }
1581 }
1582}
1583
1584/*
1585 * This function updates the pointers used in beacon buffer for given bss
1586 * descriptor to reflect shifts
1587 *
1588 * Following pointers are updated
1589 * - WPA IE pointer
1590 * - RSN IE pointer
1591 * - WAPI IE pointer
1592 * - HT capability IE pointer
1593 * - HT information IE pointer
1594 * - BSS coexistence 20/40 IE pointer
1595 * - Extended capability IE pointer
1596 * - Overlapping BSS scan parameter IE pointer
1597 */
1598static void
1599mwifiex_update_beacon_buffer_ptrs(struct mwifiex_bssdescriptor *beacon)
1600{
1601 if (beacon->bcn_wpa_ie)
1602 beacon->bcn_wpa_ie = (struct ieee_types_vendor_specific *)
1603 (beacon->beacon_buf + beacon->wpa_offset);
1604 if (beacon->bcn_rsn_ie)
1605 beacon->bcn_rsn_ie = (struct ieee_types_generic *)
1606 (beacon->beacon_buf + beacon->rsn_offset);
1607 if (beacon->bcn_wapi_ie)
1608 beacon->bcn_wapi_ie = (struct ieee_types_generic *)
1609 (beacon->beacon_buf + beacon->wapi_offset);
1610 if (beacon->bcn_ht_cap)
1611 beacon->bcn_ht_cap = (struct ieee80211_ht_cap *)
1612 (beacon->beacon_buf + beacon->ht_cap_offset);
1613 if (beacon->bcn_ht_info)
1614 beacon->bcn_ht_info = (struct ieee80211_ht_info *)
1615 (beacon->beacon_buf + beacon->ht_info_offset);
1616 if (beacon->bcn_bss_co_2040)
1617 beacon->bcn_bss_co_2040 = (u8 *) (beacon->beacon_buf +
1618 beacon->bss_co_2040_offset);
1619 if (beacon->bcn_ext_cap)
1620 beacon->bcn_ext_cap = (u8 *) (beacon->beacon_buf +
1621 beacon->ext_cap_offset);
1622 if (beacon->bcn_obss_scan)
1623 beacon->bcn_obss_scan = (struct ieee_types_obss_scan_param *)
1624 (beacon->beacon_buf + beacon->overlap_bss_offset);
1625}
1626
1627/*
1628 * This function stores a beacon or probe response for a BSS returned
1629 * in the scan.
1630 *
1631 * This stores a new scan response or an update for a previous scan response.
1632 * New entries need to verify that they do not exceed the total amount of
1633 * memory allocated for the table.
1634 *
1635 * Replacement entries need to take into consideration the amount of space
1636 * currently allocated for the beacon/probe response and adjust the entry
1637 * as needed.
1638 *
1639 * A small amount of extra pad (SCAN_BEACON_ENTRY_PAD) is generally reserved
1640 * for an entry in case it is a beacon since a probe response for the
1641 * network will by larger per the standard. This helps to reduce the
1642 * amount of memory copying to fit a new probe response into an entry
1643 * already occupied by a network's previously stored beacon.
1644 */
1645static void
1646mwifiex_ret_802_11_scan_store_beacon(struct mwifiex_private *priv,
1647 u32 beacon_idx, u32 num_of_ent,
1648 struct mwifiex_bssdescriptor *new_beacon)
1649{
1650 struct mwifiex_adapter *adapter = priv->adapter;
1651 u8 *bcn_store;
1652 u32 new_bcn_size;
1653 u32 old_bcn_size;
1654 u32 bcn_space;
1655
1656 if (adapter->scan_table[beacon_idx].beacon_buf) {
1657
1658 new_bcn_size = new_beacon->beacon_buf_size;
1659 old_bcn_size = adapter->scan_table[beacon_idx].beacon_buf_size;
1660 bcn_space = adapter->scan_table[beacon_idx].beacon_buf_size_max;
1661 bcn_store = adapter->scan_table[beacon_idx].beacon_buf;
1662
1663 /* Set the max to be the same as current entry unless changed
1664 below */
1665 new_beacon->beacon_buf_size_max = bcn_space;
1666 if (new_bcn_size == old_bcn_size) {
1667 /*
1668 * Beacon is the same size as the previous entry.
1669 * Replace the previous contents with the scan result
1670 */
1671 memcpy(bcn_store, new_beacon->beacon_buf,
1672 new_beacon->beacon_buf_size);
1673
1674 } else if (new_bcn_size <= bcn_space) {
1675 /*
1676 * New beacon size will fit in the amount of space
1677 * we have previously allocated for it
1678 */
1679
1680 /* Copy the new beacon buffer entry over the old one */
1681 memcpy(bcn_store, new_beacon->beacon_buf, new_bcn_size);
1682
1683 /*
1684 * If the old beacon size was less than the maximum
1685 * we had alloted for the entry, and the new entry
1686 * is even smaller, reset the max size to the old
1687 * beacon entry and compress the storage space
1688 * (leaving a new pad space of (old_bcn_size -
1689 * new_bcn_size).
1690 */
1691 if (old_bcn_size < bcn_space
1692 && new_bcn_size <= old_bcn_size) {
1693 /*
1694 * Old Beacon size is smaller than the alloted
1695 * storage size. Shrink the alloted storage
1696 * space.
1697 */
1698 dev_dbg(adapter->dev, "info: AppControl:"
1699 " smaller duplicate beacon "
1700 "(%d), old = %d, new = %d, space = %d,"
1701 "left = %d\n",
1702 beacon_idx, old_bcn_size, new_bcn_size,
1703 bcn_space,
1704 (int)(sizeof(adapter->bcn_buf) -
1705 (adapter->bcn_buf_end -
1706 adapter->bcn_buf)));
1707
1708 /*
1709 * memmove (since the memory overlaps) the
1710 * data after the beacon we just stored to the
1711 * end of the current beacon. This cleans up
1712 * any unused space the old larger beacon was
1713 * using in the buffer
1714 */
1715 memmove(bcn_store + old_bcn_size,
1716 bcn_store + bcn_space,
1717 adapter->bcn_buf_end - (bcn_store +
1718 bcn_space));
1719
1720 /*
1721 * Decrement the end pointer by the difference
1722 * between the old larger size and the new
1723 * smaller size since we are using less space
1724 * due to the new beacon being smaller
1725 */
1726 adapter->bcn_buf_end -=
1727 (bcn_space - old_bcn_size);
1728
1729 /* Set the maximum storage size to the old
1730 beacon size */
1731 new_beacon->beacon_buf_size_max = old_bcn_size;
1732
1733 /* Adjust beacon buffer pointers that are past
1734 the current */
1735 mwifiex_adjust_beacon_buffer_ptrs(priv, 0,
1736 bcn_store, (bcn_space - old_bcn_size),
1737 num_of_ent);
1738 }
1739 } else if (adapter->bcn_buf_end + (new_bcn_size - bcn_space)
1740 < (adapter->bcn_buf + sizeof(adapter->bcn_buf))) {
1741 /*
1742 * Beacon is larger than space previously allocated
1743 * (bcn_space) and there is enough space left in the
1744 * beaconBuffer to store the additional data
1745 */
1746 dev_dbg(adapter->dev, "info: AppControl:"
1747 " larger duplicate beacon (%d), "
1748 "old = %d, new = %d, space = %d, left = %d\n",
1749 beacon_idx, old_bcn_size, new_bcn_size,
1750 bcn_space,
1751 (int)(sizeof(adapter->bcn_buf) -
1752 (adapter->bcn_buf_end -
1753 adapter->bcn_buf)));
1754
1755 /*
1756 * memmove (since the memory overlaps) the data
1757 * after the beacon we just stored to the end of
1758 * the current beacon. This moves the data for
1759 * the beacons after this further in memory to
1760 * make space for the new larger beacon we are
1761 * about to copy in.
1762 */
1763 memmove(bcn_store + new_bcn_size,
1764 bcn_store + bcn_space,
1765 adapter->bcn_buf_end - (bcn_store + bcn_space));
1766
1767 /* Copy the new beacon buffer entry over the old one */
1768 memcpy(bcn_store, new_beacon->beacon_buf, new_bcn_size);
1769
1770 /* Move the beacon end pointer by the amount of new
1771 beacon data we are adding */
1772 adapter->bcn_buf_end += (new_bcn_size - bcn_space);
1773
1774 /*
1775 * This entry is bigger than the alloted max space
1776 * previously reserved. Increase the max space to
1777 * be equal to the new beacon size
1778 */
1779 new_beacon->beacon_buf_size_max = new_bcn_size;
1780
1781 /* Adjust beacon buffer pointers that are past the
1782 current */
1783 mwifiex_adjust_beacon_buffer_ptrs(priv, 1, bcn_store,
1784 (new_bcn_size - bcn_space),
1785 num_of_ent);
1786 } else {
1787 /*
1788 * Beacon is larger than the previously allocated space,
1789 * but there is not enough free space to store the
1790 * additional data.
1791 */
1792 dev_err(adapter->dev, "AppControl: larger duplicate "
1793 " beacon (%d), old = %d new = %d, space = %d,"
1794 " left = %d\n", beacon_idx, old_bcn_size,
1795 new_bcn_size, bcn_space,
1796 (int)(sizeof(adapter->bcn_buf) -
1797 (adapter->bcn_buf_end - adapter->bcn_buf)));
1798
1799 /* Storage failure, keep old beacon intact */
1800 new_beacon->beacon_buf_size = old_bcn_size;
1801 if (new_beacon->bcn_wpa_ie)
1802 new_beacon->wpa_offset =
1803 adapter->scan_table[beacon_idx].
1804 wpa_offset;
1805 if (new_beacon->bcn_rsn_ie)
1806 new_beacon->rsn_offset =
1807 adapter->scan_table[beacon_idx].
1808 rsn_offset;
1809 if (new_beacon->bcn_wapi_ie)
1810 new_beacon->wapi_offset =
1811 adapter->scan_table[beacon_idx].
1812 wapi_offset;
1813 if (new_beacon->bcn_ht_cap)
1814 new_beacon->ht_cap_offset =
1815 adapter->scan_table[beacon_idx].
1816 ht_cap_offset;
1817 if (new_beacon->bcn_ht_info)
1818 new_beacon->ht_info_offset =
1819 adapter->scan_table[beacon_idx].
1820 ht_info_offset;
1821 if (new_beacon->bcn_bss_co_2040)
1822 new_beacon->bss_co_2040_offset =
1823 adapter->scan_table[beacon_idx].
1824 bss_co_2040_offset;
1825 if (new_beacon->bcn_ext_cap)
1826 new_beacon->ext_cap_offset =
1827 adapter->scan_table[beacon_idx].
1828 ext_cap_offset;
1829 if (new_beacon->bcn_obss_scan)
1830 new_beacon->overlap_bss_offset =
1831 adapter->scan_table[beacon_idx].
1832 overlap_bss_offset;
1833 }
1834 /* Point the new entry to its permanent storage space */
1835 new_beacon->beacon_buf = bcn_store;
1836 mwifiex_update_beacon_buffer_ptrs(new_beacon);
1837 } else {
1838 /*
1839 * No existing beacon data exists for this entry, check to see
1840 * if we can fit it in the remaining space
1841 */
1842 if (adapter->bcn_buf_end + new_beacon->beacon_buf_size +
1843 SCAN_BEACON_ENTRY_PAD < (adapter->bcn_buf +
1844 sizeof(adapter->bcn_buf))) {
1845
1846 /*
1847 * Copy the beacon buffer data from the local entry to
1848 * the adapter dev struct buffer space used to store
1849 * the raw beacon data for each entry in the scan table
1850 */
1851 memcpy(adapter->bcn_buf_end, new_beacon->beacon_buf,
1852 new_beacon->beacon_buf_size);
1853
1854 /* Update the beacon ptr to point to the table save
1855 area */
1856 new_beacon->beacon_buf = adapter->bcn_buf_end;
1857 new_beacon->beacon_buf_size_max =
1858 (new_beacon->beacon_buf_size +
1859 SCAN_BEACON_ENTRY_PAD);
1860
1861 mwifiex_update_beacon_buffer_ptrs(new_beacon);
1862
1863 /* Increment the end pointer by the size reserved */
1864 adapter->bcn_buf_end += new_beacon->beacon_buf_size_max;
1865
1866 dev_dbg(adapter->dev, "info: AppControl: beacon[%02d]"
1867 " sz=%03d, used = %04d, left = %04d\n",
1868 beacon_idx,
1869 new_beacon->beacon_buf_size,
1870 (int)(adapter->bcn_buf_end - adapter->bcn_buf),
1871 (int)(sizeof(adapter->bcn_buf) -
1872 (adapter->bcn_buf_end -
1873 adapter->bcn_buf)));
1874 } else {
1875 /* No space for new beacon */
1876 dev_dbg(adapter->dev, "info: AppControl: no space for"
1877 " beacon (%d): %pM sz=%03d, left=%03d\n",
1878 beacon_idx, new_beacon->mac_address,
1879 new_beacon->beacon_buf_size,
1880 (int)(sizeof(adapter->bcn_buf) -
1881 (adapter->bcn_buf_end -
1882 adapter->bcn_buf)));
1883
1884 /* Storage failure; clear storage records for this
1885 bcn */
1886 new_beacon->beacon_buf = NULL;
1887 new_beacon->beacon_buf_size = 0;
1888 new_beacon->beacon_buf_size_max = 0;
1889 new_beacon->bcn_wpa_ie = NULL;
1890 new_beacon->wpa_offset = 0;
1891 new_beacon->bcn_rsn_ie = NULL;
1892 new_beacon->rsn_offset = 0;
1893 new_beacon->bcn_wapi_ie = NULL;
1894 new_beacon->wapi_offset = 0;
1895 new_beacon->bcn_ht_cap = NULL;
1896 new_beacon->ht_cap_offset = 0;
1897 new_beacon->bcn_ht_info = NULL;
1898 new_beacon->ht_info_offset = 0;
1899 new_beacon->bcn_bss_co_2040 = NULL;
1900 new_beacon->bss_co_2040_offset = 0;
1901 new_beacon->bcn_ext_cap = NULL;
1902 new_beacon->ext_cap_offset = 0;
1903 new_beacon->bcn_obss_scan = NULL;
1904 new_beacon->overlap_bss_offset = 0;
1905 }
1906 }
1907}
1908
1909/*
1910 * This function restores a beacon buffer of the current BSS descriptor.
1911 */
1912static void mwifiex_restore_curr_bcn(struct mwifiex_private *priv)
1913{
1914 struct mwifiex_adapter *adapter = priv->adapter;
1915 struct mwifiex_bssdescriptor *curr_bss =
1916 &priv->curr_bss_params.bss_descriptor;
1917 unsigned long flags;
1918
1919 if (priv->curr_bcn_buf &&
1920 ((adapter->bcn_buf_end + priv->curr_bcn_size) <
1921 (adapter->bcn_buf + sizeof(adapter->bcn_buf)))) {
1922 spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
1923
1924 /* restore the current beacon buffer */
1925 memcpy(adapter->bcn_buf_end, priv->curr_bcn_buf,
1926 priv->curr_bcn_size);
1927 curr_bss->beacon_buf = adapter->bcn_buf_end;
1928 curr_bss->beacon_buf_size = priv->curr_bcn_size;
1929 adapter->bcn_buf_end += priv->curr_bcn_size;
1930
1931 /* adjust the pointers in the current BSS descriptor */
1932 if (curr_bss->bcn_wpa_ie)
1933 curr_bss->bcn_wpa_ie =
1934 (struct ieee_types_vendor_specific *)
1935 (curr_bss->beacon_buf +
1936 curr_bss->wpa_offset);
1937
1938 if (curr_bss->bcn_rsn_ie)
1939 curr_bss->bcn_rsn_ie = (struct ieee_types_generic *)
1940 (curr_bss->beacon_buf +
1941 curr_bss->rsn_offset);
1942
1943 if (curr_bss->bcn_ht_cap)
1944 curr_bss->bcn_ht_cap = (struct ieee80211_ht_cap *)
1945 (curr_bss->beacon_buf +
1946 curr_bss->ht_cap_offset);
1947
1948 if (curr_bss->bcn_ht_info)
1949 curr_bss->bcn_ht_info = (struct ieee80211_ht_info *)
1950 (curr_bss->beacon_buf +
1951 curr_bss->ht_info_offset);
1952
1953 if (curr_bss->bcn_bss_co_2040)
1954 curr_bss->bcn_bss_co_2040 =
1955 (u8 *) (curr_bss->beacon_buf +
1956 curr_bss->bss_co_2040_offset);
1957
1958 if (curr_bss->bcn_ext_cap)
1959 curr_bss->bcn_ext_cap = (u8 *) (curr_bss->beacon_buf +
1960 curr_bss->ext_cap_offset);
1961
1962 if (curr_bss->bcn_obss_scan)
1963 curr_bss->bcn_obss_scan =
1964 (struct ieee_types_obss_scan_param *)
1965 (curr_bss->beacon_buf +
1966 curr_bss->overlap_bss_offset);
1967
1968 spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
1969
1970 dev_dbg(adapter->dev, "info: current beacon restored %d\n",
1971 priv->curr_bcn_size);
1972 } else {
1973 dev_warn(adapter->dev,
1974 "curr_bcn_buf not saved or bcn_buf has no space\n");
1975 }
1976}
1977
1978/*
1979 * This function post processes the scan table after a new scan command has
1980 * completed.
1981 *
1982 * It inspects each entry of the scan table and tries to find an entry that
1983 * matches with our current associated/joined network from the scan. If
1984 * one is found, the stored copy of the BSS descriptor of our current network
1985 * is updated.
1986 *
1987 * It also debug dumps the current scan table contents after processing is over.
1988 */
1989static void
1990mwifiex_process_scan_results(struct mwifiex_private *priv)
1991{
1992 struct mwifiex_adapter *adapter = priv->adapter;
1993 s32 j;
1994 u32 i;
1995 unsigned long flags;
1996
1997 if (priv->media_connected) {
1998
1999 j = mwifiex_find_ssid_in_list(priv, &priv->curr_bss_params.
2000 bss_descriptor.ssid,
2001 priv->curr_bss_params.
2002 bss_descriptor.mac_address,
2003 priv->bss_mode);
2004
2005 if (j >= 0) {
2006 spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
2007 priv->curr_bss_params.bss_descriptor.bcn_wpa_ie = NULL;
2008 priv->curr_bss_params.bss_descriptor.wpa_offset = 0;
2009 priv->curr_bss_params.bss_descriptor.bcn_rsn_ie = NULL;
2010 priv->curr_bss_params.bss_descriptor.rsn_offset = 0;
2011 priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL;
2012 priv->curr_bss_params.bss_descriptor.wapi_offset = 0;
2013 priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL;
2014 priv->curr_bss_params.bss_descriptor.ht_cap_offset =
2015 0;
2016 priv->curr_bss_params.bss_descriptor.bcn_ht_info = NULL;
2017 priv->curr_bss_params.bss_descriptor.ht_info_offset =
2018 0;
2019 priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 =
2020 NULL;
2021 priv->curr_bss_params.bss_descriptor.
2022 bss_co_2040_offset = 0;
2023 priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL;
2024 priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0;
2025 priv->curr_bss_params.bss_descriptor.
2026 bcn_obss_scan = NULL;
2027 priv->curr_bss_params.bss_descriptor.
2028 overlap_bss_offset = 0;
2029 priv->curr_bss_params.bss_descriptor.beacon_buf = NULL;
2030 priv->curr_bss_params.bss_descriptor.beacon_buf_size =
2031 0;
2032 priv->curr_bss_params.bss_descriptor.
2033 beacon_buf_size_max = 0;
2034
2035 dev_dbg(adapter->dev, "info: Found current ssid/bssid"
2036 " in list @ index #%d\n", j);
2037 /* Make a copy of current BSSID descriptor */
2038 memcpy(&priv->curr_bss_params.bss_descriptor,
2039 &adapter->scan_table[j],
2040 sizeof(priv->curr_bss_params.bss_descriptor));
2041
2042 mwifiex_save_curr_bcn(priv);
2043 spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
2044
2045 } else {
2046 mwifiex_restore_curr_bcn(priv);
2047 }
2048 }
2049
2050 for (i = 0; i < adapter->num_in_scan_table; i++)
2051 dev_dbg(adapter->dev, "info: scan:(%02d) %pM "
2052 "RSSI[%03d], SSID[%s]\n",
2053 i, adapter->scan_table[i].mac_address,
2054 (s32) adapter->scan_table[i].rssi,
2055 adapter->scan_table[i].ssid.ssid);
2056}
2057
2058/*
2059 * This function converts radio type scan parameter to a band configuration 1295 * This function converts radio type scan parameter to a band configuration
2060 * to be used in join command. 1296 * to be used in join command.
2061 */ 1297 */
@@ -2072,175 +1308,6 @@ mwifiex_radio_type_to_band(u8 radio_type)
2072} 1308}
2073 1309
2074/* 1310/*
2075 * This function deletes a specific indexed entry from the scan table.
2076 *
2077 * This also compacts the remaining entries and adjusts any buffering
2078 * of beacon/probe response data if needed.
2079 */
2080static void
2081mwifiex_scan_delete_table_entry(struct mwifiex_private *priv, s32 table_idx)
2082{
2083 struct mwifiex_adapter *adapter = priv->adapter;
2084 u32 del_idx;
2085 u32 beacon_buf_adj;
2086 u8 *beacon_buf;
2087
2088 /*
2089 * Shift the saved beacon buffer data for the scan table back over the
2090 * entry being removed. Update the end of buffer pointer. Save the
2091 * deleted buffer allocation size for pointer adjustments for entries
2092 * compacted after the deleted index.
2093 */
2094 beacon_buf_adj = adapter->scan_table[table_idx].beacon_buf_size_max;
2095
2096 dev_dbg(adapter->dev, "info: Scan: Delete Entry %d, beacon buffer "
2097 "removal = %d bytes\n", table_idx, beacon_buf_adj);
2098
2099 /* Check if the table entry had storage allocated for its beacon */
2100 if (beacon_buf_adj) {
2101 beacon_buf = adapter->scan_table[table_idx].beacon_buf;
2102
2103 /*
2104 * Remove the entry's buffer space, decrement the table end
2105 * pointer by the amount we are removing
2106 */
2107 adapter->bcn_buf_end -= beacon_buf_adj;
2108
2109 dev_dbg(adapter->dev, "info: scan: delete entry %d,"
2110 " compact data: %p <- %p (sz = %d)\n",
2111 table_idx, beacon_buf,
2112 beacon_buf + beacon_buf_adj,
2113 (int)(adapter->bcn_buf_end - beacon_buf));
2114
2115 /*
2116 * Compact data storage. Copy all data after the deleted
2117 * entry's end address (beacon_buf + beacon_buf_adj) back
2118 * to the original start address (beacon_buf).
2119 *
2120 * Scan table entries affected by the move will have their
2121 * entry pointer adjusted below.
2122 *
2123 * Use memmove since the dest/src memory regions overlap.
2124 */
2125 memmove(beacon_buf, beacon_buf + beacon_buf_adj,
2126 adapter->bcn_buf_end - beacon_buf);
2127 }
2128
2129 dev_dbg(adapter->dev,
2130 "info: Scan: Delete Entry %d, num_in_scan_table = %d\n",
2131 table_idx, adapter->num_in_scan_table);
2132
2133 /* Shift all of the entries after the table_idx back by one, compacting
2134 the table and removing the requested entry */
2135 for (del_idx = table_idx; (del_idx + 1) < adapter->num_in_scan_table;
2136 del_idx++) {
2137 /* Copy the next entry over this one */
2138 memcpy(adapter->scan_table + del_idx,
2139 adapter->scan_table + del_idx + 1,
2140 sizeof(struct mwifiex_bssdescriptor));
2141
2142 /*
2143 * Adjust this entry's pointer to its beacon buffer based on
2144 * the removed/compacted entry from the deleted index. Don't
2145 * decrement if the buffer pointer is NULL (no data stored for
2146 * this entry).
2147 */
2148 if (adapter->scan_table[del_idx].beacon_buf) {
2149 adapter->scan_table[del_idx].beacon_buf -=
2150 beacon_buf_adj;
2151 if (adapter->scan_table[del_idx].bcn_wpa_ie)
2152 adapter->scan_table[del_idx].bcn_wpa_ie =
2153 (struct ieee_types_vendor_specific *)
2154 (adapter->scan_table[del_idx].
2155 beacon_buf +
2156 adapter->scan_table[del_idx].
2157 wpa_offset);
2158 if (adapter->scan_table[del_idx].bcn_rsn_ie)
2159 adapter->scan_table[del_idx].bcn_rsn_ie =
2160 (struct ieee_types_generic *)
2161 (adapter->scan_table[del_idx].
2162 beacon_buf +
2163 adapter->scan_table[del_idx].
2164 rsn_offset);
2165 if (adapter->scan_table[del_idx].bcn_wapi_ie)
2166 adapter->scan_table[del_idx].bcn_wapi_ie =
2167 (struct ieee_types_generic *)
2168 (adapter->scan_table[del_idx].beacon_buf
2169 + adapter->scan_table[del_idx].
2170 wapi_offset);
2171 if (adapter->scan_table[del_idx].bcn_ht_cap)
2172 adapter->scan_table[del_idx].bcn_ht_cap =
2173 (struct ieee80211_ht_cap *)
2174 (adapter->scan_table[del_idx].beacon_buf
2175 + adapter->scan_table[del_idx].
2176 ht_cap_offset);
2177
2178 if (adapter->scan_table[del_idx].bcn_ht_info)
2179 adapter->scan_table[del_idx].bcn_ht_info =
2180 (struct ieee80211_ht_info *)
2181 (adapter->scan_table[del_idx].beacon_buf
2182 + adapter->scan_table[del_idx].
2183 ht_info_offset);
2184 if (adapter->scan_table[del_idx].bcn_bss_co_2040)
2185 adapter->scan_table[del_idx].bcn_bss_co_2040 =
2186 (u8 *)
2187 (adapter->scan_table[del_idx].beacon_buf
2188 + adapter->scan_table[del_idx].
2189 bss_co_2040_offset);
2190 if (adapter->scan_table[del_idx].bcn_ext_cap)
2191 adapter->scan_table[del_idx].bcn_ext_cap =
2192 (u8 *)
2193 (adapter->scan_table[del_idx].beacon_buf
2194 + adapter->scan_table[del_idx].
2195 ext_cap_offset);
2196 if (adapter->scan_table[del_idx].bcn_obss_scan)
2197 adapter->scan_table[del_idx].
2198 bcn_obss_scan =
2199 (struct ieee_types_obss_scan_param *)
2200 (adapter->scan_table[del_idx].beacon_buf
2201 + adapter->scan_table[del_idx].
2202 overlap_bss_offset);
2203 }
2204 }
2205
2206 /* The last entry is invalid now that it has been deleted or moved
2207 back */
2208 memset(adapter->scan_table + adapter->num_in_scan_table - 1,
2209 0x00, sizeof(struct mwifiex_bssdescriptor));
2210
2211 adapter->num_in_scan_table--;
2212}
2213
2214/*
2215 * This function deletes all occurrences of a given SSID from the scan table.
2216 *
2217 * This iterates through the scan table and deletes all entries that match
2218 * the given SSID. It also compacts the remaining scan table entries.
2219 */
2220static int
2221mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv,
2222 struct mwifiex_802_11_ssid *del_ssid)
2223{
2224 s32 table_idx = -1;
2225
2226 dev_dbg(priv->adapter->dev, "info: scan: delete ssid entry: %-32s\n",
2227 del_ssid->ssid);
2228
2229 /* If the requested SSID is found in the table, delete it. Then keep
2230 searching the table for multiple entires for the SSID until no
2231 more are found */
2232 while ((table_idx = mwifiex_find_ssid_in_list(priv, del_ssid, NULL,
2233 NL80211_IFTYPE_UNSPECIFIED)) >= 0) {
2234 dev_dbg(priv->adapter->dev,
2235 "info: Scan: Delete SSID Entry: Found Idx = %d\n",
2236 table_idx);
2237 mwifiex_scan_delete_table_entry(priv, table_idx);
2238 }
2239
2240 return table_idx == -1 ? -1 : 0;
2241}
2242
2243/*
2244 * This is an internal function used to start a scan based on an input 1311 * This is an internal function used to start a scan based on an input
2245 * configuration. 1312 * configuration.
2246 * 1313 *
@@ -2258,7 +1325,6 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
2258 struct mwifiex_ie_types_chan_list_param_set *chan_list_out; 1325 struct mwifiex_ie_types_chan_list_param_set *chan_list_out;
2259 u32 buf_size; 1326 u32 buf_size;
2260 struct mwifiex_chan_scan_param_set *scan_chan_list; 1327 struct mwifiex_chan_scan_param_set *scan_chan_list;
2261 u8 keep_previous_scan;
2262 u8 filtered_scan; 1328 u8 filtered_scan;
2263 u8 scan_current_chan_only; 1329 u8 scan_current_chan_only;
2264 u8 max_chan_per_scan; 1330 u8 max_chan_per_scan;
@@ -2295,24 +1361,11 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
2295 return -ENOMEM; 1361 return -ENOMEM;
2296 } 1362 }
2297 1363
2298 keep_previous_scan = false;
2299
2300 mwifiex_scan_setup_scan_config(priv, user_scan_in, 1364 mwifiex_scan_setup_scan_config(priv, user_scan_in,
2301 &scan_cfg_out->config, &chan_list_out, 1365 &scan_cfg_out->config, &chan_list_out,
2302 scan_chan_list, &max_chan_per_scan, 1366 scan_chan_list, &max_chan_per_scan,
2303 &filtered_scan, &scan_current_chan_only); 1367 &filtered_scan, &scan_current_chan_only);
2304 1368
2305 if (user_scan_in)
2306 keep_previous_scan = user_scan_in->keep_previous_scan;
2307
2308
2309 if (!keep_previous_scan) {
2310 memset(adapter->scan_table, 0x00,
2311 sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP);
2312 adapter->num_in_scan_table = 0;
2313 adapter->bcn_buf_end = adapter->bcn_buf;
2314 }
2315
2316 ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan, 1369 ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan,
2317 &scan_cfg_out->config, chan_list_out, 1370 &scan_cfg_out->config, chan_list_out,
2318 scan_chan_list); 1371 scan_chan_list);
@@ -2379,6 +1432,107 @@ int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
2379} 1432}
2380 1433
2381/* 1434/*
1435 * This function checks compatibility of requested network with current
1436 * driver settings.
1437 */
1438int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
1439 struct mwifiex_bssdescriptor *bss_desc)
1440{
1441 int ret = -1;
1442
1443 if (!bss_desc)
1444 return -1;
1445
1446 if ((mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
1447 (u8) bss_desc->bss_band, (u16) bss_desc->channel))) {
1448 switch (priv->bss_mode) {
1449 case NL80211_IFTYPE_STATION:
1450 case NL80211_IFTYPE_ADHOC:
1451 ret = mwifiex_is_network_compatible(priv, bss_desc,
1452 priv->bss_mode);
1453 if (ret)
1454 dev_err(priv->adapter->dev, "cannot find ssid "
1455 "%s\n", bss_desc->ssid.ssid);
1456 break;
1457 default:
1458 ret = 0;
1459 }
1460 }
1461
1462 return ret;
1463}
1464
1465static int
1466mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
1467 u8 *bssid, s32 rssi, const u8 *ie_buf,
1468 size_t ie_len, u16 beacon_period, u16 cap_info_bitmap)
1469{
1470 struct mwifiex_bssdescriptor *bss_desc = NULL;
1471 int ret;
1472 unsigned long flags;
1473 u8 *beacon_ie;
1474
1475 /* Allocate and fill new bss descriptor */
1476 bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor),
1477 GFP_KERNEL);
1478 if (!bss_desc) {
1479 dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
1480 return -ENOMEM;
1481 }
1482 beacon_ie = kzalloc(ie_len, GFP_KERNEL);
1483 if (!bss_desc) {
1484 dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
1485 return -ENOMEM;
1486 }
1487 memcpy(beacon_ie, ie_buf, ie_len);
1488
1489 ret = mwifiex_fill_new_bss_desc(priv, bssid, rssi, beacon_ie,
1490 ie_len, beacon_period,
1491 cap_info_bitmap, bss_desc);
1492 if (ret)
1493 goto done;
1494
1495 ret = mwifiex_check_network_compatibility(priv, bss_desc);
1496 if (ret)
1497 goto done;
1498
1499 /* Update current bss descriptor parameters */
1500 spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
1501 priv->curr_bss_params.bss_descriptor.bcn_wpa_ie = NULL;
1502 priv->curr_bss_params.bss_descriptor.wpa_offset = 0;
1503 priv->curr_bss_params.bss_descriptor.bcn_rsn_ie = NULL;
1504 priv->curr_bss_params.bss_descriptor.rsn_offset = 0;
1505 priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL;
1506 priv->curr_bss_params.bss_descriptor.wapi_offset = 0;
1507 priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL;
1508 priv->curr_bss_params.bss_descriptor.ht_cap_offset =
1509 0;
1510 priv->curr_bss_params.bss_descriptor.bcn_ht_info = NULL;
1511 priv->curr_bss_params.bss_descriptor.ht_info_offset =
1512 0;
1513 priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 =
1514 NULL;
1515 priv->curr_bss_params.bss_descriptor.
1516 bss_co_2040_offset = 0;
1517 priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL;
1518 priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0;
1519 priv->curr_bss_params.bss_descriptor.beacon_buf = NULL;
1520 priv->curr_bss_params.bss_descriptor.beacon_buf_size =
1521 0;
1522
1523 /* Make a copy of current BSSID descriptor */
1524 memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
1525 sizeof(priv->curr_bss_params.bss_descriptor));
1526 mwifiex_save_curr_bcn(priv);
1527 spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
1528
1529done:
1530 kfree(bss_desc);
1531 kfree(beacon_ie);
1532 return 0;
1533}
1534
1535/*
2382 * This function handles the command response of scan. 1536 * This function handles the command response of scan.
2383 * 1537 *
2384 * The response buffer for the scan command has the following 1538 * The response buffer for the scan command has the following
@@ -2404,21 +1558,16 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
2404 struct mwifiex_adapter *adapter = priv->adapter; 1558 struct mwifiex_adapter *adapter = priv->adapter;
2405 struct cmd_ctrl_node *cmd_node; 1559 struct cmd_ctrl_node *cmd_node;
2406 struct host_cmd_ds_802_11_scan_rsp *scan_rsp; 1560 struct host_cmd_ds_802_11_scan_rsp *scan_rsp;
2407 struct mwifiex_bssdescriptor *bss_new_entry = NULL;
2408 struct mwifiex_ie_types_data *tlv_data; 1561 struct mwifiex_ie_types_data *tlv_data;
2409 struct mwifiex_ie_types_tsf_timestamp *tsf_tlv; 1562 struct mwifiex_ie_types_tsf_timestamp *tsf_tlv;
2410 u8 *bss_info; 1563 u8 *bss_info;
2411 u32 scan_resp_size; 1564 u32 scan_resp_size;
2412 u32 bytes_left; 1565 u32 bytes_left;
2413 u32 num_in_table;
2414 u32 bss_idx;
2415 u32 idx; 1566 u32 idx;
2416 u32 tlv_buf_size; 1567 u32 tlv_buf_size;
2417 long long tsf_val;
2418 struct mwifiex_chan_freq_power *cfp; 1568 struct mwifiex_chan_freq_power *cfp;
2419 struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv; 1569 struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
2420 struct chan_band_param_set *chan_band; 1570 struct chan_band_param_set *chan_band;
2421 u8 band;
2422 u8 is_bgscan_resp; 1571 u8 is_bgscan_resp;
2423 unsigned long flags; 1572 unsigned long flags;
2424 1573
@@ -2430,7 +1579,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
2430 scan_rsp = &resp->params.scan_resp; 1579 scan_rsp = &resp->params.scan_resp;
2431 1580
2432 1581
2433 if (scan_rsp->number_of_sets > IW_MAX_AP) { 1582 if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) {
2434 dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", 1583 dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
2435 scan_rsp->number_of_sets); 1584 scan_rsp->number_of_sets);
2436 ret = -1; 1585 ret = -1;
@@ -2447,7 +1596,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
2447 "info: SCAN_RESP: returned %d APs before parsing\n", 1596 "info: SCAN_RESP: returned %d APs before parsing\n",
2448 scan_rsp->number_of_sets); 1597 scan_rsp->number_of_sets);
2449 1598
2450 num_in_table = adapter->num_in_scan_table;
2451 bss_info = scan_rsp->bss_desc_and_tlv_buffer; 1599 bss_info = scan_rsp->bss_desc_and_tlv_buffer;
2452 1600
2453 /* 1601 /*
@@ -2479,125 +1627,147 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
2479 (struct mwifiex_ie_types_data **) 1627 (struct mwifiex_ie_types_data **)
2480 &chan_band_tlv); 1628 &chan_band_tlv);
2481 1629
2482 /*
2483 * Process each scan response returned (scan_rsp->number_of_sets).
2484 * Save the information in the bss_new_entry and then insert into the
2485 * driver scan table either as an update to an existing entry
2486 * or as an addition at the end of the table
2487 */
2488 bss_new_entry = kzalloc(sizeof(struct mwifiex_bssdescriptor),
2489 GFP_KERNEL);
2490 if (!bss_new_entry) {
2491 dev_err(adapter->dev, " failed to alloc bss_new_entry\n");
2492 return -ENOMEM;
2493 }
2494
2495 for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) { 1630 for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) {
2496 /* Zero out the bss_new_entry we are about to store info in */ 1631 u8 bssid[ETH_ALEN];
2497 memset(bss_new_entry, 0x00, 1632 s32 rssi;
2498 sizeof(struct mwifiex_bssdescriptor)); 1633 const u8 *ie_buf;
2499 1634 size_t ie_len;
2500 if (mwifiex_interpret_bss_desc_with_ie(adapter, bss_new_entry, 1635 int channel = -1;
2501 &bss_info, 1636 u64 network_tsf = 0;
2502 &bytes_left)) { 1637 u16 beacon_size = 0;
2503 /* Error parsing/interpreting scan response, skipped */ 1638 u32 curr_bcn_bytes;
2504 dev_err(adapter->dev, "SCAN_RESP: " 1639 u32 freq;
2505 "mwifiex_interpret_bss_desc_with_ie " 1640 u16 beacon_period;
2506 "returned ERROR\n"); 1641 u16 cap_info_bitmap;
2507 continue; 1642 u8 *current_ptr;
1643 struct mwifiex_bcn_param *bcn_param;
1644
1645 if (bytes_left >= sizeof(beacon_size)) {
1646 /* Extract & convert beacon size from command buffer */
1647 memcpy(&beacon_size, bss_info, sizeof(beacon_size));
1648 bytes_left -= sizeof(beacon_size);
1649 bss_info += sizeof(beacon_size);
2508 } 1650 }
2509 1651
2510 /* Process the data fields and IEs returned for this BSS */ 1652 if (!beacon_size || beacon_size > bytes_left) {
2511 dev_dbg(adapter->dev, "info: SCAN_RESP: BSSID = %pM\n", 1653 bss_info += bytes_left;
2512 bss_new_entry->mac_address); 1654 bytes_left = 0;
1655 return -1;
1656 }
2513 1657
2514 /* Search the scan table for the same bssid */ 1658 /* Initialize the current working beacon pointer for this BSS
2515 for (bss_idx = 0; bss_idx < num_in_table; bss_idx++) { 1659 * iteration */
2516 if (memcmp(bss_new_entry->mac_address, 1660 current_ptr = bss_info;
2517 adapter->scan_table[bss_idx].mac_address, 1661
2518 sizeof(bss_new_entry->mac_address))) { 1662 /* Advance the return beacon pointer past the current beacon */
2519 continue; 1663 bss_info += beacon_size;
1664 bytes_left -= beacon_size;
1665
1666 curr_bcn_bytes = beacon_size;
1667
1668 /*
1669 * First 5 fields are bssid, RSSI, time stamp, beacon interval,
1670 * and capability information
1671 */
1672 if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) {
1673 dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
1674 continue;
1675 }
1676 bcn_param = (struct mwifiex_bcn_param *)current_ptr;
1677 current_ptr += sizeof(*bcn_param);
1678 curr_bcn_bytes -= sizeof(*bcn_param);
1679
1680 memcpy(bssid, bcn_param->bssid, ETH_ALEN);
1681
1682 rssi = (s32) (bcn_param->rssi);
1683 dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n",
1684 rssi);
1685
1686 beacon_period = le16_to_cpu(bcn_param->beacon_period);
1687
1688 cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap);
1689 dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
1690 cap_info_bitmap);
1691
1692 /* Rest of the current buffer are IE's */
1693 ie_buf = current_ptr;
1694 ie_len = curr_bcn_bytes;
1695 dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP"
1696 " = %d\n", curr_bcn_bytes);
1697
1698 while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) {
1699 u8 element_id, element_len;
1700
1701 element_id = *current_ptr;
1702 element_len = *(current_ptr + 1);
1703 if (curr_bcn_bytes < element_len +
1704 sizeof(struct ieee_types_header)) {
1705 dev_err(priv->adapter->dev, "%s: in processing"
1706 " IE, bytes left < IE length\n",
1707 __func__);
1708 goto done;
2520 } 1709 }
2521 /* 1710 if (element_id == WLAN_EID_DS_PARAMS) {
2522 * If the SSID matches as well, it is a 1711 channel = *(u8 *) (current_ptr +
2523 * duplicate of this entry. Keep the bss_idx 1712 sizeof(struct ieee_types_header));
2524 * set to this entry so we replace the old
2525 * contents in the table
2526 */
2527 if ((bss_new_entry->ssid.ssid_len
2528 == adapter->scan_table[bss_idx]. ssid.ssid_len)
2529 && (!memcmp(bss_new_entry->ssid.ssid,
2530 adapter->scan_table[bss_idx].ssid.ssid,
2531 bss_new_entry->ssid.ssid_len))) {
2532 dev_dbg(adapter->dev, "info: SCAN_RESP:"
2533 " duplicate of index: %d\n", bss_idx);
2534 break; 1713 break;
2535 } 1714 }
2536 } 1715
2537 /* 1716 current_ptr += element_len +
2538 * If the bss_idx is equal to the number of entries in 1717 sizeof(struct ieee_types_header);
2539 * the table, the new entry was not a duplicate; append 1718 curr_bcn_bytes -= element_len +
2540 * it to the scan table 1719 sizeof(struct ieee_types_header);
2541 */
2542 if (bss_idx == num_in_table) {
2543 /* Range check the bss_idx, keep it limited to
2544 the last entry */
2545 if (bss_idx == IW_MAX_AP)
2546 bss_idx--;
2547 else
2548 num_in_table++;
2549 } 1720 }
2550 1721
2551 /* 1722 /*
2552 * Save the beacon/probe response returned for later application
2553 * retrieval. Duplicate beacon/probe responses are updated if
2554 * possible
2555 */
2556 mwifiex_ret_802_11_scan_store_beacon(priv, bss_idx,
2557 num_in_table, bss_new_entry);
2558 /*
2559 * If the TSF TLV was appended to the scan results, save this 1723 * If the TSF TLV was appended to the scan results, save this
2560 * entry's TSF value in the networkTSF field.The networkTSF is 1724 * entry's TSF value in the networkTSF field.The networkTSF is
2561 * the firmware's TSF value at the time the beacon or probe 1725 * the firmware's TSF value at the time the beacon or probe
2562 * response was received. 1726 * response was received.
2563 */ 1727 */
2564 if (tsf_tlv) { 1728 if (tsf_tlv)
2565 memcpy(&tsf_val, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE] 1729 memcpy(&network_tsf,
2566 , sizeof(tsf_val)); 1730 &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
2567 memcpy(&bss_new_entry->network_tsf, &tsf_val, 1731 sizeof(network_tsf));
2568 sizeof(bss_new_entry->network_tsf)); 1732
2569 } 1733 if (channel != -1) {
2570 band = BAND_G; 1734 struct ieee80211_channel *chan;
2571 if (chan_band_tlv) { 1735 u8 band;
2572 chan_band = &chan_band_tlv->chan_band_param[idx]; 1736
2573 band = mwifiex_radio_type_to_band(chan_band->radio_type 1737 band = BAND_G;
2574 & (BIT(0) | BIT(1))); 1738 if (chan_band_tlv) {
2575 } 1739 chan_band =
2576 1740 &chan_band_tlv->chan_band_param[idx];
2577 /* Save the band designation for this entry for use in join */ 1741 band = mwifiex_radio_type_to_band(
2578 bss_new_entry->bss_band = band; 1742 chan_band->radio_type
2579 cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, 1743 & (BIT(0) | BIT(1)));
2580 (u8) bss_new_entry->bss_band, 1744 }
2581 (u16)bss_new_entry->channel);
2582 1745
2583 if (cfp) 1746 cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(
2584 bss_new_entry->freq = cfp->freq; 1747 priv, (u8)band, (u16)channel);
2585 else
2586 bss_new_entry->freq = 0;
2587 1748
2588 /* Copy the locally created bss_new_entry to the scan table */ 1749 freq = cfp ? cfp->freq : 0;
2589 memcpy(&adapter->scan_table[bss_idx], bss_new_entry,
2590 sizeof(adapter->scan_table[bss_idx]));
2591 1750
2592 } 1751 chan = ieee80211_get_channel(priv->wdev->wiphy, freq);
2593 1752
2594 dev_dbg(adapter->dev, 1753 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
2595 "info: SCAN_RESP: Scanned %2d APs, %d valid, %d total\n", 1754 cfg80211_inform_bss(priv->wdev->wiphy, chan,
2596 scan_rsp->number_of_sets, 1755 bssid, network_tsf, cap_info_bitmap,
2597 num_in_table - adapter->num_in_scan_table, num_in_table); 1756 beacon_period, ie_buf, ie_len, rssi,
1757 GFP_KERNEL);
2598 1758
2599 /* Update the total number of BSSIDs in the scan table */ 1759 if (priv->media_connected && !memcmp(bssid,
2600 adapter->num_in_scan_table = num_in_table; 1760 priv->curr_bss_params.bss_descriptor
1761 .mac_address, ETH_ALEN))
1762 mwifiex_update_curr_bss_params(priv,
1763 bssid, rssi, ie_buf,
1764 ie_len, beacon_period,
1765 cap_info_bitmap);
1766 }
1767 } else {
1768 dev_dbg(adapter->dev, "missing BSS channel IE\n");
1769 }
1770 }
2601 1771
2602 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 1772 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
2603 if (list_empty(&adapter->scan_pending_q)) { 1773 if (list_empty(&adapter->scan_pending_q)) {
@@ -2605,12 +1775,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
2605 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 1775 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
2606 adapter->scan_processing = false; 1776 adapter->scan_processing = false;
2607 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 1777 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
2608 /*
2609 * Process the resulting scan table:
2610 * - Remove any bad ssids
2611 * - Update our current BSS information from scan data
2612 */
2613 mwifiex_process_scan_results(priv);
2614 1778
2615 /* Need to indicate IOCTL complete */ 1779 /* Need to indicate IOCTL complete */
2616 if (adapter->curr_cmd->wait_q_enabled) { 1780 if (adapter->curr_cmd->wait_q_enabled) {
@@ -2636,7 +1800,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
2636 } 1800 }
2637 1801
2638done: 1802done:
2639 kfree((u8 *) bss_new_entry);
2640 return ret; 1803 return ret;
2641} 1804}
2642 1805
@@ -2663,141 +1826,6 @@ int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd)
2663} 1826}
2664 1827
2665/* 1828/*
2666 * This function finds a SSID in the scan table.
2667 *
2668 * A BSSID may optionally be provided to qualify the SSID.
2669 * For non-Auto mode, further check is made to make sure the
2670 * BSS found in the scan table is compatible with the current
2671 * settings of the driver.
2672 */
2673s32
2674mwifiex_find_ssid_in_list(struct mwifiex_private *priv,
2675 struct mwifiex_802_11_ssid *ssid, u8 *bssid,
2676 u32 mode)
2677{
2678 struct mwifiex_adapter *adapter = priv->adapter;
2679 s32 net = -1, j;
2680 u8 best_rssi = 0;
2681 u32 i;
2682
2683 dev_dbg(adapter->dev, "info: num of entries in table = %d\n",
2684 adapter->num_in_scan_table);
2685
2686 /*
2687 * Loop through the table until the maximum is reached or until a match
2688 * is found based on the bssid field comparison
2689 */
2690 for (i = 0;
2691 i < adapter->num_in_scan_table && (!bssid || (bssid && net < 0));
2692 i++) {
2693 if (!mwifiex_ssid_cmp(&adapter->scan_table[i].ssid, ssid) &&
2694 (!bssid
2695 || !memcmp(adapter->scan_table[i].mac_address, bssid,
2696 ETH_ALEN))
2697 &&
2698 (mwifiex_get_cfp_by_band_and_channel_from_cfg80211
2699 (priv, (u8) adapter->scan_table[i].bss_band,
2700 (u16) adapter->scan_table[i].channel))) {
2701 switch (mode) {
2702 case NL80211_IFTYPE_STATION:
2703 case NL80211_IFTYPE_ADHOC:
2704 j = mwifiex_is_network_compatible(priv, i,
2705 mode);
2706
2707 if (j >= 0) {
2708 if (SCAN_RSSI
2709 (adapter->scan_table[i].rssi) >
2710 best_rssi) {
2711 best_rssi = SCAN_RSSI(adapter->
2712 scan_table
2713 [i].rssi);
2714 net = i;
2715 }
2716 } else {
2717 if (net == -1)
2718 net = j;
2719 }
2720 break;
2721 case NL80211_IFTYPE_UNSPECIFIED:
2722 default:
2723 /*
2724 * Do not check compatibility if the mode
2725 * requested is Auto/Unknown. Allows generic
2726 * find to work without verifying against the
2727 * Adapter security settings
2728 */
2729 if (SCAN_RSSI(adapter->scan_table[i].rssi) >
2730 best_rssi) {
2731 best_rssi = SCAN_RSSI(adapter->
2732 scan_table[i].rssi);
2733 net = i;
2734 }
2735 break;
2736 }
2737 }
2738 }
2739
2740 return net;
2741}
2742
2743/*
2744 * This function finds a specific compatible BSSID in the scan list.
2745 *
2746 * This function loops through the scan table looking for a compatible
2747 * match. If a BSSID matches, but the BSS is found to be not compatible
2748 * the function ignores it and continues to search through the rest of
2749 * the entries in case there is an AP with multiple SSIDs assigned to
2750 * the same BSSID.
2751 */
2752s32
2753mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid,
2754 u32 mode)
2755{
2756 struct mwifiex_adapter *adapter = priv->adapter;
2757 s32 net = -1;
2758 u32 i;
2759
2760 if (!bssid)
2761 return -1;
2762
2763 dev_dbg(adapter->dev, "info: FindBSSID: Num of BSSIDs = %d\n",
2764 adapter->num_in_scan_table);
2765
2766 /*
2767 * Look through the scan table for a compatible match. The ret return
2768 * variable will be equal to the index in the scan table (greater
2769 * than zero) if the network is compatible. The loop will continue
2770 * past a matched bssid that is not compatible in case there is an
2771 * AP with multiple SSIDs assigned to the same BSSID
2772 */
2773 for (i = 0; net < 0 && i < adapter->num_in_scan_table; i++) {
2774 if (!memcmp
2775 (adapter->scan_table[i].mac_address, bssid, ETH_ALEN)
2776 && mwifiex_get_cfp_by_band_and_channel_from_cfg80211
2777 (priv,
2778 (u8) adapter->
2779 scan_table[i].
2780 bss_band,
2781 (u16) adapter->
2782 scan_table[i].
2783 channel)) {
2784 switch (mode) {
2785 case NL80211_IFTYPE_STATION:
2786 case NL80211_IFTYPE_ADHOC:
2787 net = mwifiex_is_network_compatible(priv, i,
2788 mode);
2789 break;
2790 default:
2791 net = i;
2792 break;
2793 }
2794 }
2795 }
2796
2797 return net;
2798}
2799
2800/*
2801 * This function inserts scan command node to the scan pending queue. 1829 * This function inserts scan command node to the scan pending queue.
2802 */ 1830 */
2803void 1831void
@@ -2814,42 +1842,6 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
2814} 1842}
2815 1843
2816/* 1844/*
2817 * This function finds an AP with specific ssid in the scan list.
2818 */
2819int mwifiex_find_best_network(struct mwifiex_private *priv,
2820 struct mwifiex_ssid_bssid *req_ssid_bssid)
2821{
2822 struct mwifiex_adapter *adapter = priv->adapter;
2823 struct mwifiex_bssdescriptor *req_bss;
2824 s32 i;
2825
2826 memset(req_ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
2827
2828 i = mwifiex_find_best_network_in_list(priv);
2829
2830 if (i >= 0) {
2831 req_bss = &adapter->scan_table[i];
2832 memcpy(&req_ssid_bssid->ssid, &req_bss->ssid,
2833 sizeof(struct mwifiex_802_11_ssid));
2834 memcpy((u8 *) &req_ssid_bssid->bssid,
2835 (u8 *) &req_bss->mac_address, ETH_ALEN);
2836
2837 /* Make sure we are in the right mode */
2838 if (priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED)
2839 priv->bss_mode = req_bss->bss_mode;
2840 }
2841
2842 if (!req_ssid_bssid->ssid.ssid_len)
2843 return -1;
2844
2845 dev_dbg(adapter->dev, "info: Best network found = [%s], "
2846 "[%pM]\n", req_ssid_bssid->ssid.ssid,
2847 req_ssid_bssid->bssid);
2848
2849 return 0;
2850}
2851
2852/*
2853 * This function sends a scan command for all available channels to the 1845 * This function sends a scan command for all available channels to the
2854 * firmware, filtered on a specific SSID. 1846 * firmware, filtered on a specific SSID.
2855 */ 1847 */
@@ -2874,8 +1866,6 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
2874 return ret; 1866 return ret;
2875 } 1867 }
2876 1868
2877 mwifiex_scan_delete_ssid_table_entry(priv, req_ssid);
2878
2879 scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); 1869 scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
2880 if (!scan_cfg) { 1870 if (!scan_cfg) {
2881 dev_err(adapter->dev, "failed to alloc scan_cfg\n"); 1871 dev_err(adapter->dev, "failed to alloc scan_cfg\n");
@@ -2884,7 +1874,6 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
2884 1874
2885 memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid, 1875 memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid,
2886 req_ssid->ssid_len); 1876 req_ssid->ssid_len);
2887 scan_cfg->keep_previous_scan = true;
2888 1877
2889 ret = mwifiex_scan_networks(priv, scan_cfg); 1878 ret = mwifiex_scan_networks(priv, scan_cfg);
2890 1879
@@ -3010,6 +1999,39 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv)
3010 curr_bss->beacon_buf_size); 1999 curr_bss->beacon_buf_size);
3011 dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n", 2000 dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n",
3012 priv->curr_bcn_size); 2001 priv->curr_bcn_size);
2002
2003 curr_bss->beacon_buf = priv->curr_bcn_buf;
2004
2005 /* adjust the pointers in the current BSS descriptor */
2006 if (curr_bss->bcn_wpa_ie)
2007 curr_bss->bcn_wpa_ie =
2008 (struct ieee_types_vendor_specific *)
2009 (curr_bss->beacon_buf +
2010 curr_bss->wpa_offset);
2011
2012 if (curr_bss->bcn_rsn_ie)
2013 curr_bss->bcn_rsn_ie = (struct ieee_types_generic *)
2014 (curr_bss->beacon_buf +
2015 curr_bss->rsn_offset);
2016
2017 if (curr_bss->bcn_ht_cap)
2018 curr_bss->bcn_ht_cap = (struct ieee80211_ht_cap *)
2019 (curr_bss->beacon_buf +
2020 curr_bss->ht_cap_offset);
2021
2022 if (curr_bss->bcn_ht_info)
2023 curr_bss->bcn_ht_info = (struct ieee80211_ht_info *)
2024 (curr_bss->beacon_buf +
2025 curr_bss->ht_info_offset);
2026
2027 if (curr_bss->bcn_bss_co_2040)
2028 curr_bss->bcn_bss_co_2040 =
2029 (u8 *) (curr_bss->beacon_buf +
2030 curr_bss->bss_co_2040_offset);
2031
2032 if (curr_bss->bcn_ext_cap)
2033 curr_bss->bcn_ext_cap = (u8 *) (curr_bss->beacon_buf +
2034 curr_bss->ext_cap_offset);
3013} 2035}
3014 2036
3015/* 2037/*
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index fc265cab090..f204810e833 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -130,8 +130,8 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
130 if (netif_carrier_ok(priv->netdev)) 130 if (netif_carrier_ok(priv->netdev))
131 netif_carrier_off(priv->netdev); 131 netif_carrier_off(priv->netdev);
132 /* Reset wireless stats signal info */ 132 /* Reset wireless stats signal info */
133 priv->w_stats.qual.level = 0; 133 priv->qual_level = 0;
134 priv->w_stats.qual.noise = 0; 134 priv->qual_noise = 0;
135} 135}
136 136
137/* 137/*
@@ -299,11 +299,6 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
299 299
300 case EVENT_BG_SCAN_REPORT: 300 case EVENT_BG_SCAN_REPORT:
301 dev_dbg(adapter->dev, "event: BGS_REPORT\n"); 301 dev_dbg(adapter->dev, "event: BGS_REPORT\n");
302 /* Clear the previous scan result */
303 memset(adapter->scan_table, 0x00,
304 sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP);
305 adapter->num_in_scan_table = 0;
306 adapter->bcn_buf_end = adapter->bcn_buf;
307 ret = mwifiex_send_cmd_async(priv, 302 ret = mwifiex_send_cmd_async(priv,
308 HostCmd_CMD_802_11_BG_SCAN_QUERY, 303 HostCmd_CMD_802_11_BG_SCAN_QUERY,
309 HostCmd_ACT_GEN_GET, 0, NULL); 304 HostCmd_ACT_GEN_GET, 0, NULL);
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index c34ff8c4f4f..3fca219bcfb 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -142,90 +142,142 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
142} 142}
143 143
144/* 144/*
145 * This function fills bss descriptor structure using provided
146 * information.
147 */
148int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
149 u8 *bssid, s32 rssi, u8 *ie_buf,
150 size_t ie_len, u16 beacon_period,
151 u16 cap_info_bitmap,
152 struct mwifiex_bssdescriptor *bss_desc)
153{
154 int ret;
155
156 memcpy(bss_desc->mac_address, bssid, ETH_ALEN);
157 bss_desc->rssi = rssi;
158 bss_desc->beacon_buf = ie_buf;
159 bss_desc->beacon_buf_size = ie_len;
160 bss_desc->beacon_period = beacon_period;
161 bss_desc->cap_info_bitmap = cap_info_bitmap;
162 if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) {
163 dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n");
164 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
165 } else {
166 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
167 }
168 if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_IBSS)
169 bss_desc->bss_mode = NL80211_IFTYPE_ADHOC;
170 else
171 bss_desc->bss_mode = NL80211_IFTYPE_STATION;
172
173 ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc,
174 ie_buf, ie_len);
175
176 return ret;
177}
178
179/*
145 * In Ad-Hoc mode, the IBSS is created if not found in scan list. 180 * In Ad-Hoc mode, the IBSS is created if not found in scan list.
146 * In both Ad-Hoc and infra mode, an deauthentication is performed 181 * In both Ad-Hoc and infra mode, an deauthentication is performed
147 * first. 182 * first.
148 */ 183 */
149int mwifiex_bss_start(struct mwifiex_private *priv, 184int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
150 struct mwifiex_ssid_bssid *ssid_bssid) 185 struct mwifiex_802_11_ssid *req_ssid)
151{ 186{
152 int ret; 187 int ret;
153 struct mwifiex_adapter *adapter = priv->adapter; 188 struct mwifiex_adapter *adapter = priv->adapter;
154 s32 i = -1; 189 struct mwifiex_bssdescriptor *bss_desc = NULL;
190 u8 *beacon_ie = NULL;
155 191
156 priv->scan_block = false; 192 priv->scan_block = false;
157 if (!ssid_bssid) 193
158 return -1; 194 if (bss) {
195 /* Allocate and fill new bss descriptor */
196 bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor),
197 GFP_KERNEL);
198 if (!bss_desc) {
199 dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
200 return -ENOMEM;
201 }
202 beacon_ie = kzalloc(bss->len_beacon_ies, GFP_KERNEL);
203 if (!beacon_ie) {
204 dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
205 return -ENOMEM;
206 }
207 memcpy(beacon_ie, bss->information_elements,
208 bss->len_beacon_ies);
209 ret = mwifiex_fill_new_bss_desc(priv, bss->bssid, bss->signal,
210 beacon_ie, bss->len_beacon_ies,
211 bss->beacon_interval,
212 bss->capability, bss_desc);
213 if (ret)
214 goto done;
215 }
159 216
160 if (priv->bss_mode == NL80211_IFTYPE_STATION) { 217 if (priv->bss_mode == NL80211_IFTYPE_STATION) {
161 /* Infra mode */ 218 /* Infra mode */
162 ret = mwifiex_deauthenticate(priv, NULL); 219 ret = mwifiex_deauthenticate(priv, NULL);
163 if (ret) 220 if (ret)
164 return ret; 221 goto done;
165 222
166 /* Search for the requested SSID in the scan table */ 223 ret = mwifiex_check_network_compatibility(priv, bss_desc);
167 if (ssid_bssid->ssid.ssid_len) 224 if (ret)
168 i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid, 225 goto done;
169 NULL, NL80211_IFTYPE_STATION); 226
170 else 227 dev_dbg(adapter->dev, "info: SSID found in scan list ... "
171 i = mwifiex_find_bssid_in_list(priv, 228 "associating...\n");
172 (u8 *) &ssid_bssid->bssid,
173 NL80211_IFTYPE_STATION);
174 if (i < 0)
175 return -1;
176 229
177 dev_dbg(adapter->dev, 230 if (!netif_queue_stopped(priv->netdev))
178 "info: SSID found in scan list ... associating...\n"); 231 netif_stop_queue(priv->netdev);
179 232
180 /* Clear any past association response stored for 233 /* Clear any past association response stored for
181 * application retrieval */ 234 * application retrieval */
182 priv->assoc_rsp_size = 0; 235 priv->assoc_rsp_size = 0;
183 ret = mwifiex_associate(priv, &adapter->scan_table[i]); 236 ret = mwifiex_associate(priv, bss_desc);
184 if (ret) 237 if (bss)
185 return ret; 238 cfg80211_put_bss(bss);
186 } else { 239 } else {
187 /* Adhoc mode */ 240 /* Adhoc mode */
188 /* If the requested SSID matches current SSID, return */ 241 /* If the requested SSID matches current SSID, return */
189 if (ssid_bssid->ssid.ssid_len && 242 if (bss_desc && bss_desc->ssid.ssid_len &&
190 (!mwifiex_ssid_cmp 243 (!mwifiex_ssid_cmp
191 (&priv->curr_bss_params.bss_descriptor.ssid, 244 (&priv->curr_bss_params.bss_descriptor.ssid,
192 &ssid_bssid->ssid))) 245 &bss_desc->ssid))) {
246 kfree(bss_desc);
247 kfree(beacon_ie);
193 return 0; 248 return 0;
249 }
194 250
195 /* Exit Adhoc mode first */ 251 /* Exit Adhoc mode first */
196 dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n"); 252 dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n");
197 ret = mwifiex_deauthenticate(priv, NULL); 253 ret = mwifiex_deauthenticate(priv, NULL);
198 if (ret) 254 if (ret)
199 return ret; 255 goto done;
200 256
201 priv->adhoc_is_link_sensed = false; 257 priv->adhoc_is_link_sensed = false;
202 258
203 /* Search for the requested network in the scan table */ 259 ret = mwifiex_check_network_compatibility(priv, bss_desc);
204 if (ssid_bssid->ssid.ssid_len) 260
205 i = mwifiex_find_ssid_in_list(priv, 261 if (!netif_queue_stopped(priv->netdev))
206 &ssid_bssid->ssid, NULL, 262 netif_stop_queue(priv->netdev);
207 NL80211_IFTYPE_ADHOC); 263
208 else 264 if (!ret) {
209 i = mwifiex_find_bssid_in_list(priv,
210 (u8 *)&ssid_bssid->bssid,
211 NL80211_IFTYPE_ADHOC);
212
213 if (i >= 0) {
214 dev_dbg(adapter->dev, "info: network found in scan" 265 dev_dbg(adapter->dev, "info: network found in scan"
215 " list. Joining...\n"); 266 " list. Joining...\n");
216 ret = mwifiex_adhoc_join(priv, &adapter->scan_table[i]); 267 ret = mwifiex_adhoc_join(priv, bss_desc);
217 if (ret) 268 if (bss)
218 return ret; 269 cfg80211_put_bss(bss);
219 } else { 270 } else {
220 dev_dbg(adapter->dev, "info: Network not found in " 271 dev_dbg(adapter->dev, "info: Network not found in "
221 "the list, creating adhoc with ssid = %s\n", 272 "the list, creating adhoc with ssid = %s\n",
222 ssid_bssid->ssid.ssid); 273 req_ssid->ssid);
223 ret = mwifiex_adhoc_start(priv, &ssid_bssid->ssid); 274 ret = mwifiex_adhoc_start(priv, req_ssid);
224 if (ret)
225 return ret;
226 } 275 }
227 } 276 }
228 277
278done:
279 kfree(bss_desc);
280 kfree(beacon_ie);
229 return ret; 281 return ret;
230} 282}
231 283
@@ -376,7 +428,6 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv,
376{ 428{
377 struct mwifiex_adapter *adapter = priv->adapter; 429 struct mwifiex_adapter *adapter = priv->adapter;
378 struct mwifiex_bssdescriptor *bss_desc; 430 struct mwifiex_bssdescriptor *bss_desc;
379 s32 tbl_idx;
380 431
381 if (!info) 432 if (!info)
382 return -1; 433 return -1;
@@ -394,17 +445,6 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv,
394 445
395 info->region_code = adapter->region_code; 446 info->region_code = adapter->region_code;
396 447
397 /* Scan table index if connected */
398 info->scan_table_idx = 0;
399 if (priv->media_connected) {
400 tbl_idx =
401 mwifiex_find_ssid_in_list(priv, &bss_desc->ssid,
402 bss_desc->mac_address,
403 priv->bss_mode);
404 if (tbl_idx >= 0)
405 info->scan_table_idx = tbl_idx;
406 }
407
408 info->media_connected = priv->media_connected; 448 info->media_connected = priv->media_connected;
409 449
410 info->max_power_level = priv->max_tx_power_level; 450 info->max_power_level = priv->max_tx_power_level;
@@ -586,50 +626,6 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
586} 626}
587 627
588/* 628/*
589 * IOCTL request handler to find a particular BSS.
590 *
591 * The BSS can be searched with either a BSSID or a SSID. If none of
592 * these are provided, just the best BSS (best RSSI) is returned.
593 */
594int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv,
595 struct mwifiex_ssid_bssid *ssid_bssid)
596{
597 struct mwifiex_adapter *adapter = priv->adapter;
598 struct mwifiex_bssdescriptor *bss_desc;
599 u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
600 u8 mac[ETH_ALEN];
601 int i = 0;
602
603 if (memcmp(ssid_bssid->bssid, zero_mac, sizeof(zero_mac))) {
604 i = mwifiex_find_bssid_in_list(priv,
605 (u8 *) ssid_bssid->bssid,
606 priv->bss_mode);
607 if (i < 0) {
608 memcpy(mac, ssid_bssid->bssid, sizeof(mac));
609 dev_err(adapter->dev, "cannot find bssid %pM\n", mac);
610 return -1;
611 }
612 bss_desc = &adapter->scan_table[i];
613 memcpy(&ssid_bssid->ssid, &bss_desc->ssid,
614 sizeof(struct mwifiex_802_11_ssid));
615 } else if (ssid_bssid->ssid.ssid_len) {
616 i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid, NULL,
617 priv->bss_mode);
618 if (i < 0) {
619 dev_err(adapter->dev, "cannot find ssid %s\n",
620 ssid_bssid->ssid.ssid);
621 return -1;
622 }
623 bss_desc = &adapter->scan_table[i];
624 memcpy(ssid_bssid->bssid, bss_desc->mac_address, ETH_ALEN);
625 } else {
626 return mwifiex_find_best_network(priv, ssid_bssid);
627 }
628
629 return 0;
630}
631
632/*
633 * IOCTL request handler to change Ad-Hoc channel. 629 * IOCTL request handler to change Ad-Hoc channel.
634 * 630 *
635 * This function allocates the IOCTL request buffer, fills it 631 * This function allocates the IOCTL request buffer, fills it
@@ -653,6 +649,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
653 struct mwifiex_bss_info bss_info; 649 struct mwifiex_bss_info bss_info;
654 struct mwifiex_ssid_bssid ssid_bssid; 650 struct mwifiex_ssid_bssid ssid_bssid;
655 u16 curr_chan = 0; 651 u16 curr_chan = 0;
652 struct cfg80211_bss *bss = NULL;
653 struct ieee80211_channel *chan;
656 654
657 memset(&bss_info, 0, sizeof(bss_info)); 655 memset(&bss_info, 0, sizeof(bss_info));
658 656
@@ -688,12 +686,20 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
688 ret = -1; 686 ret = -1;
689 goto done; 687 goto done;
690 } 688 }
691 /* Start/Join Adhoc network */
692 memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
693 memcpy(&ssid_bssid.ssid, &bss_info.ssid,
694 sizeof(struct mwifiex_802_11_ssid));
695 689
696 ret = mwifiex_bss_start(priv, &ssid_bssid); 690 chan = __ieee80211_get_channel(priv->wdev->wiphy,
691 ieee80211_channel_to_frequency(channel,
692 priv->curr_bss_params.band));
693
694 /* Find the BSS we want using available scan results */
695 bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid,
696 bss_info.ssid.ssid, bss_info.ssid.ssid_len,
697 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
698 if (!bss)
699 wiphy_warn(priv->wdev->wiphy, "assoc: bss %pM not in scan results\n",
700 bss_info.bssid);
701
702 ret = mwifiex_bss_start(priv, bss, &bss_info.ssid);
697done: 703done:
698 return ret; 704 return ret;
699} 705}
@@ -1280,9 +1286,9 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv,
1280 1286
1281 if (!status) { 1287 if (!status) {
1282 if (signal->selector & BCN_RSSI_AVG_MASK) 1288 if (signal->selector & BCN_RSSI_AVG_MASK)
1283 priv->w_stats.qual.level = signal->bcn_rssi_avg; 1289 priv->qual_level = signal->bcn_rssi_avg;
1284 if (signal->selector & BCN_NF_AVG_MASK) 1290 if (signal->selector & BCN_NF_AVG_MASK)
1285 priv->w_stats.qual.noise = signal->bcn_nf_avg; 1291 priv->qual_noise = signal->bcn_nf_avg;
1286 } 1292 }
1287 1293
1288 return status; 1294 return status;
@@ -1341,18 +1347,8 @@ int
1341mwifiex_get_stats_info(struct mwifiex_private *priv, 1347mwifiex_get_stats_info(struct mwifiex_private *priv,
1342 struct mwifiex_ds_get_stats *log) 1348 struct mwifiex_ds_get_stats *log)
1343{ 1349{
1344 int ret; 1350 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG,
1345
1346 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG,
1347 HostCmd_ACT_GEN_GET, 0, log); 1351 HostCmd_ACT_GEN_GET, 0, log);
1348
1349 if (!ret) {
1350 priv->w_stats.discard.fragment = log->fcs_error;
1351 priv->w_stats.discard.retries = log->retry;
1352 priv->w_stats.discard.misc = log->ack_failure;
1353 }
1354
1355 return ret;
1356} 1352}
1357 1353
1358/* 1354/*
@@ -1594,7 +1590,7 @@ mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len)
1594{ 1590{
1595 struct mwifiex_ds_misc_gen_ie gen_ie; 1591 struct mwifiex_ds_misc_gen_ie gen_ie;
1596 1592
1597 if (ie_len > IW_CUSTOM_MAX) 1593 if (ie_len > IEEE_MAX_IE_SIZE)
1598 return -EFAULT; 1594 return -EFAULT;
1599 1595
1600 gen_ie.type = MWIFIEX_IE_TYPE_GEN_IE; 1596 gen_ie.type = MWIFIEX_IE_TYPE_GEN_IE;
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index bbb9beb206b..33747e131a9 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -9,6 +9,7 @@
9#include <linux/ieee80211.h> 9#include <linux/ieee80211.h>
10#include <net/iw_handler.h> 10#include <net/iw_handler.h>
11#include <net/cfg80211.h> 11#include <net/cfg80211.h>
12#include <net/cfg80211-wext.h>
12 13
13#include "hermes.h" 14#include "hermes.h"
14#include "hermes_rid.h" 15#include "hermes_rid.h"
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 6e0c61145b1..0c13840a7de 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -36,13 +36,11 @@
36#include <linux/mii.h> 36#include <linux/mii.h>
37#include <linux/usb.h> 37#include <linux/usb.h>
38#include <linux/usb/cdc.h> 38#include <linux/usb/cdc.h>
39#include <linux/wireless.h>
40#include <linux/ieee80211.h> 39#include <linux/ieee80211.h>
41#include <linux/if_arp.h> 40#include <linux/if_arp.h>
42#include <linux/ctype.h> 41#include <linux/ctype.h>
43#include <linux/spinlock.h> 42#include <linux/spinlock.h>
44#include <linux/slab.h> 43#include <linux/slab.h>
45#include <net/iw_handler.h>
46#include <net/cfg80211.h> 44#include <net/cfg80211.h>
47#include <linux/usb/usbnet.h> 45#include <linux/usb/usbnet.h>
48#include <linux/usb/rndis_host.h> 46#include <linux/usb/rndis_host.h>
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 76bcc354797..daa32fc9398 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -645,11 +645,6 @@ static void rt2400pci_start_queue(struct data_queue *queue)
645 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); 645 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
646 break; 646 break;
647 case QID_BEACON: 647 case QID_BEACON:
648 /*
649 * Allow the tbtt tasklet to be scheduled.
650 */
651 tasklet_enable(&rt2x00dev->tbtt_tasklet);
652
653 rt2x00pci_register_read(rt2x00dev, CSR14, &reg); 648 rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
654 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1); 649 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
655 rt2x00_set_field32(&reg, CSR14_TBCN, 1); 650 rt2x00_set_field32(&reg, CSR14_TBCN, 1);
@@ -715,7 +710,7 @@ static void rt2400pci_stop_queue(struct data_queue *queue)
715 /* 710 /*
716 * Wait for possibly running tbtt tasklets. 711 * Wait for possibly running tbtt tasklets.
717 */ 712 */
718 tasklet_disable(&rt2x00dev->tbtt_tasklet); 713 tasklet_kill(&rt2x00dev->tbtt_tasklet);
719 break; 714 break;
720 default: 715 default:
721 break; 716 break;
@@ -982,12 +977,6 @@ static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
982 if (state == STATE_RADIO_IRQ_ON) { 977 if (state == STATE_RADIO_IRQ_ON) {
983 rt2x00pci_register_read(rt2x00dev, CSR7, &reg); 978 rt2x00pci_register_read(rt2x00dev, CSR7, &reg);
984 rt2x00pci_register_write(rt2x00dev, CSR7, reg); 979 rt2x00pci_register_write(rt2x00dev, CSR7, reg);
985
986 /*
987 * Enable tasklets.
988 */
989 tasklet_enable(&rt2x00dev->txstatus_tasklet);
990 tasklet_enable(&rt2x00dev->rxdone_tasklet);
991 } 980 }
992 981
993 /* 982 /*
@@ -1011,8 +1000,9 @@ static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
1011 * Ensure that all tasklets are finished before 1000 * Ensure that all tasklets are finished before
1012 * disabling the interrupts. 1001 * disabling the interrupts.
1013 */ 1002 */
1014 tasklet_disable(&rt2x00dev->txstatus_tasklet); 1003 tasklet_kill(&rt2x00dev->txstatus_tasklet);
1015 tasklet_disable(&rt2x00dev->rxdone_tasklet); 1004 tasklet_kill(&rt2x00dev->rxdone_tasklet);
1005 tasklet_kill(&rt2x00dev->tbtt_tasklet);
1016 } 1006 }
1017} 1007}
1018 1008
@@ -1347,22 +1337,25 @@ static void rt2400pci_txstatus_tasklet(unsigned long data)
1347 /* 1337 /*
1348 * Enable all TXDONE interrupts again. 1338 * Enable all TXDONE interrupts again.
1349 */ 1339 */
1350 spin_lock_irq(&rt2x00dev->irqmask_lock); 1340 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
1341 spin_lock_irq(&rt2x00dev->irqmask_lock);
1351 1342
1352 rt2x00pci_register_read(rt2x00dev, CSR8, &reg); 1343 rt2x00pci_register_read(rt2x00dev, CSR8, &reg);
1353 rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, 0); 1344 rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, 0);
1354 rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, 0); 1345 rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, 0);
1355 rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, 0); 1346 rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, 0);
1356 rt2x00pci_register_write(rt2x00dev, CSR8, reg); 1347 rt2x00pci_register_write(rt2x00dev, CSR8, reg);
1357 1348
1358 spin_unlock_irq(&rt2x00dev->irqmask_lock); 1349 spin_unlock_irq(&rt2x00dev->irqmask_lock);
1350 }
1359} 1351}
1360 1352
1361static void rt2400pci_tbtt_tasklet(unsigned long data) 1353static void rt2400pci_tbtt_tasklet(unsigned long data)
1362{ 1354{
1363 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 1355 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
1364 rt2x00lib_beacondone(rt2x00dev); 1356 rt2x00lib_beacondone(rt2x00dev);
1365 rt2400pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE); 1357 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1358 rt2400pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE);
1366} 1359}
1367 1360
1368static void rt2400pci_rxdone_tasklet(unsigned long data) 1361static void rt2400pci_rxdone_tasklet(unsigned long data)
@@ -1370,7 +1363,7 @@ static void rt2400pci_rxdone_tasklet(unsigned long data)
1370 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 1363 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
1371 if (rt2x00pci_rxdone(rt2x00dev)) 1364 if (rt2x00pci_rxdone(rt2x00dev))
1372 tasklet_schedule(&rt2x00dev->rxdone_tasklet); 1365 tasklet_schedule(&rt2x00dev->rxdone_tasklet);
1373 else 1366 else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1374 rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); 1367 rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
1375} 1368}
1376 1369
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index c288d951c03..b46c3b8866f 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -735,11 +735,6 @@ static void rt2500pci_start_queue(struct data_queue *queue)
735 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); 735 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
736 break; 736 break;
737 case QID_BEACON: 737 case QID_BEACON:
738 /*
739 * Allow the tbtt tasklet to be scheduled.
740 */
741 tasklet_enable(&rt2x00dev->tbtt_tasklet);
742
743 rt2x00pci_register_read(rt2x00dev, CSR14, &reg); 738 rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
744 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1); 739 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
745 rt2x00_set_field32(&reg, CSR14_TBCN, 1); 740 rt2x00_set_field32(&reg, CSR14_TBCN, 1);
@@ -805,7 +800,7 @@ static void rt2500pci_stop_queue(struct data_queue *queue)
805 /* 800 /*
806 * Wait for possibly running tbtt tasklets. 801 * Wait for possibly running tbtt tasklets.
807 */ 802 */
808 tasklet_disable(&rt2x00dev->tbtt_tasklet); 803 tasklet_kill(&rt2x00dev->tbtt_tasklet);
809 break; 804 break;
810 default: 805 default:
811 break; 806 break;
@@ -1137,12 +1132,6 @@ static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
1137 if (state == STATE_RADIO_IRQ_ON) { 1132 if (state == STATE_RADIO_IRQ_ON) {
1138 rt2x00pci_register_read(rt2x00dev, CSR7, &reg); 1133 rt2x00pci_register_read(rt2x00dev, CSR7, &reg);
1139 rt2x00pci_register_write(rt2x00dev, CSR7, reg); 1134 rt2x00pci_register_write(rt2x00dev, CSR7, reg);
1140
1141 /*
1142 * Enable tasklets.
1143 */
1144 tasklet_enable(&rt2x00dev->txstatus_tasklet);
1145 tasklet_enable(&rt2x00dev->rxdone_tasklet);
1146 } 1135 }
1147 1136
1148 /* 1137 /*
@@ -1165,8 +1154,9 @@ static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
1165 /* 1154 /*
1166 * Ensure that all tasklets are finished. 1155 * Ensure that all tasklets are finished.
1167 */ 1156 */
1168 tasklet_disable(&rt2x00dev->txstatus_tasklet); 1157 tasklet_kill(&rt2x00dev->txstatus_tasklet);
1169 tasklet_disable(&rt2x00dev->rxdone_tasklet); 1158 tasklet_kill(&rt2x00dev->rxdone_tasklet);
1159 tasklet_kill(&rt2x00dev->tbtt_tasklet);
1170 } 1160 }
1171} 1161}
1172 1162
@@ -1479,22 +1469,25 @@ static void rt2500pci_txstatus_tasklet(unsigned long data)
1479 /* 1469 /*
1480 * Enable all TXDONE interrupts again. 1470 * Enable all TXDONE interrupts again.
1481 */ 1471 */
1482 spin_lock_irq(&rt2x00dev->irqmask_lock); 1472 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
1473 spin_lock_irq(&rt2x00dev->irqmask_lock);
1483 1474
1484 rt2x00pci_register_read(rt2x00dev, CSR8, &reg); 1475 rt2x00pci_register_read(rt2x00dev, CSR8, &reg);
1485 rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, 0); 1476 rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, 0);
1486 rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, 0); 1477 rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, 0);
1487 rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, 0); 1478 rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, 0);
1488 rt2x00pci_register_write(rt2x00dev, CSR8, reg); 1479 rt2x00pci_register_write(rt2x00dev, CSR8, reg);
1489 1480
1490 spin_unlock_irq(&rt2x00dev->irqmask_lock); 1481 spin_unlock_irq(&rt2x00dev->irqmask_lock);
1482 }
1491} 1483}
1492 1484
1493static void rt2500pci_tbtt_tasklet(unsigned long data) 1485static void rt2500pci_tbtt_tasklet(unsigned long data)
1494{ 1486{
1495 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 1487 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
1496 rt2x00lib_beacondone(rt2x00dev); 1488 rt2x00lib_beacondone(rt2x00dev);
1497 rt2500pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE); 1489 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1490 rt2500pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE);
1498} 1491}
1499 1492
1500static void rt2500pci_rxdone_tasklet(unsigned long data) 1493static void rt2500pci_rxdone_tasklet(unsigned long data)
@@ -1502,7 +1495,7 @@ static void rt2500pci_rxdone_tasklet(unsigned long data)
1502 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 1495 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
1503 if (rt2x00pci_rxdone(rt2x00dev)) 1496 if (rt2x00pci_rxdone(rt2x00dev))
1504 tasklet_schedule(&rt2x00dev->rxdone_tasklet); 1497 tasklet_schedule(&rt2x00dev->rxdone_tasklet);
1505 else 1498 else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1506 rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); 1499 rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
1507} 1500}
1508 1501
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index ebc17ad61de..cabf249aa55 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -200,13 +200,6 @@ static void rt2800pci_start_queue(struct data_queue *queue)
200 rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); 200 rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
201 break; 201 break;
202 case QID_BEACON: 202 case QID_BEACON:
203 /*
204 * Allow beacon tasklets to be scheduled for periodic
205 * beacon updates.
206 */
207 tasklet_enable(&rt2x00dev->tbtt_tasklet);
208 tasklet_enable(&rt2x00dev->pretbtt_tasklet);
209
210 rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, &reg); 203 rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
211 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1); 204 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
212 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1); 205 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
@@ -269,10 +262,13 @@ static void rt2800pci_stop_queue(struct data_queue *queue)
269 rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg); 262 rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg);
270 263
271 /* 264 /*
272 * Wait for tbtt tasklets to finish. 265 * Wait for current invocation to finish. The tasklet
266 * won't be scheduled anymore afterwards since we disabled
267 * the TBTT and PRE TBTT timer.
273 */ 268 */
274 tasklet_disable(&rt2x00dev->tbtt_tasklet); 269 tasklet_kill(&rt2x00dev->tbtt_tasklet);
275 tasklet_disable(&rt2x00dev->pretbtt_tasklet); 270 tasklet_kill(&rt2x00dev->pretbtt_tasklet);
271
276 break; 272 break;
277 default: 273 default:
278 break; 274 break;
@@ -437,14 +433,6 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
437 if (state == STATE_RADIO_IRQ_ON) { 433 if (state == STATE_RADIO_IRQ_ON) {
438 rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, &reg); 434 rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
439 rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); 435 rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
440
441 /*
442 * Enable tasklets. The beacon related tasklets are
443 * enabled when the beacon queue is started.
444 */
445 tasklet_enable(&rt2x00dev->txstatus_tasklet);
446 tasklet_enable(&rt2x00dev->rxdone_tasklet);
447 tasklet_enable(&rt2x00dev->autowake_tasklet);
448 } 436 }
449 437
450 spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); 438 spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);
@@ -472,12 +460,13 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
472 460
473 if (state == STATE_RADIO_IRQ_OFF) { 461 if (state == STATE_RADIO_IRQ_OFF) {
474 /* 462 /*
475 * Ensure that all tasklets are finished before 463 * Wait for possibly running tasklets to finish.
476 * disabling the interrupts.
477 */ 464 */
478 tasklet_disable(&rt2x00dev->txstatus_tasklet); 465 tasklet_kill(&rt2x00dev->txstatus_tasklet);
479 tasklet_disable(&rt2x00dev->rxdone_tasklet); 466 tasklet_kill(&rt2x00dev->rxdone_tasklet);
480 tasklet_disable(&rt2x00dev->autowake_tasklet); 467 tasklet_kill(&rt2x00dev->autowake_tasklet);
468 tasklet_kill(&rt2x00dev->tbtt_tasklet);
469 tasklet_kill(&rt2x00dev->pretbtt_tasklet);
481 } 470 }
482} 471}
483 472
@@ -813,14 +802,16 @@ static void rt2800pci_pretbtt_tasklet(unsigned long data)
813{ 802{
814 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 803 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
815 rt2x00lib_pretbtt(rt2x00dev); 804 rt2x00lib_pretbtt(rt2x00dev);
816 rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_PRE_TBTT); 805 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
806 rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_PRE_TBTT);
817} 807}
818 808
819static void rt2800pci_tbtt_tasklet(unsigned long data) 809static void rt2800pci_tbtt_tasklet(unsigned long data)
820{ 810{
821 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 811 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
822 rt2x00lib_beacondone(rt2x00dev); 812 rt2x00lib_beacondone(rt2x00dev);
823 rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT); 813 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
814 rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT);
824} 815}
825 816
826static void rt2800pci_rxdone_tasklet(unsigned long data) 817static void rt2800pci_rxdone_tasklet(unsigned long data)
@@ -828,7 +819,7 @@ static void rt2800pci_rxdone_tasklet(unsigned long data)
828 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 819 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
829 if (rt2x00pci_rxdone(rt2x00dev)) 820 if (rt2x00pci_rxdone(rt2x00dev))
830 tasklet_schedule(&rt2x00dev->rxdone_tasklet); 821 tasklet_schedule(&rt2x00dev->rxdone_tasklet);
831 else 822 else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
832 rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE); 823 rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE);
833} 824}
834 825
@@ -836,7 +827,8 @@ static void rt2800pci_autowake_tasklet(unsigned long data)
836{ 827{
837 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 828 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
838 rt2800pci_wakeup(rt2x00dev); 829 rt2800pci_wakeup(rt2x00dev);
839 rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_AUTO_WAKEUP); 830 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
831 rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_AUTO_WAKEUP);
840} 832}
841 833
842static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) 834static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 0955c941317..92ff6a72a2b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -946,7 +946,6 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
946 tasklet_init(&rt2x00dev->taskletname, \ 946 tasklet_init(&rt2x00dev->taskletname, \
947 rt2x00dev->ops->lib->taskletname, \ 947 rt2x00dev->ops->lib->taskletname, \
948 (unsigned long)rt2x00dev); \ 948 (unsigned long)rt2x00dev); \
949 tasklet_disable(&rt2x00dev->taskletname); \
950 } 949 }
951 950
952 RT2X00_TASKLET_INIT(txstatus_tasklet); 951 RT2X00_TASKLET_INIT(txstatus_tasklet);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 53110b83bf6..058ef4b19d1 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1142,11 +1142,6 @@ static void rt61pci_start_queue(struct data_queue *queue)
1142 rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); 1142 rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
1143 break; 1143 break;
1144 case QID_BEACON: 1144 case QID_BEACON:
1145 /*
1146 * Allow the tbtt tasklet to be scheduled.
1147 */
1148 tasklet_enable(&rt2x00dev->tbtt_tasklet);
1149
1150 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg); 1145 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
1151 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1); 1146 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
1152 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1); 1147 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
@@ -1230,7 +1225,7 @@ static void rt61pci_stop_queue(struct data_queue *queue)
1230 /* 1225 /*
1231 * Wait for possibly running tbtt tasklets. 1226 * Wait for possibly running tbtt tasklets.
1232 */ 1227 */
1233 tasklet_disable(&rt2x00dev->tbtt_tasklet); 1228 tasklet_kill(&rt2x00dev->tbtt_tasklet);
1234 break; 1229 break;
1235 default: 1230 default:
1236 break; 1231 break;
@@ -1731,13 +1726,6 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
1731 1726
1732 rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, &reg); 1727 rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, &reg);
1733 rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg); 1728 rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg);
1734
1735 /*
1736 * Enable tasklets.
1737 */
1738 tasklet_enable(&rt2x00dev->txstatus_tasklet);
1739 tasklet_enable(&rt2x00dev->rxdone_tasklet);
1740 tasklet_enable(&rt2x00dev->autowake_tasklet);
1741 } 1729 }
1742 1730
1743 /* 1731 /*
@@ -1772,9 +1760,10 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
1772 /* 1760 /*
1773 * Ensure that all tasklets are finished. 1761 * Ensure that all tasklets are finished.
1774 */ 1762 */
1775 tasklet_disable(&rt2x00dev->txstatus_tasklet); 1763 tasklet_kill(&rt2x00dev->txstatus_tasklet);
1776 tasklet_disable(&rt2x00dev->rxdone_tasklet); 1764 tasklet_kill(&rt2x00dev->rxdone_tasklet);
1777 tasklet_disable(&rt2x00dev->autowake_tasklet); 1765 tasklet_kill(&rt2x00dev->autowake_tasklet);
1766 tasklet_kill(&rt2x00dev->tbtt_tasklet);
1778 } 1767 }
1779} 1768}
1780 1769
@@ -2300,22 +2289,24 @@ static void rt61pci_txstatus_tasklet(unsigned long data)
2300{ 2289{
2301 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 2290 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
2302 rt61pci_txdone(rt2x00dev); 2291 rt61pci_txdone(rt2x00dev);
2303 rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TXDONE); 2292 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
2293 rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TXDONE);
2304} 2294}
2305 2295
2306static void rt61pci_tbtt_tasklet(unsigned long data) 2296static void rt61pci_tbtt_tasklet(unsigned long data)
2307{ 2297{
2308 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 2298 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
2309 rt2x00lib_beacondone(rt2x00dev); 2299 rt2x00lib_beacondone(rt2x00dev);
2310 rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_BEACON_DONE); 2300 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
2301 rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_BEACON_DONE);
2311} 2302}
2312 2303
2313static void rt61pci_rxdone_tasklet(unsigned long data) 2304static void rt61pci_rxdone_tasklet(unsigned long data)
2314{ 2305{
2315 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 2306 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
2316 if (rt2x00pci_rxdone(rt2x00dev)) 2307 if (rt2x00pci_rxdone(rt2x00dev))
2317 rt2x00pci_rxdone(rt2x00dev); 2308 tasklet_schedule(&rt2x00dev->rxdone_tasklet);
2318 else 2309 else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
2319 rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE); 2310 rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE);
2320} 2311}
2321 2312
@@ -2325,7 +2316,8 @@ static void rt61pci_autowake_tasklet(unsigned long data)
2325 rt61pci_wakeup(rt2x00dev); 2316 rt61pci_wakeup(rt2x00dev);
2326 rt2x00pci_register_write(rt2x00dev, 2317 rt2x00pci_register_write(rt2x00dev,
2327 M2H_CMD_DONE_CSR, 0xffffffff); 2318 M2H_CMD_DONE_CSR, 0xffffffff);
2328 rt61pci_enable_mcu_interrupt(rt2x00dev, MCU_INT_MASK_CSR_TWAKEUP); 2319 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
2320 rt61pci_enable_mcu_interrupt(rt2x00dev, MCU_INT_MASK_CSR_TWAKEUP);
2329} 2321}
2330 2322
2331static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) 2323static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance)
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 56f12358389..9983fa18065 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -218,7 +218,6 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
218 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 218 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
219 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 219 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
220 u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; 220 u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
221 u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
222 u8 num4bytes = pcipriv->ndis_adapter.num4bytes; 221 u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
223 /*Retrieve original configuration settings. */ 222 /*Retrieve original configuration settings. */
224 u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg; 223 u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg;
@@ -254,9 +253,8 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
254 udelay(50); 253 udelay(50);
255 254
256 /*4 Disable Pci Bridge ASPM */ 255 /*4 Disable Pci Bridge ASPM */
257 rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, 256 pci_write_config_byte(rtlpci->pdev, (num4bytes << 2),
258 pcicfg_addrport + (num4bytes << 2)); 257 pcibridge_linkctrlreg);
259 rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, pcibridge_linkctrlreg);
260 258
261 udelay(50); 259 udelay(50);
262} 260}
@@ -277,7 +275,6 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
277 u8 pcibridge_devnum = pcipriv->ndis_adapter.pcibridge_devnum; 275 u8 pcibridge_devnum = pcipriv->ndis_adapter.pcibridge_devnum;
278 u8 pcibridge_funcnum = pcipriv->ndis_adapter.pcibridge_funcnum; 276 u8 pcibridge_funcnum = pcipriv->ndis_adapter.pcibridge_funcnum;
279 u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; 277 u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
280 u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
281 u8 num4bytes = pcipriv->ndis_adapter.num4bytes; 278 u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
282 u16 aspmlevel; 279 u16 aspmlevel;
283 u8 u_pcibridge_aspmsetting; 280 u8 u_pcibridge_aspmsetting;
@@ -293,8 +290,6 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
293 } 290 }
294 291
295 /*4 Enable Pci Bridge ASPM */ 292 /*4 Enable Pci Bridge ASPM */
296 rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
297 pcicfg_addrport + (num4bytes << 2));
298 293
299 u_pcibridge_aspmsetting = 294 u_pcibridge_aspmsetting =
300 pcipriv->ndis_adapter.pcibridge_linkctrlreg | 295 pcipriv->ndis_adapter.pcibridge_linkctrlreg |
@@ -303,7 +298,8 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
303 if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) 298 if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL)
304 u_pcibridge_aspmsetting &= ~BIT(0); 299 u_pcibridge_aspmsetting &= ~BIT(0);
305 300
306 rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, u_pcibridge_aspmsetting); 301 pci_write_config_byte(rtlpci->pdev, (num4bytes << 2),
302 u_pcibridge_aspmsetting);
307 303
308 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 304 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
309 ("PlatformEnableASPM():PciBridge busnumber[%x], " 305 ("PlatformEnableASPM():PciBridge busnumber[%x], "
@@ -335,25 +331,18 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
335 331
336static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw) 332static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
337{ 333{
338 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 334 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
339 u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
340 335
341 bool status = false; 336 bool status = false;
342 u8 offset_e0; 337 u8 offset_e0;
343 unsigned offset_e4; 338 unsigned offset_e4;
344 339
345 rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, 340 pci_write_config_byte(rtlpci->pdev, 0xe0, 0xa0);
346 pcicfg_addrport + 0xE0);
347 rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, 0xA0);
348 341
349 rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, 342 pci_read_config_byte(rtlpci->pdev, 0xe0, &offset_e0);
350 pcicfg_addrport + 0xE0);
351 rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &offset_e0);
352 343
353 if (offset_e0 == 0xA0) { 344 if (offset_e0 == 0xA0) {
354 rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, 345 pci_read_config_dword(rtlpci->pdev, 0xe4, &offset_e4);
355 pcicfg_addrport + 0xE4);
356 rtl_pci_raw_read_port_ulong(PCI_CONF_DATA, &offset_e4);
357 if (offset_e4 & BIT(23)) 346 if (offset_e4 & BIT(23))
358 status = true; 347 status = true;
359 } 348 }
@@ -364,17 +353,15 @@ static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
364static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw) 353static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw)
365{ 354{
366 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 355 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
356 struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
367 u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset; 357 u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset;
368 u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
369 u8 linkctrl_reg; 358 u8 linkctrl_reg;
370 u8 num4bbytes; 359 u8 num4bbytes;
371 360
372 num4bbytes = (capabilityoffset + 0x10) / 4; 361 num4bbytes = (capabilityoffset + 0x10) / 4;
373 362
374 /*Read Link Control Register */ 363 /*Read Link Control Register */
375 rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, 364 pci_read_config_byte(rtlpci->pdev, (num4bbytes << 2), &linkctrl_reg);
376 pcicfg_addrport + (num4bbytes << 2));
377 rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &linkctrl_reg);
378 365
379 pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg; 366 pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg;
380} 367}
@@ -1718,10 +1705,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
1718 PCI_SLOT(bridge_pdev->devfn); 1705 PCI_SLOT(bridge_pdev->devfn);
1719 pcipriv->ndis_adapter.pcibridge_funcnum = 1706 pcipriv->ndis_adapter.pcibridge_funcnum =
1720 PCI_FUNC(bridge_pdev->devfn); 1707 PCI_FUNC(bridge_pdev->devfn);
1721 pcipriv->ndis_adapter.pcicfg_addrport =
1722 (pcipriv->ndis_adapter.pcibridge_busnum << 16) |
1723 (pcipriv->ndis_adapter.pcibridge_devnum << 11) |
1724 (pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31);
1725 pcipriv->ndis_adapter.pcibridge_pciehdr_offset = 1708 pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
1726 pci_pcie_cap(bridge_pdev); 1709 pci_pcie_cap(bridge_pdev);
1727 pcipriv->ndis_adapter.num4bytes = 1710 pcipriv->ndis_adapter.num4bytes =
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
index c53c6204674..a24e505b202 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -212,7 +212,6 @@ struct mp_adapter {
212 u16 pcibridge_vendorid; 212 u16 pcibridge_vendorid;
213 u16 pcibridge_deviceid; 213 u16 pcibridge_deviceid;
214 214
215 u32 pcicfg_addrport;
216 u8 num4bytes; 215 u8 num4bytes;
217 216
218 u8 pcibridge_pciehdr_offset; 217 u8 pcibridge_pciehdr_offset;
@@ -273,29 +272,4 @@ static inline void pci_write32_async(struct rtl_priv *rtlpriv,
273 writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); 272 writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
274} 273}
275 274
276static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val)
277{
278 outl(val, port);
279}
280
281static inline void rtl_pci_raw_write_port_uchar(u32 port, u8 val)
282{
283 outb(val, port);
284}
285
286static inline void rtl_pci_raw_read_port_uchar(u32 port, u8 *pval)
287{
288 *pval = inb(port);
289}
290
291static inline void rtl_pci_raw_read_port_ushort(u32 port, u16 *pval)
292{
293 *pval = inw(port);
294}
295
296static inline void rtl_pci_raw_read_port_ulong(u32 port, u32 *pval)
297{
298 *pval = inl(port);
299}
300
301#endif 275#endif
diff --git a/drivers/net/wireless/wl1251/cmd.h b/drivers/net/wireless/wl1251/cmd.h
index 79ca5273c9e..ee4f2b39182 100644
--- a/drivers/net/wireless/wl1251/cmd.h
+++ b/drivers/net/wireless/wl1251/cmd.h
@@ -269,7 +269,7 @@ struct cmd_join {
269 u8 bss_type; 269 u8 bss_type;
270 u8 channel; 270 u8 channel;
271 u8 ssid_len; 271 u8 ssid_len;
272 u8 ssid[IW_ESSID_MAX_SIZE]; 272 u8 ssid[IEEE80211_MAX_SSID_LEN];
273 u8 ctrl; /* JOIN_CMD_CTRL_* */ 273 u8 ctrl; /* JOIN_CMD_CTRL_* */
274 u8 tx_mgt_frame_rate; /* OBSOLETE */ 274 u8 tx_mgt_frame_rate; /* OBSOLETE */
275 u8 tx_mgt_frame_mod; /* OBSOLETE */ 275 u8 tx_mgt_frame_mod; /* OBSOLETE */
diff --git a/drivers/net/wireless/wl1251/wl12xx_80211.h b/drivers/net/wireless/wl1251/wl12xx_80211.h
index 1417b1445c3..04ed5149577 100644
--- a/drivers/net/wireless/wl1251/wl12xx_80211.h
+++ b/drivers/net/wireless/wl1251/wl12xx_80211.h
@@ -76,7 +76,7 @@ struct wl12xx_ie_header {
76 76
77struct wl12xx_ie_ssid { 77struct wl12xx_ie_ssid {
78 struct wl12xx_ie_header header; 78 struct wl12xx_ie_header header;
79 char ssid[IW_ESSID_MAX_SIZE]; 79 char ssid[IEEE80211_MAX_SSID_LEN];
80} __packed; 80} __packed;
81 81
82struct wl12xx_ie_rates { 82struct wl12xx_ie_rates {
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
index 1f7037292c1..bba077ecd94 100644
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -239,7 +239,7 @@ struct wl1271_cmd_join {
239 u8 bss_type; 239 u8 bss_type;
240 u8 channel; 240 u8 channel;
241 u8 ssid_len; 241 u8 ssid_len;
242 u8 ssid[IW_ESSID_MAX_SIZE]; 242 u8 ssid[IEEE80211_MAX_SSID_LEN];
243 u8 ctrl; /* JOIN_CMD_CTRL_* */ 243 u8 ctrl; /* JOIN_CMD_CTRL_* */
244 u8 reserved[3]; 244 u8 reserved[3];
245} __packed; 245} __packed;
@@ -528,7 +528,7 @@ struct wl1271_cmd_bss_start {
528 /* wl1271_ssid_type */ 528 /* wl1271_ssid_type */
529 u8 ssid_type; 529 u8 ssid_type;
530 u8 ssid_len; 530 u8 ssid_len;
531 u8 ssid[IW_ESSID_MAX_SIZE]; 531 u8 ssid[IEEE80211_MAX_SSID_LEN];
532 u8 padding_1[2]; 532 u8 padding_1[2];
533 533
534 /* Basic rate set */ 534 /* Basic rate set */
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index e58c22d21e3..3418299e17c 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -1997,7 +1997,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
1997 wl1271_power_off(wl); 1997 wl1271_power_off(wl);
1998 1998
1999 memset(wl->bssid, 0, ETH_ALEN); 1999 memset(wl->bssid, 0, ETH_ALEN);
2000 memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1); 2000 memset(wl->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
2001 wl->ssid_len = 0; 2001 wl->ssid_len = 0;
2002 wl->bss_type = MAX_BSS_TYPE; 2002 wl->bss_type = MAX_BSS_TYPE;
2003 wl->set_bss_type = MAX_BSS_TYPE; 2003 wl->set_bss_type = MAX_BSS_TYPE;
diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/wl12xx/scan.h
index d882e4da71b..0b2a2987439 100644
--- a/drivers/net/wireless/wl12xx/scan.h
+++ b/drivers/net/wireless/wl12xx/scan.h
@@ -77,7 +77,7 @@ struct basic_scan_params {
77 u8 ssid_len; 77 u8 ssid_len;
78 /* in order to align */ 78 /* in order to align */
79 u8 padding1[2]; 79 u8 padding1[2];
80 u8 ssid[IW_ESSID_MAX_SIZE]; 80 u8 ssid[IEEE80211_MAX_SSID_LEN];
81 /* Band to scan */ 81 /* Band to scan */
82 u8 band; 82 u8 band;
83 u8 use_ssid_list; 83 u8 use_ssid_list;
@@ -167,7 +167,7 @@ struct wl1271_cmd_sched_scan_config {
167 u8 filter_type; 167 u8 filter_type;
168 168
169 u8 ssid_len; /* For SCAN_SSID_FILTER_SPECIFIC */ 169 u8 ssid_len; /* For SCAN_SSID_FILTER_SPECIFIC */
170 u8 ssid[IW_ESSID_MAX_SIZE]; 170 u8 ssid[IEEE80211_MAX_SSID_LEN];
171 171
172 u8 n_probe_reqs; /* Number of probes requests per channel */ 172 u8 n_probe_reqs; /* Number of probes requests per channel */
173 173
@@ -194,7 +194,7 @@ enum {
194struct wl1271_ssid { 194struct wl1271_ssid {
195 u8 type; 195 u8 type;
196 u8 len; 196 u8 len;
197 u8 ssid[IW_ESSID_MAX_SIZE]; 197 u8 ssid[IEEE80211_MAX_SSID_LEN];
198 /* u8 padding[2]; */ 198 /* u8 padding[2]; */
199} __packed; 199} __packed;
200 200
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 1a8751eb814..0bc29356ebe 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -309,7 +309,7 @@ struct wl1271_scan {
309 unsigned long scanned_ch[BITS_TO_LONGS(WL1271_MAX_CHANNELS)]; 309 unsigned long scanned_ch[BITS_TO_LONGS(WL1271_MAX_CHANNELS)];
310 bool failed; 310 bool failed;
311 u8 state; 311 u8 state;
312 u8 ssid[IW_ESSID_MAX_SIZE+1]; 312 u8 ssid[IEEE80211_MAX_SSID_LEN+1];
313 size_t ssid_len; 313 size_t ssid_len;
314}; 314};
315 315
@@ -415,7 +415,7 @@ struct wl1271 {
415 u8 mac_addr[ETH_ALEN]; 415 u8 mac_addr[ETH_ALEN];
416 u8 bss_type; 416 u8 bss_type;
417 u8 set_bss_type; 417 u8 set_bss_type;
418 u8 ssid[IW_ESSID_MAX_SIZE + 1]; 418 u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
419 u8 ssid_len; 419 u8 ssid_len;
420 int channel; 420 int channel;
421 421
diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h
index 18fe542360f..f334ea08172 100644
--- a/drivers/net/wireless/wl12xx/wl12xx_80211.h
+++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h
@@ -77,7 +77,7 @@ struct wl12xx_ie_header {
77 77
78struct wl12xx_ie_ssid { 78struct wl12xx_ie_ssid {
79 struct wl12xx_ie_header header; 79 struct wl12xx_ie_header header;
80 char ssid[IW_ESSID_MAX_SIZE]; 80 char ssid[IEEE80211_MAX_SSID_LEN];
81} __packed; 81} __packed;
82 82
83struct wl12xx_ie_rates { 83struct wl12xx_ie_rates {
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 06c9081d596..d497a93748a 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -126,8 +126,6 @@ source "drivers/staging/quickstart/Kconfig"
126 126
127source "drivers/staging/sbe-2t3e3/Kconfig" 127source "drivers/staging/sbe-2t3e3/Kconfig"
128 128
129source "drivers/staging/ath6kl/Kconfig"
130
131source "drivers/staging/keucr/Kconfig" 129source "drivers/staging/keucr/Kconfig"
132 130
133source "drivers/staging/bcm/Kconfig" 131source "drivers/staging/bcm/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index f3c5e33bb26..fe6c6114a66 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -54,7 +54,6 @@ obj-$(CONFIG_SOLO6X10) += solo6x10/
54obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/ 54obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/
55obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/ 55obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/
56obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/ 56obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/
57obj-$(CONFIG_ATH6K_LEGACY) += ath6kl/
58obj-$(CONFIG_USB_ENESTORAGE) += keucr/ 57obj-$(CONFIG_USB_ENESTORAGE) += keucr/
59obj-$(CONFIG_BCM_WIMAX) += bcm/ 58obj-$(CONFIG_BCM_WIMAX) += bcm/
60obj-$(CONFIG_FT1000) += ft1000/ 59obj-$(CONFIG_FT1000) += ft1000/
diff --git a/drivers/staging/ath6kl/Kconfig b/drivers/staging/ath6kl/Kconfig
deleted file mode 100644
index afd6cc16a2b..00000000000
--- a/drivers/staging/ath6kl/Kconfig
+++ /dev/null
@@ -1,158 +0,0 @@
1config ATH6K_LEGACY
2 tristate "Atheros AR6003 support (non mac80211)"
3 depends on MMC && WLAN
4 depends on CFG80211
5 select WIRELESS_EXT
6 select WEXT_PRIV
7 help
8 This module adds support for wireless adapters based on Atheros AR6003 chipset running over SDIO. If you choose to build it as a module, it will be called ath6kl. Pls note that AR6002 and AR6001 are not supported by this driver.
9
10choice
11 prompt "AR6003 Board Data Configuration"
12 depends on ATH6K_LEGACY
13 default AR600x_SD31_XXX
14 help
15 Select the appropriate board data template from the list below that matches your AR6003 based reference design.
16
17config AR600x_SD31_XXX
18 bool "SD31-xxx"
19 help
20 Board Data file for a standard SD31 reference design (File: bdata.SD31.bin)
21
22config AR600x_WB31_XXX
23 bool "WB31-xxx"
24 help
25 Board Data file for a standard WB31 (BT/WiFi) reference design (File: bdata.WB31.bin)
26
27config AR600x_SD32_XXX
28 bool "SD32-xxx"
29 help
30 Board Data file for a standard SD32 (5GHz) reference design (File: bdata.SD32.bin)
31
32config AR600x_CUSTOM_XXX
33 bool "CUSTOM-xxx"
34 help
35 Board Data file for a custom reference design (File: should be named as bdata.CUSTOM.bin)
36endchoice
37
38config ATH6KL_ENABLE_COEXISTENCE
39 bool "BT Coexistence support"
40 depends on ATH6K_LEGACY
41 help
42 Enables WLAN/BT coexistence support. Select the apprpriate configuration from below.
43
44choice
45 prompt "Front-End Antenna Configuration"
46 depends on ATH6KL_ENABLE_COEXISTENCE
47 default AR600x_DUAL_ANTENNA
48 help
49 Indicates the number of antennas being used by BT and WLAN. Select the appropriate configuration from the list below that matches your AR6003 based reference design.
50
51config AR600x_DUAL_ANTENNA
52 bool "Dual Antenna"
53 help
54 Dual Antenna Design
55
56config AR600x_SINGLE_ANTENNA
57 bool "Single Antenna"
58 help
59 Single Antenna Design
60endchoice
61
62choice
63 prompt "Collocated Bluetooth Type"
64 depends on ATH6KL_ENABLE_COEXISTENCE
65 default AR600x_BT_AR3001
66 help
67 Select the appropriate configuration from the list below that matches your AR6003 based reference design.
68
69config AR600x_BT_QCOM
70 bool "Qualcomm BTS4020X"
71 help
72 Qualcomm BT (3 Wire PTA)
73
74config AR600x_BT_CSR
75 bool "CSR BC06"
76 help
77 CSR BT (3 Wire PTA)
78
79config AR600x_BT_AR3001
80 bool "Atheros AR3001"
81 help
82 Atheros BT (3 Wire PTA)
83endchoice
84
85config ATH6KL_HCI_BRIDGE
86 bool "HCI over SDIO support"
87 depends on ATH6K_LEGACY
88 help
89 Enables BT over SDIO. Applicable only for combo designs (eg: WB31)
90
91config ATH6KL_CONFIG_GPIO_BT_RESET
92 bool "Configure BT Reset GPIO"
93 depends on ATH6KL_HCI_BRIDGE
94 help
95 Configure a WLAN GPIO for use with BT.
96
97config AR600x_BT_RESET_PIN
98 int "GPIO"
99 depends on ATH6KL_CONFIG_GPIO_BT_RESET
100 default 22
101 help
102 WLAN GPIO to be used for resetting BT
103
104config ATH6KL_HTC_RAW_INTERFACE
105 bool "RAW HTC support"
106 depends on ATH6K_LEGACY
107 help
108 Enables raw HTC interface. Allows application to directly talk to the HTC interface via the ioctl interface
109
110config ATH6KL_VIRTUAL_SCATTER_GATHER
111 bool "Virtual Scatter-Gather support"
112 depends on ATH6K_LEGACY
113 help
114 Enables virtual scatter gather support for the hardware that does not support it natively.
115
116config ATH6KL_SKIP_ABI_VERSION_CHECK
117 bool "Skip ABI version check support"
118 depends on ATH6K_LEGACY
119 help
120 Forces the driver to disable ABI version check. Caution: Incompatilbity between the host driver and target firmware may lead to unknown side effects.
121
122config ATH6KL_BT_UART_FC_POLARITY
123 int "UART Flow Control Polarity"
124 depends on ATH6KL_LEGACY
125 default 0
126 help
127 Configures the polarity of UART Flow Control. A value of 0 implies active low and is the default setting. Set it to 1 for active high.
128
129config ATH6KL_DEBUG
130 bool "Debug support"
131 depends on ATH6K_LEGACY
132 help
133 Enables debug support
134
135config ATH6KL_ENABLE_HOST_DEBUG
136 bool "Host Debug support"
137 depends on ATH6KL_DEBUG
138 help
139 Enables debug support in the driver
140
141config ATH6KL_ENABLE_TARGET_DEBUG_PRINTS
142 bool "Target Debug support - Enable UART prints"
143 depends on ATH6KL_DEBUG
144 help
145 Enables uart prints
146
147config AR600x_DEBUG_UART_TX_PIN
148 int "GPIO"
149 depends on ATH6KL_ENABLE_TARGET_DEBUG_PRINTS
150 default 8
151 help
152 WLAN GPIO to be used for Debug UART (Tx)
153
154config ATH6KL_DISABLE_TARGET_DBGLOGS
155 bool "Target Debug support - Disable Debug logs"
156 depends on ATH6KL_DEBUG
157 help
158 Enables debug logs
diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile
deleted file mode 100644
index 1d3f2390a17..00000000000
--- a/drivers/staging/ath6kl/Makefile
+++ /dev/null
@@ -1,122 +0,0 @@
1#------------------------------------------------------------------------------
2# Copyright (c) 2004-2010 Atheros Communications Inc.
3# All rights reserved.
4#
5#
6#
7# Permission to use, copy, modify, and/or distribute this software for any
8# purpose with or without fee is hereby granted, provided that the above
9# copyright notice and this permission notice appear in all copies.
10#
11# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18#
19#
20#
21# Author(s): ="Atheros"
22#------------------------------------------------------------------------------
23
24ccflags-y += -I$(obj)/include
25ccflags-y += -I$(obj)/include/common
26ccflags-y += -I$(obj)/wlan/include
27ccflags-y += -I$(obj)/os/linux/include
28ccflags-y += -I$(obj)/os
29ccflags-y += -I$(obj)/bmi/include
30ccflags-y += -I$(obj)/include/common/AR6002/hw4.0
31
32ifeq ($(CONFIG_AR600x_DUAL_ANTENNA),y)
33ccflags-y += -DAR600x_DUAL_ANTENNA
34endif
35
36ifeq ($(CONFIG_AR600x_SINGLE_ANTENNA),y)
37ccflags-y += -DAR600x_SINGLE_ANTENNA
38endif
39
40ifeq ($(CONFIG_AR600x_BT_QCOM),y)
41ccflags-y += -DAR600x_BT_QCOM
42endif
43
44ifeq ($(CONFIG_AR600x_BT_CSR),y)
45ccflags-y += -DAR600x_BT_CSR
46endif
47
48ifeq ($(CONFIG_AR600x_BT_AR3001),y)
49ccflags-y += -DAR600x_BT_AR3001
50endif
51
52ifeq ($(CONFIG_ATH6KL_HCI_BRIDGE),y)
53ccflags-y += -DATH_AR6K_ENABLE_GMBOX
54ccflags-y += -DHCI_TRANSPORT_SDIO
55ccflags-y += -DSETUPHCI_ENABLED
56ccflags-y += -DSETUPBTDEV_ENABLED
57ath6kl-y += htc2/AR6000/ar6k_gmbox.o
58ath6kl-y += htc2/AR6000/ar6k_gmbox_hciuart.o
59ath6kl-y += miscdrv/ar3kconfig.o
60ath6kl-y += miscdrv/ar3kps/ar3kpsconfig.o
61ath6kl-y += miscdrv/ar3kps/ar3kpsparser.o
62endif
63
64ifeq ($(CONFIG_ATH6KL_CONFIG_GPIO_BT_RESET),y)
65ccflags-y += -DATH6KL_CONFIG_GPIO_BT_RESET
66endif
67
68ifeq ($(CONFIG_ATH6KL_HTC_RAW_INTERFACE),y)
69ccflags-y += -DHTC_RAW_INTERFACE
70endif
71
72ifeq ($(CONFIG_ATH6KL_ENABLE_HOST_DEBUG),y)
73ccflags-y += -DDEBUG
74ccflags-y += -DATH_DEBUG_MODULE
75endif
76
77ifeq ($(CONFIG_ATH6KL_ENABLE_TARGET_DEBUG_PRINTS),y)
78ccflags-y += -DENABLEUARTPRINT_SET
79endif
80
81ifeq ($(CONFIG_ATH6KL_DISABLE_TARGET_DBGLOGS),y)
82ccflags-y += -DATH6KL_DISABLE_TARGET_DBGLOGS
83endif
84
85ifeq ($(CONFIG_ATH6KL_VIRTUAL_SCATTER_GATHER),y)
86ccflags-y += -DATH6KL_CONFIG_HIF_VIRTUAL_SCATTER
87endif
88
89ifeq ($(CONFIG_ATH6KL_SKIP_ABI_VERSION_CHECK),y)
90ccflags-y += -DATH6KL_SKIP_ABI_VERSION_CHECK
91endif
92
93ccflags-y += -DWAPI_ENABLE
94ccflags-y += -DCHECKSUM_OFFLOAD
95
96obj-$(CONFIG_ATH6K_LEGACY) := ath6kl.o
97ath6kl-y += htc2/AR6000/ar6k.o
98ath6kl-y += htc2/AR6000/ar6k_events.o
99ath6kl-y += htc2/htc_send.o
100ath6kl-y += htc2/htc_recv.o
101ath6kl-y += htc2/htc_services.o
102ath6kl-y += htc2/htc.o
103ath6kl-y += bmi/src/bmi.o
104ath6kl-y += os/linux/cfg80211.o
105ath6kl-y += os/linux/ar6000_drv.o
106ath6kl-y += os/linux/ar6000_raw_if.o
107ath6kl-y += os/linux/ar6000_pm.o
108ath6kl-y += os/linux/netbuf.o
109ath6kl-y += os/linux/hci_bridge.o
110ath6kl-y += miscdrv/common_drv.o
111ath6kl-y += miscdrv/credit_dist.o
112ath6kl-y += wmi/wmi.o
113ath6kl-y += reorder/rcv_aggr.o
114ath6kl-y += wlan/src/wlan_node.o
115ath6kl-y += wlan/src/wlan_recv_beacon.o
116ath6kl-y += wlan/src/wlan_utils.o
117
118# ATH_HIF_TYPE := sdio
119ccflags-y += -I$(obj)/hif/sdio/linux_sdio/include
120ccflags-y += -DSDIO
121ath6kl-y += hif/sdio/linux_sdio/src/hif.o
122ath6kl-y += hif/sdio/linux_sdio/src/hif_scatter.o
diff --git a/drivers/staging/ath6kl/TODO b/drivers/staging/ath6kl/TODO
deleted file mode 100644
index 7be4b46ebb5..00000000000
--- a/drivers/staging/ath6kl/TODO
+++ /dev/null
@@ -1,25 +0,0 @@
1TODO:
2
3We are working hard on cleaning up the driver. There's sooooooooo much todo
4so instead of editing this file please use the wiki:
5
6http://wireless.kernel.org/en/users/Drivers/ath6kl
7
8There's a respective TODO page there. Please also subscribe to the wiki page
9to get e-mail updates on changes.
10
11IRC:
12
13We *really* need to coordinate development for ath6kl as the cleanup
14patches will break pretty much any other patches. Please use IRC to
15help coordinate better:
16
17irc.freenode.net
18#ath6kl
19
20Send patches to:
21
22 - Greg Kroah-Hartman <greg@kroah.com>
23 - Luis R. Rodriguez <mcgrof@gmail.com>
24 - Joe Perches <joe@perches.com>
25 - Naveen Singh <nsingh@atheros.com>
diff --git a/drivers/staging/ath6kl/bmi/include/bmi_internal.h b/drivers/staging/ath6kl/bmi/include/bmi_internal.h
deleted file mode 100644
index 8e2577074d6..00000000000
--- a/drivers/staging/ath6kl/bmi/include/bmi_internal.h
+++ /dev/null
@@ -1,54 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21//
22// Author(s): ="Atheros"
23//==============================================================================
24#ifndef BMI_INTERNAL_H
25#define BMI_INTERNAL_H
26
27#include "a_config.h"
28#include "athdefs.h"
29#include "a_osapi.h"
30#define ATH_MODULE_NAME bmi
31#include "a_debug.h"
32#include "hw/mbox_host_reg.h"
33#include "bmi_msg.h"
34
35#define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0)
36
37
38#define BMI_COMMUNICATION_TIMEOUT 100000
39
40/* ------ Global Variable Declarations ------- */
41static bool bmiDone;
42
43int
44bmiBufferSend(struct hif_device *device,
45 u8 *buffer,
46 u32 length);
47
48int
49bmiBufferReceive(struct hif_device *device,
50 u8 *buffer,
51 u32 length,
52 bool want_timeout);
53
54#endif
diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c
deleted file mode 100644
index f1f085eba9c..00000000000
--- a/drivers/staging/ath6kl/bmi/src/bmi.c
+++ /dev/null
@@ -1,1010 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="bmi.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25
26#ifdef THREAD_X
27#include <string.h>
28#endif
29
30#include "hif.h"
31#include "bmi.h"
32#include "htc_api.h"
33#include "bmi_internal.h"
34
35#ifdef ATH_DEBUG_MODULE
36static struct ath_debug_mask_description bmi_debug_desc[] = {
37 { ATH_DEBUG_BMI , "BMI Tracing"},
38};
39
40ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi,
41 "bmi",
42 "Boot Manager Interface",
43 ATH_DEBUG_MASK_DEFAULTS,
44 ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc),
45 bmi_debug_desc);
46
47#endif
48
49/*
50Although we had envisioned BMI to run on top of HTC, this is not how the
51final implementation ended up. On the Target side, BMI is a part of the BSP
52and does not use the HTC protocol nor even DMA -- it is intentionally kept
53very simple.
54*/
55
56static bool pendingEventsFuncCheck = false;
57static u32 *pBMICmdCredits;
58static u8 *pBMICmdBuf;
59#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \
60 sizeof(u32) /* cmd */ + \
61 sizeof(u32) /* addr */ + \
62 sizeof(u32))/* length */
63#define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ)
64
65/* APIs visible to the driver */
66void
67BMIInit(void)
68{
69 bmiDone = false;
70 pendingEventsFuncCheck = false;
71
72 /*
73 * On some platforms, it's not possible to DMA to a static variable
74 * in a device driver (e.g. Linux loadable driver module).
75 * So we need to A_MALLOC space for "command credits" and for commands.
76 *
77 * Note: implicitly relies on A_MALLOC to provide a buffer that is
78 * suitable for DMA (or PIO). This buffer will be passed down the
79 * bus stack.
80 */
81 if (!pBMICmdCredits) {
82 pBMICmdCredits = (u32 *)A_MALLOC_NOWAIT(4);
83 A_ASSERT(pBMICmdCredits);
84 }
85
86 if (!pBMICmdBuf) {
87 pBMICmdBuf = (u8 *)A_MALLOC_NOWAIT(MAX_BMI_CMDBUF_SZ);
88 A_ASSERT(pBMICmdBuf);
89 }
90
91 A_REGISTER_MODULE_DEBUG_INFO(bmi);
92}
93
94void
95BMICleanup(void)
96{
97 if (pBMICmdCredits) {
98 kfree(pBMICmdCredits);
99 pBMICmdCredits = NULL;
100 }
101
102 if (pBMICmdBuf) {
103 kfree(pBMICmdBuf);
104 pBMICmdBuf = NULL;
105 }
106}
107
108int
109BMIDone(struct hif_device *device)
110{
111 int status;
112 u32 cid;
113
114 if (bmiDone) {
115 AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n"));
116 return 0;
117 }
118
119 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device));
120 bmiDone = true;
121 cid = BMI_DONE;
122
123 status = bmiBufferSend(device, (u8 *)&cid, sizeof(cid));
124 if (status) {
125 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
126 return A_ERROR;
127 }
128
129 if (pBMICmdCredits) {
130 kfree(pBMICmdCredits);
131 pBMICmdCredits = NULL;
132 }
133
134 if (pBMICmdBuf) {
135 kfree(pBMICmdBuf);
136 pBMICmdBuf = NULL;
137 }
138
139 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n"));
140
141 return 0;
142}
143
144int
145BMIGetTargetInfo(struct hif_device *device, struct bmi_target_info *targ_info)
146{
147 int status;
148 u32 cid;
149
150 if (bmiDone) {
151 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
152 return A_ERROR;
153 }
154
155 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n", device));
156 cid = BMI_GET_TARGET_INFO;
157
158 status = bmiBufferSend(device, (u8 *)&cid, sizeof(cid));
159 if (status) {
160 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
161 return A_ERROR;
162 }
163
164 status = bmiBufferReceive(device, (u8 *)&targ_info->target_ver,
165 sizeof(targ_info->target_ver), true);
166 if (status) {
167 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n"));
168 return A_ERROR;
169 }
170
171 if (targ_info->target_ver == TARGET_VERSION_SENTINAL) {
172 /* Determine how many bytes are in the Target's targ_info */
173 status = bmiBufferReceive(device, (u8 *)&targ_info->target_info_byte_count,
174 sizeof(targ_info->target_info_byte_count), true);
175 if (status) {
176 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Count from the device\n"));
177 return A_ERROR;
178 }
179
180 /*
181 * The Target's targ_info doesn't match the Host's targ_info.
182 * We need to do some backwards compatibility work to make this OK.
183 */
184 A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info));
185
186 /* Read the remainder of the targ_info */
187 status = bmiBufferReceive(device,
188 ((u8 *)targ_info)+sizeof(targ_info->target_info_byte_count),
189 sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), true);
190 if (status) {
191 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d bytes) from the device\n",
192 targ_info->target_info_byte_count));
193 return A_ERROR;
194 }
195 }
196
197 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n",
198 targ_info->target_ver, targ_info->target_type));
199
200 return 0;
201}
202
203int
204BMIReadMemory(struct hif_device *device,
205 u32 address,
206 u8 *buffer,
207 u32 length)
208{
209 u32 cid;
210 int status;
211 u32 offset;
212 u32 remaining, rxlen;
213
214 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)));
215 memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length));
216
217 if (bmiDone) {
218 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
219 return A_ERROR;
220 }
221
222 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
223 ("BMI Read Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
224 device, address, length));
225
226 cid = BMI_READ_MEMORY;
227
228 remaining = length;
229
230 while (remaining)
231 {
232 rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX;
233 offset = 0;
234 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
235 offset += sizeof(cid);
236 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
237 offset += sizeof(address);
238 memcpy(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen));
239 offset += sizeof(length);
240
241 status = bmiBufferSend(device, pBMICmdBuf, offset);
242 if (status) {
243 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
244 return A_ERROR;
245 }
246 status = bmiBufferReceive(device, pBMICmdBuf, rxlen, true);
247 if (status) {
248 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
249 return A_ERROR;
250 }
251 memcpy(&buffer[length - remaining], pBMICmdBuf, rxlen);
252 remaining -= rxlen; address += rxlen;
253 }
254
255 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n"));
256 return 0;
257}
258
259int
260BMIWriteMemory(struct hif_device *device,
261 u32 address,
262 u8 *buffer,
263 u32 length)
264{
265 u32 cid;
266 int status;
267 u32 offset;
268 u32 remaining, txlen;
269 const u32 header = sizeof(cid) + sizeof(address) + sizeof(length);
270 u8 alignedBuffer[BMI_DATASZ_MAX];
271 u8 *src;
272
273 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header));
274 memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + header);
275
276 if (bmiDone) {
277 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
278 return A_ERROR;
279 }
280
281 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
282 ("BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
283 device, address, length));
284
285 cid = BMI_WRITE_MEMORY;
286
287 remaining = length;
288 while (remaining)
289 {
290 src = &buffer[length - remaining];
291 if (remaining < (BMI_DATASZ_MAX - header)) {
292 if (remaining & 3) {
293 /* align it with 4 bytes */
294 remaining = remaining + (4 - (remaining & 3));
295 memcpy(alignedBuffer, src, remaining);
296 src = alignedBuffer;
297 }
298 txlen = remaining;
299 } else {
300 txlen = (BMI_DATASZ_MAX - header);
301 }
302 offset = 0;
303 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
304 offset += sizeof(cid);
305 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
306 offset += sizeof(address);
307 memcpy(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
308 offset += sizeof(txlen);
309 memcpy(&(pBMICmdBuf[offset]), src, txlen);
310 offset += txlen;
311 status = bmiBufferSend(device, pBMICmdBuf, offset);
312 if (status) {
313 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
314 return A_ERROR;
315 }
316 remaining -= txlen; address += txlen;
317 }
318
319 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n"));
320
321 return 0;
322}
323
324int
325BMIExecute(struct hif_device *device,
326 u32 address,
327 u32 *param)
328{
329 u32 cid;
330 int status;
331 u32 offset;
332
333 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
334 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
335
336 if (bmiDone) {
337 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
338 return A_ERROR;
339 }
340
341 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
342 ("BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
343 device, address, *param));
344
345 cid = BMI_EXECUTE;
346
347 offset = 0;
348 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
349 offset += sizeof(cid);
350 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
351 offset += sizeof(address);
352 memcpy(&(pBMICmdBuf[offset]), param, sizeof(*param));
353 offset += sizeof(*param);
354 status = bmiBufferSend(device, pBMICmdBuf, offset);
355 if (status) {
356 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
357 return A_ERROR;
358 }
359
360 status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), false);
361 if (status) {
362 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
363 return A_ERROR;
364 }
365
366 memcpy(param, pBMICmdBuf, sizeof(*param));
367
368 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param));
369 return 0;
370}
371
372int
373BMISetAppStart(struct hif_device *device,
374 u32 address)
375{
376 u32 cid;
377 int status;
378 u32 offset;
379
380 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
381 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
382
383 if (bmiDone) {
384 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
385 return A_ERROR;
386 }
387
388 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
389 ("BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n",
390 device, address));
391
392 cid = BMI_SET_APP_START;
393
394 offset = 0;
395 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
396 offset += sizeof(cid);
397 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
398 offset += sizeof(address);
399 status = bmiBufferSend(device, pBMICmdBuf, offset);
400 if (status) {
401 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
402 return A_ERROR;
403 }
404
405 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n"));
406 return 0;
407}
408
409int
410BMIReadSOCRegister(struct hif_device *device,
411 u32 address,
412 u32 *param)
413{
414 u32 cid;
415 int status;
416 u32 offset;
417
418 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
419 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
420
421 if (bmiDone) {
422 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
423 return A_ERROR;
424 }
425
426 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
427 ("BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n",
428 device, address));
429
430 cid = BMI_READ_SOC_REGISTER;
431
432 offset = 0;
433 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
434 offset += sizeof(cid);
435 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
436 offset += sizeof(address);
437
438 status = bmiBufferSend(device, pBMICmdBuf, offset);
439 if (status) {
440 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
441 return A_ERROR;
442 }
443
444 status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), true);
445 if (status) {
446 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
447 return A_ERROR;
448 }
449 memcpy(param, pBMICmdBuf, sizeof(*param));
450
451 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param));
452 return 0;
453}
454
455int
456BMIWriteSOCRegister(struct hif_device *device,
457 u32 address,
458 u32 param)
459{
460 u32 cid;
461 int status;
462 u32 offset;
463
464 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
465 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
466
467 if (bmiDone) {
468 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
469 return A_ERROR;
470 }
471
472 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
473 ("BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
474 device, address, param));
475
476 cid = BMI_WRITE_SOC_REGISTER;
477
478 offset = 0;
479 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
480 offset += sizeof(cid);
481 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
482 offset += sizeof(address);
483 memcpy(&(pBMICmdBuf[offset]), &param, sizeof(param));
484 offset += sizeof(param);
485 status = bmiBufferSend(device, pBMICmdBuf, offset);
486 if (status) {
487 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
488 return A_ERROR;
489 }
490
491 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n"));
492 return 0;
493}
494
495int
496BMIrompatchInstall(struct hif_device *device,
497 u32 ROM_addr,
498 u32 RAM_addr,
499 u32 nbytes,
500 u32 do_activate,
501 u32 *rompatch_id)
502{
503 u32 cid;
504 int status;
505 u32 offset;
506
507 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
508 sizeof(nbytes) + sizeof(do_activate)));
509 memset(pBMICmdBuf, 0, sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
510 sizeof(nbytes) + sizeof(do_activate));
511
512 if (bmiDone) {
513 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
514 return A_ERROR;
515 }
516
517 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
518 ("BMI rompatch Install: Enter (device: 0x%p, ROMaddr: 0x%x, RAMaddr: 0x%x length: %d activate: %d)\n",
519 device, ROM_addr, RAM_addr, nbytes, do_activate));
520
521 cid = BMI_ROMPATCH_INSTALL;
522
523 offset = 0;
524 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
525 offset += sizeof(cid);
526 memcpy(&(pBMICmdBuf[offset]), &ROM_addr, sizeof(ROM_addr));
527 offset += sizeof(ROM_addr);
528 memcpy(&(pBMICmdBuf[offset]), &RAM_addr, sizeof(RAM_addr));
529 offset += sizeof(RAM_addr);
530 memcpy(&(pBMICmdBuf[offset]), &nbytes, sizeof(nbytes));
531 offset += sizeof(nbytes);
532 memcpy(&(pBMICmdBuf[offset]), &do_activate, sizeof(do_activate));
533 offset += sizeof(do_activate);
534 status = bmiBufferSend(device, pBMICmdBuf, offset);
535 if (status) {
536 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
537 return A_ERROR;
538 }
539
540 status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*rompatch_id), true);
541 if (status) {
542 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
543 return A_ERROR;
544 }
545 memcpy(rompatch_id, pBMICmdBuf, sizeof(*rompatch_id));
546
547 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n", *rompatch_id));
548 return 0;
549}
550
551int
552BMIrompatchUninstall(struct hif_device *device,
553 u32 rompatch_id)
554{
555 u32 cid;
556 int status;
557 u32 offset;
558
559 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(rompatch_id)));
560 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(rompatch_id));
561
562 if (bmiDone) {
563 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
564 return A_ERROR;
565 }
566
567 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
568 ("BMI rompatch Uninstall: Enter (device: 0x%p, rompatch_id: %d)\n",
569 device, rompatch_id));
570
571 cid = BMI_ROMPATCH_UNINSTALL;
572
573 offset = 0;
574 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
575 offset += sizeof(cid);
576 memcpy(&(pBMICmdBuf[offset]), &rompatch_id, sizeof(rompatch_id));
577 offset += sizeof(rompatch_id);
578 status = bmiBufferSend(device, pBMICmdBuf, offset);
579 if (status) {
580 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
581 return A_ERROR;
582 }
583
584 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch UNinstall: (rompatch_id=0x%x)\n", rompatch_id));
585 return 0;
586}
587
588static int
589_BMIrompatchChangeActivation(struct hif_device *device,
590 u32 rompatch_count,
591 u32 *rompatch_list,
592 u32 do_activate)
593{
594 u32 cid;
595 int status;
596 u32 offset;
597 u32 length;
598
599 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count)));
600 memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count));
601
602 if (bmiDone) {
603 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
604 return A_ERROR;
605 }
606
607 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
608 ("BMI Change rompatch Activation: Enter (device: 0x%p, count: %d)\n",
609 device, rompatch_count));
610
611 cid = do_activate ? BMI_ROMPATCH_ACTIVATE : BMI_ROMPATCH_DEACTIVATE;
612
613 offset = 0;
614 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
615 offset += sizeof(cid);
616 memcpy(&(pBMICmdBuf[offset]), &rompatch_count, sizeof(rompatch_count));
617 offset += sizeof(rompatch_count);
618 length = rompatch_count * sizeof(*rompatch_list);
619 memcpy(&(pBMICmdBuf[offset]), rompatch_list, length);
620 offset += length;
621 status = bmiBufferSend(device, pBMICmdBuf, offset);
622 if (status) {
623 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
624 return A_ERROR;
625 }
626
627 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Change rompatch Activation: Exit\n"));
628
629 return 0;
630}
631
632int
633BMIrompatchActivate(struct hif_device *device,
634 u32 rompatch_count,
635 u32 *rompatch_list)
636{
637 return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1);
638}
639
640int
641BMIrompatchDeactivate(struct hif_device *device,
642 u32 rompatch_count,
643 u32 *rompatch_list)
644{
645 return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0);
646}
647
648int
649BMILZData(struct hif_device *device,
650 u8 *buffer,
651 u32 length)
652{
653 u32 cid;
654 int status;
655 u32 offset;
656 u32 remaining, txlen;
657 const u32 header = sizeof(cid) + sizeof(length);
658
659 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX+header));
660 memset (pBMICmdBuf, 0, BMI_DATASZ_MAX+header);
661
662 if (bmiDone) {
663 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
664 return A_ERROR;
665 }
666
667 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
668 ("BMI Send LZ Data: Enter (device: 0x%p, length: %d)\n",
669 device, length));
670
671 cid = BMI_LZ_DATA;
672
673 remaining = length;
674 while (remaining)
675 {
676 txlen = (remaining < (BMI_DATASZ_MAX - header)) ?
677 remaining : (BMI_DATASZ_MAX - header);
678 offset = 0;
679 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
680 offset += sizeof(cid);
681 memcpy(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
682 offset += sizeof(txlen);
683 memcpy(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen);
684 offset += txlen;
685 status = bmiBufferSend(device, pBMICmdBuf, offset);
686 if (status) {
687 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
688 return A_ERROR;
689 }
690 remaining -= txlen;
691 }
692
693 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Data: Exit\n"));
694
695 return 0;
696}
697
698int
699BMILZStreamStart(struct hif_device *device,
700 u32 address)
701{
702 u32 cid;
703 int status;
704 u32 offset;
705
706 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
707 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
708
709 if (bmiDone) {
710 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
711 return A_ERROR;
712 }
713
714 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
715 ("BMI LZ Stream Start: Enter (device: 0x%p, address: 0x%x)\n",
716 device, address));
717
718 cid = BMI_LZ_STREAM_START;
719 offset = 0;
720 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
721 offset += sizeof(cid);
722 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
723 offset += sizeof(address);
724 status = bmiBufferSend(device, pBMICmdBuf, offset);
725 if (status) {
726 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to Start LZ Stream to the device\n"));
727 return A_ERROR;
728 }
729
730 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Stream Start: Exit\n"));
731
732 return 0;
733}
734
735/* BMI Access routines */
736int
737bmiBufferSend(struct hif_device *device,
738 u8 *buffer,
739 u32 length)
740{
741 int status;
742 u32 timeout;
743 u32 address;
744 u32 mboxAddress[HTC_MAILBOX_NUM_MAX];
745
746 HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
747 &mboxAddress[0], sizeof(mboxAddress));
748
749 *pBMICmdCredits = 0;
750 timeout = BMI_COMMUNICATION_TIMEOUT;
751
752 while(timeout-- && !(*pBMICmdCredits)) {
753 /* Read the counter register to get the command credits */
754 address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
755 /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause
756 * a decrement, while the remaining 3 bytes has no effect. The rationale behind this is to
757 * make all HIF accesses 4-byte aligned */
758 status = HIFReadWrite(device, address, (u8 *)pBMICmdCredits, 4,
759 HIF_RD_SYNC_BYTE_INC, NULL);
760 if (status) {
761 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register\n"));
762 return A_ERROR;
763 }
764 /* the counter is only 8=bits, ignore anything in the upper 3 bytes */
765 (*pBMICmdCredits) &= 0xFF;
766 }
767
768 if (*pBMICmdCredits) {
769 address = mboxAddress[ENDPOINT1];
770 status = HIFReadWrite(device, address, buffer, length,
771 HIF_WR_SYNC_BYTE_INC, NULL);
772 if (status) {
773 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the device\n"));
774 return A_ERROR;
775 }
776 } else {
777 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferSend\n"));
778 return A_ERROR;
779 }
780
781 return status;
782}
783
784int
785bmiBufferReceive(struct hif_device *device,
786 u8 *buffer,
787 u32 length,
788 bool want_timeout)
789{
790 int status;
791 u32 address;
792 u32 mboxAddress[HTC_MAILBOX_NUM_MAX];
793 struct hif_pending_events_info hifPendingEvents;
794 static HIF_PENDING_EVENTS_FUNC getPendingEventsFunc = NULL;
795
796 if (!pendingEventsFuncCheck) {
797 /* see if the HIF layer implements an alternative function to get pending events
798 * do this only once! */
799 HIFConfigureDevice(device,
800 HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
801 &getPendingEventsFunc,
802 sizeof(getPendingEventsFunc));
803 pendingEventsFuncCheck = true;
804 }
805
806 HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
807 &mboxAddress[0], sizeof(mboxAddress));
808
809 /*
810 * During normal bootup, small reads may be required.
811 * Rather than issue an HIF Read and then wait as the Target
812 * adds successive bytes to the FIFO, we wait here until
813 * we know that response data is available.
814 *
815 * This allows us to cleanly timeout on an unexpected
816 * Target failure rather than risk problems at the HIF level. In
817 * particular, this avoids SDIO timeouts and possibly garbage
818 * data on some host controllers. And on an interconnect
819 * such as Compact Flash (as well as some SDIO masters) which
820 * does not provide any indication on data timeout, it avoids
821 * a potential hang or garbage response.
822 *
823 * Synchronization is more difficult for reads larger than the
824 * size of the MBOX FIFO (128B), because the Target is unable
825 * to push the 129th byte of data until AFTER the Host posts an
826 * HIF Read and removes some FIFO data. So for large reads the
827 * Host proceeds to post an HIF Read BEFORE all the data is
828 * actually available to read. Fortunately, large BMI reads do
829 * not occur in practice -- they're supported for debug/development.
830 *
831 * So Host/Target BMI synchronization is divided into these cases:
832 * CASE 1: length < 4
833 * Should not happen
834 *
835 * CASE 2: 4 <= length <= 128
836 * Wait for first 4 bytes to be in FIFO
837 * If CONSERVATIVE_BMI_READ is enabled, also wait for
838 * a BMI command credit, which indicates that the ENTIRE
839 * response is available in the the FIFO
840 *
841 * CASE 3: length > 128
842 * Wait for the first 4 bytes to be in FIFO
843 *
844 * For most uses, a small timeout should be sufficient and we will
845 * usually see a response quickly; but there may be some unusual
846 * (debug) cases of BMI_EXECUTE where we want an larger timeout.
847 * For now, we use an unbounded busy loop while waiting for
848 * BMI_EXECUTE.
849 *
850 * If BMI_EXECUTE ever needs to support longer-latency execution,
851 * especially in production, this code needs to be enhanced to sleep
852 * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently
853 * a function of Host processor speed.
854 */
855 if (length >= 4) { /* NB: Currently, always true */
856 /*
857 * NB: word_available is declared static for esoteric reasons
858 * having to do with protection on some OSes.
859 */
860 static u32 word_available;
861 u32 timeout;
862
863 word_available = 0;
864 timeout = BMI_COMMUNICATION_TIMEOUT;
865 while((!want_timeout || timeout--) && !word_available) {
866
867 if (getPendingEventsFunc != NULL) {
868 status = getPendingEventsFunc(device,
869 &hifPendingEvents,
870 NULL);
871 if (status) {
872 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to get pending events \n"));
873 break;
874 }
875
876 if (hifPendingEvents.AvailableRecvBytes >= sizeof(u32)) {
877 word_available = 1;
878 }
879 continue;
880 }
881
882 status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (u8 *)&word_available,
883 sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL);
884 if (status) {
885 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read RX_LOOKAHEAD_VALID register\n"));
886 return A_ERROR;
887 }
888 /* We did a 4-byte read to the same register; all we really want is one bit */
889 word_available &= (1 << ENDPOINT1);
890 }
891
892 if (!word_available) {
893 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferReceive FIFO empty\n"));
894 return A_ERROR;
895 }
896 }
897
898#define CONSERVATIVE_BMI_READ 0
899#if CONSERVATIVE_BMI_READ
900 /*
901 * This is an extra-conservative CREDIT check. It guarantees
902 * that ALL data is available in the FIFO before we start to
903 * read from the interconnect.
904 *
905 * This credit check is useless when firmware chooses to
906 * allow multiple outstanding BMI Command Credits, since the next
907 * credit will already be present. To restrict the Target to one
908 * BMI Command Credit, see HI_OPTION_BMI_CRED_LIMIT.
909 *
910 * And for large reads (when HI_OPTION_BMI_CRED_LIMIT is set)
911 * we cannot wait for the next credit because the Target's FIFO
912 * will not hold the entire response. So we need the Host to
913 * start to empty the FIFO sooner. (And again, large reads are
914 * not used in practice; they are for debug/development only.)
915 *
916 * For a more conservative Host implementation (which would be
917 * safer for a Compact Flash interconnect):
918 * Set CONSERVATIVE_BMI_READ (above) to 1
919 * Set HI_OPTION_BMI_CRED_LIMIT and
920 * reduce BMI_DATASZ_MAX to 32 or 64
921 */
922 if ((length > 4) && (length < 128)) { /* check against MBOX FIFO size */
923 u32 timeout;
924
925 *pBMICmdCredits = 0;
926 timeout = BMI_COMMUNICATION_TIMEOUT;
927 while((!want_timeout || timeout--) && !(*pBMICmdCredits) {
928 /* Read the counter register to get the command credits */
929 address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1;
930 /* read the counter using a 4-byte read. Since the counter is NOT auto-decrementing,
931 * we can read this counter multiple times using a non-incrementing address mode.
932 * The rationale here is to make all HIF accesses a multiple of 4 bytes */
933 status = HIFReadWrite(device, address, (u8 *)pBMICmdCredits, sizeof(*pBMICmdCredits),
934 HIF_RD_SYNC_BYTE_FIX, NULL);
935 if (status) {
936 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command credit count register\n"));
937 return A_ERROR;
938 }
939 /* we did a 4-byte read to the same count register so mask off upper bytes */
940 (*pBMICmdCredits) &= 0xFF;
941 }
942
943 if (!(*pBMICmdCredits)) {
944 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout- bmiBufferReceive no credit\n"));
945 return A_ERROR;
946 }
947 }
948#endif
949
950 address = mboxAddress[ENDPOINT1];
951 status = HIFReadWrite(device, address, buffer, length, HIF_RD_SYNC_BYTE_INC, NULL);
952 if (status) {
953 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the device\n"));
954 return A_ERROR;
955 }
956
957 return 0;
958}
959
960int
961BMIFastDownload(struct hif_device *device, u32 address, u8 *buffer, u32 length)
962{
963 int status = A_ERROR;
964 u32 lastWord = 0;
965 u32 lastWordOffset = length & ~0x3;
966 u32 unalignedBytes = length & 0x3;
967
968 status = BMILZStreamStart (device, address);
969 if (status) {
970 return A_ERROR;
971 }
972
973 if (unalignedBytes) {
974 /* copy the last word into a zero padded buffer */
975 memcpy(&lastWord, &buffer[lastWordOffset], unalignedBytes);
976 }
977
978 status = BMILZData(device, buffer, lastWordOffset);
979
980 if (status) {
981 return A_ERROR;
982 }
983
984 if (unalignedBytes) {
985 status = BMILZData(device, (u8 *)&lastWord, 4);
986 }
987
988 if (!status) {
989 //
990 // Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches.
991 //
992 status = BMILZStreamStart (device, 0x00);
993 if (status) {
994 return A_ERROR;
995 }
996 }
997 return status;
998}
999
1000int
1001BMIRawWrite(struct hif_device *device, u8 *buffer, u32 length)
1002{
1003 return bmiBufferSend(device, buffer, length);
1004}
1005
1006int
1007BMIRawRead(struct hif_device *device, u8 *buffer, u32 length, bool want_timeout)
1008{
1009 return bmiBufferReceive(device, buffer, length, want_timeout);
1010}
diff --git a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h
deleted file mode 100644
index 93a2adceca3..00000000000
--- a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h
+++ /dev/null
@@ -1,87 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// common header file for HIF modules designed for SDIO
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25#ifndef HIF_SDIO_COMMON_H_
26#define HIF_SDIO_COMMON_H_
27
28 /* SDIO manufacturer ID and Codes */
29#define MANUFACTURER_ID_AR6002_BASE 0x200
30#define MANUFACTURER_ID_AR6003_BASE 0x300
31#define MANUFACTURER_ID_AR6K_BASE_MASK 0xFF00
32#define FUNCTION_CLASS 0x0
33#define MANUFACTURER_CODE 0x271 /* Atheros */
34
35 /* Mailbox address in SDIO address space */
36#define HIF_MBOX_BASE_ADDR 0x800
37#define HIF_MBOX_WIDTH 0x800
38#define HIF_MBOX_START_ADDR(mbox) \
39 ( HIF_MBOX_BASE_ADDR + mbox * HIF_MBOX_WIDTH)
40
41#define HIF_MBOX_END_ADDR(mbox) \
42 (HIF_MBOX_START_ADDR(mbox) + HIF_MBOX_WIDTH - 1)
43
44 /* extended MBOX address for larger MBOX writes to MBOX 0*/
45#define HIF_MBOX0_EXTENDED_BASE_ADDR 0x2800
46#define HIF_MBOX0_EXTENDED_WIDTH_AR6002 (6*1024)
47#define HIF_MBOX0_EXTENDED_WIDTH_AR6003 (18*1024)
48
49 /* version 1 of the chip has only a 12K extended mbox range */
50#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1 0x4000
51#define HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1 (12*1024)
52
53 /* GMBOX addresses */
54#define HIF_GMBOX_BASE_ADDR 0x7000
55#define HIF_GMBOX_WIDTH 0x4000
56
57 /* for SDIO we recommend a 128-byte block size */
58#define HIF_DEFAULT_IO_BLOCK_SIZE 128
59
60 /* set extended MBOX window information for SDIO interconnects */
61static INLINE void SetExtendedMboxWindowInfo(u16 Manfid, struct hif_device_mbox_info *pInfo)
62{
63 switch (Manfid & MANUFACTURER_ID_AR6K_BASE_MASK) {
64 case MANUFACTURER_ID_AR6002_BASE :
65 /* MBOX 0 has an extended range */
66 pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR;
67 pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6002;
68 break;
69 case MANUFACTURER_ID_AR6003_BASE :
70 /* MBOX 0 has an extended range */
71 pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1;
72 pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1;
73 pInfo->GMboxAddress = HIF_GMBOX_BASE_ADDR;
74 pInfo->GMboxSize = HIF_GMBOX_WIDTH;
75 break;
76 default:
77 A_ASSERT(false);
78 break;
79 }
80}
81
82/* special CCCR (func 0) registers */
83
84#define CCCR_SDIO_IRQ_MODE_REG 0xF0 /* interrupt mode register */
85#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ (1 << 0) /* mode to enable special 4-bit interrupt assertion without clock*/
86
87#endif /*HIF_SDIO_COMMON_H_*/
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h
deleted file mode 100644
index ed7ad4786f5..00000000000
--- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h
+++ /dev/null
@@ -1,131 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="hif_internal.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// internal header file for hif layer
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _HIF_INTERNAL_H_
26#define _HIF_INTERNAL_H_
27
28#include "a_config.h"
29#include "athdefs.h"
30#include "a_osapi.h"
31#include "hif.h"
32#include "../../../common/hif_sdio_common.h"
33#include <linux/scatterlist.h>
34#define HIF_LINUX_MMC_SCATTER_SUPPORT
35
36#define BUS_REQUEST_MAX_NUM 64
37
38#define SDIO_CLOCK_FREQUENCY_DEFAULT 25000000
39#define SDWLAN_ENABLE_DISABLE_TIMEOUT 20
40#define FLAGS_CARD_ENAB 0x02
41#define FLAGS_CARD_IRQ_UNMSK 0x04
42
43#define HIF_MBOX_BLOCK_SIZE HIF_DEFAULT_IO_BLOCK_SIZE
44#define HIF_MBOX0_BLOCK_SIZE 1
45#define HIF_MBOX1_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
46#define HIF_MBOX2_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
47#define HIF_MBOX3_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
48
49typedef struct bus_request {
50 struct bus_request *next; /* link list of available requests */
51 struct bus_request *inusenext; /* link list of in use requests */
52 struct semaphore sem_req;
53 u32 address; /* request data */
54 u8 *buffer;
55 u32 length;
56 u32 request;
57 void *context;
58 int status;
59 struct hif_scatter_req_priv *pScatterReq; /* this request is a scatter request */
60} BUS_REQUEST;
61
62struct hif_device {
63 struct sdio_func *func;
64 spinlock_t asynclock;
65 struct task_struct* async_task; /* task to handle async commands */
66 struct semaphore sem_async; /* wake up for async task */
67 int async_shutdown; /* stop the async task */
68 struct completion async_completion; /* thread completion */
69 BUS_REQUEST *asyncreq; /* request for async tasklet */
70 BUS_REQUEST *taskreq; /* async tasklet data */
71 spinlock_t lock;
72 BUS_REQUEST *s_busRequestFreeQueue; /* free list */
73 BUS_REQUEST busRequest[BUS_REQUEST_MAX_NUM]; /* available bus requests */
74 void *claimedContext;
75 HTC_CALLBACKS htcCallbacks;
76 u8 *dma_buffer;
77 struct dl_list ScatterReqHead; /* scatter request list head */
78 bool scatter_enabled; /* scatter enabled flag */
79 bool is_suspend;
80 bool is_disabled;
81 atomic_t irqHandling;
82 HIF_DEVICE_POWER_CHANGE_TYPE powerConfig;
83 const struct sdio_device_id *id;
84};
85
86#define HIF_DMA_BUFFER_SIZE (32 * 1024)
87#define CMD53_FIXED_ADDRESS 1
88#define CMD53_INCR_ADDRESS 2
89
90BUS_REQUEST *hifAllocateBusRequest(struct hif_device *device);
91void hifFreeBusRequest(struct hif_device *device, BUS_REQUEST *busrequest);
92void AddToAsyncList(struct hif_device *device, BUS_REQUEST *busrequest);
93
94#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT
95
96#define MAX_SCATTER_REQUESTS 4
97#define MAX_SCATTER_ENTRIES_PER_REQ 16
98#define MAX_SCATTER_REQ_TRANSFER_SIZE 32*1024
99
100struct hif_scatter_req_priv {
101 struct hif_scatter_req *pHifScatterReq; /* HIF scatter request with allocated entries */
102 struct hif_device *device; /* this device */
103 BUS_REQUEST *busrequest; /* request associated with request */
104 /* scatter list for linux */
105 struct scatterlist sgentries[MAX_SCATTER_ENTRIES_PER_REQ];
106};
107
108#define ATH_DEBUG_SCATTER ATH_DEBUG_MAKE_MODULE_MASK(0)
109
110int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo);
111void CleanupHIFScatterResources(struct hif_device *device);
112int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest);
113
114#else // HIF_LINUX_MMC_SCATTER_SUPPORT
115
116static inline int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo)
117{
118 return A_ENOTSUP;
119}
120
121static inline int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest)
122{
123 return A_ENOTSUP;
124}
125
126#define CleanupHIFScatterResources(d) { }
127
128#endif // HIF_LINUX_MMC_SCATTER_SUPPORT
129
130#endif // _HIF_INTERNAL_H_
131
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
deleted file mode 100644
index 5f5d67720fa..00000000000
--- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
+++ /dev/null
@@ -1,1273 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="hif.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// HIF layer reference implementation for Linux Native MMC stack
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#include <linux/mmc/card.h>
26#include <linux/mmc/mmc.h>
27#include <linux/mmc/host.h>
28#include <linux/mmc/sdio_func.h>
29#include <linux/mmc/sdio_ids.h>
30#include <linux/mmc/sdio.h>
31#include <linux/mmc/sd.h>
32#include <linux/kthread.h>
33
34/* by default setup a bounce buffer for the data packets, if the underlying host controller driver
35 does not use DMA you may be able to skip this step and save the memory allocation and transfer time */
36#define HIF_USE_DMA_BOUNCE_BUFFER 1
37#include "hif_internal.h"
38#define ATH_MODULE_NAME hif
39#include "a_debug.h"
40#include "hw/mbox_host_reg.h"
41
42#if HIF_USE_DMA_BOUNCE_BUFFER
43/* macro to check if DMA buffer is WORD-aligned and DMA-able. Most host controllers assume the
44 * buffer is DMA'able and will bug-check otherwise (i.e. buffers on the stack).
45 * virt_addr_valid check fails on stack memory.
46 */
47#define BUFFER_NEEDS_BOUNCE(buffer) (((unsigned long)(buffer) & 0x3) || !virt_addr_valid((buffer)))
48#else
49#define BUFFER_NEEDS_BOUNCE(buffer) (false)
50#endif
51
52/* ATHENV */
53#if defined(CONFIG_PM)
54#define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev)
55#define to_sdio_driver(d) container_of(d, struct sdio_driver, drv)
56#endif /* CONFIG_PM */
57static void delHifDevice(struct hif_device * device);
58static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte);
59static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte);
60
61static int hifEnableFunc(struct hif_device *device, struct sdio_func *func);
62static int hifDisableFunc(struct hif_device *device, struct sdio_func *func);
63OSDRV_CALLBACKS osdrvCallbacks;
64
65int reset_sdio_on_unload = 0;
66module_param(reset_sdio_on_unload, int, 0644);
67
68extern u32 nohifscattersupport;
69
70static struct hif_device *ath6kl_alloc_hifdev(struct sdio_func *func)
71{
72 struct hif_device *hifdevice;
73
74 hifdevice = kzalloc(sizeof(struct hif_device), GFP_KERNEL);
75
76#if HIF_USE_DMA_BOUNCE_BUFFER
77 hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
78#endif
79 hifdevice->func = func;
80 hifdevice->powerConfig = HIF_DEVICE_POWER_UP;
81 sdio_set_drvdata(func, hifdevice);
82
83 return hifdevice;
84}
85
86static struct hif_device *ath6kl_get_hifdev(struct sdio_func *func)
87{
88 return (struct hif_device *) sdio_get_drvdata(func);
89}
90
91static const struct sdio_device_id ath6kl_hifdev_ids[] = {
92 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0)) },
93 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1)) },
94 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0)) },
95 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1)) },
96 { /* null */ },
97};
98
99MODULE_DEVICE_TABLE(sdio, ath6kl_hifdev_ids);
100
101static int ath6kl_hifdev_probe(struct sdio_func *func,
102 const struct sdio_device_id *id)
103{
104 int ret;
105 struct hif_device *device;
106 int count;
107
108 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
109 ("ath6kl: Function: 0x%X, Vendor ID: 0x%X, "
110 "Device ID: 0x%X, block size: 0x%X/0x%X\n",
111 func->num, func->vendor, func->device,
112 func->max_blksize, func->cur_blksize));
113
114 ath6kl_alloc_hifdev(func);
115 device = ath6kl_get_hifdev(func);
116
117 device->id = id;
118 device->is_disabled = true;
119
120 spin_lock_init(&device->lock);
121 spin_lock_init(&device->asynclock);
122
123 DL_LIST_INIT(&device->ScatterReqHead);
124
125 /* Try to allow scatter unless globally overridden */
126 if (!nohifscattersupport)
127 device->scatter_enabled = true;
128
129 A_MEMZERO(device->busRequest, sizeof(device->busRequest));
130
131 for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) {
132 sema_init(&device->busRequest[count].sem_req, 0);
133 hifFreeBusRequest(device, &device->busRequest[count]);
134 }
135
136 sema_init(&device->sem_async, 0);
137
138 ret = hifEnableFunc(device, func);
139
140 return ret;
141}
142
143static void ath6kl_hifdev_remove(struct sdio_func *func)
144{
145 int status = 0;
146 struct hif_device *device;
147
148 device = ath6kl_get_hifdev(func);
149 if (device->claimedContext != NULL)
150 status = osdrvCallbacks.
151 deviceRemovedHandler(device->claimedContext, device);
152
153 if (device->is_disabled)
154 device->is_disabled = false;
155 else
156 status = hifDisableFunc(device, func);
157
158 CleanupHIFScatterResources(device);
159
160 delHifDevice(device);
161}
162
163#if defined(CONFIG_PM)
164static int ath6kl_hifdev_suspend(struct device *dev)
165{
166 struct sdio_func *func = dev_to_sdio_func(dev);
167 int status = 0;
168 struct hif_device *device;
169
170 device = ath6kl_get_hifdev(func);
171
172 if (device && device->claimedContext &&
173 osdrvCallbacks.deviceSuspendHandler) {
174 /* set true first for PowerStateChangeNotify(..) */
175 device->is_suspend = true;
176 status = osdrvCallbacks.
177 deviceSuspendHandler(device->claimedContext);
178 if (status)
179 device->is_suspend = false;
180 }
181
182 CleanupHIFScatterResources(device);
183
184 switch (status) {
185 case 0:
186 return 0;
187 case A_EBUSY:
188 /* Hack for kernel in order to support deep sleep and wow */
189 return -EBUSY;
190 default:
191 return -1;
192 }
193}
194
195static int ath6kl_hifdev_resume(struct device *dev)
196{
197 struct sdio_func *func = dev_to_sdio_func(dev);
198 int status = 0;
199 struct hif_device *device;
200
201 device = ath6kl_get_hifdev(func);
202 if (device && device->claimedContext &&
203 osdrvCallbacks.deviceSuspendHandler) {
204 status = osdrvCallbacks.
205 deviceResumeHandler(device->claimedContext);
206 if (status == 0)
207 device->is_suspend = false;
208 }
209
210 return status;
211}
212
213static const struct dev_pm_ops ath6kl_hifdev_pmops = {
214 .suspend = ath6kl_hifdev_suspend,
215 .resume = ath6kl_hifdev_resume,
216};
217#endif /* CONFIG_PM */
218
219static struct sdio_driver ath6kl_hifdev_driver = {
220 .name = "ath6kl_hifdev",
221 .id_table = ath6kl_hifdev_ids,
222 .probe = ath6kl_hifdev_probe,
223 .remove = ath6kl_hifdev_remove,
224#if defined(CONFIG_PM)
225 .drv = {
226 .pm = &ath6kl_hifdev_pmops,
227 },
228#endif
229};
230
231/* make sure we only unregister when registered. */
232static int registered = 0;
233
234extern u32 onebitmode;
235extern u32 busspeedlow;
236extern u32 debughif;
237
238static void ResetAllCards(void);
239
240#ifdef DEBUG
241
242ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif,
243 "hif",
244 "(Linux MMC) Host Interconnect Framework",
245 ATH_DEBUG_MASK_DEFAULTS,
246 0,
247 NULL);
248
249#endif
250
251
252/* ------ Functions ------ */
253int HIFInit(OSDRV_CALLBACKS *callbacks)
254{
255 int r;
256 AR_DEBUG_ASSERT(callbacks != NULL);
257
258 A_REGISTER_MODULE_DEBUG_INFO(hif);
259
260 /* store the callback handlers */
261 osdrvCallbacks = *callbacks;
262
263 /* Register with bus driver core */
264 registered = 1;
265
266 r = sdio_register_driver(&ath6kl_hifdev_driver);
267 if (r < 0)
268 return r;
269
270 return 0;
271}
272
273static int
274__HIFReadWrite(struct hif_device *device,
275 u32 address,
276 u8 *buffer,
277 u32 length,
278 u32 request,
279 void *context)
280{
281 u8 opcode;
282 int status = 0;
283 int ret;
284 u8 *tbuffer;
285 bool bounced = false;
286
287 AR_DEBUG_ASSERT(device != NULL);
288 AR_DEBUG_ASSERT(device->func != NULL);
289
290 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: 0x%p, buffer:0x%p (addr:0x%X)\n",
291 device, buffer, address));
292
293 do {
294 if (request & HIF_EXTENDED_IO) {
295 //AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Command type: CMD53\n"));
296 } else {
297 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
298 ("AR6000: Invalid command type: 0x%08x\n", request));
299 status = A_EINVAL;
300 break;
301 }
302
303 if (request & HIF_BLOCK_BASIS) {
304 /* round to whole block length size */
305 length = (length / HIF_MBOX_BLOCK_SIZE) * HIF_MBOX_BLOCK_SIZE;
306 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
307 ("AR6000: Block mode (BlockLen: %d)\n",
308 length));
309 } else if (request & HIF_BYTE_BASIS) {
310 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
311 ("AR6000: Byte mode (BlockLen: %d)\n",
312 length));
313 } else {
314 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
315 ("AR6000: Invalid data mode: 0x%08x\n", request));
316 status = A_EINVAL;
317 break;
318 }
319
320#if 0
321 /* useful for checking register accesses */
322 if (length & 0x3) {
323 A_PRINTF(KERN_ALERT"AR6000: HIF (%s) is not a multiple of 4 bytes, addr:0x%X, len:%d\n",
324 request & HIF_WRITE ? "write":"read", address, length);
325 }
326#endif
327
328 if (request & HIF_WRITE) {
329 if ((address >= HIF_MBOX_START_ADDR(0)) &&
330 (address <= HIF_MBOX_END_ADDR(3)))
331 {
332
333 AR_DEBUG_ASSERT(length <= HIF_MBOX_WIDTH);
334
335 /*
336 * Mailbox write. Adjust the address so that the last byte
337 * falls on the EOM address.
338 */
339 address += (HIF_MBOX_WIDTH - length);
340 }
341 }
342
343 if (request & HIF_FIXED_ADDRESS) {
344 opcode = CMD53_FIXED_ADDRESS;
345 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Fixed 0x%X\n", address));
346 } else if (request & HIF_INCREMENTAL_ADDRESS) {
347 opcode = CMD53_INCR_ADDRESS;
348 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Incremental 0x%X\n", address));
349 } else {
350 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
351 ("AR6000: Invalid address mode: 0x%08x\n", request));
352 status = A_EINVAL;
353 break;
354 }
355
356 if (request & HIF_WRITE) {
357#if HIF_USE_DMA_BOUNCE_BUFFER
358 if (BUFFER_NEEDS_BOUNCE(buffer)) {
359 AR_DEBUG_ASSERT(device->dma_buffer != NULL);
360 tbuffer = device->dma_buffer;
361 /* copy the write data to the dma buffer */
362 AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
363 memcpy(tbuffer, buffer, length);
364 bounced = true;
365 } else {
366 tbuffer = buffer;
367 }
368#else
369 tbuffer = buffer;
370#endif
371 if (opcode == CMD53_FIXED_ADDRESS) {
372 ret = sdio_writesb(device->func, address, tbuffer, length);
373 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writesb ret=%d address: 0x%X, len: %d, 0x%X\n",
374 ret, address, length, *(int *)tbuffer));
375 } else {
376 ret = sdio_memcpy_toio(device->func, address, tbuffer, length);
377 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writeio ret=%d address: 0x%X, len: %d, 0x%X\n",
378 ret, address, length, *(int *)tbuffer));
379 }
380 } else if (request & HIF_READ) {
381#if HIF_USE_DMA_BOUNCE_BUFFER
382 if (BUFFER_NEEDS_BOUNCE(buffer)) {
383 AR_DEBUG_ASSERT(device->dma_buffer != NULL);
384 AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
385 tbuffer = device->dma_buffer;
386 bounced = true;
387 } else {
388 tbuffer = buffer;
389 }
390#else
391 tbuffer = buffer;
392#endif
393 if (opcode == CMD53_FIXED_ADDRESS) {
394 ret = sdio_readsb(device->func, tbuffer, address, length);
395 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readsb ret=%d address: 0x%X, len: %d, 0x%X\n",
396 ret, address, length, *(int *)tbuffer));
397 } else {
398 ret = sdio_memcpy_fromio(device->func, tbuffer, address, length);
399 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readio ret=%d address: 0x%X, len: %d, 0x%X\n",
400 ret, address, length, *(int *)tbuffer));
401 }
402#if HIF_USE_DMA_BOUNCE_BUFFER
403 if (bounced) {
404 /* copy the read data from the dma buffer */
405 memcpy(buffer, tbuffer, length);
406 }
407#endif
408 } else {
409 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
410 ("AR6000: Invalid direction: 0x%08x\n", request));
411 status = A_EINVAL;
412 break;
413 }
414
415 if (ret) {
416 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
417 ("AR6000: SDIO bus operation failed! MMC stack returned : %d \n", ret));
418 status = A_ERROR;
419 }
420 } while (false);
421
422 return status;
423}
424
425void AddToAsyncList(struct hif_device *device, BUS_REQUEST *busrequest)
426{
427 unsigned long flags;
428 BUS_REQUEST *async;
429 BUS_REQUEST *active;
430
431 spin_lock_irqsave(&device->asynclock, flags);
432 active = device->asyncreq;
433 if (active == NULL) {
434 device->asyncreq = busrequest;
435 device->asyncreq->inusenext = NULL;
436 } else {
437 for (async = device->asyncreq;
438 async != NULL;
439 async = async->inusenext) {
440 active = async;
441 }
442 active->inusenext = busrequest;
443 busrequest->inusenext = NULL;
444 }
445 spin_unlock_irqrestore(&device->asynclock, flags);
446}
447
448
449/* queue a read/write request */
450int
451HIFReadWrite(struct hif_device *device,
452 u32 address,
453 u8 *buffer,
454 u32 length,
455 u32 request,
456 void *context)
457{
458 int status = 0;
459 BUS_REQUEST *busrequest;
460
461
462 AR_DEBUG_ASSERT(device != NULL);
463 AR_DEBUG_ASSERT(device->func != NULL);
464
465 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: %p addr:0x%X\n", device,address));
466
467 do {
468 if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS)){
469 /* serialize all requests through the async thread */
470 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Execution mode: %s\n",
471 (request & HIF_ASYNCHRONOUS)?"Async":"Synch"));
472 busrequest = hifAllocateBusRequest(device);
473 if (busrequest == NULL) {
474 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
475 ("AR6000: no async bus requests available (%s, addr:0x%X, len:%d) \n",
476 request & HIF_READ ? "READ":"WRITE", address, length));
477 return A_ERROR;
478 }
479 busrequest->address = address;
480 busrequest->buffer = buffer;
481 busrequest->length = length;
482 busrequest->request = request;
483 busrequest->context = context;
484
485 AddToAsyncList(device, busrequest);
486
487 if (request & HIF_SYNCHRONOUS) {
488 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued sync req: 0x%lX\n", (unsigned long)busrequest));
489
490 /* wait for completion */
491 up(&device->sem_async);
492 if (down_interruptible(&busrequest->sem_req) != 0) {
493 /* interrupted, exit */
494 return A_ERROR;
495 } else {
496 int status = busrequest->status;
497 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freeing 0x%lX: 0x%X\n",
498 (unsigned long)busrequest, busrequest->status));
499 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X\n", (unsigned int)request));
500 hifFreeBusRequest(device, busrequest);
501 return status;
502 }
503 } else {
504 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued async req: 0x%lX\n", (unsigned long)busrequest));
505 up(&device->sem_async);
506 return A_PENDING;
507 }
508 } else {
509 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
510 ("AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request));
511 status = A_EINVAL;
512 break;
513 }
514 } while(0);
515
516 return status;
517}
518/* thread to serialize all requests, both sync and async */
519static int async_task(void *param)
520 {
521 struct hif_device *device;
522 BUS_REQUEST *request;
523 int status;
524 unsigned long flags;
525
526 device = (struct hif_device *)param;
527 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task\n"));
528 set_current_state(TASK_INTERRUPTIBLE);
529 while(!device->async_shutdown) {
530 /* wait for work */
531 if (down_interruptible(&device->sem_async) != 0) {
532 /* interrupted, exit */
533 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task interrupted\n"));
534 break;
535 }
536 if (device->async_shutdown) {
537 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task stopping\n"));
538 break;
539 }
540 /* we want to hold the host over multiple cmds if possible, but holding the host blocks card interrupts */
541 sdio_claim_host(device->func);
542 spin_lock_irqsave(&device->asynclock, flags);
543 /* pull the request to work on */
544 while (device->asyncreq != NULL) {
545 request = device->asyncreq;
546 if (request->inusenext != NULL) {
547 device->asyncreq = request->inusenext;
548 } else {
549 device->asyncreq = NULL;
550 }
551 spin_unlock_irqrestore(&device->asynclock, flags);
552 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req: 0x%lX\n", (unsigned long)request));
553
554 if (request->pScatterReq != NULL) {
555 A_ASSERT(device->scatter_enabled);
556 /* this is a queued scatter request, pass the request to scatter routine which
557 * executes it synchronously, note, no need to free the request since scatter requests
558 * are maintained on a separate list */
559 status = DoHifReadWriteScatter(device,request);
560 } else {
561 /* call HIFReadWrite in sync mode to do the work */
562 status = __HIFReadWrite(device, request->address, request->buffer,
563 request->length, request->request & ~HIF_SYNCHRONOUS, NULL);
564 if (request->request & HIF_ASYNCHRONOUS) {
565 void *context = request->context;
566 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freeing req: 0x%lX\n", (unsigned long)request));
567 hifFreeBusRequest(device, request);
568 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task completion routine req: 0x%lX\n", (unsigned long)request));
569 device->htcCallbacks.rwCompletionHandler(context, status);
570 } else {
571 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping req: 0x%lX\n", (unsigned long)request));
572 request->status = status;
573 up(&request->sem_req);
574 }
575 }
576 spin_lock_irqsave(&device->asynclock, flags);
577 }
578 spin_unlock_irqrestore(&device->asynclock, flags);
579 sdio_release_host(device->func);
580 }
581
582 complete_and_exit(&device->async_completion, 0);
583 return 0;
584}
585
586static s32 IssueSDCommand(struct hif_device *device, u32 opcode, u32 arg, u32 flags, u32 *resp)
587{
588 struct mmc_command cmd;
589 s32 err;
590 struct mmc_host *host;
591 struct sdio_func *func;
592
593 func = device->func;
594 host = func->card->host;
595
596 memset(&cmd, 0, sizeof(struct mmc_command));
597 cmd.opcode = opcode;
598 cmd.arg = arg;
599 cmd.flags = flags;
600 err = mmc_wait_for_cmd(host, &cmd, 3);
601
602 if ((!err) && (resp)) {
603 *resp = cmd.resp[0];
604 }
605
606 return err;
607}
608
609int ReinitSDIO(struct hif_device *device)
610{
611 s32 err;
612 struct mmc_host *host;
613 struct mmc_card *card;
614 struct sdio_func *func;
615 u8 cmd52_resp;
616 u32 clock;
617
618 func = device->func;
619 card = func->card;
620 host = card->host;
621
622 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ReinitSDIO \n"));
623 sdio_claim_host(func);
624
625 do {
626 if (!device->is_suspend) {
627 u32 resp;
628 u16 rca;
629 u32 i;
630 int bit = fls(host->ocr_avail) - 1;
631 /* emulate the mmc_power_up(...) */
632 host->ios.vdd = bit;
633 host->ios.chip_select = MMC_CS_DONTCARE;
634 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
635 host->ios.power_mode = MMC_POWER_UP;
636 host->ios.bus_width = MMC_BUS_WIDTH_1;
637 host->ios.timing = MMC_TIMING_LEGACY;
638 host->ops->set_ios(host, &host->ios);
639 /*
640 * This delay should be sufficient to allow the power supply
641 * to reach the minimum voltage.
642 */
643 msleep(2);
644
645 host->ios.clock = host->f_min;
646 host->ios.power_mode = MMC_POWER_ON;
647 host->ops->set_ios(host, &host->ios);
648
649 /*
650 * This delay must be at least 74 clock sizes, or 1 ms, or the
651 * time required to reach a stable voltage.
652 */
653 msleep(2);
654
655 /* Issue CMD0. Goto idle state */
656 host->ios.chip_select = MMC_CS_HIGH;
657 host->ops->set_ios(host, &host->ios);
658 msleep(1);
659 err = IssueSDCommand(device, MMC_GO_IDLE_STATE, 0, (MMC_RSP_NONE | MMC_CMD_BC), NULL);
660 host->ios.chip_select = MMC_CS_DONTCARE;
661 host->ops->set_ios(host, &host->ios);
662 msleep(1);
663 host->use_spi_crc = 0;
664
665 if (err) {
666 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD0 failed : %d \n",err));
667 break;
668 }
669
670 if (!host->ocr) {
671 /* Issue CMD5, arg = 0 */
672 err = IssueSDCommand(device, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
673 if (err) {
674 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));
675 break;
676 }
677 host->ocr = resp;
678 }
679
680 /* Issue CMD5, arg = ocr. Wait till card is ready */
681 for (i=0;i<100;i++) {
682 err = IssueSDCommand(device, SD_IO_SEND_OP_COND, host->ocr, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
683 if (err) {
684 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));
685 break;
686 }
687 if (resp & MMC_CARD_BUSY) {
688 break;
689 }
690 msleep(10);
691 }
692
693 if ((i == 100) || (err)) {
694 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: card in not ready : %d %d \n",i,err));
695 break;
696 }
697
698 /* Issue CMD3, get RCA */
699 err = IssueSDCommand(device, SD_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6 | MMC_CMD_BCR, &resp);
700 if (err) {
701 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD3 failed : %d \n",err));
702 break;
703 }
704 rca = resp >> 16;
705 host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
706 host->ops->set_ios(host, &host->ios);
707
708 /* Issue CMD7, select card */
709 err = IssueSDCommand(device, MMC_SELECT_CARD, (rca << 16), MMC_RSP_R1 | MMC_CMD_AC, NULL);
710 if (err) {
711 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD7 failed : %d \n",err));
712 break;
713 }
714 }
715
716 /* Enable high speed */
717 if (card->host->caps & MMC_CAP_SD_HIGHSPEED) {
718 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("ReinitSDIO: Set high speed mode\n"));
719 err = Func0_CMD52ReadByte(card, SDIO_CCCR_SPEED, &cmd52_resp);
720 if (err) {
721 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 read to CCCR speed register failed : %d \n",err));
722 card->state &= ~MMC_STATE_HIGHSPEED;
723 /* no need to break */
724 } else {
725 err = Func0_CMD52WriteByte(card, SDIO_CCCR_SPEED, (cmd52_resp | SDIO_SPEED_EHS));
726 if (err) {
727 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 write to CCCR speed register failed : %d \n",err));
728 break;
729 }
730 mmc_card_set_highspeed(card);
731 host->ios.timing = MMC_TIMING_SD_HS;
732 host->ops->set_ios(host, &host->ios);
733 }
734 }
735
736 /* Set clock */
737 if (mmc_card_highspeed(card)) {
738 clock = 50000000;
739 } else {
740 clock = card->cis.max_dtr;
741 }
742
743 if (clock > host->f_max) {
744 clock = host->f_max;
745 }
746 host->ios.clock = clock;
747 host->ops->set_ios(host, &host->ios);
748
749
750 if (card->host->caps & MMC_CAP_4_BIT_DATA) {
751 /* CMD52: Set bus width & disable card detect resistor */
752 err = Func0_CMD52WriteByte(card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE | SDIO_BUS_WIDTH_4BIT);
753 if (err) {
754 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 to set bus mode failed : %d \n",err));
755 break;
756 }
757 host->ios.bus_width = MMC_BUS_WIDTH_4;
758 host->ops->set_ios(host, &host->ios);
759 }
760 } while (0);
761
762 sdio_release_host(func);
763 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ReinitSDIO \n"));
764
765 return (err) ? A_ERROR : 0;
766}
767
768int
769PowerStateChangeNotify(struct hif_device *device, HIF_DEVICE_POWER_CHANGE_TYPE config)
770{
771 int status = 0;
772#if defined(CONFIG_PM)
773 struct sdio_func *func = device->func;
774 int old_reset_val;
775 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +PowerStateChangeNotify %d\n", config));
776 switch (config) {
777 case HIF_DEVICE_POWER_DOWN:
778 case HIF_DEVICE_POWER_CUT:
779 old_reset_val = reset_sdio_on_unload;
780 reset_sdio_on_unload = 1;
781 status = hifDisableFunc(device, func);
782 reset_sdio_on_unload = old_reset_val;
783 if (!device->is_suspend) {
784 struct mmc_host *host = func->card->host;
785 host->ios.clock = 0;
786 host->ios.vdd = 0;
787 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
788 host->ios.chip_select = MMC_CS_DONTCARE;
789 host->ios.power_mode = MMC_POWER_OFF;
790 host->ios.bus_width = MMC_BUS_WIDTH_1;
791 host->ios.timing = MMC_TIMING_LEGACY;
792 host->ops->set_ios(host, &host->ios);
793 }
794 break;
795 case HIF_DEVICE_POWER_UP:
796 if (device->powerConfig == HIF_DEVICE_POWER_CUT) {
797 status = ReinitSDIO(device);
798 }
799 if (status == 0) {
800 status = hifEnableFunc(device, func);
801 }
802 break;
803 }
804 device->powerConfig = config;
805
806 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -PowerStateChangeNotify\n"));
807#endif
808 return status;
809}
810
811int
812HIFConfigureDevice(struct hif_device *device, HIF_DEVICE_CONFIG_OPCODE opcode,
813 void *config, u32 configLen)
814{
815 u32 count;
816 int status = 0;
817
818 switch(opcode) {
819 case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
820 ((u32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
821 ((u32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
822 ((u32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
823 ((u32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
824 break;
825
826 case HIF_DEVICE_GET_MBOX_ADDR:
827 for (count = 0; count < 4; count ++) {
828 ((u32 *)config)[count] = HIF_MBOX_START_ADDR(count);
829 }
830
831 if (configLen >= sizeof(struct hif_device_mbox_info)) {
832 SetExtendedMboxWindowInfo((u16)device->func->device,
833 (struct hif_device_mbox_info *)config);
834 }
835
836 break;
837 case HIF_DEVICE_GET_IRQ_PROC_MODE:
838 *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ONLY;
839 break;
840 case HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT:
841 if (!device->scatter_enabled) {
842 return A_ENOTSUP;
843 }
844 status = SetupHIFScatterSupport(device, (struct hif_device_scatter_support_info *)config);
845 if (status) {
846 device->scatter_enabled = false;
847 }
848 break;
849 case HIF_DEVICE_GET_OS_DEVICE:
850 /* pass back a pointer to the SDIO function's "dev" struct */
851 ((struct hif_device_os_device_info *)config)->pOSDevice = &device->func->dev;
852 break;
853 case HIF_DEVICE_POWER_STATE_CHANGE:
854 status = PowerStateChangeNotify(device, *(HIF_DEVICE_POWER_CHANGE_TYPE *)config);
855 break;
856 default:
857 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
858 ("AR6000: Unsupported configuration opcode: %d\n", opcode));
859 status = A_ERROR;
860 }
861
862 return status;
863}
864
865void
866HIFShutDownDevice(struct hif_device *device)
867{
868 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +HIFShutDownDevice\n"));
869 if (device != NULL) {
870 AR_DEBUG_ASSERT(device->func != NULL);
871 } else {
872 /* since we are unloading the driver anyways, reset all cards in case the SDIO card
873 * is externally powered and we are unloading the SDIO stack. This avoids the problem when
874 * the SDIO stack is reloaded and attempts are made to re-enumerate a card that is already
875 * enumerated */
876 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFShutDownDevice, resetting\n"));
877 ResetAllCards();
878
879 /* Unregister with bus driver core */
880 if (registered) {
881 registered = 0;
882 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
883 ("AR6000: Unregistering with the bus driver\n"));
884 sdio_unregister_driver(&ath6kl_hifdev_driver);
885 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
886 ("AR6000: Unregistered\n"));
887 }
888 }
889 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -HIFShutDownDevice\n"));
890}
891
892static void
893hifIRQHandler(struct sdio_func *func)
894{
895 int status;
896 struct hif_device *device;
897 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n"));
898
899 device = ath6kl_get_hifdev(func);
900 atomic_set(&device->irqHandling, 1);
901 /* release the host during ints so we can pick it back up when we process cmds */
902 sdio_release_host(device->func);
903 status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context);
904 sdio_claim_host(device->func);
905 atomic_set(&device->irqHandling, 0);
906 AR_DEBUG_ASSERT(status == 0 || status == A_ECANCELED);
907 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifIRQHandler\n"));
908}
909
910/* handle HTC startup via thread*/
911static int startup_task(void *param)
912{
913 struct hif_device *device;
914
915 device = (struct hif_device *)param;
916 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n"));
917 /* start up inform DRV layer */
918 if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != 0) {
919 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
920 }
921 return 0;
922}
923
924#if defined(CONFIG_PM)
925static int enable_task(void *param)
926{
927 struct hif_device *device;
928 device = (struct hif_device *)param;
929 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call from resume_task\n"));
930
931 /* start up inform DRV layer */
932 if (device &&
933 device->claimedContext &&
934 osdrvCallbacks.devicePowerChangeHandler &&
935 osdrvCallbacks.devicePowerChangeHandler(device->claimedContext, HIF_DEVICE_POWER_UP) != 0)
936 {
937 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
938 }
939
940 return 0;
941}
942#endif
943
944void
945HIFAckInterrupt(struct hif_device *device)
946{
947 AR_DEBUG_ASSERT(device != NULL);
948
949 /* Acknowledge our function IRQ */
950}
951
952void
953HIFUnMaskInterrupt(struct hif_device *device)
954{
955 int ret;
956
957 AR_DEBUG_ASSERT(device != NULL);
958 AR_DEBUG_ASSERT(device->func != NULL);
959
960 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFUnMaskInterrupt\n"));
961
962 /* Register the IRQ Handler */
963 sdio_claim_host(device->func);
964 ret = sdio_claim_irq(device->func, hifIRQHandler);
965 sdio_release_host(device->func);
966 AR_DEBUG_ASSERT(ret == 0);
967}
968
969void HIFMaskInterrupt(struct hif_device *device)
970{
971 int ret;
972 AR_DEBUG_ASSERT(device != NULL);
973 AR_DEBUG_ASSERT(device->func != NULL);
974
975 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFMaskInterrupt\n"));
976
977 /* Mask our function IRQ */
978 sdio_claim_host(device->func);
979 while (atomic_read(&device->irqHandling)) {
980 sdio_release_host(device->func);
981 schedule_timeout(HZ/10);
982 sdio_claim_host(device->func);
983 }
984 ret = sdio_release_irq(device->func);
985 sdio_release_host(device->func);
986 AR_DEBUG_ASSERT(ret == 0);
987}
988
989BUS_REQUEST *hifAllocateBusRequest(struct hif_device *device)
990{
991 BUS_REQUEST *busrequest;
992 unsigned long flag;
993
994 /* Acquire lock */
995 spin_lock_irqsave(&device->lock, flag);
996
997 /* Remove first in list */
998 if((busrequest = device->s_busRequestFreeQueue) != NULL)
999 {
1000 device->s_busRequestFreeQueue = busrequest->next;
1001 }
1002 /* Release lock */
1003 spin_unlock_irqrestore(&device->lock, flag);
1004 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifAllocateBusRequest: 0x%p\n", busrequest));
1005 return busrequest;
1006}
1007
1008void
1009hifFreeBusRequest(struct hif_device *device, BUS_REQUEST *busrequest)
1010{
1011 unsigned long flag;
1012
1013 AR_DEBUG_ASSERT(busrequest != NULL);
1014 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifFreeBusRequest: 0x%p\n", busrequest));
1015 /* Acquire lock */
1016 spin_lock_irqsave(&device->lock, flag);
1017
1018
1019 /* Insert first in list */
1020 busrequest->next = device->s_busRequestFreeQueue;
1021 busrequest->inusenext = NULL;
1022 device->s_busRequestFreeQueue = busrequest;
1023
1024 /* Release lock */
1025 spin_unlock_irqrestore(&device->lock, flag);
1026}
1027
1028static int hifDisableFunc(struct hif_device *device, struct sdio_func *func)
1029{
1030 int ret;
1031 int status = 0;
1032
1033 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDisableFunc\n"));
1034 device = ath6kl_get_hifdev(func);
1035 if (!IS_ERR(device->async_task)) {
1036 init_completion(&device->async_completion);
1037 device->async_shutdown = 1;
1038 up(&device->sem_async);
1039 wait_for_completion(&device->async_completion);
1040 device->async_task = NULL;
1041 }
1042 /* Disable the card */
1043 sdio_claim_host(device->func);
1044 ret = sdio_disable_func(device->func);
1045 if (ret) {
1046 status = A_ERROR;
1047 }
1048
1049 if (reset_sdio_on_unload) {
1050 /* reset the SDIO interface. This is useful in automated testing where the card
1051 * does not need to be removed at the end of the test. It is expected that the user will
1052 * also unload/reload the host controller driver to force the bus driver to re-enumerate the slot */
1053 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6000: reseting SDIO card back to uninitialized state \n"));
1054
1055 /* NOTE : sdio_f0_writeb() cannot be used here, that API only allows access
1056 * to undefined registers in the range of: 0xF0-0xFF */
1057
1058 ret = Func0_CMD52WriteByte(device->func->card, SDIO_CCCR_ABORT, (1 << 3));
1059 if (ret) {
1060 status = A_ERROR;
1061 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: reset failed : %d \n",ret));
1062 }
1063 }
1064
1065 sdio_release_host(device->func);
1066
1067 if (status == 0) {
1068 device->is_disabled = true;
1069 }
1070 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDisableFunc\n"));
1071
1072 return status;
1073}
1074
1075static int hifEnableFunc(struct hif_device *device, struct sdio_func *func)
1076{
1077 struct task_struct* pTask;
1078 const char *taskName = NULL;
1079 int (*taskFunc)(void *) = NULL;
1080 int ret = 0;
1081
1082 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n"));
1083 device = ath6kl_get_hifdev(func);
1084
1085 if (device->is_disabled) {
1086 /* enable the SDIO function */
1087 sdio_claim_host(func);
1088
1089 if ((device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK) >= MANUFACTURER_ID_AR6003_BASE) {
1090 /* enable 4-bit ASYNC interrupt on AR6003 or later devices */
1091 ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG, SDIO_IRQ_MODE_ASYNC_4BIT_IRQ);
1092 if (ret) {
1093 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret));
1094 sdio_release_host(func);
1095 return ret;
1096 }
1097 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n"));
1098 }
1099 /* give us some time to enable, in ms */
1100 func->enable_timeout = 100;
1101 ret = sdio_enable_func(func);
1102 if (ret) {
1103 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n",
1104 __FUNCTION__, ret));
1105 sdio_release_host(func);
1106 return ret;
1107 }
1108 ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
1109 sdio_release_host(func);
1110 if (ret) {
1111 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x AR6K: 0x%X\n",
1112 __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret));
1113 return ret;
1114 }
1115 device->is_disabled = false;
1116 /* create async I/O thread */
1117 if (!device->async_task) {
1118 device->async_shutdown = 0;
1119 device->async_task = kthread_create(async_task,
1120 (void *)device,
1121 "AR6K Async");
1122 if (IS_ERR(device->async_task)) {
1123 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__));
1124 return -ENOMEM;
1125 }
1126 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n"));
1127 wake_up_process(device->async_task );
1128 }
1129 }
1130
1131 if (!device->claimedContext) {
1132 taskFunc = startup_task;
1133 taskName = "AR6K startup";
1134 ret = 0;
1135#if defined(CONFIG_PM)
1136 } else {
1137 taskFunc = enable_task;
1138 taskName = "AR6K enable";
1139 ret = -ENOMEM;
1140#endif /* CONFIG_PM */
1141 }
1142 /* create resume thread */
1143 pTask = kthread_create(taskFunc, (void *)device, taskName);
1144 if (IS_ERR(pTask)) {
1145 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create enabel task\n", __FUNCTION__));
1146 return -ENOMEM;
1147 }
1148 wake_up_process(pTask);
1149 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifEnableFunc\n"));
1150
1151 /* task will call the enable func, indicate pending */
1152 return ret;
1153}
1154
1155/*
1156 * This should be moved to AR6K HTC layer.
1157 */
1158int hifWaitForPendingRecv(struct hif_device *device)
1159{
1160 s32 cnt = 10;
1161 u8 host_int_status;
1162 int status = 0;
1163
1164 do {
1165 while (atomic_read(&device->irqHandling)) {
1166 /* wait until irq handler finished all the jobs */
1167 schedule_timeout(HZ/10);
1168 }
1169 /* check if there is any pending irq due to force done */
1170 host_int_status = 0;
1171 status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS,
1172 (u8 *)&host_int_status, sizeof(host_int_status),
1173 HIF_RD_SYNC_BYTE_INC, NULL);
1174 host_int_status = !status ? (host_int_status & (1 << 0)) : 0;
1175 if (host_int_status) {
1176 schedule(); /* schedule for next dsrHandler */
1177 }
1178 } while (host_int_status && --cnt > 0);
1179
1180 if (host_int_status && cnt == 0) {
1181 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
1182 ("AR6000: %s(), Unable clear up pending IRQ before the system suspended\n", __FUNCTION__));
1183 }
1184
1185 return 0;
1186}
1187
1188static void
1189delHifDevice(struct hif_device * device)
1190{
1191 AR_DEBUG_ASSERT(device!= NULL);
1192 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: delHifDevice; 0x%p\n", device));
1193 kfree(device->dma_buffer);
1194 kfree(device);
1195}
1196
1197static void ResetAllCards(void)
1198{
1199}
1200
1201void HIFClaimDevice(struct hif_device *device, void *context)
1202{
1203 device->claimedContext = context;
1204}
1205
1206void HIFReleaseDevice(struct hif_device *device)
1207{
1208 device->claimedContext = NULL;
1209}
1210
1211int HIFAttachHTC(struct hif_device *device, HTC_CALLBACKS *callbacks)
1212{
1213 if (device->htcCallbacks.context != NULL) {
1214 /* already in use! */
1215 return A_ERROR;
1216 }
1217 device->htcCallbacks = *callbacks;
1218 return 0;
1219}
1220
1221void HIFDetachHTC(struct hif_device *device)
1222{
1223 A_MEMZERO(&device->htcCallbacks,sizeof(device->htcCallbacks));
1224}
1225
1226#define SDIO_SET_CMD52_ARG(arg,rw,func,raw,address,writedata) \
1227 (arg) = (((rw) & 1) << 31) | \
1228 (((func) & 0x7) << 28) | \
1229 (((raw) & 1) << 27) | \
1230 (1 << 26) | \
1231 (((address) & 0x1FFFF) << 9) | \
1232 (1 << 8) | \
1233 ((writedata) & 0xFF)
1234
1235#define SDIO_SET_CMD52_READ_ARG(arg,func,address) \
1236 SDIO_SET_CMD52_ARG(arg,0,(func),0,address,0x00)
1237#define SDIO_SET_CMD52_WRITE_ARG(arg,func,address,value) \
1238 SDIO_SET_CMD52_ARG(arg,1,(func),0,address,value)
1239
1240static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte)
1241{
1242 struct mmc_command ioCmd;
1243 unsigned long arg;
1244
1245 memset(&ioCmd,0,sizeof(ioCmd));
1246 SDIO_SET_CMD52_WRITE_ARG(arg,0,address,byte);
1247 ioCmd.opcode = SD_IO_RW_DIRECT;
1248 ioCmd.arg = arg;
1249 ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
1250
1251 return mmc_wait_for_cmd(card->host, &ioCmd, 0);
1252}
1253
1254static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte)
1255{
1256 struct mmc_command ioCmd;
1257 unsigned long arg;
1258 s32 err;
1259
1260 memset(&ioCmd,0,sizeof(ioCmd));
1261 SDIO_SET_CMD52_READ_ARG(arg,0,address);
1262 ioCmd.opcode = SD_IO_RW_DIRECT;
1263 ioCmd.arg = arg;
1264 ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
1265
1266 err = mmc_wait_for_cmd(card->host, &ioCmd, 0);
1267
1268 if ((!err) && (byte)) {
1269 *byte = ioCmd.resp[0] & 0xFF;
1270 }
1271
1272 return err;
1273}
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c
deleted file mode 100644
index 7516d913dab..00000000000
--- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c
+++ /dev/null
@@ -1,393 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// HIF scatter implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25#include <linux/mmc/card.h>
26#include <linux/mmc/host.h>
27#include <linux/mmc/sdio_func.h>
28#include <linux/mmc/sdio_ids.h>
29#include <linux/mmc/sdio.h>
30#include <linux/kthread.h>
31#include "hif_internal.h"
32#define ATH_MODULE_NAME hif
33#include "a_debug.h"
34
35#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT
36
37#define _CMD53_ARG_READ 0
38#define _CMD53_ARG_WRITE 1
39#define _CMD53_ARG_BLOCK_BASIS 1
40#define _CMD53_ARG_FIXED_ADDRESS 0
41#define _CMD53_ARG_INCR_ADDRESS 1
42
43#define SDIO_SET_CMD53_ARG(arg,rw,func,mode,opcode,address,bytes_blocks) \
44 (arg) = (((rw) & 1) << 31) | \
45 (((func) & 0x7) << 28) | \
46 (((mode) & 1) << 27) | \
47 (((opcode) & 1) << 26) | \
48 (((address) & 0x1FFFF) << 9) | \
49 ((bytes_blocks) & 0x1FF)
50
51static void FreeScatterReq(struct hif_device *device, struct hif_scatter_req *pReq)
52{
53 unsigned long flag;
54
55 spin_lock_irqsave(&device->lock, flag);
56
57 DL_ListInsertTail(&device->ScatterReqHead, &pReq->ListLink);
58
59 spin_unlock_irqrestore(&device->lock, flag);
60
61}
62
63static struct hif_scatter_req *AllocScatterReq(struct hif_device *device)
64{
65 struct dl_list *pItem;
66 unsigned long flag;
67
68 spin_lock_irqsave(&device->lock, flag);
69
70 pItem = DL_ListRemoveItemFromHead(&device->ScatterReqHead);
71
72 spin_unlock_irqrestore(&device->lock, flag);
73
74 if (pItem != NULL) {
75 return A_CONTAINING_STRUCT(pItem, struct hif_scatter_req, ListLink);
76 }
77
78 return NULL;
79}
80
81 /* called by async task to perform the operation synchronously using direct MMC APIs */
82int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest)
83{
84 int i;
85 u8 rw;
86 u8 opcode;
87 struct mmc_request mmcreq;
88 struct mmc_command cmd;
89 struct mmc_data data;
90 struct hif_scatter_req_priv *pReqPriv;
91 struct hif_scatter_req *pReq;
92 int status = 0;
93 struct scatterlist *pSg;
94
95 pReqPriv = busrequest->pScatterReq;
96
97 A_ASSERT(pReqPriv != NULL);
98
99 pReq = pReqPriv->pHifScatterReq;
100
101 memset(&mmcreq, 0, sizeof(struct mmc_request));
102 memset(&cmd, 0, sizeof(struct mmc_command));
103 memset(&data, 0, sizeof(struct mmc_data));
104
105 data.blksz = HIF_MBOX_BLOCK_SIZE;
106 data.blocks = pReq->TotalLength / HIF_MBOX_BLOCK_SIZE;
107
108 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: (%s) Address: 0x%X, (BlockLen: %d, BlockCount: %d) , (tot:%d,sg:%d)\n",
109 (pReq->Request & HIF_WRITE) ? "WRITE":"READ", pReq->Address, data.blksz, data.blocks,
110 pReq->TotalLength,pReq->ValidScatterEntries));
111
112 if (pReq->Request & HIF_WRITE) {
113 rw = _CMD53_ARG_WRITE;
114 data.flags = MMC_DATA_WRITE;
115 } else {
116 rw = _CMD53_ARG_READ;
117 data.flags = MMC_DATA_READ;
118 }
119
120 if (pReq->Request & HIF_FIXED_ADDRESS) {
121 opcode = _CMD53_ARG_FIXED_ADDRESS;
122 } else {
123 opcode = _CMD53_ARG_INCR_ADDRESS;
124 }
125
126 /* fill SG entries */
127 pSg = pReqPriv->sgentries;
128 sg_init_table(pSg, pReq->ValidScatterEntries);
129
130 /* assemble SG list */
131 for (i = 0 ; i < pReq->ValidScatterEntries ; i++, pSg++) {
132 /* setup each sg entry */
133 if ((unsigned long)pReq->ScatterList[i].pBuffer & 0x3) {
134 /* note some scatter engines can handle unaligned buffers, print this
135 * as informational only */
136 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER,
137 ("HIF: (%s) Scatter Buffer is unaligned 0x%lx\n",
138 pReq->Request & HIF_WRITE ? "WRITE":"READ",
139 (unsigned long)pReq->ScatterList[i].pBuffer));
140 }
141
142 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, (" %d: Addr:0x%lX, Len:%d \n",
143 i,(unsigned long)pReq->ScatterList[i].pBuffer,pReq->ScatterList[i].Length));
144
145 sg_set_buf(pSg, pReq->ScatterList[i].pBuffer, pReq->ScatterList[i].Length);
146 }
147 /* set scatter-gather table for request */
148 data.sg = pReqPriv->sgentries;
149 data.sg_len = pReq->ValidScatterEntries;
150 /* set command argument */
151 SDIO_SET_CMD53_ARG(cmd.arg,
152 rw,
153 device->func->num,
154 _CMD53_ARG_BLOCK_BASIS,
155 opcode,
156 pReq->Address,
157 data.blocks);
158
159 cmd.opcode = SD_IO_RW_EXTENDED;
160 cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
161
162 mmcreq.cmd = &cmd;
163 mmcreq.data = &data;
164
165 mmc_set_data_timeout(&data, device->func->card);
166 /* synchronous call to process request */
167 mmc_wait_for_req(device->func->card->host, &mmcreq);
168
169 if (cmd.error) {
170 status = A_ERROR;
171 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: cmd error: %d \n",cmd.error));
172 }
173
174 if (data.error) {
175 status = A_ERROR;
176 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: data error: %d \n",data.error));
177 }
178
179 if (status) {
180 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: FAILED!!! (%s) Address: 0x%X, Block mode (BlockLen: %d, BlockCount: %d)\n",
181 (pReq->Request & HIF_WRITE) ? "WRITE":"READ",pReq->Address, data.blksz, data.blocks));
182 }
183
184 /* set completion status, fail or success */
185 pReq->CompletionStatus = status;
186
187 if (pReq->Request & HIF_ASYNCHRONOUS) {
188 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: async_task completion routine req: 0x%lX (%d)\n",(unsigned long)busrequest, status));
189 /* complete the request */
190 A_ASSERT(pReq->CompletionRoutine != NULL);
191 pReq->CompletionRoutine(pReq);
192 } else {
193 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER async_task upping busrequest : 0x%lX (%d)\n", (unsigned long)busrequest,status));
194 /* signal wait */
195 up(&busrequest->sem_req);
196 }
197
198 return status;
199}
200
201 /* callback to issue a read-write scatter request */
202static int HifReadWriteScatter(struct hif_device *device, struct hif_scatter_req *pReq)
203{
204 int status = A_EINVAL;
205 u32 request = pReq->Request;
206 struct hif_scatter_req_priv *pReqPriv = (struct hif_scatter_req_priv *)pReq->HIFPrivate[0];
207
208 do {
209
210 A_ASSERT(pReqPriv != NULL);
211
212 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: total len: %d Scatter Entries: %d\n",
213 pReq->TotalLength, pReq->ValidScatterEntries));
214
215 if (!(request & HIF_EXTENDED_IO)) {
216 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
217 ("HIF-SCATTER: Invalid command type: 0x%08x\n", request));
218 break;
219 }
220
221 if (!(request & (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS))) {
222 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
223 ("HIF-SCATTER: Invalid execution mode: 0x%08x\n", request));
224 break;
225 }
226
227 if (!(request & HIF_BLOCK_BASIS)) {
228 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
229 ("HIF-SCATTER: Invalid data mode: 0x%08x\n", request));
230 break;
231 }
232
233 if (pReq->TotalLength > MAX_SCATTER_REQ_TRANSFER_SIZE) {
234 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
235 ("HIF-SCATTER: Invalid length: %d \n", pReq->TotalLength));
236 break;
237 }
238
239 if (pReq->TotalLength == 0) {
240 A_ASSERT(false);
241 break;
242 }
243
244 /* add bus request to the async list for the async I/O thread to process */
245 AddToAsyncList(device, pReqPriv->busrequest);
246
247 if (request & HIF_SYNCHRONOUS) {
248 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued sync req: 0x%lX\n", (unsigned long)pReqPriv->busrequest));
249 /* signal thread and wait */
250 up(&device->sem_async);
251 if (down_interruptible(&pReqPriv->busrequest->sem_req) != 0) {
252 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,("HIF-SCATTER: interrupted! \n"));
253 /* interrupted, exit */
254 status = A_ERROR;
255 break;
256 } else {
257 status = pReq->CompletionStatus;
258 }
259 } else {
260 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued async req: 0x%lX\n", (unsigned long)pReqPriv->busrequest));
261 /* wake thread, it will process and then take care of the async callback */
262 up(&device->sem_async);
263 status = 0;
264 }
265
266 } while (false);
267
268 if (status && (request & HIF_ASYNCHRONOUS)) {
269 pReq->CompletionStatus = status;
270 pReq->CompletionRoutine(pReq);
271 status = 0;
272 }
273
274 return status;
275}
276
277 /* setup of HIF scatter resources */
278int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo)
279{
280 int status = A_ERROR;
281 int i;
282 struct hif_scatter_req_priv *pReqPriv;
283 BUS_REQUEST *busrequest;
284
285 do {
286
287 /* check if host supports scatter requests and it meets our requirements */
288 if (device->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
289 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n",
290 device->func->card->host->max_segs, MAX_SCATTER_ENTRIES_PER_REQ));
291 status = A_ENOTSUP;
292 break;
293 }
294
295 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HIF-SCATTER Enabled: max scatter req : %d entries: %d \n",
296 MAX_SCATTER_REQUESTS, MAX_SCATTER_ENTRIES_PER_REQ));
297
298 for (i = 0; i < MAX_SCATTER_REQUESTS; i++) {
299 /* allocate the private request blob */
300 pReqPriv = (struct hif_scatter_req_priv *)A_MALLOC(sizeof(struct hif_scatter_req_priv));
301 if (NULL == pReqPriv) {
302 break;
303 }
304 A_MEMZERO(pReqPriv, sizeof(struct hif_scatter_req_priv));
305 /* save the device instance*/
306 pReqPriv->device = device;
307 /* allocate the scatter request */
308 pReqPriv->pHifScatterReq = (struct hif_scatter_req *)A_MALLOC(sizeof(struct hif_scatter_req) +
309 (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item)));
310
311 if (NULL == pReqPriv->pHifScatterReq) {
312 kfree(pReqPriv);
313 break;
314 }
315 /* just zero the main part of the scatter request */
316 A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(struct hif_scatter_req));
317 /* back pointer to the private struct */
318 pReqPriv->pHifScatterReq->HIFPrivate[0] = pReqPriv;
319 /* allocate a bus request for this scatter request */
320 busrequest = hifAllocateBusRequest(device);
321 if (NULL == busrequest) {
322 kfree(pReqPriv->pHifScatterReq);
323 kfree(pReqPriv);
324 break;
325 }
326 /* assign the scatter request to this bus request */
327 busrequest->pScatterReq = pReqPriv;
328 /* point back to the request */
329 pReqPriv->busrequest = busrequest;
330 /* add it to the scatter pool */
331 FreeScatterReq(device,pReqPriv->pHifScatterReq);
332 }
333
334 if (i != MAX_SCATTER_REQUESTS) {
335 status = A_NO_MEMORY;
336 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : failed to alloc scatter resources !\n"));
337 break;
338 }
339
340 /* set scatter function pointers */
341 pInfo->pAllocateReqFunc = AllocScatterReq;
342 pInfo->pFreeReqFunc = FreeScatterReq;
343 pInfo->pReadWriteScatterFunc = HifReadWriteScatter;
344 pInfo->MaxScatterEntries = MAX_SCATTER_ENTRIES_PER_REQ;
345 pInfo->MaxTransferSizePerScatterReq = MAX_SCATTER_REQ_TRANSFER_SIZE;
346
347 status = 0;
348
349 } while (false);
350
351 if (status) {
352 CleanupHIFScatterResources(device);
353 }
354
355 return status;
356}
357
358 /* clean up scatter support */
359void CleanupHIFScatterResources(struct hif_device *device)
360{
361 struct hif_scatter_req_priv *pReqPriv;
362 struct hif_scatter_req *pReq;
363
364 /* empty the free list */
365
366 while (1) {
367
368 pReq = AllocScatterReq(device);
369
370 if (NULL == pReq) {
371 break;
372 }
373
374 pReqPriv = (struct hif_scatter_req_priv *)pReq->HIFPrivate[0];
375 A_ASSERT(pReqPriv != NULL);
376
377 if (pReqPriv->busrequest != NULL) {
378 pReqPriv->busrequest->pScatterReq = NULL;
379 /* free bus request */
380 hifFreeBusRequest(device, pReqPriv->busrequest);
381 pReqPriv->busrequest = NULL;
382 }
383
384 if (pReqPriv->pHifScatterReq != NULL) {
385 kfree(pReqPriv->pHifScatterReq);
386 pReqPriv->pHifScatterReq = NULL;
387 }
388
389 kfree(pReqPriv);
390 }
391}
392
393#endif // HIF_LINUX_MMC_SCATTER_SUPPORT
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c
deleted file mode 100644
index f8607bc0892..00000000000
--- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c
+++ /dev/null
@@ -1,1479 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6k.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// AR6K device layer that handles register level I/O
22//
23// Author(s): ="Atheros"
24//==============================================================================
25
26#include "a_config.h"
27#include "athdefs.h"
28#include "hw/mbox_host_reg.h"
29#include "a_osapi.h"
30#include "../htc_debug.h"
31#include "hif.h"
32#include "htc_packet.h"
33#include "ar6k.h"
34
35#define MAILBOX_FOR_BLOCK_SIZE 1
36
37int DevEnableInterrupts(struct ar6k_device *pDev);
38int DevDisableInterrupts(struct ar6k_device *pDev);
39
40static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev);
41
42void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket)
43{
44 LOCK_AR6K(pDev);
45 HTC_PACKET_ENQUEUE(&pDev->RegisterIOList,pPacket);
46 UNLOCK_AR6K(pDev);
47}
48
49struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev)
50{
51 struct htc_packet *pPacket;
52
53 LOCK_AR6K(pDev);
54 pPacket = HTC_PACKET_DEQUEUE(&pDev->RegisterIOList);
55 UNLOCK_AR6K(pDev);
56
57 return pPacket;
58}
59
60void DevCleanup(struct ar6k_device *pDev)
61{
62 DevCleanupGMbox(pDev);
63
64 if (pDev->HifAttached) {
65 HIFDetachHTC(pDev->HIFDevice);
66 pDev->HifAttached = false;
67 }
68
69 DevCleanupVirtualScatterSupport(pDev);
70
71 if (A_IS_MUTEX_VALID(&pDev->Lock)) {
72 A_MUTEX_DELETE(&pDev->Lock);
73 }
74}
75
76int DevSetup(struct ar6k_device *pDev)
77{
78 u32 blocksizes[AR6K_MAILBOXES];
79 int status = 0;
80 int i;
81 HTC_CALLBACKS htcCallbacks;
82
83 do {
84
85 DL_LIST_INIT(&pDev->ScatterReqHead);
86 /* initialize our free list of IO packets */
87 INIT_HTC_PACKET_QUEUE(&pDev->RegisterIOList);
88 A_MUTEX_INIT(&pDev->Lock);
89
90 A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS));
91 /* the device layer handles these */
92 htcCallbacks.rwCompletionHandler = DevRWCompletionHandler;
93 htcCallbacks.dsrHandler = DevDsrHandler;
94 htcCallbacks.context = pDev;
95
96 status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks);
97
98 if (status) {
99 break;
100 }
101
102 pDev->HifAttached = true;
103
104 /* get the addresses for all 4 mailboxes */
105 status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR,
106 &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo));
107
108 if (status) {
109 A_ASSERT(false);
110 break;
111 }
112
113 /* carve up register I/O packets (these are for ASYNC register I/O ) */
114 for (i = 0; i < AR6K_MAX_REG_IO_BUFFERS; i++) {
115 struct htc_packet *pIOPacket;
116 pIOPacket = &pDev->RegIOBuffers[i].HtcPacket;
117 SET_HTC_PACKET_INFO_RX_REFILL(pIOPacket,
118 pDev,
119 pDev->RegIOBuffers[i].Buffer,
120 AR6K_REG_IO_BUFFER_SIZE,
121 0); /* don't care */
122 AR6KFreeIOPacket(pDev,pIOPacket);
123 }
124
125 /* get the block sizes */
126 status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
127 blocksizes, sizeof(blocksizes));
128
129 if (status) {
130 A_ASSERT(false);
131 break;
132 }
133
134 /* note: we actually get the block size of a mailbox other than 0, for SDIO the block
135 * size on mailbox 0 is artificially set to 1. So we use the block size that is set
136 * for the other 3 mailboxes */
137 pDev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE];
138 /* must be a power of 2 */
139 A_ASSERT((pDev->BlockSize & (pDev->BlockSize - 1)) == 0);
140
141 /* assemble mask, used for padding to a block */
142 pDev->BlockMask = pDev->BlockSize - 1;
143
144 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("BlockSize: %d, MailboxAddress:0x%X \n",
145 pDev->BlockSize, pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]));
146
147 pDev->GetPendingEventsFunc = NULL;
148 /* see if the HIF layer implements the get pending events function */
149 HIFConfigureDevice(pDev->HIFDevice,
150 HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
151 &pDev->GetPendingEventsFunc,
152 sizeof(pDev->GetPendingEventsFunc));
153
154 /* assume we can process HIF interrupt events asynchronously */
155 pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC;
156
157 /* see if the HIF layer overrides this assumption */
158 HIFConfigureDevice(pDev->HIFDevice,
159 HIF_DEVICE_GET_IRQ_PROC_MODE,
160 &pDev->HifIRQProcessingMode,
161 sizeof(pDev->HifIRQProcessingMode));
162
163 switch (pDev->HifIRQProcessingMode) {
164 case HIF_DEVICE_IRQ_SYNC_ONLY:
165 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HIF Interrupt processing is SYNC ONLY\n"));
166 /* see if HIF layer wants HTC to yield */
167 HIFConfigureDevice(pDev->HIFDevice,
168 HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
169 &pDev->HifIRQYieldParams,
170 sizeof(pDev->HifIRQYieldParams));
171
172 if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) {
173 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
174 ("HIF requests that DSR yield per %d RECV packets \n",
175 pDev->HifIRQYieldParams.RecvPacketYieldCount));
176 pDev->DSRCanYield = true;
177 }
178 break;
179 case HIF_DEVICE_IRQ_ASYNC_SYNC:
180 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYNC and SYNC\n"));
181 break;
182 default:
183 A_ASSERT(false);
184 }
185
186 pDev->HifMaskUmaskRecvEvent = NULL;
187
188 /* see if the HIF layer implements the mask/unmask recv events function */
189 HIFConfigureDevice(pDev->HIFDevice,
190 HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
191 &pDev->HifMaskUmaskRecvEvent,
192 sizeof(pDev->HifMaskUmaskRecvEvent));
193
194 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF special overrides : 0x%lX , 0x%lX\n",
195 (unsigned long)pDev->GetPendingEventsFunc, (unsigned long)pDev->HifMaskUmaskRecvEvent));
196
197 status = DevDisableInterrupts(pDev);
198
199 if (status) {
200 break;
201 }
202
203 status = DevSetupGMbox(pDev);
204
205 } while (false);
206
207 if (status) {
208 if (pDev->HifAttached) {
209 HIFDetachHTC(pDev->HIFDevice);
210 pDev->HifAttached = false;
211 }
212 }
213
214 return status;
215
216}
217
218int DevEnableInterrupts(struct ar6k_device *pDev)
219{
220 int status;
221 struct ar6k_irq_enable_registers regs;
222
223 LOCK_AR6K(pDev);
224
225 /* Enable all the interrupts except for the internal AR6000 CPU interrupt */
226 pDev->IrqEnableRegisters.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) |
227 INT_STATUS_ENABLE_CPU_SET(0x01) |
228 INT_STATUS_ENABLE_COUNTER_SET(0x01);
229
230 if (NULL == pDev->GetPendingEventsFunc) {
231 pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
232 } else {
233 /* The HIF layer provided us with a pending events function which means that
234 * the detection of pending mbox messages is handled in the HIF layer.
235 * This is the case for the SPI2 interface.
236 * In the normal case we enable MBOX interrupts, for the case
237 * with HIFs that offer this mechanism, we keep these interrupts
238 * masked */
239 pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
240 }
241
242
243 /* Set up the CPU Interrupt Status Register */
244 pDev->IrqEnableRegisters.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00);
245
246 /* Set up the Error Interrupt Status Register */
247 pDev->IrqEnableRegisters.error_status_enable =
248 ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) |
249 ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01);
250
251 /* Set up the Counter Interrupt Status Register (only for debug interrupt to catch fatal errors) */
252 pDev->IrqEnableRegisters.counter_int_status_enable =
253 COUNTER_INT_STATUS_ENABLE_BIT_SET(AR6K_TARGET_DEBUG_INTR_MASK);
254
255 /* copy into our temp area */
256 memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
257
258 UNLOCK_AR6K(pDev);
259
260 /* always synchronous */
261 status = HIFReadWrite(pDev->HIFDevice,
262 INT_STATUS_ENABLE_ADDRESS,
263 &regs.int_status_enable,
264 AR6K_IRQ_ENABLE_REGS_SIZE,
265 HIF_WR_SYNC_BYTE_INC,
266 NULL);
267
268 if (status) {
269 /* Can't write it for some reason */
270 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
271 ("Failed to update interrupt control registers err: %d\n", status));
272
273 }
274
275 return status;
276}
277
278int DevDisableInterrupts(struct ar6k_device *pDev)
279{
280 struct ar6k_irq_enable_registers regs;
281
282 LOCK_AR6K(pDev);
283 /* Disable all interrupts */
284 pDev->IrqEnableRegisters.int_status_enable = 0;
285 pDev->IrqEnableRegisters.cpu_int_status_enable = 0;
286 pDev->IrqEnableRegisters.error_status_enable = 0;
287 pDev->IrqEnableRegisters.counter_int_status_enable = 0;
288 /* copy into our temp area */
289 memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
290
291 UNLOCK_AR6K(pDev);
292
293 /* always synchronous */
294 return HIFReadWrite(pDev->HIFDevice,
295 INT_STATUS_ENABLE_ADDRESS,
296 &regs.int_status_enable,
297 AR6K_IRQ_ENABLE_REGS_SIZE,
298 HIF_WR_SYNC_BYTE_INC,
299 NULL);
300}
301
302/* enable device interrupts */
303int DevUnmaskInterrupts(struct ar6k_device *pDev)
304{
305 /* for good measure, make sure interrupt are disabled before unmasking at the HIF
306 * layer.
307 * The rationale here is that between device insertion (where we clear the interrupts the first time)
308 * and when HTC is finally ready to handle interrupts, other software can perform target "soft" resets.
309 * The AR6K interrupt enables reset back to an "enabled" state when this happens.
310 * */
311 int IntStatus = 0;
312 DevDisableInterrupts(pDev);
313
314#ifdef THREAD_X
315 // Tobe verified...
316 IntStatus = DevEnableInterrupts(pDev);
317 /* Unmask the host controller interrupts */
318 HIFUnMaskInterrupt(pDev->HIFDevice);
319#else
320 /* Unmask the host controller interrupts */
321 HIFUnMaskInterrupt(pDev->HIFDevice);
322 IntStatus = DevEnableInterrupts(pDev);
323#endif
324
325 return IntStatus;
326}
327
328/* disable all device interrupts */
329int DevMaskInterrupts(struct ar6k_device *pDev)
330{
331 /* mask the interrupt at the HIF layer, we don't want a stray interrupt taken while
332 * we zero out our shadow registers in DevDisableInterrupts()*/
333 HIFMaskInterrupt(pDev->HIFDevice);
334
335 return DevDisableInterrupts(pDev);
336}
337
338/* callback when our fetch to enable/disable completes */
339static void DevDoEnableDisableRecvAsyncHandler(void *Context, struct htc_packet *pPacket)
340{
341 struct ar6k_device *pDev = (struct ar6k_device *)Context;
342
343 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDoEnableDisableRecvAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
344
345 if (pPacket->Status) {
346 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
347 (" Failed to disable receiver, status:%d \n", pPacket->Status));
348 }
349 /* free this IO packet */
350 AR6KFreeIOPacket(pDev,pPacket);
351 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDoEnableDisableRecvAsyncHandler \n"));
352}
353
354/* disable packet reception (used in case the host runs out of buffers)
355 * this is the "override" method when the HIF reports another methods to
356 * disable recv events */
357static int DevDoEnableDisableRecvOverride(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode)
358{
359 int status = 0;
360 struct htc_packet *pIOPacket = NULL;
361
362 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n",
363 EnableRecv,AsyncMode));
364
365 do {
366
367 if (AsyncMode) {
368
369 pIOPacket = AR6KAllocIOPacket(pDev);
370
371 if (NULL == pIOPacket) {
372 status = A_NO_MEMORY;
373 A_ASSERT(false);
374 break;
375 }
376
377 /* stick in our completion routine when the I/O operation completes */
378 pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
379 pIOPacket->pContext = pDev;
380
381 /* call the HIF layer override and do this asynchronously */
382 status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
383 EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
384 pIOPacket);
385 break;
386 }
387
388 /* if we get here we are doing it synchronously */
389 status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
390 EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
391 NULL);
392
393 } while (false);
394
395 if (status && (pIOPacket != NULL)) {
396 AR6KFreeIOPacket(pDev,pIOPacket);
397 }
398
399 return status;
400}
401
402/* disable packet reception (used in case the host runs out of buffers)
403 * this is the "normal" method using the interrupt enable registers through
404 * the host I/F */
405static int DevDoEnableDisableRecvNormal(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode)
406{
407 int status = 0;
408 struct htc_packet *pIOPacket = NULL;
409 struct ar6k_irq_enable_registers regs;
410
411 /* take the lock to protect interrupt enable shadows */
412 LOCK_AR6K(pDev);
413
414 if (EnableRecv) {
415 pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
416 } else {
417 pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
418 }
419
420 /* copy into our temp area */
421 memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
422 UNLOCK_AR6K(pDev);
423
424 do {
425
426 if (AsyncMode) {
427
428 pIOPacket = AR6KAllocIOPacket(pDev);
429
430 if (NULL == pIOPacket) {
431 status = A_NO_MEMORY;
432 A_ASSERT(false);
433 break;
434 }
435
436 /* copy values to write to our async I/O buffer */
437 memcpy(pIOPacket->pBuffer,&regs,AR6K_IRQ_ENABLE_REGS_SIZE);
438
439 /* stick in our completion routine when the I/O operation completes */
440 pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
441 pIOPacket->pContext = pDev;
442
443 /* write it out asynchronously */
444 HIFReadWrite(pDev->HIFDevice,
445 INT_STATUS_ENABLE_ADDRESS,
446 pIOPacket->pBuffer,
447 AR6K_IRQ_ENABLE_REGS_SIZE,
448 HIF_WR_ASYNC_BYTE_INC,
449 pIOPacket);
450 break;
451 }
452
453 /* if we get here we are doing it synchronously */
454
455 status = HIFReadWrite(pDev->HIFDevice,
456 INT_STATUS_ENABLE_ADDRESS,
457 &regs.int_status_enable,
458 AR6K_IRQ_ENABLE_REGS_SIZE,
459 HIF_WR_SYNC_BYTE_INC,
460 NULL);
461
462 } while (false);
463
464 if (status && (pIOPacket != NULL)) {
465 AR6KFreeIOPacket(pDev,pIOPacket);
466 }
467
468 return status;
469}
470
471
472int DevStopRecv(struct ar6k_device *pDev, bool AsyncMode)
473{
474 if (NULL == pDev->HifMaskUmaskRecvEvent) {
475 return DevDoEnableDisableRecvNormal(pDev,false,AsyncMode);
476 } else {
477 return DevDoEnableDisableRecvOverride(pDev,false,AsyncMode);
478 }
479}
480
481int DevEnableRecv(struct ar6k_device *pDev, bool AsyncMode)
482{
483 if (NULL == pDev->HifMaskUmaskRecvEvent) {
484 return DevDoEnableDisableRecvNormal(pDev,true,AsyncMode);
485 } else {
486 return DevDoEnableDisableRecvOverride(pDev,true,AsyncMode);
487 }
488}
489
490int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRecvPending)
491{
492 int status = 0;
493 u8 host_int_status = 0x0;
494 u32 counter = 0x0;
495
496 if(TimeoutInMs < 100)
497 {
498 TimeoutInMs = 100;
499 }
500
501 counter = TimeoutInMs / 100;
502
503 do
504 {
505 //Read the Host Interrupt Status Register
506 status = HIFReadWrite(pDev->HIFDevice,
507 HOST_INT_STATUS_ADDRESS,
508 &host_int_status,
509 sizeof(u8),
510 HIF_RD_SYNC_BYTE_INC,
511 NULL);
512 if (status)
513 {
514 AR_DEBUG_PRINTF(ATH_LOG_ERR,("DevWaitForPendingRecv:Read HOST_INT_STATUS_ADDRESS Failed 0x%X\n",status));
515 break;
516 }
517
518 host_int_status = !status ? (host_int_status & (1 << 0)):0;
519 if(!host_int_status)
520 {
521 status = 0;
522 *pbIsRecvPending = false;
523 break;
524 }
525 else
526 {
527 *pbIsRecvPending = true;
528 }
529
530 A_MDELAY(100);
531
532 counter--;
533
534 }while(counter);
535 return status;
536}
537
538void DevDumpRegisters(struct ar6k_device *pDev,
539 struct ar6k_irq_proc_registers *pIrqProcRegs,
540 struct ar6k_irq_enable_registers *pIrqEnableRegs)
541{
542
543 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("\n<------- Register Table -------->\n"));
544
545 if (pIrqProcRegs != NULL) {
546 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
547 ("Host Int Status: 0x%x\n",pIrqProcRegs->host_int_status));
548 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
549 ("CPU Int Status: 0x%x\n",pIrqProcRegs->cpu_int_status));
550 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
551 ("Error Int Status: 0x%x\n",pIrqProcRegs->error_int_status));
552 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
553 ("Counter Int Status: 0x%x\n",pIrqProcRegs->counter_int_status));
554 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
555 ("Mbox Frame: 0x%x\n",pIrqProcRegs->mbox_frame));
556 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
557 ("Rx Lookahead Valid: 0x%x\n",pIrqProcRegs->rx_lookahead_valid));
558 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
559 ("Rx Lookahead 0: 0x%x\n",pIrqProcRegs->rx_lookahead[0]));
560 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
561 ("Rx Lookahead 1: 0x%x\n",pIrqProcRegs->rx_lookahead[1]));
562
563 if (pDev->MailBoxInfo.GMboxAddress != 0) {
564 /* if the target supports GMBOX hardware, dump some additional state */
565 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
566 ("GMBOX Host Int Status 2: 0x%x\n",pIrqProcRegs->host_int_status2));
567 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
568 ("GMBOX RX Avail: 0x%x\n",pIrqProcRegs->gmbox_rx_avail));
569 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
570 ("GMBOX lookahead alias 0: 0x%x\n",pIrqProcRegs->rx_gmbox_lookahead_alias[0]));
571 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
572 ("GMBOX lookahead alias 1: 0x%x\n",pIrqProcRegs->rx_gmbox_lookahead_alias[1]));
573 }
574
575 }
576
577 if (pIrqEnableRegs != NULL) {
578 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
579 ("Int Status Enable: 0x%x\n",pIrqEnableRegs->int_status_enable));
580 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
581 ("Counter Int Status Enable: 0x%x\n",pIrqEnableRegs->counter_int_status_enable));
582 }
583 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("<------------------------------->\n"));
584}
585
586
587#define DEV_GET_VIRT_DMA_INFO(p) ((struct dev_scatter_dma_virtual_info *)((p)->HIFPrivate[0]))
588
589static struct hif_scatter_req *DevAllocScatterReq(struct hif_device *Context)
590{
591 struct dl_list *pItem;
592 struct ar6k_device *pDev = (struct ar6k_device *)Context;
593 LOCK_AR6K(pDev);
594 pItem = DL_ListRemoveItemFromHead(&pDev->ScatterReqHead);
595 UNLOCK_AR6K(pDev);
596 if (pItem != NULL) {
597 return A_CONTAINING_STRUCT(pItem, struct hif_scatter_req, ListLink);
598 }
599 return NULL;
600}
601
602static void DevFreeScatterReq(struct hif_device *Context, struct hif_scatter_req *pReq)
603{
604 struct ar6k_device *pDev = (struct ar6k_device *)Context;
605 LOCK_AR6K(pDev);
606 DL_ListInsertTail(&pDev->ScatterReqHead, &pReq->ListLink);
607 UNLOCK_AR6K(pDev);
608}
609
610int DevCopyScatterListToFromDMABuffer(struct hif_scatter_req *pReq, bool FromDMA)
611{
612 u8 *pDMABuffer = NULL;
613 int i, remaining;
614 u32 length;
615
616 pDMABuffer = pReq->pScatterBounceBuffer;
617
618 if (pDMABuffer == NULL) {
619 A_ASSERT(false);
620 return A_EINVAL;
621 }
622
623 remaining = (int)pReq->TotalLength;
624
625 for (i = 0; i < pReq->ValidScatterEntries; i++) {
626
627 length = min((int)pReq->ScatterList[i].Length, remaining);
628
629 if (length != (int)pReq->ScatterList[i].Length) {
630 A_ASSERT(false);
631 /* there is a problem with the scatter list */
632 return A_EINVAL;
633 }
634
635 if (FromDMA) {
636 /* from DMA buffer */
637 memcpy(pReq->ScatterList[i].pBuffer, pDMABuffer , length);
638 } else {
639 /* to DMA buffer */
640 memcpy(pDMABuffer, pReq->ScatterList[i].pBuffer, length);
641 }
642
643 pDMABuffer += length;
644 remaining -= length;
645 }
646
647 return 0;
648}
649
650static void DevReadWriteScatterAsyncHandler(void *Context, struct htc_packet *pPacket)
651{
652 struct ar6k_device *pDev = (struct ar6k_device *)Context;
653 struct hif_scatter_req *pReq = (struct hif_scatter_req *)pPacket->pPktContext;
654
655 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevReadWriteScatterAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
656
657 pReq->CompletionStatus = pPacket->Status;
658
659 AR6KFreeIOPacket(pDev,pPacket);
660
661 pReq->CompletionRoutine(pReq);
662
663 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevReadWriteScatterAsyncHandler \n"));
664}
665
666static int DevReadWriteScatter(struct hif_device *Context, struct hif_scatter_req *pReq)
667{
668 struct ar6k_device *pDev = (struct ar6k_device *)Context;
669 int status = 0;
670 struct htc_packet *pIOPacket = NULL;
671 u32 request = pReq->Request;
672
673 do {
674
675 if (pReq->TotalLength > AR6K_MAX_TRANSFER_SIZE_PER_SCATTER) {
676 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
677 ("Invalid length: %d \n", pReq->TotalLength));
678 break;
679 }
680
681 if (pReq->TotalLength == 0) {
682 A_ASSERT(false);
683 break;
684 }
685
686 if (request & HIF_ASYNCHRONOUS) {
687 /* use an I/O packet to carry this request */
688 pIOPacket = AR6KAllocIOPacket(pDev);
689 if (NULL == pIOPacket) {
690 status = A_NO_MEMORY;
691 break;
692 }
693
694 /* save the request */
695 pIOPacket->pPktContext = pReq;
696 /* stick in our completion routine when the I/O operation completes */
697 pIOPacket->Completion = DevReadWriteScatterAsyncHandler;
698 pIOPacket->pContext = pDev;
699 }
700
701 if (request & HIF_WRITE) {
702 /* in virtual DMA, we are issuing the requests through the legacy HIFReadWrite API
703 * this API will adjust the address automatically for the last byte to fall on the mailbox
704 * EOM. */
705
706 /* if the address is an extended address, we can adjust the address here since the extended
707 * address will bypass the normal checks in legacy HIF layers */
708 if (pReq->Address == pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress) {
709 pReq->Address += pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize - pReq->TotalLength;
710 }
711 }
712
713 /* use legacy readwrite */
714 status = HIFReadWrite(pDev->HIFDevice,
715 pReq->Address,
716 DEV_GET_VIRT_DMA_INFO(pReq)->pVirtDmaBuffer,
717 pReq->TotalLength,
718 request,
719 (request & HIF_ASYNCHRONOUS) ? pIOPacket : NULL);
720
721 } while (false);
722
723 if ((status != A_PENDING) && status && (request & HIF_ASYNCHRONOUS)) {
724 if (pIOPacket != NULL) {
725 AR6KFreeIOPacket(pDev,pIOPacket);
726 }
727 pReq->CompletionStatus = status;
728 pReq->CompletionRoutine(pReq);
729 status = 0;
730 }
731
732 return status;
733}
734
735
736static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev)
737{
738 struct hif_scatter_req *pReq;
739
740 while (1) {
741 pReq = DevAllocScatterReq((struct hif_device *)pDev);
742 if (NULL == pReq) {
743 break;
744 }
745 kfree(pReq);
746 }
747
748}
749
750 /* function to set up virtual scatter support if HIF layer has not implemented the interface */
751static int DevSetupVirtualScatterSupport(struct ar6k_device *pDev)
752{
753 int status = 0;
754 int bufferSize, sgreqSize;
755 int i;
756 struct dev_scatter_dma_virtual_info *pVirtualInfo;
757 struct hif_scatter_req *pReq;
758
759 bufferSize = sizeof(struct dev_scatter_dma_virtual_info) +
760 2 * (A_GET_CACHE_LINE_BYTES()) + AR6K_MAX_TRANSFER_SIZE_PER_SCATTER;
761
762 sgreqSize = sizeof(struct hif_scatter_req) +
763 (AR6K_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item));
764
765 for (i = 0; i < AR6K_SCATTER_REQS; i++) {
766 /* allocate the scatter request, buffer info and the actual virtual buffer itself */
767 pReq = (struct hif_scatter_req *)A_MALLOC(sgreqSize + bufferSize);
768
769 if (NULL == pReq) {
770 status = A_NO_MEMORY;
771 break;
772 }
773
774 A_MEMZERO(pReq, sgreqSize);
775
776 /* the virtual DMA starts after the scatter request struct */
777 pVirtualInfo = (struct dev_scatter_dma_virtual_info *)((u8 *)pReq + sgreqSize);
778 A_MEMZERO(pVirtualInfo, sizeof(struct dev_scatter_dma_virtual_info));
779
780 pVirtualInfo->pVirtDmaBuffer = &pVirtualInfo->DataArea[0];
781 /* align buffer to cache line in case host controller can actually DMA this */
782 pVirtualInfo->pVirtDmaBuffer = A_ALIGN_TO_CACHE_LINE(pVirtualInfo->pVirtDmaBuffer);
783 /* store the structure in the private area */
784 pReq->HIFPrivate[0] = pVirtualInfo;
785 /* we emulate a DMA bounce interface */
786 pReq->ScatterMethod = HIF_SCATTER_DMA_BOUNCE;
787 pReq->pScatterBounceBuffer = pVirtualInfo->pVirtDmaBuffer;
788 /* free request to the list */
789 DevFreeScatterReq((struct hif_device *)pDev,pReq);
790 }
791
792 if (status) {
793 DevCleanupVirtualScatterSupport(pDev);
794 } else {
795 pDev->HifScatterInfo.pAllocateReqFunc = DevAllocScatterReq;
796 pDev->HifScatterInfo.pFreeReqFunc = DevFreeScatterReq;
797 pDev->HifScatterInfo.pReadWriteScatterFunc = DevReadWriteScatter;
798 if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) {
799 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K: SPI bus requires RX scatter limits\n"));
800 pDev->HifScatterInfo.MaxScatterEntries = AR6K_MIN_SCATTER_ENTRIES_PER_REQ;
801 pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MIN_TRANSFER_SIZE_PER_SCATTER;
802 } else {
803 pDev->HifScatterInfo.MaxScatterEntries = AR6K_SCATTER_ENTRIES_PER_REQ;
804 pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MAX_TRANSFER_SIZE_PER_SCATTER;
805 }
806 pDev->ScatterIsVirtual = true;
807 }
808
809 return status;
810}
811
812int DevCleanupMsgBundling(struct ar6k_device *pDev)
813{
814 if(NULL != pDev)
815 {
816 DevCleanupVirtualScatterSupport(pDev);
817 }
818
819 return 0;
820}
821
822int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer)
823{
824 int status;
825
826 if (pDev->MailBoxInfo.Flags & HIF_MBOX_FLAG_NO_BUNDLING) {
827 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HIF requires bundling disabled\n"));
828 return A_ENOTSUP;
829 }
830
831 status = HIFConfigureDevice(pDev->HIFDevice,
832 HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT,
833 &pDev->HifScatterInfo,
834 sizeof(pDev->HifScatterInfo));
835
836 if (status) {
837 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
838 ("AR6K: ** HIF layer does not support scatter requests (%d) \n",status));
839
840 /* we can try to use a virtual DMA scatter mechanism using legacy HIFReadWrite() */
841 status = DevSetupVirtualScatterSupport(pDev);
842
843 if (!status) {
844 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
845 ("AR6K: virtual scatter transfers enabled (max scatter items:%d: maxlen:%d) \n",
846 DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(pDev)));
847 }
848
849 } else {
850 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
851 ("AR6K: HIF layer supports scatter requests (max scatter items:%d: maxlen:%d) \n",
852 DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(pDev)));
853 }
854
855 if (!status) {
856 /* for the recv path, the maximum number of bytes per recv bundle is just limited
857 * by the maximum transfer size at the HIF layer */
858 pDev->MaxRecvBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatterReq;
859
860 if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) {
861 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K : SPI bus requires TX bundling disabled\n"));
862 pDev->MaxSendBundleSize = 0;
863 } else {
864 /* for the send path, the max transfer size is limited by the existence and size of
865 * the extended mailbox address range */
866 if (pDev->MailBoxInfo.MboxProp[0].ExtendedAddress != 0) {
867 pDev->MaxSendBundleSize = pDev->MailBoxInfo.MboxProp[0].ExtendedSize;
868 } else {
869 /* legacy */
870 pDev->MaxSendBundleSize = AR6K_LEGACY_MAX_WRITE_LENGTH;
871 }
872
873 if (pDev->MaxSendBundleSize > pDev->HifScatterInfo.MaxTransferSizePerScatterReq) {
874 /* limit send bundle size to what the HIF can support for scatter requests */
875 pDev->MaxSendBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatterReq;
876 }
877 }
878
879 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
880 ("AR6K: max recv: %d max send: %d \n",
881 DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev), DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev)));
882
883 }
884 return status;
885}
886
887int DevSubmitScatterRequest(struct ar6k_device *pDev, struct hif_scatter_req *pScatterReq, bool Read, bool Async)
888{
889 int status;
890
891 if (Read) {
892 /* read operation */
893 pScatterReq->Request = (Async) ? HIF_RD_ASYNC_BLOCK_FIX : HIF_RD_SYNC_BLOCK_FIX;
894 pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX];
895 A_ASSERT(pScatterReq->TotalLength <= (u32)DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev));
896 } else {
897 u32 mailboxWidth;
898
899 /* write operation */
900 pScatterReq->Request = (Async) ? HIF_WR_ASYNC_BLOCK_INC : HIF_WR_SYNC_BLOCK_INC;
901 A_ASSERT(pScatterReq->TotalLength <= (u32)DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev));
902 if (pScatterReq->TotalLength > AR6K_LEGACY_MAX_WRITE_LENGTH) {
903 /* for large writes use the extended address */
904 pScatterReq->Address = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress;
905 mailboxWidth = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize;
906 } else {
907 pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX];
908 mailboxWidth = AR6K_LEGACY_MAX_WRITE_LENGTH;
909 }
910
911 if (!pDev->ScatterIsVirtual) {
912 /* we are passing this scatter list down to the HIF layer' scatter request handler, fixup the address
913 * so that the last byte falls on the EOM, we do this for those HIFs that support the
914 * scatter API */
915 pScatterReq->Address += (mailboxWidth - pScatterReq->TotalLength);
916 }
917
918 }
919
920 AR_DEBUG_PRINTF(ATH_DEBUG_RECV | ATH_DEBUG_SEND,
921 ("DevSubmitScatterRequest, Entries: %d, Total Length: %d Mbox:0x%X (mode: %s : %s)\n",
922 pScatterReq->ValidScatterEntries,
923 pScatterReq->TotalLength,
924 pScatterReq->Address,
925 Async ? "ASYNC" : "SYNC",
926 (Read) ? "RD" : "WR"));
927
928 status = DEV_PREPARE_SCATTER_OPERATION(pScatterReq);
929
930 if (status) {
931 if (Async) {
932 pScatterReq->CompletionStatus = status;
933 pScatterReq->CompletionRoutine(pScatterReq);
934 return 0;
935 }
936 return status;
937 }
938
939 status = pDev->HifScatterInfo.pReadWriteScatterFunc(pDev->ScatterIsVirtual ? pDev : pDev->HIFDevice,
940 pScatterReq);
941 if (!Async) {
942 /* in sync mode, we can touch the scatter request */
943 pScatterReq->CompletionStatus = status;
944 DEV_FINISH_SCATTER_OPERATION(pScatterReq);
945 } else {
946 if (status == A_PENDING) {
947 status = 0;
948 }
949 }
950
951 return status;
952}
953
954
955#ifdef MBOXHW_UNIT_TEST
956
957
958/* This is a mailbox hardware unit test that must be called in a schedulable context
959 * This test is very simple, it will send a list of buffers with a counting pattern
960 * and the target will invert the data and send the message back
961 *
962 * the unit test has the following constraints:
963 *
964 * The target has at least 8 buffers of 256 bytes each. The host will send
965 * the following pattern of buffers in rapid succession :
966 *
967 * 1 buffer - 128 bytes
968 * 1 buffer - 256 bytes
969 * 1 buffer - 512 bytes
970 * 1 buffer - 1024 bytes
971 *
972 * The host will send the buffers to one mailbox and wait for buffers to be reflected
973 * back from the same mailbox. The target sends the buffers FIFO order.
974 * Once the final buffer has been received for a mailbox, the next mailbox is tested.
975 *
976 *
977 * Note: To simplifythe test , we assume that the chosen buffer sizes
978 * will fall on a nice block pad
979 *
980 * It is expected that higher-order tests will be written to stress the mailboxes using
981 * a message-based protocol (with some performance timming) that can create more
982 * randomness in the packets sent over mailboxes.
983 *
984 * */
985
986#define A_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1))
987
988#define BUFFER_BLOCK_PAD 128
989
990#if 0
991#define BUFFER1 128
992#define BUFFER2 256
993#define BUFFER3 512
994#define BUFFER4 1024
995#endif
996
997#if 1
998#define BUFFER1 80
999#define BUFFER2 200
1000#define BUFFER3 444
1001#define BUFFER4 800
1002#endif
1003
1004#define TOTAL_BYTES (A_ROUND_UP_PWR2(BUFFER1,BUFFER_BLOCK_PAD) + \
1005 A_ROUND_UP_PWR2(BUFFER2,BUFFER_BLOCK_PAD) + \
1006 A_ROUND_UP_PWR2(BUFFER3,BUFFER_BLOCK_PAD) + \
1007 A_ROUND_UP_PWR2(BUFFER4,BUFFER_BLOCK_PAD) )
1008
1009#define TEST_BYTES (BUFFER1 + BUFFER2 + BUFFER3 + BUFFER4)
1010
1011#define TEST_CREDITS_RECV_TIMEOUT 100
1012
1013static u8 g_Buffer[TOTAL_BYTES];
1014static u32 g_MailboxAddrs[AR6K_MAILBOXES];
1015static u32 g_BlockSizes[AR6K_MAILBOXES];
1016
1017#define BUFFER_PROC_LIST_DEPTH 4
1018
1019struct buffer_proc_list {
1020 u8 *pBuffer;
1021 u32 length;
1022};
1023
1024
1025#define PUSH_BUFF_PROC_ENTRY(pList,len,pCurrpos) \
1026{ \
1027 (pList)->pBuffer = (pCurrpos); \
1028 (pList)->length = (len); \
1029 (pCurrpos) += (len); \
1030 (pList)++; \
1031}
1032
1033/* a simple and crude way to send different "message" sizes */
1034static void AssembleBufferList(struct buffer_proc_list *pList)
1035{
1036 u8 *pBuffer = g_Buffer;
1037
1038#if BUFFER_PROC_LIST_DEPTH < 4
1039#error "Buffer processing list depth is not deep enough!!"
1040#endif
1041
1042 PUSH_BUFF_PROC_ENTRY(pList,BUFFER1,pBuffer);
1043 PUSH_BUFF_PROC_ENTRY(pList,BUFFER2,pBuffer);
1044 PUSH_BUFF_PROC_ENTRY(pList,BUFFER3,pBuffer);
1045 PUSH_BUFF_PROC_ENTRY(pList,BUFFER4,pBuffer);
1046
1047}
1048
1049#define FILL_ZERO true
1050#define FILL_COUNTING false
1051static void InitBuffers(bool Zero)
1052{
1053 u16 *pBuffer16 = (u16 *)g_Buffer;
1054 int i;
1055
1056 /* fill buffer with 16 bit counting pattern or zeros */
1057 for (i = 0; i < (TOTAL_BYTES / 2) ; i++) {
1058 if (!Zero) {
1059 pBuffer16[i] = (u16)i;
1060 } else {
1061 pBuffer16[i] = 0;
1062 }
1063 }
1064}
1065
1066
1067static bool CheckOneBuffer(u16 *pBuffer16, int Length)
1068{
1069 int i;
1070 u16 startCount;
1071 bool success = true;
1072
1073 /* get the starting count */
1074 startCount = pBuffer16[0];
1075 /* invert it, this is the expected value */
1076 startCount = ~startCount;
1077 /* scan the buffer and verify */
1078 for (i = 0; i < (Length / 2) ; i++,startCount++) {
1079 /* target will invert all the data */
1080 if ((u16)pBuffer16[i] != (u16)~startCount) {
1081 success = false;
1082 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Data Got:0x%X, Expecting:0x%X (offset:%d, total:%d) \n",
1083 pBuffer16[i], ((u16)~startCount), i, Length));
1084 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("0x%X 0x%X 0x%X 0x%X \n",
1085 pBuffer16[i], pBuffer16[i + 1], pBuffer16[i + 2],pBuffer16[i+3]));
1086 break;
1087 }
1088 }
1089
1090 return success;
1091}
1092
1093static bool CheckBuffers(void)
1094{
1095 int i;
1096 bool success = true;
1097 struct buffer_proc_list checkList[BUFFER_PROC_LIST_DEPTH];
1098
1099 /* assemble the list */
1100 AssembleBufferList(checkList);
1101
1102 /* scan the buffers and verify */
1103 for (i = 0; i < BUFFER_PROC_LIST_DEPTH ; i++) {
1104 success = CheckOneBuffer((u16 *)checkList[i].pBuffer, checkList[i].length);
1105 if (!success) {
1106 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer : 0x%X, Length:%d failed verify \n",
1107 (u32)checkList[i].pBuffer, checkList[i].length));
1108 break;
1109 }
1110 }
1111
1112 return success;
1113}
1114
1115 /* find the end marker for the last buffer we will be sending */
1116static u16 GetEndMarker(void)
1117{
1118 u8 *pBuffer;
1119 struct buffer_proc_list checkList[BUFFER_PROC_LIST_DEPTH];
1120
1121 /* fill up buffers with the normal counting pattern */
1122 InitBuffers(FILL_COUNTING);
1123
1124 /* assemble the list we will be sending down */
1125 AssembleBufferList(checkList);
1126 /* point to the last 2 bytes of the last buffer */
1127 pBuffer = &(checkList[BUFFER_PROC_LIST_DEPTH - 1].pBuffer[(checkList[BUFFER_PROC_LIST_DEPTH - 1].length) - 2]);
1128
1129 /* the last count in the last buffer is the marker */
1130 return (u16)pBuffer[0] | ((u16)pBuffer[1] << 8);
1131}
1132
1133#define ATH_PRINT_OUT_ZONE ATH_DEBUG_ERR
1134
1135/* send the ordered buffers to the target */
1136static int SendBuffers(struct ar6k_device *pDev, int mbox)
1137{
1138 int status = 0;
1139 u32 request = HIF_WR_SYNC_BLOCK_INC;
1140 struct buffer_proc_list sendList[BUFFER_PROC_LIST_DEPTH];
1141 int i;
1142 int totalBytes = 0;
1143 int paddedLength;
1144 int totalwPadding = 0;
1145
1146 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sending buffers on mailbox : %d \n",mbox));
1147
1148 /* fill buffer with counting pattern */
1149 InitBuffers(FILL_COUNTING);
1150
1151 /* assemble the order in which we send */
1152 AssembleBufferList(sendList);
1153
1154 for (i = 0; i < BUFFER_PROC_LIST_DEPTH; i++) {
1155
1156 /* we are doing block transfers, so we need to pad everything to a block size */
1157 paddedLength = (sendList[i].length + (g_BlockSizes[mbox] - 1)) &
1158 (~(g_BlockSizes[mbox] - 1));
1159
1160 /* send each buffer synchronously */
1161 status = HIFReadWrite(pDev->HIFDevice,
1162 g_MailboxAddrs[mbox],
1163 sendList[i].pBuffer,
1164 paddedLength,
1165 request,
1166 NULL);
1167 if (status) {
1168 break;
1169 }
1170 totalBytes += sendList[i].length;
1171 totalwPadding += paddedLength;
1172 }
1173
1174 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sent %d bytes (%d padded bytes) to mailbox : %d \n",totalBytes,totalwPadding,mbox));
1175
1176 return status;
1177}
1178
1179/* poll the mailbox credit counter until we get a credit or timeout */
1180static int GetCredits(struct ar6k_device *pDev, int mbox, int *pCredits)
1181{
1182 int status = 0;
1183 int timeout = TEST_CREDITS_RECV_TIMEOUT;
1184 u8 credits = 0;
1185 u32 address;
1186
1187 while (true) {
1188
1189 /* Read the counter register to get credits, this auto-decrements */
1190 address = COUNT_DEC_ADDRESS + (AR6K_MAILBOXES + mbox) * 4;
1191 status = HIFReadWrite(pDev->HIFDevice, address, &credits, sizeof(credits),
1192 HIF_RD_SYNC_BYTE_FIX, NULL);
1193 if (status) {
1194 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1195 ("Unable to decrement the command credit count register (mbox=%d)\n",mbox));
1196 status = A_ERROR;
1197 break;
1198 }
1199
1200 if (credits) {
1201 break;
1202 }
1203
1204 timeout--;
1205
1206 if (timeout <= 0) {
1207 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1208 (" Timeout reading credit registers (mbox=%d, address:0x%X) \n",mbox,address));
1209 status = A_ERROR;
1210 break;
1211 }
1212
1213 /* delay a little, target may not be ready */
1214 A_MDELAY(1000);
1215
1216 }
1217
1218 if (status == 0) {
1219 *pCredits = credits;
1220 }
1221
1222 return status;
1223}
1224
1225
1226/* wait for the buffers to come back */
1227static int RecvBuffers(struct ar6k_device *pDev, int mbox)
1228{
1229 int status = 0;
1230 u32 request = HIF_RD_SYNC_BLOCK_INC;
1231 struct buffer_proc_list recvList[BUFFER_PROC_LIST_DEPTH];
1232 int curBuffer;
1233 int credits;
1234 int i;
1235 int totalBytes = 0;
1236 int paddedLength;
1237 int totalwPadding = 0;
1238
1239 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Waiting for buffers on mailbox : %d \n",mbox));
1240
1241 /* zero the buffers */
1242 InitBuffers(FILL_ZERO);
1243
1244 /* assemble the order in which we should receive */
1245 AssembleBufferList(recvList);
1246
1247 curBuffer = 0;
1248
1249 while (curBuffer < BUFFER_PROC_LIST_DEPTH) {
1250
1251 /* get number of buffers that have been completed, this blocks
1252 * until we get at least 1 credit or it times out */
1253 status = GetCredits(pDev, mbox, &credits);
1254
1255 if (status) {
1256 break;
1257 }
1258
1259 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got %d messages on mailbox : %d \n",credits, mbox));
1260
1261 /* get all the buffers that are sitting on the queue */
1262 for (i = 0; i < credits; i++) {
1263 A_ASSERT(curBuffer < BUFFER_PROC_LIST_DEPTH);
1264 /* recv the current buffer synchronously, the buffers should come back in
1265 * order... with padding applied by the target */
1266 paddedLength = (recvList[curBuffer].length + (g_BlockSizes[mbox] - 1)) &
1267 (~(g_BlockSizes[mbox] - 1));
1268
1269 status = HIFReadWrite(pDev->HIFDevice,
1270 g_MailboxAddrs[mbox],
1271 recvList[curBuffer].pBuffer,
1272 paddedLength,
1273 request,
1274 NULL);
1275 if (status) {
1276 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to read %d bytes on mailbox:%d : address:0x%X \n",
1277 recvList[curBuffer].length, mbox, g_MailboxAddrs[mbox]));
1278 break;
1279 }
1280
1281 totalwPadding += paddedLength;
1282 totalBytes += recvList[curBuffer].length;
1283 curBuffer++;
1284 }
1285
1286 if (status) {
1287 break;
1288 }
1289 /* go back and get some more */
1290 credits = 0;
1291 }
1292
1293 if (totalBytes != TEST_BYTES) {
1294 A_ASSERT(false);
1295 } else {
1296 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got all buffers on mbox:%d total recv :%d (w/Padding : %d) \n",
1297 mbox, totalBytes, totalwPadding));
1298 }
1299
1300 return status;
1301
1302
1303}
1304
1305static int DoOneMboxHWTest(struct ar6k_device *pDev, int mbox)
1306{
1307 int status;
1308
1309 do {
1310 /* send out buffers */
1311 status = SendBuffers(pDev,mbox);
1312
1313 if (status) {
1314 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Sending buffers Failed : %d mbox:%d\n",status,mbox));
1315 break;
1316 }
1317
1318 /* go get them, this will block */
1319 status = RecvBuffers(pDev, mbox);
1320
1321 if (status) {
1322 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Recv buffers Failed : %d mbox:%d\n",status,mbox));
1323 break;
1324 }
1325
1326 /* check the returned data patterns */
1327 if (!CheckBuffers()) {
1328 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer Verify Failed : mbox:%d\n",mbox));
1329 status = A_ERROR;
1330 break;
1331 }
1332
1333 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" Send/Recv success! mailbox : %d \n",mbox));
1334
1335 } while (false);
1336
1337 return status;
1338}
1339
1340/* here is where the test starts */
1341int DoMboxHWTest(struct ar6k_device *pDev)
1342{
1343 int i;
1344 int status;
1345 int credits = 0;
1346 u8 params[4];
1347 int numBufs;
1348 int bufferSize;
1349 u16 temp;
1350
1351
1352 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest START - \n"));
1353
1354 do {
1355 /* get the addresses for all 4 mailboxes */
1356 status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR,
1357 g_MailboxAddrs, sizeof(g_MailboxAddrs));
1358
1359 if (status) {
1360 A_ASSERT(false);
1361 break;
1362 }
1363
1364 /* get the block sizes */
1365 status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
1366 g_BlockSizes, sizeof(g_BlockSizes));
1367
1368 if (status) {
1369 A_ASSERT(false);
1370 break;
1371 }
1372
1373 /* note, the HIF layer usually reports mbox 0 to have a block size of
1374 * 1, but our test wants to run in block-mode for all mailboxes, so we treat all mailboxes
1375 * the same. */
1376 g_BlockSizes[0] = g_BlockSizes[1];
1377 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Block Size to use: %d \n",g_BlockSizes[0]));
1378
1379 if (g_BlockSizes[1] > BUFFER_BLOCK_PAD) {
1380 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("%d Block size is too large for buffer pad %d\n",
1381 g_BlockSizes[1], BUFFER_BLOCK_PAD));
1382 break;
1383 }
1384
1385 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Waiting for target.... \n"));
1386
1387 /* the target lets us know it is ready by giving us 1 credit on
1388 * mailbox 0 */
1389 status = GetCredits(pDev, 0, &credits);
1390
1391 if (status) {
1392 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait for target ready \n"));
1393 break;
1394 }
1395
1396 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Target is ready ...\n"));
1397
1398 /* read the first 4 scratch registers */
1399 status = HIFReadWrite(pDev->HIFDevice,
1400 SCRATCH_ADDRESS,
1401 params,
1402 4,
1403 HIF_RD_SYNC_BYTE_INC,
1404 NULL);
1405
1406 if (status) {
1407 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait get parameters \n"));
1408 break;
1409 }
1410
1411 numBufs = params[0];
1412 bufferSize = (int)(((u16)params[2] << 8) | (u16)params[1]);
1413
1414 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE,
1415 ("Target parameters: bufs per mailbox:%d, buffer size:%d bytes (total space: %d, minimum required space (w/padding): %d) \n",
1416 numBufs, bufferSize, (numBufs * bufferSize), TOTAL_BYTES));
1417
1418 if ((numBufs * bufferSize) < TOTAL_BYTES) {
1419 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Not Enough buffer space to run test! need:%d, got:%d \n",
1420 TOTAL_BYTES, (numBufs*bufferSize)));
1421 status = A_ERROR;
1422 break;
1423 }
1424
1425 temp = GetEndMarker();
1426
1427 status = HIFReadWrite(pDev->HIFDevice,
1428 SCRATCH_ADDRESS + 4,
1429 (u8 *)&temp,
1430 2,
1431 HIF_WR_SYNC_BYTE_INC,
1432 NULL);
1433
1434 if (status) {
1435 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write end marker \n"));
1436 break;
1437 }
1438
1439 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("End Marker: 0x%X \n",temp));
1440
1441 temp = (u16)g_BlockSizes[1];
1442 /* convert to a mask */
1443 temp = temp - 1;
1444 status = HIFReadWrite(pDev->HIFDevice,
1445 SCRATCH_ADDRESS + 6,
1446 (u8 *)&temp,
1447 2,
1448 HIF_WR_SYNC_BYTE_INC,
1449 NULL);
1450
1451 if (status) {
1452 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write block mask \n"));
1453 break;
1454 }
1455
1456 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Set Block Mask: 0x%X \n",temp));
1457
1458 /* execute the test on each mailbox */
1459 for (i = 0; i < AR6K_MAILBOXES; i++) {
1460 status = DoOneMboxHWTest(pDev, i);
1461 if (status) {
1462 break;
1463 }
1464 }
1465
1466 } while (false);
1467
1468 if (status == 0) {
1469 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - SUCCESS! - \n"));
1470 } else {
1471 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - FAILED! - \n"));
1472 }
1473 /* don't let HTC_Start continue, the target is actually not running any HTC code */
1474 return A_ERROR;
1475}
1476#endif
1477
1478
1479
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h
deleted file mode 100644
index e551dbe674d..00000000000
--- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h
+++ /dev/null
@@ -1,401 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6k.h" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// AR6K device layer that handles register level I/O
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef AR6K_H_
26#define AR6K_H_
27
28#include "hci_transport_api.h"
29#include "../htc_debug.h"
30
31#define AR6K_MAILBOXES 4
32
33/* HTC runs over mailbox 0 */
34#define HTC_MAILBOX 0
35
36#define AR6K_TARGET_DEBUG_INTR_MASK 0x01
37
38#define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK | \
39 INT_STATUS_ENABLE_CPU_MASK | \
40 INT_STATUS_ENABLE_COUNTER_MASK)
41
42
43//#define MBOXHW_UNIT_TEST 1
44
45PREPACK struct ar6k_irq_proc_registers {
46 u8 host_int_status;
47 u8 cpu_int_status;
48 u8 error_int_status;
49 u8 counter_int_status;
50 u8 mbox_frame;
51 u8 rx_lookahead_valid;
52 u8 host_int_status2;
53 u8 gmbox_rx_avail;
54 u32 rx_lookahead[2];
55 u32 rx_gmbox_lookahead_alias[2];
56} POSTPACK;
57
58#define AR6K_IRQ_PROC_REGS_SIZE sizeof(struct ar6k_irq_proc_registers)
59
60PREPACK struct ar6k_irq_enable_registers {
61 u8 int_status_enable;
62 u8 cpu_int_status_enable;
63 u8 error_status_enable;
64 u8 counter_int_status_enable;
65} POSTPACK;
66
67PREPACK struct ar6k_gmbox_ctrl_registers {
68 u8 int_status_enable;
69} POSTPACK;
70
71#define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(struct ar6k_irq_enable_registers)
72
73#define AR6K_REG_IO_BUFFER_SIZE 32
74#define AR6K_MAX_REG_IO_BUFFERS 8
75#define FROM_DMA_BUFFER true
76#define TO_DMA_BUFFER false
77#define AR6K_SCATTER_ENTRIES_PER_REQ 16
78#define AR6K_MAX_TRANSFER_SIZE_PER_SCATTER 16*1024
79#define AR6K_SCATTER_REQS 4
80#define AR6K_LEGACY_MAX_WRITE_LENGTH 2048
81
82#ifndef A_CACHE_LINE_PAD
83#define A_CACHE_LINE_PAD 128
84#endif
85#define AR6K_MIN_SCATTER_ENTRIES_PER_REQ 2
86#define AR6K_MIN_TRANSFER_SIZE_PER_SCATTER 4*1024
87
88/* buffers for ASYNC I/O */
89struct ar6k_async_reg_io_buffer {
90 struct htc_packet HtcPacket; /* we use an HTC packet as a wrapper for our async register-based I/O */
91 u8 _Pad1[A_CACHE_LINE_PAD];
92 u8 Buffer[AR6K_REG_IO_BUFFER_SIZE]; /* cache-line safe with pads around */
93 u8 _Pad2[A_CACHE_LINE_PAD];
94};
95
96struct ar6k_gmbox_info {
97 void *pProtocolContext;
98 int (*pMessagePendingCallBack)(void *pContext, u8 LookAheadBytes[], int ValidBytes);
99 int (*pCreditsPendingCallback)(void *pContext, int NumCredits, bool CreditIRQEnabled);
100 void (*pTargetFailureCallback)(void *pContext, int Status);
101 void (*pStateDumpCallback)(void *pContext);
102 bool CreditCountIRQEnabled;
103};
104
105struct ar6k_device {
106 A_MUTEX_T Lock;
107 u8 _Pad1[A_CACHE_LINE_PAD];
108 struct ar6k_irq_proc_registers IrqProcRegisters; /* cache-line safe with pads around */
109 u8 _Pad2[A_CACHE_LINE_PAD];
110 struct ar6k_irq_enable_registers IrqEnableRegisters; /* cache-line safe with pads around */
111 u8 _Pad3[A_CACHE_LINE_PAD];
112 void *HIFDevice;
113 u32 BlockSize;
114 u32 BlockMask;
115 struct hif_device_mbox_info MailBoxInfo;
116 HIF_PENDING_EVENTS_FUNC GetPendingEventsFunc;
117 void *HTCContext;
118 struct htc_packet_queue RegisterIOList;
119 struct ar6k_async_reg_io_buffer RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS];
120 void (*TargetFailureCallback)(void *Context);
121 int (*MessagePendingCallback)(void *Context,
122 u32 LookAheads[],
123 int NumLookAheads,
124 bool *pAsyncProc,
125 int *pNumPktsFetched);
126 HIF_DEVICE_IRQ_PROCESSING_MODE HifIRQProcessingMode;
127 HIF_MASK_UNMASK_RECV_EVENT HifMaskUmaskRecvEvent;
128 bool HifAttached;
129 struct hif_device_irq_yield_params HifIRQYieldParams;
130 bool DSRCanYield;
131 int CurrentDSRRecvCount;
132 struct hif_device_scatter_support_info HifScatterInfo;
133 struct dl_list ScatterReqHead;
134 bool ScatterIsVirtual;
135 int MaxRecvBundleSize;
136 int MaxSendBundleSize;
137 struct ar6k_gmbox_info GMboxInfo;
138 bool GMboxEnabled;
139 struct ar6k_gmbox_ctrl_registers GMboxControlRegisters;
140 int RecheckIRQStatusCnt;
141};
142
143#define LOCK_AR6K(p) A_MUTEX_LOCK(&(p)->Lock);
144#define UNLOCK_AR6K(p) A_MUTEX_UNLOCK(&(p)->Lock);
145#define REF_IRQ_STATUS_RECHECK(p) (p)->RecheckIRQStatusCnt = 1 /* note: no need to lock this, it only gets set */
146
147int DevSetup(struct ar6k_device *pDev);
148void DevCleanup(struct ar6k_device *pDev);
149int DevUnmaskInterrupts(struct ar6k_device *pDev);
150int DevMaskInterrupts(struct ar6k_device *pDev);
151int DevPollMboxMsgRecv(struct ar6k_device *pDev,
152 u32 *pLookAhead,
153 int TimeoutMS);
154int DevRWCompletionHandler(void *context, int status);
155int DevDsrHandler(void *context);
156int DevCheckPendingRecvMsgsAsync(void *context);
157void DevAsyncIrqProcessComplete(struct ar6k_device *pDev);
158void DevDumpRegisters(struct ar6k_device *pDev,
159 struct ar6k_irq_proc_registers *pIrqProcRegs,
160 struct ar6k_irq_enable_registers *pIrqEnableRegs);
161
162#define DEV_STOP_RECV_ASYNC true
163#define DEV_STOP_RECV_SYNC false
164#define DEV_ENABLE_RECV_ASYNC true
165#define DEV_ENABLE_RECV_SYNC false
166int DevStopRecv(struct ar6k_device *pDev, bool ASyncMode);
167int DevEnableRecv(struct ar6k_device *pDev, bool ASyncMode);
168int DevEnableInterrupts(struct ar6k_device *pDev);
169int DevDisableInterrupts(struct ar6k_device *pDev);
170int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRecvPending);
171
172#define DEV_CALC_RECV_PADDED_LEN(pDev, length) (((length) + (pDev)->BlockMask) & (~((pDev)->BlockMask)))
173#define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length)
174#define DEV_IS_LEN_BLOCK_ALIGNED(pDev, length) (((length) % (pDev)->BlockSize) == 0)
175
176static INLINE int DevSendPacket(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 SendLength) {
177 u32 paddedLength;
178 bool sync = (pPacket->Completion == NULL) ? true : false;
179 int status;
180
181 /* adjust the length to be a multiple of block size if appropriate */
182 paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, SendLength);
183
184#if 0
185 if (paddedLength > pPacket->BufferLength) {
186 A_ASSERT(false);
187 if (pPacket->Completion != NULL) {
188 COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
189 return 0;
190 }
191 return A_EINVAL;
192 }
193#endif
194
195 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
196 ("DevSendPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n",
197 paddedLength,
198 pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
199 sync ? "SYNC" : "ASYNC"));
200
201 status = HIFReadWrite(pDev->HIFDevice,
202 pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
203 pPacket->pBuffer,
204 paddedLength, /* the padded length */
205 sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
206 sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
207
208 if (sync) {
209 pPacket->Status = status;
210 } else {
211 if (status == A_PENDING) {
212 status = 0;
213 }
214 }
215
216 return status;
217}
218
219static INLINE int DevRecvPacket(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 RecvLength) {
220 u32 paddedLength;
221 int status;
222 bool sync = (pPacket->Completion == NULL) ? true : false;
223
224 /* adjust the length to be a multiple of block size if appropriate */
225 paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, RecvLength);
226
227 if (paddedLength > pPacket->BufferLength) {
228 A_ASSERT(false);
229 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
230 ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
231 paddedLength,RecvLength,pPacket->BufferLength));
232 if (pPacket->Completion != NULL) {
233 COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
234 return 0;
235 }
236 return A_EINVAL;
237 }
238
239 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
240 ("DevRecvPacket (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n",
241 (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
242 paddedLength,
243 pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
244 sync ? "SYNC" : "ASYNC"));
245
246 status = HIFReadWrite(pDev->HIFDevice,
247 pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
248 pPacket->pBuffer,
249 paddedLength,
250 sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX,
251 sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
252
253 if (sync) {
254 pPacket->Status = status;
255 }
256
257 return status;
258}
259
260#define DEV_CHECK_RECV_YIELD(pDev) \
261 ((pDev)->CurrentDSRRecvCount >= (pDev)->HifIRQYieldParams.RecvPacketYieldCount)
262
263#define IS_DEV_IRQ_PROC_SYNC_MODE(pDev) (HIF_DEVICE_IRQ_SYNC_ONLY == (pDev)->HifIRQProcessingMode)
264#define IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev) ((pDev)->HifIRQProcessingMode != HIF_DEVICE_IRQ_SYNC_ONLY)
265
266/**************************************************/
267/****** Scatter Function and Definitions
268 *
269 *
270 */
271
272int DevCopyScatterListToFromDMABuffer(struct hif_scatter_req *pReq, bool FromDMA);
273
274 /* copy any READ data back into scatter list */
275#define DEV_FINISH_SCATTER_OPERATION(pR) \
276do { \
277 if (!((pR)->CompletionStatus) && \
278 !((pR)->Request & HIF_WRITE) && \
279 ((pR)->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { \
280 (pR)->CompletionStatus = \
281 DevCopyScatterListToFromDMABuffer((pR), \
282 FROM_DMA_BUFFER); \
283 } \
284} while (0)
285
286 /* copy any WRITE data to bounce buffer */
287static INLINE int DEV_PREPARE_SCATTER_OPERATION(struct hif_scatter_req *pReq) {
288 if ((pReq->Request & HIF_WRITE) && (pReq->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) {
289 return DevCopyScatterListToFromDMABuffer(pReq,TO_DMA_BUFFER);
290 } else {
291 return 0;
292 }
293}
294
295
296int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer);
297
298int DevCleanupMsgBundling(struct ar6k_device *pDev);
299
300#define DEV_GET_MAX_MSG_PER_BUNDLE(pDev) (pDev)->HifScatterInfo.MaxScatterEntries
301#define DEV_GET_MAX_BUNDLE_LENGTH(pDev) (pDev)->HifScatterInfo.MaxTransferSizePerScatterReq
302#define DEV_ALLOC_SCATTER_REQ(pDev) \
303 (pDev)->HifScatterInfo.pAllocateReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice)
304
305#define DEV_FREE_SCATTER_REQ(pDev,pR) \
306 (pDev)->HifScatterInfo.pFreeReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice,(pR))
307
308#define DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev) (pDev)->MaxRecvBundleSize
309#define DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev) (pDev)->MaxSendBundleSize
310
311#define DEV_SCATTER_READ true
312#define DEV_SCATTER_WRITE false
313#define DEV_SCATTER_ASYNC true
314#define DEV_SCATTER_SYNC false
315int DevSubmitScatterRequest(struct ar6k_device *pDev, struct hif_scatter_req *pScatterReq, bool Read, bool Async);
316
317#ifdef MBOXHW_UNIT_TEST
318int DoMboxHWTest(struct ar6k_device *pDev);
319#endif
320
321 /* completely virtual */
322struct dev_scatter_dma_virtual_info {
323 u8 *pVirtDmaBuffer; /* dma-able buffer - CPU accessible address */
324 u8 DataArea[1]; /* start of data area */
325};
326
327
328
329void DumpAR6KDevState(struct ar6k_device *pDev);
330
331/**************************************************/
332/****** GMBOX functions and definitions
333 *
334 *
335 */
336
337#ifdef ATH_AR6K_ENABLE_GMBOX
338
339void DevCleanupGMbox(struct ar6k_device *pDev);
340int DevSetupGMbox(struct ar6k_device *pDev);
341int DevCheckGMboxInterrupts(struct ar6k_device *pDev);
342void DevNotifyGMboxTargetFailure(struct ar6k_device *pDev);
343
344#else
345
346 /* compiled out */
347#define DevCleanupGMbox(p)
348#define DevCheckGMboxInterrupts(p) 0
349#define DevNotifyGMboxTargetFailure(p)
350
351static INLINE int DevSetupGMbox(struct ar6k_device *pDev) {
352 pDev->GMboxEnabled = false;
353 return 0;
354}
355
356#endif
357
358#ifdef ATH_AR6K_ENABLE_GMBOX
359
360 /* GMBOX protocol modules must expose each of these internal APIs */
361HCI_TRANSPORT_HANDLE GMboxAttachProtocol(struct ar6k_device *pDev, struct hci_transport_config_info *pInfo);
362int GMboxProtocolInstall(struct ar6k_device *pDev);
363void GMboxProtocolUninstall(struct ar6k_device *pDev);
364
365 /* API used by GMBOX protocol modules */
366struct ar6k_device *HTCGetAR6KDevice(void *HTCHandle);
367#define DEV_GMBOX_SET_PROTOCOL(pDev,recv_callback,credits_pending,failure,statedump,context) \
368{ \
369 (pDev)->GMboxInfo.pProtocolContext = (context); \
370 (pDev)->GMboxInfo.pMessagePendingCallBack = (recv_callback); \
371 (pDev)->GMboxInfo.pCreditsPendingCallback = (credits_pending); \
372 (pDev)->GMboxInfo.pTargetFailureCallback = (failure); \
373 (pDev)->GMboxInfo.pStateDumpCallback = (statedump); \
374}
375
376#define DEV_GMBOX_GET_PROTOCOL(pDev) (pDev)->GMboxInfo.pProtocolContext
377
378int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength);
379int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength);
380
381#define PROC_IO_ASYNC true
382#define PROC_IO_SYNC false
383typedef enum GMBOX_IRQ_ACTION_TYPE {
384 GMBOX_ACTION_NONE = 0,
385 GMBOX_DISABLE_ALL,
386 GMBOX_ERRORS_IRQ_ENABLE,
387 GMBOX_RECV_IRQ_ENABLE,
388 GMBOX_RECV_IRQ_DISABLE,
389 GMBOX_CREDIT_IRQ_ENABLE,
390 GMBOX_CREDIT_IRQ_DISABLE,
391} GMBOX_IRQ_ACTION_TYPE;
392
393int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE, bool AsyncMode);
394int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits);
395int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize);
396int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes);
397int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int SignalNumber, int AckTimeoutMS);
398
399#endif
400
401#endif /*AR6K_H_*/
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c
deleted file mode 100644
index d7af68f7056..00000000000
--- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c
+++ /dev/null
@@ -1,783 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6k_events.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// AR6K Driver layer event handling (i.e. interrupts, message polling)
22//
23// Author(s): ="Atheros"
24//==============================================================================
25
26#include "a_config.h"
27#include "athdefs.h"
28#include "hw/mbox_host_reg.h"
29#include "a_osapi.h"
30#include "../htc_debug.h"
31#include "hif.h"
32#include "htc_packet.h"
33#include "ar6k.h"
34
35extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket);
36extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev);
37
38static int DevServiceDebugInterrupt(struct ar6k_device *pDev);
39
40#define DELAY_PER_INTERVAL_MS 10 /* 10 MS delay per polling interval */
41
42/* completion routine for ALL HIF layer async I/O */
43int DevRWCompletionHandler(void *context, int status)
44{
45 struct htc_packet *pPacket = (struct htc_packet *)context;
46
47 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
48 ("+DevRWCompletionHandler (Pkt:0x%lX) , Status: %d \n",
49 (unsigned long)pPacket,
50 status));
51
52 COMPLETE_HTC_PACKET(pPacket,status);
53
54 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
55 ("-DevRWCompletionHandler\n"));
56
57 return 0;
58}
59
60/* mailbox recv message polling */
61int DevPollMboxMsgRecv(struct ar6k_device *pDev,
62 u32 *pLookAhead,
63 int TimeoutMS)
64{
65 int status = 0;
66 int timeout = TimeoutMS/DELAY_PER_INTERVAL_MS;
67
68 A_ASSERT(timeout > 0);
69
70 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevPollMboxMsgRecv \n"));
71
72 while (true) {
73
74 if (pDev->GetPendingEventsFunc != NULL) {
75
76 struct hif_pending_events_info events;
77
78#ifdef THREAD_X
79 events.Polling =1;
80#endif
81
82 /* the HIF layer uses a special mechanism to get events, do this
83 * synchronously */
84 status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
85 &events,
86 NULL);
87 if (status)
88 {
89 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get pending events \n"));
90 break;
91 }
92
93 if (events.Events & HIF_RECV_MSG_AVAIL)
94 {
95 /* there is a message available, the lookahead should be valid now */
96 *pLookAhead = events.LookAhead;
97
98 break;
99 }
100 } else {
101
102 /* this is the standard HIF way.... */
103 /* load the register table */
104 status = HIFReadWrite(pDev->HIFDevice,
105 HOST_INT_STATUS_ADDRESS,
106 (u8 *)&pDev->IrqProcRegisters,
107 AR6K_IRQ_PROC_REGS_SIZE,
108 HIF_RD_SYNC_BYTE_INC,
109 NULL);
110
111 if (status){
112 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to read register table \n"));
113 break;
114 }
115
116 /* check for MBOX data and valid lookahead */
117 if (pDev->IrqProcRegisters.host_int_status & (1 << HTC_MAILBOX)) {
118 if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBOX))
119 {
120 /* mailbox has a message and the look ahead is valid */
121 *pLookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX];
122 break;
123 }
124 }
125
126 }
127
128 timeout--;
129
130 if (timeout <= 0) {
131 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Timeout waiting for recv message \n"));
132 status = A_ERROR;
133
134 /* check if the target asserted */
135 if ( pDev->IrqProcRegisters.counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) {
136 /* target signaled an assert, process this pending interrupt
137 * this will call the target failure handler */
138 DevServiceDebugInterrupt(pDev);
139 }
140
141 break;
142 }
143
144 /* delay a little */
145 A_MDELAY(DELAY_PER_INTERVAL_MS);
146 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Retry Mbox Poll : %d \n",timeout));
147 }
148
149 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevPollMboxMsgRecv \n"));
150
151 return status;
152}
153
154static int DevServiceCPUInterrupt(struct ar6k_device *pDev)
155{
156 int status;
157 u8 cpu_int_status;
158 u8 regBuffer[4];
159
160 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("CPU Interrupt\n"));
161 cpu_int_status = pDev->IrqProcRegisters.cpu_int_status &
162 pDev->IrqEnableRegisters.cpu_int_status_enable;
163 A_ASSERT(cpu_int_status);
164 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
165 ("Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
166 cpu_int_status));
167
168 /* Clear the interrupt */
169 pDev->IrqProcRegisters.cpu_int_status &= ~cpu_int_status; /* W1C */
170
171 /* set up the register transfer buffer to hit the register 4 times , this is done
172 * to make the access 4-byte aligned to mitigate issues with host bus interconnects that
173 * restrict bus transfer lengths to be a multiple of 4-bytes */
174
175 /* set W1C value to clear the interrupt, this hits the register first */
176 regBuffer[0] = cpu_int_status;
177 /* the remaining 4 values are set to zero which have no-effect */
178 regBuffer[1] = 0;
179 regBuffer[2] = 0;
180 regBuffer[3] = 0;
181
182 status = HIFReadWrite(pDev->HIFDevice,
183 CPU_INT_STATUS_ADDRESS,
184 regBuffer,
185 4,
186 HIF_WR_SYNC_BYTE_FIX,
187 NULL);
188
189 A_ASSERT(status == 0);
190 return status;
191}
192
193
194static int DevServiceErrorInterrupt(struct ar6k_device *pDev)
195{
196 int status;
197 u8 error_int_status;
198 u8 regBuffer[4];
199
200 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error Interrupt\n"));
201 error_int_status = pDev->IrqProcRegisters.error_int_status & 0x0F;
202 A_ASSERT(error_int_status);
203 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
204 ("Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
205 error_int_status));
206
207 if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) {
208 /* Wakeup */
209 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error : Wakeup\n"));
210 }
211
212 if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) {
213 /* Rx Underflow */
214 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Rx Underflow\n"));
215 }
216
217 if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) {
218 /* Tx Overflow */
219 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Tx Overflow\n"));
220 }
221
222 /* Clear the interrupt */
223 pDev->IrqProcRegisters.error_int_status &= ~error_int_status; /* W1C */
224
225 /* set up the register transfer buffer to hit the register 4 times , this is done
226 * to make the access 4-byte aligned to mitigate issues with host bus interconnects that
227 * restrict bus transfer lengths to be a multiple of 4-bytes */
228
229 /* set W1C value to clear the interrupt, this hits the register first */
230 regBuffer[0] = error_int_status;
231 /* the remaining 4 values are set to zero which have no-effect */
232 regBuffer[1] = 0;
233 regBuffer[2] = 0;
234 regBuffer[3] = 0;
235
236 status = HIFReadWrite(pDev->HIFDevice,
237 ERROR_INT_STATUS_ADDRESS,
238 regBuffer,
239 4,
240 HIF_WR_SYNC_BYTE_FIX,
241 NULL);
242
243 A_ASSERT(status == 0);
244 return status;
245}
246
247static int DevServiceDebugInterrupt(struct ar6k_device *pDev)
248{
249 u32 dummy;
250 int status;
251
252 /* Send a target failure event to the application */
253 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Target debug interrupt\n"));
254
255 if (pDev->TargetFailureCallback != NULL) {
256 pDev->TargetFailureCallback(pDev->HTCContext);
257 }
258
259 if (pDev->GMboxEnabled) {
260 DevNotifyGMboxTargetFailure(pDev);
261 }
262
263 /* clear the interrupt , the debug error interrupt is
264 * counter 0 */
265 /* read counter to clear interrupt */
266 status = HIFReadWrite(pDev->HIFDevice,
267 COUNT_DEC_ADDRESS,
268 (u8 *)&dummy,
269 4,
270 HIF_RD_SYNC_BYTE_INC,
271 NULL);
272
273 A_ASSERT(status == 0);
274 return status;
275}
276
277static int DevServiceCounterInterrupt(struct ar6k_device *pDev)
278{
279 u8 counter_int_status;
280
281 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Counter Interrupt\n"));
282
283 counter_int_status = pDev->IrqProcRegisters.counter_int_status &
284 pDev->IrqEnableRegisters.counter_int_status_enable;
285
286 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
287 ("Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
288 counter_int_status));
289
290 /* Check if the debug interrupt is pending
291 * NOTE: other modules like GMBOX may use the counter interrupt for
292 * credit flow control on other counters, we only need to check for the debug assertion
293 * counter interrupt */
294 if (counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) {
295 return DevServiceDebugInterrupt(pDev);
296 }
297
298 return 0;
299}
300
301/* callback when our fetch to get interrupt status registers completes */
302static void DevGetEventAsyncHandler(void *Context, struct htc_packet *pPacket)
303{
304 struct ar6k_device *pDev = (struct ar6k_device *)Context;
305 u32 lookAhead = 0;
306 bool otherInts = false;
307
308 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
309
310 do {
311
312 if (pPacket->Status) {
313 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
314 (" GetEvents I/O request failed, status:%d \n", pPacket->Status));
315 /* bail out, don't unmask HIF interrupt */
316 break;
317 }
318
319 if (pDev->GetPendingEventsFunc != NULL) {
320 /* the HIF layer collected the information for us */
321 struct hif_pending_events_info *pEvents = (struct hif_pending_events_info *)pPacket->pBuffer;
322 if (pEvents->Events & HIF_RECV_MSG_AVAIL) {
323 lookAhead = pEvents->LookAhead;
324 if (0 == lookAhead) {
325 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler1, lookAhead is zero! \n"));
326 }
327 }
328 if (pEvents->Events & HIF_OTHER_EVENTS) {
329 otherInts = true;
330 }
331 } else {
332 /* standard interrupt table handling.... */
333 struct ar6k_irq_proc_registers *pReg = (struct ar6k_irq_proc_registers *)pPacket->pBuffer;
334 u8 host_int_status;
335
336 host_int_status = pReg->host_int_status & pDev->IrqEnableRegisters.int_status_enable;
337
338 if (host_int_status & (1 << HTC_MAILBOX)) {
339 host_int_status &= ~(1 << HTC_MAILBOX);
340 if (pReg->rx_lookahead_valid & (1 << HTC_MAILBOX)) {
341 /* mailbox has a message and the look ahead is valid */
342 lookAhead = pReg->rx_lookahead[HTC_MAILBOX];
343 if (0 == lookAhead) {
344 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler2, lookAhead is zero! \n"));
345 }
346 }
347 }
348
349 if (host_int_status) {
350 /* there are other interrupts to handle */
351 otherInts = true;
352 }
353 }
354
355 if (otherInts || (lookAhead == 0)) {
356 /* if there are other interrupts to process, we cannot do this in the async handler so
357 * ack the interrupt which will cause our sync handler to run again
358 * if however there are no more messages, we can now ack the interrupt */
359 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
360 (" Acking interrupt from DevGetEventAsyncHandler (otherints:%d, lookahead:0x%X)\n",
361 otherInts, lookAhead));
362 HIFAckInterrupt(pDev->HIFDevice);
363 } else {
364 int fetched = 0;
365 int status;
366
367 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
368 (" DevGetEventAsyncHandler : detected another message, lookahead :0x%X \n",
369 lookAhead));
370 /* lookahead is non-zero and there are no other interrupts to service,
371 * go get the next message */
372 status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, NULL, &fetched);
373
374 if (!status && !fetched) {
375 /* HTC layer could not pull out messages due to lack of resources, stop IRQ processing */
376 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("MessagePendingCallback did not pull any messages, force-ack \n"));
377 DevAsyncIrqProcessComplete(pDev);
378 }
379 }
380
381 } while (false);
382
383 /* free this IO packet */
384 AR6KFreeIOPacket(pDev,pPacket);
385 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGetEventAsyncHandler \n"));
386}
387
388/* called by the HTC layer when it wants us to check if the device has any more pending
389 * recv messages, this starts off a series of async requests to read interrupt registers */
390int DevCheckPendingRecvMsgsAsync(void *context)
391{
392 struct ar6k_device *pDev = (struct ar6k_device *)context;
393 int status = 0;
394 struct htc_packet *pIOPacket;
395
396 /* this is called in an ASYNC only context, we may NOT block, sleep or call any apis that can
397 * cause us to switch contexts */
398
399 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevCheckPendingRecvMsgsAsync: (dev: 0x%lX)\n", (unsigned long)pDev));
400
401 do {
402
403 if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) {
404 /* break the async processing chain right here, no need to continue.
405 * The DevDsrHandler() will handle things in a loop when things are driven
406 * synchronously */
407 break;
408 }
409
410 /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake
411 * the target, if upper layers determine that we are in a low-throughput mode, we can
412 * rely on taking another interrupt rather than re-checking the status registers which can
413 * re-wake the target */
414 if (pDev->RecheckIRQStatusCnt == 0) {
415 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, re-acking HIF interrupts\n"));
416 /* ack interrupt */
417 HIFAckInterrupt(pDev->HIFDevice);
418 break;
419 }
420
421 /* first allocate one of our HTC packets we created for async I/O
422 * we reuse HTC packet definitions so that we can use the completion mechanism
423 * in DevRWCompletionHandler() */
424 pIOPacket = AR6KAllocIOPacket(pDev);
425
426 if (NULL == pIOPacket) {
427 /* there should be only 1 asynchronous request out at a time to read these registers
428 * so this should actually never happen */
429 status = A_NO_MEMORY;
430 A_ASSERT(false);
431 break;
432 }
433
434 /* stick in our completion routine when the I/O operation completes */
435 pIOPacket->Completion = DevGetEventAsyncHandler;
436 pIOPacket->pContext = pDev;
437
438 if (pDev->GetPendingEventsFunc) {
439 /* HIF layer has it's own mechanism, pass the IO to it.. */
440 status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
441 (struct hif_pending_events_info *)pIOPacket->pBuffer,
442 pIOPacket);
443
444 } else {
445 /* standard way, read the interrupt register table asynchronously again */
446 status = HIFReadWrite(pDev->HIFDevice,
447 HOST_INT_STATUS_ADDRESS,
448 pIOPacket->pBuffer,
449 AR6K_IRQ_PROC_REGS_SIZE,
450 HIF_RD_ASYNC_BYTE_INC,
451 pIOPacket);
452 }
453
454 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Async IO issued to get interrupt status...\n"));
455 } while (false);
456
457 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevCheckPendingRecvMsgsAsync \n"));
458
459 return status;
460}
461
462void DevAsyncIrqProcessComplete(struct ar6k_device *pDev)
463{
464 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("DevAsyncIrqProcessComplete - forcing HIF IRQ ACK \n"));
465 HIFAckInterrupt(pDev->HIFDevice);
466}
467
468/* process pending interrupts synchronously */
469static int ProcessPendingIRQs(struct ar6k_device *pDev, bool *pDone, bool *pASyncProcessing)
470{
471 int status = 0;
472 u8 host_int_status = 0;
473 u32 lookAhead = 0;
474
475 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+ProcessPendingIRQs: (dev: 0x%lX)\n", (unsigned long)pDev));
476
477 /*** NOTE: the HIF implementation guarantees that the context of this call allows
478 * us to perform SYNCHRONOUS I/O, that is we can block, sleep or call any API that
479 * can block or switch thread/task ontexts.
480 * This is a fully schedulable context.
481 * */
482 do {
483
484 if (pDev->IrqEnableRegisters.int_status_enable == 0) {
485 /* interrupt enables have been cleared, do not try to process any pending interrupts that
486 * may result in more bus transactions. The target may be unresponsive at this
487 * point. */
488 break;
489 }
490
491 if (pDev->GetPendingEventsFunc != NULL) {
492 struct hif_pending_events_info events;
493
494#ifdef THREAD_X
495 events.Polling= 0;
496#endif
497 /* the HIF layer uses a special mechanism to get events
498 * get this synchronously */
499 status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
500 &events,
501 NULL);
502
503 if (status) {
504 break;
505 }
506
507 if (events.Events & HIF_RECV_MSG_AVAIL) {
508 lookAhead = events.LookAhead;
509 if (0 == lookAhead) {
510 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs1 lookAhead is zero! \n"));
511 }
512 }
513
514 if (!(events.Events & HIF_OTHER_EVENTS) ||
515 !(pDev->IrqEnableRegisters.int_status_enable & OTHER_INTS_ENABLED)) {
516 /* no need to read the register table, no other interesting interrupts.
517 * Some interfaces (like SPI) can shadow interrupt sources without
518 * requiring the host to do a full table read */
519 break;
520 }
521
522 /* otherwise fall through and read the register table */
523 }
524
525 /*
526 * Read the first 28 bytes of the HTC register table. This will yield us
527 * the value of different int status registers and the lookahead
528 * registers.
529 * length = sizeof(int_status) + sizeof(cpu_int_status) +
530 * sizeof(error_int_status) + sizeof(counter_int_status) +
531 * sizeof(mbox_frame) + sizeof(rx_lookahead_valid) +
532 * sizeof(hole) + sizeof(rx_lookahead) +
533 * sizeof(int_status_enable) + sizeof(cpu_int_status_enable) +
534 * sizeof(error_status_enable) +
535 * sizeof(counter_int_status_enable);
536 *
537 */
538#ifdef CONFIG_MMC_SDHCI_S3C
539 pDev->IrqProcRegisters.host_int_status = 0;
540 pDev->IrqProcRegisters.rx_lookahead_valid = 0;
541 pDev->IrqProcRegisters.host_int_status2 = 0;
542 pDev->IrqProcRegisters.rx_lookahead[0] = 0;
543 pDev->IrqProcRegisters.rx_lookahead[1] = 0xaaa5555;
544#endif /* CONFIG_MMC_SDHCI_S3C */
545 status = HIFReadWrite(pDev->HIFDevice,
546 HOST_INT_STATUS_ADDRESS,
547 (u8 *)&pDev->IrqProcRegisters,
548 AR6K_IRQ_PROC_REGS_SIZE,
549 HIF_RD_SYNC_BYTE_INC,
550 NULL);
551
552 if (status) {
553 break;
554 }
555
556#ifdef ATH_DEBUG_MODULE
557 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) {
558 DevDumpRegisters(pDev,
559 &pDev->IrqProcRegisters,
560 &pDev->IrqEnableRegisters);
561 }
562#endif
563
564 /* Update only those registers that are enabled */
565 host_int_status = pDev->IrqProcRegisters.host_int_status &
566 pDev->IrqEnableRegisters.int_status_enable;
567
568 if (NULL == pDev->GetPendingEventsFunc) {
569 /* only look at mailbox status if the HIF layer did not provide this function,
570 * on some HIF interfaces reading the RX lookahead is not valid to do */
571 if (host_int_status & (1 << HTC_MAILBOX)) {
572 /* mask out pending mailbox value, we use "lookAhead" as the real flag for
573 * mailbox processing below */
574 host_int_status &= ~(1 << HTC_MAILBOX);
575 if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBOX)) {
576 /* mailbox has a message and the look ahead is valid */
577 lookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX];
578 if (0 == lookAhead) {
579 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs2, lookAhead is zero! \n"));
580 }
581 }
582 }
583 } else {
584 /* not valid to check if the HIF has another mechanism for reading mailbox pending status*/
585 host_int_status &= ~(1 << HTC_MAILBOX);
586 }
587
588 if (pDev->GMboxEnabled) {
589 /*call GMBOX layer to process any interrupts of interest */
590 status = DevCheckGMboxInterrupts(pDev);
591 }
592
593 } while (false);
594
595
596 do {
597
598 /* did the interrupt status fetches succeed? */
599 if (status) {
600 break;
601 }
602
603 if ((0 == host_int_status) && (0 == lookAhead)) {
604 /* nothing to process, the caller can use this to break out of a loop */
605 *pDone = true;
606 break;
607 }
608
609 if (lookAhead != 0) {
610 int fetched = 0;
611
612 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Pending mailbox message, LookAhead: 0x%X\n",lookAhead));
613 /* Mailbox Interrupt, the HTC layer may issue async requests to empty the
614 * mailbox...
615 * When emptying the recv mailbox we use the async handler above called from the
616 * completion routine of the callers read request. This can improve performance
617 * by reducing context switching when we rapidly pull packets */
618 status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, pASyncProcessing, &fetched);
619 if (status) {
620 break;
621 }
622
623 if (!fetched) {
624 /* HTC could not pull any messages out due to lack of resources */
625 /* force DSR handler to ack the interrupt */
626 *pASyncProcessing = false;
627 pDev->RecheckIRQStatusCnt = 0;
628 }
629 }
630
631 /* now handle the rest of them */
632 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
633 (" Valid interrupt source(s) for OTHER interrupts: 0x%x\n",
634 host_int_status));
635
636 if (HOST_INT_STATUS_CPU_GET(host_int_status)) {
637 /* CPU Interrupt */
638 status = DevServiceCPUInterrupt(pDev);
639 if (status){
640 break;
641 }
642 }
643
644 if (HOST_INT_STATUS_ERROR_GET(host_int_status)) {
645 /* Error Interrupt */
646 status = DevServiceErrorInterrupt(pDev);
647 if (status){
648 break;
649 }
650 }
651
652 if (HOST_INT_STATUS_COUNTER_GET(host_int_status)) {
653 /* Counter Interrupt */
654 status = DevServiceCounterInterrupt(pDev);
655 if (status){
656 break;
657 }
658 }
659
660 } while (false);
661
662 /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake
663 * the target, if upper layers determine that we are in a low-throughput mode, we can
664 * rely on taking another interrupt rather than re-checking the status registers which can
665 * re-wake the target.
666 *
667 * NOTE : for host interfaces that use the special GetPendingEventsFunc, this optimization cannot
668 * be used due to possible side-effects. For example, SPI requires the host to drain all
669 * messages from the mailbox before exiting the ISR routine. */
670 if (!(*pASyncProcessing) && (pDev->RecheckIRQStatusCnt == 0) && (pDev->GetPendingEventsFunc == NULL)) {
671 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, forcing done \n"));
672 *pDone = true;
673 }
674
675 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-ProcessPendingIRQs: (done:%d, async:%d) status=%d \n",
676 *pDone, *pASyncProcessing, status));
677
678 return status;
679}
680
681
682/* Synchronousinterrupt handler, this handler kicks off all interrupt processing.*/
683int DevDsrHandler(void *context)
684{
685 struct ar6k_device *pDev = (struct ar6k_device *)context;
686 int status = 0;
687 bool done = false;
688 bool asyncProc = false;
689
690 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDsrHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
691
692 /* reset the recv counter that tracks when we need to yield from the DSR */
693 pDev->CurrentDSRRecvCount = 0;
694 /* reset counter used to flag a re-scan of IRQ status registers on the target */
695 pDev->RecheckIRQStatusCnt = 0;
696
697 while (!done) {
698 status = ProcessPendingIRQs(pDev, &done, &asyncProc);
699 if (status) {
700 break;
701 }
702
703 if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) {
704 /* the HIF layer does not allow async IRQ processing, override the asyncProc flag */
705 asyncProc = false;
706 /* this will cause us to re-enter ProcessPendingIRQ() and re-read interrupt status registers.
707 * this has a nice side effect of blocking us until all async read requests are completed.
708 * This behavior is required on some HIF implementations that do not allow ASYNC
709 * processing in interrupt handlers (like Windows CE) */
710
711 if (pDev->DSRCanYield && DEV_CHECK_RECV_YIELD(pDev)) {
712 /* ProcessPendingIRQs() pulled enough recv messages to satisfy the yield count, stop
713 * checking for more messages and return */
714 break;
715 }
716 }
717
718 if (asyncProc) {
719 /* the function performed some async I/O for performance, we
720 need to exit the ISR immediately, the check below will prevent the interrupt from being
721 Ack'd while we handle it asynchronously */
722 break;
723 }
724
725 }
726
727 if (!status && !asyncProc) {
728 /* Ack the interrupt only if :
729 * 1. we did not get any errors in processing interrupts
730 * 2. there are no outstanding async processing requests */
731 if (pDev->DSRCanYield) {
732 /* if the DSR can yield do not ACK the interrupt, there could be more pending messages.
733 * The HIF layer must ACK the interrupt on behalf of HTC */
734 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Yield in effect (cur RX count: %d) \n", pDev->CurrentDSRRecvCount));
735 } else {
736 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Acking interrupt from DevDsrHandler \n"));
737 HIFAckInterrupt(pDev->HIFDevice);
738 }
739 }
740
741 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDsrHandler \n"));
742 return status;
743}
744
745#ifdef ATH_DEBUG_MODULE
746void DumpAR6KDevState(struct ar6k_device *pDev)
747{
748 int status;
749 struct ar6k_irq_enable_registers regs;
750 struct ar6k_irq_proc_registers procRegs;
751
752 LOCK_AR6K(pDev);
753 /* copy into our temp area */
754 memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
755 UNLOCK_AR6K(pDev);
756
757 /* load the register table from the device */
758 status = HIFReadWrite(pDev->HIFDevice,
759 HOST_INT_STATUS_ADDRESS,
760 (u8 *)&procRegs,
761 AR6K_IRQ_PROC_REGS_SIZE,
762 HIF_RD_SYNC_BYTE_INC,
763 NULL);
764
765 if (status) {
766 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
767 ("DumpAR6KDevState : Failed to read register table (%d) \n",status));
768 return;
769 }
770
771 DevDumpRegisters(pDev,&procRegs,&regs);
772
773 if (pDev->GMboxInfo.pStateDumpCallback != NULL) {
774 pDev->GMboxInfo.pStateDumpCallback(pDev->GMboxInfo.pProtocolContext);
775 }
776
777 /* dump any bus state at the HIF layer */
778 HIFConfigureDevice(pDev->HIFDevice,HIF_DEVICE_DEBUG_BUS_STATE,NULL,0);
779
780}
781#endif
782
783
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c
deleted file mode 100644
index 725540f9add..00000000000
--- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c
+++ /dev/null
@@ -1,755 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6k_gmbox.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Generic MBOX API implementation
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#include "a_config.h"
26#include "athdefs.h"
27#include "a_osapi.h"
28#include "../htc_debug.h"
29#include "hif.h"
30#include "htc_packet.h"
31#include "ar6k.h"
32#include "hw/mbox_host_reg.h"
33#include "gmboxif.h"
34
35/*
36 * This file provides management functions and a toolbox for GMBOX protocol modules.
37 * Only one protocol module can be installed at a time. The determination of which protocol
38 * module is installed is determined at compile time.
39 *
40 */
41#ifdef ATH_AR6K_ENABLE_GMBOX
42 /* GMBOX definitions */
43#define GMBOX_INT_STATUS_ENABLE_REG 0x488
44#define GMBOX_INT_STATUS_RX_DATA (1 << 0)
45#define GMBOX_INT_STATUS_TX_OVERFLOW (1 << 1)
46#define GMBOX_INT_STATUS_RX_OVERFLOW (1 << 2)
47
48#define GMBOX_LOOKAHEAD_MUX_REG 0x498
49#define GMBOX_LA_MUX_OVERRIDE_2_3 (1 << 0)
50
51#define AR6K_GMBOX_CREDIT_DEC_ADDRESS (COUNT_DEC_ADDRESS + 4 * AR6K_GMBOX_CREDIT_COUNTER)
52#define AR6K_GMBOX_CREDIT_SIZE_ADDRESS (COUNT_ADDRESS + AR6K_GMBOX_CREDIT_SIZE_COUNTER)
53
54
55 /* external APIs for allocating and freeing internal I/O packets to handle ASYNC I/O */
56extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket);
57extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev);
58
59
60/* callback when our fetch to enable/disable completes */
61static void DevGMboxIRQActionAsyncHandler(void *Context, struct htc_packet *pPacket)
62{
63 struct ar6k_device *pDev = (struct ar6k_device *)Context;
64
65 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
66
67 if (pPacket->Status) {
68 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
69 ("IRQAction Operation (%d) failed! status:%d \n", pPacket->PktInfo.AsRx.HTCRxFlags,pPacket->Status));
70 }
71 /* free this IO packet */
72 AR6KFreeIOPacket(pDev,pPacket);
73 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxIRQActionAsyncHandler \n"));
74}
75
76static int DevGMboxCounterEnableDisable(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode)
77{
78 int status = 0;
79 struct ar6k_irq_enable_registers regs;
80 struct htc_packet *pIOPacket = NULL;
81
82 LOCK_AR6K(pDev);
83
84 if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
85 pDev->GMboxInfo.CreditCountIRQEnabled = true;
86 pDev->IrqEnableRegisters.counter_int_status_enable |=
87 COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER);
88 pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_COUNTER_SET(0x01);
89 } else {
90 pDev->GMboxInfo.CreditCountIRQEnabled = false;
91 pDev->IrqEnableRegisters.counter_int_status_enable &=
92 ~(COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER));
93 }
94 /* copy into our temp area */
95 memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
96
97 UNLOCK_AR6K(pDev);
98
99 do {
100
101 if (AsyncMode) {
102
103 pIOPacket = AR6KAllocIOPacket(pDev);
104
105 if (NULL == pIOPacket) {
106 status = A_NO_MEMORY;
107 A_ASSERT(false);
108 break;
109 }
110
111 /* copy values to write to our async I/O buffer */
112 memcpy(pIOPacket->pBuffer,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
113
114 /* stick in our completion routine when the I/O operation completes */
115 pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
116 pIOPacket->pContext = pDev;
117 pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
118 /* write it out asynchronously */
119 HIFReadWrite(pDev->HIFDevice,
120 INT_STATUS_ENABLE_ADDRESS,
121 pIOPacket->pBuffer,
122 AR6K_IRQ_ENABLE_REGS_SIZE,
123 HIF_WR_ASYNC_BYTE_INC,
124 pIOPacket);
125
126 pIOPacket = NULL;
127 break;
128 }
129
130 /* if we get here we are doing it synchronously */
131 status = HIFReadWrite(pDev->HIFDevice,
132 INT_STATUS_ENABLE_ADDRESS,
133 &regs.int_status_enable,
134 AR6K_IRQ_ENABLE_REGS_SIZE,
135 HIF_WR_SYNC_BYTE_INC,
136 NULL);
137 } while (false);
138
139 if (status) {
140 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
141 (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status));
142 } else {
143 if (!AsyncMode) {
144 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
145 (" IRQAction Operation (%d) success \n", IrqAction));
146 }
147 }
148
149 if (pIOPacket != NULL) {
150 AR6KFreeIOPacket(pDev,pIOPacket);
151 }
152
153 return status;
154}
155
156
157int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode)
158{
159 int status = 0;
160 struct htc_packet *pIOPacket = NULL;
161 u8 GMboxIntControl[4];
162
163 if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
164 return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_ENABLE, AsyncMode);
165 } else if(GMBOX_CREDIT_IRQ_DISABLE == IrqAction) {
166 return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);
167 }
168
169 if (GMBOX_DISABLE_ALL == IrqAction) {
170 /* disable credit IRQ, those are on a different set of registers */
171 DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);
172 }
173
174 /* take the lock to protect interrupt enable shadows */
175 LOCK_AR6K(pDev);
176
177 switch (IrqAction) {
178
179 case GMBOX_DISABLE_ALL:
180 pDev->GMboxControlRegisters.int_status_enable = 0;
181 break;
182 case GMBOX_ERRORS_IRQ_ENABLE:
183 pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_TX_OVERFLOW |
184 GMBOX_INT_STATUS_RX_OVERFLOW;
185 break;
186 case GMBOX_RECV_IRQ_ENABLE:
187 pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_RX_DATA;
188 break;
189 case GMBOX_RECV_IRQ_DISABLE:
190 pDev->GMboxControlRegisters.int_status_enable &= ~GMBOX_INT_STATUS_RX_DATA;
191 break;
192 case GMBOX_ACTION_NONE:
193 default:
194 A_ASSERT(false);
195 break;
196 }
197
198 GMboxIntControl[0] = pDev->GMboxControlRegisters.int_status_enable;
199 GMboxIntControl[1] = GMboxIntControl[0];
200 GMboxIntControl[2] = GMboxIntControl[0];
201 GMboxIntControl[3] = GMboxIntControl[0];
202
203 UNLOCK_AR6K(pDev);
204
205 do {
206
207 if (AsyncMode) {
208
209 pIOPacket = AR6KAllocIOPacket(pDev);
210
211 if (NULL == pIOPacket) {
212 status = A_NO_MEMORY;
213 A_ASSERT(false);
214 break;
215 }
216
217 /* copy values to write to our async I/O buffer */
218 memcpy(pIOPacket->pBuffer,GMboxIntControl,sizeof(GMboxIntControl));
219
220 /* stick in our completion routine when the I/O operation completes */
221 pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
222 pIOPacket->pContext = pDev;
223 pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
224 /* write it out asynchronously */
225 HIFReadWrite(pDev->HIFDevice,
226 GMBOX_INT_STATUS_ENABLE_REG,
227 pIOPacket->pBuffer,
228 sizeof(GMboxIntControl),
229 HIF_WR_ASYNC_BYTE_FIX,
230 pIOPacket);
231 pIOPacket = NULL;
232 break;
233 }
234
235 /* if we get here we are doing it synchronously */
236
237 status = HIFReadWrite(pDev->HIFDevice,
238 GMBOX_INT_STATUS_ENABLE_REG,
239 GMboxIntControl,
240 sizeof(GMboxIntControl),
241 HIF_WR_SYNC_BYTE_FIX,
242 NULL);
243
244 } while (false);
245
246 if (status) {
247 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
248 (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status));
249 } else {
250 if (!AsyncMode) {
251 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
252 (" IRQAction Operation (%d) success \n", IrqAction));
253 }
254 }
255
256 if (pIOPacket != NULL) {
257 AR6KFreeIOPacket(pDev,pIOPacket);
258 }
259
260 return status;
261}
262
263void DevCleanupGMbox(struct ar6k_device *pDev)
264{
265 if (pDev->GMboxEnabled) {
266 pDev->GMboxEnabled = false;
267 GMboxProtocolUninstall(pDev);
268 }
269}
270
271int DevSetupGMbox(struct ar6k_device *pDev)
272{
273 int status = 0;
274 u8 muxControl[4];
275
276 do {
277
278 if (0 == pDev->MailBoxInfo.GMboxAddress) {
279 break;
280 }
281
282 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" GMBOX Advertised: Address:0x%X , size:%d \n",
283 pDev->MailBoxInfo.GMboxAddress, pDev->MailBoxInfo.GMboxSize));
284
285 status = DevGMboxIRQAction(pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC);
286
287 if (status) {
288 break;
289 }
290
291 /* write to mailbox look ahead mux control register, we want the
292 * GMBOX lookaheads to appear on lookaheads 2 and 3
293 * the register is 1-byte wide so we need to hit it 4 times to align the operation
294 * to 4-bytes */
295 muxControl[0] = GMBOX_LA_MUX_OVERRIDE_2_3;
296 muxControl[1] = GMBOX_LA_MUX_OVERRIDE_2_3;
297 muxControl[2] = GMBOX_LA_MUX_OVERRIDE_2_3;
298 muxControl[3] = GMBOX_LA_MUX_OVERRIDE_2_3;
299
300 status = HIFReadWrite(pDev->HIFDevice,
301 GMBOX_LOOKAHEAD_MUX_REG,
302 muxControl,
303 sizeof(muxControl),
304 HIF_WR_SYNC_BYTE_FIX, /* hit this register 4 times */
305 NULL);
306
307 if (status) {
308 break;
309 }
310
311 status = GMboxProtocolInstall(pDev);
312
313 if (status) {
314 break;
315 }
316
317 pDev->GMboxEnabled = true;
318
319 } while (false);
320
321 return status;
322}
323
324int DevCheckGMboxInterrupts(struct ar6k_device *pDev)
325{
326 int status = 0;
327 u8 counter_int_status;
328 int credits;
329 u8 host_int_status2;
330
331 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("+DevCheckGMboxInterrupts \n"));
332
333 /* the caller guarantees that this is a context that allows for blocking I/O */
334
335 do {
336
337 host_int_status2 = pDev->IrqProcRegisters.host_int_status2 &
338 pDev->GMboxControlRegisters.int_status_enable;
339
340 if (host_int_status2 & GMBOX_INT_STATUS_TX_OVERFLOW) {
341 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : TX Overflow \n"));
342 status = A_ECOMM;
343 }
344
345 if (host_int_status2 & GMBOX_INT_STATUS_RX_OVERFLOW) {
346 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : RX Overflow \n"));
347 status = A_ECOMM;
348 }
349
350 if (status) {
351 if (pDev->GMboxInfo.pTargetFailureCallback != NULL) {
352 pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, status);
353 }
354 break;
355 }
356
357 if (host_int_status2 & GMBOX_INT_STATUS_RX_DATA) {
358 if (pDev->IrqProcRegisters.gmbox_rx_avail > 0) {
359 A_ASSERT(pDev->GMboxInfo.pMessagePendingCallBack != NULL);
360 status = pDev->GMboxInfo.pMessagePendingCallBack(
361 pDev->GMboxInfo.pProtocolContext,
362 (u8 *)&pDev->IrqProcRegisters.rx_gmbox_lookahead_alias[0],
363 pDev->IrqProcRegisters.gmbox_rx_avail);
364 }
365 }
366
367 if (status) {
368 break;
369 }
370
371 counter_int_status = pDev->IrqProcRegisters.counter_int_status &
372 pDev->IrqEnableRegisters.counter_int_status_enable;
373
374 /* check if credit interrupt is pending */
375 if (counter_int_status & (COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER))) {
376
377 /* do synchronous read */
378 status = DevGMboxReadCreditCounter(pDev, PROC_IO_SYNC, &credits);
379
380 if (status) {
381 break;
382 }
383
384 A_ASSERT(pDev->GMboxInfo.pCreditsPendingCallback != NULL);
385 status = pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext,
386 credits,
387 pDev->GMboxInfo.CreditCountIRQEnabled);
388 }
389
390 } while (false);
391
392 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("-DevCheckGMboxInterrupts (%d) \n",status));
393
394 return status;
395}
396
397
398int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength)
399{
400 u32 paddedLength;
401 bool sync = (pPacket->Completion == NULL) ? true : false;
402 int status;
403 u32 address;
404
405 /* adjust the length to be a multiple of block size if appropriate */
406 paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, WriteLength);
407
408 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
409 ("DevGMboxWrite, Padded Length: %d Mbox:0x%X (mode:%s)\n",
410 WriteLength,
411 pDev->MailBoxInfo.GMboxAddress,
412 sync ? "SYNC" : "ASYNC"));
413
414 /* last byte of packet has to hit the EOM marker */
415 address = pDev->MailBoxInfo.GMboxAddress + pDev->MailBoxInfo.GMboxSize - paddedLength;
416
417 status = HIFReadWrite(pDev->HIFDevice,
418 address,
419 pPacket->pBuffer,
420 paddedLength, /* the padded length */
421 sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
422 sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
423
424 if (sync) {
425 pPacket->Status = status;
426 } else {
427 if (status == A_PENDING) {
428 status = 0;
429 }
430 }
431
432 return status;
433}
434
435int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength)
436{
437
438 u32 paddedLength;
439 int status;
440 bool sync = (pPacket->Completion == NULL) ? true : false;
441
442 /* adjust the length to be a multiple of block size if appropriate */
443 paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, ReadLength);
444
445 if (paddedLength > pPacket->BufferLength) {
446 A_ASSERT(false);
447 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
448 ("DevGMboxRead, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
449 paddedLength,ReadLength,pPacket->BufferLength));
450 if (pPacket->Completion != NULL) {
451 COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
452 return 0;
453 }
454 return A_EINVAL;
455 }
456
457 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
458 ("DevGMboxRead (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n",
459 (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
460 paddedLength,
461 pDev->MailBoxInfo.GMboxAddress,
462 sync ? "SYNC" : "ASYNC"));
463
464 status = HIFReadWrite(pDev->HIFDevice,
465 pDev->MailBoxInfo.GMboxAddress,
466 pPacket->pBuffer,
467 paddedLength,
468 sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX,
469 sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
470
471 if (sync) {
472 pPacket->Status = status;
473 }
474
475 return status;
476}
477
478
479static int ProcessCreditCounterReadBuffer(u8 *pBuffer, int Length)
480{
481 int credits = 0;
482
483 /* theory of how this works:
484 * We read the credit decrement register multiple times on a byte-wide basis.
485 * The number of times (32) aligns the I/O operation to be a multiple of 4 bytes and provides a
486 * reasonable chance to acquire "all" pending credits in a single I/O operation.
487 *
488 * Once we obtain the filled buffer, we can walk through it looking for credit decrement transitions.
489 * Each non-zero byte represents a single credit decrement (which is a credit given back to the host)
490 * For example if the target provides 3 credits and added 4 more during the 32-byte read operation the following
491 * pattern "could" appear:
492 *
493 * 0x3 0x2 0x1 0x0 0x0 0x0 0x0 0x0 0x1 0x0 0x1 0x0 0x1 0x0 0x1 0x0 ......rest zeros
494 * <---------> <----------------------------->
495 * \_ credits aleady there \_ target adding 4 more credits
496 *
497 * The total available credits would be 7, since there are 7 non-zero bytes in the buffer.
498 *
499 * */
500
501 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
502 DebugDumpBytes(pBuffer, Length, "GMBOX Credit read buffer");
503 }
504
505 while (Length) {
506 if (*pBuffer != 0) {
507 credits++;
508 }
509 Length--;
510 pBuffer++;
511 }
512
513 return credits;
514}
515
516
517/* callback when our fetch to enable/disable completes */
518static void DevGMboxReadCreditsAsyncHandler(void *Context, struct htc_packet *pPacket)
519{
520 struct ar6k_device *pDev = (struct ar6k_device *)Context;
521
522 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
523
524 if (pPacket->Status) {
525 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
526 ("Read Credit Operation failed! status:%d \n", pPacket->Status));
527 } else {
528 int credits = 0;
529 credits = ProcessCreditCounterReadBuffer(pPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);
530 pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext,
531 credits,
532 pDev->GMboxInfo.CreditCountIRQEnabled);
533
534
535 }
536 /* free this IO packet */
537 AR6KFreeIOPacket(pDev,pPacket);
538 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxReadCreditsAsyncHandler \n"));
539}
540
541int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits)
542{
543 int status = 0;
544 struct htc_packet *pIOPacket = NULL;
545
546 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode ? "ASYNC" : "SYNC"));
547
548 do {
549
550 pIOPacket = AR6KAllocIOPacket(pDev);
551
552 if (NULL == pIOPacket) {
553 status = A_NO_MEMORY;
554 A_ASSERT(false);
555 break;
556 }
557
558 A_MEMZERO(pIOPacket->pBuffer,AR6K_REG_IO_BUFFER_SIZE);
559
560 if (AsyncMode) {
561 /* stick in our completion routine when the I/O operation completes */
562 pIOPacket->Completion = DevGMboxReadCreditsAsyncHandler;
563 pIOPacket->pContext = pDev;
564 /* read registers asynchronously */
565 HIFReadWrite(pDev->HIFDevice,
566 AR6K_GMBOX_CREDIT_DEC_ADDRESS,
567 pIOPacket->pBuffer,
568 AR6K_REG_IO_BUFFER_SIZE, /* hit the register multiple times */
569 HIF_RD_ASYNC_BYTE_FIX,
570 pIOPacket);
571 pIOPacket = NULL;
572 break;
573 }
574
575 pIOPacket->Completion = NULL;
576 /* if we get here we are doing it synchronously */
577 status = HIFReadWrite(pDev->HIFDevice,
578 AR6K_GMBOX_CREDIT_DEC_ADDRESS,
579 pIOPacket->pBuffer,
580 AR6K_REG_IO_BUFFER_SIZE,
581 HIF_RD_SYNC_BYTE_FIX,
582 NULL);
583 } while (false);
584
585 if (status) {
586 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
587 (" DevGMboxReadCreditCounter failed! status:%d \n", status));
588 }
589
590 if (pIOPacket != NULL) {
591 if (!status) {
592 /* sync mode processing */
593 *pCredits = ProcessCreditCounterReadBuffer(pIOPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);
594 }
595 AR6KFreeIOPacket(pDev,pIOPacket);
596 }
597
598 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-DevGMboxReadCreditCounter (%s) (%d) \n",
599 AsyncMode ? "ASYNC" : "SYNC", status));
600
601 return status;
602}
603
604int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize)
605{
606 int status;
607 u8 buffer[4];
608
609 status = HIFReadWrite(pDev->HIFDevice,
610 AR6K_GMBOX_CREDIT_SIZE_ADDRESS,
611 buffer,
612 sizeof(buffer),
613 HIF_RD_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */
614 NULL);
615
616 if (!status) {
617 if (buffer[0] == 0) {
618 *pCreditSize = 256;
619 } else {
620 *pCreditSize = buffer[0];
621 }
622
623 }
624
625 return status;
626}
627
628void DevNotifyGMboxTargetFailure(struct ar6k_device *pDev)
629{
630 /* Target ASSERTED!!! */
631 if (pDev->GMboxInfo.pTargetFailureCallback != NULL) {
632 pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, A_HARDWARE);
633 }
634}
635
636int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes)
637{
638
639 int status = 0;
640 struct ar6k_irq_proc_registers procRegs;
641 int maxCopy;
642
643 do {
644 /* on entry the caller provides the length of the lookahead buffer */
645 if (*pLookAheadBytes > sizeof(procRegs.rx_gmbox_lookahead_alias)) {
646 A_ASSERT(false);
647 status = A_EINVAL;
648 break;
649 }
650
651 maxCopy = *pLookAheadBytes;
652 *pLookAheadBytes = 0;
653 /* load the register table from the device */
654 status = HIFReadWrite(pDev->HIFDevice,
655 HOST_INT_STATUS_ADDRESS,
656 (u8 *)&procRegs,
657 AR6K_IRQ_PROC_REGS_SIZE,
658 HIF_RD_SYNC_BYTE_INC,
659 NULL);
660
661 if (status) {
662 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
663 ("DevGMboxRecvLookAheadPeek : Failed to read register table (%d) \n",status));
664 break;
665 }
666
667 if (procRegs.gmbox_rx_avail > 0) {
668 int bytes = procRegs.gmbox_rx_avail > maxCopy ? maxCopy : procRegs.gmbox_rx_avail;
669 memcpy(pLookAheadBuffer,&procRegs.rx_gmbox_lookahead_alias[0],bytes);
670 *pLookAheadBytes = bytes;
671 }
672
673 } while (false);
674
675 return status;
676}
677
678int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int Signal, int AckTimeoutMS)
679{
680 int status = 0;
681 int i;
682 u8 buffer[4];
683
684 A_MEMZERO(buffer, sizeof(buffer));
685
686 do {
687
688 if (Signal >= MBOX_SIG_HCI_BRIDGE_MAX) {
689 status = A_EINVAL;
690 break;
691 }
692
693 /* set the last buffer to do the actual signal trigger */
694 buffer[3] = (1 << Signal);
695
696 status = HIFReadWrite(pDev->HIFDevice,
697 INT_WLAN_ADDRESS,
698 buffer,
699 sizeof(buffer),
700 HIF_WR_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */
701 NULL);
702
703 if (status) {
704 break;
705 }
706
707 } while (false);
708
709
710 if (!status) {
711 /* now read back the register to see if the bit cleared */
712 while (AckTimeoutMS) {
713 status = HIFReadWrite(pDev->HIFDevice,
714 INT_WLAN_ADDRESS,
715 buffer,
716 sizeof(buffer),
717 HIF_RD_SYNC_BYTE_FIX,
718 NULL);
719
720 if (status) {
721 break;
722 }
723
724 for (i = 0; i < sizeof(buffer); i++) {
725 if (buffer[i] & (1 << Signal)) {
726 /* bit is still set */
727 break;
728 }
729 }
730
731 if (i >= sizeof(buffer)) {
732 /* done */
733 break;
734 }
735
736 AckTimeoutMS--;
737 A_MDELAY(1);
738 }
739
740 if (0 == AckTimeoutMS) {
741 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
742 ("DevGMboxSetTargetInterrupt : Ack Timed-out (sig:%d) \n",Signal));
743 status = A_ERROR;
744 }
745 }
746
747 return status;
748
749}
750
751#endif //ATH_AR6K_ENABLE_GMBOX
752
753
754
755
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c
deleted file mode 100644
index 56a0d714380..00000000000
--- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c
+++ /dev/null
@@ -1,1284 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6k_prot_hciUart.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Protocol module for use in bridging HCI-UART packets over the GMBOX interface
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#include "a_config.h"
26#include "athdefs.h"
27#include "a_osapi.h"
28#include "../htc_debug.h"
29#include "hif.h"
30#include "htc_packet.h"
31#include "ar6k.h"
32#include "hci_transport_api.h"
33#include "gmboxif.h"
34#include "ar6000_diag.h"
35#include "hw/apb_map.h"
36#include "hw/mbox_reg.h"
37
38#ifdef ATH_AR6K_ENABLE_GMBOX
39#define HCI_UART_COMMAND_PKT 0x01
40#define HCI_UART_ACL_PKT 0x02
41#define HCI_UART_SCO_PKT 0x03
42#define HCI_UART_EVENT_PKT 0x04
43
44#define HCI_RECV_WAIT_BUFFERS (1 << 0)
45
46#define HCI_SEND_WAIT_CREDITS (1 << 0)
47
48#define HCI_UART_BRIDGE_CREDIT_SIZE 128
49
50#define CREDIT_POLL_COUNT 256
51
52#define HCI_DELAY_PER_INTERVAL_MS 10
53#define BTON_TIMEOUT_MS 500
54#define BTOFF_TIMEOUT_MS 500
55#define BAUD_TIMEOUT_MS 1
56#define BTPWRSAV_TIMEOUT_MS 1
57
58struct gmbox_proto_hci_uart {
59 struct hci_transport_config_info HCIConfig;
60 bool HCIAttached;
61 bool HCIStopped;
62 u32 RecvStateFlags;
63 u32 SendStateFlags;
64 HCI_TRANSPORT_PACKET_TYPE WaitBufferType;
65 struct htc_packet_queue SendQueue; /* write queue holding HCI Command and ACL packets */
66 struct htc_packet_queue HCIACLRecvBuffers; /* recv queue holding buffers for incomming ACL packets */
67 struct htc_packet_queue HCIEventBuffers; /* recv queue holding buffers for incomming event packets */
68 struct ar6k_device *pDev;
69 A_MUTEX_T HCIRxLock;
70 A_MUTEX_T HCITxLock;
71 int CreditsMax;
72 int CreditsConsumed;
73 int CreditsAvailable;
74 int CreditSize;
75 int CreditsCurrentSeek;
76 int SendProcessCount;
77};
78
79#define LOCK_HCI_RX(t) A_MUTEX_LOCK(&(t)->HCIRxLock);
80#define UNLOCK_HCI_RX(t) A_MUTEX_UNLOCK(&(t)->HCIRxLock);
81#define LOCK_HCI_TX(t) A_MUTEX_LOCK(&(t)->HCITxLock);
82#define UNLOCK_HCI_TX(t) A_MUTEX_UNLOCK(&(t)->HCITxLock);
83
84#define DO_HCI_RECV_INDICATION(p, pt) \
85do { \
86 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, \
87 ("HCI: Indicate Recv on packet:0x%lX status:%d len:%d type:%d \n", \
88 (unsigned long)(pt), \
89 (pt)->Status, \
90 !(pt)->Status ? (pt)->ActualLength : 0, \
91 HCI_GET_PACKET_TYPE(pt))); \
92 (p)->HCIConfig.pHCIPktRecv((p)->HCIConfig.pContext, (pt)); \
93} while (0)
94
95#define DO_HCI_SEND_INDICATION(p,pt) \
96{ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Indicate Send on packet:0x%lX status:%d type:%d \n", \
97 (unsigned long)(pt),(pt)->Status,HCI_GET_PACKET_TYPE(pt))); \
98 (p)->HCIConfig.pHCISendComplete((p)->HCIConfig.pContext, (pt)); \
99}
100
101static int HCITrySend(struct gmbox_proto_hci_uart *pProt, struct htc_packet *pPacket, bool Synchronous);
102
103static void HCIUartCleanup(struct gmbox_proto_hci_uart *pProtocol)
104{
105 A_ASSERT(pProtocol != NULL);
106
107 A_MUTEX_DELETE(&pProtocol->HCIRxLock);
108 A_MUTEX_DELETE(&pProtocol->HCITxLock);
109
110 kfree(pProtocol);
111}
112
113static int InitTxCreditState(struct gmbox_proto_hci_uart *pProt)
114{
115 int status;
116 int credits;
117 int creditPollCount = CREDIT_POLL_COUNT;
118 bool gotCredits = false;
119
120 pProt->CreditsConsumed = 0;
121
122 do {
123
124 if (pProt->CreditsMax != 0) {
125 /* we can only call this only once per target reset */
126 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI: InitTxCreditState - already called! \n"));
127 A_ASSERT(false);
128 status = A_EINVAL;
129 break;
130 }
131
132 /* read the credit counter. At startup the target will set the credit counter
133 * to the max available, we read this in a loop because it may take
134 * multiple credit counter reads to get all credits */
135
136 while (creditPollCount) {
137
138 credits = 0;
139
140 status = DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits);
141
142 if (status) {
143 break;
144 }
145
146 if (!gotCredits && (0 == credits)) {
147 creditPollCount--;
148 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: credit is 0, retrying (%d) \n",creditPollCount));
149 A_MDELAY(HCI_DELAY_PER_INTERVAL_MS);
150 continue;
151 } else {
152 gotCredits = true;
153 }
154
155 if (0 == credits) {
156 break;
157 }
158
159 pProt->CreditsMax += credits;
160 }
161
162 if (status) {
163 break;
164 }
165
166 if (0 == creditPollCount) {
167 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
168 ("** HCI : Failed to get credits! GMBOX Target was not available \n"));
169 status = A_ERROR;
170 break;
171 }
172
173 /* now get the size */
174 status = DevGMboxReadCreditSize(pProt->pDev, &pProt->CreditSize);
175
176 if (status) {
177 break;
178 }
179
180 } while (false);
181
182 if (!status) {
183 pProt->CreditsAvailable = pProt->CreditsMax;
184 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HCI : InitTxCreditState - credits avail: %d, size: %d \n",
185 pProt->CreditsAvailable, pProt->CreditSize));
186 }
187
188 return status;
189}
190
191static int CreditsAvailableCallback(void *pContext, int Credits, bool CreditIRQEnabled)
192{
193 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext;
194 bool enableCreditIrq = false;
195 bool disableCreditIrq = false;
196 bool doPendingSends = false;
197 int status = 0;
198
199 /** this callback is called under 2 conditions:
200 * 1. The credit IRQ interrupt was enabled and signaled.
201 * 2. A credit counter read completed.
202 *
203 * The function must not assume that the calling context can block !
204 */
205
206 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+CreditsAvailableCallback (Credits:%d, IRQ:%s) \n",
207 Credits, CreditIRQEnabled ? "ON" : "OFF"));
208
209 LOCK_HCI_TX(pProt);
210
211 do {
212
213 if (0 == Credits) {
214 if (!CreditIRQEnabled) {
215 /* enable credit IRQ */
216 enableCreditIrq = true;
217 }
218 break;
219 }
220
221 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: current credit state, consumed:%d available:%d max:%d seek:%d\n",
222 pProt->CreditsConsumed,
223 pProt->CreditsAvailable,
224 pProt->CreditsMax,
225 pProt->CreditsCurrentSeek));
226
227 pProt->CreditsAvailable += Credits;
228 A_ASSERT(pProt->CreditsAvailable <= pProt->CreditsMax);
229 pProt->CreditsConsumed -= Credits;
230 A_ASSERT(pProt->CreditsConsumed >= 0);
231
232 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: new credit state, consumed:%d available:%d max:%d seek:%d\n",
233 pProt->CreditsConsumed,
234 pProt->CreditsAvailable,
235 pProt->CreditsMax,
236 pProt->CreditsCurrentSeek));
237
238 if (pProt->CreditsAvailable >= pProt->CreditsCurrentSeek) {
239 /* we have enough credits to fulfill at least 1 packet waiting in the queue */
240 pProt->CreditsCurrentSeek = 0;
241 pProt->SendStateFlags &= ~HCI_SEND_WAIT_CREDITS;
242 doPendingSends = true;
243 if (CreditIRQEnabled) {
244 /* credit IRQ was enabled, we shouldn't need it anymore */
245 disableCreditIrq = true;
246 }
247 } else {
248 /* not enough credits yet, enable credit IRQ if we haven't already */
249 if (!CreditIRQEnabled) {
250 enableCreditIrq = true;
251 }
252 }
253
254 } while (false);
255
256 UNLOCK_HCI_TX(pProt);
257
258 if (enableCreditIrq) {
259 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Enabling credit count IRQ...\n"));
260 /* must use async only */
261 status = DevGMboxIRQAction(pProt->pDev, GMBOX_CREDIT_IRQ_ENABLE, PROC_IO_ASYNC);
262 } else if (disableCreditIrq) {
263 /* must use async only */
264 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Disabling credit count IRQ...\n"));
265 status = DevGMboxIRQAction(pProt->pDev, GMBOX_CREDIT_IRQ_DISABLE, PROC_IO_ASYNC);
266 }
267
268 if (doPendingSends) {
269 HCITrySend(pProt, NULL, false);
270 }
271
272 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+CreditsAvailableCallback \n"));
273 return status;
274}
275
276static INLINE void NotifyTransportFailure(struct gmbox_proto_hci_uart *pProt, int status)
277{
278 if (pProt->HCIConfig.TransportFailure != NULL) {
279 pProt->HCIConfig.TransportFailure(pProt->HCIConfig.pContext, status);
280 }
281}
282
283static void FailureCallback(void *pContext, int Status)
284{
285 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext;
286
287 /* target assertion occurred */
288 NotifyTransportFailure(pProt, Status);
289}
290
291static void StateDumpCallback(void *pContext)
292{
293 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext;
294
295 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("============ HCIUart State ======================\n"));
296 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("RecvStateFlags : 0x%X \n",pProt->RecvStateFlags));
297 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("SendStateFlags : 0x%X \n",pProt->SendStateFlags));
298 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("WaitBufferType : %d \n",pProt->WaitBufferType));
299 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("SendQueue Depth : %d \n",HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue)));
300 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsMax : %d \n",pProt->CreditsMax));
301 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsConsumed : %d \n",pProt->CreditsConsumed));
302 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsAvailable : %d \n",pProt->CreditsAvailable));
303 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("==================================================\n"));
304}
305
306static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidBytes)
307{
308 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext;
309 int status = 0;
310 int totalRecvLength = 0;
311 HCI_TRANSPORT_PACKET_TYPE pktType = HCI_PACKET_INVALID;
312 bool recvRefillCalled = false;
313 bool blockRecv = false;
314 struct htc_packet *pPacket = NULL;
315
316 /** caller guarantees that this is a fully block-able context (synch I/O is allowed) */
317
318 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HCIUartMessagePending Lookahead Bytes:%d \n",ValidBytes));
319
320 LOCK_HCI_RX(pProt);
321
322 do {
323
324 if (ValidBytes < 3) {
325 /* not enough for ACL or event header */
326 break;
327 }
328
329 if ((LookAheadBytes[0] == HCI_UART_ACL_PKT) && (ValidBytes < 5)) {
330 /* not enough for ACL data header */
331 break;
332 }
333
334 switch (LookAheadBytes[0]) {
335 case HCI_UART_EVENT_PKT:
336 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI Event: %d param length: %d \n",
337 LookAheadBytes[1], LookAheadBytes[2]));
338 totalRecvLength = LookAheadBytes[2];
339 totalRecvLength += 3; /* add type + event code + length field */
340 pktType = HCI_EVENT_TYPE;
341 break;
342 case HCI_UART_ACL_PKT:
343 totalRecvLength = (LookAheadBytes[4] << 8) | LookAheadBytes[3];
344 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI ACL: conn:0x%X length: %d \n",
345 ((LookAheadBytes[2] & 0xF0) << 8) | LookAheadBytes[1], totalRecvLength));
346 totalRecvLength += 5; /* add type + connection handle + length field */
347 pktType = HCI_ACL_TYPE;
348 break;
349 default:
350 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("**Invalid HCI packet type: %d \n",LookAheadBytes[0]));
351 status = A_EPROTO;
352 break;
353 }
354
355 if (status) {
356 break;
357 }
358
359 if (pProt->HCIConfig.pHCIPktRecvAlloc != NULL) {
360 UNLOCK_HCI_RX(pProt);
361 /* user is using a per-packet allocation callback */
362 pPacket = pProt->HCIConfig.pHCIPktRecvAlloc(pProt->HCIConfig.pContext,
363 pktType,
364 totalRecvLength);
365 LOCK_HCI_RX(pProt);
366
367 } else {
368 struct htc_packet_queue *pQueue;
369 /* user is using a refill handler that can refill multiple HTC buffers */
370
371 /* select buffer queue */
372 if (pktType == HCI_ACL_TYPE) {
373 pQueue = &pProt->HCIACLRecvBuffers;
374 } else {
375 pQueue = &pProt->HCIEventBuffers;
376 }
377
378 if (HTC_QUEUE_EMPTY(pQueue)) {
379 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
380 ("** HCI pkt type: %d has no buffers available calling allocation handler \n",
381 pktType));
382 /* check for refill handler */
383 if (pProt->HCIConfig.pHCIPktRecvRefill != NULL) {
384 recvRefillCalled = true;
385 UNLOCK_HCI_RX(pProt);
386 /* call the re-fill handler */
387 pProt->HCIConfig.pHCIPktRecvRefill(pProt->HCIConfig.pContext,
388 pktType,
389 0);
390 LOCK_HCI_RX(pProt);
391 /* check if we have more buffers */
392 pPacket = HTC_PACKET_DEQUEUE(pQueue);
393 /* fall through */
394 }
395 } else {
396 pPacket = HTC_PACKET_DEQUEUE(pQueue);
397 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
398 ("HCI pkt type: %d now has %d recv buffers left \n",
399 pktType, HTC_PACKET_QUEUE_DEPTH(pQueue)));
400 }
401 }
402
403 if (NULL == pPacket) {
404 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
405 ("** HCI pkt type: %d has no buffers available stopping recv...\n", pktType));
406 /* this is not an error, we simply need to mark that we are waiting for buffers.*/
407 pProt->RecvStateFlags |= HCI_RECV_WAIT_BUFFERS;
408 pProt->WaitBufferType = pktType;
409 blockRecv = true;
410 break;
411 }
412
413 if (totalRecvLength > (int)pPacket->BufferLength) {
414 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI-UART pkt: %d requires %d bytes (%d buffer bytes avail) ! \n",
415 LookAheadBytes[0], totalRecvLength, pPacket->BufferLength));
416 status = A_EINVAL;
417 break;
418 }
419
420 } while (false);
421
422 UNLOCK_HCI_RX(pProt);
423
424 /* locks are released, we can go fetch the packet */
425
426 do {
427
428 if (status || (NULL == pPacket)) {
429 break;
430 }
431
432 /* do this synchronously, we don't need to be fast here */
433 pPacket->Completion = NULL;
434
435 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI : getting recv packet len:%d hci-uart-type: %s \n",
436 totalRecvLength, (LookAheadBytes[0] == HCI_UART_EVENT_PKT) ? "EVENT" : "ACL"));
437
438 status = DevGMboxRead(pProt->pDev, pPacket, totalRecvLength);
439
440 if (status) {
441 break;
442 }
443
444 if (pPacket->pBuffer[0] != LookAheadBytes[0]) {
445 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not contain expected packet type: %d ! \n",
446 pPacket->pBuffer[0]));
447 status = A_EPROTO;
448 break;
449 }
450
451 if (pPacket->pBuffer[0] == HCI_UART_EVENT_PKT) {
452 /* validate event header fields */
453 if ((pPacket->pBuffer[1] != LookAheadBytes[1]) ||
454 (pPacket->pBuffer[2] != LookAheadBytes[2])) {
455 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not match lookahead! \n"));
456 DebugDumpBytes(LookAheadBytes, 3, "Expected HCI-UART Header");
457 DebugDumpBytes(pPacket->pBuffer, 3, "** Bad HCI-UART Header");
458 status = A_EPROTO;
459 break;
460 }
461 } else if (pPacket->pBuffer[0] == HCI_UART_ACL_PKT) {
462 /* validate acl header fields */
463 if ((pPacket->pBuffer[1] != LookAheadBytes[1]) ||
464 (pPacket->pBuffer[2] != LookAheadBytes[2]) ||
465 (pPacket->pBuffer[3] != LookAheadBytes[3]) ||
466 (pPacket->pBuffer[4] != LookAheadBytes[4])) {
467 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not match lookahead! \n"));
468 DebugDumpBytes(LookAheadBytes, 5, "Expected HCI-UART Header");
469 DebugDumpBytes(pPacket->pBuffer, 5, "** Bad HCI-UART Header");
470 status = A_EPROTO;
471 break;
472 }
473 }
474
475 /* adjust buffer to move past packet ID */
476 pPacket->pBuffer++;
477 pPacket->ActualLength = totalRecvLength - 1;
478 pPacket->Status = 0;
479 /* indicate packet */
480 DO_HCI_RECV_INDICATION(pProt,pPacket);
481 pPacket = NULL;
482
483 /* check if we need to refill recv buffers */
484 if ((pProt->HCIConfig.pHCIPktRecvRefill != NULL) && !recvRefillCalled) {
485 struct htc_packet_queue *pQueue;
486 int watermark;
487
488 if (pktType == HCI_ACL_TYPE) {
489 watermark = pProt->HCIConfig.ACLRecvBufferWaterMark;
490 pQueue = &pProt->HCIACLRecvBuffers;
491 } else {
492 watermark = pProt->HCIConfig.EventRecvBufferWaterMark;
493 pQueue = &pProt->HCIEventBuffers;
494 }
495
496 if (HTC_PACKET_QUEUE_DEPTH(pQueue) < watermark) {
497 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
498 ("** HCI pkt type: %d watermark hit (%d) current:%d \n",
499 pktType, watermark, HTC_PACKET_QUEUE_DEPTH(pQueue)));
500 /* call the re-fill handler */
501 pProt->HCIConfig.pHCIPktRecvRefill(pProt->HCIConfig.pContext,
502 pktType,
503 HTC_PACKET_QUEUE_DEPTH(pQueue));
504 }
505 }
506
507 } while (false);
508
509 /* check if we need to disable the receiver */
510 if (status || blockRecv) {
511 DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_DISABLE, PROC_IO_SYNC);
512 }
513
514 /* see if we need to recycle the recv buffer */
515 if (status && (pPacket != NULL)) {
516 struct htc_packet_queue queue;
517
518 if (A_EPROTO == status) {
519 DebugDumpBytes(pPacket->pBuffer, totalRecvLength, "Bad HCI-UART Recv packet");
520 }
521 /* recycle packet */
522 HTC_PACKET_RESET_RX(pPacket);
523 INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket);
524 HCI_TransportAddReceivePkts(pProt,&queue);
525 NotifyTransportFailure(pProt,status);
526 }
527
528
529 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HCIUartMessagePending \n"));
530
531 return status;
532}
533
534static void HCISendPacketCompletion(void *Context, struct htc_packet *pPacket)
535{
536 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)Context;
537 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion (pPacket:0x%lX) \n",(unsigned long)pPacket));
538
539 if (pPacket->Status) {
540 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Send Packet (0x%lX) failed: %d , len:%d \n",
541 (unsigned long)pPacket, pPacket->Status, pPacket->ActualLength));
542 }
543
544 DO_HCI_SEND_INDICATION(pProt,pPacket);
545
546 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion \n"));
547}
548
549static int SeekCreditsSynch(struct gmbox_proto_hci_uart *pProt)
550{
551 int status = 0;
552 int credits;
553 int retry = 100;
554
555 while (true) {
556 credits = 0;
557 status = DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits);
558 if (status) {
559 break;
560 }
561 LOCK_HCI_TX(pProt);
562 pProt->CreditsAvailable += credits;
563 pProt->CreditsConsumed -= credits;
564 if (pProt->CreditsAvailable >= pProt->CreditsCurrentSeek) {
565 pProt->CreditsCurrentSeek = 0;
566 UNLOCK_HCI_TX(pProt);
567 break;
568 }
569 UNLOCK_HCI_TX(pProt);
570 retry--;
571 if (0 == retry) {
572 status = A_EBUSY;
573 break;
574 }
575 A_MDELAY(20);
576 }
577
578 return status;
579}
580
581static int HCITrySend(struct gmbox_proto_hci_uart *pProt, struct htc_packet *pPacket, bool Synchronous)
582{
583 int status = 0;
584 int transferLength;
585 int creditsRequired, remainder;
586 u8 hciUartType;
587 bool synchSendComplete = false;
588
589 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCITrySend (pPacket:0x%lX) %s \n",(unsigned long)pPacket,
590 Synchronous ? "SYNC" :"ASYNC"));
591
592 LOCK_HCI_TX(pProt);
593
594 /* increment write processing count on entry */
595 pProt->SendProcessCount++;
596
597 do {
598
599 if (pProt->HCIStopped) {
600 status = A_ECANCELED;
601 break;
602 }
603
604 if (pPacket != NULL) {
605 /* packet was supplied */
606 if (Synchronous) {
607 /* in synchronous mode, the send queue can only hold 1 packet */
608 if (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) {
609 status = A_EBUSY;
610 A_ASSERT(false);
611 break;
612 }
613
614 if (pProt->SendProcessCount > 1) {
615 /* another thread or task is draining the TX queues */
616 status = A_EBUSY;
617 A_ASSERT(false);
618 break;
619 }
620
621 HTC_PACKET_ENQUEUE(&pProt->SendQueue,pPacket);
622
623 } else {
624 /* see if adding this packet hits the max depth (asynchronous mode only) */
625 if ((pProt->HCIConfig.MaxSendQueueDepth > 0) &&
626 ((HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue) + 1) >= pProt->HCIConfig.MaxSendQueueDepth)) {
627 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("HCI Send queue is full, Depth:%d, Max:%d \n",
628 HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue),
629 pProt->HCIConfig.MaxSendQueueDepth));
630 /* queue will be full, invoke any callbacks to determine what action to take */
631 if (pProt->HCIConfig.pHCISendFull != NULL) {
632 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
633 ("HCI : Calling driver's send full callback.... \n"));
634 if (pProt->HCIConfig.pHCISendFull(pProt->HCIConfig.pContext,
635 pPacket) == HCI_SEND_FULL_DROP) {
636 /* drop it */
637 status = A_NO_RESOURCE;
638 break;
639 }
640 }
641 }
642
643 HTC_PACKET_ENQUEUE(&pProt->SendQueue,pPacket);
644 }
645
646 }
647
648 if (pProt->SendStateFlags & HCI_SEND_WAIT_CREDITS) {
649 break;
650 }
651
652 if (pProt->SendProcessCount > 1) {
653 /* another thread or task is draining the TX queues */
654 break;
655 }
656
657 /***** beyond this point only 1 thread may enter ******/
658
659 /* now drain the send queue for transmission as long as we have enough
660 * credits */
661 while (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) {
662
663 pPacket = HTC_PACKET_DEQUEUE(&pProt->SendQueue);
664
665 switch (HCI_GET_PACKET_TYPE(pPacket)) {
666 case HCI_COMMAND_TYPE:
667 hciUartType = HCI_UART_COMMAND_PKT;
668 break;
669 case HCI_ACL_TYPE:
670 hciUartType = HCI_UART_ACL_PKT;
671 break;
672 default:
673 status = A_EINVAL;
674 A_ASSERT(false);
675 break;
676 }
677
678 if (status) {
679 break;
680 }
681
682 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Got head packet:0x%lX , Type:%d Length: %d Remaining Queue Depth: %d\n",
683 (unsigned long)pPacket, HCI_GET_PACKET_TYPE(pPacket), pPacket->ActualLength,
684 HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue)));
685
686 transferLength = 1; /* UART type header is 1 byte */
687 transferLength += pPacket->ActualLength;
688 transferLength = DEV_CALC_SEND_PADDED_LEN(pProt->pDev, transferLength);
689
690 /* figure out how many credits this message requires */
691 creditsRequired = transferLength / pProt->CreditSize;
692 remainder = transferLength % pProt->CreditSize;
693
694 if (remainder) {
695 creditsRequired++;
696 }
697
698 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Creds Required:%d Got:%d\n",
699 creditsRequired, pProt->CreditsAvailable));
700
701 if (creditsRequired > pProt->CreditsAvailable) {
702 if (Synchronous) {
703 /* in synchronous mode we need to seek credits in synchronously */
704 pProt->CreditsCurrentSeek = creditsRequired;
705 UNLOCK_HCI_TX(pProt);
706 status = SeekCreditsSynch(pProt);
707 LOCK_HCI_TX(pProt);
708 if (status) {
709 break;
710 }
711 /* fall through and continue processing this send op */
712 } else {
713 /* not enough credits, queue back to the head */
714 HTC_PACKET_ENQUEUE_TO_HEAD(&pProt->SendQueue,pPacket);
715 /* waiting for credits */
716 pProt->SendStateFlags |= HCI_SEND_WAIT_CREDITS;
717 /* provide a hint to reduce attempts to re-send if credits are dribbling back
718 * this hint is the short fall of credits */
719 pProt->CreditsCurrentSeek = creditsRequired;
720 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: packet:0x%lX placed back in queue. head packet needs: %d credits \n",
721 (unsigned long)pPacket, pProt->CreditsCurrentSeek));
722 pPacket = NULL;
723 UNLOCK_HCI_TX(pProt);
724
725 /* schedule a credit counter read, our CreditsAvailableCallback callback will be called
726 * with the result */
727 DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_ASYNC, NULL);
728
729 LOCK_HCI_TX(pProt);
730 break;
731 }
732 }
733
734 /* caller guarantees some head room */
735 pPacket->pBuffer--;
736 pPacket->pBuffer[0] = hciUartType;
737
738 pProt->CreditsAvailable -= creditsRequired;
739 pProt->CreditsConsumed += creditsRequired;
740 A_ASSERT(pProt->CreditsConsumed <= pProt->CreditsMax);
741
742 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: new credit state: consumed:%d available:%d max:%d\n",
743 pProt->CreditsConsumed, pProt->CreditsAvailable, pProt->CreditsMax));
744
745 UNLOCK_HCI_TX(pProt);
746
747 /* write it out */
748 if (Synchronous) {
749 pPacket->Completion = NULL;
750 pPacket->pContext = NULL;
751 } else {
752 pPacket->Completion = HCISendPacketCompletion;
753 pPacket->pContext = pProt;
754 }
755
756 status = DevGMboxWrite(pProt->pDev,pPacket,transferLength);
757 if (Synchronous) {
758 synchSendComplete = true;
759 } else {
760 pPacket = NULL;
761 }
762
763 LOCK_HCI_TX(pProt);
764
765 }
766
767 } while (false);
768
769 pProt->SendProcessCount--;
770 A_ASSERT(pProt->SendProcessCount >= 0);
771 UNLOCK_HCI_TX(pProt);
772
773 if (Synchronous) {
774 A_ASSERT(pPacket != NULL);
775 if (!status && (!synchSendComplete)) {
776 status = A_EBUSY;
777 A_ASSERT(false);
778 LOCK_HCI_TX(pProt);
779 if (pPacket->ListLink.pNext != NULL) {
780 /* remove from the queue */
781 HTC_PACKET_REMOVE(&pProt->SendQueue,pPacket);
782 }
783 UNLOCK_HCI_TX(pProt);
784 }
785 } else {
786 if (status && (pPacket != NULL)) {
787 pPacket->Status = status;
788 DO_HCI_SEND_INDICATION(pProt,pPacket);
789 }
790 }
791
792 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HCITrySend: \n"));
793 return status;
794}
795
796static void FlushSendQueue(struct gmbox_proto_hci_uart *pProt)
797{
798 struct htc_packet *pPacket;
799 struct htc_packet_queue discardQueue;
800
801 INIT_HTC_PACKET_QUEUE(&discardQueue);
802
803 LOCK_HCI_TX(pProt);
804
805 if (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) {
806 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->SendQueue);
807 }
808
809 UNLOCK_HCI_TX(pProt);
810
811 /* discard packets */
812 while (!HTC_QUEUE_EMPTY(&discardQueue)) {
813 pPacket = HTC_PACKET_DEQUEUE(&discardQueue);
814 pPacket->Status = A_ECANCELED;
815 DO_HCI_SEND_INDICATION(pProt,pPacket);
816 }
817
818}
819
820static void FlushRecvBuffers(struct gmbox_proto_hci_uart *pProt)
821{
822 struct htc_packet_queue discardQueue;
823 struct htc_packet *pPacket;
824
825 INIT_HTC_PACKET_QUEUE(&discardQueue);
826
827 LOCK_HCI_RX(pProt);
828 /*transfer list items from ACL and event buffer queues to the discard queue */
829 if (!HTC_QUEUE_EMPTY(&pProt->HCIACLRecvBuffers)) {
830 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->HCIACLRecvBuffers);
831 }
832 if (!HTC_QUEUE_EMPTY(&pProt->HCIEventBuffers)) {
833 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->HCIEventBuffers);
834 }
835 UNLOCK_HCI_RX(pProt);
836
837 /* now empty the discard queue */
838 while (!HTC_QUEUE_EMPTY(&discardQueue)) {
839 pPacket = HTC_PACKET_DEQUEUE(&discardQueue);
840 pPacket->Status = A_ECANCELED;
841 DO_HCI_RECV_INDICATION(pProt,pPacket);
842 }
843
844}
845
846/*** protocol module install entry point ***/
847
848int GMboxProtocolInstall(struct ar6k_device *pDev)
849{
850 int status = 0;
851 struct gmbox_proto_hci_uart *pProtocol = NULL;
852
853 do {
854
855 pProtocol = A_MALLOC(sizeof(struct gmbox_proto_hci_uart));
856
857 if (NULL == pProtocol) {
858 status = A_NO_MEMORY;
859 break;
860 }
861
862 A_MEMZERO(pProtocol, sizeof(*pProtocol));
863 pProtocol->pDev = pDev;
864 INIT_HTC_PACKET_QUEUE(&pProtocol->SendQueue);
865 INIT_HTC_PACKET_QUEUE(&pProtocol->HCIACLRecvBuffers);
866 INIT_HTC_PACKET_QUEUE(&pProtocol->HCIEventBuffers);
867 A_MUTEX_INIT(&pProtocol->HCIRxLock);
868 A_MUTEX_INIT(&pProtocol->HCITxLock);
869
870 } while (false);
871
872 if (!status) {
873 LOCK_AR6K(pDev);
874 DEV_GMBOX_SET_PROTOCOL(pDev,
875 HCIUartMessagePending,
876 CreditsAvailableCallback,
877 FailureCallback,
878 StateDumpCallback,
879 pProtocol);
880 UNLOCK_AR6K(pDev);
881 } else {
882 if (pProtocol != NULL) {
883 HCIUartCleanup(pProtocol);
884 }
885 }
886
887 return status;
888}
889
890/*** protocol module uninstall entry point ***/
891void GMboxProtocolUninstall(struct ar6k_device *pDev)
892{
893 struct gmbox_proto_hci_uart *pProtocol = (struct gmbox_proto_hci_uart *)DEV_GMBOX_GET_PROTOCOL(pDev);
894
895 if (pProtocol != NULL) {
896
897 /* notify anyone attached */
898 if (pProtocol->HCIAttached) {
899 A_ASSERT(pProtocol->HCIConfig.TransportRemoved != NULL);
900 pProtocol->HCIConfig.TransportRemoved(pProtocol->HCIConfig.pContext);
901 pProtocol->HCIAttached = false;
902 }
903
904 HCIUartCleanup(pProtocol);
905 DEV_GMBOX_SET_PROTOCOL(pDev,NULL,NULL,NULL,NULL,NULL);
906 }
907
908}
909
910static int NotifyTransportReady(struct gmbox_proto_hci_uart *pProt)
911{
912 struct hci_transport_properties props;
913 int status = 0;
914
915 do {
916
917 A_MEMZERO(&props,sizeof(props));
918
919 /* HCI UART only needs one extra byte at the head to indicate the packet TYPE */
920 props.HeadRoom = 1;
921 props.TailRoom = 0;
922 props.IOBlockPad = pProt->pDev->BlockSize;
923 if (pProt->HCIAttached) {
924 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HCI: notifying attached client to transport... \n"));
925 A_ASSERT(pProt->HCIConfig.TransportReady != NULL);
926 status = pProt->HCIConfig.TransportReady(pProt,
927 &props,
928 pProt->HCIConfig.pContext);
929 }
930
931 } while (false);
932
933 return status;
934}
935
936/*********** HCI UART protocol implementation ************************************************/
937
938HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, struct hci_transport_config_info *pInfo)
939{
940 struct gmbox_proto_hci_uart *pProtocol = NULL;
941 struct ar6k_device *pDev;
942
943 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportAttach \n"));
944
945 pDev = HTCGetAR6KDevice(HTCHandle);
946
947 LOCK_AR6K(pDev);
948
949 do {
950
951 pProtocol = (struct gmbox_proto_hci_uart *)DEV_GMBOX_GET_PROTOCOL(pDev);
952
953 if (NULL == pProtocol) {
954 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol not installed! \n"));
955 break;
956 }
957
958 if (pProtocol->HCIAttached) {
959 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol already attached! \n"));
960 break;
961 }
962
963 memcpy(&pProtocol->HCIConfig, pInfo, sizeof(struct hci_transport_config_info));
964
965 A_ASSERT(pProtocol->HCIConfig.pHCIPktRecv != NULL);
966 A_ASSERT(pProtocol->HCIConfig.pHCISendComplete != NULL);
967
968 pProtocol->HCIAttached = true;
969
970 } while (false);
971
972 UNLOCK_AR6K(pDev);
973
974 if (pProtocol != NULL) {
975 /* TODO ... should we use a worker? */
976 NotifyTransportReady(pProtocol);
977 }
978
979 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportAttach (0x%lX) \n",(unsigned long)pProtocol));
980 return (HCI_TRANSPORT_HANDLE)pProtocol;
981}
982
983void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans)
984{
985 struct gmbox_proto_hci_uart *pProtocol = (struct gmbox_proto_hci_uart *)HciTrans;
986 struct ar6k_device *pDev = pProtocol->pDev;
987
988 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportDetach \n"));
989
990 LOCK_AR6K(pDev);
991 if (!pProtocol->HCIAttached) {
992 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol not attached! \n"));
993 UNLOCK_AR6K(pDev);
994 return;
995 }
996 pProtocol->HCIAttached = false;
997 UNLOCK_AR6K(pDev);
998
999 HCI_TransportStop(HciTrans);
1000 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportAttach \n"));
1001}
1002
1003int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue)
1004{
1005 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1006 int status = 0;
1007 bool unblockRecv = false;
1008 struct htc_packet *pPacket;
1009
1010 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HCI_TransportAddReceivePkt \n"));
1011
1012 LOCK_HCI_RX(pProt);
1013
1014 do {
1015
1016 if (pProt->HCIStopped) {
1017 status = A_ECANCELED;
1018 break;
1019 }
1020
1021 pPacket = HTC_GET_PKT_AT_HEAD(pQueue);
1022
1023 if (NULL == pPacket) {
1024 status = A_EINVAL;
1025 break;
1026 }
1027
1028 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" HCI recv packet added, type :%d, len:%d num:%d \n",
1029 HCI_GET_PACKET_TYPE(pPacket), pPacket->BufferLength, HTC_PACKET_QUEUE_DEPTH(pQueue)));
1030
1031 if (HCI_GET_PACKET_TYPE(pPacket) == HCI_EVENT_TYPE) {
1032 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pProt->HCIEventBuffers, pQueue);
1033 } else if (HCI_GET_PACKET_TYPE(pPacket) == HCI_ACL_TYPE) {
1034 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pProt->HCIACLRecvBuffers, pQueue);
1035 } else {
1036 status = A_EINVAL;
1037 break;
1038 }
1039
1040 if (pProt->RecvStateFlags & HCI_RECV_WAIT_BUFFERS) {
1041 if (pProt->WaitBufferType == HCI_GET_PACKET_TYPE(pPacket)) {
1042 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" HCI recv was blocked on packet type :%d, unblocking.. \n",
1043 pProt->WaitBufferType));
1044 pProt->RecvStateFlags &= ~HCI_RECV_WAIT_BUFFERS;
1045 pProt->WaitBufferType = HCI_PACKET_INVALID;
1046 unblockRecv = true;
1047 }
1048 }
1049
1050 } while (false);
1051
1052 UNLOCK_HCI_RX(pProt);
1053
1054 if (status) {
1055 while (!HTC_QUEUE_EMPTY(pQueue)) {
1056 pPacket = HTC_PACKET_DEQUEUE(pQueue);
1057 pPacket->Status = A_ECANCELED;
1058 DO_HCI_RECV_INDICATION(pProt,pPacket);
1059 }
1060 }
1061
1062 if (unblockRecv) {
1063 DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_ENABLE, PROC_IO_ASYNC);
1064 }
1065
1066 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HCI_TransportAddReceivePkt \n"));
1067
1068 return 0;
1069}
1070
1071int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous)
1072{
1073 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1074
1075 return HCITrySend(pProt,pPacket,Synchronous);
1076}
1077
1078void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans)
1079{
1080 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1081
1082 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStop \n"));
1083
1084 LOCK_AR6K(pProt->pDev);
1085 if (pProt->HCIStopped) {
1086 UNLOCK_AR6K(pProt->pDev);
1087 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStop \n"));
1088 return;
1089 }
1090 pProt->HCIStopped = true;
1091 UNLOCK_AR6K(pProt->pDev);
1092
1093 /* disable interrupts */
1094 DevGMboxIRQAction(pProt->pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC);
1095 FlushSendQueue(pProt);
1096 FlushRecvBuffers(pProt);
1097
1098 /* signal bridge side to power down BT */
1099 DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BT_OFF, BTOFF_TIMEOUT_MS);
1100
1101 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStop \n"));
1102}
1103
1104int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans)
1105{
1106 int status;
1107 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1108
1109 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStart \n"));
1110
1111 /* set stopped in case we have a problem in starting */
1112 pProt->HCIStopped = true;
1113
1114 do {
1115
1116 status = InitTxCreditState(pProt);
1117
1118 if (status) {
1119 break;
1120 }
1121
1122 status = DevGMboxIRQAction(pProt->pDev, GMBOX_ERRORS_IRQ_ENABLE, PROC_IO_SYNC);
1123
1124 if (status) {
1125 break;
1126 }
1127 /* enable recv */
1128 status = DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_ENABLE, PROC_IO_SYNC);
1129
1130 if (status) {
1131 break;
1132 }
1133 /* signal bridge side to power up BT */
1134 status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BT_ON, BTON_TIMEOUT_MS);
1135
1136 if (status) {
1137 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI_TransportStart : Failed to trigger BT ON \n"));
1138 break;
1139 }
1140
1141 /* we made it */
1142 pProt->HCIStopped = false;
1143
1144 } while (false);
1145
1146 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStart \n"));
1147
1148 return status;
1149}
1150
1151int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool Enable)
1152{
1153 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1154 return DevGMboxIRQAction(pProt->pDev,
1155 Enable ? GMBOX_RECV_IRQ_ENABLE : GMBOX_RECV_IRQ_DISABLE,
1156 PROC_IO_SYNC);
1157
1158}
1159
1160int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans,
1161 struct htc_packet *pPacket,
1162 int MaxPollMS)
1163{
1164 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1165 int status = 0;
1166 u8 lookAhead[8];
1167 int bytes;
1168 int totalRecvLength;
1169
1170 MaxPollMS = MaxPollMS / 16;
1171
1172 if (MaxPollMS < 2) {
1173 MaxPollMS = 2;
1174 }
1175
1176 while (MaxPollMS) {
1177
1178 bytes = sizeof(lookAhead);
1179 status = DevGMboxRecvLookAheadPeek(pProt->pDev,lookAhead,&bytes);
1180 if (status) {
1181 break;
1182 }
1183
1184 if (bytes < 3) {
1185 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI recv poll got bytes: %d, retry : %d \n",
1186 bytes, MaxPollMS));
1187 A_MDELAY(16);
1188 MaxPollMS--;
1189 continue;
1190 }
1191
1192 totalRecvLength = 0;
1193 switch (lookAhead[0]) {
1194 case HCI_UART_EVENT_PKT:
1195 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI Event: %d param length: %d \n",
1196 lookAhead[1], lookAhead[2]));
1197 totalRecvLength = lookAhead[2];
1198 totalRecvLength += 3; /* add type + event code + length field */
1199 break;
1200 default:
1201 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("**Invalid HCI packet type: %d \n",lookAhead[0]));
1202 status = A_EPROTO;
1203 break;
1204 }
1205
1206 if (status) {
1207 break;
1208 }
1209
1210 pPacket->Completion = NULL;
1211 status = DevGMboxRead(pProt->pDev,pPacket,totalRecvLength);
1212 if (status) {
1213 break;
1214 }
1215
1216 pPacket->pBuffer++;
1217 pPacket->ActualLength = totalRecvLength - 1;
1218 pPacket->Status = 0;
1219 break;
1220 }
1221
1222 if (MaxPollMS == 0) {
1223 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI recv poll timeout! \n"));
1224 status = A_ERROR;
1225 }
1226
1227 return status;
1228}
1229
1230#define LSB_SCRATCH_IDX 4
1231#define MSB_SCRATCH_IDX 5
1232int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud)
1233{
1234 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1235 struct hif_device *pHIFDevice = (struct hif_device *)(pProt->pDev->HIFDevice);
1236 u32 scaledBaud, scratchAddr;
1237 int status = 0;
1238
1239 /* Divide the desired baud rate by 100
1240 * Store the LSB in the local scratch register 4 and the MSB in the local
1241 * scratch register 5 for the target to read
1242 */
1243 scratchAddr = MBOX_BASE_ADDRESS | (LOCAL_SCRATCH_ADDRESS + 4 * LSB_SCRATCH_IDX);
1244 scaledBaud = (Baud / 100) & LOCAL_SCRATCH_VALUE_MASK;
1245 status = ar6000_WriteRegDiag(pHIFDevice, &scratchAddr, &scaledBaud);
1246 scratchAddr = MBOX_BASE_ADDRESS | (LOCAL_SCRATCH_ADDRESS + 4 * MSB_SCRATCH_IDX);
1247 scaledBaud = ((Baud / 100) >> (LOCAL_SCRATCH_VALUE_MSB+1)) & LOCAL_SCRATCH_VALUE_MASK;
1248 status |= ar6000_WriteRegDiag(pHIFDevice, &scratchAddr, &scaledBaud);
1249 if (0 != status) {
1250 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to set up baud rate in scratch register!"));
1251 return status;
1252 }
1253
1254 /* Now interrupt the target to tell it about the baud rate */
1255 status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BAUD_SET, BAUD_TIMEOUT_MS);
1256 if (0 != status) {
1257 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to tell target to change baud rate!"));
1258 }
1259
1260 return status;
1261}
1262
1263int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, bool Enable)
1264{
1265 int status;
1266 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1267
1268 if (Enable) {
1269 status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_PWR_SAV_ON, BTPWRSAV_TIMEOUT_MS);
1270 } else {
1271 status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF, BTPWRSAV_TIMEOUT_MS);
1272 }
1273
1274 if (status) {
1275 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to enable/disable HCI power management!\n"));
1276 } else {
1277 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI power management enabled/disabled!\n"));
1278 }
1279
1280 return status;
1281}
1282
1283#endif //ATH_AR6K_ENABLE_GMBOX
1284
diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c
deleted file mode 100644
index ae54e64b624..00000000000
--- a/drivers/staging/ath6kl/htc2/htc.c
+++ /dev/null
@@ -1,575 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#include "htc_internal.h"
24
25#ifdef ATH_DEBUG_MODULE
26static struct ath_debug_mask_description g_HTCDebugDescription[] = {
27 { ATH_DEBUG_SEND , "Send"},
28 { ATH_DEBUG_RECV , "Recv"},
29 { ATH_DEBUG_SYNC , "Sync"},
30 { ATH_DEBUG_DUMP , "Dump Data (RX or TX)"},
31 { ATH_DEBUG_IRQ , "Interrupt Processing"}
32};
33
34ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc,
35 "htc",
36 "Host Target Communications",
37 ATH_DEBUG_MASK_DEFAULTS,
38 ATH_DEBUG_DESCRIPTION_COUNT(g_HTCDebugDescription),
39 g_HTCDebugDescription);
40
41#endif
42
43static void HTCReportFailure(void *Context);
44static void ResetEndpointStates(struct htc_target *target);
45
46void HTCFreeControlBuffer(struct htc_target *target, struct htc_packet *pPacket, struct htc_packet_queue *pList)
47{
48 LOCK_HTC(target);
49 HTC_PACKET_ENQUEUE(pList,pPacket);
50 UNLOCK_HTC(target);
51}
52
53struct htc_packet *HTCAllocControlBuffer(struct htc_target *target, struct htc_packet_queue *pList)
54{
55 struct htc_packet *pPacket;
56
57 LOCK_HTC(target);
58 pPacket = HTC_PACKET_DEQUEUE(pList);
59 UNLOCK_HTC(target);
60
61 return pPacket;
62}
63
64/* cleanup the HTC instance */
65static void HTCCleanup(struct htc_target *target)
66{
67 s32 i;
68
69 DevCleanup(&target->Device);
70
71 for (i = 0;i < NUM_CONTROL_BUFFERS;i++) {
72 if (target->HTCControlBuffers[i].Buffer) {
73 kfree(target->HTCControlBuffers[i].Buffer);
74 }
75 }
76
77 if (A_IS_MUTEX_VALID(&target->HTCLock)) {
78 A_MUTEX_DELETE(&target->HTCLock);
79 }
80
81 if (A_IS_MUTEX_VALID(&target->HTCRxLock)) {
82 A_MUTEX_DELETE(&target->HTCRxLock);
83 }
84
85 if (A_IS_MUTEX_VALID(&target->HTCTxLock)) {
86 A_MUTEX_DELETE(&target->HTCTxLock);
87 }
88 /* free our instance */
89 kfree(target);
90}
91
92/* registered target arrival callback from the HIF layer */
93HTC_HANDLE HTCCreate(void *hif_handle, struct htc_init_info *pInfo)
94{
95 struct htc_target *target = NULL;
96 int status = 0;
97 int i;
98 u32 ctrl_bufsz;
99 u32 blocksizes[HTC_MAILBOX_NUM_MAX];
100
101 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Enter\n"));
102
103 A_REGISTER_MODULE_DEBUG_INFO(htc);
104
105 do {
106
107 /* allocate target memory */
108 if ((target = (struct htc_target *)A_MALLOC(sizeof(struct htc_target))) == NULL) {
109 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
110 status = A_ERROR;
111 break;
112 }
113
114 A_MEMZERO(target, sizeof(struct htc_target));
115 A_MUTEX_INIT(&target->HTCLock);
116 A_MUTEX_INIT(&target->HTCRxLock);
117 A_MUTEX_INIT(&target->HTCTxLock);
118 INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);
119 INIT_HTC_PACKET_QUEUE(&target->ControlBufferRXFreeList);
120
121 /* give device layer the hif device handle */
122 target->Device.HIFDevice = hif_handle;
123 /* give the device layer our context (for event processing)
124 * the device layer will register it's own context with HIF
125 * so we need to set this so we can fetch it in the target remove handler */
126 target->Device.HTCContext = target;
127 /* set device layer target failure callback */
128 target->Device.TargetFailureCallback = HTCReportFailure;
129 /* set device layer recv message pending callback */
130 target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler;
131 target->EpWaitingForBuffers = ENDPOINT_MAX;
132
133 memcpy(&target->HTCInitInfo,pInfo,sizeof(struct htc_init_info));
134
135 ResetEndpointStates(target);
136
137 /* setup device layer */
138 status = DevSetup(&target->Device);
139
140 if (status) {
141 break;
142 }
143
144
145 /* get the block sizes */
146 status = HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
147 blocksizes, sizeof(blocksizes));
148 if (status) {
149 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get block size info from HIF layer...\n"));
150 break;
151 }
152
153 /* Set the control buffer size based on the block size */
154 if (blocksizes[1] > HTC_MAX_CONTROL_MESSAGE_LENGTH) {
155 ctrl_bufsz = blocksizes[1] + HTC_HDR_LENGTH;
156 } else {
157 ctrl_bufsz = HTC_MAX_CONTROL_MESSAGE_LENGTH + HTC_HDR_LENGTH;
158 }
159 for (i = 0;i < NUM_CONTROL_BUFFERS;i++) {
160 target->HTCControlBuffers[i].Buffer = A_MALLOC(ctrl_bufsz);
161 if (target->HTCControlBuffers[i].Buffer == NULL) {
162 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
163 status = A_ERROR;
164 break;
165 }
166 }
167
168 if (status) {
169 break;
170 }
171
172 /* carve up buffers/packets for control messages */
173 for (i = 0; i < NUM_CONTROL_RX_BUFFERS; i++) {
174 struct htc_packet *pControlPacket;
175 pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
176 SET_HTC_PACKET_INFO_RX_REFILL(pControlPacket,
177 target,
178 target->HTCControlBuffers[i].Buffer,
179 ctrl_bufsz,
180 ENDPOINT_0);
181 HTC_FREE_CONTROL_RX(target,pControlPacket);
182 }
183
184 for (;i < NUM_CONTROL_BUFFERS;i++) {
185 struct htc_packet *pControlPacket;
186 pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
187 INIT_HTC_PACKET_INFO(pControlPacket,
188 target->HTCControlBuffers[i].Buffer,
189 ctrl_bufsz);
190 HTC_FREE_CONTROL_TX(target,pControlPacket);
191 }
192
193 } while (false);
194
195 if (status) {
196 if (target != NULL) {
197 HTCCleanup(target);
198 target = NULL;
199 }
200 }
201
202 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Exit\n"));
203
204 return target;
205}
206
207void HTCDestroy(HTC_HANDLE HTCHandle)
208{
209 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
210 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCDestroy .. Destroying :0x%lX \n",(unsigned long)target));
211 HTCCleanup(target);
212 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCDestroy \n"));
213}
214
215/* get the low level HIF device for the caller , the caller may wish to do low level
216 * HIF requests */
217void *HTCGetHifDevice(HTC_HANDLE HTCHandle)
218{
219 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
220 return target->Device.HIFDevice;
221}
222
223/* wait for the target to arrive (sends HTC Ready message)
224 * this operation is fully synchronous and the message is polled for */
225int HTCWaitTarget(HTC_HANDLE HTCHandle)
226{
227 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
228 int status;
229 struct htc_packet *pPacket = NULL;
230 HTC_READY_EX_MSG *pRdyMsg;
231
232 struct htc_service_connect_req connect;
233 struct htc_service_connect_resp resp;
234
235 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%lX) \n", (unsigned long)target));
236
237 do {
238
239#ifdef MBOXHW_UNIT_TEST
240
241 status = DoMboxHWTest(&target->Device);
242
243 if (status) {
244 break;
245 }
246
247#endif
248
249 /* we should be getting 1 control message that the target is ready */
250 status = HTCWaitforControlMessage(target, &pPacket);
251
252 if (status) {
253 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target Not Available!!\n"));
254 break;
255 }
256
257 /* we controlled the buffer creation so it has to be properly aligned */
258 pRdyMsg = (HTC_READY_EX_MSG *)pPacket->pBuffer;
259
260 if ((pRdyMsg->Version2_0_Info.MessageID != HTC_MSG_READY_ID) ||
261 (pPacket->ActualLength < sizeof(HTC_READY_MSG))) {
262 /* this message is not valid */
263 AR_DEBUG_ASSERT(false);
264 status = A_EPROTO;
265 break;
266 }
267
268
269 if (pRdyMsg->Version2_0_Info.CreditCount == 0 || pRdyMsg->Version2_0_Info.CreditSize == 0) {
270 /* this message is not valid */
271 AR_DEBUG_ASSERT(false);
272 status = A_EPROTO;
273 break;
274 }
275
276 target->TargetCredits = pRdyMsg->Version2_0_Info.CreditCount;
277 target->TargetCreditSize = pRdyMsg->Version2_0_Info.CreditSize;
278
279 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, (" Target Ready: credits: %d credit size: %d\n",
280 target->TargetCredits, target->TargetCreditSize));
281
282 /* check if this is an extended ready message */
283 if (pPacket->ActualLength >= sizeof(HTC_READY_EX_MSG)) {
284 /* this is an extended message */
285 target->HTCTargetVersion = pRdyMsg->HTCVersion;
286 target->MaxMsgPerBundle = pRdyMsg->MaxMsgsPerHTCBundle;
287 } else {
288 /* legacy */
289 target->HTCTargetVersion = HTC_VERSION_2P0;
290 target->MaxMsgPerBundle = 0;
291 }
292
293#ifdef HTC_FORCE_LEGACY_2P0
294 /* for testing and comparison...*/
295 target->HTCTargetVersion = HTC_VERSION_2P0;
296 target->MaxMsgPerBundle = 0;
297#endif
298
299 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
300 ("Using HTC Protocol Version : %s (%d)\n ",
301 (target->HTCTargetVersion == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
302 target->HTCTargetVersion));
303
304 if (target->MaxMsgPerBundle > 0) {
305 /* limit what HTC can handle */
306 target->MaxMsgPerBundle = min(HTC_HOST_MAX_MSG_PER_BUNDLE, target->MaxMsgPerBundle);
307 /* target supports message bundling, setup device layer */
308 if (DevSetupMsgBundling(&target->Device,target->MaxMsgPerBundle)) {
309 /* device layer can't handle bundling */
310 target->MaxMsgPerBundle = 0;
311 } else {
312 /* limit bundle what the device layer can handle */
313 target->MaxMsgPerBundle = min(DEV_GET_MAX_MSG_PER_BUNDLE(&target->Device),
314 target->MaxMsgPerBundle);
315 }
316 }
317
318 if (target->MaxMsgPerBundle > 0) {
319 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
320 (" HTC bundling allowed. Max Msg Per HTC Bundle: %d\n", target->MaxMsgPerBundle));
321
322 if (DEV_GET_MAX_BUNDLE_SEND_LENGTH(&target->Device) != 0) {
323 target->SendBundlingEnabled = true;
324 }
325 if (DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device) != 0) {
326 target->RecvBundlingEnabled = true;
327 }
328
329 if (!DEV_IS_LEN_BLOCK_ALIGNED(&target->Device,target->TargetCreditSize)) {
330 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("*** Credit size: %d is not block aligned! Disabling send bundling \n",
331 target->TargetCreditSize));
332 /* disallow send bundling since the credit size is not aligned to a block size
333 * the I/O block padding will spill into the next credit buffer which is fatal */
334 target->SendBundlingEnabled = false;
335 }
336 }
337
338 /* setup our pseudo HTC control endpoint connection */
339 A_MEMZERO(&connect,sizeof(connect));
340 A_MEMZERO(&resp,sizeof(resp));
341 connect.EpCallbacks.pContext = target;
342 connect.EpCallbacks.EpTxComplete = HTCControlTxComplete;
343 connect.EpCallbacks.EpRecv = HTCControlRecv;
344 connect.EpCallbacks.EpRecvRefill = NULL; /* not needed */
345 connect.EpCallbacks.EpSendFull = NULL; /* not nedded */
346 connect.MaxSendQueueDepth = NUM_CONTROL_BUFFERS;
347 connect.ServiceID = HTC_CTRL_RSVD_SVC;
348
349 /* connect fake service */
350 status = HTCConnectService((HTC_HANDLE)target,
351 &connect,
352 &resp);
353
354 if (!status) {
355 break;
356 }
357
358 } while (false);
359
360 if (pPacket != NULL) {
361 HTC_FREE_CONTROL_RX(target,pPacket);
362 }
363
364 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit\n"));
365
366 return status;
367}
368
369
370
371/* Start HTC, enable interrupts and let the target know host has finished setup */
372int HTCStart(HTC_HANDLE HTCHandle)
373{
374 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
375 struct htc_packet *pPacket;
376 int status;
377
378 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n"));
379
380 /* make sure interrupts are disabled at the chip level,
381 * this function can be called again from a reboot of the target without shutting down HTC */
382 DevDisableInterrupts(&target->Device);
383 /* make sure state is cleared again */
384 target->OpStateFlags = 0;
385 target->RecvStateFlags = 0;
386
387 /* now that we are starting, push control receive buffers into the
388 * HTC control endpoint */
389
390 while (1) {
391 pPacket = HTC_ALLOC_CONTROL_RX(target);
392 if (NULL == pPacket) {
393 break;
394 }
395 HTCAddReceivePkt((HTC_HANDLE)target,pPacket);
396 }
397
398 do {
399
400 AR_DEBUG_ASSERT(target->InitCredits != NULL);
401 AR_DEBUG_ASSERT(target->EpCreditDistributionListHead != NULL);
402 AR_DEBUG_ASSERT(target->EpCreditDistributionListHead->pNext != NULL);
403
404 /* call init credits callback to do the distribution ,
405 * NOTE: the first entry in the distribution list is ENDPOINT_0, so
406 * we pass the start of the list after this one. */
407 target->InitCredits(target->pCredDistContext,
408 target->EpCreditDistributionListHead->pNext,
409 target->TargetCredits);
410
411#ifdef ATH_DEBUG_MODULE
412
413 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) {
414 DumpCreditDistStates(target);
415 }
416#endif
417
418 /* the caller is done connecting to services, so we can indicate to the
419 * target that the setup phase is complete */
420 status = HTCSendSetupComplete(target);
421
422 if (status) {
423 break;
424 }
425
426 /* unmask interrupts */
427 status = DevUnmaskInterrupts(&target->Device);
428
429 if (status) {
430 HTCStop(target);
431 }
432
433 } while (false);
434
435 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n"));
436 return status;
437}
438
439static void ResetEndpointStates(struct htc_target *target)
440{
441 struct htc_endpoint *pEndpoint;
442 int i;
443
444 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
445 pEndpoint = &target->EndPoint[i];
446
447 A_MEMZERO(&pEndpoint->CreditDist, sizeof(pEndpoint->CreditDist));
448 pEndpoint->ServiceID = 0;
449 pEndpoint->MaxMsgLength = 0;
450 pEndpoint->MaxTxQueueDepth = 0;
451 A_MEMZERO(&pEndpoint->EndPointStats,sizeof(pEndpoint->EndPointStats));
452 INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBuffers);
453 INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
454 INIT_HTC_PACKET_QUEUE(&pEndpoint->RecvIndicationQueue);
455 pEndpoint->target = target;
456 }
457 /* reset distribution list */
458 target->EpCreditDistributionListHead = NULL;
459}
460
461/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */
462void HTCStop(HTC_HANDLE HTCHandle)
463{
464 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
465 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n"));
466
467 LOCK_HTC(target);
468 /* mark that we are shutting down .. */
469 target->OpStateFlags |= HTC_OP_STATE_STOPPING;
470 UNLOCK_HTC(target);
471
472 /* Masking interrupts is a synchronous operation, when this function returns
473 * all pending HIF I/O has completed, we can safely flush the queues */
474 DevMaskInterrupts(&target->Device);
475
476#ifdef THREAD_X
477 //
478 // Is this delay required
479 //
480 A_MDELAY(200); // wait for IRQ process done
481#endif
482 /* flush all send packets */
483 HTCFlushSendPkts(target);
484 /* flush all recv buffers */
485 HTCFlushRecvBuffers(target);
486
487 DevCleanupMsgBundling(&target->Device);
488
489 ResetEndpointStates(target);
490
491 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n"));
492}
493
494#ifdef ATH_DEBUG_MODULE
495void HTCDumpCreditStates(HTC_HANDLE HTCHandle)
496{
497 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
498
499 LOCK_HTC_TX(target);
500
501 DumpCreditDistStates(target);
502
503 UNLOCK_HTC_TX(target);
504
505 DumpAR6KDevState(&target->Device);
506}
507#endif
508/* report a target failure from the device, this is a callback from the device layer
509 * which uses a mechanism to report errors from the target (i.e. special interrupts) */
510static void HTCReportFailure(void *Context)
511{
512 struct htc_target *target = (struct htc_target *)Context;
513
514 target->TargetFailure = true;
515
516 if (target->HTCInitInfo.TargetFailure != NULL) {
517 /* let upper layer know, it needs to call HTCStop() */
518 target->HTCInitInfo.TargetFailure(target->HTCInitInfo.pContext, A_ERROR);
519 }
520}
521
522bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle,
523 HTC_ENDPOINT_ID Endpoint,
524 HTC_ENDPOINT_STAT_ACTION Action,
525 struct htc_endpoint_stats *pStats)
526{
527
528 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
529 bool clearStats = false;
530 bool sample = false;
531
532 switch (Action) {
533 case HTC_EP_STAT_SAMPLE :
534 sample = true;
535 break;
536 case HTC_EP_STAT_SAMPLE_AND_CLEAR :
537 sample = true;
538 clearStats = true;
539 break;
540 case HTC_EP_STAT_CLEAR :
541 clearStats = true;
542 break;
543 default:
544 break;
545 }
546
547 A_ASSERT(Endpoint < ENDPOINT_MAX);
548
549 /* lock out TX and RX while we sample and/or clear */
550 LOCK_HTC_TX(target);
551 LOCK_HTC_RX(target);
552
553 if (sample) {
554 A_ASSERT(pStats != NULL);
555 /* return the stats to the caller */
556 memcpy(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(struct htc_endpoint_stats));
557 }
558
559 if (clearStats) {
560 /* reset stats */
561 A_MEMZERO(&target->EndPoint[Endpoint].EndPointStats, sizeof(struct htc_endpoint_stats));
562 }
563
564 UNLOCK_HTC_RX(target);
565 UNLOCK_HTC_TX(target);
566
567 return true;
568}
569
570struct ar6k_device *HTCGetAR6KDevice(void *HTCHandle)
571{
572 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
573 return &target->Device;
574}
575
diff --git a/drivers/staging/ath6kl/htc2/htc_debug.h b/drivers/staging/ath6kl/htc2/htc_debug.h
deleted file mode 100644
index 8455703e221..00000000000
--- a/drivers/staging/ath6kl/htc2/htc_debug.h
+++ /dev/null
@@ -1,38 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_debug.h" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef HTC_DEBUG_H_
24#define HTC_DEBUG_H_
25
26#define ATH_MODULE_NAME htc
27#include "a_debug.h"
28
29/* ------- Debug related stuff ------- */
30
31#define ATH_DEBUG_SEND ATH_DEBUG_MAKE_MODULE_MASK(0)
32#define ATH_DEBUG_RECV ATH_DEBUG_MAKE_MODULE_MASK(1)
33#define ATH_DEBUG_SYNC ATH_DEBUG_MAKE_MODULE_MASK(2)
34#define ATH_DEBUG_DUMP ATH_DEBUG_MAKE_MODULE_MASK(3)
35#define ATH_DEBUG_IRQ ATH_DEBUG_MAKE_MODULE_MASK(4)
36
37
38#endif /*HTC_DEBUG_H_*/
diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h
deleted file mode 100644
index cac97351769..00000000000
--- a/drivers/staging/ath6kl/htc2/htc_internal.h
+++ /dev/null
@@ -1,211 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_internal.h" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _HTC_INTERNAL_H_
24#define _HTC_INTERNAL_H_
25
26/* for debugging, uncomment this to capture the last frame header, on frame header
27 * processing errors, the last frame header is dump for comparison */
28//#define HTC_CAPTURE_LAST_FRAME
29
30
31#ifdef __cplusplus
32extern "C" {
33#endif /* __cplusplus */
34
35/* Header files */
36
37#include "a_config.h"
38#include "athdefs.h"
39#include "a_osapi.h"
40#include "htc_debug.h"
41#include "htc.h"
42#include "htc_api.h"
43#include "bmi_msg.h"
44#include "hif.h"
45#include "AR6000/ar6k.h"
46
47/* HTC operational parameters */
48#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */
49#define HTC_TARGET_DEBUG_INTR_MASK 0x01
50#define HTC_TARGET_CREDIT_INTR_MASK 0xF0
51
52#define HTC_HOST_MAX_MSG_PER_BUNDLE 8
53#define HTC_MIN_HTC_MSGS_TO_BUNDLE 2
54
55/* packet flags */
56
57#define HTC_RX_PKT_IGNORE_LOOKAHEAD (1 << 0)
58#define HTC_RX_PKT_REFRESH_HDR (1 << 1)
59#define HTC_RX_PKT_PART_OF_BUNDLE (1 << 2)
60#define HTC_RX_PKT_NO_RECYCLE (1 << 3)
61
62/* scatter request flags */
63
64#define HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE (1 << 0)
65
66struct htc_endpoint {
67 HTC_ENDPOINT_ID Id;
68 HTC_SERVICE_ID ServiceID; /* service ID this endpoint is bound to
69 non-zero value means this endpoint is in use */
70 struct htc_packet_queue TxQueue; /* HTC frame buffer TX queue */
71 struct htc_packet_queue RxBuffers; /* HTC frame buffer RX list */
72 struct htc_endpoint_credit_dist CreditDist; /* credit distribution structure (exposed to driver layer) */
73 struct htc_ep_callbacks EpCallBacks; /* callbacks associated with this endpoint */
74 int MaxTxQueueDepth; /* max depth of the TX queue before we need to
75 call driver's full handler */
76 int MaxMsgLength; /* max length of endpoint message */
77 int TxProcessCount; /* reference count to continue tx processing */
78 struct htc_packet_queue RecvIndicationQueue; /* recv packets ready to be indicated */
79 int RxProcessCount; /* reference count to allow single processing context */
80 struct htc_target *target; /* back pointer to target */
81 u8 SeqNo; /* TX seq no (helpful) for debugging */
82 u32 LocalConnectionFlags; /* local connection flags */
83 struct htc_endpoint_stats EndPointStats; /* endpoint statistics */
84};
85
86#define INC_HTC_EP_STAT(p,stat,count) (p)->EndPointStats.stat += (count);
87#define HTC_SERVICE_TX_PACKET_TAG HTC_TX_PACKET_TAG_INTERNAL
88
89#define NUM_CONTROL_BUFFERS 8
90#define NUM_CONTROL_TX_BUFFERS 2
91#define NUM_CONTROL_RX_BUFFERS (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS)
92
93struct htc_control_buffer {
94 struct htc_packet HtcPacket;
95 u8 *Buffer;
96};
97
98#define HTC_RECV_WAIT_BUFFERS (1 << 0)
99#define HTC_OP_STATE_STOPPING (1 << 0)
100
101/* our HTC target state */
102struct htc_target {
103 struct htc_endpoint EndPoint[ENDPOINT_MAX];
104 struct htc_control_buffer HTCControlBuffers[NUM_CONTROL_BUFFERS];
105 struct htc_endpoint_credit_dist *EpCreditDistributionListHead;
106 struct htc_packet_queue ControlBufferTXFreeList;
107 struct htc_packet_queue ControlBufferRXFreeList;
108 HTC_CREDIT_DIST_CALLBACK DistributeCredits;
109 HTC_CREDIT_INIT_CALLBACK InitCredits;
110 void *pCredDistContext;
111 int TargetCredits;
112 unsigned int TargetCreditSize;
113 A_MUTEX_T HTCLock;
114 A_MUTEX_T HTCRxLock;
115 A_MUTEX_T HTCTxLock;
116 struct ar6k_device Device; /* AR6K - specific state */
117 u32 OpStateFlags;
118 u32 RecvStateFlags;
119 HTC_ENDPOINT_ID EpWaitingForBuffers;
120 bool TargetFailure;
121#ifdef HTC_CAPTURE_LAST_FRAME
122 struct htc_frame_hdr LastFrameHdr; /* useful for debugging */
123 u8 LastTrailer[256];
124 u8 LastTrailerLength;
125#endif
126 struct htc_init_info HTCInitInfo;
127 u8 HTCTargetVersion;
128 int MaxMsgPerBundle; /* max messages per bundle for HTC */
129 bool SendBundlingEnabled; /* run time enable for send bundling (dynamic) */
130 int RecvBundlingEnabled; /* run time enable for recv bundling (dynamic) */
131};
132
133#define HTC_STOPPING(t) ((t)->OpStateFlags & HTC_OP_STATE_STOPPING)
134#define LOCK_HTC(t) A_MUTEX_LOCK(&(t)->HTCLock);
135#define UNLOCK_HTC(t) A_MUTEX_UNLOCK(&(t)->HTCLock);
136#define LOCK_HTC_RX(t) A_MUTEX_LOCK(&(t)->HTCRxLock);
137#define UNLOCK_HTC_RX(t) A_MUTEX_UNLOCK(&(t)->HTCRxLock);
138#define LOCK_HTC_TX(t) A_MUTEX_LOCK(&(t)->HTCTxLock);
139#define UNLOCK_HTC_TX(t) A_MUTEX_UNLOCK(&(t)->HTCTxLock);
140
141#define GET_HTC_TARGET_FROM_HANDLE(hnd) ((struct htc_target *)(hnd))
142#define HTC_RECYCLE_RX_PKT(target,p,e) \
143{ \
144 if ((p)->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_NO_RECYCLE) { \
145 HTC_PACKET_RESET_RX(pPacket); \
146 pPacket->Status = A_ECANCELED; \
147 (e)->EpCallBacks.EpRecv((e)->EpCallBacks.pContext, \
148 (p)); \
149 } else { \
150 HTC_PACKET_RESET_RX(pPacket); \
151 HTCAddReceivePkt((HTC_HANDLE)(target),(p)); \
152 } \
153}
154
155/* internal HTC functions */
156void HTCControlTxComplete(void *Context, struct htc_packet *pPacket);
157void HTCControlRecv(void *Context, struct htc_packet *pPacket);
158int HTCWaitforControlMessage(struct htc_target *target, struct htc_packet **ppControlPacket);
159struct htc_packet *HTCAllocControlBuffer(struct htc_target *target, struct htc_packet_queue *pList);
160void HTCFreeControlBuffer(struct htc_target *target, struct htc_packet *pPacket, struct htc_packet_queue *pList);
161int HTCIssueSend(struct htc_target *target, struct htc_packet *pPacket);
162void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket);
163int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched);
164void HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint);
165int HTCSendSetupComplete(struct htc_target *target);
166void HTCFlushRecvBuffers(struct htc_target *target);
167void HTCFlushSendPkts(struct htc_target *target);
168
169#ifdef ATH_DEBUG_MODULE
170void DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist);
171void DumpCreditDistStates(struct htc_target *target);
172void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription);
173#endif
174
175static INLINE struct htc_packet *HTC_ALLOC_CONTROL_TX(struct htc_target *target) {
176 struct htc_packet *pPacket = HTCAllocControlBuffer(target,&target->ControlBufferTXFreeList);
177 if (pPacket != NULL) {
178 /* set payload pointer area with some headroom */
179 pPacket->pBuffer = pPacket->pBufferStart + HTC_HDR_LENGTH;
180 }
181 return pPacket;
182}
183
184#define HTC_FREE_CONTROL_TX(t,p) HTCFreeControlBuffer((t),(p),&(t)->ControlBufferTXFreeList)
185#define HTC_ALLOC_CONTROL_RX(t) HTCAllocControlBuffer((t),&(t)->ControlBufferRXFreeList)
186#define HTC_FREE_CONTROL_RX(t,p) \
187{ \
188 HTC_PACKET_RESET_RX(p); \
189 HTCFreeControlBuffer((t),(p),&(t)->ControlBufferRXFreeList); \
190}
191
192#define HTC_PREPARE_SEND_PKT(pP,sendflags,ctrl0,ctrl1) \
193{ \
194 u8 *pHdrBuf; \
195 (pP)->pBuffer -= HTC_HDR_LENGTH; \
196 pHdrBuf = (pP)->pBuffer; \
197 A_SET_UINT16_FIELD(pHdrBuf,struct htc_frame_hdr,PayloadLen,(u16)(pP)->ActualLength); \
198 A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,Flags,(sendflags)); \
199 A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,EndpointID, (u8)(pP)->Endpoint); \
200 A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,ControlBytes[0], (u8)(ctrl0)); \
201 A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,ControlBytes[1], (u8)(ctrl1)); \
202}
203
204#define HTC_UNPREPARE_SEND_PKT(pP) \
205 (pP)->pBuffer += HTC_HDR_LENGTH; \
206
207#ifdef __cplusplus
208}
209#endif
210
211#endif /* _HTC_INTERNAL_H_ */
diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c
deleted file mode 100644
index 974cc8cd693..00000000000
--- a/drivers/staging/ath6kl/htc2/htc_recv.c
+++ /dev/null
@@ -1,1572 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_recv.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#include "htc_internal.h"
24
25#define HTCIssueRecv(t, p) \
26 DevRecvPacket(&(t)->Device, \
27 (p), \
28 (p)->ActualLength)
29
30#define DO_RCV_COMPLETION(e,q) DoRecvCompletion(e,q)
31
32#define DUMP_RECV_PKT_INFO(pP) \
33 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC RECV packet 0x%lX (%d bytes) (hdr:0x%X) on ep : %d \n", \
34 (unsigned long)(pP), \
35 (pP)->ActualLength, \
36 (pP)->PktInfo.AsRx.ExpectedHdr, \
37 (pP)->Endpoint))
38
39#define HTC_RX_STAT_PROFILE(t,ep,numLookAheads) \
40{ \
41 INC_HTC_EP_STAT((ep), RxReceived, 1); \
42 if ((numLookAheads) == 1) { \
43 INC_HTC_EP_STAT((ep), RxLookAheads, 1); \
44 } else if ((numLookAheads) > 1) { \
45 INC_HTC_EP_STAT((ep), RxBundleLookAheads, 1); \
46 } \
47}
48
49static void DoRecvCompletion(struct htc_endpoint *pEndpoint,
50 struct htc_packet_queue *pQueueToIndicate)
51{
52
53 do {
54
55 if (HTC_QUEUE_EMPTY(pQueueToIndicate)) {
56 /* nothing to indicate */
57 break;
58 }
59
60 if (pEndpoint->EpCallBacks.EpRecvPktMultiple != NULL) {
61 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d, recv multiple callback (%d pkts) \n",
62 pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate)));
63 /* a recv multiple handler is being used, pass the queue to the handler */
64 pEndpoint->EpCallBacks.EpRecvPktMultiple(pEndpoint->EpCallBacks.pContext,
65 pQueueToIndicate);
66 INIT_HTC_PACKET_QUEUE(pQueueToIndicate);
67 } else {
68 struct htc_packet *pPacket;
69 /* using legacy EpRecv */
70 do {
71 pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate);
72 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d recv callback on packet 0x%lX \n", \
73 pEndpoint->Id, (unsigned long)(pPacket)));
74 pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext, pPacket);
75 } while (!HTC_QUEUE_EMPTY(pQueueToIndicate));
76 }
77
78 } while (false);
79
80}
81
82static INLINE int HTCProcessTrailer(struct htc_target *target,
83 u8 *pBuffer,
84 int Length,
85 u32 *pNextLookAheads,
86 int *pNumLookAheads,
87 HTC_ENDPOINT_ID FromEndpoint)
88{
89 HTC_RECORD_HDR *pRecord;
90 u8 *pRecordBuf;
91 HTC_LOOKAHEAD_REPORT *pLookAhead;
92 u8 *pOrigBuffer;
93 int origLength;
94 int status;
95
96 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessTrailer (length:%d) \n", Length));
97
98 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
99 AR_DEBUG_PRINTBUF(pBuffer,Length,"Recv Trailer");
100 }
101
102 pOrigBuffer = pBuffer;
103 origLength = Length;
104 status = 0;
105
106 while (Length > 0) {
107
108 if (Length < sizeof(HTC_RECORD_HDR)) {
109 status = A_EPROTO;
110 break;
111 }
112 /* these are byte aligned structs */
113 pRecord = (HTC_RECORD_HDR *)pBuffer;
114 Length -= sizeof(HTC_RECORD_HDR);
115 pBuffer += sizeof(HTC_RECORD_HDR);
116
117 if (pRecord->Length > Length) {
118 /* no room left in buffer for record */
119 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
120 (" invalid record length: %d (id:%d) buffer has: %d bytes left \n",
121 pRecord->Length, pRecord->RecordID, Length));
122 status = A_EPROTO;
123 break;
124 }
125 /* start of record follows the header */
126 pRecordBuf = pBuffer;
127
128 switch (pRecord->RecordID) {
129 case HTC_RECORD_CREDITS:
130 AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_CREDIT_REPORT));
131 HTCProcessCreditRpt(target,
132 (HTC_CREDIT_REPORT *)pRecordBuf,
133 pRecord->Length / (sizeof(HTC_CREDIT_REPORT)),
134 FromEndpoint);
135 break;
136 case HTC_RECORD_LOOKAHEAD:
137 AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_LOOKAHEAD_REPORT));
138 pLookAhead = (HTC_LOOKAHEAD_REPORT *)pRecordBuf;
139 if ((pLookAhead->PreValid == ((~pLookAhead->PostValid) & 0xFF)) &&
140 (pNextLookAheads != NULL)) {
141
142 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
143 (" LookAhead Report Found (pre valid:0x%X, post valid:0x%X) \n",
144 pLookAhead->PreValid,
145 pLookAhead->PostValid));
146
147 /* look ahead bytes are valid, copy them over */
148 ((u8 *)(&pNextLookAheads[0]))[0] = pLookAhead->LookAhead[0];
149 ((u8 *)(&pNextLookAheads[0]))[1] = pLookAhead->LookAhead[1];
150 ((u8 *)(&pNextLookAheads[0]))[2] = pLookAhead->LookAhead[2];
151 ((u8 *)(&pNextLookAheads[0]))[3] = pLookAhead->LookAhead[3];
152
153#ifdef ATH_DEBUG_MODULE
154 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
155 DebugDumpBytes((u8 *)pNextLookAheads,4,"Next Look Ahead");
156 }
157#endif
158 /* just one normal lookahead */
159 *pNumLookAheads = 1;
160 }
161 break;
162 case HTC_RECORD_LOOKAHEAD_BUNDLE:
163 AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT));
164 if (pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT) &&
165 (pNextLookAheads != NULL)) {
166 HTC_BUNDLED_LOOKAHEAD_REPORT *pBundledLookAheadRpt;
167 int i;
168
169 pBundledLookAheadRpt = (HTC_BUNDLED_LOOKAHEAD_REPORT *)pRecordBuf;
170
171#ifdef ATH_DEBUG_MODULE
172 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
173 DebugDumpBytes(pRecordBuf,pRecord->Length,"Bundle LookAhead");
174 }
175#endif
176
177 if ((pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))) >
178 HTC_HOST_MAX_MSG_PER_BUNDLE) {
179 /* this should never happen, the target restricts the number
180 * of messages per bundle configured by the host */
181 A_ASSERT(false);
182 status = A_EPROTO;
183 break;
184 }
185
186 for (i = 0; i < (int)(pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))); i++) {
187 ((u8 *)(&pNextLookAheads[i]))[0] = pBundledLookAheadRpt->LookAhead[0];
188 ((u8 *)(&pNextLookAheads[i]))[1] = pBundledLookAheadRpt->LookAhead[1];
189 ((u8 *)(&pNextLookAheads[i]))[2] = pBundledLookAheadRpt->LookAhead[2];
190 ((u8 *)(&pNextLookAheads[i]))[3] = pBundledLookAheadRpt->LookAhead[3];
191 pBundledLookAheadRpt++;
192 }
193
194 *pNumLookAheads = i;
195 }
196 break;
197 default:
198 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" unhandled record: id:%d length:%d \n",
199 pRecord->RecordID, pRecord->Length));
200 break;
201 }
202
203 if (status) {
204 break;
205 }
206
207 /* advance buffer past this record for next time around */
208 pBuffer += pRecord->Length;
209 Length -= pRecord->Length;
210 }
211
212#ifdef ATH_DEBUG_MODULE
213 if (status) {
214 DebugDumpBytes(pOrigBuffer,origLength,"BAD Recv Trailer");
215 }
216#endif
217
218 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessTrailer \n"));
219 return status;
220
221}
222
223/* process a received message (i.e. strip off header, process any trailer data)
224 * note : locks must be released when this function is called */
225static int HTCProcessRecvHeader(struct htc_target *target,
226 struct htc_packet *pPacket,
227 u32 *pNextLookAheads,
228 int *pNumLookAheads)
229{
230 u8 temp;
231 u8 *pBuf;
232 int status = 0;
233 u16 payloadLen;
234 u32 lookAhead;
235
236 pBuf = pPacket->pBuffer;
237
238 if (pNumLookAheads != NULL) {
239 *pNumLookAheads = 0;
240 }
241
242 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessRecvHeader \n"));
243
244 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
245 AR_DEBUG_PRINTBUF(pBuf,pPacket->ActualLength,"HTC Recv PKT");
246 }
247
248 do {
249 /* note, we cannot assume the alignment of pBuffer, so we use the safe macros to
250 * retrieve 16 bit fields */
251 payloadLen = A_GET_UINT16_FIELD(pBuf, struct htc_frame_hdr, PayloadLen);
252
253 ((u8 *)&lookAhead)[0] = pBuf[0];
254 ((u8 *)&lookAhead)[1] = pBuf[1];
255 ((u8 *)&lookAhead)[2] = pBuf[2];
256 ((u8 *)&lookAhead)[3] = pBuf[3];
257
258 if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_REFRESH_HDR) {
259 /* refresh expected hdr, since this was unknown at the time we grabbed the packets
260 * as part of a bundle */
261 pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead;
262 /* refresh actual length since we now have the real header */
263 pPacket->ActualLength = payloadLen + HTC_HDR_LENGTH;
264
265 /* validate the actual header that was refreshed */
266 if (pPacket->ActualLength > pPacket->BufferLength) {
267 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
268 ("Refreshed HDR payload length (%d) in bundled RECV is invalid (hdr: 0x%X) \n",
269 payloadLen, lookAhead));
270 /* limit this to max buffer just to print out some of the buffer */
271 pPacket->ActualLength = min(pPacket->ActualLength, pPacket->BufferLength);
272 status = A_EPROTO;
273 break;
274 }
275
276 if (pPacket->Endpoint != A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, EndpointID)) {
277 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
278 ("Refreshed HDR endpoint (%d) does not match expected endpoint (%d) \n",
279 A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, EndpointID), pPacket->Endpoint));
280 status = A_EPROTO;
281 break;
282 }
283 }
284
285 if (lookAhead != pPacket->PktInfo.AsRx.ExpectedHdr) {
286 /* somehow the lookahead that gave us the full read length did not
287 * reflect the actual header in the pending message */
288 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
289 ("HTCProcessRecvHeader, lookahead mismatch! (pPkt:0x%lX flags:0x%X) \n",
290 (unsigned long)pPacket, pPacket->PktInfo.AsRx.HTCRxFlags));
291#ifdef ATH_DEBUG_MODULE
292 DebugDumpBytes((u8 *)&pPacket->PktInfo.AsRx.ExpectedHdr,4,"Expected Message LookAhead");
293 DebugDumpBytes(pBuf,sizeof(struct htc_frame_hdr),"Current Frame Header");
294#ifdef HTC_CAPTURE_LAST_FRAME
295 DebugDumpBytes((u8 *)&target->LastFrameHdr,sizeof(struct htc_frame_hdr),"Last Frame Header");
296 if (target->LastTrailerLength != 0) {
297 DebugDumpBytes(target->LastTrailer,
298 target->LastTrailerLength,
299 "Last trailer");
300 }
301#endif
302#endif
303 status = A_EPROTO;
304 break;
305 }
306
307 /* get flags */
308 temp = A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, Flags);
309
310 if (temp & HTC_FLAGS_RECV_TRAILER) {
311 /* this packet has a trailer */
312
313 /* extract the trailer length in control byte 0 */
314 temp = A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, ControlBytes[0]);
315
316 if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) {
317 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
318 ("HTCProcessRecvHeader, invalid header (payloadlength should be :%d, CB[0] is:%d) \n",
319 payloadLen, temp));
320 status = A_EPROTO;
321 break;
322 }
323
324 if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
325 /* this packet was fetched as part of an HTC bundle, the embedded lookahead is
326 * not valid since the next packet may have already been fetched as part of the
327 * bundle */
328 pNextLookAheads = NULL;
329 pNumLookAheads = NULL;
330 }
331
332 /* process trailer data that follows HDR + application payload */
333 status = HTCProcessTrailer(target,
334 (pBuf + HTC_HDR_LENGTH + payloadLen - temp),
335 temp,
336 pNextLookAheads,
337 pNumLookAheads,
338 pPacket->Endpoint);
339
340 if (status) {
341 break;
342 }
343
344#ifdef HTC_CAPTURE_LAST_FRAME
345 memcpy(target->LastTrailer, (pBuf + HTC_HDR_LENGTH + payloadLen - temp), temp);
346 target->LastTrailerLength = temp;
347#endif
348 /* trim length by trailer bytes */
349 pPacket->ActualLength -= temp;
350 }
351#ifdef HTC_CAPTURE_LAST_FRAME
352 else {
353 target->LastTrailerLength = 0;
354 }
355#endif
356
357 /* if we get to this point, the packet is good */
358 /* remove header and adjust length */
359 pPacket->pBuffer += HTC_HDR_LENGTH;
360 pPacket->ActualLength -= HTC_HDR_LENGTH;
361
362 } while (false);
363
364 if (status) {
365 /* dump the whole packet */
366#ifdef ATH_DEBUG_MODULE
367 DebugDumpBytes(pBuf,pPacket->ActualLength < 256 ? pPacket->ActualLength : 256 ,"BAD HTC Recv PKT");
368#endif
369 } else {
370#ifdef HTC_CAPTURE_LAST_FRAME
371 memcpy(&target->LastFrameHdr,pBuf,sizeof(struct htc_frame_hdr));
372#endif
373 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
374 if (pPacket->ActualLength > 0) {
375 AR_DEBUG_PRINTBUF(pPacket->pBuffer,pPacket->ActualLength,"HTC - Application Msg");
376 }
377 }
378 }
379
380 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessRecvHeader \n"));
381 return status;
382}
383
384static INLINE void HTCAsyncRecvCheckMorePackets(struct htc_target *target,
385 u32 NextLookAheads[],
386 int NumLookAheads,
387 bool CheckMoreMsgs)
388{
389 /* was there a lookahead for the next packet? */
390 if (NumLookAheads > 0) {
391 int nextStatus;
392 int fetched = 0;
393 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
394 ("HTCAsyncRecvCheckMorePackets - num lookaheads were non-zero : %d \n",
395 NumLookAheads));
396 /* force status re-check */
397 REF_IRQ_STATUS_RECHECK(&target->Device);
398 /* we have more packets, get the next packet fetch started */
399 nextStatus = HTCRecvMessagePendingHandler(target, NextLookAheads, NumLookAheads, NULL, &fetched);
400 if (A_EPROTO == nextStatus) {
401 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
402 ("Next look ahead from recv header was INVALID\n"));
403#ifdef ATH_DEBUG_MODULE
404 DebugDumpBytes((u8 *)NextLookAheads,
405 NumLookAheads * (sizeof(u32)),
406 "BAD lookaheads from lookahead report");
407#endif
408 }
409 if (!nextStatus && !fetched) {
410 /* we could not fetch any more packets due to resources */
411 DevAsyncIrqProcessComplete(&target->Device);
412 }
413 } else {
414 if (CheckMoreMsgs) {
415 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
416 ("HTCAsyncRecvCheckMorePackets - rechecking for more messages...\n"));
417 /* if we did not get anything on the look-ahead,
418 * call device layer to asynchronously re-check for messages. If we can keep the async
419 * processing going we get better performance. If there is a pending message we will keep processing
420 * messages asynchronously which should pipeline things nicely */
421 DevCheckPendingRecvMsgsAsync(&target->Device);
422 } else {
423 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("HTCAsyncRecvCheckMorePackets - no check \n"));
424 }
425 }
426
427
428}
429
430 /* unload the recv completion queue */
431static INLINE void DrainRecvIndicationQueue(struct htc_target *target, struct htc_endpoint *pEndpoint)
432{
433 struct htc_packet_queue recvCompletions;
434
435 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+DrainRecvIndicationQueue \n"));
436
437 INIT_HTC_PACKET_QUEUE(&recvCompletions);
438
439 LOCK_HTC_RX(target);
440
441 /* increment rx processing count on entry */
442 pEndpoint->RxProcessCount++;
443 if (pEndpoint->RxProcessCount > 1) {
444 pEndpoint->RxProcessCount--;
445 /* another thread or task is draining the RX completion queue on this endpoint
446 * that thread will reset the rx processing count when the queue is drained */
447 UNLOCK_HTC_RX(target);
448 return;
449 }
450
451 /******* at this point only 1 thread may enter ******/
452
453 while (true) {
454
455 /* transfer items from main recv queue to the local one so we can release the lock */
456 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&recvCompletions, &pEndpoint->RecvIndicationQueue);
457
458 if (HTC_QUEUE_EMPTY(&recvCompletions)) {
459 /* all drained */
460 break;
461 }
462
463 /* release lock while we do the recv completions
464 * other threads can now queue more recv completions */
465 UNLOCK_HTC_RX(target);
466
467 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
468 ("DrainRecvIndicationQueue : completing %d RECV packets \n",
469 HTC_PACKET_QUEUE_DEPTH(&recvCompletions)));
470 /* do completion */
471 DO_RCV_COMPLETION(pEndpoint,&recvCompletions);
472
473 /* re-acquire lock to grab some more completions */
474 LOCK_HTC_RX(target);
475 }
476
477 /* reset count */
478 pEndpoint->RxProcessCount = 0;
479 UNLOCK_HTC_RX(target);
480
481 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-DrainRecvIndicationQueue \n"));
482
483}
484
485 /* optimization for recv packets, we can indicate a "hint" that there are more
486 * single-packets to fetch on this endpoint */
487#define SET_MORE_RX_PACKET_INDICATION_FLAG(L,N,E,P) \
488 if ((N) > 0) { SetRxPacketIndicationFlags((L)[0],(E),(P)); }
489
490 /* for bundled frames, we can force the flag to indicate there are more packets */
491#define FORCE_MORE_RX_PACKET_INDICATION_FLAG(P) \
492 (P)->PktInfo.AsRx.IndicationFlags |= HTC_RX_FLAGS_INDICATE_MORE_PKTS;
493
494 /* note: this function can be called with the RX lock held */
495static INLINE void SetRxPacketIndicationFlags(u32 LookAhead,
496 struct htc_endpoint *pEndpoint,
497 struct htc_packet *pPacket)
498{
499 struct htc_frame_hdr *pHdr = (struct htc_frame_hdr *)&LookAhead;
500 /* check to see if the "next" packet is from the same endpoint of the
501 completing packet */
502 if (pHdr->EndpointID == pPacket->Endpoint) {
503 /* check that there is a buffer available to actually fetch it */
504 if (!HTC_QUEUE_EMPTY(&pEndpoint->RxBuffers)) {
505 /* provide a hint that there are more RX packets to fetch */
506 FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket);
507 }
508 }
509}
510
511
512/* asynchronous completion handler for recv packet fetching, when the device layer
513 * completes a read request, it will call this completion handler */
514void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket)
515{
516 struct htc_target *target = (struct htc_target *)Context;
517 struct htc_endpoint *pEndpoint;
518 u32 nextLookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
519 int numLookAheads = 0;
520 int status;
521 bool checkMorePkts = true;
522
523 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCRecvCompleteHandler (pkt:0x%lX, status:%d, ep:%d) \n",
524 (unsigned long)pPacket, pPacket->Status, pPacket->Endpoint));
525
526 A_ASSERT(!IS_DEV_IRQ_PROC_SYNC_MODE(&target->Device));
527 AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX);
528 pEndpoint = &target->EndPoint[pPacket->Endpoint];
529 pPacket->Completion = NULL;
530
531 /* get completion status */
532 status = pPacket->Status;
533
534 do {
535
536 if (status) {
537 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCRecvCompleteHandler: request failed (status:%d, ep:%d) \n",
538 pPacket->Status, pPacket->Endpoint));
539 break;
540 }
541 /* process the header for any trailer data */
542 status = HTCProcessRecvHeader(target,pPacket,nextLookAheads,&numLookAheads);
543
544 if (status) {
545 break;
546 }
547
548 if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
549 /* this packet was part of a bundle that had to be broken up.
550 * It was fetched one message at a time. There may be other asynchronous reads queued behind this one.
551 * Do no issue another check for more packets since the last one in the series of requests
552 * will handle it */
553 checkMorePkts = false;
554 }
555
556 DUMP_RECV_PKT_INFO(pPacket);
557 LOCK_HTC_RX(target);
558 SET_MORE_RX_PACKET_INDICATION_FLAG(nextLookAheads,numLookAheads,pEndpoint,pPacket);
559 /* we have a good packet, queue it to the completion queue */
560 HTC_PACKET_ENQUEUE(&pEndpoint->RecvIndicationQueue,pPacket);
561 HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads);
562 UNLOCK_HTC_RX(target);
563
564 /* check for more recv packets before indicating */
565 HTCAsyncRecvCheckMorePackets(target,nextLookAheads,numLookAheads,checkMorePkts);
566
567 } while (false);
568
569 if (status) {
570 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
571 ("HTCRecvCompleteHandler , message fetch failed (status = %d) \n",
572 status));
573 /* recycle this packet */
574 HTC_RECYCLE_RX_PKT(target, pPacket, pEndpoint);
575 } else {
576 /* a good packet was queued, drain the queue */
577 DrainRecvIndicationQueue(target,pEndpoint);
578 }
579
580 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCRecvCompleteHandler\n"));
581}
582
583/* synchronously wait for a control message from the target,
584 * This function is used at initialization time ONLY. At init messages
585 * on ENDPOINT 0 are expected. */
586int HTCWaitforControlMessage(struct htc_target *target, struct htc_packet **ppControlPacket)
587{
588 int status;
589 u32 lookAhead;
590 struct htc_packet *pPacket = NULL;
591 struct htc_frame_hdr *pHdr;
592
593 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCWaitforControlMessage \n"));
594
595 do {
596
597 *ppControlPacket = NULL;
598
599 /* call the polling function to see if we have a message */
600 status = DevPollMboxMsgRecv(&target->Device,
601 &lookAhead,
602 HTC_TARGET_RESPONSE_TIMEOUT);
603
604 if (status) {
605 break;
606 }
607
608 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
609 ("HTCWaitforControlMessage : lookAhead : 0x%X \n", lookAhead));
610
611 /* check the lookahead */
612 pHdr = (struct htc_frame_hdr *)&lookAhead;
613
614 if (pHdr->EndpointID != ENDPOINT_0) {
615 /* unexpected endpoint number, should be zero */
616 AR_DEBUG_ASSERT(false);
617 status = A_EPROTO;
618 break;
619 }
620
621 if (status) {
622 /* bad message */
623 AR_DEBUG_ASSERT(false);
624 status = A_EPROTO;
625 break;
626 }
627
628 pPacket = HTC_ALLOC_CONTROL_RX(target);
629
630 if (pPacket == NULL) {
631 AR_DEBUG_ASSERT(false);
632 status = A_NO_MEMORY;
633 break;
634 }
635
636 pPacket->PktInfo.AsRx.HTCRxFlags = 0;
637 pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead;
638 pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;
639
640 if (pPacket->ActualLength > pPacket->BufferLength) {
641 AR_DEBUG_ASSERT(false);
642 status = A_EPROTO;
643 break;
644 }
645
646 /* we want synchronous operation */
647 pPacket->Completion = NULL;
648
649 /* get the message from the device, this will block */
650 status = HTCIssueRecv(target, pPacket);
651
652 if (status) {
653 break;
654 }
655
656 /* process receive header */
657 status = HTCProcessRecvHeader(target,pPacket,NULL,NULL);
658
659 pPacket->Status = status;
660
661 if (status) {
662 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
663 ("HTCWaitforControlMessage, HTCProcessRecvHeader failed (status = %d) \n",
664 status));
665 break;
666 }
667
668 /* give the caller this control message packet, they are responsible to free */
669 *ppControlPacket = pPacket;
670
671 } while (false);
672
673 if (status) {
674 if (pPacket != NULL) {
675 /* cleanup buffer on error */
676 HTC_FREE_CONTROL_RX(target,pPacket);
677 }
678 }
679
680 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCWaitforControlMessage \n"));
681
682 return status;
683}
684
685static int AllocAndPrepareRxPackets(struct htc_target *target,
686 u32 LookAheads[],
687 int Messages,
688 struct htc_endpoint *pEndpoint,
689 struct htc_packet_queue *pQueue)
690{
691 int status = 0;
692 struct htc_packet *pPacket;
693 struct htc_frame_hdr *pHdr;
694 int i,j;
695 int numMessages;
696 int fullLength;
697 bool noRecycle;
698
699 /* lock RX while we assemble the packet buffers */
700 LOCK_HTC_RX(target);
701
702 for (i = 0; i < Messages; i++) {
703
704 pHdr = (struct htc_frame_hdr *)&LookAheads[i];
705
706 if (pHdr->EndpointID >= ENDPOINT_MAX) {
707 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d \n",pHdr->EndpointID));
708 /* invalid endpoint */
709 status = A_EPROTO;
710 break;
711 }
712
713 if (pHdr->EndpointID != pEndpoint->Id) {
714 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d should be : %d (index:%d)\n",
715 pHdr->EndpointID, pEndpoint->Id, i));
716 /* invalid endpoint */
717 status = A_EPROTO;
718 break;
719 }
720
721 if (pHdr->PayloadLen > HTC_MAX_PAYLOAD_LENGTH) {
722 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Payload length %d exceeds max HTC : %d !\n",
723 pHdr->PayloadLen, (u32)HTC_MAX_PAYLOAD_LENGTH));
724 status = A_EPROTO;
725 break;
726 }
727
728 if (0 == pEndpoint->ServiceID) {
729 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Endpoint %d is not connected !\n",pHdr->EndpointID));
730 /* endpoint isn't even connected */
731 status = A_EPROTO;
732 break;
733 }
734
735 if ((pHdr->Flags & HTC_FLAGS_RECV_BUNDLE_CNT_MASK) == 0) {
736 /* HTC header only indicates 1 message to fetch */
737 numMessages = 1;
738 } else {
739 /* HTC header indicates that every packet to follow has the same padded length so that it can
740 * be optimally fetched as a full bundle */
741 numMessages = (pHdr->Flags & HTC_FLAGS_RECV_BUNDLE_CNT_MASK) >> HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT;
742 /* the count doesn't include the starter frame, just a count of frames to follow */
743 numMessages++;
744 A_ASSERT(numMessages <= target->MaxMsgPerBundle);
745 INC_HTC_EP_STAT(pEndpoint, RxBundleIndFromHdr, 1);
746 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
747 ("HTC header indicates :%d messages can be fetched as a bundle \n",numMessages));
748 }
749
750 fullLength = DEV_CALC_RECV_PADDED_LEN(&target->Device,pHdr->PayloadLen + sizeof(struct htc_frame_hdr));
751
752 /* get packet buffers for each message, if there was a bundle detected in the header,
753 * use pHdr as a template to fetch all packets in the bundle */
754 for (j = 0; j < numMessages; j++) {
755
756 /* reset flag, any packets allocated using the RecvAlloc() API cannot be recycled on cleanup,
757 * they must be explicitly returned */
758 noRecycle = false;
759
760 if (pEndpoint->EpCallBacks.EpRecvAlloc != NULL) {
761 UNLOCK_HTC_RX(target);
762 noRecycle = true;
763 /* user is using a per-packet allocation callback */
764 pPacket = pEndpoint->EpCallBacks.EpRecvAlloc(pEndpoint->EpCallBacks.pContext,
765 pEndpoint->Id,
766 fullLength);
767 LOCK_HTC_RX(target);
768
769 } else if ((pEndpoint->EpCallBacks.EpRecvAllocThresh != NULL) &&
770 (fullLength > pEndpoint->EpCallBacks.RecvAllocThreshold)) {
771 INC_HTC_EP_STAT(pEndpoint,RxAllocThreshHit,1);
772 INC_HTC_EP_STAT(pEndpoint,RxAllocThreshBytes,pHdr->PayloadLen);
773 /* threshold was hit, call the special recv allocation callback */
774 UNLOCK_HTC_RX(target);
775 noRecycle = true;
776 /* user wants to allocate packets above a certain threshold */
777 pPacket = pEndpoint->EpCallBacks.EpRecvAllocThresh(pEndpoint->EpCallBacks.pContext,
778 pEndpoint->Id,
779 fullLength);
780 LOCK_HTC_RX(target);
781
782 } else {
783 /* user is using a refill handler that can refill multiple HTC buffers */
784
785 /* get a packet from the endpoint recv queue */
786 pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers);
787
788 if (NULL == pPacket) {
789 /* check for refill handler */
790 if (pEndpoint->EpCallBacks.EpRecvRefill != NULL) {
791 UNLOCK_HTC_RX(target);
792 /* call the re-fill handler */
793 pEndpoint->EpCallBacks.EpRecvRefill(pEndpoint->EpCallBacks.pContext,
794 pEndpoint->Id);
795 LOCK_HTC_RX(target);
796 /* check if we have more buffers */
797 pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers);
798 /* fall through */
799 }
800 }
801 }
802
803 if (NULL == pPacket) {
804 /* this is not an error, we simply need to mark that we are waiting for buffers.*/
805 target->RecvStateFlags |= HTC_RECV_WAIT_BUFFERS;
806 target->EpWaitingForBuffers = pEndpoint->Id;
807 status = A_NO_RESOURCE;
808 break;
809 }
810
811 AR_DEBUG_ASSERT(pPacket->Endpoint == pEndpoint->Id);
812 /* clear flags */
813 pPacket->PktInfo.AsRx.HTCRxFlags = 0;
814 pPacket->PktInfo.AsRx.IndicationFlags = 0;
815 pPacket->Status = 0;
816
817 if (noRecycle) {
818 /* flag that these packets cannot be recycled, they have to be returned to the
819 * user */
820 pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_NO_RECYCLE;
821 }
822 /* add packet to queue (also incase we need to cleanup down below) */
823 HTC_PACKET_ENQUEUE(pQueue,pPacket);
824
825 if (HTC_STOPPING(target)) {
826 status = A_ECANCELED;
827 break;
828 }
829
830 /* make sure this message can fit in the endpoint buffer */
831 if ((u32)fullLength > pPacket->BufferLength) {
832 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
833 ("Payload Length Error : header reports payload of: %d (%d) endpoint buffer size: %d \n",
834 pHdr->PayloadLen, fullLength, pPacket->BufferLength));
835 status = A_EPROTO;
836 break;
837 }
838
839 if (j > 0) {
840 /* for messages fetched in a bundle the expected lookahead is unknown since we
841 * are only using the lookahead of the first packet as a template of what to
842 * expect for lengths */
843 /* flag that once we get the real HTC header we need to refesh the information */
844 pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_REFRESH_HDR;
845 /* set it to something invalid */
846 pPacket->PktInfo.AsRx.ExpectedHdr = 0xFFFFFFFF;
847 } else {
848
849 pPacket->PktInfo.AsRx.ExpectedHdr = LookAheads[i]; /* set expected look ahead */
850 }
851 /* set the amount of data to fetch */
852 pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;
853 }
854
855 if (status) {
856 if (A_NO_RESOURCE == status) {
857 /* this is actually okay */
858 status = 0;
859 }
860 break;
861 }
862
863 }
864
865 UNLOCK_HTC_RX(target);
866
867 if (status) {
868 while (!HTC_QUEUE_EMPTY(pQueue)) {
869 pPacket = HTC_PACKET_DEQUEUE(pQueue);
870 /* recycle all allocated packets */
871 HTC_RECYCLE_RX_PKT(target,pPacket,&target->EndPoint[pPacket->Endpoint]);
872 }
873 }
874
875 return status;
876}
877
878static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq)
879{
880 int i;
881 struct htc_packet *pPacket;
882 struct htc_endpoint *pEndpoint;
883 u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
884 int numLookAheads = 0;
885 struct htc_target *target = (struct htc_target *)pScatterReq->Context;
886 int status;
887 bool partialBundle = false;
888 struct htc_packet_queue localRecvQueue;
889 bool procError = false;
890
891 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCAsyncRecvScatterCompletion TotLen: %d Entries: %d\n",
892 pScatterReq->TotalLength, pScatterReq->ValidScatterEntries));
893
894 A_ASSERT(!IS_DEV_IRQ_PROC_SYNC_MODE(&target->Device));
895
896 if (pScatterReq->CompletionStatus) {
897 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Recv Scatter Request Failed: %d \n",pScatterReq->CompletionStatus));
898 }
899
900 if (pScatterReq->CallerFlags & HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE) {
901 partialBundle = true;
902 }
903
904 DEV_FINISH_SCATTER_OPERATION(pScatterReq);
905
906 INIT_HTC_PACKET_QUEUE(&localRecvQueue);
907
908 pPacket = (struct htc_packet *)pScatterReq->ScatterList[0].pCallerContexts[0];
909 /* note: all packets in a scatter req are for the same endpoint ! */
910 pEndpoint = &target->EndPoint[pPacket->Endpoint];
911
912 /* walk through the scatter list and process */
913 /* **** NOTE: DO NOT HOLD ANY LOCKS here, HTCProcessRecvHeader can take the TX lock
914 * as it processes credit reports */
915 for (i = 0; i < pScatterReq->ValidScatterEntries; i++) {
916 pPacket = (struct htc_packet *)pScatterReq->ScatterList[i].pCallerContexts[0];
917 A_ASSERT(pPacket != NULL);
918 /* reset count, we are only interested in the look ahead in the last packet when we
919 * break out of this loop */
920 numLookAheads = 0;
921
922 if (!pScatterReq->CompletionStatus) {
923 /* process header for each of the recv packets */
924 status = HTCProcessRecvHeader(target,pPacket,lookAheads,&numLookAheads);
925 } else {
926 status = A_ERROR;
927 }
928
929 if (!status) {
930 LOCK_HTC_RX(target);
931 HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads);
932 INC_HTC_EP_STAT(pEndpoint, RxPacketsBundled, 1);
933 UNLOCK_HTC_RX(target);
934 if (i == (pScatterReq->ValidScatterEntries - 1)) {
935 /* last packet's more packets flag is set based on the lookahead */
936 SET_MORE_RX_PACKET_INDICATION_FLAG(lookAheads,numLookAheads,pEndpoint,pPacket);
937 } else {
938 /* packets in a bundle automatically have this flag set */
939 FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket);
940 }
941
942 DUMP_RECV_PKT_INFO(pPacket);
943 /* since we can't hold a lock in this loop, we insert into our local recv queue for
944 * storage until we can transfer them to the recv completion queue */
945 HTC_PACKET_ENQUEUE(&localRecvQueue,pPacket);
946
947 } else {
948 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Recv packet scatter entry %d failed (out of %d) \n",
949 i, pScatterReq->ValidScatterEntries));
950 /* recycle failed recv */
951 HTC_RECYCLE_RX_PKT(target, pPacket, pEndpoint);
952 /* set flag and continue processing the remaining scatter entries */
953 procError = true;
954 }
955
956 }
957
958 /* free scatter request */
959 DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq);
960
961 LOCK_HTC_RX(target);
962 /* transfer the packets in the local recv queue to the recv completion queue */
963 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RecvIndicationQueue, &localRecvQueue);
964
965 UNLOCK_HTC_RX(target);
966
967 if (!procError) {
968 /* pipeline the next check (asynchronously) for more packets */
969 HTCAsyncRecvCheckMorePackets(target,
970 lookAheads,
971 numLookAheads,
972 partialBundle ? false : true);
973 }
974
975 /* now drain the indication queue */
976 DrainRecvIndicationQueue(target,pEndpoint);
977
978 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCAsyncRecvScatterCompletion \n"));
979}
980
981static int HTCIssueRecvPacketBundle(struct htc_target *target,
982 struct htc_packet_queue *pRecvPktQueue,
983 struct htc_packet_queue *pSyncCompletionQueue,
984 int *pNumPacketsFetched,
985 bool PartialBundle)
986{
987 int status = 0;
988 struct hif_scatter_req *pScatterReq;
989 int i, totalLength;
990 int pktsToScatter;
991 struct htc_packet *pPacket;
992 bool asyncMode = (pSyncCompletionQueue == NULL) ? true : false;
993 int scatterSpaceRemaining = DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device);
994
995 pktsToScatter = HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue);
996 pktsToScatter = min(pktsToScatter, target->MaxMsgPerBundle);
997
998 if ((HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue) - pktsToScatter) > 0) {
999 /* we were forced to split this bundle receive operation
1000 * all packets in this partial bundle must have their lookaheads ignored */
1001 PartialBundle = true;
1002 /* this would only happen if the target ignored our max bundle limit */
1003 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
1004 ("HTCIssueRecvPacketBundle : partial bundle detected num:%d , %d \n",
1005 HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue), pktsToScatter));
1006 }
1007
1008 totalLength = 0;
1009
1010 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCIssueRecvPacketBundle (Numpackets: %d , actual : %d) \n",
1011 HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue), pktsToScatter));
1012
1013 do {
1014
1015 pScatterReq = DEV_ALLOC_SCATTER_REQ(&target->Device);
1016
1017 if (pScatterReq == NULL) {
1018 /* no scatter resources left, just let caller handle it the legacy way */
1019 break;
1020 }
1021
1022 pScatterReq->CallerFlags = 0;
1023
1024 if (PartialBundle) {
1025 /* mark that this is a partial bundle, this has special ramifications to the
1026 * scatter completion routine */
1027 pScatterReq->CallerFlags |= HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE;
1028 }
1029
1030 /* convert HTC packets to scatter list */
1031 for (i = 0; i < pktsToScatter; i++) {
1032 int paddedLength;
1033
1034 pPacket = HTC_PACKET_DEQUEUE(pRecvPktQueue);
1035 A_ASSERT(pPacket != NULL);
1036
1037 paddedLength = DEV_CALC_RECV_PADDED_LEN(&target->Device, pPacket->ActualLength);
1038
1039 if ((scatterSpaceRemaining - paddedLength) < 0) {
1040 /* exceeds what we can transfer, put the packet back */
1041 HTC_PACKET_ENQUEUE_TO_HEAD(pRecvPktQueue,pPacket);
1042 break;
1043 }
1044
1045 scatterSpaceRemaining -= paddedLength;
1046
1047 if (PartialBundle || (i < (pktsToScatter - 1))) {
1048 /* packet 0..n-1 cannot be checked for look-aheads since we are fetching a bundle
1049 * the last packet however can have it's lookahead used */
1050 pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD;
1051 }
1052
1053 /* note: 1 HTC packet per scatter entry */
1054 /* setup packet into */
1055 pScatterReq->ScatterList[i].pBuffer = pPacket->pBuffer;
1056 pScatterReq->ScatterList[i].Length = paddedLength;
1057
1058 pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_PART_OF_BUNDLE;
1059
1060 if (asyncMode) {
1061 /* save HTC packet for async completion routine */
1062 pScatterReq->ScatterList[i].pCallerContexts[0] = pPacket;
1063 } else {
1064 /* queue to caller's sync completion queue, caller will unload this when we return */
1065 HTC_PACKET_ENQUEUE(pSyncCompletionQueue,pPacket);
1066 }
1067
1068 A_ASSERT(pScatterReq->ScatterList[i].Length);
1069 totalLength += pScatterReq->ScatterList[i].Length;
1070 }
1071
1072 pScatterReq->TotalLength = totalLength;
1073 pScatterReq->ValidScatterEntries = i;
1074
1075 if (asyncMode) {
1076 pScatterReq->CompletionRoutine = HTCAsyncRecvScatterCompletion;
1077 pScatterReq->Context = target;
1078 }
1079
1080 status = DevSubmitScatterRequest(&target->Device, pScatterReq, DEV_SCATTER_READ, asyncMode);
1081
1082 if (!status) {
1083 *pNumPacketsFetched = i;
1084 }
1085
1086 if (!asyncMode) {
1087 /* free scatter request */
1088 DEV_FREE_SCATTER_REQ(&target->Device, pScatterReq);
1089 }
1090
1091 } while (false);
1092
1093 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCIssueRecvPacketBundle (status:%d) (fetched:%d) \n",
1094 status,*pNumPacketsFetched));
1095
1096 return status;
1097}
1098
1099static INLINE void CheckRecvWaterMark(struct htc_endpoint *pEndpoint)
1100{
1101 /* see if endpoint is using a refill watermark
1102 * ** no need to use a lock here, since we are only inspecting...
1103 * caller may must not hold locks when calling this function */
1104 if (pEndpoint->EpCallBacks.RecvRefillWaterMark > 0) {
1105 if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->RxBuffers) < pEndpoint->EpCallBacks.RecvRefillWaterMark) {
1106 /* call the re-fill handler before we continue */
1107 pEndpoint->EpCallBacks.EpRecvRefill(pEndpoint->EpCallBacks.pContext,
1108 pEndpoint->Id);
1109 }
1110 }
1111}
1112
1113/* callback when device layer or lookahead report parsing detects a pending message */
1114int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched)
1115{
1116 struct htc_target *target = (struct htc_target *)Context;
1117 int status = 0;
1118 struct htc_packet *pPacket;
1119 struct htc_endpoint *pEndpoint;
1120 bool asyncProc = false;
1121 u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
1122 int pktsFetched;
1123 struct htc_packet_queue recvPktQueue, syncCompletedPktsQueue;
1124 bool partialBundle;
1125 HTC_ENDPOINT_ID id;
1126 int totalFetched = 0;
1127
1128 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCRecvMessagePendingHandler NumLookAheads: %d \n",NumLookAheads));
1129
1130 if (pNumPktsFetched != NULL) {
1131 *pNumPktsFetched = 0;
1132 }
1133
1134 if (IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(&target->Device)) {
1135 /* We use async mode to get the packets if the device layer supports it.
1136 * The device layer interfaces with HIF in which HIF may have restrictions on
1137 * how interrupts are processed */
1138 asyncProc = true;
1139 }
1140
1141 if (pAsyncProc != NULL) {
1142 /* indicate to caller how we decided to process this */
1143 *pAsyncProc = asyncProc;
1144 }
1145
1146 if (NumLookAheads > HTC_HOST_MAX_MSG_PER_BUNDLE) {
1147 A_ASSERT(false);
1148 return A_EPROTO;
1149 }
1150
1151 /* on first entry copy the lookaheads into our temp array for processing */
1152 memcpy(lookAheads, MsgLookAheads, (sizeof(u32)) * NumLookAheads);
1153
1154 while (true) {
1155
1156 /* reset packets queues */
1157 INIT_HTC_PACKET_QUEUE(&recvPktQueue);
1158 INIT_HTC_PACKET_QUEUE(&syncCompletedPktsQueue);
1159
1160 if (NumLookAheads > HTC_HOST_MAX_MSG_PER_BUNDLE) {
1161 status = A_EPROTO;
1162 A_ASSERT(false);
1163 break;
1164 }
1165
1166 /* first lookahead sets the expected endpoint IDs for all packets in a bundle */
1167 id = ((struct htc_frame_hdr *)&lookAheads[0])->EndpointID;
1168 pEndpoint = &target->EndPoint[id];
1169
1170 if (id >= ENDPOINT_MAX) {
1171 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MsgPend, Invalid Endpoint in look-ahead: %d \n",id));
1172 status = A_EPROTO;
1173 break;
1174 }
1175
1176 /* try to allocate as many HTC RX packets indicated by the lookaheads
1177 * these packets are stored in the recvPkt queue */
1178 status = AllocAndPrepareRxPackets(target,
1179 lookAheads,
1180 NumLookAheads,
1181 pEndpoint,
1182 &recvPktQueue);
1183 if (status) {
1184 break;
1185 }
1186
1187 if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) >= 2) {
1188 /* a recv bundle was detected, force IRQ status re-check again */
1189 REF_IRQ_STATUS_RECHECK(&target->Device);
1190 }
1191
1192 totalFetched += HTC_PACKET_QUEUE_DEPTH(&recvPktQueue);
1193
1194 /* we've got packet buffers for all we can currently fetch,
1195 * this count is not valid anymore */
1196 NumLookAheads = 0;
1197 partialBundle = false;
1198
1199 /* now go fetch the list of HTC packets */
1200 while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {
1201
1202 pktsFetched = 0;
1203
1204 if (target->RecvBundlingEnabled && (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 1)) {
1205 /* there are enough packets to attempt a bundle transfer and recv bundling is allowed */
1206 status = HTCIssueRecvPacketBundle(target,
1207 &recvPktQueue,
1208 asyncProc ? NULL : &syncCompletedPktsQueue,
1209 &pktsFetched,
1210 partialBundle);
1211 if (status) {
1212 break;
1213 }
1214
1215 if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) != 0) {
1216 /* we couldn't fetch all packets at one time, this creates a broken
1217 * bundle */
1218 partialBundle = true;
1219 }
1220 }
1221
1222 /* see if the previous operation fetched any packets using bundling */
1223 if (0 == pktsFetched) {
1224 /* dequeue one packet */
1225 pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue);
1226 A_ASSERT(pPacket != NULL);
1227
1228 if (asyncProc) {
1229 /* we use async mode to get the packet if the device layer supports it
1230 * set our callback and context */
1231 pPacket->Completion = HTCRecvCompleteHandler;
1232 pPacket->pContext = target;
1233 } else {
1234 /* fully synchronous */
1235 pPacket->Completion = NULL;
1236 }
1237
1238 if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 0) {
1239 /* lookaheads in all packets except the last one in the bundle must be ignored */
1240 pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD;
1241 }
1242
1243 /* go fetch the packet */
1244 status = HTCIssueRecv(target, pPacket);
1245 if (status) {
1246 break;
1247 }
1248
1249 if (!asyncProc) {
1250 /* sent synchronously, queue this packet for synchronous completion */
1251 HTC_PACKET_ENQUEUE(&syncCompletedPktsQueue,pPacket);
1252 }
1253
1254 }
1255
1256 }
1257
1258 if (!status) {
1259 CheckRecvWaterMark(pEndpoint);
1260 }
1261
1262 if (asyncProc) {
1263 /* we did this asynchronously so we can get out of the loop, the asynch processing
1264 * creates a chain of requests to continue processing pending messages in the
1265 * context of callbacks */
1266 break;
1267 }
1268
1269 /* synchronous handling */
1270 if (target->Device.DSRCanYield) {
1271 /* for the SYNC case, increment count that tracks when the DSR should yield */
1272 target->Device.CurrentDSRRecvCount++;
1273 }
1274
1275 /* in the sync case, all packet buffers are now filled,
1276 * we can process each packet, check lookaheads and then repeat */
1277
1278 /* unload sync completion queue */
1279 while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
1280 struct htc_packet_queue container;
1281
1282 pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue);
1283 A_ASSERT(pPacket != NULL);
1284
1285 pEndpoint = &target->EndPoint[pPacket->Endpoint];
1286 /* reset count on each iteration, we are only interested in the last packet's lookahead
1287 * information when we break out of this loop */
1288 NumLookAheads = 0;
1289 /* process header for each of the recv packets
1290 * note: the lookahead of the last packet is useful for us to continue in this loop */
1291 status = HTCProcessRecvHeader(target,pPacket,lookAheads,&NumLookAheads);
1292 if (status) {
1293 break;
1294 }
1295
1296 if (HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
1297 /* last packet's more packets flag is set based on the lookahead */
1298 SET_MORE_RX_PACKET_INDICATION_FLAG(lookAheads,NumLookAheads,pEndpoint,pPacket);
1299 } else {
1300 /* packets in a bundle automatically have this flag set */
1301 FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket);
1302 }
1303 /* good packet, indicate it */
1304 HTC_RX_STAT_PROFILE(target,pEndpoint,NumLookAheads);
1305
1306 if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_PART_OF_BUNDLE) {
1307 INC_HTC_EP_STAT(pEndpoint, RxPacketsBundled, 1);
1308 }
1309
1310 INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
1311 DO_RCV_COMPLETION(pEndpoint,&container);
1312 }
1313
1314 if (status) {
1315 break;
1316 }
1317
1318 if (NumLookAheads == 0) {
1319 /* no more look aheads */
1320 break;
1321 }
1322
1323 /* when we process recv synchronously we need to check if we should yield and stop
1324 * fetching more packets indicated by the embedded lookaheads */
1325 if (target->Device.DSRCanYield) {
1326 if (DEV_CHECK_RECV_YIELD(&target->Device)) {
1327 /* break out, don't fetch any more packets */
1328 break;
1329 }
1330 }
1331
1332
1333 /* check whether other OS contexts have queued any WMI command/data for WLAN.
1334 * This check is needed only if WLAN Tx and Rx happens in same thread context */
1335 A_CHECK_DRV_TX();
1336
1337 /* for SYNCH processing, if we get here, we are running through the loop again due to a detected lookahead.
1338 * Set flag that we should re-check IRQ status registers again before leaving IRQ processing,
1339 * this can net better performance in high throughput situations */
1340 REF_IRQ_STATUS_RECHECK(&target->Device);
1341 }
1342
1343 if (status) {
1344 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1345 ("Failed to get pending recv messages (%d) \n",status));
1346 /* cleanup any packets we allocated but didn't use to actually fetch any packets */
1347 while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {
1348 pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue);
1349 /* clean up packets */
1350 HTC_RECYCLE_RX_PKT(target, pPacket, &target->EndPoint[pPacket->Endpoint]);
1351 }
1352 /* cleanup any packets in sync completion queue */
1353 while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
1354 pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue);
1355 /* clean up packets */
1356 HTC_RECYCLE_RX_PKT(target, pPacket, &target->EndPoint[pPacket->Endpoint]);
1357 }
1358 if (HTC_STOPPING(target)) {
1359 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
1360 (" Host is going to stop. blocking receiver for HTCStop.. \n"));
1361 DevStopRecv(&target->Device, asyncProc ? DEV_STOP_RECV_ASYNC : DEV_STOP_RECV_SYNC);
1362 }
1363 }
1364 /* before leaving, check to see if host ran out of buffers and needs to stop the
1365 * receiver */
1366 if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) {
1367 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
1368 (" Host has no RX buffers, blocking receiver to prevent overrun.. \n"));
1369 /* try to stop receive at the device layer */
1370 DevStopRecv(&target->Device, asyncProc ? DEV_STOP_RECV_ASYNC : DEV_STOP_RECV_SYNC);
1371 }
1372
1373 if (pNumPktsFetched != NULL) {
1374 *pNumPktsFetched = totalFetched;
1375 }
1376
1377 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCRecvMessagePendingHandler \n"));
1378
1379 return status;
1380}
1381
1382int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue)
1383{
1384 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1385 struct htc_endpoint *pEndpoint;
1386 bool unblockRecv = false;
1387 int status = 0;
1388 struct htc_packet *pFirstPacket;
1389
1390 pFirstPacket = HTC_GET_PKT_AT_HEAD(pPktQueue);
1391
1392 if (NULL == pFirstPacket) {
1393 A_ASSERT(false);
1394 return A_EINVAL;
1395 }
1396
1397 AR_DEBUG_ASSERT(pFirstPacket->Endpoint < ENDPOINT_MAX);
1398
1399 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
1400 ("+- HTCAddReceivePktMultiple : endPointId: %d, cnt:%d, length: %d\n",
1401 pFirstPacket->Endpoint,
1402 HTC_PACKET_QUEUE_DEPTH(pPktQueue),
1403 pFirstPacket->BufferLength));
1404
1405 do {
1406
1407 pEndpoint = &target->EndPoint[pFirstPacket->Endpoint];
1408
1409 LOCK_HTC_RX(target);
1410
1411 if (HTC_STOPPING(target)) {
1412 struct htc_packet *pPacket;
1413
1414 UNLOCK_HTC_RX(target);
1415
1416 /* walk through queue and mark each one canceled */
1417 HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) {
1418 pPacket->Status = A_ECANCELED;
1419 } HTC_PACKET_QUEUE_ITERATE_END;
1420
1421 DO_RCV_COMPLETION(pEndpoint,pPktQueue);
1422 break;
1423 }
1424
1425 /* store receive packets */
1426 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RxBuffers, pPktQueue);
1427
1428 /* check if we are blocked waiting for a new buffer */
1429 if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) {
1430 if (target->EpWaitingForBuffers == pFirstPacket->Endpoint) {
1431 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" receiver was blocked on ep:%d, unblocking.. \n",
1432 target->EpWaitingForBuffers));
1433 target->RecvStateFlags &= ~HTC_RECV_WAIT_BUFFERS;
1434 target->EpWaitingForBuffers = ENDPOINT_MAX;
1435 unblockRecv = true;
1436 }
1437 }
1438
1439 UNLOCK_HTC_RX(target);
1440
1441 if (unblockRecv && !HTC_STOPPING(target)) {
1442 /* TODO : implement a buffer threshold count? */
1443 DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
1444 }
1445
1446 } while (false);
1447
1448 return status;
1449}
1450
1451/* Makes a buffer available to the HTC module */
1452int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket)
1453{
1454 struct htc_packet_queue queue;
1455 INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket);
1456 return HTCAddReceivePktMultiple(HTCHandle, &queue);
1457}
1458
1459void HTCUnblockRecv(HTC_HANDLE HTCHandle)
1460{
1461 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1462 bool unblockRecv = false;
1463
1464 LOCK_HTC_RX(target);
1465
1466 /* check if we are blocked waiting for a new buffer */
1467 if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) {
1468 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HTCUnblockRx : receiver was blocked on ep:%d, unblocking.. \n",
1469 target->EpWaitingForBuffers));
1470 target->RecvStateFlags &= ~HTC_RECV_WAIT_BUFFERS;
1471 target->EpWaitingForBuffers = ENDPOINT_MAX;
1472 unblockRecv = true;
1473 }
1474
1475 UNLOCK_HTC_RX(target);
1476
1477 if (unblockRecv && !HTC_STOPPING(target)) {
1478 /* re-enable */
1479 DevEnableRecv(&target->Device,DEV_ENABLE_RECV_ASYNC);
1480 }
1481}
1482
1483static void HTCFlushRxQueue(struct htc_target *target, struct htc_endpoint *pEndpoint, struct htc_packet_queue *pQueue)
1484{
1485 struct htc_packet *pPacket;
1486 struct htc_packet_queue container;
1487
1488 LOCK_HTC_RX(target);
1489
1490 while (1) {
1491 pPacket = HTC_PACKET_DEQUEUE(pQueue);
1492 if (NULL == pPacket) {
1493 break;
1494 }
1495 UNLOCK_HTC_RX(target);
1496 pPacket->Status = A_ECANCELED;
1497 pPacket->ActualLength = 0;
1498 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" Flushing RX packet:0x%lX, length:%d, ep:%d \n",
1499 (unsigned long)pPacket, pPacket->BufferLength, pPacket->Endpoint));
1500 INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
1501 /* give the packet back */
1502 DO_RCV_COMPLETION(pEndpoint,&container);
1503 LOCK_HTC_RX(target);
1504 }
1505
1506 UNLOCK_HTC_RX(target);
1507}
1508
1509static void HTCFlushEndpointRX(struct htc_target *target, struct htc_endpoint *pEndpoint)
1510{
1511 /* flush any recv indications not already made */
1512 HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RecvIndicationQueue);
1513 /* flush any rx buffers */
1514 HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RxBuffers);
1515}
1516
1517void HTCFlushRecvBuffers(struct htc_target *target)
1518{
1519 struct htc_endpoint *pEndpoint;
1520 int i;
1521
1522 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
1523 pEndpoint = &target->EndPoint[i];
1524 if (pEndpoint->ServiceID == 0) {
1525 /* not in use.. */
1526 continue;
1527 }
1528 HTCFlushEndpointRX(target,pEndpoint);
1529 }
1530}
1531
1532
1533void HTCEnableRecv(HTC_HANDLE HTCHandle)
1534{
1535 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1536
1537 if (!HTC_STOPPING(target)) {
1538 /* re-enable */
1539 DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
1540 }
1541}
1542
1543void HTCDisableRecv(HTC_HANDLE HTCHandle)
1544{
1545 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1546
1547 if (!HTC_STOPPING(target)) {
1548 /* disable */
1549 DevStopRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
1550 }
1551}
1552
1553int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle,
1554 HTC_ENDPOINT_ID Endpoint)
1555{
1556 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1557 return HTC_PACKET_QUEUE_DEPTH(&(target->EndPoint[Endpoint].RxBuffers));
1558}
1559
1560int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle,
1561 u32 TimeoutInMs,
1562 bool *pbIsRecvPending)
1563{
1564 int status = 0;
1565 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1566
1567 status = DevWaitForPendingRecv(&target->Device,
1568 TimeoutInMs,
1569 pbIsRecvPending);
1570
1571 return status;
1572}
diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c
deleted file mode 100644
index 9310d4d5c99..00000000000
--- a/drivers/staging/ath6kl/htc2/htc_send.c
+++ /dev/null
@@ -1,1018 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_send.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#include "htc_internal.h"
24
25typedef enum _HTC_SEND_QUEUE_RESULT {
26 HTC_SEND_QUEUE_OK = 0, /* packet was queued */
27 HTC_SEND_QUEUE_DROP = 1, /* this packet should be dropped */
28} HTC_SEND_QUEUE_RESULT;
29
30#define DO_EP_TX_COMPLETION(ep,q) DoSendCompletion(ep,q)
31
32/* call the distribute credits callback with the distribution */
33#define DO_DISTRIBUTION(t,reason,description,pList) \
34{ \
35 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, \
36 (" calling distribute function (%s) (dfn:0x%lX, ctxt:0x%lX, dist:0x%lX) \n", \
37 (description), \
38 (unsigned long)(t)->DistributeCredits, \
39 (unsigned long)(t)->pCredDistContext, \
40 (unsigned long)pList)); \
41 (t)->DistributeCredits((t)->pCredDistContext, \
42 (pList), \
43 (reason)); \
44}
45
46static void DoSendCompletion(struct htc_endpoint *pEndpoint,
47 struct htc_packet_queue *pQueueToIndicate)
48{
49 do {
50
51 if (HTC_QUEUE_EMPTY(pQueueToIndicate)) {
52 /* nothing to indicate */
53 break;
54 }
55
56 if (pEndpoint->EpCallBacks.EpTxCompleteMultiple != NULL) {
57 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d, send complete multiple callback (%d pkts) \n",
58 pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate)));
59 /* a multiple send complete handler is being used, pass the queue to the handler */
60 pEndpoint->EpCallBacks.EpTxCompleteMultiple(pEndpoint->EpCallBacks.pContext,
61 pQueueToIndicate);
62 /* all packets are now owned by the callback, reset queue to be safe */
63 INIT_HTC_PACKET_QUEUE(pQueueToIndicate);
64 } else {
65 struct htc_packet *pPacket;
66 /* using legacy EpTxComplete */
67 do {
68 pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate);
69 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d send complete callback on packet 0x%lX \n", \
70 pEndpoint->Id, (unsigned long)(pPacket)));
71 pEndpoint->EpCallBacks.EpTxComplete(pEndpoint->EpCallBacks.pContext, pPacket);
72 } while (!HTC_QUEUE_EMPTY(pQueueToIndicate));
73 }
74
75 } while (false);
76
77}
78
79/* do final completion on sent packet */
80static INLINE void CompleteSentPacket(struct htc_target *target, struct htc_endpoint *pEndpoint, struct htc_packet *pPacket)
81{
82 pPacket->Completion = NULL;
83
84 if (pPacket->Status) {
85 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
86 ("CompleteSentPacket: request failed (status:%d, ep:%d, length:%d creds:%d) \n",
87 pPacket->Status, pPacket->Endpoint, pPacket->ActualLength, pPacket->PktInfo.AsTx.CreditsUsed));
88 /* on failure to submit, reclaim credits for this packet */
89 LOCK_HTC_TX(target);
90 pEndpoint->CreditDist.TxCreditsToDist += pPacket->PktInfo.AsTx.CreditsUsed;
91 pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
92 DO_DISTRIBUTION(target,
93 HTC_CREDIT_DIST_SEND_COMPLETE,
94 "Send Complete",
95 target->EpCreditDistributionListHead->pNext);
96 UNLOCK_HTC_TX(target);
97 }
98 /* first, fixup the head room we allocated */
99 pPacket->pBuffer += HTC_HDR_LENGTH;
100}
101
102/* our internal send packet completion handler when packets are submited to the AR6K device
103 * layer */
104static void HTCSendPktCompletionHandler(void *Context, struct htc_packet *pPacket)
105{
106 struct htc_target *target = (struct htc_target *)Context;
107 struct htc_endpoint *pEndpoint = &target->EndPoint[pPacket->Endpoint];
108 struct htc_packet_queue container;
109
110 CompleteSentPacket(target,pEndpoint,pPacket);
111 INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
112 /* do completion */
113 DO_EP_TX_COMPLETION(pEndpoint,&container);
114}
115
116int HTCIssueSend(struct htc_target *target, struct htc_packet *pPacket)
117{
118 int status;
119 bool sync = false;
120
121 if (pPacket->Completion == NULL) {
122 /* mark that this request was synchronously issued */
123 sync = true;
124 }
125
126 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
127 ("+-HTCIssueSend: transmit length : %d (%s) \n",
128 pPacket->ActualLength + (u32)HTC_HDR_LENGTH,
129 sync ? "SYNC" : "ASYNC" ));
130
131 /* send message to device */
132 status = DevSendPacket(&target->Device,
133 pPacket,
134 pPacket->ActualLength + HTC_HDR_LENGTH);
135
136 if (sync) {
137 /* use local sync variable. If this was issued asynchronously, pPacket is no longer
138 * safe to access. */
139 pPacket->pBuffer += HTC_HDR_LENGTH;
140 }
141
142 /* if this request was asynchronous, the packet completion routine will be invoked by
143 * the device layer when the HIF layer completes the request */
144
145 return status;
146}
147
148 /* get HTC send packets from the TX queue on an endpoint */
149static INLINE void GetHTCSendPackets(struct htc_target *target,
150 struct htc_endpoint *pEndpoint,
151 struct htc_packet_queue *pQueue)
152{
153 int creditsRequired;
154 int remainder;
155 u8 sendFlags;
156 struct htc_packet *pPacket;
157 unsigned int transferLength;
158
159 /****** NOTE : the TX lock is held when this function is called *****************/
160 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+GetHTCSendPackets \n"));
161
162 /* loop until we can grab as many packets out of the queue as we can */
163 while (true) {
164
165 sendFlags = 0;
166 /* get packet at head, but don't remove it */
167 pPacket = HTC_GET_PKT_AT_HEAD(&pEndpoint->TxQueue);
168 if (pPacket == NULL) {
169 break;
170 }
171
172 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Got head packet:0x%lX , Queue Depth: %d\n",
173 (unsigned long)pPacket, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
174
175 transferLength = DEV_CALC_SEND_PADDED_LEN(&target->Device, pPacket->ActualLength + HTC_HDR_LENGTH);
176
177 if (transferLength <= target->TargetCreditSize) {
178 creditsRequired = 1;
179 } else {
180 /* figure out how many credits this message requires */
181 creditsRequired = transferLength / target->TargetCreditSize;
182 remainder = transferLength % target->TargetCreditSize;
183
184 if (remainder) {
185 creditsRequired++;
186 }
187 }
188
189 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Creds Required:%d Got:%d\n",
190 creditsRequired, pEndpoint->CreditDist.TxCredits));
191
192 if (pEndpoint->CreditDist.TxCredits < creditsRequired) {
193
194 /* not enough credits */
195 if (pPacket->Endpoint == ENDPOINT_0) {
196 /* leave it in the queue */
197 break;
198 }
199 /* invoke the registered distribution function only if this is not
200 * endpoint 0, we let the driver layer provide more credits if it can.
201 * We pass the credit distribution list starting at the endpoint in question
202 * */
203
204 /* set how many credits we need */
205 pEndpoint->CreditDist.TxCreditsSeek =
206 creditsRequired - pEndpoint->CreditDist.TxCredits;
207 DO_DISTRIBUTION(target,
208 HTC_CREDIT_DIST_SEEK_CREDITS,
209 "Seek Credits",
210 &pEndpoint->CreditDist);
211 pEndpoint->CreditDist.TxCreditsSeek = 0;
212
213 if (pEndpoint->CreditDist.TxCredits < creditsRequired) {
214 /* still not enough credits to send, leave packet in the queue */
215 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
216 (" Not enough credits for ep %d leaving packet in queue..\n",
217 pPacket->Endpoint));
218 break;
219 }
220
221 }
222
223 pEndpoint->CreditDist.TxCredits -= creditsRequired;
224 INC_HTC_EP_STAT(pEndpoint, TxCreditsConsummed, creditsRequired);
225
226 /* check if we need credits back from the target */
227 if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
228 /* we are getting low on credits, see if we can ask for more from the distribution function */
229 pEndpoint->CreditDist.TxCreditsSeek =
230 pEndpoint->CreditDist.TxCreditsPerMaxMsg - pEndpoint->CreditDist.TxCredits;
231
232 DO_DISTRIBUTION(target,
233 HTC_CREDIT_DIST_SEEK_CREDITS,
234 "Seek Credits",
235 &pEndpoint->CreditDist);
236
237 pEndpoint->CreditDist.TxCreditsSeek = 0;
238 /* see if we were successful in getting more */
239 if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
240 /* tell the target we need credits ASAP! */
241 sendFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
242 INC_HTC_EP_STAT(pEndpoint, TxCreditLowIndications, 1);
243 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Host Needs Credits \n"));
244 }
245 }
246
247 /* now we can fully dequeue */
248 pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxQueue);
249 /* save the number of credits this packet consumed */
250 pPacket->PktInfo.AsTx.CreditsUsed = creditsRequired;
251 /* all TX packets are handled asynchronously */
252 pPacket->Completion = HTCSendPktCompletionHandler;
253 pPacket->pContext = target;
254 INC_HTC_EP_STAT(pEndpoint, TxIssued, 1);
255 /* save send flags */
256 pPacket->PktInfo.AsTx.SendFlags = sendFlags;
257 pPacket->PktInfo.AsTx.SeqNo = pEndpoint->SeqNo;
258 pEndpoint->SeqNo++;
259 /* queue this packet into the caller's queue */
260 HTC_PACKET_ENQUEUE(pQueue,pPacket);
261 }
262
263 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-GetHTCSendPackets \n"));
264
265}
266
267static void HTCAsyncSendScatterCompletion(struct hif_scatter_req *pScatterReq)
268{
269 int i;
270 struct htc_packet *pPacket;
271 struct htc_endpoint *pEndpoint = (struct htc_endpoint *)pScatterReq->Context;
272 struct htc_target *target = (struct htc_target *)pEndpoint->target;
273 int status = 0;
274 struct htc_packet_queue sendCompletes;
275
276 INIT_HTC_PACKET_QUEUE(&sendCompletes);
277
278 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCAsyncSendScatterCompletion TotLen: %d Entries: %d\n",
279 pScatterReq->TotalLength, pScatterReq->ValidScatterEntries));
280
281 DEV_FINISH_SCATTER_OPERATION(pScatterReq);
282
283 if (pScatterReq->CompletionStatus) {
284 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Send Scatter Request Failed: %d \n",pScatterReq->CompletionStatus));
285 status = A_ERROR;
286 }
287
288 /* walk through the scatter list and process */
289 for (i = 0; i < pScatterReq->ValidScatterEntries; i++) {
290 pPacket = (struct htc_packet *)(pScatterReq->ScatterList[i].pCallerContexts[0]);
291 A_ASSERT(pPacket != NULL);
292 pPacket->Status = status;
293 CompleteSentPacket(target,pEndpoint,pPacket);
294 /* add it to the completion queue */
295 HTC_PACKET_ENQUEUE(&sendCompletes, pPacket);
296 }
297
298 /* free scatter request */
299 DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq);
300 /* complete all packets */
301 DO_EP_TX_COMPLETION(pEndpoint,&sendCompletes);
302
303 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCAsyncSendScatterCompletion \n"));
304}
305
306 /* drain a queue and send as bundles
307 * this function may return without fully draining the queue under the following conditions :
308 * - scatter resources are exhausted
309 * - a message that will consume a partial credit will stop the bundling process early
310 * - we drop below the minimum number of messages for a bundle
311 * */
312static void HTCIssueSendBundle(struct htc_endpoint *pEndpoint,
313 struct htc_packet_queue *pQueue,
314 int *pBundlesSent,
315 int *pTotalBundlesPkts)
316{
317 int pktsToScatter;
318 unsigned int scatterSpaceRemaining;
319 struct hif_scatter_req *pScatterReq = NULL;
320 int i, packetsInScatterReq;
321 unsigned int transferLength;
322 struct htc_packet *pPacket;
323 bool done = false;
324 int bundlesSent = 0;
325 int totalPktsInBundle = 0;
326 struct htc_target *target = pEndpoint->target;
327 int creditRemainder = 0;
328 int creditPad;
329
330 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCIssueSendBundle \n"));
331
332 while (!done) {
333
334 pktsToScatter = HTC_PACKET_QUEUE_DEPTH(pQueue);
335 pktsToScatter = min(pktsToScatter, target->MaxMsgPerBundle);
336
337 if (pktsToScatter < HTC_MIN_HTC_MSGS_TO_BUNDLE) {
338 /* not enough to bundle */
339 break;
340 }
341
342 pScatterReq = DEV_ALLOC_SCATTER_REQ(&target->Device);
343
344 if (pScatterReq == NULL) {
345 /* no scatter resources */
346 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" No more scatter resources \n"));
347 break;
348 }
349
350 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" pkts to scatter: %d \n", pktsToScatter));
351
352 pScatterReq->TotalLength = 0;
353 pScatterReq->ValidScatterEntries = 0;
354
355 packetsInScatterReq = 0;
356 scatterSpaceRemaining = DEV_GET_MAX_BUNDLE_SEND_LENGTH(&target->Device);
357
358 for (i = 0; i < pktsToScatter; i++) {
359
360 pScatterReq->ScatterList[i].pCallerContexts[0] = NULL;
361
362 pPacket = HTC_GET_PKT_AT_HEAD(pQueue);
363 if (pPacket == NULL) {
364 A_ASSERT(false);
365 break;
366 }
367
368 creditPad = 0;
369 transferLength = DEV_CALC_SEND_PADDED_LEN(&target->Device,
370 pPacket->ActualLength + HTC_HDR_LENGTH);
371 /* see if the padded transfer length falls on a credit boundary */
372 creditRemainder = transferLength % target->TargetCreditSize;
373
374 if (creditRemainder != 0) {
375 /* the transfer consumes a "partial" credit, this packet cannot be bundled unless
376 * we add additional "dummy" padding (max 255 bytes) to consume the entire credit
377 *** NOTE: only allow the send padding if the endpoint is allowed to */
378 if (pEndpoint->LocalConnectionFlags & HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING) {
379 if (transferLength < target->TargetCreditSize) {
380 /* special case where the transfer is less than a credit */
381 creditPad = target->TargetCreditSize - transferLength;
382 } else {
383 creditPad = creditRemainder;
384 }
385
386 /* now check to see if we can indicate padding in the HTC header */
387 if ((creditPad > 0) && (creditPad <= 255)) {
388 /* adjust the transferlength of this packet with the new credit padding */
389 transferLength += creditPad;
390 } else {
391 /* the amount to pad is too large, bail on this packet, we have to
392 * send it using the non-bundled method */
393 pPacket = NULL;
394 }
395 } else {
396 /* bail on this packet, user does not want padding applied */
397 pPacket = NULL;
398 }
399 }
400
401 if (NULL == pPacket) {
402 /* can't bundle */
403 done = true;
404 break;
405 }
406
407 if (scatterSpaceRemaining < transferLength) {
408 /* exceeds what we can transfer */
409 break;
410 }
411
412 scatterSpaceRemaining -= transferLength;
413 /* now remove it from the queue */
414 pPacket = HTC_PACKET_DEQUEUE(pQueue);
415 /* save it in the scatter list */
416 pScatterReq->ScatterList[i].pCallerContexts[0] = pPacket;
417 /* prepare packet and flag message as part of a send bundle */
418 HTC_PREPARE_SEND_PKT(pPacket,
419 pPacket->PktInfo.AsTx.SendFlags | HTC_FLAGS_SEND_BUNDLE,
420 creditPad,
421 pPacket->PktInfo.AsTx.SeqNo);
422 pScatterReq->ScatterList[i].pBuffer = pPacket->pBuffer;
423 pScatterReq->ScatterList[i].Length = transferLength;
424 A_ASSERT(transferLength);
425 pScatterReq->TotalLength += transferLength;
426 pScatterReq->ValidScatterEntries++;
427 packetsInScatterReq++;
428 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" %d, Adding packet : 0x%lX, len:%d (remaining space:%d) \n",
429 i, (unsigned long)pPacket,transferLength,scatterSpaceRemaining));
430 }
431
432 if (packetsInScatterReq >= HTC_MIN_HTC_MSGS_TO_BUNDLE) {
433 /* send path is always asynchronous */
434 pScatterReq->CompletionRoutine = HTCAsyncSendScatterCompletion;
435 pScatterReq->Context = pEndpoint;
436 bundlesSent++;
437 totalPktsInBundle += packetsInScatterReq;
438 packetsInScatterReq = 0;
439 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Send Scatter total bytes: %d , entries: %d\n",
440 pScatterReq->TotalLength,pScatterReq->ValidScatterEntries));
441 DevSubmitScatterRequest(&target->Device, pScatterReq, DEV_SCATTER_WRITE, DEV_SCATTER_ASYNC);
442 /* we don't own this anymore */
443 pScatterReq = NULL;
444 /* try to send some more */
445 continue;
446 }
447
448 /* not enough packets to use the scatter request, cleanup */
449 if (pScatterReq != NULL) {
450 if (packetsInScatterReq > 0) {
451 /* work backwards to requeue requests */
452 for (i = (packetsInScatterReq - 1); i >= 0; i--) {
453 pPacket = (struct htc_packet *)(pScatterReq->ScatterList[i].pCallerContexts[0]);
454 if (pPacket != NULL) {
455 /* undo any prep */
456 HTC_UNPREPARE_SEND_PKT(pPacket);
457 /* queue back to the head */
458 HTC_PACKET_ENQUEUE_TO_HEAD(pQueue,pPacket);
459 }
460 }
461 }
462 DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq);
463 }
464
465 /* if we get here, we sent all that we could, get out */
466 break;
467
468 }
469
470 *pBundlesSent = bundlesSent;
471 *pTotalBundlesPkts = totalPktsInBundle;
472 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCIssueSendBundle (sent:%d) \n",bundlesSent));
473
474 return;
475}
476
477/*
478 * if there are no credits, the packet(s) remains in the queue.
479 * this function returns the result of the attempt to send a queue of HTC packets */
480static HTC_SEND_QUEUE_RESULT HTCTrySend(struct htc_target *target,
481 struct htc_endpoint *pEndpoint,
482 struct htc_packet_queue *pCallersSendQueue)
483{
484 struct htc_packet_queue sendQueue; /* temp queue to hold packets at various stages */
485 struct htc_packet *pPacket;
486 int bundlesSent;
487 int pktsInBundles;
488 int overflow;
489 HTC_SEND_QUEUE_RESULT result = HTC_SEND_QUEUE_OK;
490
491 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCTrySend (Queue:0x%lX Depth:%d)\n",
492 (unsigned long)pCallersSendQueue,
493 (pCallersSendQueue == NULL) ? 0 : HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue)));
494
495 /* init the local send queue */
496 INIT_HTC_PACKET_QUEUE(&sendQueue);
497
498 do {
499
500 if (NULL == pCallersSendQueue) {
501 /* caller didn't provide a queue, just wants us to check queues and send */
502 break;
503 }
504
505 if (HTC_QUEUE_EMPTY(pCallersSendQueue)) {
506 /* empty queue */
507 result = HTC_SEND_QUEUE_DROP;
508 break;
509 }
510
511 if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) >= pEndpoint->MaxTxQueueDepth) {
512 /* we've already overflowed */
513 overflow = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue);
514 } else {
515 /* figure out how much we will overflow by */
516 overflow = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
517 overflow += HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue);
518 /* figure out how much we will overflow the TX queue by */
519 overflow -= pEndpoint->MaxTxQueueDepth;
520 }
521
522 /* if overflow is negative or zero, we are okay */
523 if (overflow > 0) {
524 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
525 (" Endpoint %d, TX queue will overflow :%d , Tx Depth:%d, Max:%d \n",
526 pEndpoint->Id, overflow, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue), pEndpoint->MaxTxQueueDepth));
527 }
528 if ((overflow <= 0) || (pEndpoint->EpCallBacks.EpSendFull == NULL)) {
529 /* all packets will fit or caller did not provide send full indication handler
530 * -- just move all of them to the local sendQueue object */
531 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&sendQueue, pCallersSendQueue);
532 } else {
533 int i;
534 int goodPkts = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue) - overflow;
535
536 A_ASSERT(goodPkts >= 0);
537 /* we have overflowed, and a callback is provided */
538 /* dequeue all non-overflow packets into the sendqueue */
539 for (i = 0; i < goodPkts; i++) {
540 /* pop off caller's queue*/
541 pPacket = HTC_PACKET_DEQUEUE(pCallersSendQueue);
542 A_ASSERT(pPacket != NULL);
543 /* insert into local queue */
544 HTC_PACKET_ENQUEUE(&sendQueue,pPacket);
545 }
546
547 /* the caller's queue has all the packets that won't fit*/
548 /* walk through the caller's queue and indicate each one to the send full handler */
549 ITERATE_OVER_LIST_ALLOW_REMOVE(&pCallersSendQueue->QueueHead, pPacket, struct htc_packet, ListLink) {
550
551 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Indicating overflowed TX packet: 0x%lX \n",
552 (unsigned long)pPacket));
553 if (pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext,
554 pPacket) == HTC_SEND_FULL_DROP) {
555 /* callback wants the packet dropped */
556 INC_HTC_EP_STAT(pEndpoint, TxDropped, 1);
557 /* leave this one in the caller's queue for cleanup */
558 } else {
559 /* callback wants to keep this packet, remove from caller's queue */
560 HTC_PACKET_REMOVE(pCallersSendQueue, pPacket);
561 /* put it in the send queue */
562 HTC_PACKET_ENQUEUE(&sendQueue,pPacket);
563 }
564
565 } ITERATE_END;
566
567 if (HTC_QUEUE_EMPTY(&sendQueue)) {
568 /* no packets made it in, caller will cleanup */
569 result = HTC_SEND_QUEUE_DROP;
570 break;
571 }
572 }
573
574 } while (false);
575
576 if (result != HTC_SEND_QUEUE_OK) {
577 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n"));
578 return result;
579 }
580
581 LOCK_HTC_TX(target);
582
583 if (!HTC_QUEUE_EMPTY(&sendQueue)) {
584 /* transfer packets */
585 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->TxQueue,&sendQueue);
586 A_ASSERT(HTC_QUEUE_EMPTY(&sendQueue));
587 INIT_HTC_PACKET_QUEUE(&sendQueue);
588 }
589
590 /* increment tx processing count on entry */
591 pEndpoint->TxProcessCount++;
592 if (pEndpoint->TxProcessCount > 1) {
593 /* another thread or task is draining the TX queues on this endpoint
594 * that thread will reset the tx processing count when the queue is drained */
595 pEndpoint->TxProcessCount--;
596 UNLOCK_HTC_TX(target);
597 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend (busy) \n"));
598 return HTC_SEND_QUEUE_OK;
599 }
600
601 /***** beyond this point only 1 thread may enter ******/
602
603 /* now drain the endpoint TX queue for transmission as long as we have enough
604 * credits */
605 while (true) {
606
607 if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) == 0) {
608 break;
609 }
610
611 /* get all the packets for this endpoint that we can for this pass */
612 GetHTCSendPackets(target, pEndpoint, &sendQueue);
613
614 if (HTC_PACKET_QUEUE_DEPTH(&sendQueue) == 0) {
615 /* didn't get any packets due to a lack of credits */
616 break;
617 }
618
619 UNLOCK_HTC_TX(target);
620
621 /* any packets to send are now in our local send queue */
622
623 bundlesSent = 0;
624 pktsInBundles = 0;
625
626 while (true) {
627
628 /* try to send a bundle on each pass */
629 if ((target->SendBundlingEnabled) &&
630 (HTC_PACKET_QUEUE_DEPTH(&sendQueue) >= HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
631 int temp1,temp2;
632 /* bundling is enabled and there is at least a minimum number of packets in the send queue
633 * send what we can in this pass */
634 HTCIssueSendBundle(pEndpoint, &sendQueue, &temp1, &temp2);
635 bundlesSent += temp1;
636 pktsInBundles += temp2;
637 }
638
639 /* if not bundling or there was a packet that could not be placed in a bundle, pull it out
640 * and send it the normal way */
641 pPacket = HTC_PACKET_DEQUEUE(&sendQueue);
642 if (NULL == pPacket) {
643 /* local queue is fully drained */
644 break;
645 }
646 HTC_PREPARE_SEND_PKT(pPacket,
647 pPacket->PktInfo.AsTx.SendFlags,
648 0,
649 pPacket->PktInfo.AsTx.SeqNo);
650 HTCIssueSend(target, pPacket);
651
652 /* go back and see if we can bundle some more */
653 }
654
655 LOCK_HTC_TX(target);
656
657 INC_HTC_EP_STAT(pEndpoint, TxBundles, bundlesSent);
658 INC_HTC_EP_STAT(pEndpoint, TxPacketsBundled, pktsInBundles);
659
660 }
661
662 /* done with this endpoint, we can clear the count */
663 pEndpoint->TxProcessCount = 0;
664 UNLOCK_HTC_TX(target);
665
666 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n"));
667
668 return HTC_SEND_QUEUE_OK;
669}
670
671int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue)
672{
673 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
674 struct htc_endpoint *pEndpoint;
675 struct htc_packet *pPacket;
676
677 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCSendPktsMultiple: Queue: 0x%lX, Pkts %d \n",
678 (unsigned long)pPktQueue, HTC_PACKET_QUEUE_DEPTH(pPktQueue)));
679
680 /* get packet at head to figure out which endpoint these packets will go into */
681 pPacket = HTC_GET_PKT_AT_HEAD(pPktQueue);
682 if (NULL == pPacket) {
683 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n"));
684 return A_EINVAL;
685 }
686
687 AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX);
688 pEndpoint = &target->EndPoint[pPacket->Endpoint];
689
690 HTCTrySend(target, pEndpoint, pPktQueue);
691
692 /* do completion on any packets that couldn't get in */
693 if (!HTC_QUEUE_EMPTY(pPktQueue)) {
694
695 HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) {
696 if (HTC_STOPPING(target)) {
697 pPacket->Status = A_ECANCELED;
698 } else {
699 pPacket->Status = A_NO_RESOURCE;
700 }
701 } HTC_PACKET_QUEUE_ITERATE_END;
702
703 DO_EP_TX_COMPLETION(pEndpoint,pPktQueue);
704 }
705
706 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n"));
707
708 return 0;
709}
710
711/* HTC API - HTCSendPkt */
712int HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket)
713{
714 struct htc_packet_queue queue;
715
716 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
717 ("+-HTCSendPkt: Enter endPointId: %d, buffer: 0x%lX, length: %d \n",
718 pPacket->Endpoint, (unsigned long)pPacket->pBuffer, pPacket->ActualLength));
719 INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket);
720 return HTCSendPktsMultiple(HTCHandle, &queue);
721}
722
723/* check TX queues to drain because of credit distribution update */
724static INLINE void HTCCheckEndpointTxQueues(struct htc_target *target)
725{
726 struct htc_endpoint *pEndpoint;
727 struct htc_endpoint_credit_dist *pDistItem;
728
729 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCCheckEndpointTxQueues \n"));
730 pDistItem = target->EpCreditDistributionListHead;
731
732 /* run through the credit distribution list to see
733 * if there are packets queued
734 * NOTE: no locks need to be taken since the distribution list
735 * is not dynamic (cannot be re-ordered) and we are not modifying any state */
736 while (pDistItem != NULL) {
737 pEndpoint = (struct htc_endpoint *)pDistItem->pHTCReserved;
738
739 if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) > 0) {
740 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Ep %d has %d credits and %d Packets in TX Queue \n",
741 pDistItem->Endpoint, pEndpoint->CreditDist.TxCredits, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
742 /* try to start the stalled queue, this list is ordered by priority.
743 * Highest priority queue get's processed first, if there are credits available the
744 * highest priority queue will get a chance to reclaim credits from lower priority
745 * ones */
746 HTCTrySend(target, pEndpoint, NULL);
747 }
748
749 pDistItem = pDistItem->pNext;
750 }
751
752 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCCheckEndpointTxQueues \n"));
753}
754
755/* process credit reports and call distribution function */
756void HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint)
757{
758 int i;
759 struct htc_endpoint *pEndpoint;
760 int totalCredits = 0;
761 bool doDist = false;
762
763 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCProcessCreditRpt, Credit Report Entries:%d \n", NumEntries));
764
765 /* lock out TX while we update credits */
766 LOCK_HTC_TX(target);
767
768 for (i = 0; i < NumEntries; i++, pRpt++) {
769 if (pRpt->EndpointID >= ENDPOINT_MAX) {
770 AR_DEBUG_ASSERT(false);
771 break;
772 }
773
774 pEndpoint = &target->EndPoint[pRpt->EndpointID];
775
776 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d got %d credits \n",
777 pRpt->EndpointID, pRpt->Credits));
778
779 INC_HTC_EP_STAT(pEndpoint, TxCreditRpts, 1);
780 INC_HTC_EP_STAT(pEndpoint, TxCreditsReturned, pRpt->Credits);
781
782 if (FromEndpoint == pRpt->EndpointID) {
783 /* this credit report arrived on the same endpoint indicating it arrived in an RX
784 * packet */
785 INC_HTC_EP_STAT(pEndpoint, TxCreditsFromRx, pRpt->Credits);
786 INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromRx, 1);
787 } else if (FromEndpoint == ENDPOINT_0) {
788 /* this credit arrived on endpoint 0 as a NULL message */
789 INC_HTC_EP_STAT(pEndpoint, TxCreditsFromEp0, pRpt->Credits);
790 INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromEp0, 1);
791 } else {
792 /* arrived on another endpoint */
793 INC_HTC_EP_STAT(pEndpoint, TxCreditsFromOther, pRpt->Credits);
794 INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromOther, 1);
795 }
796
797 if (ENDPOINT_0 == pRpt->EndpointID) {
798 /* always give endpoint 0 credits back */
799 pEndpoint->CreditDist.TxCredits += pRpt->Credits;
800 } else {
801 /* for all other endpoints, update credits to distribute, the distribution function
802 * will handle giving out credits back to the endpoints */
803 pEndpoint->CreditDist.TxCreditsToDist += pRpt->Credits;
804 /* flag that we have to do the distribution */
805 doDist = true;
806 }
807
808 /* refresh tx depth for distribution function that will recover these credits
809 * NOTE: this is only valid when there are credits to recover! */
810 pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
811
812 totalCredits += pRpt->Credits;
813 }
814
815 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Report indicated %d credits to distribute \n", totalCredits));
816
817 if (doDist) {
818 /* this was a credit return based on a completed send operations
819 * note, this is done with the lock held */
820 DO_DISTRIBUTION(target,
821 HTC_CREDIT_DIST_SEND_COMPLETE,
822 "Send Complete",
823 target->EpCreditDistributionListHead->pNext);
824 }
825
826 UNLOCK_HTC_TX(target);
827
828 if (totalCredits) {
829 HTCCheckEndpointTxQueues(target);
830 }
831
832 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCProcessCreditRpt \n"));
833}
834
835/* flush endpoint TX queue */
836static void HTCFlushEndpointTX(struct htc_target *target, struct htc_endpoint *pEndpoint, HTC_TX_TAG Tag)
837{
838 struct htc_packet *pPacket;
839 struct htc_packet_queue discardQueue;
840 struct htc_packet_queue container;
841
842 /* initialize the discard queue */
843 INIT_HTC_PACKET_QUEUE(&discardQueue);
844
845 LOCK_HTC_TX(target);
846
847 /* interate from the front of the TX queue and flush out packets */
848 ITERATE_OVER_LIST_ALLOW_REMOVE(&pEndpoint->TxQueue.QueueHead, pPacket, struct htc_packet, ListLink) {
849
850 /* check for removal */
851 if ((HTC_TX_PACKET_TAG_ALL == Tag) || (Tag == pPacket->PktInfo.AsTx.Tag)) {
852 /* remove from queue */
853 HTC_PACKET_REMOVE(&pEndpoint->TxQueue, pPacket);
854 /* add it to the discard pile */
855 HTC_PACKET_ENQUEUE(&discardQueue, pPacket);
856 }
857
858 } ITERATE_END;
859
860 UNLOCK_HTC_TX(target);
861
862 /* empty the discard queue */
863 while (1) {
864 pPacket = HTC_PACKET_DEQUEUE(&discardQueue);
865 if (NULL == pPacket) {
866 break;
867 }
868 pPacket->Status = A_ECANCELED;
869 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" Flushing TX packet:0x%lX, length:%d, ep:%d tag:0x%X \n",
870 (unsigned long)pPacket, pPacket->ActualLength, pPacket->Endpoint, pPacket->PktInfo.AsTx.Tag));
871 INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
872 DO_EP_TX_COMPLETION(pEndpoint,&container);
873 }
874
875}
876
877void DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist)
878{
879 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("--- EP : %d ServiceID: 0x%X --------------\n",
880 pEPDist->Endpoint, pEPDist->ServiceID));
881 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" this:0x%lX next:0x%lX prev:0x%lX\n",
882 (unsigned long)pEPDist, (unsigned long)pEPDist->pNext, (unsigned long)pEPDist->pPrev));
883 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" DistFlags : 0x%X \n", pEPDist->DistFlags));
884 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsNorm : %d \n", pEPDist->TxCreditsNorm));
885 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsMin : %d \n", pEPDist->TxCreditsMin));
886 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCredits : %d \n", pEPDist->TxCredits));
887 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsAssigned : %d \n", pEPDist->TxCreditsAssigned));
888 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsSeek : %d \n", pEPDist->TxCreditsSeek));
889 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditSize : %d \n", pEPDist->TxCreditSize));
890 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsPerMaxMsg : %d \n", pEPDist->TxCreditsPerMaxMsg));
891 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsToDist : %d \n", pEPDist->TxCreditsToDist));
892 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxQueueDepth : %d \n",
893 HTC_PACKET_QUEUE_DEPTH(&((struct htc_endpoint *)pEPDist->pHTCReserved)->TxQueue)));
894 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("----------------------------------------------------\n"));
895}
896
897void DumpCreditDistStates(struct htc_target *target)
898{
899 struct htc_endpoint_credit_dist *pEPList = target->EpCreditDistributionListHead;
900
901 while (pEPList != NULL) {
902 DumpCreditDist(pEPList);
903 pEPList = pEPList->pNext;
904 }
905
906 if (target->DistributeCredits != NULL) {
907 DO_DISTRIBUTION(target,
908 HTC_DUMP_CREDIT_STATE,
909 "Dump State",
910 NULL);
911 }
912}
913
914/* flush all send packets from all endpoint queues */
915void HTCFlushSendPkts(struct htc_target *target)
916{
917 struct htc_endpoint *pEndpoint;
918 int i;
919
920 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) {
921 DumpCreditDistStates(target);
922 }
923
924 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
925 pEndpoint = &target->EndPoint[i];
926 if (pEndpoint->ServiceID == 0) {
927 /* not in use.. */
928 continue;
929 }
930 HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL);
931 }
932
933
934}
935
936/* HTC API to flush an endpoint's TX queue*/
937void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag)
938{
939 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
940 struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint];
941
942 if (pEndpoint->ServiceID == 0) {
943 AR_DEBUG_ASSERT(false);
944 /* not in use.. */
945 return;
946 }
947
948 HTCFlushEndpointTX(target, pEndpoint, Tag);
949}
950
951/* HTC API to indicate activity to the credit distribution function */
952void HTCIndicateActivityChange(HTC_HANDLE HTCHandle,
953 HTC_ENDPOINT_ID Endpoint,
954 bool Active)
955{
956 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
957 struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint];
958 bool doDist = false;
959
960 if (pEndpoint->ServiceID == 0) {
961 AR_DEBUG_ASSERT(false);
962 /* not in use.. */
963 return;
964 }
965
966 LOCK_HTC_TX(target);
967
968 if (Active) {
969 if (!(pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE)) {
970 /* mark active now */
971 pEndpoint->CreditDist.DistFlags |= HTC_EP_ACTIVE;
972 doDist = true;
973 }
974 } else {
975 if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) {
976 /* mark inactive now */
977 pEndpoint->CreditDist.DistFlags &= ~HTC_EP_ACTIVE;
978 doDist = true;
979 }
980 }
981
982 if (doDist) {
983 /* indicate current Tx Queue depth to the credit distribution function */
984 pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
985 /* do distribution again based on activity change
986 * note, this is done with the lock held */
987 DO_DISTRIBUTION(target,
988 HTC_CREDIT_DIST_ACTIVITY_CHANGE,
989 "Activity Change",
990 target->EpCreditDistributionListHead->pNext);
991 }
992
993 UNLOCK_HTC_TX(target);
994
995 if (doDist && !Active) {
996 /* if a stream went inactive and this resulted in a credit distribution change,
997 * some credits may now be available for HTC packets that are stuck in
998 * HTC queues */
999 HTCCheckEndpointTxQueues(target);
1000 }
1001}
1002
1003bool HTCIsEndpointActive(HTC_HANDLE HTCHandle,
1004 HTC_ENDPOINT_ID Endpoint)
1005{
1006 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1007 struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint];
1008
1009 if (pEndpoint->ServiceID == 0) {
1010 return false;
1011 }
1012
1013 if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) {
1014 return true;
1015 }
1016
1017 return false;
1018}
diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c
deleted file mode 100644
index c48070cbd54..00000000000
--- a/drivers/staging/ath6kl/htc2/htc_services.c
+++ /dev/null
@@ -1,450 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_services.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#include "htc_internal.h"
24
25void HTCControlTxComplete(void *Context, struct htc_packet *pPacket)
26{
27 /* not implemented
28 * we do not send control TX frames during normal runtime, only during setup */
29 AR_DEBUG_ASSERT(false);
30}
31
32 /* callback when a control message arrives on this endpoint */
33void HTCControlRecv(void *Context, struct htc_packet *pPacket)
34{
35 AR_DEBUG_ASSERT(pPacket->Endpoint == ENDPOINT_0);
36
37 if (pPacket->Status == A_ECANCELED) {
38 /* this is a flush operation, return the control packet back to the pool */
39 HTC_FREE_CONTROL_RX((struct htc_target*)Context,pPacket);
40 return;
41 }
42
43 /* the only control messages we are expecting are NULL messages (credit resports) */
44 if (pPacket->ActualLength > 0) {
45 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
46 ("HTCControlRecv, got message with length:%d \n",
47 pPacket->ActualLength + (u32)HTC_HDR_LENGTH));
48
49#ifdef ATH_DEBUG_MODULE
50 /* dump header and message */
51 DebugDumpBytes(pPacket->pBuffer - HTC_HDR_LENGTH,
52 pPacket->ActualLength + HTC_HDR_LENGTH,
53 "Unexpected ENDPOINT 0 Message");
54#endif
55 }
56
57 HTC_RECYCLE_RX_PKT((struct htc_target*)Context,pPacket,&((struct htc_target*)Context)->EndPoint[0]);
58}
59
60int HTCSendSetupComplete(struct htc_target *target)
61{
62 struct htc_packet *pSendPacket = NULL;
63 int status;
64
65 do {
66 /* allocate a packet to send to the target */
67 pSendPacket = HTC_ALLOC_CONTROL_TX(target);
68
69 if (NULL == pSendPacket) {
70 status = A_NO_MEMORY;
71 break;
72 }
73
74 if (target->HTCTargetVersion >= HTC_VERSION_2P1) {
75 HTC_SETUP_COMPLETE_EX_MSG *pSetupCompleteEx;
76 u32 setupFlags = 0;
77
78 pSetupCompleteEx = (HTC_SETUP_COMPLETE_EX_MSG *)pSendPacket->pBuffer;
79 A_MEMZERO(pSetupCompleteEx, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
80 pSetupCompleteEx->MessageID = HTC_MSG_SETUP_COMPLETE_EX_ID;
81 if (target->MaxMsgPerBundle > 0) {
82 /* host can do HTC bundling, indicate this to the target */
83 setupFlags |= HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV;
84 pSetupCompleteEx->MaxMsgsPerBundledRecv = target->MaxMsgPerBundle;
85 }
86 memcpy(&pSetupCompleteEx->SetupFlags, &setupFlags, sizeof(pSetupCompleteEx->SetupFlags));
87 SET_HTC_PACKET_INFO_TX(pSendPacket,
88 NULL,
89 (u8 *)pSetupCompleteEx,
90 sizeof(HTC_SETUP_COMPLETE_EX_MSG),
91 ENDPOINT_0,
92 HTC_SERVICE_TX_PACKET_TAG);
93
94 } else {
95 HTC_SETUP_COMPLETE_MSG *pSetupComplete;
96 /* assemble setup complete message */
97 pSetupComplete = (HTC_SETUP_COMPLETE_MSG *)pSendPacket->pBuffer;
98 A_MEMZERO(pSetupComplete, sizeof(HTC_SETUP_COMPLETE_MSG));
99 pSetupComplete->MessageID = HTC_MSG_SETUP_COMPLETE_ID;
100 SET_HTC_PACKET_INFO_TX(pSendPacket,
101 NULL,
102 (u8 *)pSetupComplete,
103 sizeof(HTC_SETUP_COMPLETE_MSG),
104 ENDPOINT_0,
105 HTC_SERVICE_TX_PACKET_TAG);
106 }
107
108 /* we want synchronous operation */
109 pSendPacket->Completion = NULL;
110 HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
111 /* send the message */
112 status = HTCIssueSend(target,pSendPacket);
113
114 } while (false);
115
116 if (pSendPacket != NULL) {
117 HTC_FREE_CONTROL_TX(target,pSendPacket);
118 }
119
120 return status;
121}
122
123
124int HTCConnectService(HTC_HANDLE HTCHandle,
125 struct htc_service_connect_req *pConnectReq,
126 struct htc_service_connect_resp *pConnectResp)
127{
128 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
129 int status = 0;
130 struct htc_packet *pRecvPacket = NULL;
131 struct htc_packet *pSendPacket = NULL;
132 HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg;
133 HTC_CONNECT_SERVICE_MSG *pConnectMsg;
134 HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX;
135 struct htc_endpoint *pEndpoint;
136 unsigned int maxMsgSize = 0;
137
138 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:0x%lX SvcID:0x%X \n",
139 (unsigned long)target, pConnectReq->ServiceID));
140
141 do {
142
143 AR_DEBUG_ASSERT(pConnectReq->ServiceID != 0);
144
145 if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) {
146 /* special case for pseudo control service */
147 assignedEndpoint = ENDPOINT_0;
148 maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH;
149 } else {
150 /* allocate a packet to send to the target */
151 pSendPacket = HTC_ALLOC_CONTROL_TX(target);
152
153 if (NULL == pSendPacket) {
154 AR_DEBUG_ASSERT(false);
155 status = A_NO_MEMORY;
156 break;
157 }
158 /* assemble connect service message */
159 pConnectMsg = (HTC_CONNECT_SERVICE_MSG *)pSendPacket->pBuffer;
160 AR_DEBUG_ASSERT(pConnectMsg != NULL);
161 A_MEMZERO(pConnectMsg,sizeof(HTC_CONNECT_SERVICE_MSG));
162 pConnectMsg->MessageID = HTC_MSG_CONNECT_SERVICE_ID;
163 pConnectMsg->ServiceID = pConnectReq->ServiceID;
164 pConnectMsg->ConnectionFlags = pConnectReq->ConnectionFlags;
165 /* check caller if it wants to transfer meta data */
166 if ((pConnectReq->pMetaData != NULL) &&
167 (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) {
168 /* copy meta data into message buffer (after header ) */
169 memcpy((u8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG),
170 pConnectReq->pMetaData,
171 pConnectReq->MetaDataLength);
172 pConnectMsg->ServiceMetaLength = pConnectReq->MetaDataLength;
173 }
174
175 SET_HTC_PACKET_INFO_TX(pSendPacket,
176 NULL,
177 (u8 *)pConnectMsg,
178 sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectMsg->ServiceMetaLength,
179 ENDPOINT_0,
180 HTC_SERVICE_TX_PACKET_TAG);
181
182 /* we want synchronous operation */
183 pSendPacket->Completion = NULL;
184 HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
185 status = HTCIssueSend(target,pSendPacket);
186
187 if (status) {
188 break;
189 }
190
191 /* wait for response */
192 status = HTCWaitforControlMessage(target, &pRecvPacket);
193
194 if (status) {
195 break;
196 }
197 /* we controlled the buffer creation so it has to be properly aligned */
198 pResponseMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)pRecvPacket->pBuffer;
199
200 if ((pResponseMsg->MessageID != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) ||
201 (pRecvPacket->ActualLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG))) {
202 /* this message is not valid */
203 AR_DEBUG_ASSERT(false);
204 status = A_EPROTO;
205 break;
206 }
207
208 pConnectResp->ConnectRespCode = pResponseMsg->Status;
209 /* check response status */
210 if (pResponseMsg->Status != HTC_SERVICE_SUCCESS) {
211 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
212 (" Target failed service 0x%X connect request (status:%d)\n",
213 pResponseMsg->ServiceID, pResponseMsg->Status));
214 status = A_EPROTO;
215 break;
216 }
217
218 assignedEndpoint = (HTC_ENDPOINT_ID) pResponseMsg->EndpointID;
219 maxMsgSize = pResponseMsg->MaxMsgSize;
220
221 if ((pConnectResp->pMetaData != NULL) &&
222 (pResponseMsg->ServiceMetaLength > 0) &&
223 (pResponseMsg->ServiceMetaLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) {
224 /* caller supplied a buffer and the target responded with data */
225 int copyLength = min((int)pConnectResp->BufferLength, (int)pResponseMsg->ServiceMetaLength);
226 /* copy the meta data */
227 memcpy(pConnectResp->pMetaData,
228 ((u8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG),
229 copyLength);
230 pConnectResp->ActualLength = copyLength;
231 }
232
233 }
234
235 /* the rest of these are parameter checks so set the error status */
236 status = A_EPROTO;
237
238 if (assignedEndpoint >= ENDPOINT_MAX) {
239 AR_DEBUG_ASSERT(false);
240 break;
241 }
242
243 if (0 == maxMsgSize) {
244 AR_DEBUG_ASSERT(false);
245 break;
246 }
247
248 pEndpoint = &target->EndPoint[assignedEndpoint];
249 pEndpoint->Id = assignedEndpoint;
250 if (pEndpoint->ServiceID != 0) {
251 /* endpoint already in use! */
252 AR_DEBUG_ASSERT(false);
253 break;
254 }
255
256 /* return assigned endpoint to caller */
257 pConnectResp->Endpoint = assignedEndpoint;
258 pConnectResp->MaxMsgLength = maxMsgSize;
259
260 /* setup the endpoint */
261 pEndpoint->ServiceID = pConnectReq->ServiceID; /* this marks the endpoint in use */
262 pEndpoint->MaxTxQueueDepth = pConnectReq->MaxSendQueueDepth;
263 pEndpoint->MaxMsgLength = maxMsgSize;
264 /* copy all the callbacks */
265 pEndpoint->EpCallBacks = pConnectReq->EpCallbacks;
266 /* set the credit distribution info for this endpoint, this information is
267 * passed back to the credit distribution callback function */
268 pEndpoint->CreditDist.ServiceID = pConnectReq->ServiceID;
269 pEndpoint->CreditDist.pHTCReserved = pEndpoint;
270 pEndpoint->CreditDist.Endpoint = assignedEndpoint;
271 pEndpoint->CreditDist.TxCreditSize = target->TargetCreditSize;
272
273 if (pConnectReq->MaxSendMsgSize != 0) {
274 /* override TxCreditsPerMaxMsg calculation, this optimizes the credit-low indications
275 * since the host will actually issue smaller messages in the Send path */
276 if (pConnectReq->MaxSendMsgSize > maxMsgSize) {
277 /* can't be larger than the maximum the target can support */
278 AR_DEBUG_ASSERT(false);
279 break;
280 }
281 pEndpoint->CreditDist.TxCreditsPerMaxMsg = pConnectReq->MaxSendMsgSize / target->TargetCreditSize;
282 } else {
283 pEndpoint->CreditDist.TxCreditsPerMaxMsg = maxMsgSize / target->TargetCreditSize;
284 }
285
286 if (0 == pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
287 pEndpoint->CreditDist.TxCreditsPerMaxMsg = 1;
288 }
289
290 /* save local connection flags */
291 pEndpoint->LocalConnectionFlags = pConnectReq->LocalConnectionFlags;
292
293 status = 0;
294
295 } while (false);
296
297 if (pSendPacket != NULL) {
298 HTC_FREE_CONTROL_TX(target,pSendPacket);
299 }
300
301 if (pRecvPacket != NULL) {
302 HTC_FREE_CONTROL_RX(target,pRecvPacket);
303 }
304
305 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCConnectService \n"));
306
307 return status;
308}
309
310static void AddToEndpointDistList(struct htc_target *target, struct htc_endpoint_credit_dist *pEpDist)
311{
312 struct htc_endpoint_credit_dist *pCurEntry,*pLastEntry;
313
314 if (NULL == target->EpCreditDistributionListHead) {
315 target->EpCreditDistributionListHead = pEpDist;
316 pEpDist->pNext = NULL;
317 pEpDist->pPrev = NULL;
318 return;
319 }
320
321 /* queue to the end of the list, this does not have to be very
322 * fast since this list is built at startup time */
323 pCurEntry = target->EpCreditDistributionListHead;
324
325 while (pCurEntry) {
326 pLastEntry = pCurEntry;
327 pCurEntry = pCurEntry->pNext;
328 }
329
330 pLastEntry->pNext = pEpDist;
331 pEpDist->pPrev = pLastEntry;
332 pEpDist->pNext = NULL;
333}
334
335
336
337/* default credit init callback */
338static void HTCDefaultCreditInit(void *Context,
339 struct htc_endpoint_credit_dist *pEPList,
340 int TotalCredits)
341{
342 struct htc_endpoint_credit_dist *pCurEpDist;
343 int totalEps = 0;
344 int creditsPerEndpoint;
345
346 pCurEpDist = pEPList;
347 /* first run through the list and figure out how many endpoints we are dealing with */
348 while (pCurEpDist != NULL) {
349 pCurEpDist = pCurEpDist->pNext;
350 totalEps++;
351 }
352
353 /* even distribution */
354 creditsPerEndpoint = TotalCredits/totalEps;
355
356 pCurEpDist = pEPList;
357 /* run through the list and set minimum and normal credits and
358 * provide the endpoint with some credits to start */
359 while (pCurEpDist != NULL) {
360
361 if (creditsPerEndpoint < pCurEpDist->TxCreditsPerMaxMsg) {
362 /* too many endpoints and not enough credits */
363 AR_DEBUG_ASSERT(false);
364 break;
365 }
366 /* our minimum is set for at least 1 max message */
367 pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg;
368 /* this value is ignored by our credit alg, since we do
369 * not dynamically adjust credits, this is the policy of
370 * the "default" credit distribution, something simple and easy */
371 pCurEpDist->TxCreditsNorm = 0xFFFF;
372 /* give the endpoint minimum credits */
373 pCurEpDist->TxCredits = creditsPerEndpoint;
374 pCurEpDist->TxCreditsAssigned = creditsPerEndpoint;
375 pCurEpDist = pCurEpDist->pNext;
376 }
377
378}
379
380/* default credit distribution callback, NOTE, this callback holds the TX lock */
381void HTCDefaultCreditDist(void *Context,
382 struct htc_endpoint_credit_dist *pEPDistList,
383 HTC_CREDIT_DIST_REASON Reason)
384{
385 struct htc_endpoint_credit_dist *pCurEpDist;
386
387 if (Reason == HTC_CREDIT_DIST_SEND_COMPLETE) {
388 pCurEpDist = pEPDistList;
389 /* simple distribution */
390 while (pCurEpDist != NULL) {
391 if (pCurEpDist->TxCreditsToDist > 0) {
392 /* just give the endpoint back the credits */
393 pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist;
394 pCurEpDist->TxCreditsToDist = 0;
395 }
396 pCurEpDist = pCurEpDist->pNext;
397 }
398 }
399
400 /* note we do not need to handle the other reason codes as this is a very
401 * simple distribution scheme, no need to seek for more credits or handle inactivity */
402}
403
404void HTCSetCreditDistribution(HTC_HANDLE HTCHandle,
405 void *pCreditDistContext,
406 HTC_CREDIT_DIST_CALLBACK CreditDistFunc,
407 HTC_CREDIT_INIT_CALLBACK CreditInitFunc,
408 HTC_SERVICE_ID ServicePriorityOrder[],
409 int ListLength)
410{
411 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
412 int i;
413 int ep;
414
415 if (CreditInitFunc != NULL) {
416 /* caller has supplied their own distribution functions */
417 target->InitCredits = CreditInitFunc;
418 AR_DEBUG_ASSERT(CreditDistFunc != NULL);
419 target->DistributeCredits = CreditDistFunc;
420 target->pCredDistContext = pCreditDistContext;
421 } else {
422 /* caller wants HTC to do distribution */
423 /* if caller wants service to handle distributions then
424 * it must set both of these to NULL! */
425 AR_DEBUG_ASSERT(CreditDistFunc == NULL);
426 target->InitCredits = HTCDefaultCreditInit;
427 target->DistributeCredits = HTCDefaultCreditDist;
428 target->pCredDistContext = target;
429 }
430
431 /* always add HTC control endpoint first, we only expose the list after the
432 * first one, this is added for TX queue checking */
433 AddToEndpointDistList(target, &target->EndPoint[ENDPOINT_0].CreditDist);
434
435 /* build the list of credit distribution structures in priority order
436 * supplied by the caller, these will follow endpoint 0 */
437 for (i = 0; i < ListLength; i++) {
438 /* match services with endpoints and add the endpoints to the distribution list
439 * in FIFO order */
440 for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) {
441 if (target->EndPoint[ep].ServiceID == ServicePriorityOrder[i]) {
442 /* queue this one to the list */
443 AddToEndpointDistList(target, &target->EndPoint[ep].CreditDist);
444 break;
445 }
446 }
447 AR_DEBUG_ASSERT(ep < ENDPOINT_MAX);
448 }
449
450}
diff --git a/drivers/staging/ath6kl/include/a_config.h b/drivers/staging/ath6kl/include/a_config.h
deleted file mode 100644
index f7c09319433..00000000000
--- a/drivers/staging/ath6kl/include/a_config.h
+++ /dev/null
@@ -1,31 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="a_config.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains software configuration options that enables
22// specific software "features"
23//
24// Author(s): ="Atheros"
25//==============================================================================
26#ifndef _A_CONFIG_H_
27#define _A_CONFIG_H_
28
29#include "../os/linux/include/config_linux.h"
30
31#endif
diff --git a/drivers/staging/ath6kl/include/a_debug.h b/drivers/staging/ath6kl/include/a_debug.h
deleted file mode 100644
index 5154fcb1ca6..00000000000
--- a/drivers/staging/ath6kl/include/a_debug.h
+++ /dev/null
@@ -1,195 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="a_debug.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _A_DEBUG_H_
24#define _A_DEBUG_H_
25
26#ifdef __cplusplus
27extern "C" {
28#endif /* __cplusplus */
29
30#include <a_osapi.h>
31
32 /* standard debug print masks bits 0..7 */
33#define ATH_DEBUG_ERR (1 << 0) /* errors */
34#define ATH_DEBUG_WARN (1 << 1) /* warnings */
35#define ATH_DEBUG_INFO (1 << 2) /* informational (module startup info) */
36#define ATH_DEBUG_TRC (1 << 3) /* generic function call tracing */
37#define ATH_DEBUG_RSVD1 (1 << 4)
38#define ATH_DEBUG_RSVD2 (1 << 5)
39#define ATH_DEBUG_RSVD3 (1 << 6)
40#define ATH_DEBUG_RSVD4 (1 << 7)
41
42#define ATH_DEBUG_MASK_DEFAULTS (ATH_DEBUG_ERR | ATH_DEBUG_WARN)
43#define ATH_DEBUG_ANY 0xFFFF
44
45 /* other aliases used throughout */
46#define ATH_DEBUG_ERROR ATH_DEBUG_ERR
47#define ATH_LOG_ERR ATH_DEBUG_ERR
48#define ATH_LOG_INF ATH_DEBUG_INFO
49#define ATH_LOG_TRC ATH_DEBUG_TRC
50#define ATH_DEBUG_TRACE ATH_DEBUG_TRC
51#define ATH_DEBUG_INIT ATH_DEBUG_INFO
52
53 /* bits 8..31 are module-specific masks */
54#define ATH_DEBUG_MODULE_MASK_SHIFT 8
55
56 /* macro to make a module-specific masks */
57#define ATH_DEBUG_MAKE_MODULE_MASK(index) (1 << (ATH_DEBUG_MODULE_MASK_SHIFT + (index)))
58
59void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription);
60
61/* Debug support on a per-module basis
62 *
63 * Usage:
64 *
65 * Each module can utilize it's own debug mask variable. A set of commonly used
66 * masks are provided (ERRORS, WARNINGS, TRACE etc..). It is up to each module
67 * to define module-specific masks using the macros above.
68 *
69 * Each module defines a single debug mask variable debug_XXX where the "name" of the module is
70 * common to all C-files within that module. This requires every C-file that includes a_debug.h
71 * to define the module name in that file.
72 *
73 * Example:
74 *
75 * #define ATH_MODULE_NAME htc
76 * #include "a_debug.h"
77 *
78 * This will define a debug mask structure called debug_htc and all debug macros will reference this
79 * variable.
80 *
81 * A module can define module-specific bit masks using the ATH_DEBUG_MAKE_MODULE_MASK() macro:
82 *
83 * #define ATH_DEBUG_MY_MASK1 ATH_DEBUG_MAKE_MODULE_MASK(0)
84 * #define ATH_DEBUG_MY_MASK2 ATH_DEBUG_MAKE_MODULE_MASK(1)
85 *
86 * The instantiation of the debug structure should be made by the module. When a module is
87 * instantiated, the module can set a description string, a default mask and an array of description
88 * entries containing information on each module-defined debug mask.
89 * NOTE: The instantiation is statically allocated, only one instance can exist per module.
90 *
91 * Example:
92 *
93 *
94 * #define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0)
95 *
96 * #ifdef DEBUG
97 * static struct ath_debug_mask_description bmi_debug_desc[] = {
98 * { ATH_DEBUG_BMI , "BMI Tracing"}, <== description of the module specific mask
99 * };
100 *
101 * ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi,
102 * "bmi" <== module name
103 * "Boot Manager Interface", <== description of module
104 * ATH_DEBUG_MASK_DEFAULTS, <== defaults
105 * ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc),
106 * bmi_debug_desc);
107 *
108 * #endif
109 *
110 * A module can optionally register it's debug module information in order for other tools to change the
111 * bit mask at runtime. A module can call A_REGISTER_MODULE_DEBUG_INFO() in it's module
112 * init code. This macro can be called multiple times without consequence. The debug info maintains
113 * state to indicate whether the information was previously registered.
114 *
115 * */
116
117#define ATH_DEBUG_MAX_MASK_DESC_LENGTH 32
118#define ATH_DEBUG_MAX_MOD_DESC_LENGTH 64
119
120struct ath_debug_mask_description {
121 u32 Mask;
122 char Description[ATH_DEBUG_MAX_MASK_DESC_LENGTH];
123};
124
125#define ATH_DEBUG_INFO_FLAGS_REGISTERED (1 << 0)
126
127typedef struct _ATH_DEBUG_MODULE_DBG_INFO{
128 struct _ATH_DEBUG_MODULE_DBG_INFO *pNext;
129 char ModuleName[16];
130 char ModuleDescription[ATH_DEBUG_MAX_MOD_DESC_LENGTH];
131 u32 Flags;
132 u32 CurrentMask;
133 int MaxDescriptions;
134 struct ath_debug_mask_description *pMaskDescriptions; /* pointer to array of descriptions */
135} ATH_DEBUG_MODULE_DBG_INFO;
136
137#define ATH_DEBUG_DESCRIPTION_COUNT(d) (int)((sizeof((d))) / (sizeof(struct ath_debug_mask_description)))
138
139#define GET_ATH_MODULE_DEBUG_VAR_NAME(s) _XGET_ATH_MODULE_NAME_DEBUG_(s)
140#define GET_ATH_MODULE_DEBUG_VAR_MASK(s) _XGET_ATH_MODULE_NAME_DEBUG_(s).CurrentMask
141#define _XGET_ATH_MODULE_NAME_DEBUG_(s) debug_ ## s
142
143#ifdef ATH_DEBUG_MODULE
144
145 /* for source files that will instantiate the debug variables */
146#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s,name,moddesc,initmask,count,descriptions) \
147ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s) = \
148 {NULL,(name),(moddesc),0,(initmask),count,(descriptions)}
149
150#ifdef ATH_MODULE_NAME
151extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(ATH_MODULE_NAME);
152#define AR_DEBUG_LVL_CHECK(lvl) (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (lvl))
153#endif /* ATH_MODULE_NAME */
154
155#define ATH_DEBUG_SET_DEBUG_MASK(s,lvl) GET_ATH_MODULE_DEBUG_VAR_MASK(s) = (lvl)
156
157#define ATH_DEBUG_DECLARE_EXTERN(s) \
158 extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s)
159
160#define AR_DEBUG_PRINTBUF(buffer, length, desc) DebugDumpBytes(buffer,length,desc)
161
162
163#define AR_DEBUG_ASSERT A_ASSERT
164
165void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo);
166void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo);
167#define A_DUMP_MODULE_DEBUG_INFO(s) a_dump_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s)))
168#define A_REGISTER_MODULE_DEBUG_INFO(s) a_register_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s)))
169
170#else /* !ATH_DEBUG_MODULE */
171 /* NON ATH_DEBUG_MODULE */
172#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s,name,moddesc,initmask,count,descriptions)
173#define AR_DEBUG_LVL_CHECK(lvl) 0
174#define AR_DEBUG_PRINTBUF(buffer, length, desc)
175#define AR_DEBUG_ASSERT(test)
176#define ATH_DEBUG_DECLARE_EXTERN(s)
177#define ATH_DEBUG_SET_DEBUG_MASK(s,lvl)
178#define A_DUMP_MODULE_DEBUG_INFO(s)
179#define A_REGISTER_MODULE_DEBUG_INFO(s)
180
181#endif
182
183int a_get_module_mask(char *module_name, u32 *pMask);
184int a_set_module_mask(char *module_name, u32 Mask);
185void a_dump_module_debug_info_by_name(char *module_name);
186void a_module_debug_support_init(void);
187void a_module_debug_support_cleanup(void);
188
189#include "../os/linux/include/debug_linux.h"
190
191#ifdef __cplusplus
192}
193#endif /* __cplusplus */
194
195#endif
diff --git a/drivers/staging/ath6kl/include/a_drv.h b/drivers/staging/ath6kl/include/a_drv.h
deleted file mode 100644
index 1548604e846..00000000000
--- a/drivers/staging/ath6kl/include/a_drv.h
+++ /dev/null
@@ -1,32 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="a_drv.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains the definitions of the basic atheros data types.
22// It is used to map the data types in atheros files to a platform specific
23// type.
24//
25// Author(s): ="Atheros"
26//==============================================================================
27#ifndef _A_DRV_H_
28#define _A_DRV_H_
29
30#include "../os/linux/include/athdrv_linux.h"
31
32#endif /* _ADRV_H_ */
diff --git a/drivers/staging/ath6kl/include/a_drv_api.h b/drivers/staging/ath6kl/include/a_drv_api.h
deleted file mode 100644
index a40d97a84ff..00000000000
--- a/drivers/staging/ath6kl/include/a_drv_api.h
+++ /dev/null
@@ -1,204 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="a_drv_api.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _A_DRV_API_H_
24#define _A_DRV_API_H_
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30/****************************************************************************/
31/****************************************************************************/
32/** **/
33/** WMI related hooks **/
34/** **/
35/****************************************************************************/
36/****************************************************************************/
37
38#include <ar6000_api.h>
39
40#define A_WMI_CHANNELLIST_RX(devt, numChan, chanList) \
41 ar6000_channelList_rx((devt), (numChan), (chanList))
42
43#define A_WMI_SET_NUMDATAENDPTS(devt, num) \
44 ar6000_set_numdataendpts((devt), (num))
45
46#define A_WMI_CONTROL_TX(devt, osbuf, streamID) \
47 ar6000_control_tx((devt), (osbuf), (streamID))
48
49#define A_WMI_TARGETSTATS_EVENT(devt, pStats, len) \
50 ar6000_targetStats_event((devt), (pStats), (len))
51
52#define A_WMI_SCANCOMPLETE_EVENT(devt, status) \
53 ar6000_scanComplete_event((devt), (status))
54
55#ifdef CONFIG_HOST_DSET_SUPPORT
56
57#define A_WMI_DSET_DATA_REQ(devt, access_cookie, offset, length, targ_buf, targ_reply_fn, targ_reply_arg) \
58 ar6000_dset_data_req((devt), (access_cookie), (offset), (length), (targ_buf), (targ_reply_fn), (targ_reply_arg))
59
60#define A_WMI_DSET_CLOSE(devt, access_cookie) \
61 ar6000_dset_close((devt), (access_cookie))
62
63#endif
64
65#define A_WMI_DSET_OPEN_REQ(devt, id, targ_handle, targ_reply_fn, targ_reply_arg) \
66 ar6000_dset_open_req((devt), (id), (targ_handle), (targ_reply_fn), (targ_reply_arg))
67
68#define A_WMI_CONNECT_EVENT(devt, channel, bssid, listenInterval, beaconInterval, networkType, beaconIeLen, assocReqLen, assocRespLen, assocInfo) \
69 ar6000_connect_event((devt), (channel), (bssid), (listenInterval), (beaconInterval), (networkType), (beaconIeLen), (assocReqLen), (assocRespLen), (assocInfo))
70
71#define A_WMI_PSPOLL_EVENT(devt, aid)\
72 ar6000_pspoll_event((devt),(aid))
73
74#define A_WMI_DTIMEXPIRY_EVENT(devt)\
75 ar6000_dtimexpiry_event((devt))
76
77#ifdef WAPI_ENABLE
78#define A_WMI_WAPI_REKEY_EVENT(devt, type, mac)\
79 ap_wapi_rekey_event((devt),(type),(mac))
80#endif
81
82#define A_WMI_REGDOMAIN_EVENT(devt, regCode) \
83 ar6000_regDomain_event((devt), (regCode))
84
85#define A_WMI_NEIGHBORREPORT_EVENT(devt, numAps, info) \
86 ar6000_neighborReport_event((devt), (numAps), (info))
87
88#define A_WMI_DISCONNECT_EVENT(devt, reason, bssid, assocRespLen, assocInfo, protocolReasonStatus) \
89 ar6000_disconnect_event((devt), (reason), (bssid), (assocRespLen), (assocInfo), (protocolReasonStatus))
90
91#define A_WMI_TKIP_MICERR_EVENT(devt, keyid, ismcast) \
92 ar6000_tkip_micerr_event((devt), (keyid), (ismcast))
93
94#define A_WMI_BITRATE_RX(devt, rateKbps) \
95 ar6000_bitrate_rx((devt), (rateKbps))
96
97#define A_WMI_TXPWR_RX(devt, txPwr) \
98 ar6000_txPwr_rx((devt), (txPwr))
99
100#define A_WMI_READY_EVENT(devt, datap, phyCap, sw_ver, abi_ver) \
101 ar6000_ready_event((devt), (datap), (phyCap), (sw_ver), (abi_ver))
102
103#define A_WMI_DBGLOG_INIT_DONE(ar) \
104 ar6000_dbglog_init_done(ar);
105
106#define A_WMI_RSSI_THRESHOLD_EVENT(devt, newThreshold, rssi) \
107 ar6000_rssiThreshold_event((devt), (newThreshold), (rssi))
108
109#define A_WMI_REPORT_ERROR_EVENT(devt, errorVal) \
110 ar6000_reportError_event((devt), (errorVal))
111
112#define A_WMI_ROAM_TABLE_EVENT(devt, pTbl) \
113 ar6000_roam_tbl_event((devt), (pTbl))
114
115#define A_WMI_ROAM_DATA_EVENT(devt, p) \
116 ar6000_roam_data_event((devt), (p))
117
118#define A_WMI_WOW_LIST_EVENT(devt, num_filters, wow_filters) \
119 ar6000_wow_list_event((devt), (num_filters), (wow_filters))
120
121#define A_WMI_CAC_EVENT(devt, ac, cac_indication, statusCode, tspecSuggestion) \
122 ar6000_cac_event((devt), (ac), (cac_indication), (statusCode), (tspecSuggestion))
123
124#define A_WMI_CHANNEL_CHANGE_EVENT(devt, oldChannel, newChannel) \
125 ar6000_channel_change_event((devt), (oldChannel), (newChannel))
126
127#define A_WMI_PMKID_LIST_EVENT(devt, num_pmkid, pmkid_list, bssid_list) \
128 ar6000_pmkid_list_event((devt), (num_pmkid), (pmkid_list), (bssid_list))
129
130#define A_WMI_PEER_EVENT(devt, eventCode, bssid) \
131 ar6000_peer_event ((devt), (eventCode), (bssid))
132
133#ifdef CONFIG_HOST_TCMD_SUPPORT
134#define A_WMI_TCMD_RX_REPORT_EVENT(devt, results, len) \
135 ar6000_tcmd_rx_report_event((devt), (results), (len))
136#endif
137
138#define A_WMI_HBCHALLENGERESP_EVENT(devt, cookie, source) \
139 ar6000_hbChallengeResp_event((devt), (cookie), (source))
140
141#define A_WMI_TX_RETRY_ERR_EVENT(devt) \
142 ar6000_tx_retry_err_event((devt))
143
144#define A_WMI_SNR_THRESHOLD_EVENT_RX(devt, newThreshold, snr) \
145 ar6000_snrThresholdEvent_rx((devt), (newThreshold), (snr))
146
147#define A_WMI_LQ_THRESHOLD_EVENT_RX(devt, range, lqVal) \
148 ar6000_lqThresholdEvent_rx((devt), (range), (lqVal))
149
150#define A_WMI_RATEMASK_RX(devt, ratemask) \
151 ar6000_ratemask_rx((devt), (ratemask))
152
153#define A_WMI_KEEPALIVE_RX(devt, configured) \
154 ar6000_keepalive_rx((devt), (configured))
155
156#define A_WMI_BSSINFO_EVENT_RX(ar, datp, len) \
157 ar6000_bssInfo_event_rx((ar), (datap), (len))
158
159#define A_WMI_DBGLOG_EVENT(ar, dropped, buffer, length) \
160 ar6000_dbglog_event((ar), (dropped), (buffer), (length));
161
162#define A_WMI_STREAM_TX_ACTIVE(devt,trafficClass) \
163 ar6000_indicate_tx_activity((devt),(trafficClass), true)
164
165#define A_WMI_STREAM_TX_INACTIVE(devt,trafficClass) \
166 ar6000_indicate_tx_activity((devt),(trafficClass), false)
167#define A_WMI_Ac2EndpointID(devht, ac)\
168 ar6000_ac2_endpoint_id((devht), (ac))
169
170#define A_WMI_AGGR_RECV_ADDBA_REQ_EVT(devt, cmd)\
171 ar6000_aggr_rcv_addba_req_evt((devt), (cmd))
172#define A_WMI_AGGR_RECV_ADDBA_RESP_EVT(devt, cmd)\
173 ar6000_aggr_rcv_addba_resp_evt((devt), (cmd))
174#define A_WMI_AGGR_RECV_DELBA_REQ_EVT(devt, cmd)\
175 ar6000_aggr_rcv_delba_req_evt((devt), (cmd))
176#define A_WMI_HCI_EVENT_EVT(devt, cmd)\
177 ar6000_hci_event_rcv_evt((devt), (cmd))
178
179#define A_WMI_Endpoint2Ac(devt, ep) \
180 ar6000_endpoint_id2_ac((devt), (ep))
181
182#define A_WMI_BTCOEX_CONFIG_EVENT(devt, evt, len)\
183 ar6000_btcoex_config_event((devt), (evt), (len))
184
185#define A_WMI_BTCOEX_STATS_EVENT(devt, datap, len)\
186 ar6000_btcoex_stats_event((devt), (datap), (len))
187
188/****************************************************************************/
189/****************************************************************************/
190/** **/
191/** HTC related hooks **/
192/** **/
193/****************************************************************************/
194/****************************************************************************/
195
196#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
197#define A_WMI_PROF_COUNT_RX(addr, count) prof_count_rx((addr), (count))
198#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
199
200#ifdef __cplusplus
201}
202#endif
203
204#endif
diff --git a/drivers/staging/ath6kl/include/a_osapi.h b/drivers/staging/ath6kl/include/a_osapi.h
deleted file mode 100644
index fd7ae0d612c..00000000000
--- a/drivers/staging/ath6kl/include/a_osapi.h
+++ /dev/null
@@ -1,32 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="a_osapi.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains the definitions of the basic atheros data types.
22// It is used to map the data types in atheros files to a platform specific
23// type.
24//
25// Author(s): ="Atheros"
26//==============================================================================
27#ifndef _A_OSAPI_H_
28#define _A_OSAPI_H_
29
30#include "../os/linux/include/osapi_linux.h"
31
32#endif /* _OSAPI_H_ */
diff --git a/drivers/staging/ath6kl/include/aggr_recv_api.h b/drivers/staging/ath6kl/include/aggr_recv_api.h
deleted file mode 100644
index 5ead58d5feb..00000000000
--- a/drivers/staging/ath6kl/include/aggr_recv_api.h
+++ /dev/null
@@ -1,140 +0,0 @@
1/*
2 *
3 * Copyright (c) 2004-2010 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7//
8// Permission to use, copy, modify, and/or distribute this software for any
9// purpose with or without fee is hereby granted, provided that the above
10// copyright notice and this permission notice appear in all copies.
11//
12// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19//
20//
21 *
22 */
23
24#ifndef __AGGR_RECV_API_H__
25#define __AGGR_RECV_API_H__
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31typedef void (* RX_CALLBACK)(void * dev, void *osbuf);
32
33typedef void (* ALLOC_NETBUFS)(A_NETBUF_QUEUE_T *q, u16 num);
34
35/*
36 * aggr_init:
37 * Initialises the data structures, allocates data queues and
38 * os buffers. Netbuf allocator is the input param, used by the
39 * aggr module for allocation of NETBUFs from driver context.
40 * These NETBUFs are used for AMSDU processing.
41 * Returns the context for the aggr module.
42 */
43void *
44aggr_init(ALLOC_NETBUFS netbuf_allocator);
45
46
47/*
48 * aggr_register_rx_dispatcher:
49 * Registers OS call back function to deliver the
50 * frames to OS. This is generally the topmost layer of
51 * the driver context, after which the frames go to
52 * IP stack via the call back function.
53 * This dispatcher is active only when aggregation is ON.
54 */
55void
56aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn);
57
58
59/*
60 * aggr_process_bar:
61 * When target receives BAR, it communicates to host driver
62 * for modifying window parameters. Target indicates this via the
63 * event: WMI_ADDBA_REQ_EVENTID. Host will dequeue all frames
64 * up to the indicated sequence number.
65 */
66void
67aggr_process_bar(void *cntxt, u8 tid, u16 seq_no);
68
69
70/*
71 * aggr_recv_addba_req_evt:
72 * This event is to initiate/modify the receive side window.
73 * Target will send WMI_ADDBA_REQ_EVENTID event to host - to setup
74 * recv re-ordering queues. Target will negotiate ADDBA with peer,
75 * and indicate via this event after successfully completing the
76 * negotiation. This happens in two situations:
77 * 1. Initial setup of aggregation
78 * 2. Renegotiation of current recv window.
79 * Window size for re-ordering is limited by target buffer
80 * space, which is reflected in win_sz.
81 * (Re)Start the periodic timer to deliver long standing frames,
82 * in hold_q to OS.
83 */
84void
85aggr_recv_addba_req_evt(void * cntxt, u8 tid, u16 seq_no, u8 win_sz);
86
87
88/*
89 * aggr_recv_delba_req_evt:
90 * Target indicates deletion of a BA window for a tid via the
91 * WMI_DELBA_EVENTID. Host would deliver all the frames in the
92 * hold_q, reset tid config and disable the periodic timer, if
93 * aggr is not enabled on any tid.
94 */
95void
96aggr_recv_delba_req_evt(void * cntxt, u8 tid);
97
98
99
100/*
101 * aggr_process_recv_frm:
102 * Called only for data frames. When aggr is ON for a tid, the buffer
103 * is always consumed, and osbuf would be NULL. For a non-aggr case,
104 * osbuf is not modified.
105 * AMSDU frames are consumed and are later freed. They are sliced and
106 * diced to individual frames and dispatched to stack.
107 * After consuming a osbuf(when aggr is ON), a previously registered
108 * callback may be called to deliver frames in order.
109 */
110void
111aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf);
112
113
114/*
115 * aggr_module_destroy:
116 * Frees up all the queues and frames in them. Releases the cntxt to OS.
117 */
118void
119aggr_module_destroy(void *cntxt);
120
121/*
122 * Dumps the aggregation stats
123 */
124void
125aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf);
126
127/*
128 * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate
129 * hold Q state. Examples include when a Connect event or disconnect event is
130 * received.
131 */
132void
133aggr_reset_state(void *cntxt);
134
135
136#ifdef __cplusplus
137}
138#endif
139
140#endif /*__AGGR_RECV_API_H__ */
diff --git a/drivers/staging/ath6kl/include/ar3kconfig.h b/drivers/staging/ath6kl/include/ar3kconfig.h
deleted file mode 100644
index 91bc4ee3512..00000000000
--- a/drivers/staging/ath6kl/include/ar3kconfig.h
+++ /dev/null
@@ -1,65 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22
23/* AR3K module configuration APIs for HCI-bridge operation */
24
25#ifndef AR3KCONFIG_H_
26#define AR3KCONFIG_H_
27
28#include <net/bluetooth/bluetooth.h>
29#include <net/bluetooth/hci_core.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35#define AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT (1 << 0)
36#define AR3K_CONFIG_FLAG_SET_AR3K_BAUD (1 << 1)
37#define AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY (1 << 2)
38#define AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP (1 << 3)
39
40
41struct ar3k_config_info {
42 u32 Flags; /* config flags */
43 void *pHCIDev; /* HCI bridge device */
44 struct hci_transport_properties *pHCIProps; /* HCI bridge props */
45 struct hif_device *pHIFDevice; /* HIF layer device */
46
47 u32 AR3KBaudRate; /* AR3K operational baud rate */
48 u16 AR6KScale; /* AR6K UART scale value */
49 u16 AR6KStep; /* AR6K UART step value */
50 struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */
51 u32 PwrMgmtEnabled; /* TLPM enabled? */
52 u16 IdleTimeout; /* TLPM idle timeout */
53 u16 WakeupTimeout; /* TLPM wakeup timeout */
54 u8 bdaddr[6]; /* Bluetooth device address */
55};
56
57int AR3KConfigure(struct ar3k_config_info *pConfigInfo);
58
59int AR3KConfigureExit(void *config);
60
61#ifdef __cplusplus
62}
63#endif
64
65#endif /*AR3KCONFIG_H_*/
diff --git a/drivers/staging/ath6kl/include/ar6000_api.h b/drivers/staging/ath6kl/include/ar6000_api.h
deleted file mode 100644
index e9460800272..00000000000
--- a/drivers/staging/ath6kl/include/ar6000_api.h
+++ /dev/null
@@ -1,32 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6000_api.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains the API to access the OS dependent atheros host driver
22// by the WMI or WLAN generic modules.
23//
24// Author(s): ="Atheros"
25//==============================================================================
26#ifndef _AR6000_API_H_
27#define _AR6000_API_H_
28
29#include "../os/linux/include/ar6xapi_linux.h"
30
31#endif /* _AR6000_API_H */
32
diff --git a/drivers/staging/ath6kl/include/ar6000_diag.h b/drivers/staging/ath6kl/include/ar6000_diag.h
deleted file mode 100644
index 739c01c53f0..00000000000
--- a/drivers/staging/ath6kl/include/ar6000_diag.h
+++ /dev/null
@@ -1,48 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6000_diag.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef AR6000_DIAG_H_
25#define AR6000_DIAG_H_
26
27
28int
29ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
30
31int
32ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
33
34int
35ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address,
36 u8 *data, u32 length);
37
38int
39ar6000_WriteDataDiag(struct hif_device *hifDevice, u32 address,
40 u8 *data, u32 length);
41
42int
43ar6k_ReadTargetRegister(struct hif_device *hifDevice, int regsel, u32 *regval);
44
45void
46ar6k_FetchTargetRegs(struct hif_device *hifDevice, u32 *targregs);
47
48#endif /*AR6000_DIAG_H_*/
diff --git a/drivers/staging/ath6kl/include/ar6kap_common.h b/drivers/staging/ath6kl/include/ar6kap_common.h
deleted file mode 100644
index 532d8eba932..00000000000
--- a/drivers/staging/ath6kl/include/ar6kap_common.h
+++ /dev/null
@@ -1,44 +0,0 @@
1//------------------------------------------------------------------------------
2
3// <copyright file="ar6kap_common.h" company="Atheros">
4// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//------------------------------------------------------------------------------
21
22//==============================================================================
23
24// This file contains the definitions of common AP mode data structures.
25//
26// Author(s): ="Atheros"
27//==============================================================================
28
29#ifndef _AR6KAP_COMMON_H_
30#define _AR6KAP_COMMON_H_
31/*
32 * Used with AR6000_XIOCTL_AP_GET_STA_LIST
33 */
34typedef struct {
35 u8 mac[ATH_MAC_LEN];
36 u8 aid;
37 u8 keymgmt;
38 u8 ucipher;
39 u8 auth;
40} station_t;
41typedef struct {
42 station_t sta[AP_MAX_NUM_STA];
43} ap_get_sta_t;
44#endif /* _AR6KAP_COMMON_H_ */
diff --git a/drivers/staging/ath6kl/include/athbtfilter.h b/drivers/staging/ath6kl/include/athbtfilter.h
deleted file mode 100644
index 81456eea3b0..00000000000
--- a/drivers/staging/ath6kl/include/athbtfilter.h
+++ /dev/null
@@ -1,135 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="athbtfilter.h" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Public Bluetooth filter APIs
22// Author(s): ="Atheros"
23//==============================================================================
24#ifndef ATHBTFILTER_H_
25#define ATHBTFILTER_H_
26
27#define ATH_DEBUG_INFO (1 << 2)
28#define ATH_DEBUG_INF ATH_DEBUG_INFO
29
30typedef enum _ATHBT_HCI_CTRL_TYPE {
31 ATHBT_HCI_COMMAND = 0,
32 ATHBT_HCI_EVENT = 1,
33} ATHBT_HCI_CTRL_TYPE;
34
35typedef enum _ATHBT_STATE_INDICATION {
36 ATH_BT_NOOP = 0,
37 ATH_BT_INQUIRY = 1,
38 ATH_BT_CONNECT = 2,
39 ATH_BT_SCO = 3,
40 ATH_BT_ACL = 4,
41 ATH_BT_A2DP = 5,
42 ATH_BT_ESCO = 6,
43 /* new states go here.. */
44
45 ATH_BT_MAX_STATE_INDICATION
46} ATHBT_STATE_INDICATION;
47
48 /* filter function for OUTGOING commands and INCOMMING events */
49typedef void (*ATHBT_FILTER_CMD_EVENTS_FN)(void *pContext, ATHBT_HCI_CTRL_TYPE Type, unsigned char *pBuffer, int Length);
50
51 /* filter function for OUTGOING data HCI packets */
52typedef void (*ATHBT_FILTER_DATA_FN)(void *pContext, unsigned char *pBuffer, int Length);
53
54typedef enum _ATHBT_STATE {
55 STATE_OFF = 0,
56 STATE_ON = 1,
57 STATE_MAX
58} ATHBT_STATE;
59
60 /* BT state indication (when filter functions are not used) */
61
62typedef void (*ATHBT_INDICATE_STATE_FN)(void *pContext, ATHBT_STATE_INDICATION Indication, ATHBT_STATE State, unsigned char LMPVersion);
63
64struct athbt_filter_instance {
65#ifdef UNDER_CE
66 WCHAR *pWlanAdapterName; /* filled in by user */
67#else
68 char *pWlanAdapterName; /* filled in by user */
69#endif /* UNDER_CE */
70 int FilterEnabled; /* filtering is enabled */
71 int Attached; /* filter library is attached */
72 void *pContext; /* private context for filter library */
73 ATHBT_FILTER_CMD_EVENTS_FN pFilterCmdEvents; /* function ptr to filter a command or event */
74 ATHBT_FILTER_DATA_FN pFilterAclDataOut; /* function ptr to filter ACL data out (to radio) */
75 ATHBT_FILTER_DATA_FN pFilterAclDataIn; /* function ptr to filter ACL data in (from radio) */
76 ATHBT_INDICATE_STATE_FN pIndicateState; /* function ptr to indicate a state */
77}; /* XXX: unused ? */
78
79
80/* API MACROS */
81
82#define AthBtFilterHciCommand(instance,packet,length) \
83 if ((instance)->FilterEnabled) { \
84 (instance)->pFilterCmdEvents((instance)->pContext, \
85 ATHBT_HCI_COMMAND, \
86 (unsigned char *)(packet), \
87 (length)); \
88 }
89
90#define AthBtFilterHciEvent(instance,packet,length) \
91 if ((instance)->FilterEnabled) { \
92 (instance)->pFilterCmdEvents((instance)->pContext, \
93 ATHBT_HCI_EVENT, \
94 (unsigned char *)(packet), \
95 (length)); \
96 }
97
98#define AthBtFilterHciAclDataOut(instance,packet,length) \
99 if ((instance)->FilterEnabled) { \
100 (instance)->pFilterAclDataOut((instance)->pContext, \
101 (unsigned char *)(packet), \
102 (length)); \
103 }
104
105#define AthBtFilterHciAclDataIn(instance,packet,length) \
106 if ((instance)->FilterEnabled) { \
107 (instance)->pFilterAclDataIn((instance)->pContext, \
108 (unsigned char *)(packet), \
109 (length)); \
110 }
111
112/* if filtering is not desired, the application can indicate the state directly using this
113 * macro:
114 */
115#define AthBtIndicateState(instance,indication,state) \
116 if ((instance)->FilterEnabled) { \
117 (instance)->pIndicateState((instance)->pContext, \
118 (indication), \
119 (state), \
120 0); \
121 }
122
123#ifdef __cplusplus
124extern "C" {
125#endif
126
127/* API prototypes */
128int AthBtFilter_Attach(ATH_BT_FILTER_INSTANCE *pInstance, unsigned int flags);
129void AthBtFilter_Detach(ATH_BT_FILTER_INSTANCE *pInstance);
130
131#ifdef __cplusplus
132}
133#endif
134
135#endif /*ATHBTFILTER_H_*/
diff --git a/drivers/staging/ath6kl/include/bmi.h b/drivers/staging/ath6kl/include/bmi.h
deleted file mode 100644
index d3227f77fa5..00000000000
--- a/drivers/staging/ath6kl/include/bmi.h
+++ /dev/null
@@ -1,134 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="bmi.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// BMI declarations and prototypes
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _BMI_H_
26#define _BMI_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* Header files */
33#include "a_config.h"
34#include "athdefs.h"
35#include "hif.h"
36#include "a_osapi.h"
37#include "bmi_msg.h"
38
39void
40BMIInit(void);
41
42void
43BMICleanup(void);
44
45int
46BMIDone(struct hif_device *device);
47
48int
49BMIGetTargetInfo(struct hif_device *device, struct bmi_target_info *targ_info);
50
51int
52BMIReadMemory(struct hif_device *device,
53 u32 address,
54 u8 *buffer,
55 u32 length);
56
57int
58BMIWriteMemory(struct hif_device *device,
59 u32 address,
60 u8 *buffer,
61 u32 length);
62
63int
64BMIExecute(struct hif_device *device,
65 u32 address,
66 u32 *param);
67
68int
69BMISetAppStart(struct hif_device *device,
70 u32 address);
71
72int
73BMIReadSOCRegister(struct hif_device *device,
74 u32 address,
75 u32 *param);
76
77int
78BMIWriteSOCRegister(struct hif_device *device,
79 u32 address,
80 u32 param);
81
82int
83BMIrompatchInstall(struct hif_device *device,
84 u32 ROM_addr,
85 u32 RAM_addr,
86 u32 nbytes,
87 u32 do_activate,
88 u32 *patch_id);
89
90int
91BMIrompatchUninstall(struct hif_device *device,
92 u32 rompatch_id);
93
94int
95BMIrompatchActivate(struct hif_device *device,
96 u32 rompatch_count,
97 u32 *rompatch_list);
98
99int
100BMIrompatchDeactivate(struct hif_device *device,
101 u32 rompatch_count,
102 u32 *rompatch_list);
103
104int
105BMILZStreamStart(struct hif_device *device,
106 u32 address);
107
108int
109BMILZData(struct hif_device *device,
110 u8 *buffer,
111 u32 length);
112
113int
114BMIFastDownload(struct hif_device *device,
115 u32 address,
116 u8 *buffer,
117 u32 length);
118
119int
120BMIRawWrite(struct hif_device *device,
121 u8 *buffer,
122 u32 length);
123
124int
125BMIRawRead(struct hif_device *device,
126 u8 *buffer,
127 u32 length,
128 bool want_timeout);
129
130#ifdef __cplusplus
131}
132#endif
133
134#endif /* _BMI_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h b/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h
deleted file mode 100644
index 5407e05d9b0..00000000000
--- a/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h
+++ /dev/null
@@ -1,52 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="AR6K_version.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#define __VER_MAJOR_ 3
25#define __VER_MINOR_ 0
26#define __VER_PATCH_ 0
27
28/* The makear6ksdk script (used for release builds) modifies the following line. */
29#define __BUILD_NUMBER_ 233
30
31
32/* Format of the version number. */
33#define VER_MAJOR_BIT_OFFSET 28
34#define VER_MINOR_BIT_OFFSET 24
35#define VER_PATCH_BIT_OFFSET 16
36#define VER_BUILD_NUM_BIT_OFFSET 0
37
38
39/*
40 * The version has the following format:
41 * Bits 28-31: Major version
42 * Bits 24-27: Minor version
43 * Bits 16-23: Patch version
44 * Bits 0-15: Build number (automatically generated during build process )
45 * E.g. Build 1.1.3.7 would be represented as 0x11030007.
46 *
47 * DO NOT split the following macro into multiple lines as this may confuse the build scripts.
48 */
49#define AR6K_SW_VERSION ( ( __VER_MAJOR_ << VER_MAJOR_BIT_OFFSET ) + ( __VER_MINOR_ << VER_MINOR_BIT_OFFSET ) + ( __VER_PATCH_ << VER_PATCH_BIT_OFFSET ) + ( __BUILD_NUMBER_ << VER_BUILD_NUM_BIT_OFFSET ) )
50
51/* ABI Version. Reflects the version of binary interface exposed by AR6K target firmware. Needs to be incremented by 1 for any change in the firmware that requires upgrade of the driver on the host side for the change to work correctly */
52#define AR6K_ABI_VERSION 1
diff --git a/drivers/staging/ath6kl/include/common/AR6002/addrs.h b/drivers/staging/ath6kl/include/common/AR6002/addrs.h
deleted file mode 100644
index bbf8d42828c..00000000000
--- a/drivers/staging/ath6kl/include/common/AR6002/addrs.h
+++ /dev/null
@@ -1,90 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//
19// Author(s): ="Atheros"
20//------------------------------------------------------------------------------
21
22#ifndef __ADDRS_H__
23#define __ADDRS_H__
24
25/*
26 * Special AR6002 Addresses that may be needed by special
27 * applications (e.g. ART) on the Host as well as Target.
28 */
29
30#if defined(AR6002_REV2)
31#define AR6K_RAM_START 0x00500000
32#define TARG_RAM_OFFSET(vaddr) ((u32)(vaddr) & 0xfffff)
33#define TARG_RAM_SZ (184*1024)
34#define TARG_ROM_SZ (80*1024)
35#endif
36#if defined(AR6002_REV4) || defined(AR6003)
37#define AR6K_RAM_START 0x00540000
38#define TARG_RAM_OFFSET(vaddr) (((u32)(vaddr) & 0xfffff) - 0x40000)
39#define TARG_RAM_SZ (256*1024)
40#define TARG_ROM_SZ (256*1024)
41#endif
42
43#define AR6002_BOARD_DATA_SZ 768
44#define AR6002_BOARD_EXT_DATA_SZ 0
45#define AR6003_BOARD_DATA_SZ 1024
46#define AR6003_BOARD_EXT_DATA_SZ 768
47
48#define AR6K_RAM_ADDR(byte_offset) (AR6K_RAM_START+(byte_offset))
49#define TARG_RAM_ADDRS(byte_offset) AR6K_RAM_ADDR(byte_offset)
50
51#define AR6K_ROM_START 0x004e0000
52#define TARG_ROM_OFFSET(vaddr) (((u32)(vaddr) & 0x1fffff) - 0xe0000)
53#define AR6K_ROM_ADDR(byte_offset) (AR6K_ROM_START+(byte_offset))
54#define TARG_ROM_ADDRS(byte_offset) AR6K_ROM_ADDR(byte_offset)
55
56/*
57 * At this ROM address is a pointer to the start of the ROM DataSet Index.
58 * If there are no ROM DataSets, there's a 0 at this address.
59 */
60#define ROM_DATASET_INDEX_ADDR (TARG_ROM_ADDRS(TARG_ROM_SZ)-8)
61#define ROM_MBIST_CKSUM_ADDR (TARG_ROM_ADDRS(TARG_ROM_SZ)-4)
62
63/*
64 * The API A_BOARD_DATA_ADDR() is the proper way to get a read pointer to
65 * board data.
66 */
67
68/* Size of Board Data, in bytes */
69#if defined(AR6002_REV4) || defined(AR6003)
70#define BOARD_DATA_SZ AR6003_BOARD_DATA_SZ
71#else
72#define BOARD_DATA_SZ AR6002_BOARD_DATA_SZ
73#endif
74
75
76/*
77 * Constants used by ASM code to access fields of host_interest_s,
78 * which is at a fixed location in RAM.
79 */
80#if defined(AR6002_REV4) || defined(AR6003)
81#define HOST_INTEREST_FLASH_IS_PRESENT_ADDR (AR6K_RAM_START + 0x60c)
82#else
83#define HOST_INTEREST_FLASH_IS_PRESENT_ADDR (AR6K_RAM_START + 0x40c)
84#endif
85#define FLASH_IS_PRESENT_TARGADDR HOST_INTEREST_FLASH_IS_PRESENT_ADDR
86
87#endif /* __ADDRS_H__ */
88
89
90
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h
deleted file mode 100644
index 609eb9841f5..00000000000
--- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h
+++ /dev/null
@@ -1,40 +0,0 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#ifndef _APB_ATHR_WLAN_MAP_H_
25#define _APB_ATHR_WLAN_MAP_H_
26
27#define WLAN_RTC_BASE_ADDRESS 0x00004000
28#define WLAN_VMC_BASE_ADDRESS 0x00008000
29#define WLAN_UART_BASE_ADDRESS 0x0000c000
30#define WLAN_DBG_UART_BASE_ADDRESS 0x0000d000
31#define WLAN_UMBOX_BASE_ADDRESS 0x0000e000
32#define WLAN_SI_BASE_ADDRESS 0x00010000
33#define WLAN_GPIO_BASE_ADDRESS 0x00014000
34#define WLAN_MBOX_BASE_ADDRESS 0x00018000
35#define WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000
36#define WLAN_MAC_BASE_ADDRESS 0x00020000
37#define WLAN_RDMA_BASE_ADDRESS 0x00030100
38#define EFUSE_BASE_ADDRESS 0x00031000
39
40#endif /* _APB_ATHR_WLAN_MAP_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h
deleted file mode 100644
index 0068ca31b05..00000000000
--- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h
+++ /dev/null
@@ -1,40 +0,0 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#include "apb_athr_wlan_map.h"
25
26#ifndef BT_HEADERS
27
28#define RTC_BASE_ADDRESS WLAN_RTC_BASE_ADDRESS
29#define VMC_BASE_ADDRESS WLAN_VMC_BASE_ADDRESS
30#define UART_BASE_ADDRESS WLAN_UART_BASE_ADDRESS
31#define DBG_UART_BASE_ADDRESS WLAN_DBG_UART_BASE_ADDRESS
32#define UMBOX_BASE_ADDRESS WLAN_UMBOX_BASE_ADDRESS
33#define SI_BASE_ADDRESS WLAN_SI_BASE_ADDRESS
34#define GPIO_BASE_ADDRESS WLAN_GPIO_BASE_ADDRESS
35#define MBOX_BASE_ADDRESS WLAN_MBOX_BASE_ADDRESS
36#define ANALOG_INTF_BASE_ADDRESS WLAN_ANALOG_INTF_BASE_ADDRESS
37#define MAC_BASE_ADDRESS WLAN_MAC_BASE_ADDRESS
38#define RDMA_BASE_ADDRESS WLAN_RDMA_BASE_ADDRESS
39
40#endif
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h
deleted file mode 100644
index 109f24e10a6..00000000000
--- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h
+++ /dev/null
@@ -1,24 +0,0 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#include "mbox_wlan_host_reg.h"
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h
deleted file mode 100644
index 72fa483450d..00000000000
--- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h
+++ /dev/null
@@ -1,552 +0,0 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#include "mbox_wlan_reg.h"
25
26#ifndef BT_HEADERS
27
28#define MBOX_FIFO_ADDRESS WLAN_MBOX_FIFO_ADDRESS
29#define MBOX_FIFO_OFFSET WLAN_MBOX_FIFO_OFFSET
30#define MBOX_FIFO_DATA_MSB WLAN_MBOX_FIFO_DATA_MSB
31#define MBOX_FIFO_DATA_LSB WLAN_MBOX_FIFO_DATA_LSB
32#define MBOX_FIFO_DATA_MASK WLAN_MBOX_FIFO_DATA_MASK
33#define MBOX_FIFO_DATA_GET(x) WLAN_MBOX_FIFO_DATA_GET(x)
34#define MBOX_FIFO_DATA_SET(x) WLAN_MBOX_FIFO_DATA_SET(x)
35#define MBOX_FIFO_STATUS_ADDRESS WLAN_MBOX_FIFO_STATUS_ADDRESS
36#define MBOX_FIFO_STATUS_OFFSET WLAN_MBOX_FIFO_STATUS_OFFSET
37#define MBOX_FIFO_STATUS_EMPTY_MSB WLAN_MBOX_FIFO_STATUS_EMPTY_MSB
38#define MBOX_FIFO_STATUS_EMPTY_LSB WLAN_MBOX_FIFO_STATUS_EMPTY_LSB
39#define MBOX_FIFO_STATUS_EMPTY_MASK WLAN_MBOX_FIFO_STATUS_EMPTY_MASK
40#define MBOX_FIFO_STATUS_EMPTY_GET(x) WLAN_MBOX_FIFO_STATUS_EMPTY_GET(x)
41#define MBOX_FIFO_STATUS_EMPTY_SET(x) WLAN_MBOX_FIFO_STATUS_EMPTY_SET(x)
42#define MBOX_FIFO_STATUS_FULL_MSB WLAN_MBOX_FIFO_STATUS_FULL_MSB
43#define MBOX_FIFO_STATUS_FULL_LSB WLAN_MBOX_FIFO_STATUS_FULL_LSB
44#define MBOX_FIFO_STATUS_FULL_MASK WLAN_MBOX_FIFO_STATUS_FULL_MASK
45#define MBOX_FIFO_STATUS_FULL_GET(x) WLAN_MBOX_FIFO_STATUS_FULL_GET(x)
46#define MBOX_FIFO_STATUS_FULL_SET(x) WLAN_MBOX_FIFO_STATUS_FULL_SET(x)
47#define MBOX_DMA_POLICY_ADDRESS WLAN_MBOX_DMA_POLICY_ADDRESS
48#define MBOX_DMA_POLICY_OFFSET WLAN_MBOX_DMA_POLICY_OFFSET
49#define MBOX_DMA_POLICY_TX_QUANTUM_MSB WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MSB
50#define MBOX_DMA_POLICY_TX_QUANTUM_LSB WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB
51#define MBOX_DMA_POLICY_TX_QUANTUM_MASK WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK
52#define MBOX_DMA_POLICY_TX_QUANTUM_GET(x) WLAN_MBOX_DMA_POLICY_TX_QUANTUM_GET(x)
53#define MBOX_DMA_POLICY_TX_QUANTUM_SET(x) WLAN_MBOX_DMA_POLICY_TX_QUANTUM_SET(x)
54#define MBOX_DMA_POLICY_TX_ORDER_MSB WLAN_MBOX_DMA_POLICY_TX_ORDER_MSB
55#define MBOX_DMA_POLICY_TX_ORDER_LSB WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB
56#define MBOX_DMA_POLICY_TX_ORDER_MASK WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK
57#define MBOX_DMA_POLICY_TX_ORDER_GET(x) WLAN_MBOX_DMA_POLICY_TX_ORDER_GET(x)
58#define MBOX_DMA_POLICY_TX_ORDER_SET(x) WLAN_MBOX_DMA_POLICY_TX_ORDER_SET(x)
59#define MBOX_DMA_POLICY_RX_QUANTUM_MSB WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MSB
60#define MBOX_DMA_POLICY_RX_QUANTUM_LSB WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB
61#define MBOX_DMA_POLICY_RX_QUANTUM_MASK WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK
62#define MBOX_DMA_POLICY_RX_QUANTUM_GET(x) WLAN_MBOX_DMA_POLICY_RX_QUANTUM_GET(x)
63#define MBOX_DMA_POLICY_RX_QUANTUM_SET(x) WLAN_MBOX_DMA_POLICY_RX_QUANTUM_SET(x)
64#define MBOX_DMA_POLICY_RX_ORDER_MSB WLAN_MBOX_DMA_POLICY_RX_ORDER_MSB
65#define MBOX_DMA_POLICY_RX_ORDER_LSB WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB
66#define MBOX_DMA_POLICY_RX_ORDER_MASK WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK
67#define MBOX_DMA_POLICY_RX_ORDER_GET(x) WLAN_MBOX_DMA_POLICY_RX_ORDER_GET(x)
68#define MBOX_DMA_POLICY_RX_ORDER_SET(x) WLAN_MBOX_DMA_POLICY_RX_ORDER_SET(x)
69#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS
70#define MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET
71#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
72#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
73#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
74#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
75#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
76#define MBOX0_DMA_RX_CONTROL_ADDRESS WLAN_MBOX0_DMA_RX_CONTROL_ADDRESS
77#define MBOX0_DMA_RX_CONTROL_OFFSET WLAN_MBOX0_DMA_RX_CONTROL_OFFSET
78#define MBOX0_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MSB
79#define MBOX0_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB
80#define MBOX0_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK
81#define MBOX0_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_RESUME_GET(x)
82#define MBOX0_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_RESUME_SET(x)
83#define MBOX0_DMA_RX_CONTROL_START_MSB WLAN_MBOX0_DMA_RX_CONTROL_START_MSB
84#define MBOX0_DMA_RX_CONTROL_START_LSB WLAN_MBOX0_DMA_RX_CONTROL_START_LSB
85#define MBOX0_DMA_RX_CONTROL_START_MASK WLAN_MBOX0_DMA_RX_CONTROL_START_MASK
86#define MBOX0_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_START_GET(x)
87#define MBOX0_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_START_SET(x)
88#define MBOX0_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX0_DMA_RX_CONTROL_STOP_MSB
89#define MBOX0_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB
90#define MBOX0_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK
91#define MBOX0_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_STOP_GET(x)
92#define MBOX0_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_STOP_SET(x)
93#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS
94#define MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET
95#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
96#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
97#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
98#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
99#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
100#define MBOX0_DMA_TX_CONTROL_ADDRESS WLAN_MBOX0_DMA_TX_CONTROL_ADDRESS
101#define MBOX0_DMA_TX_CONTROL_OFFSET WLAN_MBOX0_DMA_TX_CONTROL_OFFSET
102#define MBOX0_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MSB
103#define MBOX0_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB
104#define MBOX0_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK
105#define MBOX0_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_RESUME_GET(x)
106#define MBOX0_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_RESUME_SET(x)
107#define MBOX0_DMA_TX_CONTROL_START_MSB WLAN_MBOX0_DMA_TX_CONTROL_START_MSB
108#define MBOX0_DMA_TX_CONTROL_START_LSB WLAN_MBOX0_DMA_TX_CONTROL_START_LSB
109#define MBOX0_DMA_TX_CONTROL_START_MASK WLAN_MBOX0_DMA_TX_CONTROL_START_MASK
110#define MBOX0_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_START_GET(x)
111#define MBOX0_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_START_SET(x)
112#define MBOX0_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX0_DMA_TX_CONTROL_STOP_MSB
113#define MBOX0_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB
114#define MBOX0_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK
115#define MBOX0_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_STOP_GET(x)
116#define MBOX0_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_STOP_SET(x)
117#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS
118#define MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET
119#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
120#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
121#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
122#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
123#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
124#define MBOX1_DMA_RX_CONTROL_ADDRESS WLAN_MBOX1_DMA_RX_CONTROL_ADDRESS
125#define MBOX1_DMA_RX_CONTROL_OFFSET WLAN_MBOX1_DMA_RX_CONTROL_OFFSET
126#define MBOX1_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MSB
127#define MBOX1_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB
128#define MBOX1_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK
129#define MBOX1_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_RESUME_GET(x)
130#define MBOX1_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_RESUME_SET(x)
131#define MBOX1_DMA_RX_CONTROL_START_MSB WLAN_MBOX1_DMA_RX_CONTROL_START_MSB
132#define MBOX1_DMA_RX_CONTROL_START_LSB WLAN_MBOX1_DMA_RX_CONTROL_START_LSB
133#define MBOX1_DMA_RX_CONTROL_START_MASK WLAN_MBOX1_DMA_RX_CONTROL_START_MASK
134#define MBOX1_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_START_GET(x)
135#define MBOX1_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_START_SET(x)
136#define MBOX1_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX1_DMA_RX_CONTROL_STOP_MSB
137#define MBOX1_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB
138#define MBOX1_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK
139#define MBOX1_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_STOP_GET(x)
140#define MBOX1_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_STOP_SET(x)
141#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS
142#define MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET
143#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
144#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
145#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
146#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
147#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
148#define MBOX1_DMA_TX_CONTROL_ADDRESS WLAN_MBOX1_DMA_TX_CONTROL_ADDRESS
149#define MBOX1_DMA_TX_CONTROL_OFFSET WLAN_MBOX1_DMA_TX_CONTROL_OFFSET
150#define MBOX1_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MSB
151#define MBOX1_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB
152#define MBOX1_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK
153#define MBOX1_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_RESUME_GET(x)
154#define MBOX1_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_RESUME_SET(x)
155#define MBOX1_DMA_TX_CONTROL_START_MSB WLAN_MBOX1_DMA_TX_CONTROL_START_MSB
156#define MBOX1_DMA_TX_CONTROL_START_LSB WLAN_MBOX1_DMA_TX_CONTROL_START_LSB
157#define MBOX1_DMA_TX_CONTROL_START_MASK WLAN_MBOX1_DMA_TX_CONTROL_START_MASK
158#define MBOX1_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_START_GET(x)
159#define MBOX1_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_START_SET(x)
160#define MBOX1_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX1_DMA_TX_CONTROL_STOP_MSB
161#define MBOX1_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB
162#define MBOX1_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK
163#define MBOX1_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_STOP_GET(x)
164#define MBOX1_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_STOP_SET(x)
165#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS
166#define MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET
167#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
168#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
169#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
170#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
171#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
172#define MBOX2_DMA_RX_CONTROL_ADDRESS WLAN_MBOX2_DMA_RX_CONTROL_ADDRESS
173#define MBOX2_DMA_RX_CONTROL_OFFSET WLAN_MBOX2_DMA_RX_CONTROL_OFFSET
174#define MBOX2_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MSB
175#define MBOX2_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB
176#define MBOX2_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK
177#define MBOX2_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_RESUME_GET(x)
178#define MBOX2_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_RESUME_SET(x)
179#define MBOX2_DMA_RX_CONTROL_START_MSB WLAN_MBOX2_DMA_RX_CONTROL_START_MSB
180#define MBOX2_DMA_RX_CONTROL_START_LSB WLAN_MBOX2_DMA_RX_CONTROL_START_LSB
181#define MBOX2_DMA_RX_CONTROL_START_MASK WLAN_MBOX2_DMA_RX_CONTROL_START_MASK
182#define MBOX2_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_START_GET(x)
183#define MBOX2_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_START_SET(x)
184#define MBOX2_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX2_DMA_RX_CONTROL_STOP_MSB
185#define MBOX2_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB
186#define MBOX2_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK
187#define MBOX2_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_STOP_GET(x)
188#define MBOX2_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_STOP_SET(x)
189#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS
190#define MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET
191#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
192#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
193#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
194#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
195#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
196#define MBOX2_DMA_TX_CONTROL_ADDRESS WLAN_MBOX2_DMA_TX_CONTROL_ADDRESS
197#define MBOX2_DMA_TX_CONTROL_OFFSET WLAN_MBOX2_DMA_TX_CONTROL_OFFSET
198#define MBOX2_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MSB
199#define MBOX2_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB
200#define MBOX2_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK
201#define MBOX2_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_RESUME_GET(x)
202#define MBOX2_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_RESUME_SET(x)
203#define MBOX2_DMA_TX_CONTROL_START_MSB WLAN_MBOX2_DMA_TX_CONTROL_START_MSB
204#define MBOX2_DMA_TX_CONTROL_START_LSB WLAN_MBOX2_DMA_TX_CONTROL_START_LSB
205#define MBOX2_DMA_TX_CONTROL_START_MASK WLAN_MBOX2_DMA_TX_CONTROL_START_MASK
206#define MBOX2_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_START_GET(x)
207#define MBOX2_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_START_SET(x)
208#define MBOX2_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX2_DMA_TX_CONTROL_STOP_MSB
209#define MBOX2_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB
210#define MBOX2_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK
211#define MBOX2_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_STOP_GET(x)
212#define MBOX2_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_STOP_SET(x)
213#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS
214#define MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET
215#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
216#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
217#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
218#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
219#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
220#define MBOX3_DMA_RX_CONTROL_ADDRESS WLAN_MBOX3_DMA_RX_CONTROL_ADDRESS
221#define MBOX3_DMA_RX_CONTROL_OFFSET WLAN_MBOX3_DMA_RX_CONTROL_OFFSET
222#define MBOX3_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MSB
223#define MBOX3_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB
224#define MBOX3_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK
225#define MBOX3_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_RESUME_GET(x)
226#define MBOX3_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_RESUME_SET(x)
227#define MBOX3_DMA_RX_CONTROL_START_MSB WLAN_MBOX3_DMA_RX_CONTROL_START_MSB
228#define MBOX3_DMA_RX_CONTROL_START_LSB WLAN_MBOX3_DMA_RX_CONTROL_START_LSB
229#define MBOX3_DMA_RX_CONTROL_START_MASK WLAN_MBOX3_DMA_RX_CONTROL_START_MASK
230#define MBOX3_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_START_GET(x)
231#define MBOX3_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_START_SET(x)
232#define MBOX3_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX3_DMA_RX_CONTROL_STOP_MSB
233#define MBOX3_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB
234#define MBOX3_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK
235#define MBOX3_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_STOP_GET(x)
236#define MBOX3_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_STOP_SET(x)
237#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS
238#define MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET
239#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
240#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
241#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
242#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
243#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
244#define MBOX3_DMA_TX_CONTROL_ADDRESS WLAN_MBOX3_DMA_TX_CONTROL_ADDRESS
245#define MBOX3_DMA_TX_CONTROL_OFFSET WLAN_MBOX3_DMA_TX_CONTROL_OFFSET
246#define MBOX3_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MSB
247#define MBOX3_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB
248#define MBOX3_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK
249#define MBOX3_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_RESUME_GET(x)
250#define MBOX3_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_RESUME_SET(x)
251#define MBOX3_DMA_TX_CONTROL_START_MSB WLAN_MBOX3_DMA_TX_CONTROL_START_MSB
252#define MBOX3_DMA_TX_CONTROL_START_LSB WLAN_MBOX3_DMA_TX_CONTROL_START_LSB
253#define MBOX3_DMA_TX_CONTROL_START_MASK WLAN_MBOX3_DMA_TX_CONTROL_START_MASK
254#define MBOX3_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_START_GET(x)
255#define MBOX3_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_START_SET(x)
256#define MBOX3_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX3_DMA_TX_CONTROL_STOP_MSB
257#define MBOX3_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB
258#define MBOX3_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK
259#define MBOX3_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_STOP_GET(x)
260#define MBOX3_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_STOP_SET(x)
261#define MBOX_INT_STATUS_ADDRESS WLAN_MBOX_INT_STATUS_ADDRESS
262#define MBOX_INT_STATUS_OFFSET WLAN_MBOX_INT_STATUS_OFFSET
263#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB
264#define MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB
265#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK
266#define MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x)
267#define MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x)
268#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB
269#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB
270#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK
271#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x)
272#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x)
273#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB
274#define MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB
275#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK
276#define MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x)
277#define MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x)
278#define MBOX_INT_STATUS_TX_OVERFLOW_MSB WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MSB
279#define MBOX_INT_STATUS_TX_OVERFLOW_LSB WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB
280#define MBOX_INT_STATUS_TX_OVERFLOW_MASK WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK
281#define MBOX_INT_STATUS_TX_OVERFLOW_GET(x) WLAN_MBOX_INT_STATUS_TX_OVERFLOW_GET(x)
282#define MBOX_INT_STATUS_TX_OVERFLOW_SET(x) WLAN_MBOX_INT_STATUS_TX_OVERFLOW_SET(x)
283#define MBOX_INT_STATUS_RX_UNDERFLOW_MSB WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MSB
284#define MBOX_INT_STATUS_RX_UNDERFLOW_LSB WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB
285#define MBOX_INT_STATUS_RX_UNDERFLOW_MASK WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK
286#define MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_GET(x)
287#define MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_SET(x)
288#define MBOX_INT_STATUS_TX_NOT_EMPTY_MSB WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MSB
289#define MBOX_INT_STATUS_TX_NOT_EMPTY_LSB WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB
290#define MBOX_INT_STATUS_TX_NOT_EMPTY_MASK WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK
291#define MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x)
292#define MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x)
293#define MBOX_INT_STATUS_RX_NOT_FULL_MSB WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MSB
294#define MBOX_INT_STATUS_RX_NOT_FULL_LSB WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB
295#define MBOX_INT_STATUS_RX_NOT_FULL_MASK WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK
296#define MBOX_INT_STATUS_RX_NOT_FULL_GET(x) WLAN_MBOX_INT_STATUS_RX_NOT_FULL_GET(x)
297#define MBOX_INT_STATUS_RX_NOT_FULL_SET(x) WLAN_MBOX_INT_STATUS_RX_NOT_FULL_SET(x)
298#define MBOX_INT_STATUS_HOST_MSB WLAN_MBOX_INT_STATUS_HOST_MSB
299#define MBOX_INT_STATUS_HOST_LSB WLAN_MBOX_INT_STATUS_HOST_LSB
300#define MBOX_INT_STATUS_HOST_MASK WLAN_MBOX_INT_STATUS_HOST_MASK
301#define MBOX_INT_STATUS_HOST_GET(x) WLAN_MBOX_INT_STATUS_HOST_GET(x)
302#define MBOX_INT_STATUS_HOST_SET(x) WLAN_MBOX_INT_STATUS_HOST_SET(x)
303#define MBOX_INT_ENABLE_ADDRESS WLAN_MBOX_INT_ENABLE_ADDRESS
304#define MBOX_INT_ENABLE_OFFSET WLAN_MBOX_INT_ENABLE_OFFSET
305#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB
306#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB
307#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK
308#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x)
309#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x)
310#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB
311#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB
312#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK
313#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x)
314#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x)
315#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB
316#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB
317#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK
318#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x)
319#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x)
320#define MBOX_INT_ENABLE_TX_OVERFLOW_MSB WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MSB
321#define MBOX_INT_ENABLE_TX_OVERFLOW_LSB WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB
322#define MBOX_INT_ENABLE_TX_OVERFLOW_MASK WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK
323#define MBOX_INT_ENABLE_TX_OVERFLOW_GET(x) WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_GET(x)
324#define MBOX_INT_ENABLE_TX_OVERFLOW_SET(x) WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_SET(x)
325#define MBOX_INT_ENABLE_RX_UNDERFLOW_MSB WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MSB
326#define MBOX_INT_ENABLE_RX_UNDERFLOW_LSB WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB
327#define MBOX_INT_ENABLE_RX_UNDERFLOW_MASK WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK
328#define MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x)
329#define MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x)
330#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB
331#define MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB
332#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK
333#define MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x)
334#define MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x)
335#define MBOX_INT_ENABLE_RX_NOT_FULL_MSB WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MSB
336#define MBOX_INT_ENABLE_RX_NOT_FULL_LSB WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB
337#define MBOX_INT_ENABLE_RX_NOT_FULL_MASK WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK
338#define MBOX_INT_ENABLE_RX_NOT_FULL_GET(x) WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_GET(x)
339#define MBOX_INT_ENABLE_RX_NOT_FULL_SET(x) WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_SET(x)
340#define MBOX_INT_ENABLE_HOST_MSB WLAN_MBOX_INT_ENABLE_HOST_MSB
341#define MBOX_INT_ENABLE_HOST_LSB WLAN_MBOX_INT_ENABLE_HOST_LSB
342#define MBOX_INT_ENABLE_HOST_MASK WLAN_MBOX_INT_ENABLE_HOST_MASK
343#define MBOX_INT_ENABLE_HOST_GET(x) WLAN_MBOX_INT_ENABLE_HOST_GET(x)
344#define MBOX_INT_ENABLE_HOST_SET(x) WLAN_MBOX_INT_ENABLE_HOST_SET(x)
345#define INT_HOST_ADDRESS WLAN_INT_HOST_ADDRESS
346#define INT_HOST_OFFSET WLAN_INT_HOST_OFFSET
347#define INT_HOST_VECTOR_MSB WLAN_INT_HOST_VECTOR_MSB
348#define INT_HOST_VECTOR_LSB WLAN_INT_HOST_VECTOR_LSB
349#define INT_HOST_VECTOR_MASK WLAN_INT_HOST_VECTOR_MASK
350#define INT_HOST_VECTOR_GET(x) WLAN_INT_HOST_VECTOR_GET(x)
351#define INT_HOST_VECTOR_SET(x) WLAN_INT_HOST_VECTOR_SET(x)
352#define LOCAL_COUNT_ADDRESS WLAN_LOCAL_COUNT_ADDRESS
353#define LOCAL_COUNT_OFFSET WLAN_LOCAL_COUNT_OFFSET
354#define LOCAL_COUNT_VALUE_MSB WLAN_LOCAL_COUNT_VALUE_MSB
355#define LOCAL_COUNT_VALUE_LSB WLAN_LOCAL_COUNT_VALUE_LSB
356#define LOCAL_COUNT_VALUE_MASK WLAN_LOCAL_COUNT_VALUE_MASK
357#define LOCAL_COUNT_VALUE_GET(x) WLAN_LOCAL_COUNT_VALUE_GET(x)
358#define LOCAL_COUNT_VALUE_SET(x) WLAN_LOCAL_COUNT_VALUE_SET(x)
359#define COUNT_INC_ADDRESS WLAN_COUNT_INC_ADDRESS
360#define COUNT_INC_OFFSET WLAN_COUNT_INC_OFFSET
361#define COUNT_INC_VALUE_MSB WLAN_COUNT_INC_VALUE_MSB
362#define COUNT_INC_VALUE_LSB WLAN_COUNT_INC_VALUE_LSB
363#define COUNT_INC_VALUE_MASK WLAN_COUNT_INC_VALUE_MASK
364#define COUNT_INC_VALUE_GET(x) WLAN_COUNT_INC_VALUE_GET(x)
365#define COUNT_INC_VALUE_SET(x) WLAN_COUNT_INC_VALUE_SET(x)
366#define LOCAL_SCRATCH_ADDRESS WLAN_LOCAL_SCRATCH_ADDRESS
367#define LOCAL_SCRATCH_OFFSET WLAN_LOCAL_SCRATCH_OFFSET
368#define LOCAL_SCRATCH_VALUE_MSB WLAN_LOCAL_SCRATCH_VALUE_MSB
369#define LOCAL_SCRATCH_VALUE_LSB WLAN_LOCAL_SCRATCH_VALUE_LSB
370#define LOCAL_SCRATCH_VALUE_MASK WLAN_LOCAL_SCRATCH_VALUE_MASK
371#define LOCAL_SCRATCH_VALUE_GET(x) WLAN_LOCAL_SCRATCH_VALUE_GET(x)
372#define LOCAL_SCRATCH_VALUE_SET(x) WLAN_LOCAL_SCRATCH_VALUE_SET(x)
373#define USE_LOCAL_BUS_ADDRESS WLAN_USE_LOCAL_BUS_ADDRESS
374#define USE_LOCAL_BUS_OFFSET WLAN_USE_LOCAL_BUS_OFFSET
375#define USE_LOCAL_BUS_PIN_INIT_MSB WLAN_USE_LOCAL_BUS_PIN_INIT_MSB
376#define USE_LOCAL_BUS_PIN_INIT_LSB WLAN_USE_LOCAL_BUS_PIN_INIT_LSB
377#define USE_LOCAL_BUS_PIN_INIT_MASK WLAN_USE_LOCAL_BUS_PIN_INIT_MASK
378#define USE_LOCAL_BUS_PIN_INIT_GET(x) WLAN_USE_LOCAL_BUS_PIN_INIT_GET(x)
379#define USE_LOCAL_BUS_PIN_INIT_SET(x) WLAN_USE_LOCAL_BUS_PIN_INIT_SET(x)
380#define SDIO_CONFIG_ADDRESS WLAN_SDIO_CONFIG_ADDRESS
381#define SDIO_CONFIG_OFFSET WLAN_SDIO_CONFIG_OFFSET
382#define SDIO_CONFIG_CCCR_IOR1_MSB WLAN_SDIO_CONFIG_CCCR_IOR1_MSB
383#define SDIO_CONFIG_CCCR_IOR1_LSB WLAN_SDIO_CONFIG_CCCR_IOR1_LSB
384#define SDIO_CONFIG_CCCR_IOR1_MASK WLAN_SDIO_CONFIG_CCCR_IOR1_MASK
385#define SDIO_CONFIG_CCCR_IOR1_GET(x) WLAN_SDIO_CONFIG_CCCR_IOR1_GET(x)
386#define SDIO_CONFIG_CCCR_IOR1_SET(x) WLAN_SDIO_CONFIG_CCCR_IOR1_SET(x)
387#define MBOX_DEBUG_ADDRESS WLAN_MBOX_DEBUG_ADDRESS
388#define MBOX_DEBUG_OFFSET WLAN_MBOX_DEBUG_OFFSET
389#define MBOX_DEBUG_SEL_MSB WLAN_MBOX_DEBUG_SEL_MSB
390#define MBOX_DEBUG_SEL_LSB WLAN_MBOX_DEBUG_SEL_LSB
391#define MBOX_DEBUG_SEL_MASK WLAN_MBOX_DEBUG_SEL_MASK
392#define MBOX_DEBUG_SEL_GET(x) WLAN_MBOX_DEBUG_SEL_GET(x)
393#define MBOX_DEBUG_SEL_SET(x) WLAN_MBOX_DEBUG_SEL_SET(x)
394#define MBOX_FIFO_RESET_ADDRESS WLAN_MBOX_FIFO_RESET_ADDRESS
395#define MBOX_FIFO_RESET_OFFSET WLAN_MBOX_FIFO_RESET_OFFSET
396#define MBOX_FIFO_RESET_INIT_MSB WLAN_MBOX_FIFO_RESET_INIT_MSB
397#define MBOX_FIFO_RESET_INIT_LSB WLAN_MBOX_FIFO_RESET_INIT_LSB
398#define MBOX_FIFO_RESET_INIT_MASK WLAN_MBOX_FIFO_RESET_INIT_MASK
399#define MBOX_FIFO_RESET_INIT_GET(x) WLAN_MBOX_FIFO_RESET_INIT_GET(x)
400#define MBOX_FIFO_RESET_INIT_SET(x) WLAN_MBOX_FIFO_RESET_INIT_SET(x)
401#define MBOX_TXFIFO_POP_ADDRESS WLAN_MBOX_TXFIFO_POP_ADDRESS
402#define MBOX_TXFIFO_POP_OFFSET WLAN_MBOX_TXFIFO_POP_OFFSET
403#define MBOX_TXFIFO_POP_DATA_MSB WLAN_MBOX_TXFIFO_POP_DATA_MSB
404#define MBOX_TXFIFO_POP_DATA_LSB WLAN_MBOX_TXFIFO_POP_DATA_LSB
405#define MBOX_TXFIFO_POP_DATA_MASK WLAN_MBOX_TXFIFO_POP_DATA_MASK
406#define MBOX_TXFIFO_POP_DATA_GET(x) WLAN_MBOX_TXFIFO_POP_DATA_GET(x)
407#define MBOX_TXFIFO_POP_DATA_SET(x) WLAN_MBOX_TXFIFO_POP_DATA_SET(x)
408#define MBOX_RXFIFO_POP_ADDRESS WLAN_MBOX_RXFIFO_POP_ADDRESS
409#define MBOX_RXFIFO_POP_OFFSET WLAN_MBOX_RXFIFO_POP_OFFSET
410#define MBOX_RXFIFO_POP_DATA_MSB WLAN_MBOX_RXFIFO_POP_DATA_MSB
411#define MBOX_RXFIFO_POP_DATA_LSB WLAN_MBOX_RXFIFO_POP_DATA_LSB
412#define MBOX_RXFIFO_POP_DATA_MASK WLAN_MBOX_RXFIFO_POP_DATA_MASK
413#define MBOX_RXFIFO_POP_DATA_GET(x) WLAN_MBOX_RXFIFO_POP_DATA_GET(x)
414#define MBOX_RXFIFO_POP_DATA_SET(x) WLAN_MBOX_RXFIFO_POP_DATA_SET(x)
415#define SDIO_DEBUG_ADDRESS WLAN_SDIO_DEBUG_ADDRESS
416#define SDIO_DEBUG_OFFSET WLAN_SDIO_DEBUG_OFFSET
417#define SDIO_DEBUG_SEL_MSB WLAN_SDIO_DEBUG_SEL_MSB
418#define SDIO_DEBUG_SEL_LSB WLAN_SDIO_DEBUG_SEL_LSB
419#define SDIO_DEBUG_SEL_MASK WLAN_SDIO_DEBUG_SEL_MASK
420#define SDIO_DEBUG_SEL_GET(x) WLAN_SDIO_DEBUG_SEL_GET(x)
421#define SDIO_DEBUG_SEL_SET(x) WLAN_SDIO_DEBUG_SEL_SET(x)
422#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS
423#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET
424#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
425#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
426#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
427#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
428#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
429#define GMBOX0_DMA_RX_CONTROL_ADDRESS WLAN_GMBOX0_DMA_RX_CONTROL_ADDRESS
430#define GMBOX0_DMA_RX_CONTROL_OFFSET WLAN_GMBOX0_DMA_RX_CONTROL_OFFSET
431#define GMBOX0_DMA_RX_CONTROL_RESUME_MSB WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MSB
432#define GMBOX0_DMA_RX_CONTROL_RESUME_LSB WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB
433#define GMBOX0_DMA_RX_CONTROL_RESUME_MASK WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK
434#define GMBOX0_DMA_RX_CONTROL_RESUME_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_GET(x)
435#define GMBOX0_DMA_RX_CONTROL_RESUME_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_SET(x)
436#define GMBOX0_DMA_RX_CONTROL_START_MSB WLAN_GMBOX0_DMA_RX_CONTROL_START_MSB
437#define GMBOX0_DMA_RX_CONTROL_START_LSB WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB
438#define GMBOX0_DMA_RX_CONTROL_START_MASK WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK
439#define GMBOX0_DMA_RX_CONTROL_START_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_START_GET(x)
440#define GMBOX0_DMA_RX_CONTROL_START_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_START_SET(x)
441#define GMBOX0_DMA_RX_CONTROL_STOP_MSB WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MSB
442#define GMBOX0_DMA_RX_CONTROL_STOP_LSB WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB
443#define GMBOX0_DMA_RX_CONTROL_STOP_MASK WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK
444#define GMBOX0_DMA_RX_CONTROL_STOP_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_STOP_GET(x)
445#define GMBOX0_DMA_RX_CONTROL_STOP_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_STOP_SET(x)
446#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS
447#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET
448#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
449#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
450#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
451#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
452#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
453#define GMBOX0_DMA_TX_CONTROL_ADDRESS WLAN_GMBOX0_DMA_TX_CONTROL_ADDRESS
454#define GMBOX0_DMA_TX_CONTROL_OFFSET WLAN_GMBOX0_DMA_TX_CONTROL_OFFSET
455#define GMBOX0_DMA_TX_CONTROL_RESUME_MSB WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MSB
456#define GMBOX0_DMA_TX_CONTROL_RESUME_LSB WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB
457#define GMBOX0_DMA_TX_CONTROL_RESUME_MASK WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK
458#define GMBOX0_DMA_TX_CONTROL_RESUME_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_GET(x)
459#define GMBOX0_DMA_TX_CONTROL_RESUME_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_SET(x)
460#define GMBOX0_DMA_TX_CONTROL_START_MSB WLAN_GMBOX0_DMA_TX_CONTROL_START_MSB
461#define GMBOX0_DMA_TX_CONTROL_START_LSB WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB
462#define GMBOX0_DMA_TX_CONTROL_START_MASK WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK
463#define GMBOX0_DMA_TX_CONTROL_START_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_START_GET(x)
464#define GMBOX0_DMA_TX_CONTROL_START_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_START_SET(x)
465#define GMBOX0_DMA_TX_CONTROL_STOP_MSB WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MSB
466#define GMBOX0_DMA_TX_CONTROL_STOP_LSB WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB
467#define GMBOX0_DMA_TX_CONTROL_STOP_MASK WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK
468#define GMBOX0_DMA_TX_CONTROL_STOP_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_STOP_GET(x)
469#define GMBOX0_DMA_TX_CONTROL_STOP_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_STOP_SET(x)
470#define GMBOX_INT_STATUS_ADDRESS WLAN_GMBOX_INT_STATUS_ADDRESS
471#define GMBOX_INT_STATUS_OFFSET WLAN_GMBOX_INT_STATUS_OFFSET
472#define GMBOX_INT_STATUS_TX_OVERFLOW_MSB WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MSB
473#define GMBOX_INT_STATUS_TX_OVERFLOW_LSB WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB
474#define GMBOX_INT_STATUS_TX_OVERFLOW_MASK WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK
475#define GMBOX_INT_STATUS_TX_OVERFLOW_GET(x) WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_GET(x)
476#define GMBOX_INT_STATUS_TX_OVERFLOW_SET(x) WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_SET(x)
477#define GMBOX_INT_STATUS_RX_UNDERFLOW_MSB WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MSB
478#define GMBOX_INT_STATUS_RX_UNDERFLOW_LSB WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB
479#define GMBOX_INT_STATUS_RX_UNDERFLOW_MASK WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK
480#define GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x) WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x)
481#define GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x) WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x)
482#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB
483#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB
484#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK
485#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x)
486#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x)
487#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB
488#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB
489#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK
490#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x)
491#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x)
492#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB
493#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB
494#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK
495#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x)
496#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x)
497#define GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB
498#define GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB
499#define GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK
500#define GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x)
501#define GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x)
502#define GMBOX_INT_STATUS_RX_NOT_FULL_MSB WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MSB
503#define GMBOX_INT_STATUS_RX_NOT_FULL_LSB WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB
504#define GMBOX_INT_STATUS_RX_NOT_FULL_MASK WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK
505#define GMBOX_INT_STATUS_RX_NOT_FULL_GET(x) WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_GET(x)
506#define GMBOX_INT_STATUS_RX_NOT_FULL_SET(x) WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_SET(x)
507#define GMBOX_INT_ENABLE_ADDRESS WLAN_GMBOX_INT_ENABLE_ADDRESS
508#define GMBOX_INT_ENABLE_OFFSET WLAN_GMBOX_INT_ENABLE_OFFSET
509#define GMBOX_INT_ENABLE_TX_OVERFLOW_MSB WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MSB
510#define GMBOX_INT_ENABLE_TX_OVERFLOW_LSB WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB
511#define GMBOX_INT_ENABLE_TX_OVERFLOW_MASK WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK
512#define GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x) WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x)
513#define GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x) WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x)
514#define GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB
515#define GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB
516#define GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK
517#define GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x)
518#define GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x)
519#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB
520#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB
521#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK
522#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x)
523#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x)
524#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB
525#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB
526#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK
527#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x)
528#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x)
529#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB
530#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB
531#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK
532#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x)
533#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x)
534#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB
535#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB
536#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK
537#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x)
538#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x)
539#define GMBOX_INT_ENABLE_RX_NOT_FULL_MSB WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MSB
540#define GMBOX_INT_ENABLE_RX_NOT_FULL_LSB WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB
541#define GMBOX_INT_ENABLE_RX_NOT_FULL_MASK WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK
542#define GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x) WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x)
543#define GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x) WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x)
544#define HOST_IF_WINDOW_ADDRESS WLAN_HOST_IF_WINDOW_ADDRESS
545#define HOST_IF_WINDOW_OFFSET WLAN_HOST_IF_WINDOW_OFFSET
546#define HOST_IF_WINDOW_DATA_MSB WLAN_HOST_IF_WINDOW_DATA_MSB
547#define HOST_IF_WINDOW_DATA_LSB WLAN_HOST_IF_WINDOW_DATA_LSB
548#define HOST_IF_WINDOW_DATA_MASK WLAN_HOST_IF_WINDOW_DATA_MASK
549#define HOST_IF_WINDOW_DATA_GET(x) WLAN_HOST_IF_WINDOW_DATA_GET(x)
550#define HOST_IF_WINDOW_DATA_SET(x) WLAN_HOST_IF_WINDOW_DATA_SET(x)
551
552#endif
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h
deleted file mode 100644
index 038d0d01927..00000000000
--- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h
+++ /dev/null
@@ -1,471 +0,0 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#ifndef _MBOX_WLAN_HOST_REG_REG_H_
25#define _MBOX_WLAN_HOST_REG_REG_H_
26
27#define HOST_INT_STATUS_ADDRESS 0x00000400
28#define HOST_INT_STATUS_OFFSET 0x00000400
29#define HOST_INT_STATUS_ERROR_MSB 7
30#define HOST_INT_STATUS_ERROR_LSB 7
31#define HOST_INT_STATUS_ERROR_MASK 0x00000080
32#define HOST_INT_STATUS_ERROR_GET(x) (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB)
33#define HOST_INT_STATUS_ERROR_SET(x) (((x) << HOST_INT_STATUS_ERROR_LSB) & HOST_INT_STATUS_ERROR_MASK)
34#define HOST_INT_STATUS_CPU_MSB 6
35#define HOST_INT_STATUS_CPU_LSB 6
36#define HOST_INT_STATUS_CPU_MASK 0x00000040
37#define HOST_INT_STATUS_CPU_GET(x) (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB)
38#define HOST_INT_STATUS_CPU_SET(x) (((x) << HOST_INT_STATUS_CPU_LSB) & HOST_INT_STATUS_CPU_MASK)
39#define HOST_INT_STATUS_INT_MSB 5
40#define HOST_INT_STATUS_INT_LSB 5
41#define HOST_INT_STATUS_INT_MASK 0x00000020
42#define HOST_INT_STATUS_INT_GET(x) (((x) & HOST_INT_STATUS_INT_MASK) >> HOST_INT_STATUS_INT_LSB)
43#define HOST_INT_STATUS_INT_SET(x) (((x) << HOST_INT_STATUS_INT_LSB) & HOST_INT_STATUS_INT_MASK)
44#define HOST_INT_STATUS_COUNTER_MSB 4
45#define HOST_INT_STATUS_COUNTER_LSB 4
46#define HOST_INT_STATUS_COUNTER_MASK 0x00000010
47#define HOST_INT_STATUS_COUNTER_GET(x) (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB)
48#define HOST_INT_STATUS_COUNTER_SET(x) (((x) << HOST_INT_STATUS_COUNTER_LSB) & HOST_INT_STATUS_COUNTER_MASK)
49#define HOST_INT_STATUS_MBOX_DATA_MSB 3
50#define HOST_INT_STATUS_MBOX_DATA_LSB 0
51#define HOST_INT_STATUS_MBOX_DATA_MASK 0x0000000f
52#define HOST_INT_STATUS_MBOX_DATA_GET(x) (((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> HOST_INT_STATUS_MBOX_DATA_LSB)
53#define HOST_INT_STATUS_MBOX_DATA_SET(x) (((x) << HOST_INT_STATUS_MBOX_DATA_LSB) & HOST_INT_STATUS_MBOX_DATA_MASK)
54
55#define CPU_INT_STATUS_ADDRESS 0x00000401
56#define CPU_INT_STATUS_OFFSET 0x00000401
57#define CPU_INT_STATUS_BIT_MSB 7
58#define CPU_INT_STATUS_BIT_LSB 0
59#define CPU_INT_STATUS_BIT_MASK 0x000000ff
60#define CPU_INT_STATUS_BIT_GET(x) (((x) & CPU_INT_STATUS_BIT_MASK) >> CPU_INT_STATUS_BIT_LSB)
61#define CPU_INT_STATUS_BIT_SET(x) (((x) << CPU_INT_STATUS_BIT_LSB) & CPU_INT_STATUS_BIT_MASK)
62
63#define ERROR_INT_STATUS_ADDRESS 0x00000402
64#define ERROR_INT_STATUS_OFFSET 0x00000402
65#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MSB 6
66#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB 6
67#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK 0x00000040
68#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB)
69#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK)
70#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MSB 5
71#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB 5
72#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK 0x00000020
73#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB)
74#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK)
75#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MSB 4
76#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB 4
77#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK 0x00000010
78#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB)
79#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK)
80#define ERROR_INT_STATUS_SPI_MSB 3
81#define ERROR_INT_STATUS_SPI_LSB 3
82#define ERROR_INT_STATUS_SPI_MASK 0x00000008
83#define ERROR_INT_STATUS_SPI_GET(x) (((x) & ERROR_INT_STATUS_SPI_MASK) >> ERROR_INT_STATUS_SPI_LSB)
84#define ERROR_INT_STATUS_SPI_SET(x) (((x) << ERROR_INT_STATUS_SPI_LSB) & ERROR_INT_STATUS_SPI_MASK)
85#define ERROR_INT_STATUS_WAKEUP_MSB 2
86#define ERROR_INT_STATUS_WAKEUP_LSB 2
87#define ERROR_INT_STATUS_WAKEUP_MASK 0x00000004
88#define ERROR_INT_STATUS_WAKEUP_GET(x) (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB)
89#define ERROR_INT_STATUS_WAKEUP_SET(x) (((x) << ERROR_INT_STATUS_WAKEUP_LSB) & ERROR_INT_STATUS_WAKEUP_MASK)
90#define ERROR_INT_STATUS_RX_UNDERFLOW_MSB 1
91#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB 1
92#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00000002
93#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB)
94#define ERROR_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << ERROR_INT_STATUS_RX_UNDERFLOW_LSB) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK)
95#define ERROR_INT_STATUS_TX_OVERFLOW_MSB 0
96#define ERROR_INT_STATUS_TX_OVERFLOW_LSB 0
97#define ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00000001
98#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB)
99#define ERROR_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << ERROR_INT_STATUS_TX_OVERFLOW_LSB) & ERROR_INT_STATUS_TX_OVERFLOW_MASK)
100
101#define COUNTER_INT_STATUS_ADDRESS 0x00000403
102#define COUNTER_INT_STATUS_OFFSET 0x00000403
103#define COUNTER_INT_STATUS_COUNTER_MSB 7
104#define COUNTER_INT_STATUS_COUNTER_LSB 0
105#define COUNTER_INT_STATUS_COUNTER_MASK 0x000000ff
106#define COUNTER_INT_STATUS_COUNTER_GET(x) (((x) & COUNTER_INT_STATUS_COUNTER_MASK) >> COUNTER_INT_STATUS_COUNTER_LSB)
107#define COUNTER_INT_STATUS_COUNTER_SET(x) (((x) << COUNTER_INT_STATUS_COUNTER_LSB) & COUNTER_INT_STATUS_COUNTER_MASK)
108
109#define MBOX_FRAME_ADDRESS 0x00000404
110#define MBOX_FRAME_OFFSET 0x00000404
111#define MBOX_FRAME_RX_EOM_MSB 7
112#define MBOX_FRAME_RX_EOM_LSB 4
113#define MBOX_FRAME_RX_EOM_MASK 0x000000f0
114#define MBOX_FRAME_RX_EOM_GET(x) (((x) & MBOX_FRAME_RX_EOM_MASK) >> MBOX_FRAME_RX_EOM_LSB)
115#define MBOX_FRAME_RX_EOM_SET(x) (((x) << MBOX_FRAME_RX_EOM_LSB) & MBOX_FRAME_RX_EOM_MASK)
116#define MBOX_FRAME_RX_SOM_MSB 3
117#define MBOX_FRAME_RX_SOM_LSB 0
118#define MBOX_FRAME_RX_SOM_MASK 0x0000000f
119#define MBOX_FRAME_RX_SOM_GET(x) (((x) & MBOX_FRAME_RX_SOM_MASK) >> MBOX_FRAME_RX_SOM_LSB)
120#define MBOX_FRAME_RX_SOM_SET(x) (((x) << MBOX_FRAME_RX_SOM_LSB) & MBOX_FRAME_RX_SOM_MASK)
121
122#define RX_LOOKAHEAD_VALID_ADDRESS 0x00000405
123#define RX_LOOKAHEAD_VALID_OFFSET 0x00000405
124#define RX_LOOKAHEAD_VALID_MBOX_MSB 3
125#define RX_LOOKAHEAD_VALID_MBOX_LSB 0
126#define RX_LOOKAHEAD_VALID_MBOX_MASK 0x0000000f
127#define RX_LOOKAHEAD_VALID_MBOX_GET(x) (((x) & RX_LOOKAHEAD_VALID_MBOX_MASK) >> RX_LOOKAHEAD_VALID_MBOX_LSB)
128#define RX_LOOKAHEAD_VALID_MBOX_SET(x) (((x) << RX_LOOKAHEAD_VALID_MBOX_LSB) & RX_LOOKAHEAD_VALID_MBOX_MASK)
129
130#define HOST_INT_STATUS2_ADDRESS 0x00000406
131#define HOST_INT_STATUS2_OFFSET 0x00000406
132#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MSB 2
133#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB 2
134#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK 0x00000004
135#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK) >> HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB)
136#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB) & HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK)
137#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MSB 1
138#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB 1
139#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK 0x00000002
140#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK) >> HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB)
141#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB) & HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK)
142#define HOST_INT_STATUS2_GMBOX_DATA_MSB 0
143#define HOST_INT_STATUS2_GMBOX_DATA_LSB 0
144#define HOST_INT_STATUS2_GMBOX_DATA_MASK 0x00000001
145#define HOST_INT_STATUS2_GMBOX_DATA_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_DATA_MASK) >> HOST_INT_STATUS2_GMBOX_DATA_LSB)
146#define HOST_INT_STATUS2_GMBOX_DATA_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_DATA_LSB) & HOST_INT_STATUS2_GMBOX_DATA_MASK)
147
148#define GMBOX_RX_AVAIL_ADDRESS 0x00000407
149#define GMBOX_RX_AVAIL_OFFSET 0x00000407
150#define GMBOX_RX_AVAIL_BYTE_MSB 6
151#define GMBOX_RX_AVAIL_BYTE_LSB 0
152#define GMBOX_RX_AVAIL_BYTE_MASK 0x0000007f
153#define GMBOX_RX_AVAIL_BYTE_GET(x) (((x) & GMBOX_RX_AVAIL_BYTE_MASK) >> GMBOX_RX_AVAIL_BYTE_LSB)
154#define GMBOX_RX_AVAIL_BYTE_SET(x) (((x) << GMBOX_RX_AVAIL_BYTE_LSB) & GMBOX_RX_AVAIL_BYTE_MASK)
155
156#define RX_LOOKAHEAD0_ADDRESS 0x00000408
157#define RX_LOOKAHEAD0_OFFSET 0x00000408
158#define RX_LOOKAHEAD0_DATA_MSB 7
159#define RX_LOOKAHEAD0_DATA_LSB 0
160#define RX_LOOKAHEAD0_DATA_MASK 0x000000ff
161#define RX_LOOKAHEAD0_DATA_GET(x) (((x) & RX_LOOKAHEAD0_DATA_MASK) >> RX_LOOKAHEAD0_DATA_LSB)
162#define RX_LOOKAHEAD0_DATA_SET(x) (((x) << RX_LOOKAHEAD0_DATA_LSB) & RX_LOOKAHEAD0_DATA_MASK)
163
164#define RX_LOOKAHEAD1_ADDRESS 0x0000040c
165#define RX_LOOKAHEAD1_OFFSET 0x0000040c
166#define RX_LOOKAHEAD1_DATA_MSB 7
167#define RX_LOOKAHEAD1_DATA_LSB 0
168#define RX_LOOKAHEAD1_DATA_MASK 0x000000ff
169#define RX_LOOKAHEAD1_DATA_GET(x) (((x) & RX_LOOKAHEAD1_DATA_MASK) >> RX_LOOKAHEAD1_DATA_LSB)
170#define RX_LOOKAHEAD1_DATA_SET(x) (((x) << RX_LOOKAHEAD1_DATA_LSB) & RX_LOOKAHEAD1_DATA_MASK)
171
172#define RX_LOOKAHEAD2_ADDRESS 0x00000410
173#define RX_LOOKAHEAD2_OFFSET 0x00000410
174#define RX_LOOKAHEAD2_DATA_MSB 7
175#define RX_LOOKAHEAD2_DATA_LSB 0
176#define RX_LOOKAHEAD2_DATA_MASK 0x000000ff
177#define RX_LOOKAHEAD2_DATA_GET(x) (((x) & RX_LOOKAHEAD2_DATA_MASK) >> RX_LOOKAHEAD2_DATA_LSB)
178#define RX_LOOKAHEAD2_DATA_SET(x) (((x) << RX_LOOKAHEAD2_DATA_LSB) & RX_LOOKAHEAD2_DATA_MASK)
179
180#define RX_LOOKAHEAD3_ADDRESS 0x00000414
181#define RX_LOOKAHEAD3_OFFSET 0x00000414
182#define RX_LOOKAHEAD3_DATA_MSB 7
183#define RX_LOOKAHEAD3_DATA_LSB 0
184#define RX_LOOKAHEAD3_DATA_MASK 0x000000ff
185#define RX_LOOKAHEAD3_DATA_GET(x) (((x) & RX_LOOKAHEAD3_DATA_MASK) >> RX_LOOKAHEAD3_DATA_LSB)
186#define RX_LOOKAHEAD3_DATA_SET(x) (((x) << RX_LOOKAHEAD3_DATA_LSB) & RX_LOOKAHEAD3_DATA_MASK)
187
188#define INT_STATUS_ENABLE_ADDRESS 0x00000418
189#define INT_STATUS_ENABLE_OFFSET 0x00000418
190#define INT_STATUS_ENABLE_ERROR_MSB 7
191#define INT_STATUS_ENABLE_ERROR_LSB 7
192#define INT_STATUS_ENABLE_ERROR_MASK 0x00000080
193#define INT_STATUS_ENABLE_ERROR_GET(x) (((x) & INT_STATUS_ENABLE_ERROR_MASK) >> INT_STATUS_ENABLE_ERROR_LSB)
194#define INT_STATUS_ENABLE_ERROR_SET(x) (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK)
195#define INT_STATUS_ENABLE_CPU_MSB 6
196#define INT_STATUS_ENABLE_CPU_LSB 6
197#define INT_STATUS_ENABLE_CPU_MASK 0x00000040
198#define INT_STATUS_ENABLE_CPU_GET(x) (((x) & INT_STATUS_ENABLE_CPU_MASK) >> INT_STATUS_ENABLE_CPU_LSB)
199#define INT_STATUS_ENABLE_CPU_SET(x) (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK)
200#define INT_STATUS_ENABLE_INT_MSB 5
201#define INT_STATUS_ENABLE_INT_LSB 5
202#define INT_STATUS_ENABLE_INT_MASK 0x00000020
203#define INT_STATUS_ENABLE_INT_GET(x) (((x) & INT_STATUS_ENABLE_INT_MASK) >> INT_STATUS_ENABLE_INT_LSB)
204#define INT_STATUS_ENABLE_INT_SET(x) (((x) << INT_STATUS_ENABLE_INT_LSB) & INT_STATUS_ENABLE_INT_MASK)
205#define INT_STATUS_ENABLE_COUNTER_MSB 4
206#define INT_STATUS_ENABLE_COUNTER_LSB 4
207#define INT_STATUS_ENABLE_COUNTER_MASK 0x00000010
208#define INT_STATUS_ENABLE_COUNTER_GET(x) (((x) & INT_STATUS_ENABLE_COUNTER_MASK) >> INT_STATUS_ENABLE_COUNTER_LSB)
209#define INT_STATUS_ENABLE_COUNTER_SET(x) (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK)
210#define INT_STATUS_ENABLE_MBOX_DATA_MSB 3
211#define INT_STATUS_ENABLE_MBOX_DATA_LSB 0
212#define INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f
213#define INT_STATUS_ENABLE_MBOX_DATA_GET(x) (((x) & INT_STATUS_ENABLE_MBOX_DATA_MASK) >> INT_STATUS_ENABLE_MBOX_DATA_LSB)
214#define INT_STATUS_ENABLE_MBOX_DATA_SET(x) (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK)
215
216#define CPU_INT_STATUS_ENABLE_ADDRESS 0x00000419
217#define CPU_INT_STATUS_ENABLE_OFFSET 0x00000419
218#define CPU_INT_STATUS_ENABLE_BIT_MSB 7
219#define CPU_INT_STATUS_ENABLE_BIT_LSB 0
220#define CPU_INT_STATUS_ENABLE_BIT_MASK 0x000000ff
221#define CPU_INT_STATUS_ENABLE_BIT_GET(x) (((x) & CPU_INT_STATUS_ENABLE_BIT_MASK) >> CPU_INT_STATUS_ENABLE_BIT_LSB)
222#define CPU_INT_STATUS_ENABLE_BIT_SET(x) (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK)
223
224#define ERROR_STATUS_ENABLE_ADDRESS 0x0000041a
225#define ERROR_STATUS_ENABLE_OFFSET 0x0000041a
226#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MSB 6
227#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB 6
228#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK 0x00000040
229#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB)
230#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK)
231#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MSB 5
232#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB 5
233#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK 0x00000020
234#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB)
235#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK)
236#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MSB 4
237#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB 4
238#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK 0x00000010
239#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB)
240#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK)
241#define ERROR_STATUS_ENABLE_WAKEUP_MSB 2
242#define ERROR_STATUS_ENABLE_WAKEUP_LSB 2
243#define ERROR_STATUS_ENABLE_WAKEUP_MASK 0x00000004
244#define ERROR_STATUS_ENABLE_WAKEUP_GET(x) (((x) & ERROR_STATUS_ENABLE_WAKEUP_MASK) >> ERROR_STATUS_ENABLE_WAKEUP_LSB)
245#define ERROR_STATUS_ENABLE_WAKEUP_SET(x) (((x) << ERROR_STATUS_ENABLE_WAKEUP_LSB) & ERROR_STATUS_ENABLE_WAKEUP_MASK)
246#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MSB 1
247#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 1
248#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00000002
249#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB)
250#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK)
251#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MSB 0
252#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 0
253#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00000001
254#define ERROR_STATUS_ENABLE_TX_OVERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB)
255#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK)
256
257#define COUNTER_INT_STATUS_ENABLE_ADDRESS 0x0000041b
258#define COUNTER_INT_STATUS_ENABLE_OFFSET 0x0000041b
259#define COUNTER_INT_STATUS_ENABLE_BIT_MSB 7
260#define COUNTER_INT_STATUS_ENABLE_BIT_LSB 0
261#define COUNTER_INT_STATUS_ENABLE_BIT_MASK 0x000000ff
262#define COUNTER_INT_STATUS_ENABLE_BIT_GET(x) (((x) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) >> COUNTER_INT_STATUS_ENABLE_BIT_LSB)
263#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK)
264
265#define COUNT_ADDRESS 0x00000420
266#define COUNT_OFFSET 0x00000420
267#define COUNT_VALUE_MSB 7
268#define COUNT_VALUE_LSB 0
269#define COUNT_VALUE_MASK 0x000000ff
270#define COUNT_VALUE_GET(x) (((x) & COUNT_VALUE_MASK) >> COUNT_VALUE_LSB)
271#define COUNT_VALUE_SET(x) (((x) << COUNT_VALUE_LSB) & COUNT_VALUE_MASK)
272
273#define COUNT_DEC_ADDRESS 0x00000440
274#define COUNT_DEC_OFFSET 0x00000440
275#define COUNT_DEC_VALUE_MSB 7
276#define COUNT_DEC_VALUE_LSB 0
277#define COUNT_DEC_VALUE_MASK 0x000000ff
278#define COUNT_DEC_VALUE_GET(x) (((x) & COUNT_DEC_VALUE_MASK) >> COUNT_DEC_VALUE_LSB)
279#define COUNT_DEC_VALUE_SET(x) (((x) << COUNT_DEC_VALUE_LSB) & COUNT_DEC_VALUE_MASK)
280
281#define SCRATCH_ADDRESS 0x00000460
282#define SCRATCH_OFFSET 0x00000460
283#define SCRATCH_VALUE_MSB 7
284#define SCRATCH_VALUE_LSB 0
285#define SCRATCH_VALUE_MASK 0x000000ff
286#define SCRATCH_VALUE_GET(x) (((x) & SCRATCH_VALUE_MASK) >> SCRATCH_VALUE_LSB)
287#define SCRATCH_VALUE_SET(x) (((x) << SCRATCH_VALUE_LSB) & SCRATCH_VALUE_MASK)
288
289#define FIFO_TIMEOUT_ADDRESS 0x00000468
290#define FIFO_TIMEOUT_OFFSET 0x00000468
291#define FIFO_TIMEOUT_VALUE_MSB 7
292#define FIFO_TIMEOUT_VALUE_LSB 0
293#define FIFO_TIMEOUT_VALUE_MASK 0x000000ff
294#define FIFO_TIMEOUT_VALUE_GET(x) (((x) & FIFO_TIMEOUT_VALUE_MASK) >> FIFO_TIMEOUT_VALUE_LSB)
295#define FIFO_TIMEOUT_VALUE_SET(x) (((x) << FIFO_TIMEOUT_VALUE_LSB) & FIFO_TIMEOUT_VALUE_MASK)
296
297#define FIFO_TIMEOUT_ENABLE_ADDRESS 0x00000469
298#define FIFO_TIMEOUT_ENABLE_OFFSET 0x00000469
299#define FIFO_TIMEOUT_ENABLE_SET_MSB 0
300#define FIFO_TIMEOUT_ENABLE_SET_LSB 0
301#define FIFO_TIMEOUT_ENABLE_SET_MASK 0x00000001
302#define FIFO_TIMEOUT_ENABLE_SET_GET(x) (((x) & FIFO_TIMEOUT_ENABLE_SET_MASK) >> FIFO_TIMEOUT_ENABLE_SET_LSB)
303#define FIFO_TIMEOUT_ENABLE_SET_SET(x) (((x) << FIFO_TIMEOUT_ENABLE_SET_LSB) & FIFO_TIMEOUT_ENABLE_SET_MASK)
304
305#define DISABLE_SLEEP_ADDRESS 0x0000046a
306#define DISABLE_SLEEP_OFFSET 0x0000046a
307#define DISABLE_SLEEP_FOR_INT_MSB 1
308#define DISABLE_SLEEP_FOR_INT_LSB 1
309#define DISABLE_SLEEP_FOR_INT_MASK 0x00000002
310#define DISABLE_SLEEP_FOR_INT_GET(x) (((x) & DISABLE_SLEEP_FOR_INT_MASK) >> DISABLE_SLEEP_FOR_INT_LSB)
311#define DISABLE_SLEEP_FOR_INT_SET(x) (((x) << DISABLE_SLEEP_FOR_INT_LSB) & DISABLE_SLEEP_FOR_INT_MASK)
312#define DISABLE_SLEEP_ON_MSB 0
313#define DISABLE_SLEEP_ON_LSB 0
314#define DISABLE_SLEEP_ON_MASK 0x00000001
315#define DISABLE_SLEEP_ON_GET(x) (((x) & DISABLE_SLEEP_ON_MASK) >> DISABLE_SLEEP_ON_LSB)
316#define DISABLE_SLEEP_ON_SET(x) (((x) << DISABLE_SLEEP_ON_LSB) & DISABLE_SLEEP_ON_MASK)
317
318#define LOCAL_BUS_ADDRESS 0x00000470
319#define LOCAL_BUS_OFFSET 0x00000470
320#define LOCAL_BUS_STATE_MSB 1
321#define LOCAL_BUS_STATE_LSB 0
322#define LOCAL_BUS_STATE_MASK 0x00000003
323#define LOCAL_BUS_STATE_GET(x) (((x) & LOCAL_BUS_STATE_MASK) >> LOCAL_BUS_STATE_LSB)
324#define LOCAL_BUS_STATE_SET(x) (((x) << LOCAL_BUS_STATE_LSB) & LOCAL_BUS_STATE_MASK)
325
326#define INT_WLAN_ADDRESS 0x00000472
327#define INT_WLAN_OFFSET 0x00000472
328#define INT_WLAN_VECTOR_MSB 7
329#define INT_WLAN_VECTOR_LSB 0
330#define INT_WLAN_VECTOR_MASK 0x000000ff
331#define INT_WLAN_VECTOR_GET(x) (((x) & INT_WLAN_VECTOR_MASK) >> INT_WLAN_VECTOR_LSB)
332#define INT_WLAN_VECTOR_SET(x) (((x) << INT_WLAN_VECTOR_LSB) & INT_WLAN_VECTOR_MASK)
333
334#define WINDOW_DATA_ADDRESS 0x00000474
335#define WINDOW_DATA_OFFSET 0x00000474
336#define WINDOW_DATA_DATA_MSB 7
337#define WINDOW_DATA_DATA_LSB 0
338#define WINDOW_DATA_DATA_MASK 0x000000ff
339#define WINDOW_DATA_DATA_GET(x) (((x) & WINDOW_DATA_DATA_MASK) >> WINDOW_DATA_DATA_LSB)
340#define WINDOW_DATA_DATA_SET(x) (((x) << WINDOW_DATA_DATA_LSB) & WINDOW_DATA_DATA_MASK)
341
342#define WINDOW_WRITE_ADDR_ADDRESS 0x00000478
343#define WINDOW_WRITE_ADDR_OFFSET 0x00000478
344#define WINDOW_WRITE_ADDR_ADDR_MSB 7
345#define WINDOW_WRITE_ADDR_ADDR_LSB 0
346#define WINDOW_WRITE_ADDR_ADDR_MASK 0x000000ff
347#define WINDOW_WRITE_ADDR_ADDR_GET(x) (((x) & WINDOW_WRITE_ADDR_ADDR_MASK) >> WINDOW_WRITE_ADDR_ADDR_LSB)
348#define WINDOW_WRITE_ADDR_ADDR_SET(x) (((x) << WINDOW_WRITE_ADDR_ADDR_LSB) & WINDOW_WRITE_ADDR_ADDR_MASK)
349
350#define WINDOW_READ_ADDR_ADDRESS 0x0000047c
351#define WINDOW_READ_ADDR_OFFSET 0x0000047c
352#define WINDOW_READ_ADDR_ADDR_MSB 7
353#define WINDOW_READ_ADDR_ADDR_LSB 0
354#define WINDOW_READ_ADDR_ADDR_MASK 0x000000ff
355#define WINDOW_READ_ADDR_ADDR_GET(x) (((x) & WINDOW_READ_ADDR_ADDR_MASK) >> WINDOW_READ_ADDR_ADDR_LSB)
356#define WINDOW_READ_ADDR_ADDR_SET(x) (((x) << WINDOW_READ_ADDR_ADDR_LSB) & WINDOW_READ_ADDR_ADDR_MASK)
357
358#define HOST_CTRL_SPI_CONFIG_ADDRESS 0x00000480
359#define HOST_CTRL_SPI_CONFIG_OFFSET 0x00000480
360#define HOST_CTRL_SPI_CONFIG_SPI_RESET_MSB 4
361#define HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB 4
362#define HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK 0x00000010
363#define HOST_CTRL_SPI_CONFIG_SPI_RESET_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK) >> HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB)
364#define HOST_CTRL_SPI_CONFIG_SPI_RESET_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB) & HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK)
365#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MSB 3
366#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB 3
367#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK 0x00000008
368#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK) >> HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB)
369#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB) & HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK)
370#define HOST_CTRL_SPI_CONFIG_TEST_MODE_MSB 2
371#define HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB 2
372#define HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK 0x00000004
373#define HOST_CTRL_SPI_CONFIG_TEST_MODE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK) >> HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB)
374#define HOST_CTRL_SPI_CONFIG_TEST_MODE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB) & HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK)
375#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_MSB 1
376#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB 0
377#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK 0x00000003
378#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK) >> HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB)
379#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB) & HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK)
380
381#define HOST_CTRL_SPI_STATUS_ADDRESS 0x00000481
382#define HOST_CTRL_SPI_STATUS_OFFSET 0x00000481
383#define HOST_CTRL_SPI_STATUS_ADDR_ERR_MSB 3
384#define HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB 3
385#define HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK 0x00000008
386#define HOST_CTRL_SPI_STATUS_ADDR_ERR_GET(x) (((x) & HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK) >> HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB)
387#define HOST_CTRL_SPI_STATUS_ADDR_ERR_SET(x) (((x) << HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB) & HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK)
388#define HOST_CTRL_SPI_STATUS_RD_ERR_MSB 2
389#define HOST_CTRL_SPI_STATUS_RD_ERR_LSB 2
390#define HOST_CTRL_SPI_STATUS_RD_ERR_MASK 0x00000004
391#define HOST_CTRL_SPI_STATUS_RD_ERR_GET(x) (((x) & HOST_CTRL_SPI_STATUS_RD_ERR_MASK) >> HOST_CTRL_SPI_STATUS_RD_ERR_LSB)
392#define HOST_CTRL_SPI_STATUS_RD_ERR_SET(x) (((x) << HOST_CTRL_SPI_STATUS_RD_ERR_LSB) & HOST_CTRL_SPI_STATUS_RD_ERR_MASK)
393#define HOST_CTRL_SPI_STATUS_WR_ERR_MSB 1
394#define HOST_CTRL_SPI_STATUS_WR_ERR_LSB 1
395#define HOST_CTRL_SPI_STATUS_WR_ERR_MASK 0x00000002
396#define HOST_CTRL_SPI_STATUS_WR_ERR_GET(x) (((x) & HOST_CTRL_SPI_STATUS_WR_ERR_MASK) >> HOST_CTRL_SPI_STATUS_WR_ERR_LSB)
397#define HOST_CTRL_SPI_STATUS_WR_ERR_SET(x) (((x) << HOST_CTRL_SPI_STATUS_WR_ERR_LSB) & HOST_CTRL_SPI_STATUS_WR_ERR_MASK)
398#define HOST_CTRL_SPI_STATUS_READY_MSB 0
399#define HOST_CTRL_SPI_STATUS_READY_LSB 0
400#define HOST_CTRL_SPI_STATUS_READY_MASK 0x00000001
401#define HOST_CTRL_SPI_STATUS_READY_GET(x) (((x) & HOST_CTRL_SPI_STATUS_READY_MASK) >> HOST_CTRL_SPI_STATUS_READY_LSB)
402#define HOST_CTRL_SPI_STATUS_READY_SET(x) (((x) << HOST_CTRL_SPI_STATUS_READY_LSB) & HOST_CTRL_SPI_STATUS_READY_MASK)
403
404#define NON_ASSOC_SLEEP_EN_ADDRESS 0x00000482
405#define NON_ASSOC_SLEEP_EN_OFFSET 0x00000482
406#define NON_ASSOC_SLEEP_EN_BIT_MSB 0
407#define NON_ASSOC_SLEEP_EN_BIT_LSB 0
408#define NON_ASSOC_SLEEP_EN_BIT_MASK 0x00000001
409#define NON_ASSOC_SLEEP_EN_BIT_GET(x) (((x) & NON_ASSOC_SLEEP_EN_BIT_MASK) >> NON_ASSOC_SLEEP_EN_BIT_LSB)
410#define NON_ASSOC_SLEEP_EN_BIT_SET(x) (((x) << NON_ASSOC_SLEEP_EN_BIT_LSB) & NON_ASSOC_SLEEP_EN_BIT_MASK)
411
412#define CPU_DBG_SEL_ADDRESS 0x00000483
413#define CPU_DBG_SEL_OFFSET 0x00000483
414#define CPU_DBG_SEL_BIT_MSB 5
415#define CPU_DBG_SEL_BIT_LSB 0
416#define CPU_DBG_SEL_BIT_MASK 0x0000003f
417#define CPU_DBG_SEL_BIT_GET(x) (((x) & CPU_DBG_SEL_BIT_MASK) >> CPU_DBG_SEL_BIT_LSB)
418#define CPU_DBG_SEL_BIT_SET(x) (((x) << CPU_DBG_SEL_BIT_LSB) & CPU_DBG_SEL_BIT_MASK)
419
420#define CPU_DBG_ADDRESS 0x00000484
421#define CPU_DBG_OFFSET 0x00000484
422#define CPU_DBG_DATA_MSB 7
423#define CPU_DBG_DATA_LSB 0
424#define CPU_DBG_DATA_MASK 0x000000ff
425#define CPU_DBG_DATA_GET(x) (((x) & CPU_DBG_DATA_MASK) >> CPU_DBG_DATA_LSB)
426#define CPU_DBG_DATA_SET(x) (((x) << CPU_DBG_DATA_LSB) & CPU_DBG_DATA_MASK)
427
428#define INT_STATUS2_ENABLE_ADDRESS 0x00000488
429#define INT_STATUS2_ENABLE_OFFSET 0x00000488
430#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MSB 2
431#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB 2
432#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK 0x00000004
433#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK) >> INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB)
434#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB) & INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK)
435#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MSB 1
436#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB 1
437#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK 0x00000002
438#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK) >> INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB)
439#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB) & INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK)
440#define INT_STATUS2_ENABLE_GMBOX_DATA_MSB 0
441#define INT_STATUS2_ENABLE_GMBOX_DATA_LSB 0
442#define INT_STATUS2_ENABLE_GMBOX_DATA_MASK 0x00000001
443#define INT_STATUS2_ENABLE_GMBOX_DATA_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_DATA_MASK) >> INT_STATUS2_ENABLE_GMBOX_DATA_LSB)
444#define INT_STATUS2_ENABLE_GMBOX_DATA_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_DATA_LSB) & INT_STATUS2_ENABLE_GMBOX_DATA_MASK)
445
446#define GMBOX_RX_LOOKAHEAD_ADDRESS 0x00000490
447#define GMBOX_RX_LOOKAHEAD_OFFSET 0x00000490
448#define GMBOX_RX_LOOKAHEAD_DATA_MSB 7
449#define GMBOX_RX_LOOKAHEAD_DATA_LSB 0
450#define GMBOX_RX_LOOKAHEAD_DATA_MASK 0x000000ff
451#define GMBOX_RX_LOOKAHEAD_DATA_GET(x) (((x) & GMBOX_RX_LOOKAHEAD_DATA_MASK) >> GMBOX_RX_LOOKAHEAD_DATA_LSB)
452#define GMBOX_RX_LOOKAHEAD_DATA_SET(x) (((x) << GMBOX_RX_LOOKAHEAD_DATA_LSB) & GMBOX_RX_LOOKAHEAD_DATA_MASK)
453
454#define GMBOX_RX_LOOKAHEAD_MUX_ADDRESS 0x00000498
455#define GMBOX_RX_LOOKAHEAD_MUX_OFFSET 0x00000498
456#define GMBOX_RX_LOOKAHEAD_MUX_SEL_MSB 0
457#define GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB 0
458#define GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK 0x00000001
459#define GMBOX_RX_LOOKAHEAD_MUX_SEL_GET(x) (((x) & GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK) >> GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB)
460#define GMBOX_RX_LOOKAHEAD_MUX_SEL_SET(x) (((x) << GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB) & GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK)
461
462#define CIS_WINDOW_ADDRESS 0x00000600
463#define CIS_WINDOW_OFFSET 0x00000600
464#define CIS_WINDOW_DATA_MSB 7
465#define CIS_WINDOW_DATA_LSB 0
466#define CIS_WINDOW_DATA_MASK 0x000000ff
467#define CIS_WINDOW_DATA_GET(x) (((x) & CIS_WINDOW_DATA_MASK) >> CIS_WINDOW_DATA_LSB)
468#define CIS_WINDOW_DATA_SET(x) (((x) << CIS_WINDOW_DATA_LSB) & CIS_WINDOW_DATA_MASK)
469
470
471#endif /* _MBOX_WLAN_HOST_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h
deleted file mode 100644
index f5167b9ae8d..00000000000
--- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h
+++ /dev/null
@@ -1,589 +0,0 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#ifndef _MBOX_WLAN_REG_REG_H_
25#define _MBOX_WLAN_REG_REG_H_
26
27#define WLAN_MBOX_FIFO_ADDRESS 0x00000000
28#define WLAN_MBOX_FIFO_OFFSET 0x00000000
29#define WLAN_MBOX_FIFO_DATA_MSB 19
30#define WLAN_MBOX_FIFO_DATA_LSB 0
31#define WLAN_MBOX_FIFO_DATA_MASK 0x000fffff
32#define WLAN_MBOX_FIFO_DATA_GET(x) (((x) & WLAN_MBOX_FIFO_DATA_MASK) >> WLAN_MBOX_FIFO_DATA_LSB)
33#define WLAN_MBOX_FIFO_DATA_SET(x) (((x) << WLAN_MBOX_FIFO_DATA_LSB) & WLAN_MBOX_FIFO_DATA_MASK)
34
35#define WLAN_MBOX_FIFO_STATUS_ADDRESS 0x00000010
36#define WLAN_MBOX_FIFO_STATUS_OFFSET 0x00000010
37#define WLAN_MBOX_FIFO_STATUS_EMPTY_MSB 19
38#define WLAN_MBOX_FIFO_STATUS_EMPTY_LSB 16
39#define WLAN_MBOX_FIFO_STATUS_EMPTY_MASK 0x000f0000
40#define WLAN_MBOX_FIFO_STATUS_EMPTY_GET(x) (((x) & WLAN_MBOX_FIFO_STATUS_EMPTY_MASK) >> WLAN_MBOX_FIFO_STATUS_EMPTY_LSB)
41#define WLAN_MBOX_FIFO_STATUS_EMPTY_SET(x) (((x) << WLAN_MBOX_FIFO_STATUS_EMPTY_LSB) & WLAN_MBOX_FIFO_STATUS_EMPTY_MASK)
42#define WLAN_MBOX_FIFO_STATUS_FULL_MSB 15
43#define WLAN_MBOX_FIFO_STATUS_FULL_LSB 12
44#define WLAN_MBOX_FIFO_STATUS_FULL_MASK 0x0000f000
45#define WLAN_MBOX_FIFO_STATUS_FULL_GET(x) (((x) & WLAN_MBOX_FIFO_STATUS_FULL_MASK) >> WLAN_MBOX_FIFO_STATUS_FULL_LSB)
46#define WLAN_MBOX_FIFO_STATUS_FULL_SET(x) (((x) << WLAN_MBOX_FIFO_STATUS_FULL_LSB) & WLAN_MBOX_FIFO_STATUS_FULL_MASK)
47
48#define WLAN_MBOX_DMA_POLICY_ADDRESS 0x00000014
49#define WLAN_MBOX_DMA_POLICY_OFFSET 0x00000014
50#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MSB 3
51#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB 3
52#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK 0x00000008
53#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK) >> WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB)
54#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB) & WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK)
55#define WLAN_MBOX_DMA_POLICY_TX_ORDER_MSB 2
56#define WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB 2
57#define WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK 0x00000004
58#define WLAN_MBOX_DMA_POLICY_TX_ORDER_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK) >> WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB)
59#define WLAN_MBOX_DMA_POLICY_TX_ORDER_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB) & WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK)
60#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MSB 1
61#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB 1
62#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK 0x00000002
63#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK) >> WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB)
64#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB) & WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK)
65#define WLAN_MBOX_DMA_POLICY_RX_ORDER_MSB 0
66#define WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB 0
67#define WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK 0x00000001
68#define WLAN_MBOX_DMA_POLICY_RX_ORDER_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK) >> WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB)
69#define WLAN_MBOX_DMA_POLICY_RX_ORDER_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB) & WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK)
70
71#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000018
72#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000018
73#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
74#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
75#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
76#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
77#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
78
79#define WLAN_MBOX0_DMA_RX_CONTROL_ADDRESS 0x0000001c
80#define WLAN_MBOX0_DMA_RX_CONTROL_OFFSET 0x0000001c
81#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MSB 2
82#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB 2
83#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK 0x00000004
84#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB)
85#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK)
86#define WLAN_MBOX0_DMA_RX_CONTROL_START_MSB 1
87#define WLAN_MBOX0_DMA_RX_CONTROL_START_LSB 1
88#define WLAN_MBOX0_DMA_RX_CONTROL_START_MASK 0x00000002
89#define WLAN_MBOX0_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX0_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_START_LSB)
90#define WLAN_MBOX0_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX0_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_START_MASK)
91#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_MSB 0
92#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB 0
93#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK 0x00000001
94#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB)
95#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK)
96
97#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000020
98#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000020
99#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
100#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
101#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
102#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
103#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
104
105#define WLAN_MBOX0_DMA_TX_CONTROL_ADDRESS 0x00000024
106#define WLAN_MBOX0_DMA_TX_CONTROL_OFFSET 0x00000024
107#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MSB 2
108#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB 2
109#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK 0x00000004
110#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB)
111#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK)
112#define WLAN_MBOX0_DMA_TX_CONTROL_START_MSB 1
113#define WLAN_MBOX0_DMA_TX_CONTROL_START_LSB 1
114#define WLAN_MBOX0_DMA_TX_CONTROL_START_MASK 0x00000002
115#define WLAN_MBOX0_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX0_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_START_LSB)
116#define WLAN_MBOX0_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX0_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_START_MASK)
117#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_MSB 0
118#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB 0
119#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK 0x00000001
120#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB)
121#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK)
122
123#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000028
124#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000028
125#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
126#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
127#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
128#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
129#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
130
131#define WLAN_MBOX1_DMA_RX_CONTROL_ADDRESS 0x0000002c
132#define WLAN_MBOX1_DMA_RX_CONTROL_OFFSET 0x0000002c
133#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MSB 2
134#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB 2
135#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK 0x00000004
136#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB)
137#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK)
138#define WLAN_MBOX1_DMA_RX_CONTROL_START_MSB 1
139#define WLAN_MBOX1_DMA_RX_CONTROL_START_LSB 1
140#define WLAN_MBOX1_DMA_RX_CONTROL_START_MASK 0x00000002
141#define WLAN_MBOX1_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX1_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_START_LSB)
142#define WLAN_MBOX1_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX1_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_START_MASK)
143#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_MSB 0
144#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB 0
145#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK 0x00000001
146#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB)
147#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK)
148
149#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000030
150#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000030
151#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
152#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
153#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
154#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
155#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
156
157#define WLAN_MBOX1_DMA_TX_CONTROL_ADDRESS 0x00000034
158#define WLAN_MBOX1_DMA_TX_CONTROL_OFFSET 0x00000034
159#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MSB 2
160#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB 2
161#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK 0x00000004
162#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB)
163#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK)
164#define WLAN_MBOX1_DMA_TX_CONTROL_START_MSB 1
165#define WLAN_MBOX1_DMA_TX_CONTROL_START_LSB 1
166#define WLAN_MBOX1_DMA_TX_CONTROL_START_MASK 0x00000002
167#define WLAN_MBOX1_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX1_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_START_LSB)
168#define WLAN_MBOX1_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX1_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_START_MASK)
169#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_MSB 0
170#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB 0
171#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK 0x00000001
172#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB)
173#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK)
174
175#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000038
176#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000038
177#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
178#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
179#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
180#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
181#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
182
183#define WLAN_MBOX2_DMA_RX_CONTROL_ADDRESS 0x0000003c
184#define WLAN_MBOX2_DMA_RX_CONTROL_OFFSET 0x0000003c
185#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MSB 2
186#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB 2
187#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK 0x00000004
188#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB)
189#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK)
190#define WLAN_MBOX2_DMA_RX_CONTROL_START_MSB 1
191#define WLAN_MBOX2_DMA_RX_CONTROL_START_LSB 1
192#define WLAN_MBOX2_DMA_RX_CONTROL_START_MASK 0x00000002
193#define WLAN_MBOX2_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX2_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_START_LSB)
194#define WLAN_MBOX2_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX2_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_START_MASK)
195#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_MSB 0
196#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB 0
197#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK 0x00000001
198#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB)
199#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK)
200
201#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000040
202#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000040
203#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
204#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
205#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
206#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
207#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
208
209#define WLAN_MBOX2_DMA_TX_CONTROL_ADDRESS 0x00000044
210#define WLAN_MBOX2_DMA_TX_CONTROL_OFFSET 0x00000044
211#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MSB 2
212#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB 2
213#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK 0x00000004
214#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB)
215#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK)
216#define WLAN_MBOX2_DMA_TX_CONTROL_START_MSB 1
217#define WLAN_MBOX2_DMA_TX_CONTROL_START_LSB 1
218#define WLAN_MBOX2_DMA_TX_CONTROL_START_MASK 0x00000002
219#define WLAN_MBOX2_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX2_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_START_LSB)
220#define WLAN_MBOX2_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX2_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_START_MASK)
221#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_MSB 0
222#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB 0
223#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK 0x00000001
224#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB)
225#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK)
226
227#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000048
228#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000048
229#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
230#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
231#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
232#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
233#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
234
235#define WLAN_MBOX3_DMA_RX_CONTROL_ADDRESS 0x0000004c
236#define WLAN_MBOX3_DMA_RX_CONTROL_OFFSET 0x0000004c
237#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MSB 2
238#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB 2
239#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK 0x00000004
240#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB)
241#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK)
242#define WLAN_MBOX3_DMA_RX_CONTROL_START_MSB 1
243#define WLAN_MBOX3_DMA_RX_CONTROL_START_LSB 1
244#define WLAN_MBOX3_DMA_RX_CONTROL_START_MASK 0x00000002
245#define WLAN_MBOX3_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX3_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_START_LSB)
246#define WLAN_MBOX3_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX3_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_START_MASK)
247#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_MSB 0
248#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB 0
249#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK 0x00000001
250#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB)
251#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK)
252
253#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000050
254#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000050
255#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
256#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
257#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
258#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
259#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
260
261#define WLAN_MBOX3_DMA_TX_CONTROL_ADDRESS 0x00000054
262#define WLAN_MBOX3_DMA_TX_CONTROL_OFFSET 0x00000054
263#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MSB 2
264#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB 2
265#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK 0x00000004
266#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB)
267#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK)
268#define WLAN_MBOX3_DMA_TX_CONTROL_START_MSB 1
269#define WLAN_MBOX3_DMA_TX_CONTROL_START_LSB 1
270#define WLAN_MBOX3_DMA_TX_CONTROL_START_MASK 0x00000002
271#define WLAN_MBOX3_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX3_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_START_LSB)
272#define WLAN_MBOX3_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX3_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_START_MASK)
273#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_MSB 0
274#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB 0
275#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK 0x00000001
276#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB)
277#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK)
278
279#define WLAN_MBOX_INT_STATUS_ADDRESS 0x00000058
280#define WLAN_MBOX_INT_STATUS_OFFSET 0x00000058
281#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 31
282#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 28
283#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0xf0000000
284#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
285#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
286#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 27
287#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 24
288#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
289#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
290#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
291#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 23
292#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 20
293#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00f00000
294#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
295#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
296#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MSB 17
297#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB 17
298#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK 0x00020000
299#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK) >> WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB)
300#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB) & WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK)
301#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MSB 16
302#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB 16
303#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK 0x00010000
304#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB)
305#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB) & WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK)
306#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MSB 15
307#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB 12
308#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK 0x0000f000
309#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
310#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
311#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MSB 11
312#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB 8
313#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK 0x00000f00
314#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK) >> WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB)
315#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB) & WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK)
316#define WLAN_MBOX_INT_STATUS_HOST_MSB 7
317#define WLAN_MBOX_INT_STATUS_HOST_LSB 0
318#define WLAN_MBOX_INT_STATUS_HOST_MASK 0x000000ff
319#define WLAN_MBOX_INT_STATUS_HOST_GET(x) (((x) & WLAN_MBOX_INT_STATUS_HOST_MASK) >> WLAN_MBOX_INT_STATUS_HOST_LSB)
320#define WLAN_MBOX_INT_STATUS_HOST_SET(x) (((x) << WLAN_MBOX_INT_STATUS_HOST_LSB) & WLAN_MBOX_INT_STATUS_HOST_MASK)
321
322#define WLAN_MBOX_INT_ENABLE_ADDRESS 0x0000005c
323#define WLAN_MBOX_INT_ENABLE_OFFSET 0x0000005c
324#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 31
325#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 28
326#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0xf0000000
327#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
328#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
329#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 27
330#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 24
331#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
332#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
333#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
334#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 23
335#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 20
336#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00f00000
337#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
338#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
339#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MSB 17
340#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB 17
341#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK 0x00020000
342#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB)
343#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB) & WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK)
344#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MSB 16
345#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB 16
346#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK 0x00010000
347#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
348#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
349#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB 15
350#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB 12
351#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK 0x0000f000
352#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
353#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
354#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MSB 11
355#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB 8
356#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK 0x00000f00
357#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB)
358#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB) & WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK)
359#define WLAN_MBOX_INT_ENABLE_HOST_MSB 7
360#define WLAN_MBOX_INT_ENABLE_HOST_LSB 0
361#define WLAN_MBOX_INT_ENABLE_HOST_MASK 0x000000ff
362#define WLAN_MBOX_INT_ENABLE_HOST_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_HOST_MASK) >> WLAN_MBOX_INT_ENABLE_HOST_LSB)
363#define WLAN_MBOX_INT_ENABLE_HOST_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_HOST_LSB) & WLAN_MBOX_INT_ENABLE_HOST_MASK)
364
365#define WLAN_INT_HOST_ADDRESS 0x00000060
366#define WLAN_INT_HOST_OFFSET 0x00000060
367#define WLAN_INT_HOST_VECTOR_MSB 7
368#define WLAN_INT_HOST_VECTOR_LSB 0
369#define WLAN_INT_HOST_VECTOR_MASK 0x000000ff
370#define WLAN_INT_HOST_VECTOR_GET(x) (((x) & WLAN_INT_HOST_VECTOR_MASK) >> WLAN_INT_HOST_VECTOR_LSB)
371#define WLAN_INT_HOST_VECTOR_SET(x) (((x) << WLAN_INT_HOST_VECTOR_LSB) & WLAN_INT_HOST_VECTOR_MASK)
372
373#define WLAN_LOCAL_COUNT_ADDRESS 0x00000080
374#define WLAN_LOCAL_COUNT_OFFSET 0x00000080
375#define WLAN_LOCAL_COUNT_VALUE_MSB 7
376#define WLAN_LOCAL_COUNT_VALUE_LSB 0
377#define WLAN_LOCAL_COUNT_VALUE_MASK 0x000000ff
378#define WLAN_LOCAL_COUNT_VALUE_GET(x) (((x) & WLAN_LOCAL_COUNT_VALUE_MASK) >> WLAN_LOCAL_COUNT_VALUE_LSB)
379#define WLAN_LOCAL_COUNT_VALUE_SET(x) (((x) << WLAN_LOCAL_COUNT_VALUE_LSB) & WLAN_LOCAL_COUNT_VALUE_MASK)
380
381#define WLAN_COUNT_INC_ADDRESS 0x000000a0
382#define WLAN_COUNT_INC_OFFSET 0x000000a0
383#define WLAN_COUNT_INC_VALUE_MSB 7
384#define WLAN_COUNT_INC_VALUE_LSB 0
385#define WLAN_COUNT_INC_VALUE_MASK 0x000000ff
386#define WLAN_COUNT_INC_VALUE_GET(x) (((x) & WLAN_COUNT_INC_VALUE_MASK) >> WLAN_COUNT_INC_VALUE_LSB)
387#define WLAN_COUNT_INC_VALUE_SET(x) (((x) << WLAN_COUNT_INC_VALUE_LSB) & WLAN_COUNT_INC_VALUE_MASK)
388
389#define WLAN_LOCAL_SCRATCH_ADDRESS 0x000000c0
390#define WLAN_LOCAL_SCRATCH_OFFSET 0x000000c0
391#define WLAN_LOCAL_SCRATCH_VALUE_MSB 7
392#define WLAN_LOCAL_SCRATCH_VALUE_LSB 0
393#define WLAN_LOCAL_SCRATCH_VALUE_MASK 0x000000ff
394#define WLAN_LOCAL_SCRATCH_VALUE_GET(x) (((x) & WLAN_LOCAL_SCRATCH_VALUE_MASK) >> WLAN_LOCAL_SCRATCH_VALUE_LSB)
395#define WLAN_LOCAL_SCRATCH_VALUE_SET(x) (((x) << WLAN_LOCAL_SCRATCH_VALUE_LSB) & WLAN_LOCAL_SCRATCH_VALUE_MASK)
396
397#define WLAN_USE_LOCAL_BUS_ADDRESS 0x000000e0
398#define WLAN_USE_LOCAL_BUS_OFFSET 0x000000e0
399#define WLAN_USE_LOCAL_BUS_PIN_INIT_MSB 0
400#define WLAN_USE_LOCAL_BUS_PIN_INIT_LSB 0
401#define WLAN_USE_LOCAL_BUS_PIN_INIT_MASK 0x00000001
402#define WLAN_USE_LOCAL_BUS_PIN_INIT_GET(x) (((x) & WLAN_USE_LOCAL_BUS_PIN_INIT_MASK) >> WLAN_USE_LOCAL_BUS_PIN_INIT_LSB)
403#define WLAN_USE_LOCAL_BUS_PIN_INIT_SET(x) (((x) << WLAN_USE_LOCAL_BUS_PIN_INIT_LSB) & WLAN_USE_LOCAL_BUS_PIN_INIT_MASK)
404
405#define WLAN_SDIO_CONFIG_ADDRESS 0x000000e4
406#define WLAN_SDIO_CONFIG_OFFSET 0x000000e4
407#define WLAN_SDIO_CONFIG_CCCR_IOR1_MSB 0
408#define WLAN_SDIO_CONFIG_CCCR_IOR1_LSB 0
409#define WLAN_SDIO_CONFIG_CCCR_IOR1_MASK 0x00000001
410#define WLAN_SDIO_CONFIG_CCCR_IOR1_GET(x) (((x) & WLAN_SDIO_CONFIG_CCCR_IOR1_MASK) >> WLAN_SDIO_CONFIG_CCCR_IOR1_LSB)
411#define WLAN_SDIO_CONFIG_CCCR_IOR1_SET(x) (((x) << WLAN_SDIO_CONFIG_CCCR_IOR1_LSB) & WLAN_SDIO_CONFIG_CCCR_IOR1_MASK)
412
413#define WLAN_MBOX_DEBUG_ADDRESS 0x000000e8
414#define WLAN_MBOX_DEBUG_OFFSET 0x000000e8
415#define WLAN_MBOX_DEBUG_SEL_MSB 2
416#define WLAN_MBOX_DEBUG_SEL_LSB 0
417#define WLAN_MBOX_DEBUG_SEL_MASK 0x00000007
418#define WLAN_MBOX_DEBUG_SEL_GET(x) (((x) & WLAN_MBOX_DEBUG_SEL_MASK) >> WLAN_MBOX_DEBUG_SEL_LSB)
419#define WLAN_MBOX_DEBUG_SEL_SET(x) (((x) << WLAN_MBOX_DEBUG_SEL_LSB) & WLAN_MBOX_DEBUG_SEL_MASK)
420
421#define WLAN_MBOX_FIFO_RESET_ADDRESS 0x000000ec
422#define WLAN_MBOX_FIFO_RESET_OFFSET 0x000000ec
423#define WLAN_MBOX_FIFO_RESET_INIT_MSB 0
424#define WLAN_MBOX_FIFO_RESET_INIT_LSB 0
425#define WLAN_MBOX_FIFO_RESET_INIT_MASK 0x00000001
426#define WLAN_MBOX_FIFO_RESET_INIT_GET(x) (((x) & WLAN_MBOX_FIFO_RESET_INIT_MASK) >> WLAN_MBOX_FIFO_RESET_INIT_LSB)
427#define WLAN_MBOX_FIFO_RESET_INIT_SET(x) (((x) << WLAN_MBOX_FIFO_RESET_INIT_LSB) & WLAN_MBOX_FIFO_RESET_INIT_MASK)
428
429#define WLAN_MBOX_TXFIFO_POP_ADDRESS 0x000000f0
430#define WLAN_MBOX_TXFIFO_POP_OFFSET 0x000000f0
431#define WLAN_MBOX_TXFIFO_POP_DATA_MSB 0
432#define WLAN_MBOX_TXFIFO_POP_DATA_LSB 0
433#define WLAN_MBOX_TXFIFO_POP_DATA_MASK 0x00000001
434#define WLAN_MBOX_TXFIFO_POP_DATA_GET(x) (((x) & WLAN_MBOX_TXFIFO_POP_DATA_MASK) >> WLAN_MBOX_TXFIFO_POP_DATA_LSB)
435#define WLAN_MBOX_TXFIFO_POP_DATA_SET(x) (((x) << WLAN_MBOX_TXFIFO_POP_DATA_LSB) & WLAN_MBOX_TXFIFO_POP_DATA_MASK)
436
437#define WLAN_MBOX_RXFIFO_POP_ADDRESS 0x00000100
438#define WLAN_MBOX_RXFIFO_POP_OFFSET 0x00000100
439#define WLAN_MBOX_RXFIFO_POP_DATA_MSB 0
440#define WLAN_MBOX_RXFIFO_POP_DATA_LSB 0
441#define WLAN_MBOX_RXFIFO_POP_DATA_MASK 0x00000001
442#define WLAN_MBOX_RXFIFO_POP_DATA_GET(x) (((x) & WLAN_MBOX_RXFIFO_POP_DATA_MASK) >> WLAN_MBOX_RXFIFO_POP_DATA_LSB)
443#define WLAN_MBOX_RXFIFO_POP_DATA_SET(x) (((x) << WLAN_MBOX_RXFIFO_POP_DATA_LSB) & WLAN_MBOX_RXFIFO_POP_DATA_MASK)
444
445#define WLAN_SDIO_DEBUG_ADDRESS 0x00000110
446#define WLAN_SDIO_DEBUG_OFFSET 0x00000110
447#define WLAN_SDIO_DEBUG_SEL_MSB 3
448#define WLAN_SDIO_DEBUG_SEL_LSB 0
449#define WLAN_SDIO_DEBUG_SEL_MASK 0x0000000f
450#define WLAN_SDIO_DEBUG_SEL_GET(x) (((x) & WLAN_SDIO_DEBUG_SEL_MASK) >> WLAN_SDIO_DEBUG_SEL_LSB)
451#define WLAN_SDIO_DEBUG_SEL_SET(x) (((x) << WLAN_SDIO_DEBUG_SEL_LSB) & WLAN_SDIO_DEBUG_SEL_MASK)
452
453#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000114
454#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000114
455#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
456#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
457#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
458#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
459#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
460
461#define WLAN_GMBOX0_DMA_RX_CONTROL_ADDRESS 0x00000118
462#define WLAN_GMBOX0_DMA_RX_CONTROL_OFFSET 0x00000118
463#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MSB 2
464#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB 2
465#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK 0x00000004
466#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB)
467#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK)
468#define WLAN_GMBOX0_DMA_RX_CONTROL_START_MSB 1
469#define WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB 1
470#define WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK 0x00000002
471#define WLAN_GMBOX0_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB)
472#define WLAN_GMBOX0_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK)
473#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MSB 0
474#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB 0
475#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK 0x00000001
476#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB)
477#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK)
478
479#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x0000011c
480#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x0000011c
481#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
482#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
483#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
484#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
485#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
486
487#define WLAN_GMBOX0_DMA_TX_CONTROL_ADDRESS 0x00000120
488#define WLAN_GMBOX0_DMA_TX_CONTROL_OFFSET 0x00000120
489#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MSB 2
490#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB 2
491#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK 0x00000004
492#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB)
493#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK)
494#define WLAN_GMBOX0_DMA_TX_CONTROL_START_MSB 1
495#define WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB 1
496#define WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK 0x00000002
497#define WLAN_GMBOX0_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB)
498#define WLAN_GMBOX0_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK)
499#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MSB 0
500#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB 0
501#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK 0x00000001
502#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB)
503#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK)
504
505#define WLAN_GMBOX_INT_STATUS_ADDRESS 0x00000124
506#define WLAN_GMBOX_INT_STATUS_OFFSET 0x00000124
507#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MSB 6
508#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB 6
509#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK 0x00000040
510#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK) >> WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB)
511#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB) & WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK)
512#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MSB 5
513#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB 5
514#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK 0x00000020
515#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB)
516#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB) & WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK)
517#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 4
518#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 4
519#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0x00000010
520#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
521#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
522#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 3
523#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 3
524#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x00000008
525#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
526#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
527#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 2
528#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 2
529#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00000004
530#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
531#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
532#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB 1
533#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB 1
534#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK 0x00000002
535#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
536#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
537#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MSB 0
538#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB 0
539#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK 0x00000001
540#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK) >> WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB)
541#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB) & WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK)
542
543#define WLAN_GMBOX_INT_ENABLE_ADDRESS 0x00000128
544#define WLAN_GMBOX_INT_ENABLE_OFFSET 0x00000128
545#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MSB 6
546#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB 6
547#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK 0x00000040
548#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB)
549#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB) & WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK)
550#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB 5
551#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB 5
552#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK 0x00000020
553#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
554#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
555#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 4
556#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 4
557#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0x00000010
558#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
559#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
560#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 3
561#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 3
562#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x00000008
563#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
564#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
565#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 2
566#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 2
567#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00000004
568#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
569#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
570#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB 1
571#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB 1
572#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK 0x00000002
573#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
574#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
575#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MSB 0
576#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB 0
577#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK 0x00000001
578#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB)
579#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB) & WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK)
580
581#define WLAN_HOST_IF_WINDOW_ADDRESS 0x00002000
582#define WLAN_HOST_IF_WINDOW_OFFSET 0x00002000
583#define WLAN_HOST_IF_WINDOW_DATA_MSB 7
584#define WLAN_HOST_IF_WINDOW_DATA_LSB 0
585#define WLAN_HOST_IF_WINDOW_DATA_MASK 0x000000ff
586#define WLAN_HOST_IF_WINDOW_DATA_GET(x) (((x) & WLAN_HOST_IF_WINDOW_DATA_MASK) >> WLAN_HOST_IF_WINDOW_DATA_LSB)
587#define WLAN_HOST_IF_WINDOW_DATA_SET(x) (((x) << WLAN_HOST_IF_WINDOW_DATA_LSB) & WLAN_HOST_IF_WINDOW_DATA_MASK)
588
589#endif /* _MBOX_WLAN_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h
deleted file mode 100644
index fcafec88a6b..00000000000
--- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h
+++ /dev/null
@@ -1,187 +0,0 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#include "rtc_wlan_reg.h"
25
26#ifndef BT_HEADERS
27
28#define RESET_CONTROL_ADDRESS WLAN_RESET_CONTROL_ADDRESS
29#define RESET_CONTROL_OFFSET WLAN_RESET_CONTROL_OFFSET
30#define RESET_CONTROL_DEBUG_UART_RST_MSB WLAN_RESET_CONTROL_DEBUG_UART_RST_MSB
31#define RESET_CONTROL_DEBUG_UART_RST_LSB WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB
32#define RESET_CONTROL_DEBUG_UART_RST_MASK WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK
33#define RESET_CONTROL_DEBUG_UART_RST_GET(x) WLAN_RESET_CONTROL_DEBUG_UART_RST_GET(x)
34#define RESET_CONTROL_DEBUG_UART_RST_SET(x) WLAN_RESET_CONTROL_DEBUG_UART_RST_SET(x)
35#define RESET_CONTROL_BB_COLD_RST_MSB WLAN_RESET_CONTROL_BB_COLD_RST_MSB
36#define RESET_CONTROL_BB_COLD_RST_LSB WLAN_RESET_CONTROL_BB_COLD_RST_LSB
37#define RESET_CONTROL_BB_COLD_RST_MASK WLAN_RESET_CONTROL_BB_COLD_RST_MASK
38#define RESET_CONTROL_BB_COLD_RST_GET(x) WLAN_RESET_CONTROL_BB_COLD_RST_GET(x)
39#define RESET_CONTROL_BB_COLD_RST_SET(x) WLAN_RESET_CONTROL_BB_COLD_RST_SET(x)
40#define RESET_CONTROL_BB_WARM_RST_MSB WLAN_RESET_CONTROL_BB_WARM_RST_MSB
41#define RESET_CONTROL_BB_WARM_RST_LSB WLAN_RESET_CONTROL_BB_WARM_RST_LSB
42#define RESET_CONTROL_BB_WARM_RST_MASK WLAN_RESET_CONTROL_BB_WARM_RST_MASK
43#define RESET_CONTROL_BB_WARM_RST_GET(x) WLAN_RESET_CONTROL_BB_WARM_RST_GET(x)
44#define RESET_CONTROL_BB_WARM_RST_SET(x) WLAN_RESET_CONTROL_BB_WARM_RST_SET(x)
45#define RESET_CONTROL_CPU_INIT_RESET_MSB WLAN_RESET_CONTROL_CPU_INIT_RESET_MSB
46#define RESET_CONTROL_CPU_INIT_RESET_LSB WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB
47#define RESET_CONTROL_CPU_INIT_RESET_MASK WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK
48#define RESET_CONTROL_CPU_INIT_RESET_GET(x) WLAN_RESET_CONTROL_CPU_INIT_RESET_GET(x)
49#define RESET_CONTROL_CPU_INIT_RESET_SET(x) WLAN_RESET_CONTROL_CPU_INIT_RESET_SET(x)
50#define RESET_CONTROL_VMC_REMAP_RESET_MSB WLAN_RESET_CONTROL_VMC_REMAP_RESET_MSB
51#define RESET_CONTROL_VMC_REMAP_RESET_LSB WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB
52#define RESET_CONTROL_VMC_REMAP_RESET_MASK WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK
53#define RESET_CONTROL_VMC_REMAP_RESET_GET(x) WLAN_RESET_CONTROL_VMC_REMAP_RESET_GET(x)
54#define RESET_CONTROL_VMC_REMAP_RESET_SET(x) WLAN_RESET_CONTROL_VMC_REMAP_RESET_SET(x)
55#define RESET_CONTROL_RST_OUT_MSB WLAN_RESET_CONTROL_RST_OUT_MSB
56#define RESET_CONTROL_RST_OUT_LSB WLAN_RESET_CONTROL_RST_OUT_LSB
57#define RESET_CONTROL_RST_OUT_MASK WLAN_RESET_CONTROL_RST_OUT_MASK
58#define RESET_CONTROL_RST_OUT_GET(x) WLAN_RESET_CONTROL_RST_OUT_GET(x)
59#define RESET_CONTROL_RST_OUT_SET(x) WLAN_RESET_CONTROL_RST_OUT_SET(x)
60#define RESET_CONTROL_COLD_RST_MSB WLAN_RESET_CONTROL_COLD_RST_MSB
61#define RESET_CONTROL_COLD_RST_LSB WLAN_RESET_CONTROL_COLD_RST_LSB
62#define RESET_CONTROL_COLD_RST_MASK WLAN_RESET_CONTROL_COLD_RST_MASK
63#define RESET_CONTROL_COLD_RST_GET(x) WLAN_RESET_CONTROL_COLD_RST_GET(x)
64#define RESET_CONTROL_COLD_RST_SET(x) WLAN_RESET_CONTROL_COLD_RST_SET(x)
65#define RESET_CONTROL_WARM_RST_MSB WLAN_RESET_CONTROL_WARM_RST_MSB
66#define RESET_CONTROL_WARM_RST_LSB WLAN_RESET_CONTROL_WARM_RST_LSB
67#define RESET_CONTROL_WARM_RST_MASK WLAN_RESET_CONTROL_WARM_RST_MASK
68#define RESET_CONTROL_WARM_RST_GET(x) WLAN_RESET_CONTROL_WARM_RST_GET(x)
69#define RESET_CONTROL_WARM_RST_SET(x) WLAN_RESET_CONTROL_WARM_RST_SET(x)
70#define RESET_CONTROL_CPU_WARM_RST_MSB WLAN_RESET_CONTROL_CPU_WARM_RST_MSB
71#define RESET_CONTROL_CPU_WARM_RST_LSB WLAN_RESET_CONTROL_CPU_WARM_RST_LSB
72#define RESET_CONTROL_CPU_WARM_RST_MASK WLAN_RESET_CONTROL_CPU_WARM_RST_MASK
73#define RESET_CONTROL_CPU_WARM_RST_GET(x) WLAN_RESET_CONTROL_CPU_WARM_RST_GET(x)
74#define RESET_CONTROL_CPU_WARM_RST_SET(x) WLAN_RESET_CONTROL_CPU_WARM_RST_SET(x)
75#define RESET_CONTROL_MAC_COLD_RST_MSB WLAN_RESET_CONTROL_MAC_COLD_RST_MSB
76#define RESET_CONTROL_MAC_COLD_RST_LSB WLAN_RESET_CONTROL_MAC_COLD_RST_LSB
77#define RESET_CONTROL_MAC_COLD_RST_MASK WLAN_RESET_CONTROL_MAC_COLD_RST_MASK
78#define RESET_CONTROL_MAC_COLD_RST_GET(x) WLAN_RESET_CONTROL_MAC_COLD_RST_GET(x)
79#define RESET_CONTROL_MAC_COLD_RST_SET(x) WLAN_RESET_CONTROL_MAC_COLD_RST_SET(x)
80#define RESET_CONTROL_MAC_WARM_RST_MSB WLAN_RESET_CONTROL_MAC_WARM_RST_MSB
81#define RESET_CONTROL_MAC_WARM_RST_LSB WLAN_RESET_CONTROL_MAC_WARM_RST_LSB
82#define RESET_CONTROL_MAC_WARM_RST_MASK WLAN_RESET_CONTROL_MAC_WARM_RST_MASK
83#define RESET_CONTROL_MAC_WARM_RST_GET(x) WLAN_RESET_CONTROL_MAC_WARM_RST_GET(x)
84#define RESET_CONTROL_MAC_WARM_RST_SET(x) WLAN_RESET_CONTROL_MAC_WARM_RST_SET(x)
85#define RESET_CONTROL_MBOX_RST_MSB WLAN_RESET_CONTROL_MBOX_RST_MSB
86#define RESET_CONTROL_MBOX_RST_LSB WLAN_RESET_CONTROL_MBOX_RST_LSB
87#define RESET_CONTROL_MBOX_RST_MASK WLAN_RESET_CONTROL_MBOX_RST_MASK
88#define RESET_CONTROL_MBOX_RST_GET(x) WLAN_RESET_CONTROL_MBOX_RST_GET(x)
89#define RESET_CONTROL_MBOX_RST_SET(x) WLAN_RESET_CONTROL_MBOX_RST_SET(x)
90#define RESET_CONTROL_UART_RST_MSB WLAN_RESET_CONTROL_UART_RST_MSB
91#define RESET_CONTROL_UART_RST_LSB WLAN_RESET_CONTROL_UART_RST_LSB
92#define RESET_CONTROL_UART_RST_MASK WLAN_RESET_CONTROL_UART_RST_MASK
93#define RESET_CONTROL_UART_RST_GET(x) WLAN_RESET_CONTROL_UART_RST_GET(x)
94#define RESET_CONTROL_UART_RST_SET(x) WLAN_RESET_CONTROL_UART_RST_SET(x)
95#define RESET_CONTROL_SI0_RST_MSB WLAN_RESET_CONTROL_SI0_RST_MSB
96#define RESET_CONTROL_SI0_RST_LSB WLAN_RESET_CONTROL_SI0_RST_LSB
97#define RESET_CONTROL_SI0_RST_MASK WLAN_RESET_CONTROL_SI0_RST_MASK
98#define RESET_CONTROL_SI0_RST_GET(x) WLAN_RESET_CONTROL_SI0_RST_GET(x)
99#define RESET_CONTROL_SI0_RST_SET(x) WLAN_RESET_CONTROL_SI0_RST_SET(x)
100#define CPU_CLOCK_ADDRESS WLAN_CPU_CLOCK_ADDRESS
101#define CPU_CLOCK_OFFSET WLAN_CPU_CLOCK_OFFSET
102#define CPU_CLOCK_STANDARD_MSB WLAN_CPU_CLOCK_STANDARD_MSB
103#define CPU_CLOCK_STANDARD_LSB WLAN_CPU_CLOCK_STANDARD_LSB
104#define CPU_CLOCK_STANDARD_MASK WLAN_CPU_CLOCK_STANDARD_MASK
105#define CPU_CLOCK_STANDARD_GET(x) WLAN_CPU_CLOCK_STANDARD_GET(x)
106#define CPU_CLOCK_STANDARD_SET(x) WLAN_CPU_CLOCK_STANDARD_SET(x)
107#define CLOCK_OUT_ADDRESS WLAN_CLOCK_OUT_ADDRESS
108#define CLOCK_OUT_OFFSET WLAN_CLOCK_OUT_OFFSET
109#define CLOCK_OUT_SELECT_MSB WLAN_CLOCK_OUT_SELECT_MSB
110#define CLOCK_OUT_SELECT_LSB WLAN_CLOCK_OUT_SELECT_LSB
111#define CLOCK_OUT_SELECT_MASK WLAN_CLOCK_OUT_SELECT_MASK
112#define CLOCK_OUT_SELECT_GET(x) WLAN_CLOCK_OUT_SELECT_GET(x)
113#define CLOCK_OUT_SELECT_SET(x) WLAN_CLOCK_OUT_SELECT_SET(x)
114#define CLOCK_CONTROL_ADDRESS WLAN_CLOCK_CONTROL_ADDRESS
115#define CLOCK_CONTROL_OFFSET WLAN_CLOCK_CONTROL_OFFSET
116#define CLOCK_CONTROL_LF_CLK32_MSB WLAN_CLOCK_CONTROL_LF_CLK32_MSB
117#define CLOCK_CONTROL_LF_CLK32_LSB WLAN_CLOCK_CONTROL_LF_CLK32_LSB
118#define CLOCK_CONTROL_LF_CLK32_MASK WLAN_CLOCK_CONTROL_LF_CLK32_MASK
119#define CLOCK_CONTROL_LF_CLK32_GET(x) WLAN_CLOCK_CONTROL_LF_CLK32_GET(x)
120#define CLOCK_CONTROL_LF_CLK32_SET(x) WLAN_CLOCK_CONTROL_LF_CLK32_SET(x)
121#define CLOCK_CONTROL_SI0_CLK_MSB WLAN_CLOCK_CONTROL_SI0_CLK_MSB
122#define CLOCK_CONTROL_SI0_CLK_LSB WLAN_CLOCK_CONTROL_SI0_CLK_LSB
123#define CLOCK_CONTROL_SI0_CLK_MASK WLAN_CLOCK_CONTROL_SI0_CLK_MASK
124#define CLOCK_CONTROL_SI0_CLK_GET(x) WLAN_CLOCK_CONTROL_SI0_CLK_GET(x)
125#define CLOCK_CONTROL_SI0_CLK_SET(x) WLAN_CLOCK_CONTROL_SI0_CLK_SET(x)
126#define RESET_CAUSE_ADDRESS WLAN_RESET_CAUSE_ADDRESS
127#define RESET_CAUSE_OFFSET WLAN_RESET_CAUSE_OFFSET
128#define RESET_CAUSE_LAST_MSB WLAN_RESET_CAUSE_LAST_MSB
129#define RESET_CAUSE_LAST_LSB WLAN_RESET_CAUSE_LAST_LSB
130#define RESET_CAUSE_LAST_MASK WLAN_RESET_CAUSE_LAST_MASK
131#define RESET_CAUSE_LAST_GET(x) WLAN_RESET_CAUSE_LAST_GET(x)
132#define RESET_CAUSE_LAST_SET(x) WLAN_RESET_CAUSE_LAST_SET(x)
133#define SYSTEM_SLEEP_ADDRESS WLAN_SYSTEM_SLEEP_ADDRESS
134#define SYSTEM_SLEEP_OFFSET WLAN_SYSTEM_SLEEP_OFFSET
135#define SYSTEM_SLEEP_HOST_IF_MSB WLAN_SYSTEM_SLEEP_HOST_IF_MSB
136#define SYSTEM_SLEEP_HOST_IF_LSB WLAN_SYSTEM_SLEEP_HOST_IF_LSB
137#define SYSTEM_SLEEP_HOST_IF_MASK WLAN_SYSTEM_SLEEP_HOST_IF_MASK
138#define SYSTEM_SLEEP_HOST_IF_GET(x) WLAN_SYSTEM_SLEEP_HOST_IF_GET(x)
139#define SYSTEM_SLEEP_HOST_IF_SET(x) WLAN_SYSTEM_SLEEP_HOST_IF_SET(x)
140#define SYSTEM_SLEEP_MBOX_MSB WLAN_SYSTEM_SLEEP_MBOX_MSB
141#define SYSTEM_SLEEP_MBOX_LSB WLAN_SYSTEM_SLEEP_MBOX_LSB
142#define SYSTEM_SLEEP_MBOX_MASK WLAN_SYSTEM_SLEEP_MBOX_MASK
143#define SYSTEM_SLEEP_MBOX_GET(x) WLAN_SYSTEM_SLEEP_MBOX_GET(x)
144#define SYSTEM_SLEEP_MBOX_SET(x) WLAN_SYSTEM_SLEEP_MBOX_SET(x)
145#define SYSTEM_SLEEP_MAC_IF_MSB WLAN_SYSTEM_SLEEP_MAC_IF_MSB
146#define SYSTEM_SLEEP_MAC_IF_LSB WLAN_SYSTEM_SLEEP_MAC_IF_LSB
147#define SYSTEM_SLEEP_MAC_IF_MASK WLAN_SYSTEM_SLEEP_MAC_IF_MASK
148#define SYSTEM_SLEEP_MAC_IF_GET(x) WLAN_SYSTEM_SLEEP_MAC_IF_GET(x)
149#define SYSTEM_SLEEP_MAC_IF_SET(x) WLAN_SYSTEM_SLEEP_MAC_IF_SET(x)
150#define SYSTEM_SLEEP_LIGHT_MSB WLAN_SYSTEM_SLEEP_LIGHT_MSB
151#define SYSTEM_SLEEP_LIGHT_LSB WLAN_SYSTEM_SLEEP_LIGHT_LSB
152#define SYSTEM_SLEEP_LIGHT_MASK WLAN_SYSTEM_SLEEP_LIGHT_MASK
153#define SYSTEM_SLEEP_LIGHT_GET(x) WLAN_SYSTEM_SLEEP_LIGHT_GET(x)
154#define SYSTEM_SLEEP_LIGHT_SET(x) WLAN_SYSTEM_SLEEP_LIGHT_SET(x)
155#define SYSTEM_SLEEP_DISABLE_MSB WLAN_SYSTEM_SLEEP_DISABLE_MSB
156#define SYSTEM_SLEEP_DISABLE_LSB WLAN_SYSTEM_SLEEP_DISABLE_LSB
157#define SYSTEM_SLEEP_DISABLE_MASK WLAN_SYSTEM_SLEEP_DISABLE_MASK
158#define SYSTEM_SLEEP_DISABLE_GET(x) WLAN_SYSTEM_SLEEP_DISABLE_GET(x)
159#define SYSTEM_SLEEP_DISABLE_SET(x) WLAN_SYSTEM_SLEEP_DISABLE_SET(x)
160#define LPO_INIT_DIVIDEND_INT_ADDRESS WLAN_LPO_INIT_DIVIDEND_INT_ADDRESS
161#define LPO_INIT_DIVIDEND_INT_OFFSET WLAN_LPO_INIT_DIVIDEND_INT_OFFSET
162#define LPO_INIT_DIVIDEND_INT_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MSB
163#define LPO_INIT_DIVIDEND_INT_VALUE_LSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB
164#define LPO_INIT_DIVIDEND_INT_VALUE_MASK WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK
165#define LPO_INIT_DIVIDEND_INT_VALUE_GET(x) WLAN_LPO_INIT_DIVIDEND_INT_VALUE_GET(x)
166#define LPO_INIT_DIVIDEND_INT_VALUE_SET(x) WLAN_LPO_INIT_DIVIDEND_INT_VALUE_SET(x)
167#define LPO_INIT_DIVIDEND_FRACTION_ADDRESS WLAN_LPO_INIT_DIVIDEND_FRACTION_ADDRESS
168#define LPO_INIT_DIVIDEND_FRACTION_OFFSET WLAN_LPO_INIT_DIVIDEND_FRACTION_OFFSET
169#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB
170#define LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB
171#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK
172#define LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x)
173#define LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x)
174#define LPO_CAL_ADDRESS WLAN_LPO_CAL_ADDRESS
175#define LPO_CAL_OFFSET WLAN_LPO_CAL_OFFSET
176#define LPO_CAL_ENABLE_MSB WLAN_LPO_CAL_ENABLE_MSB
177#define LPO_CAL_ENABLE_LSB WLAN_LPO_CAL_ENABLE_LSB
178#define LPO_CAL_ENABLE_MASK WLAN_LPO_CAL_ENABLE_MASK
179#define LPO_CAL_ENABLE_GET(x) WLAN_LPO_CAL_ENABLE_GET(x)
180#define LPO_CAL_ENABLE_SET(x) WLAN_LPO_CAL_ENABLE_SET(x)
181#define LPO_CAL_COUNT_MSB WLAN_LPO_CAL_COUNT_MSB
182#define LPO_CAL_COUNT_LSB WLAN_LPO_CAL_COUNT_LSB
183#define LPO_CAL_COUNT_MASK WLAN_LPO_CAL_COUNT_MASK
184#define LPO_CAL_COUNT_GET(x) WLAN_LPO_CAL_COUNT_GET(x)
185#define LPO_CAL_COUNT_SET(x) WLAN_LPO_CAL_COUNT_SET(x)
186
187#endif
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h
deleted file mode 100644
index 5c048ff51b0..00000000000
--- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h
+++ /dev/null
@@ -1,162 +0,0 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#ifndef _RTC_WLAN_REG_REG_H_
25#define _RTC_WLAN_REG_REG_H_
26
27#define WLAN_RESET_CONTROL_ADDRESS 0x00000000
28#define WLAN_RESET_CONTROL_OFFSET 0x00000000
29#define WLAN_RESET_CONTROL_DEBUG_UART_RST_MSB 14
30#define WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB 14
31#define WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK 0x00004000
32#define WLAN_RESET_CONTROL_DEBUG_UART_RST_GET(x) (((x) & WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK) >> WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB)
33#define WLAN_RESET_CONTROL_DEBUG_UART_RST_SET(x) (((x) << WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB) & WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK)
34#define WLAN_RESET_CONTROL_BB_COLD_RST_MSB 13
35#define WLAN_RESET_CONTROL_BB_COLD_RST_LSB 13
36#define WLAN_RESET_CONTROL_BB_COLD_RST_MASK 0x00002000
37#define WLAN_RESET_CONTROL_BB_COLD_RST_GET(x) (((x) & WLAN_RESET_CONTROL_BB_COLD_RST_MASK) >> WLAN_RESET_CONTROL_BB_COLD_RST_LSB)
38#define WLAN_RESET_CONTROL_BB_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_BB_COLD_RST_LSB) & WLAN_RESET_CONTROL_BB_COLD_RST_MASK)
39#define WLAN_RESET_CONTROL_BB_WARM_RST_MSB 12
40#define WLAN_RESET_CONTROL_BB_WARM_RST_LSB 12
41#define WLAN_RESET_CONTROL_BB_WARM_RST_MASK 0x00001000
42#define WLAN_RESET_CONTROL_BB_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_BB_WARM_RST_MASK) >> WLAN_RESET_CONTROL_BB_WARM_RST_LSB)
43#define WLAN_RESET_CONTROL_BB_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_BB_WARM_RST_LSB) & WLAN_RESET_CONTROL_BB_WARM_RST_MASK)
44#define WLAN_RESET_CONTROL_CPU_INIT_RESET_MSB 11
45#define WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB 11
46#define WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK 0x00000800
47#define WLAN_RESET_CONTROL_CPU_INIT_RESET_GET(x) (((x) & WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK) >> WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB)
48#define WLAN_RESET_CONTROL_CPU_INIT_RESET_SET(x) (((x) << WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB) & WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK)
49#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_MSB 10
50#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB 10
51#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK 0x00000400
52#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_GET(x) (((x) & WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK) >> WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB)
53#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_SET(x) (((x) << WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB) & WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK)
54#define WLAN_RESET_CONTROL_RST_OUT_MSB 9
55#define WLAN_RESET_CONTROL_RST_OUT_LSB 9
56#define WLAN_RESET_CONTROL_RST_OUT_MASK 0x00000200
57#define WLAN_RESET_CONTROL_RST_OUT_GET(x) (((x) & WLAN_RESET_CONTROL_RST_OUT_MASK) >> WLAN_RESET_CONTROL_RST_OUT_LSB)
58#define WLAN_RESET_CONTROL_RST_OUT_SET(x) (((x) << WLAN_RESET_CONTROL_RST_OUT_LSB) & WLAN_RESET_CONTROL_RST_OUT_MASK)
59#define WLAN_RESET_CONTROL_COLD_RST_MSB 8
60#define WLAN_RESET_CONTROL_COLD_RST_LSB 8
61#define WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000100
62#define WLAN_RESET_CONTROL_COLD_RST_GET(x) (((x) & WLAN_RESET_CONTROL_COLD_RST_MASK) >> WLAN_RESET_CONTROL_COLD_RST_LSB)
63#define WLAN_RESET_CONTROL_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_COLD_RST_LSB) & WLAN_RESET_CONTROL_COLD_RST_MASK)
64#define WLAN_RESET_CONTROL_WARM_RST_MSB 7
65#define WLAN_RESET_CONTROL_WARM_RST_LSB 7
66#define WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000080
67#define WLAN_RESET_CONTROL_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_WARM_RST_MASK) >> WLAN_RESET_CONTROL_WARM_RST_LSB)
68#define WLAN_RESET_CONTROL_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_WARM_RST_LSB) & WLAN_RESET_CONTROL_WARM_RST_MASK)
69#define WLAN_RESET_CONTROL_CPU_WARM_RST_MSB 6
70#define WLAN_RESET_CONTROL_CPU_WARM_RST_LSB 6
71#define WLAN_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040
72#define WLAN_RESET_CONTROL_CPU_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_CPU_WARM_RST_MASK) >> WLAN_RESET_CONTROL_CPU_WARM_RST_LSB)
73#define WLAN_RESET_CONTROL_CPU_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_CPU_WARM_RST_LSB) & WLAN_RESET_CONTROL_CPU_WARM_RST_MASK)
74#define WLAN_RESET_CONTROL_MAC_COLD_RST_MSB 5
75#define WLAN_RESET_CONTROL_MAC_COLD_RST_LSB 5
76#define WLAN_RESET_CONTROL_MAC_COLD_RST_MASK 0x00000020
77#define WLAN_RESET_CONTROL_MAC_COLD_RST_GET(x) (((x) & WLAN_RESET_CONTROL_MAC_COLD_RST_MASK) >> WLAN_RESET_CONTROL_MAC_COLD_RST_LSB)
78#define WLAN_RESET_CONTROL_MAC_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MAC_COLD_RST_LSB) & WLAN_RESET_CONTROL_MAC_COLD_RST_MASK)
79#define WLAN_RESET_CONTROL_MAC_WARM_RST_MSB 4
80#define WLAN_RESET_CONTROL_MAC_WARM_RST_LSB 4
81#define WLAN_RESET_CONTROL_MAC_WARM_RST_MASK 0x00000010
82#define WLAN_RESET_CONTROL_MAC_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_MAC_WARM_RST_MASK) >> WLAN_RESET_CONTROL_MAC_WARM_RST_LSB)
83#define WLAN_RESET_CONTROL_MAC_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MAC_WARM_RST_LSB) & WLAN_RESET_CONTROL_MAC_WARM_RST_MASK)
84#define WLAN_RESET_CONTROL_MBOX_RST_MSB 2
85#define WLAN_RESET_CONTROL_MBOX_RST_LSB 2
86#define WLAN_RESET_CONTROL_MBOX_RST_MASK 0x00000004
87#define WLAN_RESET_CONTROL_MBOX_RST_GET(x) (((x) & WLAN_RESET_CONTROL_MBOX_RST_MASK) >> WLAN_RESET_CONTROL_MBOX_RST_LSB)
88#define WLAN_RESET_CONTROL_MBOX_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MBOX_RST_LSB) & WLAN_RESET_CONTROL_MBOX_RST_MASK)
89#define WLAN_RESET_CONTROL_UART_RST_MSB 1
90#define WLAN_RESET_CONTROL_UART_RST_LSB 1
91#define WLAN_RESET_CONTROL_UART_RST_MASK 0x00000002
92#define WLAN_RESET_CONTROL_UART_RST_GET(x) (((x) & WLAN_RESET_CONTROL_UART_RST_MASK) >> WLAN_RESET_CONTROL_UART_RST_LSB)
93#define WLAN_RESET_CONTROL_UART_RST_SET(x) (((x) << WLAN_RESET_CONTROL_UART_RST_LSB) & WLAN_RESET_CONTROL_UART_RST_MASK)
94#define WLAN_RESET_CONTROL_SI0_RST_MSB 0
95#define WLAN_RESET_CONTROL_SI0_RST_LSB 0
96#define WLAN_RESET_CONTROL_SI0_RST_MASK 0x00000001
97#define WLAN_RESET_CONTROL_SI0_RST_GET(x) (((x) & WLAN_RESET_CONTROL_SI0_RST_MASK) >> WLAN_RESET_CONTROL_SI0_RST_LSB)
98#define WLAN_RESET_CONTROL_SI0_RST_SET(x) (((x) << WLAN_RESET_CONTROL_SI0_RST_LSB) & WLAN_RESET_CONTROL_SI0_RST_MASK)
99
100#define WLAN_CPU_CLOCK_ADDRESS 0x00000020
101#define WLAN_CPU_CLOCK_OFFSET 0x00000020
102#define WLAN_CPU_CLOCK_STANDARD_MSB 1
103#define WLAN_CPU_CLOCK_STANDARD_LSB 0
104#define WLAN_CPU_CLOCK_STANDARD_MASK 0x00000003
105#define WLAN_CPU_CLOCK_STANDARD_GET(x) (((x) & WLAN_CPU_CLOCK_STANDARD_MASK) >> WLAN_CPU_CLOCK_STANDARD_LSB)
106#define WLAN_CPU_CLOCK_STANDARD_SET(x) (((x) << WLAN_CPU_CLOCK_STANDARD_LSB) & WLAN_CPU_CLOCK_STANDARD_MASK)
107
108#define WLAN_CLOCK_CONTROL_ADDRESS 0x00000028
109#define WLAN_CLOCK_CONTROL_OFFSET 0x00000028
110#define WLAN_CLOCK_CONTROL_LF_CLK32_MSB 2
111#define WLAN_CLOCK_CONTROL_LF_CLK32_LSB 2
112#define WLAN_CLOCK_CONTROL_LF_CLK32_MASK 0x00000004
113#define WLAN_CLOCK_CONTROL_LF_CLK32_GET(x) (((x) & WLAN_CLOCK_CONTROL_LF_CLK32_MASK) >> WLAN_CLOCK_CONTROL_LF_CLK32_LSB)
114#define WLAN_CLOCK_CONTROL_LF_CLK32_SET(x) (((x) << WLAN_CLOCK_CONTROL_LF_CLK32_LSB) & WLAN_CLOCK_CONTROL_LF_CLK32_MASK)
115#define WLAN_CLOCK_CONTROL_SI0_CLK_MSB 0
116#define WLAN_CLOCK_CONTROL_SI0_CLK_LSB 0
117#define WLAN_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001
118#define WLAN_CLOCK_CONTROL_SI0_CLK_GET(x) (((x) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK) >> WLAN_CLOCK_CONTROL_SI0_CLK_LSB)
119#define WLAN_CLOCK_CONTROL_SI0_CLK_SET(x) (((x) << WLAN_CLOCK_CONTROL_SI0_CLK_LSB) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK)
120
121#define WLAN_SYSTEM_SLEEP_ADDRESS 0x000000c4
122#define WLAN_SYSTEM_SLEEP_OFFSET 0x000000c4
123#define WLAN_SYSTEM_SLEEP_HOST_IF_MSB 4
124#define WLAN_SYSTEM_SLEEP_HOST_IF_LSB 4
125#define WLAN_SYSTEM_SLEEP_HOST_IF_MASK 0x00000010
126#define WLAN_SYSTEM_SLEEP_HOST_IF_GET(x) (((x) & WLAN_SYSTEM_SLEEP_HOST_IF_MASK) >> WLAN_SYSTEM_SLEEP_HOST_IF_LSB)
127#define WLAN_SYSTEM_SLEEP_HOST_IF_SET(x) (((x) << WLAN_SYSTEM_SLEEP_HOST_IF_LSB) & WLAN_SYSTEM_SLEEP_HOST_IF_MASK)
128#define WLAN_SYSTEM_SLEEP_MBOX_MSB 3
129#define WLAN_SYSTEM_SLEEP_MBOX_LSB 3
130#define WLAN_SYSTEM_SLEEP_MBOX_MASK 0x00000008
131#define WLAN_SYSTEM_SLEEP_MBOX_GET(x) (((x) & WLAN_SYSTEM_SLEEP_MBOX_MASK) >> WLAN_SYSTEM_SLEEP_MBOX_LSB)
132#define WLAN_SYSTEM_SLEEP_MBOX_SET(x) (((x) << WLAN_SYSTEM_SLEEP_MBOX_LSB) & WLAN_SYSTEM_SLEEP_MBOX_MASK)
133#define WLAN_SYSTEM_SLEEP_MAC_IF_MSB 2
134#define WLAN_SYSTEM_SLEEP_MAC_IF_LSB 2
135#define WLAN_SYSTEM_SLEEP_MAC_IF_MASK 0x00000004
136#define WLAN_SYSTEM_SLEEP_MAC_IF_GET(x) (((x) & WLAN_SYSTEM_SLEEP_MAC_IF_MASK) >> WLAN_SYSTEM_SLEEP_MAC_IF_LSB)
137#define WLAN_SYSTEM_SLEEP_MAC_IF_SET(x) (((x) << WLAN_SYSTEM_SLEEP_MAC_IF_LSB) & WLAN_SYSTEM_SLEEP_MAC_IF_MASK)
138#define WLAN_SYSTEM_SLEEP_LIGHT_MSB 1
139#define WLAN_SYSTEM_SLEEP_LIGHT_LSB 1
140#define WLAN_SYSTEM_SLEEP_LIGHT_MASK 0x00000002
141#define WLAN_SYSTEM_SLEEP_LIGHT_GET(x) (((x) & WLAN_SYSTEM_SLEEP_LIGHT_MASK) >> WLAN_SYSTEM_SLEEP_LIGHT_LSB)
142#define WLAN_SYSTEM_SLEEP_LIGHT_SET(x) (((x) << WLAN_SYSTEM_SLEEP_LIGHT_LSB) & WLAN_SYSTEM_SLEEP_LIGHT_MASK)
143#define WLAN_SYSTEM_SLEEP_DISABLE_MSB 0
144#define WLAN_SYSTEM_SLEEP_DISABLE_LSB 0
145#define WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001
146#define WLAN_SYSTEM_SLEEP_DISABLE_GET(x) (((x) & WLAN_SYSTEM_SLEEP_DISABLE_MASK) >> WLAN_SYSTEM_SLEEP_DISABLE_LSB)
147#define WLAN_SYSTEM_SLEEP_DISABLE_SET(x) (((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & WLAN_SYSTEM_SLEEP_DISABLE_MASK)
148
149#define WLAN_LPO_CAL_ADDRESS 0x000000e0
150#define WLAN_LPO_CAL_OFFSET 0x000000e0
151#define WLAN_LPO_CAL_ENABLE_MSB 20
152#define WLAN_LPO_CAL_ENABLE_LSB 20
153#define WLAN_LPO_CAL_ENABLE_MASK 0x00100000
154#define WLAN_LPO_CAL_ENABLE_GET(x) (((x) & WLAN_LPO_CAL_ENABLE_MASK) >> WLAN_LPO_CAL_ENABLE_LSB)
155#define WLAN_LPO_CAL_ENABLE_SET(x) (((x) << WLAN_LPO_CAL_ENABLE_LSB) & WLAN_LPO_CAL_ENABLE_MASK)
156#define WLAN_LPO_CAL_COUNT_MSB 19
157#define WLAN_LPO_CAL_COUNT_LSB 0
158#define WLAN_LPO_CAL_COUNT_MASK 0x000fffff
159#define WLAN_LPO_CAL_COUNT_GET(x) (((x) & WLAN_LPO_CAL_COUNT_MASK) >> WLAN_LPO_CAL_COUNT_LSB)
160#define WLAN_LPO_CAL_COUNT_SET(x) (((x) << WLAN_LPO_CAL_COUNT_LSB) & WLAN_LPO_CAL_COUNT_MASK)
161
162#endif /* _RTC_WLAN_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h
deleted file mode 100644
index 302b20bc1ba..00000000000
--- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h
+++ /dev/null
@@ -1,40 +0,0 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#ifndef _UART_REG_REG_H_
25#define _UART_REG_REG_H_
26
27#define UART_CLKDIV_ADDRESS 0x00000008
28#define UART_CLKDIV_OFFSET 0x00000008
29#define UART_CLKDIV_CLK_SCALE_MSB 23
30#define UART_CLKDIV_CLK_SCALE_LSB 16
31#define UART_CLKDIV_CLK_SCALE_MASK 0x00ff0000
32#define UART_CLKDIV_CLK_SCALE_GET(x) (((x) & UART_CLKDIV_CLK_SCALE_MASK) >> UART_CLKDIV_CLK_SCALE_LSB)
33#define UART_CLKDIV_CLK_SCALE_SET(x) (((x) << UART_CLKDIV_CLK_SCALE_LSB) & UART_CLKDIV_CLK_SCALE_MASK)
34#define UART_CLKDIV_CLK_STEP_MSB 15
35#define UART_CLKDIV_CLK_STEP_LSB 0
36#define UART_CLKDIV_CLK_STEP_MASK 0x0000ffff
37#define UART_CLKDIV_CLK_STEP_GET(x) (((x) & UART_CLKDIV_CLK_STEP_MASK) >> UART_CLKDIV_CLK_STEP_LSB)
38#define UART_CLKDIV_CLK_STEP_SET(x) (((x) << UART_CLKDIV_CLK_STEP_LSB) & UART_CLKDIV_CLK_STEP_MASK)
39
40#endif /* _UART_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/athdefs.h b/drivers/staging/ath6kl/include/common/athdefs.h
deleted file mode 100644
index 74922481e06..00000000000
--- a/drivers/staging/ath6kl/include/common/athdefs.h
+++ /dev/null
@@ -1,75 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="athdefs.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef __ATHDEFS_H__
24#define __ATHDEFS_H__
25
26/*
27 * This file contains definitions that may be used across both
28 * Host and Target software. Nothing here is module-dependent
29 * or platform-dependent.
30 */
31
32/*
33 * Generic error codes that can be used by hw, sta, ap, sim, dk
34 * and any other environments.
35 * Feel free to add any more non-zero codes that you need.
36 */
37
38#define A_ERROR (-1) /* Generic error return */
39#define A_DEVICE_NOT_FOUND 1 /* not able to find PCI device */
40#define A_NO_MEMORY 2 /* not able to allocate memory,
41 * not avail#defineable */
42#define A_MEMORY_NOT_AVAIL 3 /* memory region is not free for
43 * mapping */
44#define A_NO_FREE_DESC 4 /* no free descriptors available */
45#define A_BAD_ADDRESS 5 /* address does not match descriptor */
46#define A_WIN_DRIVER_ERROR 6 /* used in NT_HW version,
47 * if problem at init */
48#define A_REGS_NOT_MAPPED 7 /* registers not correctly mapped */
49#define A_EPERM 8 /* Not superuser */
50#define A_EACCES 0 /* Access denied */
51#define A_ENOENT 10 /* No such entry, search failed, etc. */
52#define A_EEXIST 11 /* The object already exists
53 * (can't create) */
54#define A_EFAULT 12 /* Bad address fault */
55#define A_EBUSY 13 /* Object is busy */
56#define A_EINVAL 14 /* Invalid parameter */
57#define A_EMSGSIZE 15 /* Bad message buffer length */
58#define A_ECANCELED 16 /* Operation canceled */
59#define A_ENOTSUP 17 /* Operation not supported */
60#define A_ECOMM 18 /* Communication error on send */
61#define A_EPROTO 19 /* Protocol error */
62#define A_ENODEV 20 /* No such device */
63#define A_EDEVNOTUP 21 /* device is not UP */
64#define A_NO_RESOURCE 22 /* No resources for
65 * requested operation */
66#define A_HARDWARE 23 /* Hardware failure */
67#define A_PENDING 24 /* Asynchronous routine; will send up
68 * results later
69 * (typically in callback) */
70#define A_EBADCHANNEL 25 /* The channel cannot be used */
71#define A_DECRYPT_ERROR 26 /* Decryption error */
72#define A_PHY_ERROR 27 /* RX PHY error */
73#define A_CONSUMED 28 /* Object was consumed */
74
75#endif /* __ATHDEFS_H__ */
diff --git a/drivers/staging/ath6kl/include/common/bmi_msg.h b/drivers/staging/ath6kl/include/common/bmi_msg.h
deleted file mode 100644
index 84e8db569a9..00000000000
--- a/drivers/staging/ath6kl/include/common/bmi_msg.h
+++ /dev/null
@@ -1,233 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//
19// Author(s): ="Atheros"
20//------------------------------------------------------------------------------
21
22#ifndef __BMI_MSG_H__
23#define __BMI_MSG_H__
24
25/*
26 * Bootloader Messaging Interface (BMI)
27 *
28 * BMI is a very simple messaging interface used during initialization
29 * to read memory, write memory, execute code, and to define an
30 * application entry PC.
31 *
32 * It is used to download an application to AR6K, to provide
33 * patches to code that is already resident on AR6K, and generally
34 * to examine and modify state. The Host has an opportunity to use
35 * BMI only once during bootup. Once the Host issues a BMI_DONE
36 * command, this opportunity ends.
37 *
38 * The Host writes BMI requests to mailbox0, and reads BMI responses
39 * from mailbox0. BMI requests all begin with a command
40 * (see below for specific commands), and are followed by
41 * command-specific data.
42 *
43 * Flow control:
44 * The Host can only issue a command once the Target gives it a
45 * "BMI Command Credit", using AR6K Counter #4. As soon as the
46 * Target has completed a command, it issues another BMI Command
47 * Credit (so the Host can issue the next command).
48 *
49 * BMI handles all required Target-side cache flushing.
50 */
51
52
53/* Maximum data size used for BMI transfers */
54#define BMI_DATASZ_MAX 256
55
56/* BMI Commands */
57
58#define BMI_NO_COMMAND 0
59
60#define BMI_DONE 1
61 /*
62 * Semantics: Host is done using BMI
63 * Request format:
64 * u32 command (BMI_DONE)
65 * Response format: none
66 */
67
68#define BMI_READ_MEMORY 2
69 /*
70 * Semantics: Host reads AR6K memory
71 * Request format:
72 * u32 command (BMI_READ_MEMORY)
73 * u32 address
74 * u32 length, at most BMI_DATASZ_MAX
75 * Response format:
76 * u8 data[length]
77 */
78
79#define BMI_WRITE_MEMORY 3
80 /*
81 * Semantics: Host writes AR6K memory
82 * Request format:
83 * u32 command (BMI_WRITE_MEMORY)
84 * u32 address
85 * u32 length, at most BMI_DATASZ_MAX
86 * u8 data[length]
87 * Response format: none
88 */
89
90#define BMI_EXECUTE 4
91 /*
92 * Semantics: Causes AR6K to execute code
93 * Request format:
94 * u32 command (BMI_EXECUTE)
95 * u32 address
96 * u32 parameter
97 * Response format:
98 * u32 return value
99 */
100
101#define BMI_SET_APP_START 5
102 /*
103 * Semantics: Set Target application starting address
104 * Request format:
105 * u32 command (BMI_SET_APP_START)
106 * u32 address
107 * Response format: none
108 */
109
110#define BMI_READ_SOC_REGISTER 6
111 /*
112 * Semantics: Read a 32-bit Target SOC register.
113 * Request format:
114 * u32 command (BMI_READ_REGISTER)
115 * u32 address
116 * Response format:
117 * u32 value
118 */
119
120#define BMI_WRITE_SOC_REGISTER 7
121 /*
122 * Semantics: Write a 32-bit Target SOC register.
123 * Request format:
124 * u32 command (BMI_WRITE_REGISTER)
125 * u32 address
126 * u32 value
127 *
128 * Response format: none
129 */
130
131#define BMI_GET_TARGET_ID 8
132#define BMI_GET_TARGET_INFO 8
133 /*
134 * Semantics: Fetch the 4-byte Target information
135 * Request format:
136 * u32 command (BMI_GET_TARGET_ID/INFO)
137 * Response format1 (old firmware):
138 * u32 TargetVersionID
139 * Response format2 (newer firmware):
140 * u32 TARGET_VERSION_SENTINAL
141 * struct bmi_target_info;
142 */
143
144PREPACK struct bmi_target_info {
145 u32 target_info_byte_count; /* size of this structure */
146 u32 target_ver; /* Target Version ID */
147 u32 target_type; /* Target type */
148} POSTPACK;
149#define TARGET_VERSION_SENTINAL 0xffffffff
150#define TARGET_TYPE_AR6001 1
151#define TARGET_TYPE_AR6002 2
152#define TARGET_TYPE_AR6003 3
153
154
155#define BMI_ROMPATCH_INSTALL 9
156 /*
157 * Semantics: Install a ROM Patch.
158 * Request format:
159 * u32 command (BMI_ROMPATCH_INSTALL)
160 * u32 Target ROM Address
161 * u32 Target RAM Address or Value (depending on Target Type)
162 * u32 Size, in bytes
163 * u32 Activate? 1-->activate;
164 * 0-->install but do not activate
165 * Response format:
166 * u32 PatchID
167 */
168
169#define BMI_ROMPATCH_UNINSTALL 10
170 /*
171 * Semantics: Uninstall a previously-installed ROM Patch,
172 * automatically deactivating, if necessary.
173 * Request format:
174 * u32 command (BMI_ROMPATCH_UNINSTALL)
175 * u32 PatchID
176 *
177 * Response format: none
178 */
179
180#define BMI_ROMPATCH_ACTIVATE 11
181 /*
182 * Semantics: Activate a list of previously-installed ROM Patches.
183 * Request format:
184 * u32 command (BMI_ROMPATCH_ACTIVATE)
185 * u32 rompatch_count
186 * u32 PatchID[rompatch_count]
187 *
188 * Response format: none
189 */
190
191#define BMI_ROMPATCH_DEACTIVATE 12
192 /*
193 * Semantics: Deactivate a list of active ROM Patches.
194 * Request format:
195 * u32 command (BMI_ROMPATCH_DEACTIVATE)
196 * u32 rompatch_count
197 * u32 PatchID[rompatch_count]
198 *
199 * Response format: none
200 */
201
202
203#define BMI_LZ_STREAM_START 13
204 /*
205 * Semantics: Begin an LZ-compressed stream of input
206 * which is to be uncompressed by the Target to an
207 * output buffer at address. The output buffer must
208 * be sufficiently large to hold the uncompressed
209 * output from the compressed input stream. This BMI
210 * command should be followed by a series of 1 or more
211 * BMI_LZ_DATA commands.
212 * u32 command (BMI_LZ_STREAM_START)
213 * u32 address
214 * Note: Not supported on all versions of ROM firmware.
215 */
216
217#define BMI_LZ_DATA 14
218 /*
219 * Semantics: Host writes AR6K memory with LZ-compressed
220 * data which is uncompressed by the Target. This command
221 * must be preceded by a BMI_LZ_STREAM_START command. A series
222 * of BMI_LZ_DATA commands are considered part of a single
223 * input stream until another BMI_LZ_STREAM_START is issued.
224 * Request format:
225 * u32 command (BMI_LZ_DATA)
226 * u32 length (of compressed data),
227 * at most BMI_DATASZ_MAX
228 * u8 CompressedData[length]
229 * Response format: none
230 * Note: Not supported on all versions of ROM firmware.
231 */
232
233#endif /* __BMI_MSG_H__ */
diff --git a/drivers/staging/ath6kl/include/common/cnxmgmt.h b/drivers/staging/ath6kl/include/common/cnxmgmt.h
deleted file mode 100644
index 7a902cb5483..00000000000
--- a/drivers/staging/ath6kl/include/common/cnxmgmt.h
+++ /dev/null
@@ -1,36 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="cnxmgmt.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef _CNXMGMT_H_
25#define _CNXMGMT_H_
26
27typedef enum {
28 CM_CONNECT_WITHOUT_SCAN = 0x0001,
29 CM_CONNECT_ASSOC_POLICY_USER = 0x0002,
30 CM_CONNECT_SEND_REASSOC = 0x0004,
31 CM_CONNECT_WITHOUT_ROAMTABLE_UPDATE = 0x0008,
32 CM_CONNECT_DO_WPA_OFFLOAD = 0x0010,
33 CM_CONNECT_DO_NOT_DEAUTH = 0x0020,
34} CM_CONNECT_TYPE;
35
36#endif /* _CNXMGMT_H_ */
diff --git a/drivers/staging/ath6kl/include/common/dbglog.h b/drivers/staging/ath6kl/include/common/dbglog.h
deleted file mode 100644
index 5566e568b83..00000000000
--- a/drivers/staging/ath6kl/include/common/dbglog.h
+++ /dev/null
@@ -1,126 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="dbglog.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef _DBGLOG_H_
25#define _DBGLOG_H_
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#define DBGLOG_TIMESTAMP_OFFSET 0
32#define DBGLOG_TIMESTAMP_MASK 0x0000FFFF /* Bit 0-15. Contains bit
33 8-23 of the LF0 timer */
34#define DBGLOG_DBGID_OFFSET 16
35#define DBGLOG_DBGID_MASK 0x03FF0000 /* Bit 16-25 */
36#define DBGLOG_DBGID_NUM_MAX 256 /* Upper limit is width of mask */
37
38#define DBGLOG_MODULEID_OFFSET 26
39#define DBGLOG_MODULEID_MASK 0x3C000000 /* Bit 26-29 */
40#define DBGLOG_MODULEID_NUM_MAX 16 /* Upper limit is width of mask */
41
42/*
43 * Please ensure that the definition of any new module introduced is captured
44 * between the DBGLOG_MODULEID_START and DBGLOG_MODULEID_END defines. The
45 * structure is required for the parser to correctly pick up the values for
46 * different modules.
47 */
48#define DBGLOG_MODULEID_START
49#define DBGLOG_MODULEID_INF 0
50#define DBGLOG_MODULEID_WMI 1
51#define DBGLOG_MODULEID_MISC 2
52#define DBGLOG_MODULEID_PM 3
53#define DBGLOG_MODULEID_TXRX_MGMTBUF 4
54#define DBGLOG_MODULEID_TXRX_TXBUF 5
55#define DBGLOG_MODULEID_TXRX_RXBUF 6
56#define DBGLOG_MODULEID_WOW 7
57#define DBGLOG_MODULEID_WHAL 8
58#define DBGLOG_MODULEID_DC 9
59#define DBGLOG_MODULEID_CO 10
60#define DBGLOG_MODULEID_RO 11
61#define DBGLOG_MODULEID_CM 12
62#define DBGLOG_MODULEID_MGMT 13
63#define DBGLOG_MODULEID_TMR 14
64#define DBGLOG_MODULEID_BTCOEX 15
65#define DBGLOG_MODULEID_END
66
67#define DBGLOG_NUM_ARGS_OFFSET 30
68#define DBGLOG_NUM_ARGS_MASK 0xC0000000 /* Bit 30-31 */
69#define DBGLOG_NUM_ARGS_MAX 2 /* Upper limit is width of mask */
70
71#define DBGLOG_MODULE_LOG_ENABLE_OFFSET 0
72#define DBGLOG_MODULE_LOG_ENABLE_MASK 0x0000FFFF
73
74#define DBGLOG_REPORTING_ENABLED_OFFSET 16
75#define DBGLOG_REPORTING_ENABLED_MASK 0x00010000
76
77#define DBGLOG_TIMESTAMP_RESOLUTION_OFFSET 17
78#define DBGLOG_TIMESTAMP_RESOLUTION_MASK 0x000E0000
79
80#define DBGLOG_REPORT_SIZE_OFFSET 20
81#define DBGLOG_REPORT_SIZE_MASK 0x3FF00000
82
83#define DBGLOG_LOG_BUFFER_SIZE 1500
84#define DBGLOG_DBGID_DEFINITION_LEN_MAX 90
85
86PREPACK struct dbglog_buf_s {
87 struct dbglog_buf_s *next;
88 u8 *buffer;
89 u32 bufsize;
90 u32 length;
91 u32 count;
92 u32 free;
93} POSTPACK;
94
95PREPACK struct dbglog_hdr_s {
96 struct dbglog_buf_s *dbuf;
97 u32 dropped;
98} POSTPACK;
99
100PREPACK struct dbglog_config_s {
101 u32 cfgvalid; /* Mask with valid config bits */
102 union {
103 /* TODO: Take care of endianness */
104 struct {
105 u32 mmask:16; /* Mask of modules with logging on */
106 u32 rep:1; /* Reporting enabled or not */
107 u32 tsr:3; /* Time stamp resolution. Def: 1 ms */
108 u32 size:10; /* Report size in number of messages */
109 u32 reserved:2;
110 } dbglog_config;
111
112 u32 value;
113 } u;
114} POSTPACK;
115
116#define cfgmmask u.dbglog_config.mmask
117#define cfgrep u.dbglog_config.rep
118#define cfgtsr u.dbglog_config.tsr
119#define cfgsize u.dbglog_config.size
120#define cfgvalue u.value
121
122#ifdef __cplusplus
123}
124#endif
125
126#endif /* _DBGLOG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/dbglog_id.h b/drivers/staging/ath6kl/include/common/dbglog_id.h
deleted file mode 100644
index 15ef829cab2..00000000000
--- a/drivers/staging/ath6kl/include/common/dbglog_id.h
+++ /dev/null
@@ -1,558 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="dbglog_id.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef _DBGLOG_ID_H_
25#define _DBGLOG_ID_H_
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/*
32 * The nomenclature for the debug identifiers is MODULE_DESCRIPTION.
33 * Please ensure that the definition of any new debugid introduced is captured
34 * between the <MODULE>_DBGID_DEFINITION_START and
35 * <MODULE>_DBGID_DEFINITION_END defines. The structure is required for the
36 * parser to correctly pick up the values for different debug identifiers.
37 */
38
39/* INF debug identifier definitions */
40#define INF_DBGID_DEFINITION_START
41#define INF_ASSERTION_FAILED 1
42#define INF_TARGET_ID 2
43#define INF_DBGID_DEFINITION_END
44
45/* WMI debug identifier definitions */
46#define WMI_DBGID_DEFINITION_START
47#define WMI_CMD_RX_XTND_PKT_TOO_SHORT 1
48#define WMI_EXTENDED_CMD_NOT_HANDLED 2
49#define WMI_CMD_RX_PKT_TOO_SHORT 3
50#define WMI_CALLING_WMI_EXTENSION_FN 4
51#define WMI_CMD_NOT_HANDLED 5
52#define WMI_IN_SYNC 6
53#define WMI_TARGET_WMI_SYNC_CMD 7
54#define WMI_SET_SNR_THRESHOLD_PARAMS 8
55#define WMI_SET_RSSI_THRESHOLD_PARAMS 9
56#define WMI_SET_LQ_TRESHOLD_PARAMS 10
57#define WMI_TARGET_CREATE_PSTREAM_CMD 11
58#define WMI_WI_DTM_INUSE 12
59#define WMI_TARGET_DELETE_PSTREAM_CMD 13
60#define WMI_TARGET_IMPLICIT_DELETE_PSTREAM_CMD 14
61#define WMI_TARGET_GET_BIT_RATE_CMD 15
62#define WMI_GET_RATE_MASK_CMD_FIX_RATE_MASK_IS 16
63#define WMI_TARGET_GET_AVAILABLE_CHANNELS_CMD 17
64#define WMI_TARGET_GET_TX_PWR_CMD 18
65#define WMI_FREE_EVBUF_WMIBUF 19
66#define WMI_FREE_EVBUF_DATABUF 20
67#define WMI_FREE_EVBUF_BADFLAG 21
68#define WMI_HTC_RX_ERROR_DATA_PACKET 22
69#define WMI_HTC_RX_SYNC_PAUSING_FOR_MBOX 23
70#define WMI_INCORRECT_WMI_DATA_HDR_DROPPING_PKT 24
71#define WMI_SENDING_READY_EVENT 25
72#define WMI_SETPOWER_MDOE_TO_MAXPERF 26
73#define WMI_SETPOWER_MDOE_TO_REC 27
74#define WMI_BSSINFO_EVENT_FROM 28
75#define WMI_TARGET_GET_STATS_CMD 29
76#define WMI_SENDING_SCAN_COMPLETE_EVENT 30
77#define WMI_SENDING_RSSI_INDB_THRESHOLD_EVENT 31
78#define WMI_SENDING_RSSI_INDBM_THRESHOLD_EVENT 32
79#define WMI_SENDING_LINK_QUALITY_THRESHOLD_EVENT 33
80#define WMI_SENDING_ERROR_REPORT_EVENT 34
81#define WMI_SENDING_CAC_EVENT 35
82#define WMI_TARGET_GET_ROAM_TABLE_CMD 36
83#define WMI_TARGET_GET_ROAM_DATA_CMD 37
84#define WMI_SENDING_GPIO_INTR_EVENT 38
85#define WMI_SENDING_GPIO_ACK_EVENT 39
86#define WMI_SENDING_GPIO_DATA_EVENT 40
87#define WMI_CMD_RX 41
88#define WMI_CMD_RX_XTND 42
89#define WMI_EVENT_SEND 43
90#define WMI_EVENT_SEND_XTND 44
91#define WMI_CMD_PARAMS_DUMP_START 45
92#define WMI_CMD_PARAMS_DUMP_END 46
93#define WMI_CMD_PARAMS 47
94#define WMI_DBGID_DEFINITION_END
95
96/* MISC debug identifier definitions */
97#define MISC_DBGID_DEFINITION_START
98#define MISC_WLAN_SCHEDULER_EVENT_REGISTER_ERROR 1
99#define TLPM_INIT 2
100#define TLPM_FILTER_POWER_STATE 3
101#define TLPM_NOTIFY_NOT_IDLE 4
102#define TLPM_TIMEOUT_IDLE_HANDLER 5
103#define TLPM_TIMEOUT_WAKEUP_HANDLER 6
104#define TLPM_WAKEUP_SIGNAL_HANDLER 7
105#define TLPM_UNEXPECTED_GPIO_INTR_ERROR 8
106#define TLPM_BREAK_ON_NOT_RECEIVED_ERROR 9
107#define TLPM_BREAK_OFF_NOT_RECIVED_ERROR 10
108#define TLPM_ACK_GPIO_INTR 11
109#define TLPM_ON 12
110#define TLPM_OFF 13
111#define TLPM_WAKEUP_FROM_HOST 14
112#define TLPM_WAKEUP_FROM_BT 15
113#define TLPM_TX_BREAK_RECIVED 16
114#define TLPM_IDLE_TIMER_NOT_RUNNING 17
115#define MISC_DBGID_DEFINITION_END
116
117/* TXRX debug identifier definitions */
118#define TXRX_TXBUF_DBGID_DEFINITION_START
119#define TXRX_TXBUF_ALLOCATE_BUF 1
120#define TXRX_TXBUF_QUEUE_BUF_TO_MBOX 2
121#define TXRX_TXBUF_QUEUE_BUF_TO_TXQ 3
122#define TXRX_TXBUF_TXQ_DEPTH 4
123#define TXRX_TXBUF_IBSS_QUEUE_TO_SFQ 5
124#define TXRX_TXBUF_IBSS_QUEUE_TO_TXQ_FRM_SFQ 6
125#define TXRX_TXBUF_INITIALIZE_TIMER 7
126#define TXRX_TXBUF_ARM_TIMER 8
127#define TXRX_TXBUF_DISARM_TIMER 9
128#define TXRX_TXBUF_UNINITIALIZE_TIMER 10
129#define TXRX_TXBUF_DBGID_DEFINITION_END
130
131#define TXRX_RXBUF_DBGID_DEFINITION_START
132#define TXRX_RXBUF_ALLOCATE_BUF 1
133#define TXRX_RXBUF_QUEUE_TO_HOST 2
134#define TXRX_RXBUF_QUEUE_TO_WLAN 3
135#define TXRX_RXBUF_ZERO_LEN_BUF 4
136#define TXRX_RXBUF_QUEUE_TO_HOST_LASTBUF_IN_RXCHAIN 5
137#define TXRX_RXBUF_LASTBUF_IN_RXCHAIN_ZEROBUF 6
138#define TXRX_RXBUF_QUEUE_EMPTY_QUEUE_TO_WLAN 7
139#define TXRX_RXBUF_SEND_TO_RECV_MGMT 8
140#define TXRX_RXBUF_SEND_TO_IEEE_LAYER 9
141#define TXRX_RXBUF_REQUEUE_ERROR 10
142#define TXRX_RXBUF_DBGID_DEFINITION_END
143
144#define TXRX_MGMTBUF_DBGID_DEFINITION_START
145#define TXRX_MGMTBUF_ALLOCATE_BUF 1
146#define TXRX_MGMTBUF_ALLOCATE_SM_BUF 2
147#define TXRX_MGMTBUF_ALLOCATE_RMBUF 3
148#define TXRX_MGMTBUF_GET_BUF 4
149#define TXRX_MGMTBUF_GET_SM_BUF 5
150#define TXRX_MGMTBUF_QUEUE_BUF_TO_TXQ 6
151#define TXRX_MGMTBUF_REAPED_BUF 7
152#define TXRX_MGMTBUF_REAPED_SM_BUF 8
153#define TXRX_MGMTBUF_WAIT_FOR_TXQ_DRAIN 9
154#define TXRX_MGMTBUF_WAIT_FOR_TXQ_SFQ_DRAIN 10
155#define TXRX_MGMTBUF_ENQUEUE_INTO_DATA_SFQ 11
156#define TXRX_MGMTBUF_DEQUEUE_FROM_DATA_SFQ 12
157#define TXRX_MGMTBUF_PAUSE_DATA_TXQ 13
158#define TXRX_MGMTBUF_RESUME_DATA_TXQ 14
159#define TXRX_MGMTBUF_WAIT_FORTXQ_DRAIN_TIMEOUT 15
160#define TXRX_MGMTBUF_DRAINQ 16
161#define TXRX_MGMTBUF_INDICATE_Q_DRAINED 17
162#define TXRX_MGMTBUF_ENQUEUE_INTO_HW_SFQ 18
163#define TXRX_MGMTBUF_DEQUEUE_FROM_HW_SFQ 19
164#define TXRX_MGMTBUF_PAUSE_HW_TXQ 20
165#define TXRX_MGMTBUF_RESUME_HW_TXQ 21
166#define TXRX_MGMTBUF_TEAR_DOWN_BA 22
167#define TXRX_MGMTBUF_PROCESS_ADDBA_REQ 23
168#define TXRX_MGMTBUF_PROCESS_DELBA 24
169#define TXRX_MGMTBUF_PERFORM_BA 25
170#define TXRX_MGMTBUF_WLAN_RESET_ON_ERROR 26
171#define TXRX_MGMTBUF_DBGID_DEFINITION_END
172
173/* PM (Power Module) debug identifier definitions */
174#define PM_DBGID_DEFINITION_START
175#define PM_INIT 1
176#define PM_ENABLE 2
177#define PM_SET_STATE 3
178#define PM_SET_POWERMODE 4
179#define PM_CONN_NOTIFY 5
180#define PM_REF_COUNT_NEGATIVE 6
181#define PM_INFRA_STA_APSD_ENABLE 7
182#define PM_INFRA_STA_UPDATE_APSD_STATE 8
183#define PM_CHAN_OP_REQ 9
184#define PM_SET_MY_BEACON_POLICY 10
185#define PM_SET_ALL_BEACON_POLICY 11
186#define PM_INFRA_STA_SET_PM_PARAMS1 12
187#define PM_INFRA_STA_SET_PM_PARAMS2 13
188#define PM_ADHOC_SET_PM_CAPS_FAIL 14
189#define PM_ADHOC_UNKNOWN_IBSS_ATTRIB_ID 15
190#define PM_ADHOC_SET_PM_PARAMS 16
191#define PM_ADHOC_STATE1 18
192#define PM_ADHOC_STATE2 19
193#define PM_ADHOC_CONN_MAP 20
194#define PM_FAKE_SLEEP 21
195#define PM_AP_STATE1 22
196#define PM_AP_SET_PM_PARAMS 23
197#define PM_DBGID_DEFINITION_END
198
199/* Wake on Wireless debug identifier definitions */
200#define WOW_DBGID_DEFINITION_START
201#define WOW_INIT 1
202#define WOW_GET_CONFIG_DSET 2
203#define WOW_NO_CONFIG_DSET 3
204#define WOW_INVALID_CONFIG_DSET 4
205#define WOW_USE_DEFAULT_CONFIG 5
206#define WOW_SETUP_GPIO 6
207#define WOW_INIT_DONE 7
208#define WOW_SET_GPIO_PIN 8
209#define WOW_CLEAR_GPIO_PIN 9
210#define WOW_SET_WOW_MODE_CMD 10
211#define WOW_SET_HOST_MODE_CMD 11
212#define WOW_ADD_WOW_PATTERN_CMD 12
213#define WOW_NEW_WOW_PATTERN_AT_INDEX 13
214#define WOW_DEL_WOW_PATTERN_CMD 14
215#define WOW_LIST_CONTAINS_PATTERNS 15
216#define WOW_GET_WOW_LIST_CMD 16
217#define WOW_INVALID_FILTER_ID 17
218#define WOW_INVALID_FILTER_LISTID 18
219#define WOW_NO_VALID_FILTER_AT_ID 19
220#define WOW_NO_VALID_LIST_AT_ID 20
221#define WOW_NUM_PATTERNS_EXCEEDED 21
222#define WOW_NUM_LISTS_EXCEEDED 22
223#define WOW_GET_WOW_STATS 23
224#define WOW_CLEAR_WOW_STATS 24
225#define WOW_WAKEUP_HOST 25
226#define WOW_EVENT_WAKEUP_HOST 26
227#define WOW_EVENT_DISCARD 27
228#define WOW_PATTERN_MATCH 28
229#define WOW_PATTERN_NOT_MATCH 29
230#define WOW_PATTERN_NOT_MATCH_OFFSET 30
231#define WOW_DISABLED_HOST_ASLEEP 31
232#define WOW_ENABLED_HOST_ASLEEP_NO_PATTERNS 32
233#define WOW_ENABLED_HOST_ASLEEP_NO_MATCH_FOUND 33
234#define WOW_DBGID_DEFINITION_END
235
236/* WHAL debug identifier definitions */
237#define WHAL_DBGID_DEFINITION_START
238#define WHAL_ERROR_ANI_CONTROL 1
239#define WHAL_ERROR_CHIP_TEST1 2
240#define WHAL_ERROR_CHIP_TEST2 3
241#define WHAL_ERROR_EEPROM_CHECKSUM 4
242#define WHAL_ERROR_EEPROM_MACADDR 5
243#define WHAL_ERROR_INTERRUPT_HIU 6
244#define WHAL_ERROR_KEYCACHE_RESET 7
245#define WHAL_ERROR_KEYCACHE_SET 8
246#define WHAL_ERROR_KEYCACHE_TYPE 9
247#define WHAL_ERROR_KEYCACHE_TKIPENTRY 10
248#define WHAL_ERROR_KEYCACHE_WEPLENGTH 11
249#define WHAL_ERROR_PHY_INVALID_CHANNEL 12
250#define WHAL_ERROR_POWER_AWAKE 13
251#define WHAL_ERROR_POWER_SET 14
252#define WHAL_ERROR_RECV_STOPDMA 15
253#define WHAL_ERROR_RECV_STOPPCU 16
254#define WHAL_ERROR_RESET_CHANNF1 17
255#define WHAL_ERROR_RESET_CHANNF2 18
256#define WHAL_ERROR_RESET_PM 19
257#define WHAL_ERROR_RESET_OFFSETCAL 20
258#define WHAL_ERROR_RESET_RFGRANT 21
259#define WHAL_ERROR_RESET_RXFRAME 22
260#define WHAL_ERROR_RESET_STOPDMA 23
261#define WHAL_ERROR_RESET_RECOVER 24
262#define WHAL_ERROR_XMIT_COMPUTE 25
263#define WHAL_ERROR_XMIT_NOQUEUE 26
264#define WHAL_ERROR_XMIT_ACTIVEQUEUE 27
265#define WHAL_ERROR_XMIT_BADTYPE 28
266#define WHAL_ERROR_XMIT_STOPDMA 29
267#define WHAL_ERROR_INTERRUPT_BB_PANIC 30
268#define WHAL_ERROR_RESET_TXIQCAL 31
269#define WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW 32
270#define WHAL_DBGID_DEFINITION_END
271
272/* DC debug identifier definitions */
273#define DC_DBGID_DEFINITION_START
274#define DC_SCAN_CHAN_START 1
275#define DC_SCAN_CHAN_FINISH 2
276#define DC_BEACON_RECEIVE7 3
277#define DC_SSID_PROBE_CB 4
278#define DC_SEND_NEXT_SSID_PROBE 5
279#define DC_START_SEARCH 6
280#define DC_CANCEL_SEARCH_CB 7
281#define DC_STOP_SEARCH 8
282#define DC_END_SEARCH 9
283#define DC_MIN_CHDWELL_TIMEOUT 10
284#define DC_START_SEARCH_CANCELED 11
285#define DC_SET_POWER_MODE 12
286#define DC_INIT 13
287#define DC_SEARCH_OPPORTUNITY 14
288#define DC_RECEIVED_ANY_BEACON 15
289#define DC_RECEIVED_MY_BEACON 16
290#define DC_PROFILE_IS_ADHOC_BUT_BSS_IS_INFRA 17
291#define DC_PS_ENABLED_BUT_ATHEROS_IE_ABSENT 18
292#define DC_BSS_ADHOC_CHANNEL_NOT_ALLOWED 19
293#define DC_SET_BEACON_UPDATE 20
294#define DC_BEACON_UPDATE_COMPLETE 21
295#define DC_END_SEARCH_BEACON_UPDATE_COMP_CB 22
296#define DC_BSSINFO_EVENT_DROPPED 23
297#define DC_IEEEPS_ENABLED_BUT_ATIM_ABSENT 24
298#define DC_DBGID_DEFINITION_END
299
300/* CO debug identifier definitions */
301#define CO_DBGID_DEFINITION_START
302#define CO_INIT 1
303#define CO_ACQUIRE_LOCK 2
304#define CO_START_OP1 3
305#define CO_START_OP2 4
306#define CO_DRAIN_TX_COMPLETE_CB 5
307#define CO_CHANGE_CHANNEL_CB 6
308#define CO_RETURN_TO_HOME_CHANNEL 7
309#define CO_FINISH_OP_TIMEOUT 8
310#define CO_OP_END 9
311#define CO_CANCEL_OP 10
312#define CO_CHANGE_CHANNEL 11
313#define CO_RELEASE_LOCK 12
314#define CO_CHANGE_STATE 13
315#define CO_DBGID_DEFINITION_END
316
317/* RO debug identifier definitions */
318#define RO_DBGID_DEFINITION_START
319#define RO_REFRESH_ROAM_TABLE 1
320#define RO_UPDATE_ROAM_CANDIDATE 2
321#define RO_UPDATE_ROAM_CANDIDATE_CB 3
322#define RO_UPDATE_ROAM_CANDIDATE_FINISH 4
323#define RO_REFRESH_ROAM_TABLE_DONE 5
324#define RO_PERIODIC_SEARCH_CB 6
325#define RO_PERIODIC_SEARCH_TIMEOUT 7
326#define RO_INIT 8
327#define RO_BMISS_STATE1 9
328#define RO_BMISS_STATE2 10
329#define RO_SET_PERIODIC_SEARCH_ENABLE 11
330#define RO_SET_PERIODIC_SEARCH_DISABLE 12
331#define RO_ENABLE_SQ_THRESHOLD 13
332#define RO_DISABLE_SQ_THRESHOLD 14
333#define RO_ADD_BSS_TO_ROAM_TABLE 15
334#define RO_SET_PERIODIC_SEARCH_MODE 16
335#define RO_CONFIGURE_SQ_THRESHOLD1 17
336#define RO_CONFIGURE_SQ_THRESHOLD2 18
337#define RO_CONFIGURE_SQ_PARAMS 19
338#define RO_LOW_SIGNAL_QUALITY_EVENT 20
339#define RO_HIGH_SIGNAL_QUALITY_EVENT 21
340#define RO_REMOVE_BSS_FROM_ROAM_TABLE 22
341#define RO_UPDATE_CONNECTION_STATE_METRIC 23
342#define RO_DBGID_DEFINITION_END
343
344/* CM debug identifier definitions */
345#define CM_DBGID_DEFINITION_START
346#define CM_INITIATE_HANDOFF 1
347#define CM_INITIATE_HANDOFF_CB 2
348#define CM_CONNECT_EVENT 3
349#define CM_DISCONNECT_EVENT 4
350#define CM_INIT 5
351#define CM_HANDOFF_SOURCE 6
352#define CM_SET_HANDOFF_TRIGGERS 7
353#define CM_CONNECT_REQUEST 8
354#define CM_CONNECT_REQUEST_CB 9
355#define CM_CONTINUE_SCAN_CB 10
356#define CM_DBGID_DEFINITION_END
357
358
359/* mgmt debug identifier definitions */
360#define MGMT_DBGID_DEFINITION_START
361#define KEYMGMT_CONNECTION_INIT 1
362#define KEYMGMT_CONNECTION_COMPLETE 2
363#define KEYMGMT_CONNECTION_CLOSE 3
364#define KEYMGMT_ADD_KEY 4
365#define MLME_NEW_STATE 5
366#define MLME_CONN_INIT 6
367#define MLME_CONN_COMPLETE 7
368#define MLME_CONN_CLOSE 8
369#define MGMT_DBGID_DEFINITION_END
370
371/* TMR debug identifier definitions */
372#define TMR_DBGID_DEFINITION_START
373#define TMR_HANG_DETECTED 1
374#define TMR_WDT_TRIGGERED 2
375#define TMR_WDT_RESET 3
376#define TMR_HANDLER_ENTRY 4
377#define TMR_HANDLER_EXIT 5
378#define TMR_SAVED_START 6
379#define TMR_SAVED_END 7
380#define TMR_DBGID_DEFINITION_END
381
382/* BTCOEX debug identifier definitions */
383#define BTCOEX_DBGID_DEFINITION_START
384#define BTCOEX_STATUS_CMD 1
385#define BTCOEX_PARAMS_CMD 2
386#define BTCOEX_ANT_CONFIG 3
387#define BTCOEX_COLOCATED_BT_DEVICE 4
388#define BTCOEX_CLOSE_RANGE_SCO_ON 5
389#define BTCOEX_CLOSE_RANGE_SCO_OFF 6
390#define BTCOEX_CLOSE_RANGE_A2DP_ON 7
391#define BTCOEX_CLOSE_RANGE_A2DP_OFF 8
392#define BTCOEX_A2DP_PROTECT_ON 9
393#define BTCOEX_A2DP_PROTECT_OFF 10
394#define BTCOEX_SCO_PROTECT_ON 11
395#define BTCOEX_SCO_PROTECT_OFF 12
396#define BTCOEX_CLOSE_RANGE_DETECTOR_START 13
397#define BTCOEX_CLOSE_RANGE_DETECTOR_STOP 14
398#define BTCOEX_CLOSE_RANGE_TOGGLE 15
399#define BTCOEX_CLOSE_RANGE_TOGGLE_RSSI_LRCNT 16
400#define BTCOEX_CLOSE_RANGE_RSSI_THRESH 17
401#define BTCOEX_CLOSE_RANGE_LOW_RATE_THRESH 18
402#define BTCOEX_PTA_PRI_INTR_HANDLER 19
403#define BTCOEX_PSPOLL_QUEUED 20
404#define BTCOEX_PSPOLL_COMPLETE 21
405#define BTCOEX_DBG_PM_AWAKE 22
406#define BTCOEX_DBG_PM_SLEEP 23
407#define BTCOEX_DBG_SCO_COEX_ON 24
408#define BTCOEX_SCO_DATARECEIVE 25
409#define BTCOEX_INTR_INIT 26
410#define BTCOEX_PTA_PRI_DIFF 27
411#define BTCOEX_TIM_NOTIFICATION 28
412#define BTCOEX_SCO_WAKEUP_ON_DATA 29
413#define BTCOEX_SCO_SLEEP 30
414#define BTCOEX_SET_WEIGHTS 31
415#define BTCOEX_SCO_DATARECEIVE_LATENCY_VAL 32
416#define BTCOEX_SCO_MEASURE_TIME_DIFF 33
417#define BTCOEX_SET_EOL_VAL 34
418#define BTCOEX_OPT_DETECT_HANDLER 35
419#define BTCOEX_SCO_TOGGLE_STATE 36
420#define BTCOEX_SCO_STOMP 37
421#define BTCOEX_NULL_COMP_CALLBACK 38
422#define BTCOEX_RX_INCOMING 39
423#define BTCOEX_RX_INCOMING_CTL 40
424#define BTCOEX_RX_INCOMING_MGMT 41
425#define BTCOEX_RX_INCOMING_DATA 42
426#define BTCOEX_RTS_RECEPTION 43
427#define BTCOEX_FRAME_PRI_LOW_RATE_THRES 44
428#define BTCOEX_PM_FAKE_SLEEP 45
429#define BTCOEX_ACL_COEX_STATUS 46
430#define BTCOEX_ACL_COEX_DETECTION 47
431#define BTCOEX_A2DP_COEX_STATUS 48
432#define BTCOEX_SCO_STATUS 49
433#define BTCOEX_WAKEUP_ON_DATA 50
434#define BTCOEX_DATARECEIVE 51
435#define BTCOEX_GET_MAX_AGGR_SIZE 53
436#define BTCOEX_MAX_AGGR_AVAIL_TIME 54
437#define BTCOEX_DBG_WBTIMER_INTR 55
438#define BTCOEX_DBG_SCO_SYNC 57
439#define BTCOEX_UPLINK_QUEUED_RATE 59
440#define BTCOEX_DBG_UPLINK_ENABLE_EOL 60
441#define BTCOEX_UPLINK_FRAME_DURATION 61
442#define BTCOEX_UPLINK_SET_EOL 62
443#define BTCOEX_DBG_EOL_EXPIRED 63
444#define BTCOEX_DBG_DATA_COMPLETE 64
445#define BTCOEX_UPLINK_QUEUED_TIMESTAMP 65
446#define BTCOEX_DBG_DATA_COMPLETE_TIME 66
447#define BTCOEX_DBG_A2DP_ROLE_IS_SLAVE 67
448#define BTCOEX_DBG_A2DP_ROLE_IS_MASTER 68
449#define BTCOEX_DBG_UPLINK_SEQ_NUM 69
450#define BTCOEX_UPLINK_AGGR_SEQ 70
451#define BTCOEX_DBG_TX_COMP_SEQ_NO 71
452#define BTCOEX_DBG_MAX_AGGR_PAUSE_STATE 72
453#define BTCOEX_DBG_ACL_TRAFFIC 73
454#define BTCOEX_CURR_AGGR_PROP 74
455#define BTCOEX_DBG_SCO_GET_PER_TIME_DIFF 75
456#define BTCOEX_PSPOLL_PROCESS 76
457#define BTCOEX_RETURN_FROM_MAC 77
458#define BTCOEX_FREED_REQUEUED_CNT 78
459#define BTCOEX_DBG_TOGGLE_LOW_RATES 79
460#define BTCOEX_MAC_GOES_TO_SLEEP 80
461#define BTCOEX_DBG_A2DP_NO_SYNC 81
462#define BTCOEX_RETURN_FROM_MAC_HOLD_Q_INFO 82
463#define BTCOEX_RETURN_FROM_MAC_AC 83
464#define BTCOEX_DBG_DTIM_RECV 84
465#define BTCOEX_IS_PRE_UPDATE 86
466#define BTCOEX_ENQUEUED_BIT_MAP 87
467#define BTCOEX_TX_COMPLETE_FIRST_DESC_STATS 88
468#define BTCOEX_UPLINK_DESC 89
469#define BTCOEX_SCO_GET_PER_FIRST_FRM_TIMESTAMP 90
470#define BTCOEX_DBG_RECV_ACK 94
471#define BTCOEX_DBG_ADDBA_INDICATION 95
472#define BTCOEX_TX_COMPLETE_EOL_FAILED 96
473#define BTCOEX_DBG_A2DP_USAGE_COMPLETE 97
474#define BTCOEX_DBG_A2DP_STOMP_FOR_BCN_HANDLER 98
475#define BTCOEX_DBG_A2DP_SYNC_INTR 99
476#define BTCOEX_DBG_A2DP_STOMP_FOR_BCN_RECEPTION 100
477#define BTCOEX_FORM_AGGR_CURR_AGGR 101
478#define BTCOEX_DBG_TOGGLE_A2DP_BURST_CNT 102
479#define BTCOEX_DBG_BT_TRAFFIC 103
480#define BTCOEX_DBG_STOMP_BT_TRAFFIC 104
481#define BTCOEX_RECV_NULL 105
482#define BTCOEX_DBG_A2DP_MASTER_BT_END 106
483#define BTCOEX_DBG_A2DP_BT_START 107
484#define BTCOEX_DBG_A2DP_SLAVE_BT_END 108
485#define BTCOEX_DBG_A2DP_STOMP_BT 109
486#define BTCOEX_DBG_GO_TO_SLEEP 110
487#define BTCOEX_DBG_A2DP_PKT 111
488#define BTCOEX_DBG_A2DP_PSPOLL_DATA_RECV 112
489#define BTCOEX_DBG_A2DP_NULL 113
490#define BTCOEX_DBG_UPLINK_DATA 114
491#define BTCOEX_DBG_A2DP_STOMP_LOW_PRIO_NULL 115
492#define BTCOEX_DBG_ADD_BA_RESP_TIMEOUT 116
493#define BTCOEX_DBG_TXQ_STATE 117
494#define BTCOEX_DBG_ALLOW_SCAN 118
495#define BTCOEX_DBG_SCAN_REQUEST 119
496#define BTCOEX_A2DP_SLEEP 127
497#define BTCOEX_DBG_DATA_ACTIV_TIMEOUT 128
498#define BTCOEX_DBG_SWITCH_TO_PSPOLL_ON_MODE 129
499#define BTCOEX_DBG_SWITCH_TO_PSPOLL_OFF_MODE 130
500#define BTCOEX_DATARECEIVE_AGGR 131
501#define BTCOEX_DBG_DATA_RECV_SLEEPING_PENDING 132
502#define BTCOEX_DBG_DATARESP_TIMEOUT 133
503#define BTCOEX_BDG_BMISS 134
504#define BTCOEX_DBG_DATA_RECV_WAKEUP_TIM 135
505#define BTCOEX_DBG_SECOND_BMISS 136
506#define BTCOEX_DBG_SET_WLAN_STATE 138
507#define BTCOEX_BDG_FIRST_BMISS 139
508#define BTCOEX_DBG_A2DP_CHAN_OP 140
509#define BTCOEX_DBG_A2DP_INTR 141
510#define BTCOEX_DBG_BT_INQUIRY 142
511#define BTCOEX_DBG_BT_INQUIRY_DATA_FETCH 143
512#define BTCOEX_DBG_POST_INQUIRY_FINISH 144
513#define BTCOEX_DBG_SCO_OPT_MODE_TIMER_HANDLER 145
514#define BTCOEX_DBG_NULL_FRAME_SLEEP 146
515#define BTCOEX_DBG_NULL_FRAME_AWAKE 147
516#define BTCOEX_DBG_SET_AGGR_SIZE 152
517#define BTCOEX_DBG_TEAR_BA_TIMEOUT 153
518#define BTCOEX_DBG_MGMT_FRAME_SEQ_NO 154
519#define BTCOEX_DBG_SCO_STOMP_HIGH_PRI 155
520#define BTCOEX_DBG_COLOCATED_BT_DEV 156
521#define BTCOEX_DBG_FE_ANT_TYPE 157
522#define BTCOEX_DBG_BT_INQUIRY_CMD 158
523#define BTCOEX_DBG_SCO_CONFIG 159
524#define BTCOEX_DBG_SCO_PSPOLL_CONFIG 160
525#define BTCOEX_DBG_SCO_OPTMODE_CONFIG 161
526#define BTCOEX_DBG_A2DP_CONFIG 162
527#define BTCOEX_DBG_A2DP_PSPOLL_CONFIG 163
528#define BTCOEX_DBG_A2DP_OPTMODE_CONFIG 164
529#define BTCOEX_DBG_ACLCOEX_CONFIG 165
530#define BTCOEX_DBG_ACLCOEX_PSPOLL_CONFIG 166
531#define BTCOEX_DBG_ACLCOEX_OPTMODE_CONFIG 167
532#define BTCOEX_DBG_DEBUG_CMD 168
533#define BTCOEX_DBG_SET_BT_OPERATING_STATUS 169
534#define BTCOEX_DBG_GET_CONFIG 170
535#define BTCOEX_DBG_GET_STATS 171
536#define BTCOEX_DBG_BT_OPERATING_STATUS 172
537#define BTCOEX_DBG_PERFORM_RECONNECT 173
538#define BTCOEX_DBG_ACL_WLAN_MED 175
539#define BTCOEX_DBG_ACL_BT_MED 176
540#define BTCOEX_DBG_WLAN_CONNECT 177
541#define BTCOEX_DBG_A2DP_DUAL_START 178
542#define BTCOEX_DBG_PMAWAKE_NOTIFY 179
543#define BTCOEX_DBG_BEACON_SCAN_ENABLE 180
544#define BTCOEX_DBG_BEACON_SCAN_DISABLE 181
545#define BTCOEX_DBG_RX_NOTIFY 182
546#define BTCOEX_SCO_GET_PER_SECOND_FRM_TIMESTAMP 183
547#define BTCOEX_DBG_TXQ_DETAILS 184
548#define BTCOEX_DBG_SCO_STOMP_LOW_PRI 185
549#define BTCOEX_DBG_A2DP_FORCE_SCAN 186
550#define BTCOEX_DBG_DTIM_STOMP_COMP 187
551#define BTCOEX_ACL_PRESENCE_TIMER 188
552#define BTCOEX_DBGID_DEFINITION_END
553
554#ifdef __cplusplus
555}
556#endif
557
558#endif /* _DBGLOG_ID_H_ */
diff --git a/drivers/staging/ath6kl/include/common/discovery.h b/drivers/staging/ath6kl/include/common/discovery.h
deleted file mode 100644
index da1b3324506..00000000000
--- a/drivers/staging/ath6kl/include/common/discovery.h
+++ /dev/null
@@ -1,75 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="discovery.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef _DISCOVERY_H_
25#define _DISCOVERY_H_
26
27/*
28 * DC_SCAN_PRIORITY is an 8-bit bitmap of the scan priority of a channel
29 */
30typedef enum {
31 DEFAULT_SCPRI = 0x01,
32 POPULAR_SCPRI = 0x02,
33 SSIDS_SCPRI = 0x04,
34 PROF_SCPRI = 0x08,
35} DC_SCAN_PRIORITY;
36
37/* The following search type construct can be used to manipulate the behavior of the search module based on different bits set */
38typedef enum {
39 SCAN_RESET = 0,
40 SCAN_ALL = (DEFAULT_SCPRI | POPULAR_SCPRI | \
41 SSIDS_SCPRI | PROF_SCPRI),
42
43 SCAN_POPULAR = (POPULAR_SCPRI | SSIDS_SCPRI | PROF_SCPRI),
44 SCAN_SSIDS = (SSIDS_SCPRI | PROF_SCPRI),
45 SCAN_PROF_MASK = (PROF_SCPRI),
46 SCAN_MULTI_CHANNEL = 0x000100,
47 SCAN_DETERMINISTIC = 0x000200,
48 SCAN_PROFILE_MATCH_TERMINATED = 0x000400,
49 SCAN_HOME_CHANNEL_SKIP = 0x000800,
50 SCAN_CHANNEL_LIST_CONTINUE = 0x001000,
51 SCAN_CURRENT_SSID_SKIP = 0x002000,
52 SCAN_ACTIVE_PROBE_DISABLE = 0x004000,
53 SCAN_CHANNEL_HINT_ONLY = 0x008000,
54 SCAN_ACTIVE_CHANNELS_ONLY = 0x010000,
55 SCAN_UNUSED1 = 0x020000, /* unused */
56 SCAN_PERIODIC = 0x040000,
57 SCAN_FIXED_DURATION = 0x080000,
58 SCAN_AP_ASSISTED = 0x100000,
59} DC_SCAN_TYPE;
60
61typedef enum {
62 BSS_REPORTING_DEFAULT = 0x0,
63 EXCLUDE_NON_SCAN_RESULTS = 0x1, /* Exclude results outside of scan */
64} DC_BSS_REPORTING_POLICY;
65
66typedef enum {
67 DC_IGNORE_WPAx_GROUP_CIPHER = 0x01,
68 DC_PROFILE_MATCH_DONE = 0x02,
69 DC_IGNORE_AAC_BEACON = 0x04,
70 DC_CSA_FOLLOW_BSS = 0x08,
71} DC_PROFILE_FILTER;
72
73#define DEFAULT_DC_PROFILE_FILTER (DC_CSA_FOLLOW_BSS)
74
75#endif /* _DISCOVERY_H_ */
diff --git a/drivers/staging/ath6kl/include/common/epping_test.h b/drivers/staging/ath6kl/include/common/epping_test.h
deleted file mode 100644
index 9eb5fdfa746..00000000000
--- a/drivers/staging/ath6kl/include/common/epping_test.h
+++ /dev/null
@@ -1,111 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//
22
23/* This file contains shared definitions for the host/target endpoint ping test */
24
25#ifndef EPPING_TEST_H_
26#define EPPING_TEST_H_
27
28 /* alignment to 4-bytes */
29#define EPPING_ALIGNMENT_PAD (((sizeof(struct htc_frame_hdr) + 3) & (~0x3)) - sizeof(struct htc_frame_hdr))
30
31#ifndef A_OFFSETOF
32#define A_OFFSETOF(type,field) (int)(&(((type *)NULL)->field))
33#endif
34
35#define EPPING_RSVD_FILL 0xCC
36
37#define HCI_RSVD_EXPECTED_PKT_TYPE_RECV_OFFSET 7
38
39typedef PREPACK struct {
40 u8 _HCIRsvd[8]; /* reserved for HCI packet header (GMBOX) testing */
41 u8 StreamEcho_h; /* stream no. to echo this packet on (filled by host) */
42 u8 StreamEchoSent_t; /* stream no. packet was echoed to (filled by target)
43 When echoed: StreamEchoSent_t == StreamEcho_h */
44 u8 StreamRecv_t; /* stream no. that target received this packet on (filled by target) */
45 u8 StreamNo_h; /* stream number to send on (filled by host) */
46 u8 Magic_h[4]; /* magic number to filter for this packet on the host*/
47 u8 _rsvd[6]; /* reserved fields that must be set to a "reserved" value
48 since this packet maps to a 14-byte ethernet frame we want
49 to make sure ethertype field is set to something unknown */
50
51 u8 _pad[2]; /* padding for alignment */
52 u8 TimeStamp[8]; /* timestamp of packet (host or target) */
53 u32 HostContext_h; /* 4 byte host context, target echos this back */
54 u32 SeqNo; /* sequence number (set by host or target) */
55 u16 Cmd_h; /* ping command (filled by host) */
56 u16 CmdFlags_h; /* optional flags */
57 u8 CmdBuffer_h[8]; /* buffer for command (host -> target) */
58 u8 CmdBuffer_t[8]; /* buffer for command (target -> host) */
59 u16 DataLength; /* length of data */
60 u16 DataCRC; /* 16 bit CRC of data */
61 u16 HeaderCRC; /* header CRC (fields : StreamNo_h to end, minus HeaderCRC) */
62} POSTPACK EPPING_HEADER;
63
64#define EPPING_PING_MAGIC_0 0xAA
65#define EPPING_PING_MAGIC_1 0x55
66#define EPPING_PING_MAGIC_2 0xCE
67#define EPPING_PING_MAGIC_3 0xEC
68
69
70
71#define IS_EPPING_PACKET(pPkt) (((pPkt)->Magic_h[0] == EPPING_PING_MAGIC_0) && \
72 ((pPkt)->Magic_h[1] == EPPING_PING_MAGIC_1) && \
73 ((pPkt)->Magic_h[2] == EPPING_PING_MAGIC_2) && \
74 ((pPkt)->Magic_h[3] == EPPING_PING_MAGIC_3))
75
76#define SET_EPPING_PACKET_MAGIC(pPkt) { (pPkt)->Magic_h[0] = EPPING_PING_MAGIC_0; \
77 (pPkt)->Magic_h[1] = EPPING_PING_MAGIC_1; \
78 (pPkt)->Magic_h[2] = EPPING_PING_MAGIC_2; \
79 (pPkt)->Magic_h[3] = EPPING_PING_MAGIC_3;}
80
81#define CMD_FLAGS_DATA_CRC (1 << 0) /* DataCRC field is valid */
82#define CMD_FLAGS_DELAY_ECHO (1 << 1) /* delay the echo of the packet */
83#define CMD_FLAGS_NO_DROP (1 << 2) /* do not drop at HTC layer no matter what the stream is */
84
85#define IS_EPING_PACKET_NO_DROP(pPkt) ((pPkt)->CmdFlags_h & CMD_FLAGS_NO_DROP)
86
87#define EPPING_CMD_ECHO_PACKET 1 /* echo packet test */
88#define EPPING_CMD_RESET_RECV_CNT 2 /* reset recv count */
89#define EPPING_CMD_CAPTURE_RECV_CNT 3 /* fetch recv count, 4-byte count returned in CmdBuffer_t */
90#define EPPING_CMD_NO_ECHO 4 /* non-echo packet test (tx-only) */
91#define EPPING_CMD_CONT_RX_START 5 /* continuous RX packets, parameters are in CmdBuffer_h */
92#define EPPING_CMD_CONT_RX_STOP 6 /* stop continuous RX packet transmission */
93
94 /* test command parameters may be no more than 8 bytes */
95typedef PREPACK struct {
96 u16 BurstCnt; /* number of packets to burst together (for HTC 2.1 testing) */
97 u16 PacketLength; /* length of packet to generate including header */
98 u16 Flags; /* flags */
99
100#define EPPING_CONT_RX_DATA_CRC (1 << 0) /* Add CRC to all data */
101#define EPPING_CONT_RX_RANDOM_DATA (1 << 1) /* randomize the data pattern */
102#define EPPING_CONT_RX_RANDOM_LEN (1 << 2) /* randomize the packet lengths */
103} POSTPACK EPPING_CONT_RX_PARAMS;
104
105#define EPPING_HDR_CRC_OFFSET A_OFFSETOF(EPPING_HEADER,StreamNo_h)
106#define EPPING_HDR_BYTES_CRC (sizeof(EPPING_HEADER) - EPPING_HDR_CRC_OFFSET - (sizeof(u16)))
107
108#define HCI_TRANSPORT_STREAM_NUM 16 /* this number is higher than the define WMM AC classes so we
109 can use this to distinguish packets */
110
111#endif /*EPPING_TEST_H_*/
diff --git a/drivers/staging/ath6kl/include/common/gmboxif.h b/drivers/staging/ath6kl/include/common/gmboxif.h
deleted file mode 100644
index ea11c14def4..00000000000
--- a/drivers/staging/ath6kl/include/common/gmboxif.h
+++ /dev/null
@@ -1,70 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22
23#ifndef __GMBOXIF_H__
24#define __GMBOXIF_H__
25
26/* GMBOX interface definitions */
27
28#define AR6K_GMBOX_CREDIT_COUNTER 1 /* we use credit counter 1 to track credits */
29#define AR6K_GMBOX_CREDIT_SIZE_COUNTER 2 /* credit counter 2 is used to pass the size of each credit */
30
31
32 /* HCI UART transport definitions when used over GMBOX interface */
33#define HCI_UART_COMMAND_PKT 0x01
34#define HCI_UART_ACL_PKT 0x02
35#define HCI_UART_SCO_PKT 0x03
36#define HCI_UART_EVENT_PKT 0x04
37
38 /* definitions for BT HCI packets */
39typedef PREPACK struct {
40 u16 Flags_ConnHandle;
41 u16 Length;
42} POSTPACK BT_HCI_ACL_HEADER;
43
44typedef PREPACK struct {
45 u16 Flags_ConnHandle;
46 u8 Length;
47} POSTPACK BT_HCI_SCO_HEADER;
48
49typedef PREPACK struct {
50 u16 OpCode;
51 u8 ParamLength;
52} POSTPACK BT_HCI_COMMAND_HEADER;
53
54typedef PREPACK struct {
55 u8 EventCode;
56 u8 ParamLength;
57} POSTPACK BT_HCI_EVENT_HEADER;
58
59/* MBOX host interrupt signal assignments */
60
61#define MBOX_SIG_HCI_BRIDGE_MAX 8
62#define MBOX_SIG_HCI_BRIDGE_BT_ON 0
63#define MBOX_SIG_HCI_BRIDGE_BT_OFF 1
64#define MBOX_SIG_HCI_BRIDGE_BAUD_SET 2
65#define MBOX_SIG_HCI_BRIDGE_PWR_SAV_ON 3
66#define MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF 4
67
68
69#endif /* __GMBOXIF_H__ */
70
diff --git a/drivers/staging/ath6kl/include/common/gpio_reg.h b/drivers/staging/ath6kl/include/common/gpio_reg.h
deleted file mode 100644
index f9d425d48dc..00000000000
--- a/drivers/staging/ath6kl/include/common/gpio_reg.h
+++ /dev/null
@@ -1,9 +0,0 @@
1#ifndef _GPIO_REG_REG_H_
2#define _GPIO_REG_REG_H_
3
4#define GPIO_PIN10_ADDRESS 0x00000050
5#define GPIO_PIN11_ADDRESS 0x00000054
6#define GPIO_PIN12_ADDRESS 0x00000058
7#define GPIO_PIN13_ADDRESS 0x0000005c
8
9#endif /* _GPIO_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/htc.h b/drivers/staging/ath6kl/include/common/htc.h
deleted file mode 100644
index 85cbfa89d67..00000000000
--- a/drivers/staging/ath6kl/include/common/htc.h
+++ /dev/null
@@ -1,227 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef __HTC_H__
25#define __HTC_H__
26
27#define A_OFFSETOF(type,field) (unsigned long)(&(((type *)NULL)->field))
28
29#define ASSEMBLE_UNALIGNED_UINT16(p,highbyte,lowbyte) \
30 (((u16)(((u8 *)(p))[(highbyte)])) << 8 | (u16)(((u8 *)(p))[(lowbyte)]))
31
32/* alignment independent macros (little-endian) to fetch UINT16s or UINT8s from a
33 * structure using only the type and field name.
34 * Use these macros if there is the potential for unaligned buffer accesses. */
35#define A_GET_UINT16_FIELD(p,type,field) \
36 ASSEMBLE_UNALIGNED_UINT16(p,\
37 A_OFFSETOF(type,field) + 1, \
38 A_OFFSETOF(type,field))
39
40#define A_SET_UINT16_FIELD(p,type,field,value) \
41{ \
42 ((u8 *)(p))[A_OFFSETOF(type,field)] = (u8)(value); \
43 ((u8 *)(p))[A_OFFSETOF(type,field) + 1] = (u8)((value) >> 8); \
44}
45
46#define A_GET_UINT8_FIELD(p,type,field) \
47 ((u8 *)(p))[A_OFFSETOF(type,field)]
48
49#define A_SET_UINT8_FIELD(p,type,field,value) \
50 ((u8 *)(p))[A_OFFSETOF(type,field)] = (value)
51
52/****** DANGER DANGER ***************
53 *
54 * The frame header length and message formats defined herein were
55 * selected to accommodate optimal alignment for target processing. This reduces code
56 * size and improves performance.
57 *
58 * Any changes to the header length may alter the alignment and cause exceptions
59 * on the target. When adding to the message structures insure that fields are
60 * properly aligned.
61 *
62 */
63
64/* HTC frame header */
65PREPACK struct htc_frame_hdr {
66 /* do not remove or re-arrange these fields, these are minimally required
67 * to take advantage of 4-byte lookaheads in some hardware implementations */
68 u8 EndpointID;
69 u8 Flags;
70 u16 PayloadLen; /* length of data (including trailer) that follows the header */
71
72 /***** end of 4-byte lookahead ****/
73
74 u8 ControlBytes[2];
75
76 /* message payload starts after the header */
77
78} POSTPACK;
79
80/* frame header flags */
81
82 /* send direction */
83#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0)
84#define HTC_FLAGS_SEND_BUNDLE (1 << 1) /* start or part of bundle */
85 /* receive direction */
86#define HTC_FLAGS_RECV_UNUSED_0 (1 << 0) /* bit 0 unused */
87#define HTC_FLAGS_RECV_TRAILER (1 << 1) /* bit 1 trailer data present */
88#define HTC_FLAGS_RECV_UNUSED_2 (1 << 0) /* bit 2 unused */
89#define HTC_FLAGS_RECV_UNUSED_3 (1 << 0) /* bit 3 unused */
90#define HTC_FLAGS_RECV_BUNDLE_CNT_MASK (0xF0) /* bits 7..4 */
91#define HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT 4
92
93#define HTC_HDR_LENGTH (sizeof(struct htc_frame_hdr))
94#define HTC_MAX_TRAILER_LENGTH 255
95#define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(struct htc_frame_hdr))
96
97/* HTC control message IDs */
98
99#define HTC_MSG_READY_ID 1
100#define HTC_MSG_CONNECT_SERVICE_ID 2
101#define HTC_MSG_CONNECT_SERVICE_RESPONSE_ID 3
102#define HTC_MSG_SETUP_COMPLETE_ID 4
103#define HTC_MSG_SETUP_COMPLETE_EX_ID 5
104
105#define HTC_MAX_CONTROL_MESSAGE_LENGTH 256
106
107/* base message ID header */
108typedef PREPACK struct {
109 u16 MessageID;
110} POSTPACK HTC_UNKNOWN_MSG;
111
112/* HTC ready message
113 * direction : target-to-host */
114typedef PREPACK struct {
115 u16 MessageID; /* ID */
116 u16 CreditCount; /* number of credits the target can offer */
117 u16 CreditSize; /* size of each credit */
118 u8 MaxEndpoints; /* maximum number of endpoints the target has resources for */
119 u8 _Pad1;
120} POSTPACK HTC_READY_MSG;
121
122 /* extended HTC ready message */
123typedef PREPACK struct {
124 HTC_READY_MSG Version2_0_Info; /* legacy version 2.0 information at the front... */
125 /* extended information */
126 u8 HTCVersion;
127 u8 MaxMsgsPerHTCBundle;
128} POSTPACK HTC_READY_EX_MSG;
129
130#define HTC_VERSION_2P0 0x00
131#define HTC_VERSION_2P1 0x01 /* HTC 2.1 */
132
133#define HTC_SERVICE_META_DATA_MAX_LENGTH 128
134
135/* connect service
136 * direction : host-to-target */
137typedef PREPACK struct {
138 u16 MessageID;
139 u16 ServiceID; /* service ID of the service to connect to */
140 u16 ConnectionFlags; /* connection flags */
141
142#define HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE (1 << 2) /* reduce credit dribbling when
143 the host needs credits */
144#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK (0x3)
145#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_FOURTH 0x0
146#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF 0x1
147#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS 0x2
148#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_UNITY 0x3
149
150 u8 ServiceMetaLength; /* length of meta data that follows */
151 u8 _Pad1;
152
153 /* service-specific meta data starts after the header */
154
155} POSTPACK HTC_CONNECT_SERVICE_MSG;
156
157/* connect response
158 * direction : target-to-host */
159typedef PREPACK struct {
160 u16 MessageID;
161 u16 ServiceID; /* service ID that the connection request was made */
162 u8 Status; /* service connection status */
163 u8 EndpointID; /* assigned endpoint ID */
164 u16 MaxMsgSize; /* maximum expected message size on this endpoint */
165 u8 ServiceMetaLength; /* length of meta data that follows */
166 u8 _Pad1;
167
168 /* service-specific meta data starts after the header */
169
170} POSTPACK HTC_CONNECT_SERVICE_RESPONSE_MSG;
171
172typedef PREPACK struct {
173 u16 MessageID;
174 /* currently, no other fields */
175} POSTPACK HTC_SETUP_COMPLETE_MSG;
176
177 /* extended setup completion message */
178typedef PREPACK struct {
179 u16 MessageID;
180 u32 SetupFlags;
181 u8 MaxMsgsPerBundledRecv;
182 u8 Rsvd[3];
183} POSTPACK HTC_SETUP_COMPLETE_EX_MSG;
184
185#define HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV (1 << 0)
186
187/* connect response status codes */
188#define HTC_SERVICE_SUCCESS 0 /* success */
189#define HTC_SERVICE_NOT_FOUND 1 /* service could not be found */
190#define HTC_SERVICE_FAILED 2 /* specific service failed the connect */
191#define HTC_SERVICE_NO_RESOURCES 3 /* no resources (i.e. no more endpoints) */
192#define HTC_SERVICE_NO_MORE_EP 4 /* specific service is not allowing any more
193 endpoints */
194
195/* report record IDs */
196
197#define HTC_RECORD_NULL 0
198#define HTC_RECORD_CREDITS 1
199#define HTC_RECORD_LOOKAHEAD 2
200#define HTC_RECORD_LOOKAHEAD_BUNDLE 3
201
202typedef PREPACK struct {
203 u8 RecordID; /* Record ID */
204 u8 Length; /* Length of record */
205} POSTPACK HTC_RECORD_HDR;
206
207typedef PREPACK struct {
208 u8 EndpointID; /* Endpoint that owns these credits */
209 u8 Credits; /* credits to report since last report */
210} POSTPACK HTC_CREDIT_REPORT;
211
212typedef PREPACK struct {
213 u8 PreValid; /* pre valid guard */
214 u8 LookAhead[4]; /* 4 byte lookahead */
215 u8 PostValid; /* post valid guard */
216
217 /* NOTE: the LookAhead array is guarded by a PreValid and Post Valid guard bytes.
218 * The PreValid bytes must equal the inverse of the PostValid byte */
219
220} POSTPACK HTC_LOOKAHEAD_REPORT;
221
222typedef PREPACK struct {
223 u8 LookAhead[4]; /* 4 byte lookahead */
224} POSTPACK HTC_BUNDLED_LOOKAHEAD_REPORT;
225
226#endif /* __HTC_H__ */
227
diff --git a/drivers/staging/ath6kl/include/common/htc_services.h b/drivers/staging/ath6kl/include/common/htc_services.h
deleted file mode 100644
index fb22268a8d8..00000000000
--- a/drivers/staging/ath6kl/include/common/htc_services.h
+++ /dev/null
@@ -1,52 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_services.h" company="Atheros">
3// Copyright (c) 2007 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef __HTC_SERVICES_H__
25#define __HTC_SERVICES_H__
26
27/* Current service IDs */
28
29typedef enum {
30 RSVD_SERVICE_GROUP = 0,
31 WMI_SERVICE_GROUP = 1,
32
33 HTC_TEST_GROUP = 254,
34 HTC_SERVICE_GROUP_LAST = 255
35}HTC_SERVICE_GROUP_IDS;
36
37#define MAKE_SERVICE_ID(group,index) \
38 (int)(((int)group << 8) | (int)(index))
39
40/* NOTE: service ID of 0x0000 is reserved and should never be used */
41#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP,1)
42#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,0)
43#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,1)
44#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,2)
45#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,3)
46#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,4)
47#define WMI_MAX_SERVICES 5
48
49/* raw stream service (i.e. flash, tcmd, calibration apps) */
50#define HTC_RAW_STREAMS_SVC MAKE_SERVICE_ID(HTC_TEST_GROUP,0)
51
52#endif /*HTC_SERVICES_H_*/
diff --git a/drivers/staging/ath6kl/include/common/pkt_log.h b/drivers/staging/ath6kl/include/common/pkt_log.h
deleted file mode 100644
index a3719adf54c..00000000000
--- a/drivers/staging/ath6kl/include/common/pkt_log.h
+++ /dev/null
@@ -1,45 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2005-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22
23#ifndef __PKT_LOG_H__
24#define __PKT_LOG_H__
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30
31/* Pkt log info */
32typedef PREPACK struct pkt_log_t {
33 struct info_t {
34 u16 st;
35 u16 end;
36 u16 cur;
37 }info[4096];
38 u16 last_idx;
39}POSTPACK PACKET_LOG;
40
41
42#ifdef __cplusplus
43}
44#endif
45#endif /* __PKT_LOG_H__ */
diff --git a/drivers/staging/ath6kl/include/common/roaming.h b/drivers/staging/ath6kl/include/common/roaming.h
deleted file mode 100644
index 8019850a057..00000000000
--- a/drivers/staging/ath6kl/include/common/roaming.h
+++ /dev/null
@@ -1,41 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="roaming.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef _ROAMING_H_
25#define _ROAMING_H_
26
27/*
28 * The signal quality could be in terms of either snr or rssi. We should
29 * have an enum for both of them. For the time being, we are going to move
30 * it to wmi.h that is shared by both host and the target, since we are
31 * repartitioning the code to the host
32 */
33#define SIGNAL_QUALITY_NOISE_FLOOR -96
34#define SIGNAL_QUALITY_METRICS_NUM_MAX 2
35typedef enum {
36 SIGNAL_QUALITY_METRICS_SNR = 0,
37 SIGNAL_QUALITY_METRICS_RSSI,
38 SIGNAL_QUALITY_METRICS_ALL,
39} SIGNAL_QUALITY_METRICS_TYPE;
40
41#endif /* _ROAMING_H_ */
diff --git a/drivers/staging/ath6kl/include/common/targaddrs.h b/drivers/staging/ath6kl/include/common/targaddrs.h
deleted file mode 100644
index c866cefbd8f..00000000000
--- a/drivers/staging/ath6kl/include/common/targaddrs.h
+++ /dev/null
@@ -1,395 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//
19// Author(s): ="Atheros"
20//------------------------------------------------------------------------------
21
22#ifndef __TARGADDRS_H__
23#define __TARGADDRS_H__
24
25#if defined(AR6002)
26#include "AR6002/addrs.h"
27#endif
28
29/*
30 * AR6K option bits, to enable/disable various features.
31 * By default, all option bits are 0.
32 * These bits can be set in LOCAL_SCRATCH register 0.
33 */
34#define AR6K_OPTION_BMI_DISABLE 0x01 /* Disable BMI comm with Host */
35#define AR6K_OPTION_SERIAL_ENABLE 0x02 /* Enable serial port msgs */
36#define AR6K_OPTION_WDT_DISABLE 0x04 /* WatchDog Timer override */
37#define AR6K_OPTION_SLEEP_DISABLE 0x08 /* Disable system sleep */
38#define AR6K_OPTION_STOP_BOOT 0x10 /* Stop boot processes (for ATE) */
39#define AR6K_OPTION_ENABLE_NOANI 0x20 /* Operate without ANI */
40#define AR6K_OPTION_DSET_DISABLE 0x40 /* Ignore DataSets */
41#define AR6K_OPTION_IGNORE_FLASH 0x80 /* Ignore flash during bootup */
42
43/*
44 * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the
45 * host_interest structure. It must match the address of the _host_interest
46 * symbol (see linker script).
47 *
48 * Host Interest is shared between Host and Target in order to coordinate
49 * between the two, and is intended to remain constant (with additions only
50 * at the end) across software releases.
51 *
52 * All addresses are available here so that it's possible to
53 * write a single binary that works with all Target Types.
54 * May be used in assembler code as well as C.
55 */
56#define AR6002_HOST_INTEREST_ADDRESS 0x00500400
57#define AR6003_HOST_INTEREST_ADDRESS 0x00540600
58
59
60#define HOST_INTEREST_MAX_SIZE 0x100
61
62#if !defined(__ASSEMBLER__)
63struct register_dump_s;
64struct dbglog_hdr_s;
65
66/*
67 * These are items that the Host may need to access
68 * via BMI or via the Diagnostic Window. The position
69 * of items in this structure must remain constant
70 * across firmware revisions!
71 *
72 * Types for each item must be fixed size across
73 * target and host platforms.
74 *
75 * More items may be added at the end.
76 */
77PREPACK struct host_interest_s {
78 /*
79 * Pointer to application-defined area, if any.
80 * Set by Target application during startup.
81 */
82 u32 hi_app_host_interest; /* 0x00 */
83
84 /* Pointer to register dump area, valid after Target crash. */
85 u32 hi_failure_state; /* 0x04 */
86
87 /* Pointer to debug logging header */
88 u32 hi_dbglog_hdr; /* 0x08 */
89
90 u32 hi_unused1; /* 0x0c */
91
92 /*
93 * General-purpose flag bits, similar to AR6000_OPTION_* flags.
94 * Can be used by application rather than by OS.
95 */
96 u32 hi_option_flag; /* 0x10 */
97
98 /*
99 * Boolean that determines whether or not to
100 * display messages on the serial port.
101 */
102 u32 hi_serial_enable; /* 0x14 */
103
104 /* Start address of DataSet index, if any */
105 u32 hi_dset_list_head; /* 0x18 */
106
107 /* Override Target application start address */
108 u32 hi_app_start; /* 0x1c */
109
110 /* Clock and voltage tuning */
111 u32 hi_skip_clock_init; /* 0x20 */
112 u32 hi_core_clock_setting; /* 0x24 */
113 u32 hi_cpu_clock_setting; /* 0x28 */
114 u32 hi_system_sleep_setting; /* 0x2c */
115 u32 hi_xtal_control_setting; /* 0x30 */
116 u32 hi_pll_ctrl_setting_24ghz; /* 0x34 */
117 u32 hi_pll_ctrl_setting_5ghz; /* 0x38 */
118 u32 hi_ref_voltage_trim_setting; /* 0x3c */
119 u32 hi_clock_info; /* 0x40 */
120
121 /*
122 * Flash configuration overrides, used only
123 * when firmware is not executing from flash.
124 * (When using flash, modify the global variables
125 * with equivalent names.)
126 */
127 u32 hi_bank0_addr_value; /* 0x44 */
128 u32 hi_bank0_read_value; /* 0x48 */
129 u32 hi_bank0_write_value; /* 0x4c */
130 u32 hi_bank0_config_value; /* 0x50 */
131
132 /* Pointer to Board Data */
133 u32 hi_board_data; /* 0x54 */
134 u32 hi_board_data_initialized; /* 0x58 */
135
136 u32 hi_dset_RAM_index_table; /* 0x5c */
137
138 u32 hi_desired_baud_rate; /* 0x60 */
139 u32 hi_dbglog_config; /* 0x64 */
140 u32 hi_end_RAM_reserve_sz; /* 0x68 */
141 u32 hi_mbox_io_block_sz; /* 0x6c */
142
143 u32 hi_num_bpatch_streams; /* 0x70 -- unused */
144 u32 hi_mbox_isr_yield_limit; /* 0x74 */
145
146 u32 hi_refclk_hz; /* 0x78 */
147 u32 hi_ext_clk_detected; /* 0x7c */
148 u32 hi_dbg_uart_txpin; /* 0x80 */
149 u32 hi_dbg_uart_rxpin; /* 0x84 */
150 u32 hi_hci_uart_baud; /* 0x88 */
151 u32 hi_hci_uart_pin_assignments; /* 0x8C */
152 /* NOTE: byte [0] = tx pin, [1] = rx pin, [2] = rts pin, [3] = cts pin */
153 u32 hi_hci_uart_baud_scale_val; /* 0x90 */
154 u32 hi_hci_uart_baud_step_val; /* 0x94 */
155
156 u32 hi_allocram_start; /* 0x98 */
157 u32 hi_allocram_sz; /* 0x9c */
158 u32 hi_hci_bridge_flags; /* 0xa0 */
159 u32 hi_hci_uart_support_pins; /* 0xa4 */
160 /* NOTE: byte [0] = RESET pin (bit 7 is polarity), bytes[1]..bytes[3] are for future use */
161 u32 hi_hci_uart_pwr_mgmt_params; /* 0xa8 */
162 /*
163 * 0xa8 - [1]: 0 = UART FC active low, 1 = UART FC active high
164 * [31:16]: wakeup timeout in ms
165 */
166
167 /* Pointer to extended board data */
168 u32 hi_board_ext_data; /* 0xac */
169 u32 hi_board_ext_data_config; /* 0xb0 */
170
171 /*
172 * Bit [0] : valid
173 * Bit[31:16: size
174 */
175 /*
176 * hi_reset_flag is used to do some stuff when target reset.
177 * such as restore app_start after warm reset or
178 * preserve host Interest area, or preserve ROM data, literals etc.
179 */
180 u32 hi_reset_flag; /* 0xb4 */
181 /* indicate hi_reset_flag is valid */
182 u32 hi_reset_flag_valid; /* 0xb8 */
183 u32 hi_hci_uart_pwr_mgmt_params_ext; /* 0xbc */
184 /*
185 * 0xbc - [31:0]: idle timeout in ms
186 */
187 /* ACS flags */
188 u32 hi_acs_flags; /* 0xc0 */
189 u32 hi_console_flags; /* 0xc4 */
190 u32 hi_nvram_state; /* 0xc8 */
191 u32 hi_option_flag2; /* 0xcc */
192
193 /* If non-zero, override values sent to Host in WMI_READY event. */
194 u32 hi_sw_version_override; /* 0xd0 */
195 u32 hi_abi_version_override; /* 0xd4 */
196
197 /*
198 * Percentage of high priority RX traffic to total expected RX traffic -
199 * applicable only to ar6004
200 */
201 u32 hi_hp_rx_traffic_ratio; /* 0xd8 */
202
203 /* test applications flags */
204 u32 hi_test_apps_related ; /* 0xdc */
205 /* location of test script */
206 u32 hi_ota_testscript; /* 0xe0 */
207 /* location of CAL data */
208 u32 hi_cal_data; /* 0xe4 */
209 /* Number of packet log buffers */
210 u32 hi_pktlog_num_buffers; /* 0xe8 */
211
212} POSTPACK;
213
214/* Bits defined in hi_option_flag */
215#define HI_OPTION_TIMER_WAR 0x01 /* Enable timer workaround */
216#define HI_OPTION_BMI_CRED_LIMIT 0x02 /* Limit BMI command credits */
217#define HI_OPTION_RELAY_DOT11_HDR 0x04 /* Relay Dot11 hdr to/from host */
218/* MAC addr method 0-locally administred 1-globally unique addrs */
219#define HI_OPTION_MAC_ADDR_METHOD 0x08
220#define HI_OPTION_FW_BRIDGE 0x10 /* Firmware Bridging */
221#define HI_OPTION_ENABLE_PROFILE 0x20 /* Enable CPU profiling */
222#define HI_OPTION_DISABLE_DBGLOG 0x40 /* Disable debug logging */
223#define HI_OPTION_SKIP_ERA_TRACKING 0x80 /* Skip Era Tracking */
224#define HI_OPTION_PAPRD_DISABLE 0x100 /* Disable PAPRD (debug) */
225#define HI_OPTION_NUM_DEV_LSB 0x200
226#define HI_OPTION_NUM_DEV_MSB 0x800
227#define HI_OPTION_DEV_MODE_LSB 0x1000
228#define HI_OPTION_DEV_MODE_MSB 0x8000000
229/* Disable LowFreq Timer Stabilization */
230#define HI_OPTION_NO_LFT_STBL 0x10000000
231#define HI_OPTION_SKIP_REG_SCAN 0x20000000 /* Skip regulatory scan */
232/* Do regulatory scan during init beforesending WMI ready event to host */
233#define HI_OPTION_INIT_REG_SCAN 0x40000000
234#define HI_OPTION_SKIP_MEMMAP 0x80000000 /* REV6: Do not adjust memory
235 map */
236
237/* hi_option_flag2 options */
238#define HI_OPTION_OFFLOAD_AMSDU 0x01
239#define HI_OPTION_DFS_SUPPORT 0x02 /* Enable DFS support */
240
241#define HI_OPTION_MAC_ADDR_METHOD_SHIFT 3
242
243/* 2 bits of hi_option_flag are used to represent 3 modes */
244#define HI_OPTION_FW_MODE_IBSS 0x0 /* IBSS Mode */
245#define HI_OPTION_FW_MODE_BSS_STA 0x1 /* STA Mode */
246#define HI_OPTION_FW_MODE_AP 0x2 /* AP Mode */
247
248/* 2 bits of hi_option flag are usedto represent 4 submodes */
249#define HI_OPTION_FW_SUBMODE_NONE 0x0 /* Normal mode */
250#define HI_OPTION_FW_SUBMODE_P2PDEV 0x1 /* p2p device mode */
251#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2 /* p2p client mode */
252#define HI_OPTION_FW_SUBMODE_P2PGO 0x3 /* p2p go mode */
253
254/* Num dev Mask */
255#define HI_OPTION_NUM_DEV_MASK 0x7
256#define HI_OPTION_NUM_DEV_SHIFT 0x9
257
258/* firmware bridging */
259#define HI_OPTION_FW_BRIDGE_SHIFT 0x04
260
261/* Fw Mode/SubMode Mask
262|------------------------------------------------------------------------------|
263| SUB | SUB | SUB | SUB | | | |
264| MODE[3] | MODE[2] | MODE[1] | MODE[0] | MODE[3] | MODE[2] | MODE[1] | MODE[0|
265| (2) | (2) | (2) | (2) | (2) | (2) | (2) | (2)
266|------------------------------------------------------------------------------|
267*/
268#define HI_OPTION_FW_MODE_BITS 0x2
269#define HI_OPTION_FW_MODE_MASK 0x3
270#define HI_OPTION_FW_MODE_SHIFT 0xC
271#define HI_OPTION_ALL_FW_MODE_MASK 0xFF
272
273#define HI_OPTION_FW_SUBMODE_BITS 0x2
274#define HI_OPTION_FW_SUBMODE_MASK 0x3
275#define HI_OPTION_FW_SUBMODE_SHIFT 0x14
276#define HI_OPTION_ALL_FW_SUBMODE_MASK 0xFF00
277#define HI_OPTION_ALL_FW_SUBMODE_SHIFT 0x8
278
279/* hi_reset_flag */
280
281/* preserve App Start address */
282#define HI_RESET_FLAG_PRESERVE_APP_START 0x01
283/* preserve host interest */
284#define HI_RESET_FLAG_PRESERVE_HOST_INTEREST 0x02
285#define HI_RESET_FLAG_PRESERVE_ROMDATA 0x04 /* preserve ROM data */
286#define HI_RESET_FLAG_PRESERVE_NVRAM_STATE 0x08
287#define HI_RESET_FLAG_PRESERVE_BOOT_INFO 0x10
288
289#define HI_RESET_FLAG_IS_VALID 0x12345678 /* indicate the reset flag is
290valid */
291
292#define ON_RESET_FLAGS_VALID() \
293 (HOST_INTEREST->hi_reset_flag_valid == HI_RESET_FLAG_IS_VALID)
294
295#define RESET_FLAGS_VALIDATE() \
296 (HOST_INTEREST->hi_reset_flag_valid = HI_RESET_FLAG_IS_VALID)
297
298#define RESET_FLAGS_INVALIDATE() \
299 (HOST_INTEREST->hi_reset_flag_valid = 0)
300
301#define ON_RESET_PRESERVE_APP_START() \
302 (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_APP_START)
303
304#define ON_RESET_PRESERVE_NVRAM_STATE() \
305 (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_NVRAM_STATE)
306
307#define ON_RESET_PRESERVE_HOST_INTEREST() \
308 (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_HOST_INTEREST)
309
310#define ON_RESET_PRESERVE_ROMDATA() \
311 (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_ROMDATA)
312
313#define ON_RESET_PRESERVE_BOOT_INFO() \
314 (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_BOOT_INFO)
315
316#define HI_ACS_FLAGS_ENABLED (1 << 0) /* ACS is enabled */
317#define HI_ACS_FLAGS_USE_WWAN (1 << 1) /* Use physical WWAN device */
318#define HI_ACS_FLAGS_TEST_VAP (1 << 2) /* Use test VAP */
319
320/* CONSOLE FLAGS
321 *
322 * Bit Range Meaning
323 * --------- --------------------------------
324 * 2..0 UART ID (0 = Default)
325 * 3 Baud Select (0 = 9600, 1 = 115200)
326 * 30..4 Reserved
327 * 31 Enable Console
328 *
329 */
330
331#define HI_CONSOLE_FLAGS_ENABLE (1 << 31)
332#define HI_CONSOLE_FLAGS_UART_MASK (0x7)
333#define HI_CONSOLE_FLAGS_UART_SHIFT 0
334#define HI_CONSOLE_FLAGS_BAUD_SELECT (1 << 3)
335
336/*
337 * Intended for use by Host software, this macro returns the Target RAM
338 * address of any item in the host_interest structure.
339 * Example: target_addr = AR6002_HOST_INTEREST_ITEM_ADDRESS(hi_board_data);
340 */
341#define AR6002_HOST_INTEREST_ITEM_ADDRESS(item) \
342 (u32)((unsigned long)&((((struct host_interest_s *)(AR6002_HOST_INTEREST_ADDRESS))->item)))
343
344#define AR6003_HOST_INTEREST_ITEM_ADDRESS(item) \
345 (u32)((unsigned long)&((((struct host_interest_s *)(AR6003_HOST_INTEREST_ADDRESS))->item)))
346
347#define AR6004_HOST_INTEREST_ITEM_ADDRESS(item) \
348 ((u32)&((((struct host_interest_s *)(AR6004_HOST_INTEREST_ADDRESS))->item)))
349
350
351#define HOST_INTEREST_DBGLOG_IS_ENABLED() \
352 (!(HOST_INTEREST->hi_option_flag & HI_OPTION_DISABLE_DBGLOG))
353
354#define HOST_INTEREST_PKTLOG_IS_ENABLED() \
355 ((HOST_INTEREST->hi_pktlog_num_buffers))
356
357
358#define HOST_INTEREST_PROFILE_IS_ENABLED() \
359 (HOST_INTEREST->hi_option_flag & HI_OPTION_ENABLE_PROFILE)
360
361#define LF_TIMER_STABILIZATION_IS_ENABLED() \
362 (!(HOST_INTEREST->hi_option_flag & HI_OPTION_NO_LFT_STBL))
363
364#define IS_AMSDU_OFFLAOD_ENABLED() \
365 ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_OFFLOAD_AMSDU))
366
367#define HOST_INTEREST_DFS_IS_ENABLED() \
368 ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_DFS_SUPPORT))
369
370/* Convert a Target virtual address into a Target physical address */
371#define AR6002_VTOP(vaddr) ((vaddr) & 0x001fffff)
372#define AR6003_VTOP(vaddr) ((vaddr) & 0x001fffff)
373#define TARG_VTOP(TargetType, vaddr) \
374 (((TargetType) == TARGET_TYPE_AR6002) ? AR6002_VTOP(vaddr) : AR6003_VTOP(vaddr))
375
376#define AR6003_REV2_APP_START_OVERRIDE 0x944C00
377#define AR6003_REV2_APP_LOAD_ADDRESS 0x543180
378#define AR6003_REV2_BOARD_EXT_DATA_ADDRESS 0x57E500
379#define AR6003_REV2_DATASET_PATCH_ADDRESS 0x57e884
380#define AR6003_REV2_RAM_RESERVE_SIZE 6912
381
382#define AR6003_REV3_APP_START_OVERRIDE 0x945d00
383#define AR6003_REV3_APP_LOAD_ADDRESS 0x545000
384#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS 0x542330
385#define AR6003_REV3_DATASET_PATCH_ADDRESS 0x57FF74
386#define AR6003_REV3_RAM_RESERVE_SIZE 512
387
388#define AR6003_BOARD_EXT_DATA_ADDRESS 0x57E600
389
390/* # of u32 entries in targregs, used by DIAG_FETCH_TARG_REGS */
391#define AR6003_FETCH_TARG_REGS_COUNT 64
392
393#endif /* !__ASSEMBLER__ */
394
395#endif /* __TARGADDRS_H__ */
diff --git a/drivers/staging/ath6kl/include/common/testcmd.h b/drivers/staging/ath6kl/include/common/testcmd.h
deleted file mode 100644
index 7d94aee508b..00000000000
--- a/drivers/staging/ath6kl/include/common/testcmd.h
+++ /dev/null
@@ -1,185 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="testcmd.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef TESTCMD_H_
25#define TESTCMD_H_
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#ifdef AR6002_REV2
32#define TCMD_MAX_RATES 12
33#else
34#define TCMD_MAX_RATES 28
35#endif
36
37typedef enum {
38 ZEROES_PATTERN = 0,
39 ONES_PATTERN,
40 REPEATING_10,
41 PN7_PATTERN,
42 PN9_PATTERN,
43 PN15_PATTERN
44}TX_DATA_PATTERN;
45
46/* Continuous tx
47 mode : TCMD_CONT_TX_OFF - Disabling continuous tx
48 TCMD_CONT_TX_SINE - Enable continuous unmodulated tx
49 TCMD_CONT_TX_FRAME- Enable continuous modulated tx
50 freq : Channel freq in Mhz. (e.g 2412 for channel 1 in 11 g)
51dataRate: 0 - 1 Mbps
52 1 - 2 Mbps
53 2 - 5.5 Mbps
54 3 - 11 Mbps
55 4 - 6 Mbps
56 5 - 9 Mbps
57 6 - 12 Mbps
58 7 - 18 Mbps
59 8 - 24 Mbps
60 9 - 36 Mbps
61 10 - 28 Mbps
62 11 - 54 Mbps
63 txPwr: Tx power in dBm[5 -11] for unmod Tx, [5-14] for mod Tx
64antenna: 1 - one antenna
65 2 - two antenna
66Note : Enable/disable continuous tx test cmd works only when target is awake.
67*/
68
69typedef enum {
70 TCMD_CONT_TX_OFF = 0,
71 TCMD_CONT_TX_SINE,
72 TCMD_CONT_TX_FRAME,
73 TCMD_CONT_TX_TX99,
74 TCMD_CONT_TX_TX100
75} TCMD_CONT_TX_MODE;
76
77typedef enum {
78 TCMD_WLAN_MODE_NOHT = 0,
79 TCMD_WLAN_MODE_HT20 = 1,
80 TCMD_WLAN_MODE_HT40PLUS = 2,
81 TCMD_WLAN_MODE_HT40MINUS = 3,
82} TCMD_WLAN_MODE;
83
84typedef PREPACK struct {
85 u32 testCmdId;
86 u32 mode;
87 u32 freq;
88 u32 dataRate;
89 s32 txPwr;
90 u32 antenna;
91 u32 enANI;
92 u32 scramblerOff;
93 u32 aifsn;
94 u16 pktSz;
95 u16 txPattern;
96 u32 shortGuard;
97 u32 numPackets;
98 u32 wlanMode;
99} POSTPACK TCMD_CONT_TX;
100
101#define TCMD_TXPATTERN_ZERONE 0x1
102#define TCMD_TXPATTERN_ZERONE_DIS_SCRAMBLE 0x2
103
104/* Continuous Rx
105 act: TCMD_CONT_RX_PROMIS - promiscuous mode (accept all incoming frames)
106 TCMD_CONT_RX_FILTER - filter mode (accept only frames with dest
107 address equal specified
108 mac address (set via act =3)
109 TCMD_CONT_RX_REPORT off mode (disable cont rx mode and get the
110 report from the last cont
111 Rx test)
112
113 TCMD_CONT_RX_SETMAC - set MacAddr mode (sets the MAC address for the
114 target. This Overrides
115 the default MAC address.)
116
117*/
118typedef enum {
119 TCMD_CONT_RX_PROMIS =0,
120 TCMD_CONT_RX_FILTER,
121 TCMD_CONT_RX_REPORT,
122 TCMD_CONT_RX_SETMAC,
123 TCMD_CONT_RX_SET_ANT_SWITCH_TABLE
124} TCMD_CONT_RX_ACT;
125
126typedef PREPACK struct {
127 u32 testCmdId;
128 u32 act;
129 u32 enANI;
130 PREPACK union {
131 struct PREPACK TCMD_CONT_RX_PARA {
132 u32 freq;
133 u32 antenna;
134 u32 wlanMode;
135 } POSTPACK para;
136 struct PREPACK TCMD_CONT_RX_REPORT {
137 u32 totalPkt;
138 s32 rssiInDBm;
139 u32 crcErrPkt;
140 u32 secErrPkt;
141 u16 rateCnt[TCMD_MAX_RATES];
142 u16 rateCntShortGuard[TCMD_MAX_RATES];
143 } POSTPACK report;
144 struct PREPACK TCMD_CONT_RX_MAC {
145 u8 addr[ATH_MAC_LEN];
146 } POSTPACK mac;
147 struct PREPACK TCMD_CONT_RX_ANT_SWITCH_TABLE {
148 u32 antswitch1;
149 u32 antswitch2;
150 }POSTPACK antswitchtable;
151 } POSTPACK u;
152} POSTPACK TCMD_CONT_RX;
153
154/* Force sleep/wake test cmd
155 mode: TCMD_PM_WAKEUP - Wakeup the target
156 TCMD_PM_SLEEP - Force the target to sleep.
157 */
158typedef enum {
159 TCMD_PM_WAKEUP = 1, /* be consistent with target */
160 TCMD_PM_SLEEP,
161 TCMD_PM_DEEPSLEEP
162} TCMD_PM_MODE;
163
164typedef PREPACK struct {
165 u32 testCmdId;
166 u32 mode;
167} POSTPACK TCMD_PM;
168
169typedef enum {
170 TCMD_CONT_TX_ID,
171 TCMD_CONT_RX_ID,
172 TCMD_PM_ID
173} TCMD_ID;
174
175typedef PREPACK union {
176 TCMD_CONT_TX contTx;
177 TCMD_CONT_RX contRx;
178 TCMD_PM pm;
179} POSTPACK TEST_CMD;
180
181#ifdef __cplusplus
182}
183#endif
184
185#endif /* TESTCMD_H_ */
diff --git a/drivers/staging/ath6kl/include/common/tlpm.h b/drivers/staging/ath6kl/include/common/tlpm.h
deleted file mode 100644
index 659b1c07ba9..00000000000
--- a/drivers/staging/ath6kl/include/common/tlpm.h
+++ /dev/null
@@ -1,38 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22
23#ifndef __TLPM_H__
24#define __TLPM_H__
25
26/* idle timeout in 16-bit value as in HOST_INTEREST hi_hci_uart_pwr_mgmt_params */
27#define TLPM_DEFAULT_IDLE_TIMEOUT_MS 1000
28/* hex in LSB and MSB for HCI command */
29#define TLPM_DEFAULT_IDLE_TIMEOUT_LSB 0xE8
30#define TLPM_DEFAULT_IDLE_TIMEOUT_MSB 0x3
31
32/* wakeup timeout in 8-bit value as in HOST_INTEREST hi_hci_uart_pwr_mgmt_params */
33#define TLPM_DEFAULT_WAKEUP_TIMEOUT_MS 10
34
35/* default UART FC polarity is low */
36#define TLPM_DEFAULT_UART_FC_POLARITY 0
37
38#endif
diff --git a/drivers/staging/ath6kl/include/common/wlan_defs.h b/drivers/staging/ath6kl/include/common/wlan_defs.h
deleted file mode 100644
index 03e4d23788c..00000000000
--- a/drivers/staging/ath6kl/include/common/wlan_defs.h
+++ /dev/null
@@ -1,79 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="wlan_defs.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef __WLAN_DEFS_H__
24#define __WLAN_DEFS_H__
25
26/*
27 * This file contains WLAN definitions that may be used across both
28 * Host and Target software.
29 */
30
31typedef enum {
32 MODE_11A = 0, /* 11a Mode */
33 MODE_11G = 1, /* 11b/g Mode */
34 MODE_11B = 2, /* 11b Mode */
35 MODE_11GONLY = 3, /* 11g only Mode */
36#ifdef SUPPORT_11N
37 MODE_11NA_HT20 = 4, /* 11a HT20 mode */
38 MODE_11NG_HT20 = 5, /* 11g HT20 mode */
39 MODE_11NA_HT40 = 6, /* 11a HT40 mode */
40 MODE_11NG_HT40 = 7, /* 11g HT40 mode */
41 MODE_UNKNOWN = 8,
42 MODE_MAX = 8
43#else
44 MODE_UNKNOWN = 4,
45 MODE_MAX = 4
46#endif
47} WLAN_PHY_MODE;
48
49typedef enum {
50 WLAN_11A_CAPABILITY = 1,
51 WLAN_11G_CAPABILITY = 2,
52 WLAN_11AG_CAPABILITY = 3,
53}WLAN_CAPABILITY;
54
55#ifdef SUPPORT_11N
56typedef unsigned long A_RATEMASK;
57#else
58typedef unsigned short A_RATEMASK;
59#endif
60
61#ifdef SUPPORT_11N
62#define IS_MODE_11A(mode) (((mode) == MODE_11A) || \
63 ((mode) == MODE_11NA_HT20) || \
64 ((mode) == MODE_11NA_HT40))
65#define IS_MODE_11B(mode) ((mode) == MODE_11B)
66#define IS_MODE_11G(mode) (((mode) == MODE_11G) || \
67 ((mode) == MODE_11GONLY) || \
68 ((mode) == MODE_11NG_HT20) || \
69 ((mode) == MODE_11NG_HT40))
70#define IS_MODE_11GONLY(mode) ((mode) == MODE_11GONLY)
71#else
72#define IS_MODE_11A(mode) ((mode) == MODE_11A)
73#define IS_MODE_11B(mode) ((mode) == MODE_11B)
74#define IS_MODE_11G(mode) (((mode) == MODE_11G) || \
75 ((mode) == MODE_11GONLY))
76#define IS_MODE_11GONLY(mode) ((mode) == MODE_11GONLY)
77#endif /* SUPPORT_11N */
78
79#endif /* __WLANDEFS_H__ */
diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h
deleted file mode 100644
index d9687443d32..00000000000
--- a/drivers/staging/ath6kl/include/common/wmi.h
+++ /dev/null
@@ -1,3220 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//
19// Author(s): ="Atheros"
20//------------------------------------------------------------------------------
21
22/*
23 * This file contains the definitions of the WMI protocol specified in the
24 * Wireless Module Interface (WMI). It includes definitions of all the
25 * commands and events. Commands are messages from the host to the WM.
26 * Events and Replies are messages from the WM to the host.
27 *
28 * Ownership of correctness in regards to commands
29 * belongs to the host driver and the WMI is not required to validate
30 * parameters for value, proper range, or any other checking.
31 *
32 */
33
34#ifndef _WMI_H_
35#define _WMI_H_
36
37#include "wmix.h"
38#include "wlan_defs.h"
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#define HTC_PROTOCOL_VERSION 0x0002
45#define HTC_PROTOCOL_REVISION 0x0000
46
47#define WMI_PROTOCOL_VERSION 0x0002
48#define WMI_PROTOCOL_REVISION 0x0000
49
50#define ATH_MAC_LEN 6 /* length of mac in bytes */
51#define WMI_CMD_MAX_LEN 100
52#define WMI_CONTROL_MSG_MAX_LEN 256
53#define WMI_OPT_CONTROL_MSG_MAX_LEN 1536
54#define IS_ETHERTYPE(_typeOrLen) ((_typeOrLen) >= 0x0600)
55#define RFC1042OUI {0x00, 0x00, 0x00}
56
57#define IP_ETHERTYPE 0x0800
58
59#define WMI_IMPLICIT_PSTREAM 0xFF
60#define WMI_MAX_THINSTREAM 15
61
62#ifdef AR6002_REV2
63#define IBSS_MAX_NUM_STA 4
64#else
65#define IBSS_MAX_NUM_STA 8
66#endif
67
68PREPACK struct host_app_area_s {
69 u32 wmi_protocol_ver;
70} POSTPACK;
71
72/*
73 * Data Path
74 */
75typedef PREPACK struct {
76 u8 dstMac[ATH_MAC_LEN];
77 u8 srcMac[ATH_MAC_LEN];
78 u16 typeOrLen;
79} POSTPACK ATH_MAC_HDR;
80
81typedef PREPACK struct {
82 u8 dsap;
83 u8 ssap;
84 u8 cntl;
85 u8 orgCode[3];
86 u16 etherType;
87} POSTPACK ATH_LLC_SNAP_HDR;
88
89typedef enum {
90 DATA_MSGTYPE = 0x0,
91 CNTL_MSGTYPE,
92 SYNC_MSGTYPE,
93 OPT_MSGTYPE,
94} WMI_MSG_TYPE;
95
96
97/*
98 * Macros for operating on WMI_DATA_HDR (info) field
99 */
100
101#define WMI_DATA_HDR_MSG_TYPE_MASK 0x03
102#define WMI_DATA_HDR_MSG_TYPE_SHIFT 0
103#define WMI_DATA_HDR_UP_MASK 0x07
104#define WMI_DATA_HDR_UP_SHIFT 2
105/* In AP mode, the same bit (b5) is used to indicate Power save state in
106 * the Rx dir and More data bit state in the tx direction.
107 */
108#define WMI_DATA_HDR_PS_MASK 0x1
109#define WMI_DATA_HDR_PS_SHIFT 5
110
111#define WMI_DATA_HDR_MORE_MASK 0x1
112#define WMI_DATA_HDR_MORE_SHIFT 5
113
114typedef enum {
115 WMI_DATA_HDR_DATA_TYPE_802_3 = 0,
116 WMI_DATA_HDR_DATA_TYPE_802_11,
117 WMI_DATA_HDR_DATA_TYPE_ACL, /* used to be used for the PAL */
118} WMI_DATA_HDR_DATA_TYPE;
119
120#define WMI_DATA_HDR_DATA_TYPE_MASK 0x3
121#define WMI_DATA_HDR_DATA_TYPE_SHIFT 6
122
123#define WMI_DATA_HDR_SET_MORE_BIT(h) ((h)->info |= (WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT))
124
125#define WMI_DATA_HDR_IS_MSG_TYPE(h, t) (((h)->info & (WMI_DATA_HDR_MSG_TYPE_MASK)) == (t))
126#define WMI_DATA_HDR_SET_MSG_TYPE(h, t) (h)->info = (((h)->info & ~(WMI_DATA_HDR_MSG_TYPE_MASK << WMI_DATA_HDR_MSG_TYPE_SHIFT)) | (t << WMI_DATA_HDR_MSG_TYPE_SHIFT))
127#define WMI_DATA_HDR_GET_UP(h) (((h)->info >> WMI_DATA_HDR_UP_SHIFT) & WMI_DATA_HDR_UP_MASK)
128#define WMI_DATA_HDR_SET_UP(h, p) (h)->info = (((h)->info & ~(WMI_DATA_HDR_UP_MASK << WMI_DATA_HDR_UP_SHIFT)) | (p << WMI_DATA_HDR_UP_SHIFT))
129
130#define WMI_DATA_HDR_GET_DATA_TYPE(h) (((h)->info >> WMI_DATA_HDR_DATA_TYPE_SHIFT) & WMI_DATA_HDR_DATA_TYPE_MASK)
131#define WMI_DATA_HDR_SET_DATA_TYPE(h, p) (h)->info = (((h)->info & ~(WMI_DATA_HDR_DATA_TYPE_MASK << WMI_DATA_HDR_DATA_TYPE_SHIFT)) | ((p) << WMI_DATA_HDR_DATA_TYPE_SHIFT))
132
133#define WMI_DATA_HDR_GET_DOT11(h) (WMI_DATA_HDR_GET_DATA_TYPE((h)) == WMI_DATA_HDR_DATA_TYPE_802_11)
134#define WMI_DATA_HDR_SET_DOT11(h, p) WMI_DATA_HDR_SET_DATA_TYPE((h), (p))
135
136/* Macros for operating on WMI_DATA_HDR (info2) field */
137#define WMI_DATA_HDR_SEQNO_MASK 0xFFF
138#define WMI_DATA_HDR_SEQNO_SHIFT 0
139
140#define WMI_DATA_HDR_AMSDU_MASK 0x1
141#define WMI_DATA_HDR_AMSDU_SHIFT 12
142
143#define WMI_DATA_HDR_META_MASK 0x7
144#define WMI_DATA_HDR_META_SHIFT 13
145
146#define GET_SEQ_NO(_v) ((_v) & WMI_DATA_HDR_SEQNO_MASK)
147#define GET_ISMSDU(_v) ((_v) & WMI_DATA_HDR_AMSDU_MASK)
148
149#define WMI_DATA_HDR_GET_SEQNO(h) GET_SEQ_NO((h)->info2 >> WMI_DATA_HDR_SEQNO_SHIFT)
150#define WMI_DATA_HDR_SET_SEQNO(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_SEQNO_MASK << WMI_DATA_HDR_SEQNO_SHIFT)) | (GET_SEQ_NO(_v) << WMI_DATA_HDR_SEQNO_SHIFT))
151
152#define WMI_DATA_HDR_IS_AMSDU(h) GET_ISMSDU((h)->info2 >> WMI_DATA_HDR_AMSDU_SHIFT)
153#define WMI_DATA_HDR_SET_AMSDU(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_AMSDU_MASK << WMI_DATA_HDR_AMSDU_SHIFT)) | (GET_ISMSDU(_v) << WMI_DATA_HDR_AMSDU_SHIFT))
154
155#define WMI_DATA_HDR_GET_META(h) (((h)->info2 >> WMI_DATA_HDR_META_SHIFT) & WMI_DATA_HDR_META_MASK)
156#define WMI_DATA_HDR_SET_META(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_META_MASK << WMI_DATA_HDR_META_SHIFT)) | ((_v) << WMI_DATA_HDR_META_SHIFT))
157
158/* Macros for operating on WMI_DATA_HDR (info3) field */
159#define WMI_DATA_HDR_DEVID_MASK 0xF
160#define WMI_DATA_HDR_DEVID_SHIFT 0
161#define GET_DEVID(_v) ((_v) & WMI_DATA_HDR_DEVID_MASK)
162
163#define WMI_DATA_HDR_GET_DEVID(h) \
164 (((h)->info3 >> WMI_DATA_HDR_DEVID_SHIFT) & WMI_DATA_HDR_DEVID_MASK)
165#define WMI_DATA_HDR_SET_DEVID(h, _v) \
166 ((h)->info3 = ((h)->info3 & ~(WMI_DATA_HDR_DEVID_MASK << WMI_DATA_HDR_DEVID_SHIFT)) | (GET_DEVID(_v) << WMI_DATA_HDR_DEVID_SHIFT))
167
168typedef PREPACK struct {
169 s8 rssi;
170 u8 info; /* usage of 'info' field(8-bit):
171 * b1:b0 - WMI_MSG_TYPE
172 * b4:b3:b2 - UP(tid)
173 * b5 - Used in AP mode. More-data in tx dir, PS in rx.
174 * b7:b6 - Dot3 header(0),
175 * Dot11 Header(1),
176 * ACL data(2)
177 */
178
179 u16 info2; /* usage of 'info2' field(16-bit):
180 * b11:b0 - seq_no
181 * b12 - A-MSDU?
182 * b15:b13 - META_DATA_VERSION 0 - 7
183 */
184 u16 info3;
185} POSTPACK WMI_DATA_HDR;
186
187/*
188 * TX META VERSION DEFINITIONS
189 */
190#define WMI_MAX_TX_META_SZ (12)
191#define WMI_MAX_TX_META_VERSION (7)
192#define WMI_META_VERSION_1 (0x01)
193#define WMI_META_VERSION_2 (0X02)
194
195#define WMI_ACL_TO_DOT11_HEADROOM 36
196
197#if 0 /* removed to prevent compile errors for WM.. */
198typedef PREPACK struct {
199/* intentionally empty. Default version is no meta data. */
200} POSTPACK WMI_TX_META_V0;
201#endif
202
203typedef PREPACK struct {
204 u8 pktID; /* The packet ID to identify the tx request */
205 u8 ratePolicyID; /* The rate policy to be used for the tx of this frame */
206} POSTPACK WMI_TX_META_V1;
207
208
209#define WMI_CSUM_DIR_TX (0x1)
210#define TX_CSUM_CALC_FILL (0x1)
211typedef PREPACK struct {
212 u8 csumStart; /*Offset from start of the WMI header for csum calculation to begin */
213 u8 csumDest; /*Offset from start of WMI header where final csum goes*/
214 u8 csumFlags; /*number of bytes over which csum is calculated*/
215} POSTPACK WMI_TX_META_V2;
216
217
218/*
219 * RX META VERSION DEFINITIONS
220 */
221/* if RX meta data is present at all then the meta data field
222 * will consume WMI_MAX_RX_META_SZ bytes of space between the
223 * WMI_DATA_HDR and the payload. How much of the available
224 * Meta data is actually used depends on which meta data
225 * version is active. */
226#define WMI_MAX_RX_META_SZ (12)
227#define WMI_MAX_RX_META_VERSION (7)
228
229#define WMI_RX_STATUS_OK 0 /* success */
230#define WMI_RX_STATUS_DECRYPT_ERR 1 /* decrypt error */
231#define WMI_RX_STATUS_MIC_ERR 2 /* tkip MIC error */
232#define WMI_RX_STATUS_ERR 3 /* undefined error */
233
234#define WMI_RX_FLAGS_AGGR 0x0001 /* part of AGGR */
235#define WMI_RX_FlAGS_STBC 0x0002 /* used STBC */
236#define WMI_RX_FLAGS_SGI 0x0004 /* used SGI */
237#define WMI_RX_FLAGS_HT 0x0008 /* is HT packet */
238/* the flags field is also used to store the CRYPTO_TYPE of the frame
239 * that value is shifted by WMI_RX_FLAGS_CRYPTO_SHIFT */
240#define WMI_RX_FLAGS_CRYPTO_SHIFT 4
241#define WMI_RX_FLAGS_CRYPTO_MASK 0x1f
242#define WMI_RX_META_GET_CRYPTO(flags) (((flags) >> WMI_RX_FLAGS_CRYPTO_SHIFT) & WMI_RX_FLAGS_CRYPTO_MASK)
243
244#if 0 /* removed to prevent compile errors for WM.. */
245typedef PREPACK struct {
246/* intentionally empty. Default version is no meta data. */
247} POSTPACK WMI_RX_META_VERSION_0;
248#endif
249
250typedef PREPACK struct {
251 u8 status; /* one of WMI_RX_STATUS_... */
252 u8 rix; /* rate index mapped to rate at which this packet was received. */
253 u8 rssi; /* rssi of packet */
254 u8 channel;/* rf channel during packet reception */
255 u16 flags; /* a combination of WMI_RX_FLAGS_... */
256} POSTPACK WMI_RX_META_V1;
257
258#define RX_CSUM_VALID_FLAG (0x1)
259typedef PREPACK struct {
260 u16 csum;
261 u8 csumFlags;/* bit 0 set -partial csum valid
262 bit 1 set -test mode */
263} POSTPACK WMI_RX_META_V2;
264
265
266
267#define WMI_GET_DEVICE_ID(info1) ((info1) & 0xF)
268/* Macros for operating on WMI_CMD_HDR (info1) field */
269#define WMI_CMD_HDR_DEVID_MASK 0xF
270#define WMI_CMD_HDR_DEVID_SHIFT 0
271#define GET_CMD_DEVID(_v) ((_v) & WMI_CMD_HDR_DEVID_MASK)
272
273#define WMI_CMD_HDR_GET_DEVID(h) \
274 (((h)->info1 >> WMI_CMD_HDR_DEVID_SHIFT) & WMI_CMD_HDR_DEVID_MASK)
275#define WMI_CMD_HDR_SET_DEVID(h, _v) \
276 ((h)->info1 = ((h)->info1 & \
277 ~(WMI_CMD_HDR_DEVID_MASK << WMI_CMD_HDR_DEVID_SHIFT)) | \
278 (GET_CMD_DEVID(_v) << WMI_CMD_HDR_DEVID_SHIFT))
279
280/*
281 * Control Path
282 */
283typedef PREPACK struct {
284 u16 commandId;
285/*
286 * info1 - 16 bits
287 * b03:b00 - id
288 * b15:b04 - unused
289 */
290 u16 info1;
291
292 u16 reserved; /* For alignment */
293} POSTPACK WMI_CMD_HDR; /* used for commands and events */
294
295/*
296 * List of Commnands
297 */
298typedef enum {
299 WMI_CONNECT_CMDID = 0x0001,
300 WMI_RECONNECT_CMDID,
301 WMI_DISCONNECT_CMDID,
302 WMI_SYNCHRONIZE_CMDID,
303 WMI_CREATE_PSTREAM_CMDID,
304 WMI_DELETE_PSTREAM_CMDID,
305 WMI_START_SCAN_CMDID,
306 WMI_SET_SCAN_PARAMS_CMDID,
307 WMI_SET_BSS_FILTER_CMDID,
308 WMI_SET_PROBED_SSID_CMDID, /* 10 */
309 WMI_SET_LISTEN_INT_CMDID,
310 WMI_SET_BMISS_TIME_CMDID,
311 WMI_SET_DISC_TIMEOUT_CMDID,
312 WMI_GET_CHANNEL_LIST_CMDID,
313 WMI_SET_BEACON_INT_CMDID,
314 WMI_GET_STATISTICS_CMDID,
315 WMI_SET_CHANNEL_PARAMS_CMDID,
316 WMI_SET_POWER_MODE_CMDID,
317 WMI_SET_IBSS_PM_CAPS_CMDID,
318 WMI_SET_POWER_PARAMS_CMDID, /* 20 */
319 WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
320 WMI_ADD_CIPHER_KEY_CMDID,
321 WMI_DELETE_CIPHER_KEY_CMDID,
322 WMI_ADD_KRK_CMDID,
323 WMI_DELETE_KRK_CMDID,
324 WMI_SET_PMKID_CMDID,
325 WMI_SET_TX_PWR_CMDID,
326 WMI_GET_TX_PWR_CMDID,
327 WMI_SET_ASSOC_INFO_CMDID,
328 WMI_ADD_BAD_AP_CMDID, /* 30 */
329 WMI_DELETE_BAD_AP_CMDID,
330 WMI_SET_TKIP_COUNTERMEASURES_CMDID,
331 WMI_RSSI_THRESHOLD_PARAMS_CMDID,
332 WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
333 WMI_SET_ACCESS_PARAMS_CMDID,
334 WMI_SET_RETRY_LIMITS_CMDID,
335 WMI_SET_OPT_MODE_CMDID,
336 WMI_OPT_TX_FRAME_CMDID,
337 WMI_SET_VOICE_PKT_SIZE_CMDID,
338 WMI_SET_MAX_SP_LEN_CMDID, /* 40 */
339 WMI_SET_ROAM_CTRL_CMDID,
340 WMI_GET_ROAM_TBL_CMDID,
341 WMI_GET_ROAM_DATA_CMDID,
342 WMI_ENABLE_RM_CMDID,
343 WMI_SET_MAX_OFFHOME_DURATION_CMDID,
344 WMI_EXTENSION_CMDID, /* Non-wireless extensions */
345 WMI_SNR_THRESHOLD_PARAMS_CMDID,
346 WMI_LQ_THRESHOLD_PARAMS_CMDID,
347 WMI_SET_LPREAMBLE_CMDID,
348 WMI_SET_RTS_CMDID, /* 50 */
349 WMI_CLR_RSSI_SNR_CMDID,
350 WMI_SET_FIXRATES_CMDID,
351 WMI_GET_FIXRATES_CMDID,
352 WMI_SET_AUTH_MODE_CMDID,
353 WMI_SET_REASSOC_MODE_CMDID,
354 WMI_SET_WMM_CMDID,
355 WMI_SET_WMM_TXOP_CMDID,
356 WMI_TEST_CMDID,
357 /* COEX AR6002 only*/
358 WMI_SET_BT_STATUS_CMDID,
359 WMI_SET_BT_PARAMS_CMDID, /* 60 */
360
361 WMI_SET_KEEPALIVE_CMDID,
362 WMI_GET_KEEPALIVE_CMDID,
363 WMI_SET_APPIE_CMDID,
364 WMI_GET_APPIE_CMDID,
365 WMI_SET_WSC_STATUS_CMDID,
366
367 /* Wake on Wireless */
368 WMI_SET_HOST_SLEEP_MODE_CMDID,
369 WMI_SET_WOW_MODE_CMDID,
370 WMI_GET_WOW_LIST_CMDID,
371 WMI_ADD_WOW_PATTERN_CMDID,
372 WMI_DEL_WOW_PATTERN_CMDID, /* 70 */
373
374 WMI_SET_FRAMERATES_CMDID,
375 WMI_SET_AP_PS_CMDID,
376 WMI_SET_QOS_SUPP_CMDID,
377 /* WMI_THIN_RESERVED_... mark the start and end
378 * values for WMI_THIN_RESERVED command IDs. These
379 * command IDs can be found in wmi_thin.h */
380 WMI_THIN_RESERVED_START = 0x8000,
381 WMI_THIN_RESERVED_END = 0x8fff,
382 /*
383 * Developer commands starts at 0xF000
384 */
385 WMI_SET_BITRATE_CMDID = 0xF000,
386 WMI_GET_BITRATE_CMDID,
387 WMI_SET_WHALPARAM_CMDID,
388
389
390 /*Should add the new command to the tail for compatible with
391 * etna.
392 */
393 WMI_SET_MAC_ADDRESS_CMDID,
394 WMI_SET_AKMP_PARAMS_CMDID,
395 WMI_SET_PMKID_LIST_CMDID,
396 WMI_GET_PMKID_LIST_CMDID,
397 WMI_ABORT_SCAN_CMDID,
398 WMI_SET_TARGET_EVENT_REPORT_CMDID,
399
400 // Unused
401 WMI_UNUSED1,
402 WMI_UNUSED2,
403
404 /*
405 * AP mode commands
406 */
407 WMI_AP_HIDDEN_SSID_CMDID,
408 WMI_AP_SET_NUM_STA_CMDID,
409 WMI_AP_ACL_POLICY_CMDID,
410 WMI_AP_ACL_MAC_LIST_CMDID,
411 WMI_AP_CONFIG_COMMIT_CMDID,
412 WMI_AP_SET_MLME_CMDID,
413 WMI_AP_SET_PVB_CMDID,
414 WMI_AP_CONN_INACT_CMDID,
415 WMI_AP_PROT_SCAN_TIME_CMDID,
416 WMI_AP_SET_COUNTRY_CMDID,
417 WMI_AP_SET_DTIM_CMDID,
418 WMI_AP_MODE_STAT_CMDID,
419
420 WMI_SET_IP_CMDID,
421 WMI_SET_PARAMS_CMDID,
422 WMI_SET_MCAST_FILTER_CMDID,
423 WMI_DEL_MCAST_FILTER_CMDID,
424
425 WMI_ALLOW_AGGR_CMDID,
426 WMI_ADDBA_REQ_CMDID,
427 WMI_DELBA_REQ_CMDID,
428 WMI_SET_HT_CAP_CMDID,
429 WMI_SET_HT_OP_CMDID,
430 WMI_SET_TX_SELECT_RATES_CMDID,
431 WMI_SET_TX_SGI_PARAM_CMDID,
432 WMI_SET_RATE_POLICY_CMDID,
433
434 WMI_HCI_CMD_CMDID,
435 WMI_RX_FRAME_FORMAT_CMDID,
436 WMI_SET_THIN_MODE_CMDID,
437 WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
438
439 WMI_AP_SET_11BG_RATESET_CMDID,
440 WMI_SET_PMK_CMDID,
441 WMI_MCAST_FILTER_CMDID,
442 /* COEX CMDID AR6003*/
443 WMI_SET_BTCOEX_FE_ANT_CMDID,
444 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
445 WMI_SET_BTCOEX_SCO_CONFIG_CMDID,
446 WMI_SET_BTCOEX_A2DP_CONFIG_CMDID,
447 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID,
448 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
449 WMI_SET_BTCOEX_DEBUG_CMDID,
450 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID,
451 WMI_GET_BTCOEX_STATS_CMDID,
452 WMI_GET_BTCOEX_CONFIG_CMDID,
453
454 WMI_SET_DFS_ENABLE_CMDID, /* F034 */
455 WMI_SET_DFS_MINRSSITHRESH_CMDID,
456 WMI_SET_DFS_MAXPULSEDUR_CMDID,
457 WMI_DFS_RADAR_DETECTED_CMDID,
458
459 /* P2P CMDS */
460 WMI_P2P_SET_CONFIG_CMDID, /* F038 */
461 WMI_WPS_SET_CONFIG_CMDID,
462 WMI_SET_REQ_DEV_ATTR_CMDID,
463 WMI_P2P_FIND_CMDID,
464 WMI_P2P_STOP_FIND_CMDID,
465 WMI_P2P_GO_NEG_START_CMDID,
466 WMI_P2P_LISTEN_CMDID,
467
468 WMI_CONFIG_TX_MAC_RULES_CMDID, /* F040 */
469 WMI_SET_PROMISCUOUS_MODE_CMDID,
470 WMI_RX_FRAME_FILTER_CMDID,
471 WMI_SET_CHANNEL_CMDID,
472
473 /* WAC commands */
474 WMI_ENABLE_WAC_CMDID,
475 WMI_WAC_SCAN_REPLY_CMDID,
476 WMI_WAC_CTRL_REQ_CMDID,
477 WMI_SET_DIV_PARAMS_CMDID,
478
479 WMI_GET_PMK_CMDID,
480 WMI_SET_PASSPHRASE_CMDID,
481 WMI_SEND_ASSOC_RES_CMDID,
482 WMI_SET_ASSOC_REQ_RELAY_CMDID,
483 WMI_GET_RFKILL_MODE_CMDID,
484
485 /* ACS command, consists of sub-commands */
486 WMI_ACS_CTRL_CMDID,
487
488 /* Ultra low power store / recall commands */
489 WMI_STORERECALL_CONFIGURE_CMDID,
490 WMI_STORERECALL_RECALL_CMDID,
491 WMI_STORERECALL_HOST_READY_CMDID,
492 WMI_FORCE_TARGET_ASSERT_CMDID,
493 WMI_SET_EXCESS_TX_RETRY_THRES_CMDID,
494} WMI_COMMAND_ID;
495
496/*
497 * Frame Types
498 */
499typedef enum {
500 WMI_FRAME_BEACON = 0,
501 WMI_FRAME_PROBE_REQ,
502 WMI_FRAME_PROBE_RESP,
503 WMI_FRAME_ASSOC_REQ,
504 WMI_FRAME_ASSOC_RESP,
505 WMI_NUM_MGMT_FRAME
506} WMI_MGMT_FRAME_TYPE;
507
508/*
509 * Connect Command
510 */
511typedef enum {
512 INFRA_NETWORK = 0x01,
513 ADHOC_NETWORK = 0x02,
514 ADHOC_CREATOR = 0x04,
515 AP_NETWORK = 0x10,
516} NETWORK_TYPE;
517
518typedef enum {
519 OPEN_AUTH = 0x01,
520 SHARED_AUTH = 0x02,
521 LEAP_AUTH = 0x04, /* different from IEEE_AUTH_MODE definitions */
522} DOT11_AUTH_MODE;
523
524enum {
525 AUTH_IDLE,
526 AUTH_OPEN_IN_PROGRESS,
527};
528
529typedef enum {
530 NONE_AUTH = 0x01,
531 WPA_AUTH = 0x02,
532 WPA2_AUTH = 0x04,
533 WPA_PSK_AUTH = 0x08,
534 WPA2_PSK_AUTH = 0x10,
535 WPA_AUTH_CCKM = 0x20,
536 WPA2_AUTH_CCKM = 0x40,
537} AUTH_MODE;
538
539typedef enum {
540 NONE_CRYPT = 0x01,
541 WEP_CRYPT = 0x02,
542 TKIP_CRYPT = 0x04,
543 AES_CRYPT = 0x08,
544#ifdef WAPI_ENABLE
545 WAPI_CRYPT = 0x10,
546#endif /*WAPI_ENABLE*/
547} CRYPTO_TYPE;
548
549#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT
550#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1)
551
552#ifdef WAPI_ENABLE
553#undef WMI_MAX_CRYPTO_TYPE
554#define WMI_MAX_CRYPTO_TYPE (WAPI_CRYPT + 1)
555#endif /* WAPI_ENABLE */
556
557#ifdef WAPI_ENABLE
558#define IW_ENCODE_ALG_SM4 0x20
559#define IW_AUTH_WAPI_ENABLED 0x20
560#endif
561
562#define WMI_MIN_KEY_INDEX 0
563#define WMI_MAX_KEY_INDEX 3
564
565#ifdef WAPI_ENABLE
566#undef WMI_MAX_KEY_INDEX
567#define WMI_MAX_KEY_INDEX 7 /* wapi grpKey 0-3, prwKey 4-7 */
568#endif /* WAPI_ENABLE */
569
570#define WMI_MAX_KEY_LEN 32
571
572#define WMI_MAX_SSID_LEN 32
573
574typedef enum {
575 CONNECT_ASSOC_POLICY_USER = 0x0001,
576 CONNECT_SEND_REASSOC = 0x0002,
577 CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004,
578 CONNECT_PROFILE_MATCH_DONE = 0x0008,
579 CONNECT_IGNORE_AAC_BEACON = 0x0010,
580 CONNECT_CSA_FOLLOW_BSS = 0x0020,
581 CONNECT_DO_WPA_OFFLOAD = 0x0040,
582 CONNECT_DO_NOT_DEAUTH = 0x0080,
583} WMI_CONNECT_CTRL_FLAGS_BITS;
584
585#define DEFAULT_CONNECT_CTRL_FLAGS (CONNECT_CSA_FOLLOW_BSS)
586
587typedef PREPACK struct {
588 u8 networkType;
589 u8 dot11AuthMode;
590 u8 authMode;
591 u8 pairwiseCryptoType;
592 u8 pairwiseCryptoLen;
593 u8 groupCryptoType;
594 u8 groupCryptoLen;
595 u8 ssidLength;
596 u8 ssid[WMI_MAX_SSID_LEN];
597 u16 channel;
598 u8 bssid[ATH_MAC_LEN];
599 u32 ctrl_flags;
600} POSTPACK WMI_CONNECT_CMD;
601
602/*
603 * WMI_RECONNECT_CMDID
604 */
605typedef PREPACK struct {
606 u16 channel; /* hint */
607 u8 bssid[ATH_MAC_LEN]; /* mandatory if set */
608} POSTPACK WMI_RECONNECT_CMD;
609
610#define WMI_PMK_LEN 32
611typedef PREPACK struct {
612 u8 pmk[WMI_PMK_LEN];
613} POSTPACK WMI_SET_PMK_CMD;
614
615/*
616 * WMI_SET_EXCESS_TX_RETRY_THRES_CMDID
617 */
618typedef PREPACK struct {
619 u32 threshold;
620} POSTPACK WMI_SET_EXCESS_TX_RETRY_THRES_CMD;
621
622/*
623 * WMI_ADD_CIPHER_KEY_CMDID
624 */
625typedef enum {
626 PAIRWISE_USAGE = 0x00,
627 GROUP_USAGE = 0x01,
628 TX_USAGE = 0x02, /* default Tx Key - Static WEP only */
629} KEY_USAGE;
630
631/*
632 * Bit Flag
633 * Bit 0 - Initialise TSC - default is Initialize
634 */
635#define KEY_OP_INIT_TSC 0x01
636#define KEY_OP_INIT_RSC 0x02
637#ifdef WAPI_ENABLE
638#define KEY_OP_INIT_WAPIPN 0x10
639#endif /* WAPI_ENABLE */
640
641#define KEY_OP_INIT_VAL 0x03 /* Default Initialise the TSC & RSC */
642#define KEY_OP_VALID_MASK 0x03
643
644typedef PREPACK struct {
645 u8 keyIndex;
646 u8 keyType;
647 u8 keyUsage; /* KEY_USAGE */
648 u8 keyLength;
649 u8 keyRSC[8]; /* key replay sequence counter */
650 u8 key[WMI_MAX_KEY_LEN];
651 u8 key_op_ctrl; /* Additional Key Control information */
652 u8 key_macaddr[ATH_MAC_LEN];
653} POSTPACK WMI_ADD_CIPHER_KEY_CMD;
654
655/*
656 * WMI_DELETE_CIPHER_KEY_CMDID
657 */
658typedef PREPACK struct {
659 u8 keyIndex;
660} POSTPACK WMI_DELETE_CIPHER_KEY_CMD;
661
662#define WMI_KRK_LEN 16
663/*
664 * WMI_ADD_KRK_CMDID
665 */
666typedef PREPACK struct {
667 u8 krk[WMI_KRK_LEN];
668} POSTPACK WMI_ADD_KRK_CMD;
669
670/*
671 * WMI_SET_TKIP_COUNTERMEASURES_CMDID
672 */
673typedef enum {
674 WMI_TKIP_CM_DISABLE = 0x0,
675 WMI_TKIP_CM_ENABLE = 0x1,
676} WMI_TKIP_CM_CONTROL;
677
678typedef PREPACK struct {
679 u8 cm_en; /* WMI_TKIP_CM_CONTROL */
680} POSTPACK WMI_SET_TKIP_COUNTERMEASURES_CMD;
681
682/*
683 * WMI_SET_PMKID_CMDID
684 */
685
686#define WMI_PMKID_LEN 16
687
688typedef enum {
689 PMKID_DISABLE = 0,
690 PMKID_ENABLE = 1,
691} PMKID_ENABLE_FLG;
692
693typedef PREPACK struct {
694 u8 bssid[ATH_MAC_LEN];
695 u8 enable; /* PMKID_ENABLE_FLG */
696 u8 pmkid[WMI_PMKID_LEN];
697} POSTPACK WMI_SET_PMKID_CMD;
698
699/*
700 * WMI_START_SCAN_CMD
701 */
702typedef enum {
703 WMI_LONG_SCAN = 0,
704 WMI_SHORT_SCAN = 1,
705} WMI_SCAN_TYPE;
706
707typedef PREPACK struct {
708 u32 forceFgScan;
709 u32 isLegacy; /* For Legacy Cisco AP compatibility */
710 u32 homeDwellTime; /* Maximum duration in the home channel(milliseconds) */
711 u32 forceScanInterval; /* Time interval between scans (milliseconds)*/
712 u8 scanType; /* WMI_SCAN_TYPE */
713 u8 numChannels; /* how many channels follow */
714 u16 channelList[1]; /* channels in Mhz */
715} POSTPACK WMI_START_SCAN_CMD;
716
717/*
718 * WMI_SET_SCAN_PARAMS_CMDID
719 */
720#define WMI_SHORTSCANRATIO_DEFAULT 3
721/*
722 * Warning: ScanCtrlFlag value of 0xFF is used to disable all flags in WMI_SCAN_PARAMS_CMD
723 * Do not add any more flags to WMI_SCAN_CTRL_FLAG_BITS
724 */
725typedef enum {
726 CONNECT_SCAN_CTRL_FLAGS = 0x01, /* set if can scan in the Connect cmd */
727 SCAN_CONNECTED_CTRL_FLAGS = 0x02, /* set if scan for the SSID it is */
728 /* already connected to */
729 ACTIVE_SCAN_CTRL_FLAGS = 0x04, /* set if enable active scan */
730 ROAM_SCAN_CTRL_FLAGS = 0x08, /* set if enable roam scan when bmiss and lowrssi */
731 REPORT_BSSINFO_CTRL_FLAGS = 0x10, /* set if follows customer BSSINFO reporting rule */
732 ENABLE_AUTO_CTRL_FLAGS = 0x20, /* if disabled, target doesn't
733 scan after a disconnect event */
734 ENABLE_SCAN_ABORT_EVENT = 0x40 /* Scan complete event with canceled status will be generated when a scan is prempted before it gets completed */
735} WMI_SCAN_CTRL_FLAGS_BITS;
736
737#define CAN_SCAN_IN_CONNECT(flags) (flags & CONNECT_SCAN_CTRL_FLAGS)
738#define CAN_SCAN_CONNECTED(flags) (flags & SCAN_CONNECTED_CTRL_FLAGS)
739#define ENABLE_ACTIVE_SCAN(flags) (flags & ACTIVE_SCAN_CTRL_FLAGS)
740#define ENABLE_ROAM_SCAN(flags) (flags & ROAM_SCAN_CTRL_FLAGS)
741#define CONFIG_REPORT_BSSINFO(flags) (flags & REPORT_BSSINFO_CTRL_FLAGS)
742#define IS_AUTO_SCAN_ENABLED(flags) (flags & ENABLE_AUTO_CTRL_FLAGS)
743#define SCAN_ABORT_EVENT_ENABLED(flags) (flags & ENABLE_SCAN_ABORT_EVENT)
744
745#define DEFAULT_SCAN_CTRL_FLAGS (CONNECT_SCAN_CTRL_FLAGS| SCAN_CONNECTED_CTRL_FLAGS| ACTIVE_SCAN_CTRL_FLAGS| ROAM_SCAN_CTRL_FLAGS | ENABLE_AUTO_CTRL_FLAGS)
746
747
748typedef PREPACK struct {
749 u16 fg_start_period; /* seconds */
750 u16 fg_end_period; /* seconds */
751 u16 bg_period; /* seconds */
752 u16 maxact_chdwell_time; /* msec */
753 u16 pas_chdwell_time; /* msec */
754 u8 shortScanRatio; /* how many shorts scan for one long */
755 u8 scanCtrlFlags;
756 u16 minact_chdwell_time; /* msec */
757 u16 maxact_scan_per_ssid; /* max active scans per ssid */
758 u32 max_dfsch_act_time; /* msecs */
759} POSTPACK WMI_SCAN_PARAMS_CMD;
760
761/*
762 * WMI_SET_BSS_FILTER_CMDID
763 */
764typedef enum {
765 NONE_BSS_FILTER = 0x0, /* no beacons forwarded */
766 ALL_BSS_FILTER, /* all beacons forwarded */
767 PROFILE_FILTER, /* only beacons matching profile */
768 ALL_BUT_PROFILE_FILTER, /* all but beacons matching profile */
769 CURRENT_BSS_FILTER, /* only beacons matching current BSS */
770 ALL_BUT_BSS_FILTER, /* all but beacons matching BSS */
771 PROBED_SSID_FILTER, /* beacons matching probed ssid */
772 LAST_BSS_FILTER, /* marker only */
773} WMI_BSS_FILTER;
774
775typedef PREPACK struct {
776 u8 bssFilter; /* see WMI_BSS_FILTER */
777 u8 reserved1; /* For alignment */
778 u16 reserved2; /* For alignment */
779 u32 ieMask;
780} POSTPACK WMI_BSS_FILTER_CMD;
781
782/*
783 * WMI_SET_PROBED_SSID_CMDID
784 */
785#define MAX_PROBED_SSID_INDEX 9
786
787typedef enum {
788 DISABLE_SSID_FLAG = 0, /* disables entry */
789 SPECIFIC_SSID_FLAG = 0x01, /* probes specified ssid */
790 ANY_SSID_FLAG = 0x02, /* probes for any ssid */
791} WMI_SSID_FLAG;
792
793typedef PREPACK struct {
794 u8 entryIndex; /* 0 to MAX_PROBED_SSID_INDEX */
795 u8 flag; /* WMI_SSID_FLG */
796 u8 ssidLength;
797 u8 ssid[32];
798} POSTPACK WMI_PROBED_SSID_CMD;
799
800/*
801 * WMI_SET_LISTEN_INT_CMDID
802 * The Listen interval is between 15 and 3000 TUs
803 */
804#define MIN_LISTEN_INTERVAL 15
805#define MAX_LISTEN_INTERVAL 5000
806#define MIN_LISTEN_BEACONS 1
807#define MAX_LISTEN_BEACONS 50
808
809typedef PREPACK struct {
810 u16 listenInterval;
811 u16 numBeacons;
812} POSTPACK WMI_LISTEN_INT_CMD;
813
814/*
815 * WMI_SET_BEACON_INT_CMDID
816 */
817typedef PREPACK struct {
818 u16 beaconInterval;
819} POSTPACK WMI_BEACON_INT_CMD;
820
821/*
822 * WMI_SET_BMISS_TIME_CMDID
823 * valid values are between 1000 and 5000 TUs
824 */
825
826#define MIN_BMISS_TIME 1000
827#define MAX_BMISS_TIME 5000
828#define MIN_BMISS_BEACONS 1
829#define MAX_BMISS_BEACONS 50
830
831typedef PREPACK struct {
832 u16 bmissTime;
833 u16 numBeacons;
834} POSTPACK WMI_BMISS_TIME_CMD;
835
836/*
837 * WMI_SET_POWER_MODE_CMDID
838 */
839typedef enum {
840 REC_POWER = 0x01,
841 MAX_PERF_POWER,
842} WMI_POWER_MODE;
843
844typedef PREPACK struct {
845 u8 powerMode; /* WMI_POWER_MODE */
846} POSTPACK WMI_POWER_MODE_CMD;
847
848typedef PREPACK struct {
849 s8 status; /* WMI_SET_PARAMS_REPLY */
850} POSTPACK WMI_SET_PARAMS_REPLY;
851
852typedef PREPACK struct {
853 u32 opcode;
854 u32 length;
855 char buffer[1]; /* WMI_SET_PARAMS */
856} POSTPACK WMI_SET_PARAMS_CMD;
857
858typedef PREPACK struct {
859 u8 multicast_mac[ATH_MAC_LEN]; /* WMI_SET_MCAST_FILTER */
860} POSTPACK WMI_SET_MCAST_FILTER_CMD;
861
862typedef PREPACK struct {
863 u8 enable; /* WMI_MCAST_FILTER */
864} POSTPACK WMI_MCAST_FILTER_CMD;
865
866/*
867 * WMI_SET_POWER_PARAMS_CMDID
868 */
869typedef enum {
870 IGNORE_DTIM = 0x01,
871 NORMAL_DTIM = 0x02,
872 STICK_DTIM = 0x03,
873 AUTO_DTIM = 0x04,
874} WMI_DTIM_POLICY;
875
876/* Policy to determnine whether TX should wakeup WLAN if sleeping */
877typedef enum {
878 TX_WAKEUP_UPON_SLEEP = 1,
879 TX_DONT_WAKEUP_UPON_SLEEP = 2
880} WMI_TX_WAKEUP_POLICY_UPON_SLEEP;
881
882/*
883 * Policy to determnine whether power save failure event should be sent to
884 * host during scanning
885 */
886typedef enum {
887 SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1,
888 IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2,
889} POWER_SAVE_FAIL_EVENT_POLICY;
890
891typedef PREPACK struct {
892 u16 idle_period; /* msec */
893 u16 pspoll_number;
894 u16 dtim_policy;
895 u16 tx_wakeup_policy;
896 u16 num_tx_to_wakeup;
897 u16 ps_fail_event_policy;
898} POSTPACK WMI_POWER_PARAMS_CMD;
899
900/* Adhoc power save types */
901typedef enum {
902 ADHOC_PS_DISABLE=1,
903 ADHOC_PS_ATH=2,
904 ADHOC_PS_IEEE=3,
905 ADHOC_PS_OTHER=4,
906} WMI_ADHOC_PS_TYPE;
907
908typedef PREPACK struct {
909 u8 power_saving;
910 u8 ttl; /* number of beacon periods */
911 u16 atim_windows; /* msec */
912 u16 timeout_value; /* msec */
913} POSTPACK WMI_IBSS_PM_CAPS_CMD;
914
915/* AP power save types */
916typedef enum {
917 AP_PS_DISABLE=1,
918 AP_PS_ATH=2,
919} WMI_AP_PS_TYPE;
920
921typedef PREPACK struct {
922 u32 idle_time; /* in msec */
923 u32 ps_period; /* in usec */
924 u8 sleep_period; /* in ps periods */
925 u8 psType;
926} POSTPACK WMI_AP_PS_CMD;
927
928/*
929 * WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID
930 */
931typedef enum {
932 IGNORE_TIM_ALL_QUEUES_APSD = 0,
933 PROCESS_TIM_ALL_QUEUES_APSD = 1,
934 IGNORE_TIM_SIMULATED_APSD = 2,
935 PROCESS_TIM_SIMULATED_APSD = 3,
936} APSD_TIM_POLICY;
937
938typedef PREPACK struct {
939 u16 psPollTimeout; /* msec */
940 u16 triggerTimeout; /* msec */
941 u32 apsdTimPolicy; /* TIM behavior with ques APSD enabled. Default is IGNORE_TIM_ALL_QUEUES_APSD */
942 u32 simulatedAPSDTimPolicy; /* TIM behavior with simulated APSD enabled. Default is PROCESS_TIM_SIMULATED_APSD */
943} POSTPACK WMI_POWERSAVE_TIMERS_POLICY_CMD;
944
945/*
946 * WMI_SET_VOICE_PKT_SIZE_CMDID
947 */
948typedef PREPACK struct {
949 u16 voicePktSize;
950} POSTPACK WMI_SET_VOICE_PKT_SIZE_CMD;
951
952/*
953 * WMI_SET_MAX_SP_LEN_CMDID
954 */
955typedef enum {
956 DELIVER_ALL_PKT = 0x0,
957 DELIVER_2_PKT = 0x1,
958 DELIVER_4_PKT = 0x2,
959 DELIVER_6_PKT = 0x3,
960} APSD_SP_LEN_TYPE;
961
962typedef PREPACK struct {
963 u8 maxSPLen;
964} POSTPACK WMI_SET_MAX_SP_LEN_CMD;
965
966/*
967 * WMI_SET_DISC_TIMEOUT_CMDID
968 */
969typedef PREPACK struct {
970 u8 disconnectTimeout; /* seconds */
971} POSTPACK WMI_DISC_TIMEOUT_CMD;
972
973typedef enum {
974 UPLINK_TRAFFIC = 0,
975 DNLINK_TRAFFIC = 1,
976 BIDIR_TRAFFIC = 2,
977} DIR_TYPE;
978
979typedef enum {
980 DISABLE_FOR_THIS_AC = 0,
981 ENABLE_FOR_THIS_AC = 1,
982 ENABLE_FOR_ALL_AC = 2,
983} VOICEPS_CAP_TYPE;
984
985typedef enum {
986 TRAFFIC_TYPE_APERIODIC = 0,
987 TRAFFIC_TYPE_PERIODIC = 1,
988}TRAFFIC_TYPE;
989
990/*
991 * WMI_SYNCHRONIZE_CMDID
992 */
993typedef PREPACK struct {
994 u8 dataSyncMap;
995} POSTPACK WMI_SYNC_CMD;
996
997/*
998 * WMI_CREATE_PSTREAM_CMDID
999 */
1000typedef PREPACK struct {
1001 u32 minServiceInt; /* in milli-sec */
1002 u32 maxServiceInt; /* in milli-sec */
1003 u32 inactivityInt; /* in milli-sec */
1004 u32 suspensionInt; /* in milli-sec */
1005 u32 serviceStartTime;
1006 u32 minDataRate; /* in bps */
1007 u32 meanDataRate; /* in bps */
1008 u32 peakDataRate; /* in bps */
1009 u32 maxBurstSize;
1010 u32 delayBound;
1011 u32 minPhyRate; /* in bps */
1012 u32 sba;
1013 u32 mediumTime;
1014 u16 nominalMSDU; /* in octects */
1015 u16 maxMSDU; /* in octects */
1016 u8 trafficClass;
1017 u8 trafficDirection; /* DIR_TYPE */
1018 u8 rxQueueNum;
1019 u8 trafficType; /* TRAFFIC_TYPE */
1020 u8 voicePSCapability; /* VOICEPS_CAP_TYPE */
1021 u8 tsid;
1022 u8 userPriority; /* 802.1D user priority */
1023 u8 nominalPHY; /* nominal phy rate */
1024} POSTPACK WMI_CREATE_PSTREAM_CMD;
1025
1026/*
1027 * WMI_DELETE_PSTREAM_CMDID
1028 */
1029typedef PREPACK struct {
1030 u8 txQueueNumber;
1031 u8 rxQueueNumber;
1032 u8 trafficDirection;
1033 u8 trafficClass;
1034 u8 tsid;
1035} POSTPACK WMI_DELETE_PSTREAM_CMD;
1036
1037/*
1038 * WMI_SET_CHANNEL_PARAMS_CMDID
1039 */
1040typedef enum {
1041 WMI_11A_MODE = 0x1,
1042 WMI_11G_MODE = 0x2,
1043 WMI_11AG_MODE = 0x3,
1044 WMI_11B_MODE = 0x4,
1045 WMI_11GONLY_MODE = 0x5,
1046} WMI_PHY_MODE;
1047
1048#define WMI_MAX_CHANNELS 32
1049
1050typedef PREPACK struct {
1051 u8 reserved1;
1052 u8 scanParam; /* set if enable scan */
1053 u8 phyMode; /* see WMI_PHY_MODE */
1054 u8 numChannels; /* how many channels follow */
1055 u16 channelList[1]; /* channels in Mhz */
1056} POSTPACK WMI_CHANNEL_PARAMS_CMD;
1057
1058
1059/*
1060 * WMI_RSSI_THRESHOLD_PARAMS_CMDID
1061 * Setting the polltime to 0 would disable polling.
1062 * Threshold values are in the ascending order, and should agree to:
1063 * (lowThreshold_lowerVal < lowThreshold_upperVal < highThreshold_lowerVal
1064 * < highThreshold_upperVal)
1065 */
1066
1067typedef PREPACK struct WMI_RSSI_THRESHOLD_PARAMS{
1068 u32 pollTime; /* Polling time as a factor of LI */
1069 s16 thresholdAbove1_Val; /* lowest of upper */
1070 s16 thresholdAbove2_Val;
1071 s16 thresholdAbove3_Val;
1072 s16 thresholdAbove4_Val;
1073 s16 thresholdAbove5_Val;
1074 s16 thresholdAbove6_Val; /* highest of upper */
1075 s16 thresholdBelow1_Val; /* lowest of bellow */
1076 s16 thresholdBelow2_Val;
1077 s16 thresholdBelow3_Val;
1078 s16 thresholdBelow4_Val;
1079 s16 thresholdBelow5_Val;
1080 s16 thresholdBelow6_Val; /* highest of bellow */
1081 u8 weight; /* "alpha" */
1082 u8 reserved[3];
1083} POSTPACK WMI_RSSI_THRESHOLD_PARAMS_CMD;
1084
1085/*
1086 * WMI_SNR_THRESHOLD_PARAMS_CMDID
1087 * Setting the polltime to 0 would disable polling.
1088 */
1089
1090typedef PREPACK struct WMI_SNR_THRESHOLD_PARAMS{
1091 u32 pollTime; /* Polling time as a factor of LI */
1092 u8 weight; /* "alpha" */
1093 u8 thresholdAbove1_Val; /* lowest of uppper*/
1094 u8 thresholdAbove2_Val;
1095 u8 thresholdAbove3_Val;
1096 u8 thresholdAbove4_Val; /* highest of upper */
1097 u8 thresholdBelow1_Val; /* lowest of bellow */
1098 u8 thresholdBelow2_Val;
1099 u8 thresholdBelow3_Val;
1100 u8 thresholdBelow4_Val; /* highest of bellow */
1101 u8 reserved[3];
1102} POSTPACK WMI_SNR_THRESHOLD_PARAMS_CMD;
1103
1104/*
1105 * WMI_LQ_THRESHOLD_PARAMS_CMDID
1106 */
1107typedef PREPACK struct WMI_LQ_THRESHOLD_PARAMS {
1108 u8 enable;
1109 u8 thresholdAbove1_Val;
1110 u8 thresholdAbove2_Val;
1111 u8 thresholdAbove3_Val;
1112 u8 thresholdAbove4_Val;
1113 u8 thresholdBelow1_Val;
1114 u8 thresholdBelow2_Val;
1115 u8 thresholdBelow3_Val;
1116 u8 thresholdBelow4_Val;
1117 u8 reserved[3];
1118} POSTPACK WMI_LQ_THRESHOLD_PARAMS_CMD;
1119
1120typedef enum {
1121 WMI_LPREAMBLE_DISABLED = 0,
1122 WMI_LPREAMBLE_ENABLED
1123} WMI_LPREAMBLE_STATUS;
1124
1125typedef enum {
1126 WMI_IGNORE_BARKER_IN_ERP = 0,
1127 WMI_DONOT_IGNORE_BARKER_IN_ERP
1128} WMI_PREAMBLE_POLICY;
1129
1130typedef PREPACK struct {
1131 u8 status;
1132 u8 preamblePolicy;
1133}POSTPACK WMI_SET_LPREAMBLE_CMD;
1134
1135typedef PREPACK struct {
1136 u16 threshold;
1137}POSTPACK WMI_SET_RTS_CMD;
1138
1139/*
1140 * WMI_TARGET_ERROR_REPORT_BITMASK_CMDID
1141 * Sets the error reporting event bitmask in target. Target clears it
1142 * upon an error. Subsequent errors are counted, but not reported
1143 * via event, unless the bitmask is set again.
1144 */
1145typedef PREPACK struct {
1146 u32 bitmask;
1147} POSTPACK WMI_TARGET_ERROR_REPORT_BITMASK;
1148
1149/*
1150 * WMI_SET_TX_PWR_CMDID
1151 */
1152typedef PREPACK struct {
1153 u8 dbM; /* in dbM units */
1154} POSTPACK WMI_SET_TX_PWR_CMD, WMI_TX_PWR_REPLY;
1155
1156/*
1157 * WMI_SET_ASSOC_INFO_CMDID
1158 *
1159 * A maximum of 2 private IEs can be sent in the [Re]Assoc request.
1160 * A 3rd one, the CCX version IE can also be set from the host.
1161 */
1162#define WMI_MAX_ASSOC_INFO_TYPE 2
1163#define WMI_CCX_VER_IE 2 /* ieType to set CCX Version IE */
1164
1165#define WMI_MAX_ASSOC_INFO_LEN 240
1166
1167typedef PREPACK struct {
1168 u8 ieType;
1169 u8 bufferSize;
1170 u8 assocInfo[1]; /* up to WMI_MAX_ASSOC_INFO_LEN */
1171} POSTPACK WMI_SET_ASSOC_INFO_CMD;
1172
1173
1174/*
1175 * WMI_GET_TX_PWR_CMDID does not take any parameters
1176 */
1177
1178/*
1179 * WMI_ADD_BAD_AP_CMDID
1180 */
1181#define WMI_MAX_BAD_AP_INDEX 1
1182
1183typedef PREPACK struct {
1184 u8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */
1185 u8 bssid[ATH_MAC_LEN];
1186} POSTPACK WMI_ADD_BAD_AP_CMD;
1187
1188/*
1189 * WMI_DELETE_BAD_AP_CMDID
1190 */
1191typedef PREPACK struct {
1192 u8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */
1193} POSTPACK WMI_DELETE_BAD_AP_CMD;
1194
1195/*
1196 * WMI_SET_ACCESS_PARAMS_CMDID
1197 */
1198#define WMI_DEFAULT_TXOP_ACPARAM 0 /* implies one MSDU */
1199#define WMI_DEFAULT_ECWMIN_ACPARAM 4 /* corresponds to CWmin of 15 */
1200#define WMI_DEFAULT_ECWMAX_ACPARAM 10 /* corresponds to CWmax of 1023 */
1201#define WMI_MAX_CW_ACPARAM 15 /* maximum eCWmin or eCWmax */
1202#define WMI_DEFAULT_AIFSN_ACPARAM 2
1203#define WMI_MAX_AIFSN_ACPARAM 15
1204typedef PREPACK struct {
1205 u16 txop; /* in units of 32 usec */
1206 u8 eCWmin;
1207 u8 eCWmax;
1208 u8 aifsn;
1209 u8 ac;
1210} POSTPACK WMI_SET_ACCESS_PARAMS_CMD;
1211
1212
1213/*
1214 * WMI_SET_RETRY_LIMITS_CMDID
1215 *
1216 * This command is used to customize the number of retries the
1217 * wlan device will perform on a given frame.
1218 */
1219#define WMI_MIN_RETRIES 2
1220#define WMI_MAX_RETRIES 13
1221typedef enum {
1222 MGMT_FRAMETYPE = 0,
1223 CONTROL_FRAMETYPE = 1,
1224 DATA_FRAMETYPE = 2
1225} WMI_FRAMETYPE;
1226
1227typedef PREPACK struct {
1228 u8 frameType; /* WMI_FRAMETYPE */
1229 u8 trafficClass; /* applies only to DATA_FRAMETYPE */
1230 u8 maxRetries;
1231 u8 enableNotify;
1232} POSTPACK WMI_SET_RETRY_LIMITS_CMD;
1233
1234/*
1235 * WMI_SET_ROAM_CTRL_CMDID
1236 *
1237 * This command is used to influence the Roaming behaviour
1238 * Set the host biases of the BSSs before setting the roam mode as bias
1239 * based.
1240 */
1241
1242/*
1243 * Different types of Roam Control
1244 */
1245
1246typedef enum {
1247 WMI_FORCE_ROAM = 1, /* Roam to the specified BSSID */
1248 WMI_SET_ROAM_MODE = 2, /* default ,progd bias, no roam */
1249 WMI_SET_HOST_BIAS = 3, /* Set the Host Bias */
1250 WMI_SET_LOWRSSI_SCAN_PARAMS = 4, /* Set lowrssi Scan parameters */
1251} WMI_ROAM_CTRL_TYPE;
1252
1253#define WMI_MIN_ROAM_CTRL_TYPE WMI_FORCE_ROAM
1254#define WMI_MAX_ROAM_CTRL_TYPE WMI_SET_LOWRSSI_SCAN_PARAMS
1255
1256/*
1257 * ROAM MODES
1258 */
1259
1260typedef enum {
1261 WMI_DEFAULT_ROAM_MODE = 1, /* RSSI based ROAM */
1262 WMI_HOST_BIAS_ROAM_MODE = 2, /* HOST BIAS based ROAM */
1263 WMI_LOCK_BSS_MODE = 3 /* Lock to the Current BSS - no Roam */
1264} WMI_ROAM_MODE;
1265
1266/*
1267 * BSS HOST BIAS INFO
1268 */
1269
1270typedef PREPACK struct {
1271 u8 bssid[ATH_MAC_LEN];
1272 s8 bias;
1273} POSTPACK WMI_BSS_BIAS;
1274
1275typedef PREPACK struct {
1276 u8 numBss;
1277 WMI_BSS_BIAS bssBias[1];
1278} POSTPACK WMI_BSS_BIAS_INFO;
1279
1280typedef PREPACK struct WMI_LOWRSSI_SCAN_PARAMS {
1281 u16 lowrssi_scan_period;
1282 s16 lowrssi_scan_threshold;
1283 s16 lowrssi_roam_threshold;
1284 u8 roam_rssi_floor;
1285 u8 reserved[1]; /* For alignment */
1286} POSTPACK WMI_LOWRSSI_SCAN_PARAMS;
1287
1288typedef PREPACK struct {
1289 PREPACK union {
1290 u8 bssid[ATH_MAC_LEN]; /* WMI_FORCE_ROAM */
1291 u8 roamMode; /* WMI_SET_ROAM_MODE */
1292 WMI_BSS_BIAS_INFO bssBiasInfo; /* WMI_SET_HOST_BIAS */
1293 WMI_LOWRSSI_SCAN_PARAMS lrScanParams;
1294 } POSTPACK info;
1295 u8 roamCtrlType ;
1296} POSTPACK WMI_SET_ROAM_CTRL_CMD;
1297
1298/*
1299 * WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID
1300 */
1301typedef enum {
1302 BT_WLAN_CONN_PRECDENCE_WLAN=0, /* Default */
1303 BT_WLAN_CONN_PRECDENCE_PAL,
1304} BT_WLAN_CONN_PRECEDENCE;
1305
1306typedef PREPACK struct {
1307 u8 precedence;
1308} POSTPACK WMI_SET_BT_WLAN_CONN_PRECEDENCE;
1309
1310/*
1311 * WMI_ENABLE_RM_CMDID
1312 */
1313typedef PREPACK struct {
1314 u32 enable_radio_measurements;
1315} POSTPACK WMI_ENABLE_RM_CMD;
1316
1317/*
1318 * WMI_SET_MAX_OFFHOME_DURATION_CMDID
1319 */
1320typedef PREPACK struct {
1321 u8 max_offhome_duration;
1322} POSTPACK WMI_SET_MAX_OFFHOME_DURATION_CMD;
1323
1324typedef PREPACK struct {
1325 u32 frequency;
1326 u8 threshold;
1327} POSTPACK WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD;
1328/*---------------------- BTCOEX RELATED -------------------------------------*/
1329/*----------------------COMMON to AR6002 and AR6003 -------------------------*/
1330typedef enum {
1331 BT_STREAM_UNDEF = 0,
1332 BT_STREAM_SCO, /* SCO stream */
1333 BT_STREAM_A2DP, /* A2DP stream */
1334 BT_STREAM_SCAN, /* BT Discovery or Page */
1335 BT_STREAM_ESCO,
1336 BT_STREAM_MAX
1337} BT_STREAM_TYPE;
1338
1339typedef enum {
1340 BT_PARAM_SCO_PSPOLL_LATENCY_ONE_FOURTH =1,
1341 BT_PARAM_SCO_PSPOLL_LATENCY_HALF,
1342 BT_PARAM_SCO_PSPOLL_LATENCY_THREE_FOURTH,
1343} BT_PARAMS_SCO_PSPOLL_LATENCY;
1344
1345typedef enum {
1346 BT_PARAMS_SCO_STOMP_SCO_NEVER =1,
1347 BT_PARAMS_SCO_STOMP_SCO_ALWAYS,
1348 BT_PARAMS_SCO_STOMP_SCO_IN_LOWRSSI,
1349} BT_PARAMS_SCO_STOMP_RULES;
1350
1351typedef enum {
1352 BT_STATUS_UNDEF = 0,
1353 BT_STATUS_ON,
1354 BT_STATUS_OFF,
1355 BT_STATUS_MAX
1356} BT_STREAM_STATUS;
1357
1358typedef PREPACK struct {
1359 u8 streamType;
1360 u8 status;
1361} POSTPACK WMI_SET_BT_STATUS_CMD;
1362
1363typedef enum {
1364 BT_ANT_TYPE_UNDEF=0,
1365 BT_ANT_TYPE_DUAL,
1366 BT_ANT_TYPE_SPLITTER,
1367 BT_ANT_TYPE_SWITCH,
1368 BT_ANT_TYPE_HIGH_ISO_DUAL
1369} BT_ANT_FRONTEND_CONFIG;
1370
1371typedef enum {
1372 BT_COLOCATED_DEV_BTS4020=0,
1373 BT_COLCATED_DEV_CSR ,
1374 BT_COLOCATED_DEV_VALKYRIE
1375} BT_COLOCATED_DEV_TYPE;
1376
1377/*********************** Applicable to AR6002 ONLY ******************************/
1378
1379typedef enum {
1380 BT_PARAM_SCO = 1, /* SCO stream parameters */
1381 BT_PARAM_A2DP ,
1382 BT_PARAM_ANTENNA_CONFIG,
1383 BT_PARAM_COLOCATED_BT_DEVICE,
1384 BT_PARAM_ACLCOEX,
1385 BT_PARAM_11A_SEPARATE_ANT,
1386 BT_PARAM_MAX
1387} BT_PARAM_TYPE;
1388
1389
1390#define BT_SCO_ALLOW_CLOSE_RANGE_OPT (1 << 0)
1391#define BT_SCO_FORCE_AWAKE_OPT (1 << 1)
1392#define BT_SCO_SET_RSSI_OVERRIDE(flags) ((flags) |= (1 << 2))
1393#define BT_SCO_GET_RSSI_OVERRIDE(flags) (((flags) >> 2) & 0x1)
1394#define BT_SCO_SET_RTS_OVERRIDE(flags) ((flags) |= (1 << 3))
1395#define BT_SCO_GET_RTS_OVERRIDE(flags) (((flags) >> 3) & 0x1)
1396#define BT_SCO_GET_MIN_LOW_RATE_CNT(flags) (((flags) >> 8) & 0xFF)
1397#define BT_SCO_GET_MAX_LOW_RATE_CNT(flags) (((flags) >> 16) & 0xFF)
1398#define BT_SCO_SET_MIN_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 8)
1399#define BT_SCO_SET_MAX_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 16)
1400
1401typedef PREPACK struct {
1402 u32 numScoCyclesForceTrigger; /* Number SCO cycles after which
1403 force a pspoll. default = 10 */
1404 u32 dataResponseTimeout; /* Timeout Waiting for Downlink pkt
1405 in response for ps-poll,
1406 default = 10 msecs */
1407 u32 stompScoRules;
1408 u32 scoOptFlags; /* SCO Options Flags :
1409 bits: meaning:
1410 0 Allow Close Range Optimization
1411 1 Force awake during close range
1412 2 If set use host supplied RSSI for OPT
1413 3 If set use host supplied RTS COUNT for OPT
1414 4..7 Unused
1415 8..15 Low Data Rate Min Cnt
1416 16..23 Low Data Rate Max Cnt
1417 */
1418
1419 u8 stompDutyCyleVal; /* Sco cycles to limit ps-poll queuing
1420 if stomped */
1421 u8 stompDutyCyleMaxVal; /*firm ware increases stomp duty cycle
1422 gradually uptill this value on need basis*/
1423 u8 psPollLatencyFraction; /* Fraction of idle
1424 period, within which
1425 additional ps-polls
1426 can be queued */
1427 u8 noSCOSlots; /* Number of SCO Tx/Rx slots.
1428 HVx, EV3, 2EV3 = 2 */
1429 u8 noIdleSlots; /* Number of Bluetooth idle slots between
1430 consecutive SCO Tx/Rx slots
1431 HVx, EV3 = 4
1432 2EV3 = 10 */
1433 u8 scoOptOffRssi;/*RSSI value below which we go to ps poll*/
1434 u8 scoOptOnRssi; /*RSSI value above which we reenter opt mode*/
1435 u8 scoOptRtsCount;
1436} POSTPACK BT_PARAMS_SCO;
1437
1438#define BT_A2DP_ALLOW_CLOSE_RANGE_OPT (1 << 0)
1439#define BT_A2DP_FORCE_AWAKE_OPT (1 << 1)
1440#define BT_A2DP_SET_RSSI_OVERRIDE(flags) ((flags) |= (1 << 2))
1441#define BT_A2DP_GET_RSSI_OVERRIDE(flags) (((flags) >> 2) & 0x1)
1442#define BT_A2DP_SET_RTS_OVERRIDE(flags) ((flags) |= (1 << 3))
1443#define BT_A2DP_GET_RTS_OVERRIDE(flags) (((flags) >> 3) & 0x1)
1444#define BT_A2DP_GET_MIN_LOW_RATE_CNT(flags) (((flags) >> 8) & 0xFF)
1445#define BT_A2DP_GET_MAX_LOW_RATE_CNT(flags) (((flags) >> 16) & 0xFF)
1446#define BT_A2DP_SET_MIN_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 8)
1447#define BT_A2DP_SET_MAX_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 16)
1448
1449typedef PREPACK struct {
1450 u32 a2dpWlanUsageLimit; /* MAX time firmware uses the medium for
1451 wlan, after it identifies the idle time
1452 default (30 msecs) */
1453 u32 a2dpBurstCntMin; /* Minimum number of bluetooth data frames
1454 to replenish Wlan Usage limit (default 3) */
1455 u32 a2dpDataRespTimeout;
1456 u32 a2dpOptFlags; /* A2DP Option flags:
1457 bits: meaning:
1458 0 Allow Close Range Optimization
1459 1 Force awake during close range
1460 2 If set use host supplied RSSI for OPT
1461 3 If set use host supplied RTS COUNT for OPT
1462 4..7 Unused
1463 8..15 Low Data Rate Min Cnt
1464 16..23 Low Data Rate Max Cnt
1465 */
1466 u8 isCoLocatedBtRoleMaster;
1467 u8 a2dpOptOffRssi;/*RSSI value below which we go to ps poll*/
1468 u8 a2dpOptOnRssi; /*RSSI value above which we reenter opt mode*/
1469 u8 a2dpOptRtsCount;
1470}POSTPACK BT_PARAMS_A2DP;
1471
1472/* During BT ftp/ BT OPP or any another data based acl profile on bluetooth
1473 (non a2dp).*/
1474typedef PREPACK struct {
1475 u32 aclWlanMediumUsageTime; /* Wlan usage time during Acl (non-a2dp)
1476 coexistence (default 30 msecs) */
1477 u32 aclBtMediumUsageTime; /* Bt usage time during acl coexistence
1478 (default 30 msecs)*/
1479 u32 aclDataRespTimeout;
1480 u32 aclDetectTimeout; /* ACL coexistence enabled if we get
1481 10 Pkts in X msec(default 100 msecs) */
1482 u32 aclmaxPktCnt; /* No of ACL pkts to receive before
1483 enabling ACL coex */
1484
1485}POSTPACK BT_PARAMS_ACLCOEX;
1486
1487typedef PREPACK struct {
1488 PREPACK union {
1489 BT_PARAMS_SCO scoParams;
1490 BT_PARAMS_A2DP a2dpParams;
1491 BT_PARAMS_ACLCOEX aclCoexParams;
1492 u8 antType; /* 0 -Disabled (default)
1493 1 - BT_ANT_TYPE_DUAL
1494 2 - BT_ANT_TYPE_SPLITTER
1495 3 - BT_ANT_TYPE_SWITCH */
1496 u8 coLocatedBtDev; /* 0 - BT_COLOCATED_DEV_BTS4020 (default)
1497 1 - BT_COLCATED_DEV_CSR
1498 2 - BT_COLOCATED_DEV_VALKYRIe
1499 */
1500 } POSTPACK info;
1501 u8 paramType ;
1502} POSTPACK WMI_SET_BT_PARAMS_CMD;
1503
1504/************************ END AR6002 BTCOEX *******************************/
1505/*-----------------------AR6003 BTCOEX -----------------------------------*/
1506
1507/* ---------------WMI_SET_BTCOEX_FE_ANT_CMDID --------------------------*/
1508/* Indicates front end antenna configuration. This command needs to be issued
1509 * right after initialization and after WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID.
1510 * AR6003 enables coexistence and antenna switching based on the configuration.
1511 */
1512typedef enum {
1513 WMI_BTCOEX_NOT_ENABLED = 0,
1514 WMI_BTCOEX_FE_ANT_SINGLE =1,
1515 WMI_BTCOEX_FE_ANT_DUAL=2,
1516 WMI_BTCOEX_FE_ANT_DUAL_HIGH_ISO=3,
1517 WMI_BTCOEX_FE_ANT_TYPE_MAX
1518}WMI_BTCOEX_FE_ANT_TYPE;
1519
1520typedef PREPACK struct {
1521 u8 btcoexFeAntType; /* 1 - WMI_BTCOEX_FE_ANT_SINGLE for single antenna front end
1522 2 - WMI_BTCOEX_FE_ANT_DUAL for dual antenna front end
1523 (for isolations less 35dB, for higher isolation there
1524 is not need to pass this command).
1525 (not implemented)
1526 */
1527}POSTPACK WMI_SET_BTCOEX_FE_ANT_CMD;
1528
1529/* -------------WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID ----------------*/
1530/* Indicate the bluetooth chip to the firmware. Firmware can have different algorithm based
1531 * bluetooth chip type.Based on bluetooth device, different coexistence protocol would be used.
1532 */
1533typedef PREPACK struct {
1534 u8 btcoexCoLocatedBTdev; /*1 - Qcom BT (3 -wire PTA)
1535 2 - CSR BT (3 wire PTA)
1536 3 - Atheros 3001 BT (3 wire PTA)
1537 4 - STE bluetooth (4-wire ePTA)
1538 5 - Atheros 3002 BT (4-wire MCI)
1539 defaults= 3 (Atheros 3001 BT )
1540 */
1541}POSTPACK WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD;
1542
1543/* -------------WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID ------------*/
1544/* Configuration parameters during bluetooth inquiry and page. Page configuration
1545 * is applicable only on interfaces which can distinguish page (applicable only for ePTA -
1546 * STE bluetooth).
1547 * Bluetooth inquiry start and end is indicated via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID.
1548 * During this the station will be power-save mode.
1549 */
1550typedef PREPACK struct {
1551 u32 btInquiryDataFetchFrequency;/* The frequency of querying the AP for data
1552 (via pspoll) is configured by this parameter.
1553 "default = 10 ms" */
1554
1555 u32 protectBmissDurPostBtInquiry;/* The firmware will continue to be in inquiry state
1556 for configured duration, after inquiry completion
1557 . This is to ensure other bluetooth transactions
1558 (RDP, SDP profiles, link key exchange ...etc)
1559 goes through smoothly without wifi stomping.
1560 default = 10 secs*/
1561
1562 u32 maxpageStomp; /*Applicable only for STE-BT interface. Currently not
1563 used */
1564 u32 btInquiryPageFlag; /* Not used */
1565}POSTPACK WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD;
1566
1567/*---------------------WMI_SET_BTCOEX_SCO_CONFIG_CMDID ---------------*/
1568/* Configure SCO parameters. These parameters would be used whenever firmware is indicated
1569 * of (e)SCO profile on bluetooth ( via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID).
1570 * Configration of BTCOEX_SCO_CONFIG data structure are common configuration and applies
1571 * ps-poll mode and opt mode.
1572 * Ps-poll Mode - Station is in power-save and retrieves downlink data between sco gaps.
1573 * Opt Mode - station is in awake state and access point can send data to station any time.
1574 * BTCOEX_PSPOLLMODE_SCO_CONFIG - Configuration applied only during ps-poll mode.
1575 * BTCOEX_OPTMODE_SCO_CONFIG - Configuration applied only during opt mode.
1576 */
1577#define WMI_SCO_CONFIG_FLAG_ALLOW_OPTIMIZATION (1 << 0)
1578#define WMI_SCO_CONFIG_FLAG_IS_EDR_CAPABLE (1 << 1)
1579#define WMI_SCO_CONFIG_FLAG_IS_BT_MASTER (1 << 2)
1580#define WMI_SCO_CONFIG_FLAG_FW_DETECT_OF_PER (1 << 3)
1581typedef PREPACK struct {
1582 u32 scoSlots; /* Number of SCO Tx/Rx slots.
1583 HVx, EV3, 2EV3 = 2 */
1584 u32 scoIdleSlots; /* Number of Bluetooth idle slots between
1585 consecutive SCO Tx/Rx slots
1586 HVx, EV3 = 4
1587 2EV3 = 10
1588 */
1589 u32 scoFlags; /* SCO Options Flags :
1590 bits: meaning:
1591 0 Allow Close Range Optimization
1592 1 Is EDR capable or Not
1593 2 IS Co-located Bt role Master
1594 3 Firmware determines the periodicity of SCO.
1595 */
1596
1597 u32 linkId; /* applicable to STE-BT - not used */
1598}POSTPACK BTCOEX_SCO_CONFIG;
1599
1600typedef PREPACK struct {
1601 u32 scoCyclesForceTrigger; /* Number SCO cycles after which
1602 force a pspoll. default = 10 */
1603 u32 scoDataResponseTimeout; /* Timeout Waiting for Downlink pkt
1604 in response for ps-poll,
1605 default = 20 msecs */
1606
1607 u32 scoStompDutyCyleVal; /* not implemented */
1608
1609 u32 scoStompDutyCyleMaxVal; /*Not implemented */
1610
1611 u32 scoPsPollLatencyFraction; /* Fraction of idle
1612 period, within which
1613 additional ps-polls can be queued
1614 1 - 1/4 of idle duration
1615 2 - 1/2 of idle duration
1616 3 - 3/4 of idle duration
1617 default =2 (1/2)
1618 */
1619}POSTPACK BTCOEX_PSPOLLMODE_SCO_CONFIG;
1620
1621typedef PREPACK struct {
1622 u32 scoStompCntIn100ms;/*max number of SCO stomp in 100ms allowed in
1623 opt mode. If exceeds the configured value,
1624 switch to ps-poll mode
1625 default = 3 */
1626
1627 u32 scoContStompMax; /* max number of continuous stomp allowed in opt mode.
1628 if exceeded switch to pspoll mode
1629 default = 3 */
1630
1631 u32 scoMinlowRateMbps; /* Low rate threshold */
1632
1633 u32 scoLowRateCnt; /* number of low rate pkts (< scoMinlowRateMbps) allowed in 100 ms.
1634 If exceeded switch/stay to ps-poll mode, lower stay in opt mode.
1635 default = 36
1636 */
1637
1638 u32 scoHighPktRatio; /*(Total Rx pkts in 100 ms + 1)/
1639 ((Total tx pkts in 100 ms - No of high rate pkts in 100 ms) + 1) in 100 ms,
1640 if exceeded switch/stay in opt mode and if lower switch/stay in pspoll mode.
1641 default = 5 (80% of high rates)
1642 */
1643
1644 u32 scoMaxAggrSize; /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates
1645 max number of aggregates if it was negogiated to higher value
1646 default = 1
1647 Recommended value Basic rate headsets = 1, EDR (2-EV3) =4.
1648 */
1649}POSTPACK BTCOEX_OPTMODE_SCO_CONFIG;
1650
1651typedef PREPACK struct {
1652 u32 scanInterval;
1653 u32 maxScanStompCnt;
1654}POSTPACK BTCOEX_WLANSCAN_SCO_CONFIG;
1655
1656typedef PREPACK struct {
1657 BTCOEX_SCO_CONFIG scoConfig;
1658 BTCOEX_PSPOLLMODE_SCO_CONFIG scoPspollConfig;
1659 BTCOEX_OPTMODE_SCO_CONFIG scoOptModeConfig;
1660 BTCOEX_WLANSCAN_SCO_CONFIG scoWlanScanConfig;
1661}POSTPACK WMI_SET_BTCOEX_SCO_CONFIG_CMD;
1662
1663/* ------------------WMI_SET_BTCOEX_A2DP_CONFIG_CMDID -------------------*/
1664/* Configure A2DP profile parameters. These parameters would be used whenver firmware is indicated
1665 * of A2DP profile on bluetooth ( via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID).
1666 * Configuration of BTCOEX_A2DP_CONFIG data structure are common configuration and applies to
1667 * ps-poll mode and opt mode.
1668 * Ps-poll Mode - Station is in power-save and retrieves downlink data between a2dp data bursts.
1669 * Opt Mode - station is in power save during a2dp bursts and awake in the gaps.
1670 * BTCOEX_PSPOLLMODE_A2DP_CONFIG - Configuration applied only during ps-poll mode.
1671 * BTCOEX_OPTMODE_A2DP_CONFIG - Configuration applied only during opt mode.
1672 */
1673
1674#define WMI_A2DP_CONFIG_FLAG_ALLOW_OPTIMIZATION (1 << 0)
1675#define WMI_A2DP_CONFIG_FLAG_IS_EDR_CAPABLE (1 << 1)
1676#define WMI_A2DP_CONFIG_FLAG_IS_BT_ROLE_MASTER (1 << 2)
1677#define WMI_A2DP_CONFIG_FLAG_IS_A2DP_HIGH_PRI (1 << 3)
1678#define WMI_A2DP_CONFIG_FLAG_FIND_BT_ROLE (1 << 4)
1679
1680typedef PREPACK struct {
1681 u32 a2dpFlags; /* A2DP Option flags:
1682 bits: meaning:
1683 0 Allow Close Range Optimization
1684 1 IS EDR capable
1685 2 IS Co-located Bt role Master
1686 3 a2dp traffic is high priority
1687 4 Fw detect the role of bluetooth.
1688 */
1689 u32 linkId; /* Applicable only to STE-BT - not used */
1690
1691}POSTPACK BTCOEX_A2DP_CONFIG;
1692
1693typedef PREPACK struct {
1694 u32 a2dpWlanMaxDur; /* MAX time firmware uses the medium for
1695 wlan, after it identifies the idle time
1696 default (30 msecs) */
1697
1698 u32 a2dpMinBurstCnt; /* Minimum number of bluetooth data frames
1699 to replenish Wlan Usage limit (default 3) */
1700
1701 u32 a2dpDataRespTimeout; /* Max duration firmware waits for downlink
1702 by stomping on bluetooth
1703 after ps-poll is acknowledged.
1704 default = 20 ms
1705 */
1706}POSTPACK BTCOEX_PSPOLLMODE_A2DP_CONFIG;
1707
1708typedef PREPACK struct {
1709 u32 a2dpMinlowRateMbps; /* Low rate threshold */
1710
1711 u32 a2dpLowRateCnt; /* number of low rate pkts (< a2dpMinlowRateMbps) allowed in 100 ms.
1712 If exceeded switch/stay to ps-poll mode, lower stay in opt mode.
1713 default = 36
1714 */
1715
1716 u32 a2dpHighPktRatio; /*(Total Rx pkts in 100 ms + 1)/
1717 ((Total tx pkts in 100 ms - No of high rate pkts in 100 ms) + 1) in 100 ms,
1718 if exceeded switch/stay in opt mode and if lower switch/stay in pspoll mode.
1719 default = 5 (80% of high rates)
1720 */
1721
1722 u32 a2dpMaxAggrSize; /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates
1723 max number of aggregates if it was negogiated to higher value
1724 default = 1
1725 Recommended value Basic rate headsets = 1, EDR (2-EV3) =8.
1726 */
1727 u32 a2dpPktStompCnt; /*number of a2dp pkts that can be stomped per burst.
1728 default = 6*/
1729
1730}POSTPACK BTCOEX_OPTMODE_A2DP_CONFIG;
1731
1732typedef PREPACK struct {
1733 BTCOEX_A2DP_CONFIG a2dpConfig;
1734 BTCOEX_PSPOLLMODE_A2DP_CONFIG a2dppspollConfig;
1735 BTCOEX_OPTMODE_A2DP_CONFIG a2dpOptConfig;
1736}POSTPACK WMI_SET_BTCOEX_A2DP_CONFIG_CMD;
1737
1738/*------------ WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID---------------------*/
1739/* Configure non-A2dp ACL profile parameters.The starts of ACL profile can either be
1740 * indicated via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID orenabled via firmware detection
1741 * which is configured via "aclCoexFlags".
1742 * Configration of BTCOEX_ACLCOEX_CONFIG data structure are common configuration and applies
1743 * ps-poll mode and opt mode.
1744 * Ps-poll Mode - Station is in power-save and retrieves downlink data during wlan medium.
1745 * Opt Mode - station is in power save during bluetooth medium time and awake during wlan duration.
1746 * (Not implemented yet)
1747 *
1748 * BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG - Configuration applied only during ps-poll mode.
1749 * BTCOEX_OPTMODE_ACLCOEX_CONFIG - Configuration applied only during opt mode.
1750 */
1751
1752#define WMI_ACLCOEX_FLAGS_ALLOW_OPTIMIZATION (1 << 0)
1753#define WMI_ACLCOEX_FLAGS_DISABLE_FW_DETECTION (1 << 1)
1754
1755typedef PREPACK struct {
1756 u32 aclWlanMediumDur; /* Wlan usage time during Acl (non-a2dp)
1757 coexistence (default 30 msecs)
1758 */
1759
1760 u32 aclBtMediumDur; /* Bt usage time during acl coexistence
1761 (default 30 msecs)
1762 */
1763
1764 u32 aclDetectTimeout; /* BT activity observation time limit.
1765 In this time duration, number of bt pkts are counted.
1766 If the Cnt reaches "aclPktCntLowerLimit" value
1767 for "aclIterToEnableCoex" iteration continuously,
1768 firmware gets into ACL coexistence mode.
1769 Similarly, if bt traffic count during ACL coexistence
1770 has not reached "aclPktCntLowerLimit" continuously
1771 for "aclIterToEnableCoex", then ACL coexistence is
1772 disabled.
1773 -default 100 msecs
1774 */
1775
1776 u32 aclPktCntLowerLimit; /* Acl Pkt Cnt to be received in duration of
1777 "aclDetectTimeout" for
1778 "aclIterForEnDis" times to enabling ACL coex.
1779 Similar logic is used to disable acl coexistence.
1780 (If "aclPktCntLowerLimit" cnt of acl pkts
1781 are not seen by the for "aclIterForEnDis"
1782 then acl coexistence is disabled).
1783 default = 10
1784 */
1785
1786 u32 aclIterForEnDis; /* number of Iteration of "aclPktCntLowerLimit" for Enabling and
1787 Disabling Acl Coexistence.
1788 default = 3
1789 */
1790
1791 u32 aclPktCntUpperLimit; /* This is upperBound limit, if there is more than
1792 "aclPktCntUpperLimit" seen in "aclDetectTimeout",
1793 ACL coexistence is enabled right away.
1794 - default 15*/
1795
1796 u32 aclCoexFlags; /* A2DP Option flags:
1797 bits: meaning:
1798 0 Allow Close Range Optimization
1799 1 disable Firmware detection
1800 (Currently supported configuration is aclCoexFlags =0)
1801 */
1802 u32 linkId; /* Applicable only for STE-BT - not used */
1803
1804}POSTPACK BTCOEX_ACLCOEX_CONFIG;
1805
1806typedef PREPACK struct {
1807 u32 aclDataRespTimeout; /* Max duration firmware waits for downlink
1808 by stomping on bluetooth
1809 after ps-poll is acknowledged.
1810 default = 20 ms */
1811
1812}POSTPACK BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG;
1813
1814
1815/* Not implemented yet*/
1816typedef PREPACK struct {
1817 u32 aclCoexMinlowRateMbps;
1818 u32 aclCoexLowRateCnt;
1819 u32 aclCoexHighPktRatio;
1820 u32 aclCoexMaxAggrSize;
1821 u32 aclPktStompCnt;
1822}POSTPACK BTCOEX_OPTMODE_ACLCOEX_CONFIG;
1823
1824typedef PREPACK struct {
1825 BTCOEX_ACLCOEX_CONFIG aclCoexConfig;
1826 BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG aclCoexPspollConfig;
1827 BTCOEX_OPTMODE_ACLCOEX_CONFIG aclCoexOptConfig;
1828}POSTPACK WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD;
1829
1830/* -----------WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ------------------*/
1831typedef enum {
1832 WMI_BTCOEX_BT_PROFILE_SCO =1,
1833 WMI_BTCOEX_BT_PROFILE_A2DP,
1834 WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE,
1835 WMI_BTCOEX_BT_PROFILE_ACLCOEX,
1836}WMI_BTCOEX_BT_PROFILE;
1837
1838typedef PREPACK struct {
1839 u32 btProfileType;
1840 u32 btOperatingStatus;
1841 u32 btLinkId;
1842}WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD;
1843
1844/*--------------------- WMI_SET_BTCOEX_DEBUG_CMDID ---------------------*/
1845/* Used for firmware development and debugging */
1846typedef PREPACK struct {
1847 u32 btcoexDbgParam1;
1848 u32 btcoexDbgParam2;
1849 u32 btcoexDbgParam3;
1850 u32 btcoexDbgParam4;
1851 u32 btcoexDbgParam5;
1852}WMI_SET_BTCOEX_DEBUG_CMD;
1853
1854/*---------------------WMI_GET_BTCOEX_CONFIG_CMDID --------------------- */
1855/* Command to firmware to get configuration parameters of the bt profile
1856 * reported via WMI_BTCOEX_CONFIG_EVENTID */
1857typedef PREPACK struct {
1858 u32 btProfileType; /* 1 - SCO
1859 2 - A2DP
1860 3 - INQUIRY_PAGE
1861 4 - ACLCOEX
1862 */
1863 u32 linkId; /* not used */
1864}WMI_GET_BTCOEX_CONFIG_CMD;
1865
1866/*------------------WMI_REPORT_BTCOEX_CONFIG_EVENTID------------------- */
1867/* Event from firmware to host, sent in response to WMI_GET_BTCOEX_CONFIG_CMDID
1868 * */
1869typedef PREPACK struct {
1870 u32 btProfileType;
1871 u32 linkId; /* not used */
1872 PREPACK union {
1873 WMI_SET_BTCOEX_SCO_CONFIG_CMD scoConfigCmd;
1874 WMI_SET_BTCOEX_A2DP_CONFIG_CMD a2dpConfigCmd;
1875 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD aclcoexConfig;
1876 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD btinquiryPageConfigCmd;
1877 } POSTPACK info;
1878} POSTPACK WMI_BTCOEX_CONFIG_EVENT;
1879
1880/*------------- WMI_REPORT_BTCOEX_BTCOEX_STATS_EVENTID--------------------*/
1881/* Used for firmware development and debugging*/
1882typedef PREPACK struct {
1883 u32 highRatePktCnt;
1884 u32 firstBmissCnt;
1885 u32 psPollFailureCnt;
1886 u32 nullFrameFailureCnt;
1887 u32 optModeTransitionCnt;
1888}BTCOEX_GENERAL_STATS;
1889
1890typedef PREPACK struct {
1891 u32 scoStompCntAvg;
1892 u32 scoStompIn100ms;
1893 u32 scoMaxContStomp;
1894 u32 scoAvgNoRetries;
1895 u32 scoMaxNoRetriesIn100ms;
1896}BTCOEX_SCO_STATS;
1897
1898typedef PREPACK struct {
1899 u32 a2dpBurstCnt;
1900 u32 a2dpMaxBurstCnt;
1901 u32 a2dpAvgIdletimeIn100ms;
1902 u32 a2dpAvgStompCnt;
1903}BTCOEX_A2DP_STATS;
1904
1905typedef PREPACK struct {
1906 u32 aclPktCntInBtTime;
1907 u32 aclStompCntInWlanTime;
1908 u32 aclPktCntIn100ms;
1909}BTCOEX_ACLCOEX_STATS;
1910
1911typedef PREPACK struct {
1912 BTCOEX_GENERAL_STATS coexStats;
1913 BTCOEX_SCO_STATS scoStats;
1914 BTCOEX_A2DP_STATS a2dpStats;
1915 BTCOEX_ACLCOEX_STATS aclCoexStats;
1916}WMI_BTCOEX_STATS_EVENT;
1917
1918
1919/*--------------------------END OF BTCOEX -------------------------------------*/
1920typedef PREPACK struct {
1921 u32 sleepState;
1922}WMI_REPORT_SLEEP_STATE_EVENT;
1923
1924typedef enum {
1925 WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP =0,
1926 WMI_REPORT_SLEEP_STATUS_IS_AWAKE
1927} WMI_REPORT_SLEEP_STATUS;
1928typedef enum {
1929 DISCONN_EVT_IN_RECONN = 0, /* default */
1930 NO_DISCONN_EVT_IN_RECONN
1931} TARGET_EVENT_REPORT_CONFIG;
1932
1933typedef PREPACK struct {
1934 u32 evtConfig;
1935} POSTPACK WMI_SET_TARGET_EVENT_REPORT_CMD;
1936
1937
1938typedef PREPACK struct {
1939 u16 cmd_buf_sz; /* HCI cmd buffer size */
1940 u8 buf[1]; /* Absolute HCI cmd */
1941} POSTPACK WMI_HCI_CMD;
1942
1943/*
1944 * Command Replies
1945 */
1946
1947/*
1948 * WMI_GET_CHANNEL_LIST_CMDID reply
1949 */
1950typedef PREPACK struct {
1951 u8 reserved1;
1952 u8 numChannels; /* number of channels in reply */
1953 u16 channelList[1]; /* channel in Mhz */
1954} POSTPACK WMI_CHANNEL_LIST_REPLY;
1955
1956typedef enum {
1957 A_SUCCEEDED = 0,
1958 A_FAILED_DELETE_STREAM_DOESNOT_EXIST=250,
1959 A_SUCCEEDED_MODIFY_STREAM=251,
1960 A_FAILED_INVALID_STREAM = 252,
1961 A_FAILED_MAX_THINSTREAMS = 253,
1962 A_FAILED_CREATE_REMOVE_PSTREAM_FIRST = 254,
1963} PSTREAM_REPLY_STATUS;
1964
1965typedef PREPACK struct {
1966 u8 status; /* PSTREAM_REPLY_STATUS */
1967 u8 txQueueNumber;
1968 u8 rxQueueNumber;
1969 u8 trafficClass;
1970 u8 trafficDirection; /* DIR_TYPE */
1971} POSTPACK WMI_CRE_PRIORITY_STREAM_REPLY;
1972
1973typedef PREPACK struct {
1974 u8 status; /* PSTREAM_REPLY_STATUS */
1975 u8 txQueueNumber;
1976 u8 rxQueueNumber;
1977 u8 trafficDirection; /* DIR_TYPE */
1978 u8 trafficClass;
1979} POSTPACK WMI_DEL_PRIORITY_STREAM_REPLY;
1980
1981/*
1982 * List of Events (target to host)
1983 */
1984typedef enum {
1985 WMI_READY_EVENTID = 0x1001,
1986 WMI_CONNECT_EVENTID,
1987 WMI_DISCONNECT_EVENTID,
1988 WMI_BSSINFO_EVENTID,
1989 WMI_CMDERROR_EVENTID,
1990 WMI_REGDOMAIN_EVENTID,
1991 WMI_PSTREAM_TIMEOUT_EVENTID,
1992 WMI_NEIGHBOR_REPORT_EVENTID,
1993 WMI_TKIP_MICERR_EVENTID,
1994 WMI_SCAN_COMPLETE_EVENTID, /* 0x100a */
1995 WMI_REPORT_STATISTICS_EVENTID,
1996 WMI_RSSI_THRESHOLD_EVENTID,
1997 WMI_ERROR_REPORT_EVENTID,
1998 WMI_OPT_RX_FRAME_EVENTID,
1999 WMI_REPORT_ROAM_TBL_EVENTID,
2000 WMI_EXTENSION_EVENTID,
2001 WMI_CAC_EVENTID,
2002 WMI_SNR_THRESHOLD_EVENTID,
2003 WMI_LQ_THRESHOLD_EVENTID,
2004 WMI_TX_RETRY_ERR_EVENTID, /* 0x1014 */
2005 WMI_REPORT_ROAM_DATA_EVENTID,
2006 WMI_TEST_EVENTID,
2007 WMI_APLIST_EVENTID,
2008 WMI_GET_WOW_LIST_EVENTID,
2009 WMI_GET_PMKID_LIST_EVENTID,
2010 WMI_CHANNEL_CHANGE_EVENTID,
2011 WMI_PEER_NODE_EVENTID,
2012 WMI_PSPOLL_EVENTID,
2013 WMI_DTIMEXPIRY_EVENTID,
2014 WMI_WLAN_VERSION_EVENTID,
2015 WMI_SET_PARAMS_REPLY_EVENTID,
2016 WMI_ADDBA_REQ_EVENTID, /*0x1020 */
2017 WMI_ADDBA_RESP_EVENTID,
2018 WMI_DELBA_REQ_EVENTID,
2019 WMI_TX_COMPLETE_EVENTID,
2020 WMI_HCI_EVENT_EVENTID,
2021 WMI_ACL_DATA_EVENTID,
2022 WMI_REPORT_SLEEP_STATE_EVENTID,
2023#ifdef WAPI_ENABLE
2024 WMI_WAPI_REKEY_EVENTID,
2025#endif
2026 WMI_REPORT_BTCOEX_STATS_EVENTID,
2027 WMI_REPORT_BTCOEX_CONFIG_EVENTID,
2028 WMI_GET_PMK_EVENTID,
2029
2030 /* DFS Events */
2031 WMI_DFS_HOST_ATTACH_EVENTID,
2032 WMI_DFS_HOST_INIT_EVENTID,
2033 WMI_DFS_RESET_DELAYLINES_EVENTID,
2034 WMI_DFS_RESET_RADARQ_EVENTID,
2035 WMI_DFS_RESET_AR_EVENTID,
2036 WMI_DFS_RESET_ARQ_EVENTID,
2037 WMI_DFS_SET_DUR_MULTIPLIER_EVENTID,
2038 WMI_DFS_SET_BANGRADAR_EVENTID,
2039 WMI_DFS_SET_DEBUGLEVEL_EVENTID,
2040 WMI_DFS_PHYERR_EVENTID,
2041 /* CCX Evants */
2042 WMI_CCX_RM_STATUS_EVENTID,
2043
2044 /* P2P Events */
2045 WMI_P2P_GO_NEG_RESULT_EVENTID,
2046
2047 WMI_WAC_SCAN_DONE_EVENTID,
2048 WMI_WAC_REPORT_BSS_EVENTID,
2049 WMI_WAC_START_WPS_EVENTID,
2050 WMI_WAC_CTRL_REQ_REPLY_EVENTID,
2051
2052 /* RFKILL Events */
2053 WMI_RFKILL_STATE_CHANGE_EVENTID,
2054 WMI_RFKILL_GET_MODE_CMD_EVENTID,
2055 WMI_THIN_RESERVED_START_EVENTID = 0x8000,
2056
2057 /*
2058 * Events in this range are reserved for thinmode
2059 * See wmi_thin.h for actual definitions
2060 */
2061 WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
2062
2063 WMI_SET_CHANNEL_EVENTID,
2064 WMI_ASSOC_REQ_EVENTID,
2065
2066 /* generic ACS event */
2067 WMI_ACS_EVENTID,
2068 WMI_REPORT_WMM_PARAMS_EVENTID
2069} WMI_EVENT_ID;
2070
2071
2072typedef enum {
2073 WMI_11A_CAPABILITY = 1,
2074 WMI_11G_CAPABILITY = 2,
2075 WMI_11AG_CAPABILITY = 3,
2076 WMI_11NA_CAPABILITY = 4,
2077 WMI_11NG_CAPABILITY = 5,
2078 WMI_11NAG_CAPABILITY = 6,
2079 // END CAPABILITY
2080 WMI_11N_CAPABILITY_OFFSET = (WMI_11NA_CAPABILITY - WMI_11A_CAPABILITY),
2081} WMI_PHY_CAPABILITY;
2082
2083typedef PREPACK struct {
2084 u8 macaddr[ATH_MAC_LEN];
2085 u8 phyCapability; /* WMI_PHY_CAPABILITY */
2086} POSTPACK WMI_READY_EVENT_1;
2087
2088typedef PREPACK struct {
2089 u32 sw_version;
2090 u32 abi_version;
2091 u8 macaddr[ATH_MAC_LEN];
2092 u8 phyCapability; /* WMI_PHY_CAPABILITY */
2093} POSTPACK WMI_READY_EVENT_2;
2094
2095#if defined(ATH_TARGET)
2096#ifdef AR6002_REV2
2097#define WMI_READY_EVENT WMI_READY_EVENT_1 /* AR6002_REV2 target code */
2098#else
2099#define WMI_READY_EVENT WMI_READY_EVENT_2 /* AR6001, AR6002_REV4, AR6002_REV5 */
2100#endif
2101#else
2102#define WMI_READY_EVENT WMI_READY_EVENT_2 /* host code */
2103#endif
2104
2105
2106/*
2107 * Connect Event
2108 */
2109typedef PREPACK struct {
2110 u16 channel;
2111 u8 bssid[ATH_MAC_LEN];
2112 u16 listenInterval;
2113 u16 beaconInterval;
2114 u32 networkType;
2115 u8 beaconIeLen;
2116 u8 assocReqLen;
2117 u8 assocRespLen;
2118 u8 assocInfo[1];
2119} POSTPACK WMI_CONNECT_EVENT;
2120
2121/*
2122 * Disconnect Event
2123 */
2124typedef enum {
2125 NO_NETWORK_AVAIL = 0x01,
2126 LOST_LINK = 0x02, /* bmiss */
2127 DISCONNECT_CMD = 0x03,
2128 BSS_DISCONNECTED = 0x04,
2129 AUTH_FAILED = 0x05,
2130 ASSOC_FAILED = 0x06,
2131 NO_RESOURCES_AVAIL = 0x07,
2132 CSERV_DISCONNECT = 0x08,
2133 INVALID_PROFILE = 0x0a,
2134 DOT11H_CHANNEL_SWITCH = 0x0b,
2135 PROFILE_MISMATCH = 0x0c,
2136 CONNECTION_EVICTED = 0x0d,
2137 IBSS_MERGE = 0xe,
2138} WMI_DISCONNECT_REASON;
2139
2140typedef PREPACK struct {
2141 u16 protocolReasonStatus; /* reason code, see 802.11 spec. */
2142 u8 bssid[ATH_MAC_LEN]; /* set if known */
2143 u8 disconnectReason ; /* see WMI_DISCONNECT_REASON */
2144 u8 assocRespLen;
2145 u8 assocInfo[1];
2146} POSTPACK WMI_DISCONNECT_EVENT;
2147
2148/*
2149 * BSS Info Event.
2150 * Mechanism used to inform host of the presence and characteristic of
2151 * wireless networks present. Consists of bss info header followed by
2152 * the beacon or probe-response frame body. The 802.11 header is not included.
2153 */
2154typedef enum {
2155 BEACON_FTYPE = 0x1,
2156 PROBERESP_FTYPE,
2157 ACTION_MGMT_FTYPE,
2158 PROBEREQ_FTYPE,
2159} WMI_BI_FTYPE;
2160
2161enum {
2162 BSS_ELEMID_CHANSWITCH = 0x01,
2163 BSS_ELEMID_ATHEROS = 0x02,
2164};
2165
2166typedef PREPACK struct {
2167 u16 channel;
2168 u8 frameType; /* see WMI_BI_FTYPE */
2169 u8 snr;
2170 s16 rssi;
2171 u8 bssid[ATH_MAC_LEN];
2172 u32 ieMask;
2173} POSTPACK WMI_BSS_INFO_HDR;
2174
2175/*
2176 * BSS INFO HDR version 2.0
2177 * With 6 bytes HTC header and 6 bytes of WMI header
2178 * WMI_BSS_INFO_HDR cannot be accommodated in the removed 802.11 management
2179 * header space.
2180 * - Reduce the ieMask to 2 bytes as only two bit flags are used
2181 * - Remove rssi and compute it on the host. rssi = snr - 95
2182 */
2183typedef PREPACK struct {
2184 u16 channel;
2185 u8 frameType; /* see WMI_BI_FTYPE */
2186 u8 snr;
2187 u8 bssid[ATH_MAC_LEN];
2188 u16 ieMask;
2189} POSTPACK WMI_BSS_INFO_HDR2;
2190
2191/*
2192 * Command Error Event
2193 */
2194typedef enum {
2195 INVALID_PARAM = 0x01,
2196 ILLEGAL_STATE = 0x02,
2197 INTERNAL_ERROR = 0x03,
2198} WMI_ERROR_CODE;
2199
2200typedef PREPACK struct {
2201 u16 commandId;
2202 u8 errorCode;
2203} POSTPACK WMI_CMD_ERROR_EVENT;
2204
2205/*
2206 * New Regulatory Domain Event
2207 */
2208typedef PREPACK struct {
2209 u32 regDomain;
2210} POSTPACK WMI_REG_DOMAIN_EVENT;
2211
2212typedef PREPACK struct {
2213 u8 txQueueNumber;
2214 u8 rxQueueNumber;
2215 u8 trafficDirection;
2216 u8 trafficClass;
2217} POSTPACK WMI_PSTREAM_TIMEOUT_EVENT;
2218
2219typedef PREPACK struct {
2220 u8 reserve1;
2221 u8 reserve2;
2222 u8 reserve3;
2223 u8 trafficClass;
2224} POSTPACK WMI_ACM_REJECT_EVENT;
2225
2226/*
2227 * The WMI_NEIGHBOR_REPORT Event is generated by the target to inform
2228 * the host of BSS's it has found that matches the current profile.
2229 * It can be used by the host to cache PMKs and/to initiate pre-authentication
2230 * if the BSS supports it. The first bssid is always the current associated
2231 * BSS.
2232 * The bssid and bssFlags information repeats according to the number
2233 * or APs reported.
2234 */
2235typedef enum {
2236 WMI_DEFAULT_BSS_FLAGS = 0x00,
2237 WMI_PREAUTH_CAPABLE_BSS = 0x01,
2238 WMI_PMKID_VALID_BSS = 0x02,
2239} WMI_BSS_FLAGS;
2240
2241typedef PREPACK struct {
2242 u8 bssid[ATH_MAC_LEN];
2243 u8 bssFlags; /* see WMI_BSS_FLAGS */
2244} POSTPACK WMI_NEIGHBOR_INFO;
2245
2246typedef PREPACK struct {
2247 s8 numberOfAps;
2248 WMI_NEIGHBOR_INFO neighbor[1];
2249} POSTPACK WMI_NEIGHBOR_REPORT_EVENT;
2250
2251/*
2252 * TKIP MIC Error Event
2253 */
2254typedef PREPACK struct {
2255 u8 keyid;
2256 u8 ismcast;
2257} POSTPACK WMI_TKIP_MICERR_EVENT;
2258
2259/*
2260 * WMI_SCAN_COMPLETE_EVENTID - no parameters (old), staus parameter (new)
2261 */
2262typedef PREPACK struct {
2263 s32 status;
2264} POSTPACK WMI_SCAN_COMPLETE_EVENT;
2265
2266#define MAX_OPT_DATA_LEN 1400
2267
2268/*
2269 * WMI_SET_ADHOC_BSSID_CMDID
2270 */
2271typedef PREPACK struct {
2272 u8 bssid[ATH_MAC_LEN];
2273} POSTPACK WMI_SET_ADHOC_BSSID_CMD;
2274
2275/*
2276 * WMI_SET_OPT_MODE_CMDID
2277 */
2278typedef enum {
2279 SPECIAL_OFF,
2280 SPECIAL_ON,
2281} OPT_MODE_TYPE;
2282
2283typedef PREPACK struct {
2284 u8 optMode;
2285} POSTPACK WMI_SET_OPT_MODE_CMD;
2286
2287/*
2288 * WMI_TX_OPT_FRAME_CMDID
2289 */
2290typedef enum {
2291 OPT_PROBE_REQ = 0x01,
2292 OPT_PROBE_RESP = 0x02,
2293 OPT_CPPP_START = 0x03,
2294 OPT_CPPP_STOP = 0x04,
2295} WMI_OPT_FTYPE;
2296
2297typedef PREPACK struct {
2298 u16 optIEDataLen;
2299 u8 frmType;
2300 u8 dstAddr[ATH_MAC_LEN];
2301 u8 bssid[ATH_MAC_LEN];
2302 u8 reserved; /* For alignment */
2303 u8 optIEData[1];
2304} POSTPACK WMI_OPT_TX_FRAME_CMD;
2305
2306/*
2307 * Special frame receive Event.
2308 * Mechanism used to inform host of the receiption of the special frames.
2309 * Consists of special frame info header followed by special frame body.
2310 * The 802.11 header is not included.
2311 */
2312typedef PREPACK struct {
2313 u16 channel;
2314 u8 frameType; /* see WMI_OPT_FTYPE */
2315 s8 snr;
2316 u8 srcAddr[ATH_MAC_LEN];
2317 u8 bssid[ATH_MAC_LEN];
2318} POSTPACK WMI_OPT_RX_INFO_HDR;
2319
2320/*
2321 * Reporting statistics.
2322 */
2323typedef PREPACK struct {
2324 u32 tx_packets;
2325 u32 tx_bytes;
2326 u32 tx_unicast_pkts;
2327 u32 tx_unicast_bytes;
2328 u32 tx_multicast_pkts;
2329 u32 tx_multicast_bytes;
2330 u32 tx_broadcast_pkts;
2331 u32 tx_broadcast_bytes;
2332 u32 tx_rts_success_cnt;
2333 u32 tx_packet_per_ac[4];
2334 u32 tx_errors_per_ac[4];
2335
2336 u32 tx_errors;
2337 u32 tx_failed_cnt;
2338 u32 tx_retry_cnt;
2339 u32 tx_mult_retry_cnt;
2340 u32 tx_rts_fail_cnt;
2341 s32 tx_unicast_rate;
2342}POSTPACK tx_stats_t;
2343
2344typedef PREPACK struct {
2345 u32 rx_packets;
2346 u32 rx_bytes;
2347 u32 rx_unicast_pkts;
2348 u32 rx_unicast_bytes;
2349 u32 rx_multicast_pkts;
2350 u32 rx_multicast_bytes;
2351 u32 rx_broadcast_pkts;
2352 u32 rx_broadcast_bytes;
2353 u32 rx_fragment_pkt;
2354
2355 u32 rx_errors;
2356 u32 rx_crcerr;
2357 u32 rx_key_cache_miss;
2358 u32 rx_decrypt_err;
2359 u32 rx_duplicate_frames;
2360 s32 rx_unicast_rate;
2361}POSTPACK rx_stats_t;
2362
2363typedef PREPACK struct {
2364 u32 tkip_local_mic_failure;
2365 u32 tkip_counter_measures_invoked;
2366 u32 tkip_replays;
2367 u32 tkip_format_errors;
2368 u32 ccmp_format_errors;
2369 u32 ccmp_replays;
2370}POSTPACK tkip_ccmp_stats_t;
2371
2372typedef PREPACK struct {
2373 u32 power_save_failure_cnt;
2374 u16 stop_tx_failure_cnt;
2375 u16 atim_tx_failure_cnt;
2376 u16 atim_rx_failure_cnt;
2377 u16 bcn_rx_failure_cnt;
2378}POSTPACK pm_stats_t;
2379
2380typedef PREPACK struct {
2381 u32 cs_bmiss_cnt;
2382 u32 cs_lowRssi_cnt;
2383 u16 cs_connect_cnt;
2384 u16 cs_disconnect_cnt;
2385 s16 cs_aveBeacon_rssi;
2386 u16 cs_roam_count;
2387 s16 cs_rssi;
2388 u8 cs_snr;
2389 u8 cs_aveBeacon_snr;
2390 u8 cs_lastRoam_msec;
2391} POSTPACK cserv_stats_t;
2392
2393typedef PREPACK struct {
2394 tx_stats_t tx_stats;
2395 rx_stats_t rx_stats;
2396 tkip_ccmp_stats_t tkipCcmpStats;
2397}POSTPACK wlan_net_stats_t;
2398
2399typedef PREPACK struct {
2400 u32 arp_received;
2401 u32 arp_matched;
2402 u32 arp_replied;
2403} POSTPACK arp_stats_t;
2404
2405typedef PREPACK struct {
2406 u32 wow_num_pkts_dropped;
2407 u16 wow_num_events_discarded;
2408 u8 wow_num_host_pkt_wakeups;
2409 u8 wow_num_host_event_wakeups;
2410} POSTPACK wlan_wow_stats_t;
2411
2412typedef PREPACK struct {
2413 u32 lqVal;
2414 s32 noise_floor_calibation;
2415 pm_stats_t pmStats;
2416 wlan_net_stats_t txrxStats;
2417 wlan_wow_stats_t wowStats;
2418 arp_stats_t arpStats;
2419 cserv_stats_t cservStats;
2420} POSTPACK WMI_TARGET_STATS;
2421
2422/*
2423 * WMI_RSSI_THRESHOLD_EVENTID.
2424 * Indicate the RSSI events to host. Events are indicated when we breach a
2425 * thresold value.
2426 */
2427typedef enum{
2428 WMI_RSSI_THRESHOLD1_ABOVE = 0,
2429 WMI_RSSI_THRESHOLD2_ABOVE,
2430 WMI_RSSI_THRESHOLD3_ABOVE,
2431 WMI_RSSI_THRESHOLD4_ABOVE,
2432 WMI_RSSI_THRESHOLD5_ABOVE,
2433 WMI_RSSI_THRESHOLD6_ABOVE,
2434 WMI_RSSI_THRESHOLD1_BELOW,
2435 WMI_RSSI_THRESHOLD2_BELOW,
2436 WMI_RSSI_THRESHOLD3_BELOW,
2437 WMI_RSSI_THRESHOLD4_BELOW,
2438 WMI_RSSI_THRESHOLD5_BELOW,
2439 WMI_RSSI_THRESHOLD6_BELOW
2440}WMI_RSSI_THRESHOLD_VAL;
2441
2442typedef PREPACK struct {
2443 s16 rssi;
2444 u8 range;
2445}POSTPACK WMI_RSSI_THRESHOLD_EVENT;
2446
2447/*
2448 * WMI_ERROR_REPORT_EVENTID
2449 */
2450typedef enum{
2451 WMI_TARGET_PM_ERR_FAIL = 0x00000001,
2452 WMI_TARGET_KEY_NOT_FOUND = 0x00000002,
2453 WMI_TARGET_DECRYPTION_ERR = 0x00000004,
2454 WMI_TARGET_BMISS = 0x00000008,
2455 WMI_PSDISABLE_NODE_JOIN = 0x00000010,
2456 WMI_TARGET_COM_ERR = 0x00000020,
2457 WMI_TARGET_FATAL_ERR = 0x00000040
2458} WMI_TARGET_ERROR_VAL;
2459
2460typedef PREPACK struct {
2461 u32 errorVal;
2462}POSTPACK WMI_TARGET_ERROR_REPORT_EVENT;
2463
2464typedef PREPACK struct {
2465 u8 retrys;
2466}POSTPACK WMI_TX_RETRY_ERR_EVENT;
2467
2468typedef enum{
2469 WMI_SNR_THRESHOLD1_ABOVE = 1,
2470 WMI_SNR_THRESHOLD1_BELOW,
2471 WMI_SNR_THRESHOLD2_ABOVE,
2472 WMI_SNR_THRESHOLD2_BELOW,
2473 WMI_SNR_THRESHOLD3_ABOVE,
2474 WMI_SNR_THRESHOLD3_BELOW,
2475 WMI_SNR_THRESHOLD4_ABOVE,
2476 WMI_SNR_THRESHOLD4_BELOW
2477} WMI_SNR_THRESHOLD_VAL;
2478
2479typedef PREPACK struct {
2480 u8 range; /* WMI_SNR_THRESHOLD_VAL */
2481 u8 snr;
2482}POSTPACK WMI_SNR_THRESHOLD_EVENT;
2483
2484typedef enum{
2485 WMI_LQ_THRESHOLD1_ABOVE = 1,
2486 WMI_LQ_THRESHOLD1_BELOW,
2487 WMI_LQ_THRESHOLD2_ABOVE,
2488 WMI_LQ_THRESHOLD2_BELOW,
2489 WMI_LQ_THRESHOLD3_ABOVE,
2490 WMI_LQ_THRESHOLD3_BELOW,
2491 WMI_LQ_THRESHOLD4_ABOVE,
2492 WMI_LQ_THRESHOLD4_BELOW
2493} WMI_LQ_THRESHOLD_VAL;
2494
2495typedef PREPACK struct {
2496 s32 lq;
2497 u8 range; /* WMI_LQ_THRESHOLD_VAL */
2498}POSTPACK WMI_LQ_THRESHOLD_EVENT;
2499/*
2500 * WMI_REPORT_ROAM_TBL_EVENTID
2501 */
2502#define MAX_ROAM_TBL_CAND 5
2503
2504typedef PREPACK struct {
2505 s32 roam_util;
2506 u8 bssid[ATH_MAC_LEN];
2507 s8 rssi;
2508 s8 rssidt;
2509 s8 last_rssi;
2510 s8 util;
2511 s8 bias;
2512 u8 reserved; /* For alignment */
2513} POSTPACK WMI_BSS_ROAM_INFO;
2514
2515
2516typedef PREPACK struct {
2517 u16 roamMode;
2518 u16 numEntries;
2519 WMI_BSS_ROAM_INFO bssRoamInfo[1];
2520} POSTPACK WMI_TARGET_ROAM_TBL;
2521
2522/*
2523 * WMI_HCI_EVENT_EVENTID
2524 */
2525typedef PREPACK struct {
2526 u16 evt_buf_sz; /* HCI event buffer size */
2527 u8 buf[1]; /* HCI event */
2528} POSTPACK WMI_HCI_EVENT;
2529
2530/*
2531 * WMI_CAC_EVENTID
2532 */
2533typedef enum {
2534 CAC_INDICATION_ADMISSION = 0x00,
2535 CAC_INDICATION_ADMISSION_RESP = 0x01,
2536 CAC_INDICATION_DELETE = 0x02,
2537 CAC_INDICATION_NO_RESP = 0x03,
2538}CAC_INDICATION;
2539
2540#define WMM_TSPEC_IE_LEN 63
2541
2542typedef PREPACK struct {
2543 u8 ac;
2544 u8 cac_indication;
2545 u8 statusCode;
2546 u8 tspecSuggestion[WMM_TSPEC_IE_LEN];
2547}POSTPACK WMI_CAC_EVENT;
2548
2549/*
2550 * WMI_APLIST_EVENTID
2551 */
2552
2553typedef enum {
2554 APLIST_VER1 = 1,
2555} APLIST_VER;
2556
2557typedef PREPACK struct {
2558 u8 bssid[ATH_MAC_LEN];
2559 u16 channel;
2560} POSTPACK WMI_AP_INFO_V1;
2561
2562typedef PREPACK union {
2563 WMI_AP_INFO_V1 apInfoV1;
2564} POSTPACK WMI_AP_INFO;
2565
2566typedef PREPACK struct {
2567 u8 apListVer;
2568 u8 numAP;
2569 WMI_AP_INFO apList[1];
2570} POSTPACK WMI_APLIST_EVENT;
2571
2572/*
2573 * developer commands
2574 */
2575
2576/*
2577 * WMI_SET_BITRATE_CMDID
2578 *
2579 * Get bit rate cmd uses same definition as set bit rate cmd
2580 */
2581typedef enum {
2582 RATE_AUTO = -1,
2583 RATE_1Mb = 0,
2584 RATE_2Mb = 1,
2585 RATE_5_5Mb = 2,
2586 RATE_11Mb = 3,
2587 RATE_6Mb = 4,
2588 RATE_9Mb = 5,
2589 RATE_12Mb = 6,
2590 RATE_18Mb = 7,
2591 RATE_24Mb = 8,
2592 RATE_36Mb = 9,
2593 RATE_48Mb = 10,
2594 RATE_54Mb = 11,
2595 RATE_MCS_0_20 = 12,
2596 RATE_MCS_1_20 = 13,
2597 RATE_MCS_2_20 = 14,
2598 RATE_MCS_3_20 = 15,
2599 RATE_MCS_4_20 = 16,
2600 RATE_MCS_5_20 = 17,
2601 RATE_MCS_6_20 = 18,
2602 RATE_MCS_7_20 = 19,
2603 RATE_MCS_0_40 = 20,
2604 RATE_MCS_1_40 = 21,
2605 RATE_MCS_2_40 = 22,
2606 RATE_MCS_3_40 = 23,
2607 RATE_MCS_4_40 = 24,
2608 RATE_MCS_5_40 = 25,
2609 RATE_MCS_6_40 = 26,
2610 RATE_MCS_7_40 = 27,
2611} WMI_BIT_RATE;
2612
2613typedef PREPACK struct {
2614 s8 rateIndex; /* see WMI_BIT_RATE */
2615 s8 mgmtRateIndex;
2616 s8 ctlRateIndex;
2617} POSTPACK WMI_BIT_RATE_CMD;
2618
2619
2620typedef PREPACK struct {
2621 s8 rateIndex; /* see WMI_BIT_RATE */
2622} POSTPACK WMI_BIT_RATE_REPLY;
2623
2624
2625/*
2626 * WMI_SET_FIXRATES_CMDID
2627 *
2628 * Get fix rates cmd uses same definition as set fix rates cmd
2629 */
2630#define FIX_RATE_1Mb ((u32)0x1)
2631#define FIX_RATE_2Mb ((u32)0x2)
2632#define FIX_RATE_5_5Mb ((u32)0x4)
2633#define FIX_RATE_11Mb ((u32)0x8)
2634#define FIX_RATE_6Mb ((u32)0x10)
2635#define FIX_RATE_9Mb ((u32)0x20)
2636#define FIX_RATE_12Mb ((u32)0x40)
2637#define FIX_RATE_18Mb ((u32)0x80)
2638#define FIX_RATE_24Mb ((u32)0x100)
2639#define FIX_RATE_36Mb ((u32)0x200)
2640#define FIX_RATE_48Mb ((u32)0x400)
2641#define FIX_RATE_54Mb ((u32)0x800)
2642#define FIX_RATE_MCS_0_20 ((u32)0x1000)
2643#define FIX_RATE_MCS_1_20 ((u32)0x2000)
2644#define FIX_RATE_MCS_2_20 ((u32)0x4000)
2645#define FIX_RATE_MCS_3_20 ((u32)0x8000)
2646#define FIX_RATE_MCS_4_20 ((u32)0x10000)
2647#define FIX_RATE_MCS_5_20 ((u32)0x20000)
2648#define FIX_RATE_MCS_6_20 ((u32)0x40000)
2649#define FIX_RATE_MCS_7_20 ((u32)0x80000)
2650#define FIX_RATE_MCS_0_40 ((u32)0x100000)
2651#define FIX_RATE_MCS_1_40 ((u32)0x200000)
2652#define FIX_RATE_MCS_2_40 ((u32)0x400000)
2653#define FIX_RATE_MCS_3_40 ((u32)0x800000)
2654#define FIX_RATE_MCS_4_40 ((u32)0x1000000)
2655#define FIX_RATE_MCS_5_40 ((u32)0x2000000)
2656#define FIX_RATE_MCS_6_40 ((u32)0x4000000)
2657#define FIX_RATE_MCS_7_40 ((u32)0x8000000)
2658
2659typedef PREPACK struct {
2660 u32 fixRateMask; /* see WMI_BIT_RATE */
2661} POSTPACK WMI_FIX_RATES_CMD, WMI_FIX_RATES_REPLY;
2662
2663typedef PREPACK struct {
2664 u8 bEnableMask;
2665 u8 frameType; /*type and subtype*/
2666 u32 frameRateMask; /* see WMI_BIT_RATE */
2667} POSTPACK WMI_FRAME_RATES_CMD, WMI_FRAME_RATES_REPLY;
2668
2669/*
2670 * WMI_SET_RECONNECT_AUTH_MODE_CMDID
2671 *
2672 * Set authentication mode
2673 */
2674typedef enum {
2675 RECONN_DO_AUTH = 0x00,
2676 RECONN_NOT_AUTH = 0x01
2677} WMI_AUTH_MODE;
2678
2679typedef PREPACK struct {
2680 u8 mode;
2681} POSTPACK WMI_SET_AUTH_MODE_CMD;
2682
2683/*
2684 * WMI_SET_REASSOC_MODE_CMDID
2685 *
2686 * Set authentication mode
2687 */
2688typedef enum {
2689 REASSOC_DO_DISASSOC = 0x00,
2690 REASSOC_DONOT_DISASSOC = 0x01
2691} WMI_REASSOC_MODE;
2692
2693typedef PREPACK struct {
2694 u8 mode;
2695}POSTPACK WMI_SET_REASSOC_MODE_CMD;
2696
2697typedef enum {
2698 ROAM_DATA_TIME = 1, /* Get The Roam Time Data */
2699} ROAM_DATA_TYPE;
2700
2701typedef PREPACK struct {
2702 u32 disassoc_time;
2703 u32 no_txrx_time;
2704 u32 assoc_time;
2705 u32 allow_txrx_time;
2706 u8 disassoc_bssid[ATH_MAC_LEN];
2707 s8 disassoc_bss_rssi;
2708 u8 assoc_bssid[ATH_MAC_LEN];
2709 s8 assoc_bss_rssi;
2710} POSTPACK WMI_TARGET_ROAM_TIME;
2711
2712typedef PREPACK struct {
2713 PREPACK union {
2714 WMI_TARGET_ROAM_TIME roamTime;
2715 } POSTPACK u;
2716 u8 roamDataType ;
2717} POSTPACK WMI_TARGET_ROAM_DATA;
2718
2719typedef enum {
2720 WMI_WMM_DISABLED = 0,
2721 WMI_WMM_ENABLED
2722} WMI_WMM_STATUS;
2723
2724typedef PREPACK struct {
2725 u8 status;
2726}POSTPACK WMI_SET_WMM_CMD;
2727
2728typedef PREPACK struct {
2729 u8 status;
2730}POSTPACK WMI_SET_QOS_SUPP_CMD;
2731
2732typedef enum {
2733 WMI_TXOP_DISABLED = 0,
2734 WMI_TXOP_ENABLED
2735} WMI_TXOP_CFG;
2736
2737typedef PREPACK struct {
2738 u8 txopEnable;
2739}POSTPACK WMI_SET_WMM_TXOP_CMD;
2740
2741typedef PREPACK struct {
2742 u8 keepaliveInterval;
2743} POSTPACK WMI_SET_KEEPALIVE_CMD;
2744
2745typedef PREPACK struct {
2746 u32 configured;
2747 u8 keepaliveInterval;
2748} POSTPACK WMI_GET_KEEPALIVE_CMD;
2749
2750/*
2751 * Add Application specified IE to a management frame
2752 */
2753#define WMI_MAX_IE_LEN 255
2754
2755typedef PREPACK struct {
2756 u8 mgmtFrmType; /* one of WMI_MGMT_FRAME_TYPE */
2757 u8 ieLen; /* Length of the IE that should be added to the MGMT frame */
2758 u8 ieInfo[1];
2759} POSTPACK WMI_SET_APPIE_CMD;
2760
2761/*
2762 * Notify the WSC registration status to the target
2763 */
2764#define WSC_REG_ACTIVE 1
2765#define WSC_REG_INACTIVE 0
2766/* Generic Hal Interface for setting hal paramters. */
2767/* Add new Set HAL Param cmdIds here for newer params */
2768typedef enum {
2769 WHAL_SETCABTO_CMDID = 1,
2770}WHAL_CMDID;
2771
2772typedef PREPACK struct {
2773 u8 cabTimeOut;
2774} POSTPACK WHAL_SETCABTO_PARAM;
2775
2776typedef PREPACK struct {
2777 u8 whalCmdId;
2778 u8 data[1];
2779} POSTPACK WHAL_PARAMCMD;
2780
2781
2782#define WOW_MAX_FILTER_LISTS 1 /*4*/
2783#define WOW_MAX_FILTERS_PER_LIST 4
2784#define WOW_PATTERN_SIZE 64
2785#define WOW_MASK_SIZE 64
2786
2787#define MAC_MAX_FILTERS_PER_LIST 4
2788
2789typedef PREPACK struct {
2790 u8 wow_valid_filter;
2791 u8 wow_filter_id;
2792 u8 wow_filter_size;
2793 u8 wow_filter_offset;
2794 u8 wow_filter_mask[WOW_MASK_SIZE];
2795 u8 wow_filter_pattern[WOW_PATTERN_SIZE];
2796} POSTPACK WOW_FILTER;
2797
2798
2799typedef PREPACK struct {
2800 u8 wow_valid_list;
2801 u8 wow_list_id;
2802 u8 wow_num_filters;
2803 u8 wow_total_list_size;
2804 WOW_FILTER list[WOW_MAX_FILTERS_PER_LIST];
2805} POSTPACK WOW_FILTER_LIST;
2806
2807typedef PREPACK struct {
2808 u8 valid_filter;
2809 u8 mac_addr[ATH_MAC_LEN];
2810} POSTPACK MAC_FILTER;
2811
2812
2813typedef PREPACK struct {
2814 u8 total_list_size;
2815 u8 enable;
2816 MAC_FILTER list[MAC_MAX_FILTERS_PER_LIST];
2817} POSTPACK MAC_FILTER_LIST;
2818
2819#define MAX_IP_ADDRS 2
2820typedef PREPACK struct {
2821 u32 ips[MAX_IP_ADDRS]; /* IP in Network Byte Order */
2822} POSTPACK WMI_SET_IP_CMD;
2823
2824typedef PREPACK struct {
2825 u32 awake;
2826 u32 asleep;
2827} POSTPACK WMI_SET_HOST_SLEEP_MODE_CMD;
2828
2829typedef enum {
2830 WOW_FILTER_SSID = 0x1
2831} WMI_WOW_FILTER;
2832
2833typedef PREPACK struct {
2834 u32 enable_wow;
2835 WMI_WOW_FILTER filter;
2836 u16 hostReqDelay;
2837} POSTPACK WMI_SET_WOW_MODE_CMD;
2838
2839typedef PREPACK struct {
2840 u8 filter_list_id;
2841} POSTPACK WMI_GET_WOW_LIST_CMD;
2842
2843/*
2844 * WMI_GET_WOW_LIST_CMD reply
2845 */
2846typedef PREPACK struct {
2847 u8 num_filters; /* number of patterns in reply */
2848 u8 this_filter_num; /* this is filter # x of total num_filters */
2849 u8 wow_mode;
2850 u8 host_mode;
2851 WOW_FILTER wow_filters[1];
2852} POSTPACK WMI_GET_WOW_LIST_REPLY;
2853
2854typedef PREPACK struct {
2855 u8 filter_list_id;
2856 u8 filter_size;
2857 u8 filter_offset;
2858 u8 filter[1];
2859} POSTPACK WMI_ADD_WOW_PATTERN_CMD;
2860
2861typedef PREPACK struct {
2862 u16 filter_list_id;
2863 u16 filter_id;
2864} POSTPACK WMI_DEL_WOW_PATTERN_CMD;
2865
2866typedef PREPACK struct {
2867 u8 macaddr[ATH_MAC_LEN];
2868} POSTPACK WMI_SET_MAC_ADDRESS_CMD;
2869
2870/*
2871 * WMI_SET_AKMP_PARAMS_CMD
2872 */
2873
2874#define WMI_AKMP_MULTI_PMKID_EN 0x000001
2875
2876typedef PREPACK struct {
2877 u32 akmpInfo;
2878} POSTPACK WMI_SET_AKMP_PARAMS_CMD;
2879
2880typedef PREPACK struct {
2881 u8 pmkid[WMI_PMKID_LEN];
2882} POSTPACK WMI_PMKID;
2883
2884/*
2885 * WMI_SET_PMKID_LIST_CMD
2886 */
2887#define WMI_MAX_PMKID_CACHE 8
2888
2889typedef PREPACK struct {
2890 u32 numPMKID;
2891 WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE];
2892} POSTPACK WMI_SET_PMKID_LIST_CMD;
2893
2894/*
2895 * WMI_GET_PMKID_LIST_CMD Reply
2896 * Following the Number of PMKIDs is the list of PMKIDs
2897 */
2898typedef PREPACK struct {
2899 u32 numPMKID;
2900 u8 bssidList[ATH_MAC_LEN][1];
2901 WMI_PMKID pmkidList[1];
2902} POSTPACK WMI_PMKID_LIST_REPLY;
2903
2904typedef PREPACK struct {
2905 u16 oldChannel;
2906 u32 newChannel;
2907} POSTPACK WMI_CHANNEL_CHANGE_EVENT;
2908
2909typedef PREPACK struct {
2910 u32 version;
2911} POSTPACK WMI_WLAN_VERSION_EVENT;
2912
2913
2914/* WMI_ADDBA_REQ_EVENTID */
2915typedef PREPACK struct {
2916 u8 tid;
2917 u8 win_sz;
2918 u16 st_seq_no;
2919 u8 status; /* f/w response for ADDBA Req; OK(0) or failure(!=0) */
2920} POSTPACK WMI_ADDBA_REQ_EVENT;
2921
2922/* WMI_ADDBA_RESP_EVENTID */
2923typedef PREPACK struct {
2924 u8 tid;
2925 u8 status; /* OK(0), failure (!=0) */
2926 u16 amsdu_sz; /* Three values: Not supported(0), 3839, 8k */
2927} POSTPACK WMI_ADDBA_RESP_EVENT;
2928
2929/* WMI_DELBA_EVENTID
2930 * f/w received a DELBA for peer and processed it.
2931 * Host is notified of this
2932 */
2933typedef PREPACK struct {
2934 u8 tid;
2935 u8 is_peer_initiator;
2936 u16 reason_code;
2937} POSTPACK WMI_DELBA_EVENT;
2938
2939
2940#ifdef WAPI_ENABLE
2941#define WAPI_REKEY_UCAST 1
2942#define WAPI_REKEY_MCAST 2
2943typedef PREPACK struct {
2944 u8 type;
2945 u8 macAddr[ATH_MAC_LEN];
2946} POSTPACK WMI_WAPIREKEY_EVENT;
2947#endif
2948
2949
2950/* WMI_ALLOW_AGGR_CMDID
2951 * Configures tid's to allow ADDBA negotiations
2952 * on each tid, in each direction
2953 */
2954typedef PREPACK struct {
2955 u16 tx_allow_aggr; /* 16-bit mask to allow uplink ADDBA negotiation - bit position indicates tid*/
2956 u16 rx_allow_aggr; /* 16-bit mask to allow donwlink ADDBA negotiation - bit position indicates tid*/
2957} POSTPACK WMI_ALLOW_AGGR_CMD;
2958
2959/* WMI_ADDBA_REQ_CMDID
2960 * f/w starts performing ADDBA negotiations with peer
2961 * on the given tid
2962 */
2963typedef PREPACK struct {
2964 u8 tid;
2965} POSTPACK WMI_ADDBA_REQ_CMD;
2966
2967/* WMI_DELBA_REQ_CMDID
2968 * f/w would teardown BA with peer.
2969 * is_send_initiator indicates if it's or tx or rx side
2970 */
2971typedef PREPACK struct {
2972 u8 tid;
2973 u8 is_sender_initiator;
2974
2975} POSTPACK WMI_DELBA_REQ_CMD;
2976
2977#define PEER_NODE_JOIN_EVENT 0x00
2978#define PEER_NODE_LEAVE_EVENT 0x01
2979#define PEER_FIRST_NODE_JOIN_EVENT 0x10
2980#define PEER_LAST_NODE_LEAVE_EVENT 0x11
2981typedef PREPACK struct {
2982 u8 eventCode;
2983 u8 peerMacAddr[ATH_MAC_LEN];
2984} POSTPACK WMI_PEER_NODE_EVENT;
2985
2986#define IEEE80211_FRAME_TYPE_MGT 0x00
2987#define IEEE80211_FRAME_TYPE_CTL 0x04
2988
2989/*
2990 * Transmit complete event data structure(s)
2991 */
2992
2993
2994typedef PREPACK struct {
2995#define TX_COMPLETE_STATUS_SUCCESS 0
2996#define TX_COMPLETE_STATUS_RETRIES 1
2997#define TX_COMPLETE_STATUS_NOLINK 2
2998#define TX_COMPLETE_STATUS_TIMEOUT 3
2999#define TX_COMPLETE_STATUS_OTHER 4
3000
3001 u8 status; /* one of TX_COMPLETE_STATUS_... */
3002 u8 pktID; /* packet ID to identify parent packet */
3003 u8 rateIdx; /* rate index on successful transmission */
3004 u8 ackFailures; /* number of ACK failures in tx attempt */
3005#if 0 /* optional params currently omitted. */
3006 u32 queueDelay; // usec delay measured Tx Start time - host delivery time
3007 u32 mediaDelay; // usec delay measured ACK rx time - host delivery time
3008#endif
3009} POSTPACK TX_COMPLETE_MSG_V1; /* version 1 of tx complete msg */
3010
3011typedef PREPACK struct {
3012 u8 numMessages; /* number of tx comp msgs following this struct */
3013 u8 msgLen; /* length in bytes for each individual msg following this struct */
3014 u8 msgType; /* version of tx complete msg data following this struct */
3015 u8 reserved; /* individual messages follow this header */
3016} POSTPACK WMI_TX_COMPLETE_EVENT;
3017
3018#define WMI_TXCOMPLETE_VERSION_1 (0x01)
3019
3020
3021/*
3022 * ------- AP Mode definitions --------------
3023 */
3024
3025/*
3026 * !!! Warning !!!
3027 * -Changing the following values needs compilation of both driver and firmware
3028 */
3029#ifdef AR6002_REV2
3030#define AP_MAX_NUM_STA 4
3031#else
3032#define AP_MAX_NUM_STA 8
3033#endif
3034#define AP_ACL_SIZE 10
3035#define IEEE80211_MAX_IE 256
3036#define MCAST_AID 0xFF /* Spl. AID used to set DTIM flag in the beacons */
3037#define DEF_AP_COUNTRY_CODE "US "
3038#define DEF_AP_WMODE_G WMI_11G_MODE
3039#define DEF_AP_WMODE_AG WMI_11AG_MODE
3040#define DEF_AP_DTIM 5
3041#define DEF_BEACON_INTERVAL 100
3042
3043/* AP mode disconnect reasons */
3044#define AP_DISCONNECT_STA_LEFT 101
3045#define AP_DISCONNECT_FROM_HOST 102
3046#define AP_DISCONNECT_COMM_TIMEOUT 103
3047
3048/*
3049 * Used with WMI_AP_HIDDEN_SSID_CMDID
3050 */
3051#define HIDDEN_SSID_FALSE 0
3052#define HIDDEN_SSID_TRUE 1
3053typedef PREPACK struct {
3054 u8 hidden_ssid;
3055} POSTPACK WMI_AP_HIDDEN_SSID_CMD;
3056
3057/*
3058 * Used with WMI_AP_ACL_POLICY_CMDID
3059 */
3060#define AP_ACL_DISABLE 0x00
3061#define AP_ACL_ALLOW_MAC 0x01
3062#define AP_ACL_DENY_MAC 0x02
3063#define AP_ACL_RETAIN_LIST_MASK 0x80
3064typedef PREPACK struct {
3065 u8 policy;
3066} POSTPACK WMI_AP_ACL_POLICY_CMD;
3067
3068/*
3069 * Used with WMI_AP_ACL_MAC_LIST_CMDID
3070 */
3071#define ADD_MAC_ADDR 1
3072#define DEL_MAC_ADDR 2
3073typedef PREPACK struct {
3074 u8 action;
3075 u8 index;
3076 u8 mac[ATH_MAC_LEN];
3077 u8 wildcard;
3078} POSTPACK WMI_AP_ACL_MAC_CMD;
3079
3080typedef PREPACK struct {
3081 u16 index;
3082 u8 acl_mac[AP_ACL_SIZE][ATH_MAC_LEN];
3083 u8 wildcard[AP_ACL_SIZE];
3084 u8 policy;
3085} POSTPACK WMI_AP_ACL;
3086
3087/*
3088 * Used with WMI_AP_SET_NUM_STA_CMDID
3089 */
3090typedef PREPACK struct {
3091 u8 num_sta;
3092} POSTPACK WMI_AP_SET_NUM_STA_CMD;
3093
3094/*
3095 * Used with WMI_AP_SET_MLME_CMDID
3096 */
3097typedef PREPACK struct {
3098 u8 mac[ATH_MAC_LEN];
3099 u16 reason; /* 802.11 reason code */
3100 u8 cmd; /* operation to perform */
3101#define WMI_AP_MLME_ASSOC 1 /* associate station */
3102#define WMI_AP_DISASSOC 2 /* disassociate station */
3103#define WMI_AP_DEAUTH 3 /* deauthenticate station */
3104#define WMI_AP_MLME_AUTHORIZE 4 /* authorize station */
3105#define WMI_AP_MLME_UNAUTHORIZE 5 /* unauthorize station */
3106} POSTPACK WMI_AP_SET_MLME_CMD;
3107
3108typedef PREPACK struct {
3109 u32 period;
3110} POSTPACK WMI_AP_CONN_INACT_CMD;
3111
3112typedef PREPACK struct {
3113 u32 period_min;
3114 u32 dwell_ms;
3115} POSTPACK WMI_AP_PROT_SCAN_TIME_CMD;
3116
3117typedef PREPACK struct {
3118 u32 flag;
3119 u16 aid;
3120} POSTPACK WMI_AP_SET_PVB_CMD;
3121
3122#define WMI_DISABLE_REGULATORY_CODE "FF"
3123
3124typedef PREPACK struct {
3125 u8 countryCode[3];
3126} POSTPACK WMI_AP_SET_COUNTRY_CMD;
3127
3128typedef PREPACK struct {
3129 u8 dtim;
3130} POSTPACK WMI_AP_SET_DTIM_CMD;
3131
3132typedef PREPACK struct {
3133 u8 band; /* specifies which band to apply these values */
3134 u8 enable; /* allows 11n to be disabled on a per band basis */
3135 u8 chan_width_40M_supported;
3136 u8 short_GI_20MHz;
3137 u8 short_GI_40MHz;
3138 u8 intolerance_40MHz;
3139 u8 max_ampdu_len_exp;
3140} POSTPACK WMI_SET_HT_CAP_CMD;
3141
3142typedef PREPACK struct {
3143 u8 sta_chan_width;
3144} POSTPACK WMI_SET_HT_OP_CMD;
3145
3146typedef PREPACK struct {
3147 u32 rateMasks[8];
3148} POSTPACK WMI_SET_TX_SELECT_RATES_CMD;
3149
3150typedef PREPACK struct {
3151 u32 sgiMask;
3152 u8 sgiPERThreshold;
3153} POSTPACK WMI_SET_TX_SGI_PARAM_CMD;
3154
3155#define DEFAULT_SGI_MASK 0x08080000
3156#define DEFAULT_SGI_PER 10
3157
3158typedef PREPACK struct {
3159 u32 rateField; /* 1 bit per rate corresponding to index */
3160 u8 id;
3161 u8 shortTrys;
3162 u8 longTrys;
3163 u8 reserved; /* padding */
3164} POSTPACK WMI_SET_RATE_POLICY_CMD;
3165
3166typedef PREPACK struct {
3167 u8 metaVersion; /* version of meta data for rx packets <0 = default> (0-7 = valid) */
3168 u8 dot11Hdr; /* 1 == leave .11 header intact , 0 == replace .11 header with .3 <default> */
3169 u8 defragOnHost; /* 1 == defragmentation is performed by host, 0 == performed by target <default> */
3170 u8 reserved[1]; /* alignment */
3171} POSTPACK WMI_RX_FRAME_FORMAT_CMD;
3172
3173
3174typedef PREPACK struct {
3175 u8 enable; /* 1 == device operates in thin mode , 0 == normal mode <default> */
3176 u8 reserved[3];
3177} POSTPACK WMI_SET_THIN_MODE_CMD;
3178
3179/* AP mode events */
3180/* WMI_PS_POLL_EVENT */
3181typedef PREPACK struct {
3182 u16 aid;
3183} POSTPACK WMI_PSPOLL_EVENT;
3184
3185typedef PREPACK struct {
3186 u32 tx_bytes;
3187 u32 tx_pkts;
3188 u32 tx_error;
3189 u32 tx_discard;
3190 u32 rx_bytes;
3191 u32 rx_pkts;
3192 u32 rx_error;
3193 u32 rx_discard;
3194 u32 aid;
3195} POSTPACK WMI_PER_STA_STAT;
3196
3197#define AP_GET_STATS 0
3198#define AP_CLEAR_STATS 1
3199
3200typedef PREPACK struct {
3201 u32 action;
3202 WMI_PER_STA_STAT sta[AP_MAX_NUM_STA+1];
3203} POSTPACK WMI_AP_MODE_STAT;
3204#define WMI_AP_MODE_STAT_SIZE(numSta) (sizeof(u32) + ((numSta + 1) * sizeof(WMI_PER_STA_STAT)))
3205
3206#define AP_11BG_RATESET1 1
3207#define AP_11BG_RATESET2 2
3208#define DEF_AP_11BG_RATESET AP_11BG_RATESET1
3209typedef PREPACK struct {
3210 u8 rateset;
3211} POSTPACK WMI_AP_SET_11BG_RATESET_CMD;
3212/*
3213 * End of AP mode definitions
3214 */
3215
3216#ifdef __cplusplus
3217}
3218#endif
3219
3220#endif /* _WMI_H_ */
diff --git a/drivers/staging/ath6kl/include/common/wmix.h b/drivers/staging/ath6kl/include/common/wmix.h
deleted file mode 100644
index 9435eab1b7f..00000000000
--- a/drivers/staging/ath6kl/include/common/wmix.h
+++ /dev/null
@@ -1,271 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="wmix.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24/*
25 * This file contains extensions of the WMI protocol specified in the
26 * Wireless Module Interface (WMI). It includes definitions of all
27 * extended commands and events. Extensions include useful commands
28 * that are not directly related to wireless activities. They may
29 * be hardware-specific, and they might not be supported on all
30 * implementations.
31 *
32 * Extended WMIX commands are encapsulated in a WMI message with
33 * cmd=WMI_EXTENSION_CMD.
34 */
35
36#ifndef _WMIX_H_
37#define _WMIX_H_
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43#include "dbglog.h"
44
45/*
46 * Extended WMI commands are those that are needed during wireless
47 * operation, but which are not really wireless commands. This allows,
48 * for instance, platform-specific commands. Extended WMI commands are
49 * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID.
50 * Extended WMI events are similarly embedded in a WMI event message with
51 * WMI_EVENT_ID=WMI_EXTENSION_EVENTID.
52 */
53typedef PREPACK struct {
54 u32 commandId;
55} POSTPACK WMIX_CMD_HDR;
56
57typedef enum {
58 WMIX_DSETOPEN_REPLY_CMDID = 0x2001,
59 WMIX_DSETDATA_REPLY_CMDID,
60 WMIX_GPIO_OUTPUT_SET_CMDID,
61 WMIX_GPIO_INPUT_GET_CMDID,
62 WMIX_GPIO_REGISTER_SET_CMDID,
63 WMIX_GPIO_REGISTER_GET_CMDID,
64 WMIX_GPIO_INTR_ACK_CMDID,
65 WMIX_HB_CHALLENGE_RESP_CMDID,
66 WMIX_DBGLOG_CFG_MODULE_CMDID,
67 WMIX_PROF_CFG_CMDID, /* 0x200a */
68 WMIX_PROF_ADDR_SET_CMDID,
69 WMIX_PROF_START_CMDID,
70 WMIX_PROF_STOP_CMDID,
71 WMIX_PROF_COUNT_GET_CMDID,
72} WMIX_COMMAND_ID;
73
74typedef enum {
75 WMIX_DSETOPENREQ_EVENTID = 0x3001,
76 WMIX_DSETCLOSE_EVENTID,
77 WMIX_DSETDATAREQ_EVENTID,
78 WMIX_GPIO_INTR_EVENTID,
79 WMIX_GPIO_DATA_EVENTID,
80 WMIX_GPIO_ACK_EVENTID,
81 WMIX_HB_CHALLENGE_RESP_EVENTID,
82 WMIX_DBGLOG_EVENTID,
83 WMIX_PROF_COUNT_EVENTID,
84} WMIX_EVENT_ID;
85
86/*
87 * =============DataSet support=================
88 */
89
90/*
91 * WMIX_DSETOPENREQ_EVENTID
92 * DataSet Open Request Event
93 */
94typedef PREPACK struct {
95 u32 dset_id;
96 u32 targ_dset_handle; /* echo'ed, not used by Host, */
97 u32 targ_reply_fn; /* echo'ed, not used by Host, */
98 u32 targ_reply_arg; /* echo'ed, not used by Host, */
99} POSTPACK WMIX_DSETOPENREQ_EVENT;
100
101/*
102 * WMIX_DSETCLOSE_EVENTID
103 * DataSet Close Event
104 */
105typedef PREPACK struct {
106 u32 access_cookie;
107} POSTPACK WMIX_DSETCLOSE_EVENT;
108
109/*
110 * WMIX_DSETDATAREQ_EVENTID
111 * DataSet Data Request Event
112 */
113typedef PREPACK struct {
114 u32 access_cookie;
115 u32 offset;
116 u32 length;
117 u32 targ_buf; /* echo'ed, not used by Host, */
118 u32 targ_reply_fn; /* echo'ed, not used by Host, */
119 u32 targ_reply_arg; /* echo'ed, not used by Host, */
120} POSTPACK WMIX_DSETDATAREQ_EVENT;
121
122typedef PREPACK struct {
123 u32 status;
124 u32 targ_dset_handle;
125 u32 targ_reply_fn;
126 u32 targ_reply_arg;
127 u32 access_cookie;
128 u32 size;
129 u32 version;
130} POSTPACK WMIX_DSETOPEN_REPLY_CMD;
131
132typedef PREPACK struct {
133 u32 status;
134 u32 targ_buf;
135 u32 targ_reply_fn;
136 u32 targ_reply_arg;
137 u32 length;
138 u8 buf[1];
139} POSTPACK WMIX_DSETDATA_REPLY_CMD;
140
141
142/*
143 * =============GPIO support=================
144 * All masks are 18-bit masks with bit N operating on GPIO pin N.
145 */
146
147
148/*
149 * Set GPIO pin output state.
150 * In order for output to be driven, a pin must be enabled for output.
151 * This can be done during initialization through the GPIO Configuration
152 * DataSet, or during operation with the enable_mask.
153 *
154 * If a request is made to simultaneously set/clear or set/disable or
155 * clear/disable or disable/enable, results are undefined.
156 */
157typedef PREPACK struct {
158 u32 set_mask; /* pins to set */
159 u32 clear_mask; /* pins to clear */
160 u32 enable_mask; /* pins to enable for output */
161 u32 disable_mask; /* pins to disable/tristate */
162} POSTPACK WMIX_GPIO_OUTPUT_SET_CMD;
163
164/*
165 * Set a GPIO register. For debug/exceptional cases.
166 * Values for gpioreg_id are GPIO_REGISTER_IDs, defined in a
167 * platform-dependent header.
168 */
169typedef PREPACK struct {
170 u32 gpioreg_id; /* GPIO register ID */
171 u32 value; /* value to write */
172} POSTPACK WMIX_GPIO_REGISTER_SET_CMD;
173
174/* Get a GPIO register. For debug/exceptional cases. */
175typedef PREPACK struct {
176 u32 gpioreg_id; /* GPIO register to read */
177} POSTPACK WMIX_GPIO_REGISTER_GET_CMD;
178
179/*
180 * Host acknowledges and re-arms GPIO interrupts. A single
181 * message should be used to acknowledge all interrupts that
182 * were delivered in an earlier WMIX_GPIO_INTR_EVENT message.
183 */
184typedef PREPACK struct {
185 u32 ack_mask; /* interrupts to acknowledge */
186} POSTPACK WMIX_GPIO_INTR_ACK_CMD;
187
188/*
189 * Target informs Host of GPIO interrupts that have occurred since the
190 * last WMIX_GIPO_INTR_ACK_CMD was received. Additional information --
191 * the current GPIO input values is provided -- in order to support
192 * use of a GPIO interrupt as a Data Valid signal for other GPIO pins.
193 */
194typedef PREPACK struct {
195 u32 intr_mask; /* pending GPIO interrupts */
196 u32 input_values; /* recent GPIO input values */
197} POSTPACK WMIX_GPIO_INTR_EVENT;
198
199/*
200 * Target responds to Host's earlier WMIX_GPIO_INPUT_GET_CMDID request
201 * using a GPIO_DATA_EVENT with
202 * value set to the mask of GPIO pin inputs and
203 * reg_id set to GPIO_ID_NONE
204 *
205 *
206 * Target responds to Hosts's earlier WMIX_GPIO_REGISTER_GET_CMDID request
207 * using a GPIO_DATA_EVENT with
208 * value set to the value of the requested register and
209 * reg_id identifying the register (reflects the original request)
210 * NB: reg_id supports the future possibility of unsolicited
211 * WMIX_GPIO_DATA_EVENTs (for polling GPIO input), and it may
212 * simplify Host GPIO support.
213 */
214typedef PREPACK struct {
215 u32 value;
216 u32 reg_id;
217} POSTPACK WMIX_GPIO_DATA_EVENT;
218
219/*
220 * =============Error Detection support=================
221 */
222
223/*
224 * WMIX_HB_CHALLENGE_RESP_CMDID
225 * Heartbeat Challenge Response command
226 */
227typedef PREPACK struct {
228 u32 cookie;
229 u32 source;
230} POSTPACK WMIX_HB_CHALLENGE_RESP_CMD;
231
232/*
233 * WMIX_HB_CHALLENGE_RESP_EVENTID
234 * Heartbeat Challenge Response Event
235 */
236#define WMIX_HB_CHALLENGE_RESP_EVENT WMIX_HB_CHALLENGE_RESP_CMD
237
238typedef PREPACK struct {
239 struct dbglog_config_s config;
240} POSTPACK WMIX_DBGLOG_CFG_MODULE_CMD;
241
242/*
243 * =============Target Profiling support=================
244 */
245
246typedef PREPACK struct {
247 u32 period; /* Time (in 30.5us ticks) between samples */
248 u32 nbins;
249} POSTPACK WMIX_PROF_CFG_CMD;
250
251typedef PREPACK struct {
252 u32 addr;
253} POSTPACK WMIX_PROF_ADDR_SET_CMD;
254
255/*
256 * Target responds to Hosts's earlier WMIX_PROF_COUNT_GET_CMDID request
257 * using a WMIX_PROF_COUNT_EVENT with
258 * addr set to the next address
259 * count set to the corresponding count
260 */
261typedef PREPACK struct {
262 u32 addr;
263 u32 count;
264} POSTPACK WMIX_PROF_COUNT_EVENT;
265
266
267#ifdef __cplusplus
268}
269#endif
270
271#endif /* _WMIX_H_ */
diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h
deleted file mode 100644
index 34db29958bc..00000000000
--- a/drivers/staging/ath6kl/include/common_drv.h
+++ /dev/null
@@ -1,104 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22#ifndef COMMON_DRV_H_
23#define COMMON_DRV_H_
24
25#include "hif.h"
26#include "htc_packet.h"
27#include "htc_api.h"
28
29/* structure that is the state information for the default credit distribution callback
30 * drivers should instantiate (zero-init as well) this structure in their driver instance
31 * and pass it as a context to the HTC credit distribution functions */
32struct common_credit_state_info {
33 int TotalAvailableCredits; /* total credits in the system at startup */
34 int CurrentFreeCredits; /* credits available in the pool that have not been
35 given out to endpoints */
36 struct htc_endpoint_credit_dist *pLowestPriEpDist; /* pointer to the lowest priority endpoint dist struct */
37};
38
39struct hci_transport_callbacks {
40 s32 (*setupTransport)(void *ar);
41 void (*cleanupTransport)(void *ar);
42};
43
44struct hci_transport_misc_handles {
45 void *netDevice;
46 void *hifDevice;
47 void *htcHandle;
48};
49
50/* HTC TX packet tagging definitions */
51#define AR6K_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED
52#define AR6K_DATA_PKT_TAG (AR6K_CONTROL_PKT_TAG + 1)
53
54#define AR6002_VERSION_REV1 0x20000086
55#define AR6002_VERSION_REV2 0x20000188
56#define AR6003_VERSION_REV1 0x300002ba
57#define AR6003_VERSION_REV2 0x30000384
58
59#define AR6002_CUST_DATA_SIZE 112
60#define AR6003_CUST_DATA_SIZE 16
61
62#ifdef __cplusplus
63extern "C" {
64#endif
65
66/* OS-independent APIs */
67int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, struct common_credit_state_info *pCredInfo);
68
69int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
70
71int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
72
73int ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address, u8 *data, u32 length);
74
75int ar6000_reset_device(struct hif_device *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset);
76
77void ar6000_dump_target_assert_info(struct hif_device *hifDevice, u32 TargetType);
78
79int ar6000_set_htc_params(struct hif_device *hifDevice,
80 u32 TargetType,
81 u32 MboxIsrYieldValue,
82 u8 HtcControlBuffers);
83
84int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice,
85 u32 TargetType,
86 u32 Flags);
87
88void ar6000_copy_cust_data_from_target(struct hif_device *hifDevice, u32 TargetType);
89
90u8 *ar6000_get_cust_data_buffer(u32 TargetType);
91
92int ar6000_setBTState(void *context, u8 *pInBuf, u32 InBufSize);
93
94int ar6000_setDevicePowerState(void *context, u8 *pInBuf, u32 InBufSize);
95
96int ar6000_setWowMode(void *context, u8 *pInBuf, u32 InBufSize);
97
98int ar6000_setHostMode(void *context, u8 *pInBuf, u32 InBufSize);
99
100#ifdef __cplusplus
101}
102#endif
103
104#endif /*COMMON_DRV_H_*/
diff --git a/drivers/staging/ath6kl/include/dbglog_api.h b/drivers/staging/ath6kl/include/dbglog_api.h
deleted file mode 100644
index a53aed316e3..00000000000
--- a/drivers/staging/ath6kl/include/dbglog_api.h
+++ /dev/null
@@ -1,52 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="dbglog_api.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains host side debug primitives.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _DBGLOG_API_H_
26#define _DBGLOG_API_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#include "dbglog.h"
33
34#define DBGLOG_HOST_LOG_BUFFER_SIZE DBGLOG_LOG_BUFFER_SIZE
35
36#define DBGLOG_GET_DBGID(arg) \
37 ((arg & DBGLOG_DBGID_MASK) >> DBGLOG_DBGID_OFFSET)
38
39#define DBGLOG_GET_MODULEID(arg) \
40 ((arg & DBGLOG_MODULEID_MASK) >> DBGLOG_MODULEID_OFFSET)
41
42#define DBGLOG_GET_NUMARGS(arg) \
43 ((arg & DBGLOG_NUM_ARGS_MASK) >> DBGLOG_NUM_ARGS_OFFSET)
44
45#define DBGLOG_GET_TIMESTAMP(arg) \
46 ((arg & DBGLOG_TIMESTAMP_MASK) >> DBGLOG_TIMESTAMP_OFFSET)
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif /* _DBGLOG_API_H_ */
diff --git a/drivers/staging/ath6kl/include/dl_list.h b/drivers/staging/ath6kl/include/dl_list.h
deleted file mode 100644
index 13b1e6956c2..00000000000
--- a/drivers/staging/ath6kl/include/dl_list.h
+++ /dev/null
@@ -1,153 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="dl_list.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Double-link list definitions (adapted from Atheros SDIO stack)
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef __DL_LIST_H___
26#define __DL_LIST_H___
27
28#include "a_osapi.h"
29
30#define A_CONTAINING_STRUCT(address, struct_type, field_name)\
31 ((struct_type *)((unsigned long)(address) - (unsigned long)(&((struct_type *)0)->field_name)))
32
33/* list functions */
34/* pointers for the list */
35struct dl_list {
36 struct dl_list *pPrev;
37 struct dl_list *pNext;
38};
39/*
40 * DL_LIST_INIT , initialize doubly linked list
41*/
42#define DL_LIST_INIT(pList)\
43 {(pList)->pPrev = pList; (pList)->pNext = pList;}
44
45/* faster macro to init list and add a single item */
46#define DL_LIST_INIT_AND_ADD(pList,pItem) \
47{ (pList)->pPrev = (pItem); \
48 (pList)->pNext = (pItem); \
49 (pItem)->pNext = (pList); \
50 (pItem)->pPrev = (pList); \
51}
52
53#define DL_LIST_IS_EMPTY(pList) (((pList)->pPrev == (pList)) && ((pList)->pNext == (pList)))
54#define DL_LIST_GET_ITEM_AT_HEAD(pList) (pList)->pNext
55#define DL_LIST_GET_ITEM_AT_TAIL(pList) (pList)->pPrev
56/*
57 * ITERATE_OVER_LIST pStart is the list, pTemp is a temp list member
58 * NOT: do not use this function if the items in the list are deleted inside the
59 * iteration loop
60*/
61#define ITERATE_OVER_LIST(pStart, pTemp) \
62 for((pTemp) =(pStart)->pNext; pTemp != (pStart); (pTemp) = (pTemp)->pNext)
63
64
65/* safe iterate macro that allows the item to be removed from the list
66 * the iteration continues to the next item in the list
67 */
68#define ITERATE_OVER_LIST_ALLOW_REMOVE(pStart,pItem,st,offset) \
69{ \
70 struct dl_list * pTemp; \
71 pTemp = (pStart)->pNext; \
72 while (pTemp != (pStart)) { \
73 (pItem) = A_CONTAINING_STRUCT(pTemp,st,offset); \
74 pTemp = pTemp->pNext; \
75
76#define ITERATE_END }}
77
78/*
79 * DL_ListInsertTail - insert pAdd to the end of the list
80*/
81static INLINE struct dl_list *DL_ListInsertTail(struct dl_list *pList, struct dl_list *pAdd) {
82 /* insert at tail */
83 pAdd->pPrev = pList->pPrev;
84 pAdd->pNext = pList;
85 pList->pPrev->pNext = pAdd;
86 pList->pPrev = pAdd;
87 return pAdd;
88}
89
90/*
91 * DL_ListInsertHead - insert pAdd into the head of the list
92*/
93static INLINE struct dl_list * DL_ListInsertHead(struct dl_list * pList, struct dl_list * pAdd) {
94 /* insert at head */
95 pAdd->pPrev = pList;
96 pAdd->pNext = pList->pNext;
97 pList->pNext->pPrev = pAdd;
98 pList->pNext = pAdd;
99 return pAdd;
100}
101
102#define DL_ListAdd(pList,pItem) DL_ListInsertHead((pList),(pItem))
103/*
104 * DL_ListRemove - remove pDel from list
105*/
106static INLINE struct dl_list * DL_ListRemove(struct dl_list * pDel) {
107 pDel->pNext->pPrev = pDel->pPrev;
108 pDel->pPrev->pNext = pDel->pNext;
109 /* point back to itself just to be safe, incase remove is called again */
110 pDel->pNext = pDel;
111 pDel->pPrev = pDel;
112 return pDel;
113}
114
115/*
116 * DL_ListRemoveItemFromHead - get a list item from the head
117*/
118static INLINE struct dl_list * DL_ListRemoveItemFromHead(struct dl_list * pList) {
119 struct dl_list * pItem = NULL;
120 if (pList->pNext != pList) {
121 pItem = pList->pNext;
122 /* remove the first item from head */
123 DL_ListRemove(pItem);
124 }
125 return pItem;
126}
127
128static INLINE struct dl_list * DL_ListRemoveItemFromTail(struct dl_list * pList) {
129 struct dl_list * pItem = NULL;
130 if (pList->pPrev != pList) {
131 pItem = pList->pPrev;
132 /* remove the item from tail */
133 DL_ListRemove(pItem);
134 }
135 return pItem;
136}
137
138/* transfer src list items to the tail of the destination list */
139static INLINE void DL_ListTransferItemsToTail(struct dl_list * pDest, struct dl_list * pSrc) {
140 /* only concatenate if src is not empty */
141 if (!DL_LIST_IS_EMPTY(pSrc)) {
142 /* cut out circular list in src and re-attach to end of dest */
143 pSrc->pPrev->pNext = pDest;
144 pSrc->pNext->pPrev = pDest->pPrev;
145 pDest->pPrev->pNext = pSrc->pNext;
146 pDest->pPrev = pSrc->pPrev;
147 /* terminate src list, it is now empty */
148 pSrc->pPrev = pSrc;
149 pSrc->pNext = pSrc;
150 }
151}
152
153#endif /* __DL_LIST_H___ */
diff --git a/drivers/staging/ath6kl/include/dset_api.h b/drivers/staging/ath6kl/include/dset_api.h
deleted file mode 100644
index fe901ba40ec..00000000000
--- a/drivers/staging/ath6kl/include/dset_api.h
+++ /dev/null
@@ -1,65 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="dset_api.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Host-side DataSet API.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _DSET_API_H_
26#define _DSET_API_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/*
33 * Host-side DataSet support is optional, and is not
34 * currently required for correct operation. To disable
35 * Host-side DataSet support, set this to 0.
36 */
37#ifndef CONFIG_HOST_DSET_SUPPORT
38#define CONFIG_HOST_DSET_SUPPORT 1
39#endif
40
41/* Called to send a DataSet Open Reply back to the Target. */
42int wmi_dset_open_reply(struct wmi_t *wmip,
43 u32 status,
44 u32 access_cookie,
45 u32 size,
46 u32 version,
47 u32 targ_handle,
48 u32 targ_reply_fn,
49 u32 targ_reply_arg);
50
51/* Called to send a DataSet Data Reply back to the Target. */
52int wmi_dset_data_reply(struct wmi_t *wmip,
53 u32 status,
54 u8 *host_buf,
55 u32 length,
56 u32 targ_buf,
57 u32 targ_reply_fn,
58 u32 targ_reply_arg);
59
60#ifdef __cplusplus
61}
62#endif /* __cplusplus */
63
64
65#endif /* _DSET_API_H_ */
diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h
deleted file mode 100644
index 5e903fad23f..00000000000
--- a/drivers/staging/ath6kl/include/hci_transport_api.h
+++ /dev/null
@@ -1,259 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22#ifndef _HCI_TRANSPORT_API_H_
23#define _HCI_TRANSPORT_API_H_
24
25 /* Bluetooth HCI packets are stored in HTC packet containers */
26#include "htc_packet.h"
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32typedef void *HCI_TRANSPORT_HANDLE;
33
34typedef HTC_ENDPOINT_ID HCI_TRANSPORT_PACKET_TYPE;
35
36 /* we map each HCI packet class to a static Endpoint ID */
37#define HCI_COMMAND_TYPE ENDPOINT_1
38#define HCI_EVENT_TYPE ENDPOINT_2
39#define HCI_ACL_TYPE ENDPOINT_3
40#define HCI_PACKET_INVALID ENDPOINT_MAX
41
42#define HCI_GET_PACKET_TYPE(pP) (pP)->Endpoint
43#define HCI_SET_PACKET_TYPE(pP,s) (pP)->Endpoint = (s)
44
45/* callback when an HCI packet was completely sent */
46typedef void (*HCI_TRANSPORT_SEND_PKT_COMPLETE)(void *, struct htc_packet *);
47/* callback when an HCI packet is received */
48typedef void (*HCI_TRANSPORT_RECV_PKT)(void *, struct htc_packet *);
49/* Optional receive buffer re-fill callback,
50 * On some OSes (like Linux) packets are allocated from a global pool and indicated up
51 * to the network stack. The driver never gets the packets back from the OS. For these OSes
52 * a refill callback can be used to allocate and re-queue buffers into HTC.
53 * A refill callback is used for the reception of ACL and EVENT packets. The caller must
54 * set the watermark trigger point to cause a refill.
55 */
56typedef void (*HCI_TRANSPORT_RECV_REFILL)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable);
57/* Optional receive packet refill
58 * On some systems packet buffers are an extremely limited resource. Rather than
59 * queue largest-possible-sized buffers to the HCI bridge, some systems would rather
60 * allocate a specific size as the packet is received. The trade off is
61 * slightly more processing (callback invoked for each RX packet)
62 * for the benefit of committing fewer buffer resources into the bridge.
63 *
64 * The callback is provided the length of the pending packet to fetch. This includes the
65 * full transport header, HCI header, plus the length of payload. The callback can return a pointer to
66 * the allocated HTC packet for immediate use.
67 *
68 * NOTE*** This callback is mutually exclusive with the the refill callback above.
69 *
70 * */
71typedef struct htc_packet *(*HCI_TRANSPORT_RECV_ALLOC)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int Length);
72
73typedef enum _HCI_SEND_FULL_ACTION {
74 HCI_SEND_FULL_KEEP = 0, /* packet that overflowed should be kept in the queue */
75 HCI_SEND_FULL_DROP = 1, /* packet that overflowed should be dropped */
76} HCI_SEND_FULL_ACTION;
77
78/* callback when an HCI send queue exceeds the caller's MaxSendQueueDepth threshold,
79 * the callback must return the send full action to take (either DROP or KEEP) */
80typedef HCI_SEND_FULL_ACTION (*HCI_TRANSPORT_SEND_FULL)(void *, struct htc_packet *);
81
82struct hci_transport_properties {
83 int HeadRoom; /* number of bytes in front of HCI packet for header space */
84 int TailRoom; /* number of bytes at the end of the HCI packet for tail space */
85 int IOBlockPad; /* I/O block padding required (always a power of 2) */
86};
87
88struct hci_transport_config_info {
89 int ACLRecvBufferWaterMark; /* low watermark to trigger recv refill */
90 int EventRecvBufferWaterMark; /* low watermark to trigger recv refill */
91 int MaxSendQueueDepth; /* max number of packets in the single send queue */
92 void *pContext; /* context for all callbacks */
93 void (*TransportFailure)(void *pContext, int Status); /* transport failure callback */
94 int (*TransportReady)(HCI_TRANSPORT_HANDLE, struct hci_transport_properties *,void *pContext); /* transport is ready */
95 void (*TransportRemoved)(void *pContext); /* transport was removed */
96 /* packet processing callbacks */
97 HCI_TRANSPORT_SEND_PKT_COMPLETE pHCISendComplete;
98 HCI_TRANSPORT_RECV_PKT pHCIPktRecv;
99 HCI_TRANSPORT_RECV_REFILL pHCIPktRecvRefill;
100 HCI_TRANSPORT_RECV_ALLOC pHCIPktRecvAlloc;
101 HCI_TRANSPORT_SEND_FULL pHCISendFull;
102};
103
104/* ------ Function Prototypes ------ */
105/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
106 @desc: Attach to the HCI transport module
107 @function name: HCI_TransportAttach
108 @input: HTCHandle - HTC handle (see HTC apis)
109 pInfo - initialization information
110 @output:
111 @return: HCI_TRANSPORT_HANDLE on success, NULL on failure
112 @notes: The HTC module provides HCI transport services.
113 @example:
114 @see also: HCI_TransportDetach
115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
116HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, struct hci_transport_config_info *pInfo);
117
118/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
119 @desc: Detach from the HCI transport module
120 @function name: HCI_TransportDetach
121 @input: HciTrans - HCI transport handle
122 pInfo - initialization information
123 @output:
124 @return:
125 @notes:
126 @example:
127 @see also:
128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
129void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans);
130
131/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
132 @desc: Add receive packets to the HCI transport
133 @function name: HCI_TransportAddReceivePkts
134 @input: HciTrans - HCI transport handle
135 pQueue - a queue holding one or more packets
136 @output:
137 @return: 0 on success
138 @notes: user must supply HTC packets for capturing incomming HCI packets. The caller
139 must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL()
140 macro. Each packet in the queue must be of the same type and length
141 @example:
142 @see also:
143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
144int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue);
145
146/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
147 @desc: Send an HCI packet packet
148 @function name: HCI_TransportSendPkt
149 @input: HciTrans - HCI transport handle
150 pPacket - packet to send
151 Synchronous - send the packet synchronously (blocking)
152 @output:
153 @return: 0
154 @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() and
155 HCI_SET_PACKET_TYPE() macros to prepare the packet.
156 If Synchronous is set to false the call is fully asynchronous. On error or completion,
157 the registered send complete callback will be called.
158 If Synchronous is set to true, the call will block until the packet is sent, if the
159 interface cannot send the packet within a 2 second timeout, the function will return
160 the failure code : A_EBUSY.
161
162 Synchronous Mode should only be used at start-up to initialize the HCI device using
163 custom HCI commands. It should NOT be mixed with Asynchronous operations. Mixed synchronous
164 and asynchronous operation behavior is undefined.
165
166 @example:
167 @see also:
168+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
169int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous);
170
171
172/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
173 @desc: Stop HCI transport
174 @function name: HCI_TransportStop
175 @input: HciTrans - hci transport handle
176 @output:
177 @return:
178 @notes: HCI transport communication will be halted. All receive and pending TX packets will
179 be flushed.
180 @example:
181 @see also:
182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
183void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans);
184
185/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
186 @desc: Start the HCI transport
187 @function name: HCI_TransportStart
188 @input: HciTrans - hci transport handle
189 @output:
190 @return: 0 on success
191 @notes: HCI transport communication will begin, the caller can expect the arrival
192 of HCI recv packets as soon as this call returns.
193 @example:
194 @see also:
195+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
196int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans);
197
198/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
199 @desc: Enable or Disable Asynchronous Recv
200 @function name: HCI_TransportEnableDisableAsyncRecv
201 @input: HciTrans - hci transport handle
202 Enable - enable or disable asynchronous recv
203 @output:
204 @return: 0 on success
205 @notes: This API must be called when HCI recv is handled synchronously
206 @example:
207 @see also:
208+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
209int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
210
211/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
212 @desc: Receive an event packet from the HCI transport synchronously using polling
213 @function name: HCI_TransportRecvHCIEventSync
214 @input: HciTrans - hci transport handle
215 pPacket - HTC packet to hold the recv data
216 MaxPollMS - maximum polling duration in Milliseconds;
217 @output:
218 @return: 0 on success
219 @notes: This API should be used only during HCI device initialization, the caller must call
220 HCI_TransportEnableDisableAsyncRecv with Enable=false prior to using this API.
221 This API will only capture HCI Event packets.
222 @example:
223 @see also: HCI_TransportEnableDisableAsyncRecv
224+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
225int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans,
226 struct htc_packet *pPacket,
227 int MaxPollMS);
228
229/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
230 @desc: Set the desired baud rate for the underlying transport layer
231 @function name: HCI_TransportSetBaudRate
232 @input: HciTrans - hci transport handle
233 Baud - baud rate in bps
234 @output:
235 @return: 0 on success
236 @notes: This API should be used only after HCI device initialization
237 @example:
238 @see also:
239+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
240int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud);
241
242/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
243 @desc: Enable/Disable HCI Transport Power Management
244 @function name: HCI_TransportEnablePowerMgmt
245 @input: HciTrans - hci transport handle
246 Enable - 1 = Enable, 0 = Disable
247 @output:
248 @return: 0 on success
249 @notes:
250 @example:
251 @see also:
252+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
253int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
254
255#ifdef __cplusplus
256}
257#endif
258
259#endif /* _HCI_TRANSPORT_API_H_ */
diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h
deleted file mode 100644
index 24200e778c3..00000000000
--- a/drivers/staging/ath6kl/include/hif.h
+++ /dev/null
@@ -1,456 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="hif.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// HIF specific declarations and prototypes
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _HIF_H_
26#define _HIF_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* Header files */
33#include "a_config.h"
34#include "athdefs.h"
35#include "a_osapi.h"
36#include "dl_list.h"
37
38
39typedef struct htc_callbacks HTC_CALLBACKS;
40struct hif_device;
41
42/*
43 * direction - Direction of transfer (HIF_READ/HIF_WRITE).
44 */
45#define HIF_READ 0x00000001
46#define HIF_WRITE 0x00000002
47#define HIF_DIR_MASK (HIF_READ | HIF_WRITE)
48
49/*
50 * type - An interface may support different kind of read/write commands.
51 * For example: SDIO supports CMD52/CMD53s. In case of MSIO it
52 * translates to using different kinds of TPCs. The command type
53 * is thus divided into a basic and an extended command and can
54 * be specified using HIF_BASIC_IO/HIF_EXTENDED_IO.
55 */
56#define HIF_BASIC_IO 0x00000004
57#define HIF_EXTENDED_IO 0x00000008
58#define HIF_TYPE_MASK (HIF_BASIC_IO | HIF_EXTENDED_IO)
59
60/*
61 * emode - This indicates the whether the command is to be executed in a
62 * blocking or non-blocking fashion (HIF_SYNCHRONOUS/
63 * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been
64 * implemented using the asynchronous mode allowing the the bus
65 * driver to indicate the completion of operation through the
66 * registered callback routine. The requirement primarily comes
67 * from the contexts these operations get called from (a driver's
68 * transmit context or the ISR context in case of receive).
69 * Support for both of these modes is essential.
70 */
71#define HIF_SYNCHRONOUS 0x00000010
72#define HIF_ASYNCHRONOUS 0x00000020
73#define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)
74
75/*
76 * dmode - An interface may support different kinds of commands based on
77 * the tradeoff between the amount of data it can carry and the
78 * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/
79 * HIF_BLOCK_BASIS). In case of latter, the data is rounded off
80 * to the nearest block size by padding. The size of the block is
81 * configurable at compile time using the HIF_BLOCK_SIZE and is
82 * negotiated with the target during initialization after the
83 * AR6000 interrupts are enabled.
84 */
85#define HIF_BYTE_BASIS 0x00000040
86#define HIF_BLOCK_BASIS 0x00000080
87#define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)
88
89/*
90 * amode - This indicates if the address has to be incremented on AR6000
91 * after every read/write operation (HIF?FIXED_ADDRESS/
92 * HIF_INCREMENTAL_ADDRESS).
93 */
94#define HIF_FIXED_ADDRESS 0x00000100
95#define HIF_INCREMENTAL_ADDRESS 0x00000200
96#define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS)
97
98#define HIF_WR_ASYNC_BYTE_FIX \
99 (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
100#define HIF_WR_ASYNC_BYTE_INC \
101 (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
102#define HIF_WR_ASYNC_BLOCK_INC \
103 (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
104#define HIF_WR_SYNC_BYTE_FIX \
105 (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
106#define HIF_WR_SYNC_BYTE_INC \
107 (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
108#define HIF_WR_SYNC_BLOCK_INC \
109 (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
110#define HIF_WR_ASYNC_BLOCK_FIX \
111 (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
112#define HIF_WR_SYNC_BLOCK_FIX \
113 (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
114#define HIF_RD_SYNC_BYTE_INC \
115 (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
116#define HIF_RD_SYNC_BYTE_FIX \
117 (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
118#define HIF_RD_ASYNC_BYTE_FIX \
119 (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
120#define HIF_RD_ASYNC_BLOCK_FIX \
121 (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
122#define HIF_RD_ASYNC_BYTE_INC \
123 (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
124#define HIF_RD_ASYNC_BLOCK_INC \
125 (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
126#define HIF_RD_SYNC_BLOCK_INC \
127 (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
128#define HIF_RD_SYNC_BLOCK_FIX \
129 (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
130
131typedef enum {
132 HIF_DEVICE_POWER_STATE = 0,
133 HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
134 HIF_DEVICE_GET_MBOX_ADDR,
135 HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
136 HIF_DEVICE_GET_IRQ_PROC_MODE,
137 HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
138 HIF_DEVICE_POWER_STATE_CHANGE,
139 HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
140 HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT,
141 HIF_DEVICE_GET_OS_DEVICE,
142 HIF_DEVICE_DEBUG_BUS_STATE,
143} HIF_DEVICE_CONFIG_OPCODE;
144
145/*
146 * HIF CONFIGURE definitions:
147 *
148 * HIF_DEVICE_GET_MBOX_BLOCK_SIZE
149 * input : none
150 * output : array of 4 u32s
151 * notes: block size is returned for each mailbox (4)
152 *
153 * HIF_DEVICE_GET_MBOX_ADDR
154 * input : none
155 * output : struct hif_device_mbox_info
156 * notes:
157 *
158 * HIF_DEVICE_GET_PENDING_EVENTS_FUNC
159 * input : none
160 * output: HIF_PENDING_EVENTS_FUNC function pointer
161 * notes: this is optional for the HIF layer, if the request is
162 * not handled then it indicates that the upper layer can use
163 * the standard device methods to get pending events (IRQs, mailbox messages etc..)
164 * otherwise it can call the function pointer to check pending events.
165 *
166 * HIF_DEVICE_GET_IRQ_PROC_MODE
167 * input : none
168 * output : HIF_DEVICE_IRQ_PROCESSING_MODE (interrupt processing mode)
169 * note: the hif layer interfaces with the underlying OS-specific bus driver. The HIF
170 * layer can report whether IRQ processing is requires synchronous behavior or
171 * can be processed using asynchronous bus requests (typically faster).
172 *
173 * HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC
174 * input :
175 * output : HIF_MASK_UNMASK_RECV_EVENT function pointer
176 * notes: this is optional for the HIF layer. The HIF layer may require a special mechanism
177 * to mask receive message events. The upper layer can call this pointer when it needs
178 * to mask/unmask receive events (in case it runs out of buffers).
179 *
180 * HIF_DEVICE_POWER_STATE_CHANGE
181 *
182 * input : HIF_DEVICE_POWER_CHANGE_TYPE
183 * output : none
184 * note: this is optional for the HIF layer. The HIF layer can handle power on/off state change
185 * requests in an interconnect specific way. This is highly OS and bus driver dependent.
186 * The caller must guarantee that no HIF read/write requests will be made after the device
187 * is powered down.
188 *
189 * HIF_DEVICE_GET_IRQ_YIELD_PARAMS
190 *
191 * input : none
192 * output : struct hif_device_irq_yield_params
193 * note: This query checks if the HIF layer wishes to impose a processing yield count for the DSR handler.
194 * The DSR callback handler will exit after a fixed number of RX packets or events are processed.
195 * This query is only made if the device reports an IRQ processing mode of HIF_DEVICE_IRQ_SYNC_ONLY.
196 * The HIF implementation can ignore this command if it does not desire the DSR callback to yield.
197 * The HIF layer can indicate the maximum number of IRQ processing units (RX packets) before the
198 * DSR handler callback must yield and return control back to the HIF layer. When a yield limit is
199 * used the DSR callback will not call HIFAckInterrupts() as it would normally do before returning.
200 * The HIF implementation that requires a yield count must call HIFAckInterrupt() when it is prepared
201 * to process interrupts again.
202 *
203 * HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT
204 * input : none
205 * output : struct hif_device_scatter_support_info
206 * note: This query checks if the HIF layer implements the SCATTER request interface. Scatter requests
207 * allows upper layers to submit mailbox I/O operations using a list of buffers. This is useful for
208 * multi-message transfers that can better utilize the bus interconnect.
209 *
210 *
211 * HIF_DEVICE_GET_OS_DEVICE
212 * intput : none
213 * output : struct hif_device_os_device_info;
214 * note: On some operating systems, the HIF layer has a parent device object for the bus. This object
215 * may be required to register certain types of logical devices.
216 *
217 * HIF_DEVICE_DEBUG_BUS_STATE
218 * input : none
219 * output : none
220 * note: This configure option triggers the HIF interface to dump as much bus interface state. This
221 * configuration request is optional (No-OP on some HIF implementations)
222 *
223 */
224
225struct hif_mbox_properties {
226 u32 ExtendedAddress; /* extended address for larger writes */
227 u32 ExtendedSize;
228};
229
230#define HIF_MBOX_FLAG_NO_BUNDLING (1 << 0) /* do not allow bundling over the mailbox */
231
232typedef enum _MBOX_BUF_IF_TYPE {
233 MBOX_BUS_IF_SDIO = 0,
234 MBOX_BUS_IF_SPI = 1,
235} MBOX_BUF_IF_TYPE;
236
237struct hif_device_mbox_info {
238 u32 MboxAddresses[4]; /* must be first element for legacy HIFs that return the address in
239 and ARRAY of 32-bit words */
240
241 /* the following describe extended mailbox properties */
242 struct hif_mbox_properties MboxProp[4];
243 /* if the HIF supports the GMbox extended address region it can report it
244 * here, some interfaces cannot support the GMBOX address range and not set this */
245 u32 GMboxAddress;
246 u32 GMboxSize;
247 u32 Flags; /* flags to describe mbox behavior or usage */
248 MBOX_BUF_IF_TYPE MboxBusIFType; /* mailbox bus interface type */
249};
250
251typedef enum {
252 HIF_DEVICE_IRQ_SYNC_ONLY, /* for HIF implementations that require the DSR to process all
253 interrupts before returning */
254 HIF_DEVICE_IRQ_ASYNC_SYNC, /* for HIF implementations that allow DSR to process interrupts
255 using ASYNC I/O (that is HIFAckInterrupt can be called at a
256 later time */
257} HIF_DEVICE_IRQ_PROCESSING_MODE;
258
259typedef enum {
260 HIF_DEVICE_POWER_UP, /* HIF layer should power up interface and/or module */
261 HIF_DEVICE_POWER_DOWN, /* HIF layer should initiate bus-specific measures to minimize power */
262 HIF_DEVICE_POWER_CUT /* HIF layer should initiate bus-specific AND/OR platform-specific measures
263 to completely power-off the module and associated hardware (i.e. cut power supplies)
264 */
265} HIF_DEVICE_POWER_CHANGE_TYPE;
266
267struct hif_device_irq_yield_params {
268 int RecvPacketYieldCount; /* max number of packets to force DSR to return */
269};
270
271
272struct hif_scatter_item {
273 u8 *pBuffer; /* CPU accessible address of buffer */
274 int Length; /* length of transfer to/from this buffer */
275 void *pCallerContexts[2]; /* space for caller to insert a context associated with this item */
276};
277
278struct hif_scatter_req;
279typedef void ( *HIF_SCATTER_COMP_CB)(struct hif_scatter_req *);
280
281typedef enum _HIF_SCATTER_METHOD {
282 HIF_SCATTER_NONE = 0,
283 HIF_SCATTER_DMA_REAL, /* Real SG support no restrictions */
284 HIF_SCATTER_DMA_BOUNCE, /* Uses SG DMA but HIF layer uses an internal bounce buffer */
285} HIF_SCATTER_METHOD;
286
287struct hif_scatter_req {
288 struct dl_list ListLink; /* link management */
289 u32 Address; /* address for the read/write operation */
290 u32 Request; /* request flags */
291 u32 TotalLength; /* total length of entire transfer */
292 u32 CallerFlags; /* caller specific flags can be stored here */
293 HIF_SCATTER_COMP_CB CompletionRoutine; /* completion routine set by caller */
294 int CompletionStatus; /* status of completion */
295 void *Context; /* caller context for this request */
296 int ValidScatterEntries; /* number of valid entries set by caller */
297 HIF_SCATTER_METHOD ScatterMethod; /* scatter method handled by HIF */
298 void *HIFPrivate[4]; /* HIF private area */
299 u8 *pScatterBounceBuffer; /* bounce buffer for upper layers to copy to/from */
300 struct hif_scatter_item ScatterList[1]; /* start of scatter list */
301};
302
303typedef struct hif_scatter_req * ( *HIF_ALLOCATE_SCATTER_REQUEST)(struct hif_device *device);
304typedef void ( *HIF_FREE_SCATTER_REQUEST)(struct hif_device *device, struct hif_scatter_req *request);
305typedef int ( *HIF_READWRITE_SCATTER)(struct hif_device *device, struct hif_scatter_req *request);
306
307struct hif_device_scatter_support_info {
308 /* information returned from HIF layer */
309 HIF_ALLOCATE_SCATTER_REQUEST pAllocateReqFunc;
310 HIF_FREE_SCATTER_REQUEST pFreeReqFunc;
311 HIF_READWRITE_SCATTER pReadWriteScatterFunc;
312 int MaxScatterEntries;
313 int MaxTransferSizePerScatterReq;
314};
315
316struct hif_device_os_device_info {
317 void *pOSDevice;
318};
319
320#define HIF_MAX_DEVICES 1
321
322struct htc_callbacks {
323 void *context; /* context to pass to the dsrhandler
324 note : rwCompletionHandler is provided the context passed to HIFReadWrite */
325 int (* rwCompletionHandler)(void *rwContext, int status);
326 int (* dsrHandler)(void *context);
327};
328
329typedef struct osdrv_callbacks {
330 void *context; /* context to pass for all callbacks except deviceRemovedHandler
331 the deviceRemovedHandler is only called if the device is claimed */
332 int (* deviceInsertedHandler)(void *context, void *hif_handle);
333 int (* deviceRemovedHandler)(void *claimedContext, void *hif_handle);
334 int (* deviceSuspendHandler)(void *context);
335 int (* deviceResumeHandler)(void *context);
336 int (* deviceWakeupHandler)(void *context);
337 int (* devicePowerChangeHandler)(void *context, HIF_DEVICE_POWER_CHANGE_TYPE config);
338} OSDRV_CALLBACKS;
339
340#define HIF_OTHER_EVENTS (1 << 0) /* other interrupts (non-Recv) are pending, host
341 needs to read the register table to figure out what */
342#define HIF_RECV_MSG_AVAIL (1 << 1) /* pending recv packet */
343
344struct hif_pending_events_info {
345 u32 Events;
346 u32 LookAhead;
347 u32 AvailableRecvBytes;
348#ifdef THREAD_X
349 u32 Polling;
350 u32 INT_CAUSE_REG;
351#endif
352};
353
354 /* function to get pending events , some HIF modules use special mechanisms
355 * to detect packet available and other interrupts */
356typedef int ( *HIF_PENDING_EVENTS_FUNC)(struct hif_device *device,
357 struct hif_pending_events_info *pEvents,
358 void *AsyncContext);
359
360#define HIF_MASK_RECV true
361#define HIF_UNMASK_RECV false
362 /* function to mask recv events */
363typedef int ( *HIF_MASK_UNMASK_RECV_EVENT)(struct hif_device *device,
364 bool Mask,
365 void *AsyncContext);
366
367
368/*
369 * This API is used to perform any global initialization of the HIF layer
370 * and to set OS driver callbacks (i.e. insertion/removal) to the HIF layer
371 *
372 */
373int HIFInit(OSDRV_CALLBACKS *callbacks);
374
375/* This API claims the HIF device and provides a context for handling removal.
376 * The device removal callback is only called when the OSDRV layer claims
377 * a device. The claimed context must be non-NULL */
378void HIFClaimDevice(struct hif_device *device, void *claimedContext);
379/* release the claimed device */
380void HIFReleaseDevice(struct hif_device *device);
381
382/* This API allows the HTC layer to attach to the HIF device */
383int HIFAttachHTC(struct hif_device *device, HTC_CALLBACKS *callbacks);
384/* This API detaches the HTC layer from the HIF device */
385void HIFDetachHTC(struct hif_device *device);
386
387/*
388 * This API is used to provide the read/write interface over the specific bus
389 * interface.
390 * address - Starting address in the AR6000's address space. For mailbox
391 * writes, it refers to the start of the mbox boundary. It should
392 * be ensured that the last byte falls on the mailbox's EOM. For
393 * mailbox reads, it refers to the end of the mbox boundary.
394 * buffer - Pointer to the buffer containg the data to be transmitted or
395 * received.
396 * length - Amount of data to be transmitted or received.
397 * request - Characterizes the attributes of the command.
398 */
399int
400HIFReadWrite(struct hif_device *device,
401 u32 address,
402 u8 *buffer,
403 u32 length,
404 u32 request,
405 void *context);
406
407/*
408 * This can be initiated from the unload driver context when the OSDRV layer has no more use for
409 * the device.
410 */
411void HIFShutDownDevice(struct hif_device *device);
412
413/*
414 * This should translate to an acknowledgment to the bus driver indicating that
415 * the previous interrupt request has been serviced and the all the relevant
416 * sources have been cleared. HTC is ready to process more interrupts.
417 * This should prevent the bus driver from raising an interrupt unless the
418 * previous one has been serviced and acknowledged using the previous API.
419 */
420void HIFAckInterrupt(struct hif_device *device);
421
422void HIFMaskInterrupt(struct hif_device *device);
423
424void HIFUnMaskInterrupt(struct hif_device *device);
425
426#ifdef THREAD_X
427/*
428 * This set of functions are to be used by the bus driver to notify
429 * the HIF module about various events.
430 * These are not implemented if the bus driver provides an alternative
431 * way for this notification though callbacks for instance.
432 */
433int HIFInsertEventNotify(void);
434
435int HIFRemoveEventNotify(void);
436
437int HIFIRQEventNotify(void);
438
439int HIFRWCompleteEventNotify(void);
440#endif
441
442int
443HIFConfigureDevice(struct hif_device *device, HIF_DEVICE_CONFIG_OPCODE opcode,
444 void *config, u32 configLen);
445
446/*
447 * This API wait for the remaining MBOX messages to be drained
448 * This should be moved to HTC AR6K layer
449 */
450int hifWaitForPendingRecv(struct hif_device *device);
451
452#ifdef __cplusplus
453}
454#endif
455
456#endif /* _HIF_H_ */
diff --git a/drivers/staging/ath6kl/include/host_version.h b/drivers/staging/ath6kl/include/host_version.h
deleted file mode 100644
index 74f1982c681..00000000000
--- a/drivers/staging/ath6kl/include/host_version.h
+++ /dev/null
@@ -1,52 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="host_version.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains version information for the sample host driver for the
22// AR6000 chip
23//
24// Author(s): ="Atheros"
25//==============================================================================
26#ifndef _HOST_VERSION_H_
27#define _HOST_VERSION_H_
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33#include <AR6002/AR6K_version.h>
34
35/*
36 * The version number is made up of major, minor, patch and build
37 * numbers. These are 16 bit numbers. The build and release script will
38 * set the build number using a Perforce counter. Here the build number is
39 * set to 9999 so that builds done without the build-release script are easily
40 * identifiable.
41 */
42
43#define ATH_SW_VER_MAJOR __VER_MAJOR_
44#define ATH_SW_VER_MINOR __VER_MINOR_
45#define ATH_SW_VER_PATCH __VER_PATCH_
46#define ATH_SW_VER_BUILD __BUILD_NUMBER_
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif /* _HOST_VERSION_H_ */
diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h
deleted file mode 100644
index 4fb767559f8..00000000000
--- a/drivers/staging/ath6kl/include/htc_api.h
+++ /dev/null
@@ -1,575 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_api.h" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _HTC_API_H_
24#define _HTC_API_H_
25
26#include "htc_packet.h"
27#include <htc.h>
28#include <htc_services.h>
29
30#ifdef __cplusplus
31extern "C" {
32#endif /* __cplusplus */
33
34/* TODO.. for BMI */
35#define ENDPOINT1 0
36// TODO -remove me, but we have to fix BMI first
37#define HTC_MAILBOX_NUM_MAX 4
38
39/* this is the amount of header room required by users of HTC */
40#define HTC_HEADER_LEN HTC_HDR_LENGTH
41
42typedef void *HTC_HANDLE;
43
44typedef u16 HTC_SERVICE_ID;
45
46struct htc_init_info {
47 void *pContext; /* context for target failure notification */
48 void (*TargetFailure)(void *Instance, int Status);
49};
50
51/* per service connection send completion */
52typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *,struct htc_packet *);
53/* per service connection callback when a plurality of packets have been sent
54 * The struct htc_packet_queue is a temporary queue object (e.g. freed on return from the callback)
55 * to hold a list of completed send packets.
56 * If the handler cannot fully traverse the packet queue before returning, it should
57 * transfer the items of the queue into the caller's private queue using:
58 * HTC_PACKET_ENQUEUE() */
59typedef void (*HTC_EP_SEND_PKT_COMP_MULTIPLE)(void *,struct htc_packet_queue *);
60/* per service connection pkt received */
61typedef void (*HTC_EP_RECV_PKT)(void *,struct htc_packet *);
62/* per service connection callback when a plurality of packets are received
63 * The struct htc_packet_queue is a temporary queue object (e.g. freed on return from the callback)
64 * to hold a list of recv packets.
65 * If the handler cannot fully traverse the packet queue before returning, it should
66 * transfer the items of the queue into the caller's private queue using:
67 * HTC_PACKET_ENQUEUE() */
68typedef void (*HTC_EP_RECV_PKT_MULTIPLE)(void *,struct htc_packet_queue *);
69
70/* Optional per service connection receive buffer re-fill callback,
71 * On some OSes (like Linux) packets are allocated from a global pool and indicated up
72 * to the network stack. The driver never gets the packets back from the OS. For these OSes
73 * a refill callback can be used to allocate and re-queue buffers into HTC.
74 *
75 * On other OSes, the network stack can call into the driver's OS-specifc "return_packet" handler and
76 * the driver can re-queue these buffers into HTC. In this regard a refill callback is
77 * unnecessary */
78typedef void (*HTC_EP_RECV_REFILL)(void *, HTC_ENDPOINT_ID Endpoint);
79
80/* Optional per service connection receive buffer allocation callback.
81 * On some systems packet buffers are an extremely limited resource. Rather than
82 * queue largest-possible-sized buffers to HTC, some systems would rather
83 * allocate a specific size as the packet is received. The trade off is
84 * slightly more processing (callback invoked for each RX packet)
85 * for the benefit of committing fewer buffer resources into HTC.
86 *
87 * The callback is provided the length of the pending packet to fetch. This includes the
88 * HTC header length plus the length of payload. The callback can return a pointer to
89 * the allocated HTC packet for immediate use.
90 *
91 * Alternatively a variant of this handler can be used to allocate large receive packets as needed.
92 * For example an application can use the refill mechanism for normal packets and the recv-alloc mechanism to
93 * handle the case where a large packet buffer is required. This can significantly reduce the
94 * amount of "committed" memory used to receive packets.
95 *
96 * */
97typedef struct htc_packet *(*HTC_EP_RECV_ALLOC)(void *, HTC_ENDPOINT_ID Endpoint, int Length);
98
99typedef enum _HTC_SEND_FULL_ACTION {
100 HTC_SEND_FULL_KEEP = 0, /* packet that overflowed should be kept in the queue */
101 HTC_SEND_FULL_DROP = 1, /* packet that overflowed should be dropped */
102} HTC_SEND_FULL_ACTION;
103
104/* Optional per service connection callback when a send queue is full. This can occur if the
105 * host continues queueing up TX packets faster than credits can arrive
106 * To prevent the host (on some Oses like Linux) from continuously queueing packets
107 * and consuming resources, this callback is provided so that that the host
108 * can disable TX in the subsystem (i.e. network stack).
109 * This callback is invoked for each packet that "overflows" the HTC queue. The callback can
110 * determine whether the new packet that overflowed the queue can be kept (HTC_SEND_FULL_KEEP) or
111 * dropped (HTC_SEND_FULL_DROP). If a packet is dropped, the EpTxComplete handler will be called
112 * and the packet's status field will be set to A_NO_RESOURCE.
113 * Other OSes require a "per-packet" indication for each completed TX packet, this
114 * closed loop mechanism will prevent the network stack from overunning the NIC
115 * The packet to keep or drop is passed for inspection to the registered handler the handler
116 * must ONLY inspect the packet, it may not free or reclaim the packet. */
117typedef HTC_SEND_FULL_ACTION (*HTC_EP_SEND_QUEUE_FULL)(void *, struct htc_packet *pPacket);
118
119struct htc_ep_callbacks {
120 void *pContext; /* context for each callback */
121 HTC_EP_SEND_PKT_COMPLETE EpTxComplete; /* tx completion callback for connected endpoint */
122 HTC_EP_RECV_PKT EpRecv; /* receive callback for connected endpoint */
123 HTC_EP_RECV_REFILL EpRecvRefill; /* OPTIONAL receive re-fill callback for connected endpoint */
124 HTC_EP_SEND_QUEUE_FULL EpSendFull; /* OPTIONAL send full callback */
125 HTC_EP_RECV_ALLOC EpRecvAlloc; /* OPTIONAL recv allocation callback */
126 HTC_EP_RECV_ALLOC EpRecvAllocThresh; /* OPTIONAL recv allocation callback based on a threshold */
127 HTC_EP_SEND_PKT_COMP_MULTIPLE EpTxCompleteMultiple; /* OPTIONAL completion handler for multiple complete
128 indications (EpTxComplete must be NULL) */
129 HTC_EP_RECV_PKT_MULTIPLE EpRecvPktMultiple; /* OPTIONAL completion handler for multiple
130 recv packet indications (EpRecv must be NULL) */
131 int RecvAllocThreshold; /* if EpRecvAllocThresh is non-NULL, HTC will compare the
132 threshold value to the current recv packet length and invoke
133 the EpRecvAllocThresh callback to acquire a packet buffer */
134 int RecvRefillWaterMark; /* if a EpRecvRefill handler is provided, this value
135 can be used to set a trigger refill callback
136 when the recv queue drops below this value
137 if set to 0, the refill is only called when packets
138 are empty */
139};
140
141/* service connection information */
142struct htc_service_connect_req {
143 HTC_SERVICE_ID ServiceID; /* service ID to connect to */
144 u16 ConnectionFlags; /* connection flags, see htc protocol definition */
145 u8 *pMetaData; /* ptr to optional service-specific meta-data */
146 u8 MetaDataLength; /* optional meta data length */
147 struct htc_ep_callbacks EpCallbacks; /* endpoint callbacks */
148 int MaxSendQueueDepth; /* maximum depth of any send queue */
149 u32 LocalConnectionFlags; /* HTC flags for the host-side (local) connection */
150 unsigned int MaxSendMsgSize; /* override max message size in send direction */
151};
152
153#define HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING (1 << 0) /* enable send bundle padding for this endpoint */
154
155/* service connection response information */
156struct htc_service_connect_resp {
157 u8 *pMetaData; /* caller supplied buffer to optional meta-data */
158 u8 BufferLength; /* length of caller supplied buffer */
159 u8 ActualLength; /* actual length of meta data */
160 HTC_ENDPOINT_ID Endpoint; /* endpoint to communicate over */
161 unsigned int MaxMsgLength; /* max length of all messages over this endpoint */
162 u8 ConnectRespCode; /* connect response code from target */
163};
164
165/* endpoint distribution structure */
166struct htc_endpoint_credit_dist {
167 struct htc_endpoint_credit_dist *pNext;
168 struct htc_endpoint_credit_dist *pPrev;
169 HTC_SERVICE_ID ServiceID; /* Service ID (set by HTC) */
170 HTC_ENDPOINT_ID Endpoint; /* endpoint for this distribution struct (set by HTC) */
171 u32 DistFlags; /* distribution flags, distribution function can
172 set default activity using SET_EP_ACTIVE() macro */
173 int TxCreditsNorm; /* credits for normal operation, anything above this
174 indicates the endpoint is over-subscribed, this field
175 is only relevant to the credit distribution function */
176 int TxCreditsMin; /* floor for credit distribution, this field is
177 only relevant to the credit distribution function */
178 int TxCreditsAssigned; /* number of credits assigned to this EP, this field
179 is only relevant to the credit dist function */
180 int TxCredits; /* current credits available, this field is used by
181 HTC to determine whether a message can be sent or
182 must be queued */
183 int TxCreditsToDist; /* pending credits to distribute on this endpoint, this
184 is set by HTC when credit reports arrive.
185 The credit distribution functions sets this to zero
186 when it distributes the credits */
187 int TxCreditsSeek; /* this is the number of credits that the current pending TX
188 packet needs to transmit. This is set by HTC when
189 and endpoint needs credits in order to transmit */
190 int TxCreditSize; /* size in bytes of each credit (set by HTC) */
191 int TxCreditsPerMaxMsg; /* credits required for a maximum sized messages (set by HTC) */
192 void *pHTCReserved; /* reserved for HTC use */
193 int TxQueueDepth; /* current depth of TX queue , i.e. messages waiting for credits
194 This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE
195 or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint
196 that has non-zero credits to recover
197 */
198};
199
200#define HTC_EP_ACTIVE ((u32) (1u << 31))
201
202/* macro to check if an endpoint has gone active, useful for credit
203 * distributions */
204#define IS_EP_ACTIVE(epDist) ((epDist)->DistFlags & HTC_EP_ACTIVE)
205#define SET_EP_ACTIVE(epDist) (epDist)->DistFlags |= HTC_EP_ACTIVE
206
207 /* credit distibution code that is passed into the distrbution function,
208 * there are mandatory and optional codes that must be handled */
209typedef enum _HTC_CREDIT_DIST_REASON {
210 HTC_CREDIT_DIST_SEND_COMPLETE = 0, /* credits available as a result of completed
211 send operations (MANDATORY) resulting in credit reports */
212 HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1, /* a change in endpoint activity occurred (OPTIONAL) */
213 HTC_CREDIT_DIST_SEEK_CREDITS, /* an endpoint needs to "seek" credits (OPTIONAL) */
214 HTC_DUMP_CREDIT_STATE /* for debugging, dump any state information that is kept by
215 the distribution function */
216} HTC_CREDIT_DIST_REASON;
217
218typedef void (*HTC_CREDIT_DIST_CALLBACK)(void *Context,
219 struct htc_endpoint_credit_dist *pEPList,
220 HTC_CREDIT_DIST_REASON Reason);
221
222typedef void (*HTC_CREDIT_INIT_CALLBACK)(void *Context,
223 struct htc_endpoint_credit_dist *pEPList,
224 int TotalCredits);
225
226 /* endpoint statistics action */
227typedef enum _HTC_ENDPOINT_STAT_ACTION {
228 HTC_EP_STAT_SAMPLE = 0, /* only read statistics */
229 HTC_EP_STAT_SAMPLE_AND_CLEAR = 1, /* sample and immediately clear statistics */
230 HTC_EP_STAT_CLEAR /* clear only */
231} HTC_ENDPOINT_STAT_ACTION;
232
233 /* endpoint statistics */
234struct htc_endpoint_stats {
235 u32 TxCreditLowIndications; /* number of times the host set the credit-low flag in a send message on
236 this endpoint */
237 u32 TxIssued; /* running count of total TX packets issued */
238 u32 TxPacketsBundled; /* running count of TX packets that were issued in bundles */
239 u32 TxBundles; /* running count of TX bundles that were issued */
240 u32 TxDropped; /* tx packets that were dropped */
241 u32 TxCreditRpts; /* running count of total credit reports received for this endpoint */
242 u32 TxCreditRptsFromRx; /* credit reports received from this endpoint's RX packets */
243 u32 TxCreditRptsFromOther; /* credit reports received from RX packets of other endpoints */
244 u32 TxCreditRptsFromEp0; /* credit reports received from endpoint 0 RX packets */
245 u32 TxCreditsFromRx; /* count of credits received via Rx packets on this endpoint */
246 u32 TxCreditsFromOther; /* count of credits received via another endpoint */
247 u32 TxCreditsFromEp0; /* count of credits received via another endpoint */
248 u32 TxCreditsConsummed; /* count of consummed credits */
249 u32 TxCreditsReturned; /* count of credits returned */
250 u32 RxReceived; /* count of RX packets received */
251 u32 RxLookAheads; /* count of lookahead records
252 found in messages received on this endpoint */
253 u32 RxPacketsBundled; /* count of recv packets received in a bundle */
254 u32 RxBundleLookAheads; /* count of number of bundled lookaheads */
255 u32 RxBundleIndFromHdr; /* count of the number of bundle indications from the HTC header */
256 u32 RxAllocThreshHit; /* count of the number of times the recv allocation threshold was hit */
257 u32 RxAllocThreshBytes; /* total number of bytes */
258};
259
260/* ------ Function Prototypes ------ */
261/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
262 @desc: Create an instance of HTC over the underlying HIF device
263 @function name: HTCCreate
264 @input: HifDevice - hif device handle,
265 pInfo - initialization information
266 @output:
267 @return: HTC_HANDLE on success, NULL on failure
268 @notes:
269 @example:
270 @see also: HTCDestroy
271+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
272HTC_HANDLE HTCCreate(void *HifDevice, struct htc_init_info *pInfo);
273/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
274 @desc: Get the underlying HIF device handle
275 @function name: HTCGetHifDevice
276 @input: HTCHandle - handle passed into the AddInstance callback
277 @output:
278 @return: opaque HIF device handle usable in HIF API calls.
279 @notes:
280 @example:
281 @see also:
282+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
283void *HTCGetHifDevice(HTC_HANDLE HTCHandle);
284/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
285 @desc: Set credit distribution parameters
286 @function name: HTCSetCreditDistribution
287 @input: HTCHandle - HTC handle
288 pCreditDistCont - caller supplied context to pass into distribution functions
289 CreditDistFunc - Distribution function callback
290 CreditDistInit - Credit Distribution initialization callback
291 ServicePriorityOrder - Array containing list of service IDs, lowest index is highest
292 priority
293 ListLength - number of elements in ServicePriorityOrder
294 @output:
295 @return:
296 @notes: The user can set a custom credit distribution function to handle special requirements
297 for each endpoint. A default credit distribution routine can be used by setting
298 CreditInitFunc to NULL. The default credit distribution is only provided for simple
299 "fair" credit distribution without regard to any prioritization.
300
301 @example:
302 @see also:
303+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
304void HTCSetCreditDistribution(HTC_HANDLE HTCHandle,
305 void *pCreditDistContext,
306 HTC_CREDIT_DIST_CALLBACK CreditDistFunc,
307 HTC_CREDIT_INIT_CALLBACK CreditInitFunc,
308 HTC_SERVICE_ID ServicePriorityOrder[],
309 int ListLength);
310/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
311 @desc: Wait for the target to indicate the HTC layer is ready
312 @function name: HTCWaitTarget
313 @input: HTCHandle - HTC handle
314 @output:
315 @return:
316 @notes: This API blocks until the target responds with an HTC ready message.
317 The caller should not connect services until the target has indicated it is
318 ready.
319 @example:
320 @see also: HTCConnectService
321+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
322int HTCWaitTarget(HTC_HANDLE HTCHandle);
323/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
324 @desc: Start target service communications
325 @function name: HTCStart
326 @input: HTCHandle - HTC handle
327 @output:
328 @return:
329 @notes: This API indicates to the target that the service connection phase is complete
330 and the target can freely start all connected services. This API should only be
331 called AFTER all service connections have been made. TCStart will issue a
332 SETUP_COMPLETE message to the target to indicate that all service connections
333 have been made and the target can start communicating over the endpoints.
334 @example:
335 @see also: HTCConnectService
336+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
337int HTCStart(HTC_HANDLE HTCHandle);
338/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
339 @desc: Add receive packet to HTC
340 @function name: HTCAddReceivePkt
341 @input: HTCHandle - HTC handle
342 pPacket - HTC receive packet to add
343 @output:
344 @return: 0 on success
345 @notes: user must supply HTC packets for capturing incomming HTC frames. The caller
346 must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL()
347 macro.
348 @example:
349 @see also:
350+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
351int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket);
352/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
353 @desc: Connect to an HTC service
354 @function name: HTCConnectService
355 @input: HTCHandle - HTC handle
356 pReq - connection details
357 @output: pResp - connection response
358 @return:
359 @notes: Service connections must be performed before HTCStart. User provides callback handlers
360 for various endpoint events.
361 @example:
362 @see also: HTCStart
363+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
364int HTCConnectService(HTC_HANDLE HTCHandle,
365 struct htc_service_connect_req *pReq,
366 struct htc_service_connect_resp *pResp);
367/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
368 @desc: Send an HTC packet
369 @function name: HTCSendPkt
370 @input: HTCHandle - HTC handle
371 pPacket - packet to send
372 @output:
373 @return: 0
374 @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() macro.
375 This interface is fully asynchronous. On error, HTC SendPkt will
376 call the registered Endpoint callback to cleanup the packet.
377 @example:
378 @see also: HTCFlushEndpoint
379+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
380int HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket);
381/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
382 @desc: Stop HTC service communications
383 @function name: HTCStop
384 @input: HTCHandle - HTC handle
385 @output:
386 @return:
387 @notes: HTC communications is halted. All receive and pending TX packets will
388 be flushed.
389 @example:
390 @see also:
391+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
392void HTCStop(HTC_HANDLE HTCHandle);
393/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
394 @desc: Destroy HTC service
395 @function name: HTCDestroy
396 @input: HTCHandle
397 @output:
398 @return:
399 @notes: This cleans up all resources allocated by HTCCreate().
400 @example:
401 @see also: HTCCreate
402+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
403void HTCDestroy(HTC_HANDLE HTCHandle);
404/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
405 @desc: Flush pending TX packets
406 @function name: HTCFlushEndpoint
407 @input: HTCHandle - HTC handle
408 Endpoint - Endpoint to flush
409 Tag - flush tag
410 @output:
411 @return:
412 @notes: The Tag parameter is used to selectively flush packets with matching tags.
413 The value of 0 forces all packets to be flush regardless of tag.
414 @example:
415 @see also: HTCSendPkt
416+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
417void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag);
418/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
419 @desc: Dump credit distribution state
420 @function name: HTCDumpCreditStates
421 @input: HTCHandle - HTC handle
422 @output:
423 @return:
424 @notes: This dumps all credit distribution information to the debugger
425 @example:
426 @see also:
427+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
428void HTCDumpCreditStates(HTC_HANDLE HTCHandle);
429/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
430 @desc: Indicate a traffic activity change on an endpoint
431 @function name: HTCIndicateActivityChange
432 @input: HTCHandle - HTC handle
433 Endpoint - endpoint in which activity has changed
434 Active - true if active, false if it has become inactive
435 @output:
436 @return:
437 @notes: This triggers the registered credit distribution function to
438 re-adjust credits for active/inactive endpoints.
439 @example:
440 @see also:
441+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
442void HTCIndicateActivityChange(HTC_HANDLE HTCHandle,
443 HTC_ENDPOINT_ID Endpoint,
444 bool Active);
445
446/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
447 @desc: Get endpoint statistics
448 @function name: HTCGetEndpointStatistics
449 @input: HTCHandle - HTC handle
450 Endpoint - Endpoint identifier
451 Action - action to take with statistics
452 @output:
453 pStats - statistics that were sampled (can be NULL if Action is HTC_EP_STAT_CLEAR)
454
455 @return: true if statistics profiling is enabled, otherwise false.
456
457 @notes: Statistics is a compile-time option and this function may return false
458 if HTC is not compiled with profiling.
459
460 The caller can specify the statistic "action" to take when sampling
461 the statistics. This includes:
462
463 HTC_EP_STAT_SAMPLE: The pStats structure is filled with the current values.
464 HTC_EP_STAT_SAMPLE_AND_CLEAR: The structure is filled and the current statistics
465 are cleared.
466 HTC_EP_STAT_CLEA : the statistics are cleared, the called can pass a NULL value for
467 pStats
468
469 @example:
470 @see also:
471+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
472bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle,
473 HTC_ENDPOINT_ID Endpoint,
474 HTC_ENDPOINT_STAT_ACTION Action,
475 struct htc_endpoint_stats *pStats);
476
477/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
478 @desc: Unblock HTC message reception
479 @function name: HTCUnblockRecv
480 @input: HTCHandle - HTC handle
481 @output:
482 @return:
483 @notes:
484 HTC will block the receiver if the EpRecvAlloc callback fails to provide a packet.
485 The caller can use this API to indicate to HTC when resources (buffers) are available
486 such that the receiver can be unblocked and HTC may re-attempt fetching the pending message.
487
488 This API is not required if the user uses the EpRecvRefill callback or uses the HTCAddReceivePacket()
489 API to recycle or provide receive packets to HTC.
490
491 @example:
492 @see also:
493+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
494void HTCUnblockRecv(HTC_HANDLE HTCHandle);
495
496/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
497 @desc: send a series of HTC packets
498 @function name: HTCSendPktsMultiple
499 @input: HTCHandle - HTC handle
500 pPktQueue - local queue holding packets to send
501 @output:
502 @return: 0
503 @notes: Caller must initialize each packet using SET_HTC_PACKET_INFO_TX() macro.
504 The queue must only contain packets directed at the same endpoint.
505 Caller supplies a pointer to an struct htc_packet_queue structure holding the TX packets in FIFO order.
506 This API will remove the packets from the pkt queue and place them into the HTC Tx Queue
507 and bundle messages where possible.
508 The caller may allocate the pkt queue on the stack to hold the packets.
509 This interface is fully asynchronous. On error, HTCSendPkts will
510 call the registered Endpoint callback to cleanup the packet.
511 @example:
512 @see also: HTCFlushEndpoint
513+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
514int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue);
515
516/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
517 @desc: Add multiple receive packets to HTC
518 @function name: HTCAddReceivePktMultiple
519 @input: HTCHandle - HTC handle
520 pPktQueue - HTC receive packet queue holding packets to add
521 @output:
522 @return: 0 on success
523 @notes: user must supply HTC packets for capturing incomming HTC frames. The caller
524 must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL()
525 macro. The queue must only contain recv packets for the same endpoint.
526 Caller supplies a pointer to an struct htc_packet_queue structure holding the recv packet.
527 This API will remove the packets from the pkt queue and place them into internal
528 recv packet list.
529 The caller may allocate the pkt queue on the stack to hold the packets.
530 @example:
531 @see also:
532+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
533int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue);
534
535/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
536 @desc: Check if an endpoint is marked active
537 @function name: HTCIsEndpointActive
538 @input: HTCHandle - HTC handle
539 Endpoint - endpoint to check for active state
540 @output:
541 @return: returns true if Endpoint is Active
542 @notes:
543 @example:
544 @see also:
545+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
546bool HTCIsEndpointActive(HTC_HANDLE HTCHandle,
547 HTC_ENDPOINT_ID Endpoint);
548
549
550/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
551 @desc: Get the number of recv buffers currently queued into an HTC endpoint
552 @function name: HTCGetNumRecvBuffers
553 @input: HTCHandle - HTC handle
554 Endpoint - endpoint to check
555 @output:
556 @return: returns number of buffers in queue
557 @notes:
558 @example:
559 @see also:
560+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
561int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle,
562 HTC_ENDPOINT_ID Endpoint);
563
564/* internally used functions for testing... */
565void HTCEnableRecv(HTC_HANDLE HTCHandle);
566void HTCDisableRecv(HTC_HANDLE HTCHandle);
567int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle,
568 u32 TimeoutInMs,
569 bool *pbIsRecvPending);
570
571#ifdef __cplusplus
572}
573#endif
574
575#endif /* _HTC_API_H_ */
diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h
deleted file mode 100644
index ba65c34ebc9..00000000000
--- a/drivers/staging/ath6kl/include/htc_packet.h
+++ /dev/null
@@ -1,227 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_packet.h" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef HTC_PACKET_H_
24#define HTC_PACKET_H_
25
26
27#include "dl_list.h"
28
29/* ------ Endpoint IDS ------ */
30typedef enum
31{
32 ENDPOINT_UNUSED = -1,
33 ENDPOINT_0 = 0,
34 ENDPOINT_1 = 1,
35 ENDPOINT_2 = 2,
36 ENDPOINT_3,
37 ENDPOINT_4,
38 ENDPOINT_5,
39 ENDPOINT_6,
40 ENDPOINT_7,
41 ENDPOINT_8,
42 ENDPOINT_MAX,
43} HTC_ENDPOINT_ID;
44
45struct htc_packet;
46
47typedef void (* HTC_PACKET_COMPLETION)(void *,struct htc_packet *);
48
49typedef u16 HTC_TX_TAG;
50
51struct htc_tx_packet_info {
52 HTC_TX_TAG Tag; /* tag used to selective flush packets */
53 int CreditsUsed; /* number of credits used for this TX packet (HTC internal) */
54 u8 SendFlags; /* send flags (HTC internal) */
55 int SeqNo; /* internal seq no for debugging (HTC internal) */
56};
57
58#define HTC_TX_PACKET_TAG_ALL 0 /* a tag of zero is reserved and used to flush ALL packets */
59#define HTC_TX_PACKET_TAG_INTERNAL 1 /* internal tags start here */
60#define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_TX_PACKET_TAG_INTERNAL + 9) /* user-defined tags start here */
61
62struct htc_rx_packet_info {
63 u32 ExpectedHdr; /* HTC internal use */
64 u32 HTCRxFlags; /* HTC internal use */
65 u32 IndicationFlags; /* indication flags set on each RX packet indication */
66};
67
68#define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0) /* more packets on this endpoint are being fetched */
69
70/* wrapper around endpoint-specific packets */
71struct htc_packet {
72 struct dl_list ListLink; /* double link */
73 void *pPktContext; /* caller's per packet specific context */
74
75 u8 *pBufferStart; /* the true buffer start , the caller can
76 store the real buffer start here. In
77 receive callbacks, the HTC layer sets pBuffer
78 to the start of the payload past the header. This
79 field allows the caller to reset pBuffer when it
80 recycles receive packets back to HTC */
81 /*
82 * Pointer to the start of the buffer. In the transmit
83 * direction this points to the start of the payload. In the
84 * receive direction, however, the buffer when queued up
85 * points to the start of the HTC header but when returned
86 * to the caller points to the start of the payload
87 */
88 u8 *pBuffer; /* payload start (RX/TX) */
89 u32 BufferLength; /* length of buffer */
90 u32 ActualLength; /* actual length of payload */
91 HTC_ENDPOINT_ID Endpoint; /* endpoint that this packet was sent/recv'd from */
92 int Status; /* completion status */
93 union {
94 struct htc_tx_packet_info AsTx; /* Tx Packet specific info */
95 struct htc_rx_packet_info AsRx; /* Rx Packet specific info */
96 } PktInfo;
97
98 /* the following fields are for internal HTC use */
99 HTC_PACKET_COMPLETION Completion; /* completion */
100 void *pContext; /* HTC private completion context */
101};
102
103
104
105#define COMPLETE_HTC_PACKET(p,status) \
106{ \
107 (p)->Status = (status); \
108 (p)->Completion((p)->pContext,(p)); \
109}
110
111#define INIT_HTC_PACKET_INFO(p,b,len) \
112{ \
113 (p)->pBufferStart = (b); \
114 (p)->BufferLength = (len); \
115}
116
117/* macro to set an initial RX packet for refilling HTC */
118#define SET_HTC_PACKET_INFO_RX_REFILL(p,c,b,len,ep) \
119{ \
120 (p)->pPktContext = (c); \
121 (p)->pBuffer = (b); \
122 (p)->pBufferStart = (b); \
123 (p)->BufferLength = (len); \
124 (p)->Endpoint = (ep); \
125}
126
127/* fast macro to recycle an RX packet that will be re-queued to HTC */
128#define HTC_PACKET_RESET_RX(p) \
129 { (p)->pBuffer = (p)->pBufferStart; (p)->ActualLength = 0; }
130
131/* macro to set packet parameters for TX */
132#define SET_HTC_PACKET_INFO_TX(p,c,b,len,ep,tag) \
133{ \
134 (p)->pPktContext = (c); \
135 (p)->pBuffer = (b); \
136 (p)->ActualLength = (len); \
137 (p)->Endpoint = (ep); \
138 (p)->PktInfo.AsTx.Tag = (tag); \
139}
140
141/* HTC Packet Queueing Macros */
142struct htc_packet_queue {
143 struct dl_list QueueHead;
144 int Depth;
145};
146
147/* initialize queue */
148#define INIT_HTC_PACKET_QUEUE(pQ) \
149{ \
150 DL_LIST_INIT(&(pQ)->QueueHead); \
151 (pQ)->Depth = 0; \
152}
153
154/* enqueue HTC packet to the tail of the queue */
155#define HTC_PACKET_ENQUEUE(pQ,p) \
156{ DL_ListInsertTail(&(pQ)->QueueHead,&(p)->ListLink); \
157 (pQ)->Depth++; \
158}
159
160/* enqueue HTC packet to the tail of the queue */
161#define HTC_PACKET_ENQUEUE_TO_HEAD(pQ,p) \
162{ DL_ListInsertHead(&(pQ)->QueueHead,&(p)->ListLink); \
163 (pQ)->Depth++; \
164}
165/* test if a queue is empty */
166#define HTC_QUEUE_EMPTY(pQ) ((pQ)->Depth == 0)
167/* get packet at head without removing it */
168static INLINE struct htc_packet *HTC_GET_PKT_AT_HEAD(struct htc_packet_queue *queue) {
169 if (queue->Depth == 0) {
170 return NULL;
171 }
172 return A_CONTAINING_STRUCT((DL_LIST_GET_ITEM_AT_HEAD(&queue->QueueHead)),struct htc_packet,ListLink);
173}
174/* remove a packet from a queue, where-ever it is in the queue */
175#define HTC_PACKET_REMOVE(pQ,p) \
176{ \
177 DL_ListRemove(&(p)->ListLink); \
178 (pQ)->Depth--; \
179}
180
181/* dequeue an HTC packet from the head of the queue */
182static INLINE struct htc_packet *HTC_PACKET_DEQUEUE(struct htc_packet_queue *queue) {
183 struct dl_list *pItem = DL_ListRemoveItemFromHead(&queue->QueueHead);
184 if (pItem != NULL) {
185 queue->Depth--;
186 return A_CONTAINING_STRUCT(pItem, struct htc_packet, ListLink);
187 }
188 return NULL;
189}
190
191/* dequeue an HTC packet from the tail of the queue */
192static INLINE struct htc_packet *HTC_PACKET_DEQUEUE_TAIL(struct htc_packet_queue *queue) {
193 struct dl_list *pItem = DL_ListRemoveItemFromTail(&queue->QueueHead);
194 if (pItem != NULL) {
195 queue->Depth--;
196 return A_CONTAINING_STRUCT(pItem, struct htc_packet, ListLink);
197 }
198 return NULL;
199}
200
201#define HTC_PACKET_QUEUE_DEPTH(pQ) (pQ)->Depth
202
203
204#define HTC_GET_ENDPOINT_FROM_PKT(p) (p)->Endpoint
205#define HTC_GET_TAG_FROM_PKT(p) (p)->PktInfo.AsTx.Tag
206
207 /* transfer the packets from one queue to the tail of another queue */
208#define HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(pQDest,pQSrc) \
209{ \
210 DL_ListTransferItemsToTail(&(pQDest)->QueueHead,&(pQSrc)->QueueHead); \
211 (pQDest)->Depth += (pQSrc)->Depth; \
212 (pQSrc)->Depth = 0; \
213}
214
215 /* fast version to init and add a single packet to a queue */
216#define INIT_HTC_PACKET_QUEUE_AND_ADD(pQ,pP) \
217{ \
218 DL_LIST_INIT_AND_ADD(&(pQ)->QueueHead,&(pP)->ListLink) \
219 (pQ)->Depth = 1; \
220}
221
222#define HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pQ, pPTemp) \
223 ITERATE_OVER_LIST_ALLOW_REMOVE(&(pQ)->QueueHead,(pPTemp), struct htc_packet, ListLink)
224
225#define HTC_PACKET_QUEUE_ITERATE_END ITERATE_END
226
227#endif /*HTC_PACKET_H_*/
diff --git a/drivers/staging/ath6kl/include/wlan_api.h b/drivers/staging/ath6kl/include/wlan_api.h
deleted file mode 100644
index 9eea5875dd3..00000000000
--- a/drivers/staging/ath6kl/include/wlan_api.h
+++ /dev/null
@@ -1,128 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// This file contains the API for the host wlan module
21//
22// Author(s): ="Atheros"
23//==============================================================================
24#ifndef _HOST_WLAN_API_H_
25#define _HOST_WLAN_API_H_
26
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#include <a_osapi.h>
33
34struct ieee80211_node_table;
35struct ieee80211_frame;
36
37struct ieee80211_common_ie {
38 u16 ie_chan;
39 u8 *ie_tstamp;
40 u8 *ie_ssid;
41 u8 *ie_rates;
42 u8 *ie_xrates;
43 u8 *ie_country;
44 u8 *ie_wpa;
45 u8 *ie_rsn;
46 u8 *ie_wmm;
47 u8 *ie_ath;
48 u16 ie_capInfo;
49 u16 ie_beaconInt;
50 u8 *ie_tim;
51 u8 *ie_chswitch;
52 u8 ie_erp;
53 u8 *ie_wsc;
54 u8 *ie_htcap;
55 u8 *ie_htop;
56#ifdef WAPI_ENABLE
57 u8 *ie_wapi;
58#endif
59};
60
61typedef struct bss {
62 u8 ni_macaddr[6];
63 u8 ni_snr;
64 s16 ni_rssi;
65 struct bss *ni_list_next;
66 struct bss *ni_list_prev;
67 struct bss *ni_hash_next;
68 struct bss *ni_hash_prev;
69 struct ieee80211_common_ie ni_cie;
70 u8 *ni_buf;
71 u16 ni_framelen;
72 struct ieee80211_node_table *ni_table;
73 u32 ni_refcnt;
74 int ni_scangen;
75
76 u32 ni_tstamp;
77 u32 ni_actcnt;
78#ifdef OS_ROAM_MANAGEMENT
79 u32 ni_si_gen;
80#endif
81} bss_t;
82
83typedef void wlan_node_iter_func(void *arg, bss_t *);
84
85bss_t *wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size);
86void wlan_node_free(bss_t *ni);
87void wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,
88 const u8 *macaddr);
89bss_t *wlan_find_node(struct ieee80211_node_table *nt, const u8 *macaddr);
90void wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni);
91void wlan_free_allnodes(struct ieee80211_node_table *nt);
92void wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,
93 void *arg);
94
95void wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt);
96void wlan_node_table_reset(struct ieee80211_node_table *nt);
97void wlan_node_table_cleanup(struct ieee80211_node_table *nt);
98
99int wlan_parse_beacon(u8 *buf, int framelen,
100 struct ieee80211_common_ie *cie);
101
102u16 wlan_ieee2freq(int chan);
103u32 wlan_freq2ieee(u16 freq);
104
105void wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge);
106
107void
108wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt);
109
110bss_t *
111wlan_find_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
112 u32 ssidLength, bool bIsWPA2, bool bMatchSSID);
113
114void
115wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni);
116
117bss_t *wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid);
118
119bss_t *
120wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
121 u32 ssidLength, u32 dot11AuthMode, u32 authMode,
122 u32 pairwiseCryptoType, u32 grpwiseCryptoTyp);
123
124#ifdef __cplusplus
125}
126#endif
127
128#endif /* _HOST_WLAN_API_H_ */
diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h
deleted file mode 100644
index c8583e0c4a9..00000000000
--- a/drivers/staging/ath6kl/include/wmi_api.h
+++ /dev/null
@@ -1,441 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="wmi_api.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains the definitions for the Wireless Module Interface (WMI).
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _WMI_API_H_
26#define _WMI_API_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32 /* WMI converts a dix frame with an ethernet payload (up to 1500 bytes)
33 * to an 802.3 frame (adds SNAP header) and adds on a WMI data header */
34#define WMI_MAX_TX_DATA_FRAME_LENGTH (1500 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR))
35
36 /* A normal WMI data frame */
37#define WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH (1500 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR))
38
39 /* An AMSDU frame */ /* The MAX AMSDU length of AR6003 is 3839 */
40#define WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH (3840 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR))
41
42/*
43 * IP QoS Field definitions according to 802.1p
44 */
45#define BEST_EFFORT_PRI 0
46#define BACKGROUND_PRI 1
47#define EXCELLENT_EFFORT_PRI 3
48#define CONTROLLED_LOAD_PRI 4
49#define VIDEO_PRI 5
50#define VOICE_PRI 6
51#define NETWORK_CONTROL_PRI 7
52#define MAX_NUM_PRI 8
53
54#define UNDEFINED_PRI (0xff)
55
56#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 /* 5 seconds */
57
58#define A_ROUND_UP(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
59
60typedef enum {
61 ATHEROS_COMPLIANCE = 0x1,
62}TSPEC_PARAM_COMPLIANCE;
63
64struct wmi_t;
65
66void *wmi_init(void *devt);
67
68void wmi_qos_state_init(struct wmi_t *wmip);
69void wmi_shutdown(struct wmi_t *wmip);
70HTC_ENDPOINT_ID wmi_get_control_ep(struct wmi_t * wmip);
71void wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid);
72u16 wmi_get_mapped_qos_queue(struct wmi_t *, u8 );
73int wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf);
74int wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS);
75int wmi_dot3_2_dix(void *osbuf);
76
77int wmi_dot11_hdr_remove (struct wmi_t *wmip, void *osbuf);
78int wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode);
79
80int wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf);
81int wmi_syncpoint(struct wmi_t *wmip);
82int wmi_syncpoint_reset(struct wmi_t *wmip);
83u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled);
84
85u8 wmi_determine_userPriority (u8 *pkt, u32 layer2Pri);
86
87int wmi_control_rx(struct wmi_t *wmip, void *osbuf);
88void wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg);
89void wmi_free_allnodes(struct wmi_t *wmip);
90bss_t *wmi_find_node(struct wmi_t *wmip, const u8 *macaddr);
91void wmi_free_node(struct wmi_t *wmip, const u8 *macaddr);
92
93
94typedef enum {
95 NO_SYNC_WMIFLAG = 0,
96 SYNC_BEFORE_WMIFLAG, /* transmit all queued data before cmd */
97 SYNC_AFTER_WMIFLAG, /* any new data waits until cmd execs */
98 SYNC_BOTH_WMIFLAG,
99 END_WMIFLAG /* end marker */
100} WMI_SYNC_FLAG;
101
102int wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
103 WMI_SYNC_FLAG flag);
104
105int wmi_connect_cmd(struct wmi_t *wmip,
106 NETWORK_TYPE netType,
107 DOT11_AUTH_MODE dot11AuthMode,
108 AUTH_MODE authMode,
109 CRYPTO_TYPE pairwiseCrypto,
110 u8 pairwiseCryptoLen,
111 CRYPTO_TYPE groupCrypto,
112 u8 groupCryptoLen,
113 int ssidLength,
114 u8 *ssid,
115 u8 *bssid,
116 u16 channel,
117 u32 ctrl_flags);
118
119int wmi_reconnect_cmd(struct wmi_t *wmip,
120 u8 *bssid,
121 u16 channel);
122int wmi_disconnect_cmd(struct wmi_t *wmip);
123int wmi_getrev_cmd(struct wmi_t *wmip);
124int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
125 u32 forceFgScan, u32 isLegacy,
126 u32 homeDwellTime, u32 forceScanInterval,
127 s8 numChan, u16 *channelList);
128int wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec,
129 u16 fg_end_sec, u16 bg_sec,
130 u16 minact_chdw_msec,
131 u16 maxact_chdw_msec, u16 pas_chdw_msec,
132 u8 shScanRatio, u8 scanCtrlFlags,
133 u32 max_dfsch_act_time,
134 u16 maxact_scan_per_ssid);
135int wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask);
136int wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag,
137 u8 ssidLength, u8 *ssid);
138int wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons);
139int wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmisstime, u16 bmissbeacons);
140int wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType,
141 u8 ieLen, u8 *ieInfo);
142int wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode);
143int wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl,
144 u16 atim_windows, u16 timeout_value);
145int wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time,
146 u32 ps_period, u8 sleep_period);
147int wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod,
148 u16 psPollNum, u16 dtimPolicy,
149 u16 wakup_tx_policy, u16 num_tx_to_wakeup,
150 u16 ps_fail_event_policy);
151int wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout);
152int wmi_sync_cmd(struct wmi_t *wmip, u8 syncNumber);
153int wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream);
154int wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 streamID);
155int wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask);
156int wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate);
157int wmi_get_bitrate_cmd(struct wmi_t *wmip);
158s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx);
159int wmi_get_regDomain_cmd(struct wmi_t *wmip);
160int wmi_get_channelList_cmd(struct wmi_t *wmip);
161int wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam,
162 WMI_PHY_MODE mode, s8 numChan,
163 u16 *channelList);
164
165int wmi_set_snr_threshold_params(struct wmi_t *wmip,
166 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
167int wmi_set_rssi_threshold_params(struct wmi_t *wmip,
168 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
169int wmi_clr_rssi_snr(struct wmi_t *wmip);
170int wmi_set_lq_threshold_params(struct wmi_t *wmip,
171 WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd);
172int wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold);
173int wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy);
174
175int wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 bitmask);
176
177int wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie,
178 u32 source);
179
180int wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask,
181 u16 tsr, bool rep, u16 size,
182 u32 valid);
183
184int wmi_get_stats_cmd(struct wmi_t *wmip);
185
186int wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex,
187 CRYPTO_TYPE keyType, u8 keyUsage,
188 u8 keyLength,u8 *keyRSC,
189 u8 *keyMaterial, u8 key_op_ctrl, u8 *mac,
190 WMI_SYNC_FLAG sync_flag);
191int wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk);
192int wmi_delete_krk_cmd(struct wmi_t *wmip);
193int wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex);
194int wmi_set_akmp_params_cmd(struct wmi_t *wmip,
195 WMI_SET_AKMP_PARAMS_CMD *akmpParams);
196int wmi_get_pmkid_list_cmd(struct wmi_t *wmip);
197int wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
198 WMI_SET_PMKID_LIST_CMD *pmkInfo);
199int wmi_abort_scan_cmd(struct wmi_t *wmip);
200int wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM);
201int wmi_get_txPwr_cmd(struct wmi_t *wmip);
202int wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid);
203int wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex);
204int wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en);
205int wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId,
206 bool set);
207int wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop,
208 u8 eCWmin, u8 eCWmax,
209 u8 aifsn);
210int wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType,
211 u8 trafficClass, u8 maxRetries,
212 u8 enableNotify);
213
214void wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid);
215
216int wmi_get_roam_tbl_cmd(struct wmi_t *wmip);
217int wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType);
218int wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
219 u8 size);
220int wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
221 WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
222 u8 size);
223
224int wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode);
225int wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
226 u8 frmType,
227 u8 *dstMacAddr,
228 u8 *bssid,
229 u16 optIEDataLen,
230 u8 *optIEData);
231
232int wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl);
233int wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize);
234int wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSpLen);
235u8 convert_userPriority_to_trafficClass(u8 userPriority);
236u8 wmi_get_power_mode_cmd(struct wmi_t *wmip);
237int wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance);
238
239#ifdef CONFIG_HOST_TCMD_SUPPORT
240int wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len);
241#endif
242
243int wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status);
244int wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd);
245
246int wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd);
247
248int wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
249 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd);
250
251int wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
252 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *cmd);
253
254int wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
255 WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd);
256
257int wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
258 WMI_SET_BTCOEX_A2DP_CONFIG_CMD* cmd);
259
260
261int wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD* cmd);
262
263int wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd);
264
265int wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
266 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd);
267
268int wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd);
269
270int wmi_get_btcoex_stats_cmd(struct wmi_t * wmip);
271
272int wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold);
273
274/*
275 * This function is used to configure the fix rates mask to the target.
276 */
277int wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask);
278int wmi_get_ratemask_cmd(struct wmi_t *wmip);
279
280int wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode);
281
282int wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode);
283
284int wmi_set_qos_supp_cmd(struct wmi_t *wmip,u8 status);
285int wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status);
286int wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG txEnable);
287int wmi_set_country(struct wmi_t *wmip, u8 *countryCode);
288
289int wmi_get_keepalive_configured(struct wmi_t *wmip);
290u8 wmi_get_keepalive_cmd(struct wmi_t *wmip);
291int wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval);
292
293int wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType,
294 u8 ieLen,u8 *ieInfo);
295
296int wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen);
297
298s32 wmi_get_rate(s8 rateindex);
299
300int wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *cmd);
301
302/*Wake on Wireless WMI commands*/
303int wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD *cmd);
304int wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *cmd);
305int wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *cmd);
306int wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
307 WMI_ADD_WOW_PATTERN_CMD *cmd, u8 *pattern, u8 *mask, u8 pattern_size);
308int wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
309 WMI_DEL_WOW_PATTERN_CMD *cmd);
310int wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status);
311
312int
313wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer);
314
315int
316wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4);
317
318int
319wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4);
320
321int
322wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable);
323
324bss_t *
325wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
326 u32 ssidLength, bool bIsWPA2, bool bMatchSSID);
327
328
329void
330wmi_node_return (struct wmi_t *wmip, bss_t *bss);
331
332void
333wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge);
334
335#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
336int wmi_prof_cfg_cmd(struct wmi_t *wmip, u32 period, u32 nbins);
337int wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr);
338int wmi_prof_start_cmd(struct wmi_t *wmip);
339int wmi_prof_stop_cmd(struct wmi_t *wmip);
340int wmi_prof_count_get_cmd(struct wmi_t *wmip);
341#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
342#ifdef OS_ROAM_MANAGEMENT
343void wmi_scan_indication (struct wmi_t *wmip);
344#endif
345
346int
347wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd);
348
349bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id);
350int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss);
351
352
353/*
354 * AP mode
355 */
356int
357wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p);
358
359int
360wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid);
361
362int
363wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta);
364
365int
366wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy);
367
368int
369wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *a);
370
371u8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl);
372
373int
374wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason);
375
376int
377wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag);
378
379int
380wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period);
381
382int
383wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell);
384
385int
386wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim);
387
388int
389wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset);
390
391int
392wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd);
393
394int
395wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width);
396
397int
398wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz);
399
400int
401wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray);
402
403int
404wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid);
405
406int
407wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink);
408
409int
410wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask);
411
412int
413wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion, bool rxDot11Hdr, bool defragOnHost);
414
415int
416wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode);
417
418int
419wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence);
420
421int
422wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk);
423
424int
425wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd);
426
427u16 wmi_ieee2freq (int chan);
428
429u32 wmi_freq2ieee (u16 freq);
430
431bss_t *
432wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
433 u32 ssidLength,
434 u32 dot11AuthMode, u32 authMode,
435 u32 pairwiseCryptoType, u32 grpwiseCryptoTyp);
436
437#ifdef __cplusplus
438}
439#endif
440
441#endif /* _WMI_API_H_ */
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c
deleted file mode 100644
index e0ea2183019..00000000000
--- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c
+++ /dev/null
@@ -1,565 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// AR3K configuration implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25#include "a_config.h"
26#include "athdefs.h"
27#include "a_osapi.h"
28#define ATH_MODULE_NAME misc
29#include "a_debug.h"
30#include "common_drv.h"
31#ifdef EXPORT_HCI_BRIDGE_INTERFACE
32#include "export_hci_transport.h"
33#else
34#include "hci_transport_api.h"
35#endif
36#include "ar3kconfig.h"
37#include "tlpm.h"
38
39#define BAUD_CHANGE_COMMAND_STATUS_OFFSET 5
40#define HCI_EVENT_RESP_TIMEOUTMS 3000
41#define HCI_CMD_OPCODE_BYTE_LOW_OFFSET 0
42#define HCI_CMD_OPCODE_BYTE_HI_OFFSET 1
43#define HCI_EVENT_OPCODE_BYTE_LOW 3
44#define HCI_EVENT_OPCODE_BYTE_HI 4
45#define HCI_CMD_COMPLETE_EVENT_CODE 0xE
46#define HCI_MAX_EVT_RECV_LENGTH 257
47#define EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET 5
48
49int AthPSInitialize(struct ar3k_config_info *hdev);
50
51static int SendHCICommand(struct ar3k_config_info *pConfig,
52 u8 *pBuffer,
53 int Length)
54{
55 struct htc_packet *pPacket = NULL;
56 int status = 0;
57
58 do {
59
60 pPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet));
61 if (NULL == pPacket) {
62 status = A_NO_MEMORY;
63 break;
64 }
65
66 A_MEMZERO(pPacket,sizeof(struct htc_packet));
67 SET_HTC_PACKET_INFO_TX(pPacket,
68 NULL,
69 pBuffer,
70 Length,
71 HCI_COMMAND_TYPE,
72 AR6K_CONTROL_PKT_TAG);
73
74 /* issue synchronously */
75 status = HCI_TransportSendPkt(pConfig->pHCIDev,pPacket,true);
76
77 } while (false);
78
79 if (pPacket != NULL) {
80 kfree(pPacket);
81 }
82
83 return status;
84}
85
86static int RecvHCIEvent(struct ar3k_config_info *pConfig,
87 u8 *pBuffer,
88 int *pLength)
89{
90 int status = 0;
91 struct htc_packet *pRecvPacket = NULL;
92
93 do {
94
95 pRecvPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet));
96 if (NULL == pRecvPacket) {
97 status = A_NO_MEMORY;
98 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
99 break;
100 }
101
102 A_MEMZERO(pRecvPacket,sizeof(struct htc_packet));
103
104 SET_HTC_PACKET_INFO_RX_REFILL(pRecvPacket,NULL,pBuffer,*pLength,HCI_EVENT_TYPE);
105
106 status = HCI_TransportRecvHCIEventSync(pConfig->pHCIDev,
107 pRecvPacket,
108 HCI_EVENT_RESP_TIMEOUTMS);
109 if (status) {
110 break;
111 }
112
113 *pLength = pRecvPacket->ActualLength;
114
115 } while (false);
116
117 if (pRecvPacket != NULL) {
118 kfree(pRecvPacket);
119 }
120
121 return status;
122}
123
124int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig,
125 u8 *pHCICommand,
126 int CmdLength,
127 u8 **ppEventBuffer,
128 u8 **ppBufferToFree)
129{
130 int status = 0;
131 u8 *pBuffer = NULL;
132 u8 *pTemp;
133 int length;
134 bool commandComplete = false;
135 u8 opCodeBytes[2];
136
137 do {
138
139 length = max(HCI_MAX_EVT_RECV_LENGTH,CmdLength);
140 length += pConfig->pHCIProps->HeadRoom + pConfig->pHCIProps->TailRoom;
141 length += pConfig->pHCIProps->IOBlockPad;
142
143 pBuffer = (u8 *)A_MALLOC(length);
144 if (NULL == pBuffer) {
145 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to allocate bt buffer \n"));
146 status = A_NO_MEMORY;
147 break;
148 }
149
150 /* get the opcodes to check the command complete event */
151 opCodeBytes[0] = pHCICommand[HCI_CMD_OPCODE_BYTE_LOW_OFFSET];
152 opCodeBytes[1] = pHCICommand[HCI_CMD_OPCODE_BYTE_HI_OFFSET];
153
154 /* copy HCI command */
155 memcpy(pBuffer + pConfig->pHCIProps->HeadRoom,pHCICommand,CmdLength);
156 /* send command */
157 status = SendHCICommand(pConfig,
158 pBuffer + pConfig->pHCIProps->HeadRoom,
159 CmdLength);
160 if (status) {
161 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to send HCI Command (%d) \n", status));
162 AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command");
163 break;
164 }
165
166 /* reuse buffer to capture command complete event */
167 A_MEMZERO(pBuffer,length);
168 status = RecvHCIEvent(pConfig,pBuffer,&length);
169 if (status) {
170 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI event recv failed \n"));
171 AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command");
172 break;
173 }
174
175 pTemp = pBuffer + pConfig->pHCIProps->HeadRoom;
176 if (pTemp[0] == HCI_CMD_COMPLETE_EVENT_CODE) {
177 if ((pTemp[HCI_EVENT_OPCODE_BYTE_LOW] == opCodeBytes[0]) &&
178 (pTemp[HCI_EVENT_OPCODE_BYTE_HI] == opCodeBytes[1])) {
179 commandComplete = true;
180 }
181 }
182
183 if (!commandComplete) {
184 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Unexpected HCI event : %d \n",pTemp[0]));
185 AR_DEBUG_PRINTBUF(pTemp,pTemp[1],"Unexpected HCI event");
186 status = A_ECOMM;
187 break;
188 }
189
190 if (ppEventBuffer != NULL) {
191 /* caller wants to look at the event */
192 *ppEventBuffer = pTemp;
193 if (ppBufferToFree == NULL) {
194 status = A_EINVAL;
195 break;
196 }
197 /* caller must free the buffer */
198 *ppBufferToFree = pBuffer;
199 pBuffer = NULL;
200 }
201
202 } while (false);
203
204 if (pBuffer != NULL) {
205 kfree(pBuffer);
206 }
207
208 return status;
209}
210
211static int AR3KConfigureHCIBaud(struct ar3k_config_info *pConfig)
212{
213 int status = 0;
214 u8 hciBaudChangeCommand[] = {0x0c,0xfc,0x2,0,0};
215 u16 baudVal;
216 u8 *pEvent = NULL;
217 u8 *pBufferToFree = NULL;
218
219 do {
220
221 if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR3K_BAUD) {
222 baudVal = (u16)(pConfig->AR3KBaudRate / 100);
223 hciBaudChangeCommand[3] = (u8)baudVal;
224 hciBaudChangeCommand[4] = (u8)(baudVal >> 8);
225
226 status = SendHCICommandWaitCommandComplete(pConfig,
227 hciBaudChangeCommand,
228 sizeof(hciBaudChangeCommand),
229 &pEvent,
230 &pBufferToFree);
231 if (status) {
232 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Baud rate change failed! \n"));
233 break;
234 }
235
236 if (pEvent[BAUD_CHANGE_COMMAND_STATUS_OFFSET] != 0) {
237 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
238 ("AR3K Config: Baud change command event status failed: %d \n",
239 pEvent[BAUD_CHANGE_COMMAND_STATUS_OFFSET]));
240 status = A_ECOMM;
241 break;
242 }
243
244 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
245 ("AR3K Config: Baud Changed to %d \n",pConfig->AR3KBaudRate));
246 }
247
248 if (pConfig->Flags & AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY) {
249 /* some versions of AR3K do not switch baud immediately, up to 300MS */
250 A_MDELAY(325);
251 }
252
253 if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP) {
254 /* Tell target to change UART baud rate for AR6K */
255 status = HCI_TransportSetBaudRate(pConfig->pHCIDev, pConfig->AR3KBaudRate);
256
257 if (status) {
258 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
259 ("AR3K Config: failed to set scale and step values: %d \n", status));
260 break;
261 }
262
263 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
264 ("AR3K Config: Baud changed to %d for AR6K\n", pConfig->AR3KBaudRate));
265 }
266
267 } while (false);
268
269 if (pBufferToFree != NULL) {
270 kfree(pBufferToFree);
271 }
272
273 return status;
274}
275
276static int AR3KExitMinBoot(struct ar3k_config_info *pConfig)
277{
278 int status;
279 char exitMinBootCmd[] = {0x25,0xFC,0x0c,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
280 0x00,0x00,0x00,0x00,0x00};
281 u8 *pEvent = NULL;
282 u8 *pBufferToFree = NULL;
283
284 status = SendHCICommandWaitCommandComplete(pConfig,
285 exitMinBootCmd,
286 sizeof(exitMinBootCmd),
287 &pEvent,
288 &pBufferToFree);
289
290 if (!status) {
291 if (pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET] != 0) {
292 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
293 ("AR3K Config: MinBoot exit command event status failed: %d \n",
294 pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET]));
295 status = A_ECOMM;
296 } else {
297 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
298 ("AR3K Config: MinBoot Exit Command Complete (Success) \n"));
299 A_MDELAY(1);
300 }
301 } else {
302 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: MinBoot Exit Failed! \n"));
303 }
304
305 if (pBufferToFree != NULL) {
306 kfree(pBufferToFree);
307 }
308
309 return status;
310}
311
312static int AR3KConfigureSendHCIReset(struct ar3k_config_info *pConfig)
313{
314 int status = 0;
315 u8 hciResetCommand[] = {0x03,0x0c,0x0};
316 u8 *pEvent = NULL;
317 u8 *pBufferToFree = NULL;
318
319 status = SendHCICommandWaitCommandComplete( pConfig,
320 hciResetCommand,
321 sizeof(hciResetCommand),
322 &pEvent,
323 &pBufferToFree );
324
325 if (status) {
326 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI reset failed! \n"));
327 }
328
329 if (pBufferToFree != NULL) {
330 kfree(pBufferToFree);
331 }
332
333 return status;
334}
335
336static int AR3KEnableTLPM(struct ar3k_config_info *pConfig)
337{
338 int status;
339 /* AR3K vendor specific command for Host Wakeup Config */
340 char hostWakeupConfig[] = {0x31,0xFC,0x18,
341 0x02,0x00,0x00,0x00,
342 0x01,0x00,0x00,0x00,
343 TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00, //idle timeout in ms
344 0x00,0x00,0x00,0x00,
345 TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00, //wakeup timeout in ms
346 0x00,0x00,0x00,0x00};
347 /* AR3K vendor specific command for Target Wakeup Config */
348 char targetWakeupConfig[] = {0x31,0xFC,0x18,
349 0x04,0x00,0x00,0x00,
350 0x01,0x00,0x00,0x00,
351 TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00, //idle timeout in ms
352 0x00,0x00,0x00,0x00,
353 TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00, //wakeup timeout in ms
354 0x00,0x00,0x00,0x00};
355 /* AR3K vendor specific command for Host Wakeup Enable */
356 char hostWakeupEnable[] = {0x31,0xFC,0x4,
357 0x01,0x00,0x00,0x00};
358 /* AR3K vendor specific command for Target Wakeup Enable */
359 char targetWakeupEnable[] = {0x31,0xFC,0x4,
360 0x06,0x00,0x00,0x00};
361 /* AR3K vendor specific command for Sleep Enable */
362 char sleepEnable[] = {0x4,0xFC,0x1,
363 0x1};
364 u8 *pEvent = NULL;
365 u8 *pBufferToFree = NULL;
366
367 if (0 != pConfig->IdleTimeout) {
368 u8 idle_lsb = pConfig->IdleTimeout & 0xFF;
369 u8 idle_msb = (pConfig->IdleTimeout & 0xFF00) >> 8;
370 hostWakeupConfig[11] = targetWakeupConfig[11] = idle_lsb;
371 hostWakeupConfig[12] = targetWakeupConfig[12] = idle_msb;
372 }
373
374 if (0 != pConfig->WakeupTimeout) {
375 hostWakeupConfig[19] = targetWakeupConfig[19] = (pConfig->WakeupTimeout & 0xFF);
376 }
377
378 status = SendHCICommandWaitCommandComplete(pConfig,
379 hostWakeupConfig,
380 sizeof(hostWakeupConfig),
381 &pEvent,
382 &pBufferToFree);
383 if (pBufferToFree != NULL) {
384 kfree(pBufferToFree);
385 }
386 if (status) {
387 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Config Failed! \n"));
388 return status;
389 }
390
391 pEvent = NULL;
392 pBufferToFree = NULL;
393 status = SendHCICommandWaitCommandComplete(pConfig,
394 targetWakeupConfig,
395 sizeof(targetWakeupConfig),
396 &pEvent,
397 &pBufferToFree);
398 if (pBufferToFree != NULL) {
399 kfree(pBufferToFree);
400 }
401 if (status) {
402 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Config Failed! \n"));
403 return status;
404 }
405
406 pEvent = NULL;
407 pBufferToFree = NULL;
408 status = SendHCICommandWaitCommandComplete(pConfig,
409 hostWakeupEnable,
410 sizeof(hostWakeupEnable),
411 &pEvent,
412 &pBufferToFree);
413 if (pBufferToFree != NULL) {
414 kfree(pBufferToFree);
415 }
416 if (status) {
417 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Enable Failed! \n"));
418 return status;
419 }
420
421 pEvent = NULL;
422 pBufferToFree = NULL;
423 status = SendHCICommandWaitCommandComplete(pConfig,
424 targetWakeupEnable,
425 sizeof(targetWakeupEnable),
426 &pEvent,
427 &pBufferToFree);
428 if (pBufferToFree != NULL) {
429 kfree(pBufferToFree);
430 }
431 if (status) {
432 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Enable Failed! \n"));
433 return status;
434 }
435
436 pEvent = NULL;
437 pBufferToFree = NULL;
438 status = SendHCICommandWaitCommandComplete(pConfig,
439 sleepEnable,
440 sizeof(sleepEnable),
441 &pEvent,
442 &pBufferToFree);
443 if (pBufferToFree != NULL) {
444 kfree(pBufferToFree);
445 }
446 if (status) {
447 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Sleep Enable Failed! \n"));
448 }
449
450 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Enable TLPM Completed (status = %d) \n",status));
451
452 return status;
453}
454
455int AR3KConfigure(struct ar3k_config_info *pConfig)
456{
457 int status = 0;
458
459 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuring AR3K ...\n"));
460
461 do {
462
463 if ((pConfig->pHCIDev == NULL) || (pConfig->pHCIProps == NULL) || (pConfig->pHIFDevice == NULL)) {
464 status = A_EINVAL;
465 break;
466 }
467
468 /* disable asynchronous recv while we issue commands and receive events synchronously */
469 status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,false);
470 if (status) {
471 break;
472 }
473
474 if (pConfig->Flags & AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT) {
475 status = AR3KExitMinBoot(pConfig);
476 if (status) {
477 break;
478 }
479 }
480
481
482 /* Load patching and PST file if available*/
483 if (0 != AthPSInitialize(pConfig)) {
484 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch Download Failed!\n"));
485 }
486
487 /* Send HCI reset to make PS tags take effect*/
488 AR3KConfigureSendHCIReset(pConfig);
489
490 if (pConfig->Flags &
491 (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) {
492 status = AR3KConfigureHCIBaud(pConfig);
493 if (status) {
494 break;
495 }
496 }
497
498
499
500 if (pConfig->PwrMgmtEnabled) {
501 /* the delay is required after the previous HCI reset before further
502 * HCI commands can be issued
503 */
504 A_MDELAY(200);
505 AR3KEnableTLPM(pConfig);
506 }
507
508 /* re-enable asynchronous recv */
509 status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,true);
510 if (status) {
511 break;
512 }
513
514
515 } while (false);
516
517
518 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuration Complete (status = %d) \n",status));
519
520 return status;
521}
522
523int AR3KConfigureExit(void *config)
524{
525 int status = 0;
526 struct ar3k_config_info *pConfig = (struct ar3k_config_info *)config;
527
528 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleaning up AR3K ...\n"));
529
530 do {
531
532 if ((pConfig->pHCIDev == NULL) || (pConfig->pHCIProps == NULL) || (pConfig->pHIFDevice == NULL)) {
533 status = A_EINVAL;
534 break;
535 }
536
537 /* disable asynchronous recv while we issue commands and receive events synchronously */
538 status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,false);
539 if (status) {
540 break;
541 }
542
543 if (pConfig->Flags &
544 (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) {
545 status = AR3KConfigureHCIBaud(pConfig);
546 if (status) {
547 break;
548 }
549 }
550
551 /* re-enable asynchronous recv */
552 status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,true);
553 if (status) {
554 break;
555 }
556
557
558 } while (false);
559
560
561 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleanup Complete (status = %d) \n",status));
562
563 return status;
564}
565
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c
deleted file mode 100644
index 282ceac597b..00000000000
--- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c
+++ /dev/null
@@ -1,572 +0,0 @@
1/*
2 * Copyright (c) 2004-2010 Atheros Communications Inc.
3 * All rights reserved.
4 *
5 * This file implements the Atheros PS and patch downloaded for HCI UART Transport driver.
6 * This file can be used for HCI SDIO transport implementation for AR6002 with HCI_TRANSPORT_SDIO
7 * defined.
8 *
9 *
10 * ar3kcpsconfig.c
11 *
12 *
13 *
14 * The software source and binaries included in this development package are
15 * licensed, not sold. You, or your company, received the package under one
16 * or more license agreements. The rights granted to you are specifically
17 * listed in these license agreement(s). All other rights remain with Atheros
18 * Communications, Inc., its subsidiaries, or the respective owner including
19 * those listed on the included copyright notices.. Distribution of any
20 * portion of this package must be in strict compliance with the license
21 * agreement(s) terms.
22 *
23 *
24 *
25 */
26
27
28
29#include "ar3kpsconfig.h"
30#ifndef HCI_TRANSPORT_SDIO
31#include "hci_ath.h"
32#include "hci_uart.h"
33#endif /* #ifndef HCI_TRANSPORT_SDIO */
34
35#define MAX_FW_PATH_LEN 50
36#define MAX_BDADDR_FORMAT_LENGTH 30
37
38/*
39 * Structure used to send HCI packet, hci packet length and device info
40 * together as parameter to PSThread.
41 */
42typedef struct {
43
44 struct ps_cmd_packet *HciCmdList;
45 u32 num_packets;
46 struct ar3k_config_info *dev;
47}HciCommandListParam;
48
49int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig,
50 u8 *pHCICommand,
51 int CmdLength,
52 u8 **ppEventBuffer,
53 u8 **ppBufferToFree);
54
55u32 Rom_Version;
56u32 Build_Version;
57extern bool BDADDR;
58
59int getDeviceType(struct ar3k_config_info *pConfig, u32 *code);
60int ReadVersionInfo(struct ar3k_config_info *pConfig);
61#ifndef HCI_TRANSPORT_SDIO
62
63DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent);
64DECLARE_WAIT_QUEUE_HEAD(HciEvent);
65u8 *HciEventpacket;
66rwlock_t syncLock;
67wait_queue_t Eventwait;
68
69int PSHciWritepacket(struct hci_dev*,u8* Data, u32 len);
70extern char *bdaddr;
71#endif /* HCI_TRANSPORT_SDIO */
72
73int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type);
74
75int PSSendOps(void *arg);
76
77#ifdef BT_PS_DEBUG
78void Hci_log(u8 * log_string,u8 *data,u32 len)
79{
80 int i;
81 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s : ",log_string));
82 for (i = 0; i < len; i++) {
83 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("0x%02x ", data[i]));
84 }
85 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n...................................\n"));
86}
87#else
88#define Hci_log(string,data,len)
89#endif /* BT_PS_DEBUG */
90
91
92
93
94int AthPSInitialize(struct ar3k_config_info *hdev)
95{
96 int status = 0;
97 if(hdev == NULL) {
98 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Device handle received\n"));
99 return A_ERROR;
100 }
101
102#ifndef HCI_TRANSPORT_SDIO
103 DECLARE_WAITQUEUE(wait, current);
104#endif /* HCI_TRANSPORT_SDIO */
105
106
107#ifdef HCI_TRANSPORT_SDIO
108 status = PSSendOps((void*)hdev);
109#else
110 if(InitPSState(hdev) == -1) {
111 return A_ERROR;
112 }
113 allow_signal(SIGKILL);
114 add_wait_queue(&PsCompleteEvent,&wait);
115 set_current_state(TASK_INTERRUPTIBLE);
116 if(!kernel_thread(PSSendOps,(void*)hdev,CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD)) {
117 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Kthread Failed\n"));
118 remove_wait_queue(&PsCompleteEvent,&wait);
119 return A_ERROR;
120 }
121 wait_event_interruptible(PsCompleteEvent,(PSTagMode == false));
122 set_current_state(TASK_RUNNING);
123 remove_wait_queue(&PsCompleteEvent,&wait);
124
125#endif /* HCI_TRANSPORT_SDIO */
126
127
128 return status;
129
130}
131
132int PSSendOps(void *arg)
133{
134 int i;
135 int status = 0;
136 struct ps_cmd_packet *HciCmdList; /* List storing the commands */
137 const struct firmware* firmware;
138 u32 numCmds;
139 u8 *event;
140 u8 *bufferToFree;
141 struct hci_dev *device;
142 u8 *buffer;
143 u32 len;
144 u32 DevType;
145 u8 *PsFileName;
146 u8 *patchFileName;
147 u8 *path = NULL;
148 u8 *config_path = NULL;
149 u8 config_bdaddr[MAX_BDADDR_FORMAT_LENGTH];
150 struct ar3k_config_info *hdev = (struct ar3k_config_info*)arg;
151 struct device *firmwareDev = NULL;
152 status = 0;
153 HciCmdList = NULL;
154#ifdef HCI_TRANSPORT_SDIO
155 device = hdev->pBtStackHCIDev;
156 firmwareDev = device->parent;
157#else
158 device = hdev;
159 firmwareDev = &device->dev;
160 AthEnableSyncCommandOp(true);
161#endif /* HCI_TRANSPORT_SDIO */
162 /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different.
163 */
164
165 path =(u8 *)A_MALLOC(MAX_FW_PATH_LEN);
166 if(path == NULL) {
167 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for path\n", MAX_FW_PATH_LEN));
168 goto complete;
169 }
170 config_path = (u8 *) A_MALLOC(MAX_FW_PATH_LEN);
171 if(config_path == NULL) {
172 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for config_path\n", MAX_FW_PATH_LEN));
173 goto complete;
174 }
175
176 if(A_ERROR == getDeviceType(hdev,&DevType)) {
177 status = 1;
178 goto complete;
179 }
180 if(A_ERROR == ReadVersionInfo(hdev)) {
181 status = 1;
182 goto complete;
183 }
184
185 patchFileName = PATCH_FILE;
186 snprintf(path, MAX_FW_PATH_LEN, "%s/%xcoex/",CONFIG_PATH,Rom_Version);
187 if(DevType){
188 if(DevType == 0xdeadc0de){
189 PsFileName = PS_ASIC_FILE;
190 } else{
191 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x \n",Rom_Version,Build_Version));
192 if((Rom_Version == 0x99999999) && (Build_Version == 1)){
193
194 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n"));
195 patchFileName = NULL;
196 }
197 PsFileName = PS_FPGA_FILE;
198 }
199 }
200 else{
201 PsFileName = PS_ASIC_FILE;
202 }
203
204 snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,PsFileName);
205 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,config_path));
206 /* Read the PS file to a dynamically allocated buffer */
207 if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
208 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
209 status = 1;
210 goto complete;
211
212 }
213 if(NULL == firmware || firmware->size == 0) {
214 status = 1;
215 goto complete;
216 }
217 buffer = (u8 *)A_MALLOC(firmware->size);
218 if(buffer != NULL) {
219 /* Copy the read file to a local Dynamic buffer */
220 memcpy(buffer,firmware->data,firmware->size);
221 len = firmware->size;
222 A_RELEASE_FIRMWARE(firmware);
223 /* Parse the PS buffer to a global variable */
224 status = AthDoParsePS(buffer,len);
225 kfree(buffer);
226 } else {
227 A_RELEASE_FIRMWARE(firmware);
228 }
229
230
231 /* Read the patch file to a dynamically allocated buffer */
232 if(patchFileName != NULL)
233 snprintf(config_path,
234 MAX_FW_PATH_LEN, "%s%s",path,patchFileName);
235 else {
236 status = 0;
237 }
238 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
239 if((patchFileName == NULL) || (A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0)) {
240 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
241 /*
242 * It is not necessary that Patch file be available, continue with PS Operations if.
243 * failed.
244 */
245 status = 0;
246
247 } else {
248 if(NULL == firmware || firmware->size == 0) {
249 status = 0;
250 } else {
251 buffer = (u8 *)A_MALLOC(firmware->size);
252 if(buffer != NULL) {
253 /* Copy the read file to a local Dynamic buffer */
254 memcpy(buffer,firmware->data,firmware->size);
255 len = firmware->size;
256 A_RELEASE_FIRMWARE(firmware);
257 /* parse and store the Patch file contents to a global variables */
258 status = AthDoParsePatch(buffer,len);
259 kfree(buffer);
260 } else {
261 A_RELEASE_FIRMWARE(firmware);
262 }
263 }
264 }
265
266 /* Create an HCI command list from the parsed PS and patch information */
267 AthCreateCommandList(&HciCmdList,&numCmds);
268
269 /* Form the parameter for PSSendOps() API */
270
271
272 /*
273 * First Send the CRC packet,
274 * We have to continue with the PS operations only if the CRC packet has been replied with
275 * a Command complete event with status Error.
276 */
277
278 if(SendHCICommandWaitCommandComplete
279 (hdev,
280 HciCmdList[0].Hcipacket,
281 HciCmdList[0].packetLen,
282 &event,
283 &bufferToFree) == 0) {
284 if(ReadPSEvent(event) == 0) { /* Exit if the status is success */
285 if(bufferToFree != NULL) {
286 kfree(bufferToFree);
287 }
288
289#ifndef HCI_TRANSPORT_SDIO
290 if(bdaddr && bdaddr[0] !='\0') {
291 write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
292 }
293#endif
294 status = 1;
295 goto complete;
296 }
297 if(bufferToFree != NULL) {
298 kfree(bufferToFree);
299 }
300 } else {
301 status = 0;
302 goto complete;
303 }
304
305 for(i = 1; i <numCmds; i++) {
306
307 if(SendHCICommandWaitCommandComplete
308 (hdev,
309 HciCmdList[i].Hcipacket,
310 HciCmdList[i].packetLen,
311 &event,
312 &bufferToFree) == 0) {
313 if(ReadPSEvent(event) != 0) { /* Exit if the status is success */
314 if(bufferToFree != NULL) {
315 kfree(bufferToFree);
316 }
317 status = 1;
318 goto complete;
319 }
320 if(bufferToFree != NULL) {
321 kfree(bufferToFree);
322 }
323 } else {
324 status = 0;
325 goto complete;
326 }
327 }
328#ifdef HCI_TRANSPORT_SDIO
329 if(BDADDR == false)
330 if(hdev->bdaddr[0] !=0x00 ||
331 hdev->bdaddr[1] !=0x00 ||
332 hdev->bdaddr[2] !=0x00 ||
333 hdev->bdaddr[3] !=0x00 ||
334 hdev->bdaddr[4] !=0x00 ||
335 hdev->bdaddr[5] !=0x00)
336 write_bdaddr(hdev,hdev->bdaddr,BDADDR_TYPE_HEX);
337
338#ifndef HCI_TRANSPORT_SDIO
339
340 if(bdaddr && bdaddr[0] != '\0') {
341 write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
342 } else
343#endif /* HCI_TRANSPORT_SDIO */
344 /* Write BDADDR Read from OTP here */
345
346
347
348#endif
349
350 {
351 /* Read Contents of BDADDR file if user has not provided any option */
352 snprintf(config_path,MAX_FW_PATH_LEN, "%s%s",path,BDADDR_FILE);
353 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
354 if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
355 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
356 status = 1;
357 goto complete;
358 }
359 if(NULL == firmware || firmware->size == 0) {
360 status = 1;
361 goto complete;
362 }
363 len = min_t(size_t, firmware->size, MAX_BDADDR_FORMAT_LENGTH - 1);
364 memcpy(config_bdaddr, firmware->data, len);
365 config_bdaddr[len] = '\0';
366 write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING);
367 A_RELEASE_FIRMWARE(firmware);
368 }
369complete:
370#ifndef HCI_TRANSPORT_SDIO
371 AthEnableSyncCommandOp(false);
372 PSTagMode = false;
373 wake_up_interruptible(&PsCompleteEvent);
374#endif /* HCI_TRANSPORT_SDIO */
375 if(NULL != HciCmdList) {
376 AthFreeCommandList(&HciCmdList,numCmds);
377 }
378 if(path) {
379 kfree(path);
380 }
381 if(config_path) {
382 kfree(config_path);
383 }
384 return status;
385}
386#ifndef HCI_TRANSPORT_SDIO
387/*
388 * This API is used to send the HCI command to controller and return
389 * with a HCI Command Complete event.
390 * For HCI SDIO transport, this will be internally defined.
391 */
392int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig,
393 u8 *pHCICommand,
394 int CmdLength,
395 u8 **ppEventBuffer,
396 u8 **ppBufferToFree)
397{
398 if(CmdLength == 0) {
399 return A_ERROR;
400 }
401 Hci_log("COM Write -->",pHCICommand,CmdLength);
402 PSAcked = false;
403 if(PSHciWritepacket(pConfig,pHCICommand,CmdLength) == 0) {
404 /* If the controller is not available, return Error */
405 return A_ERROR;
406 }
407 //add_timer(&psCmdTimer);
408 wait_event_interruptible(HciEvent,(PSAcked == true));
409 if(NULL != HciEventpacket) {
410 *ppEventBuffer = HciEventpacket;
411 *ppBufferToFree = HciEventpacket;
412 } else {
413 /* Did not get an event from controller. return error */
414 *ppBufferToFree = NULL;
415 return A_ERROR;
416 }
417
418 return 0;
419}
420#endif /* HCI_TRANSPORT_SDIO */
421
422int ReadPSEvent(u8* Data){
423 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" PS Event %x %x %x\n",Data[4],Data[5],Data[3]));
424
425 if(Data[4] == 0xFC && Data[5] == 0x00)
426 {
427 switch(Data[3]){
428 case 0x0B:
429 return 0;
430 break;
431 case 0x0C:
432 /* Change Baudrate */
433 return 0;
434 break;
435 case 0x04:
436 return 0;
437 break;
438 case 0x1E:
439 Rom_Version = Data[9];
440 Rom_Version = ((Rom_Version << 8) |Data[8]);
441 Rom_Version = ((Rom_Version << 8) |Data[7]);
442 Rom_Version = ((Rom_Version << 8) |Data[6]);
443
444 Build_Version = Data[13];
445 Build_Version = ((Build_Version << 8) |Data[12]);
446 Build_Version = ((Build_Version << 8) |Data[11]);
447 Build_Version = ((Build_Version << 8) |Data[10]);
448 return 0;
449 break;
450
451
452 }
453 }
454
455 return A_ERROR;
456}
457int str2ba(unsigned char *str_bdaddr,unsigned char *bdaddr)
458{
459 unsigned char bdbyte[3];
460 unsigned char *str_byte = str_bdaddr;
461 int i,j;
462 unsigned char colon_present = 0;
463
464 if(NULL != strstr(str_bdaddr,":")) {
465 colon_present = 1;
466 }
467
468
469 bdbyte[2] = '\0';
470
471 for( i = 0,j = 5; i < 6; i++, j--) {
472 bdbyte[0] = str_byte[0];
473 bdbyte[1] = str_byte[1];
474 bdaddr[j] = A_STRTOL(bdbyte,NULL,16);
475 if(colon_present == 1) {
476 str_byte+=3;
477 } else {
478 str_byte+=2;
479 }
480 }
481 return 0;
482}
483
484int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type)
485{
486 u8 bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01,
487 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
488
489 u8 *event;
490 u8 *bufferToFree = NULL;
491 int result = A_ERROR;
492 int inc,outc;
493
494 if (type == BDADDR_TYPE_STRING)
495 str2ba(bdaddr,&bdaddr_cmd[7]);
496 else {
497 /* Bdaddr has to be sent as LAP first */
498 for(inc = 5 ,outc = 7; inc >=0; inc--, outc++)
499 bdaddr_cmd[outc] = bdaddr[inc];
500 }
501
502 if(0 == SendHCICommandWaitCommandComplete(pConfig,bdaddr_cmd,
503 sizeof(bdaddr_cmd),
504 &event,&bufferToFree)) {
505
506 if(event[4] == 0xFC && event[5] == 0x00){
507 if(event[3] == 0x0B){
508 result = 0;
509 }
510 }
511
512 }
513 if(bufferToFree != NULL) {
514 kfree(bufferToFree);
515 }
516 return result;
517
518}
519int ReadVersionInfo(struct ar3k_config_info *pConfig)
520{
521 u8 hciCommand[] = {0x1E,0xfc,0x00};
522 u8 *event;
523 u8 *bufferToFree = NULL;
524 int result = A_ERROR;
525 if(0 == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
526 result = ReadPSEvent(event);
527
528 }
529 if(bufferToFree != NULL) {
530 kfree(bufferToFree);
531 }
532 return result;
533}
534int getDeviceType(struct ar3k_config_info *pConfig, u32 *code)
535{
536 u8 hciCommand[] = {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04};
537 u8 *event;
538 u8 *bufferToFree = NULL;
539 u32 reg;
540 int result = A_ERROR;
541 *code = 0;
542 hciCommand[3] = (u8)(FPGA_REGISTER & 0xFF);
543 hciCommand[4] = (u8)((FPGA_REGISTER >> 8) & 0xFF);
544 hciCommand[5] = (u8)((FPGA_REGISTER >> 16) & 0xFF);
545 hciCommand[6] = (u8)((FPGA_REGISTER >> 24) & 0xFF);
546 if(0 == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
547
548 if(event[4] == 0xFC && event[5] == 0x00){
549 switch(event[3]){
550 case 0x05:
551 reg = event[9];
552 reg = ((reg << 8) |event[8]);
553 reg = ((reg << 8) |event[7]);
554 reg = ((reg << 8) |event[6]);
555 *code = reg;
556 result = 0;
557
558 break;
559 case 0x06:
560 //Sleep(500);
561 break;
562 }
563 }
564
565 }
566 if(bufferToFree != NULL) {
567 kfree(bufferToFree);
568 }
569 return result;
570}
571
572
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h
deleted file mode 100644
index d4435130780..00000000000
--- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h
+++ /dev/null
@@ -1,75 +0,0 @@
1/*
2 * Copyright (c) 2004-2010 Atheros Communications Inc.
3 * All rights reserved.
4 *
5 * This file defines the symbols exported by Atheros PS and patch download module.
6 * define the constant HCI_TRANSPORT_SDIO if the module is being used for HCI SDIO transport.
7 * defined.
8 *
9 *
10 * ar3kcpsconfig.h
11 *
12 *
13 *
14 * The software source and binaries included in this development package are
15 * licensed, not sold. You, or your company, received the package under one
16 * or more license agreements. The rights granted to you are specifically
17 * listed in these license agreement(s). All other rights remain with Atheros
18 * Communications, Inc., its subsidiaries, or the respective owner including
19 * those listed on the included copyright notices.. Distribution of any
20 * portion of this package must be in strict compliance with the license
21 * agreement(s) terms.
22 *
23 *
24 *
25 */
26
27
28
29#ifndef __AR3KPSCONFIG_H
30#define __AR3KPSCONFIG_H
31
32/*
33 * Define the flag HCI_TRANSPORT_SDIO and undefine HCI_TRANSPORT_UART if the transport being used is SDIO.
34 */
35#undef HCI_TRANSPORT_UART
36
37#include <linux/fs.h>
38#include <linux/errno.h>
39#include <linux/signal.h>
40
41
42#include <linux/ioctl.h>
43#include <linux/firmware.h>
44
45
46#include <net/bluetooth/bluetooth.h>
47#include <net/bluetooth/hci_core.h>
48
49#include "ar3kpsparser.h"
50
51#define FPGA_REGISTER 0x4FFC
52#define BDADDR_TYPE_STRING 0
53#define BDADDR_TYPE_HEX 1
54#define CONFIG_PATH "ar3k"
55
56#define PS_ASIC_FILE "PS_ASIC.pst"
57#define PS_FPGA_FILE "PS_FPGA.pst"
58
59#define PATCH_FILE "RamPatch.txt"
60#define BDADDR_FILE "ar3kbdaddr.pst"
61
62#define ROM_VER_AR3001_3_1_0 30000
63#define ROM_VER_AR3001_3_1_1 30101
64
65
66#ifndef HCI_TRANSPORT_SDIO
67#define struct ar3k_config_info struct hci_dev
68extern wait_queue_head_t HciEvent;
69extern wait_queue_t Eventwait;
70extern u8 *HciEventpacket;
71#endif /* #ifndef HCI_TRANSPORT_SDIO */
72
73int AthPSInitialize(struct ar3k_config_info *hdev);
74int ReadPSEvent(u8* Data);
75#endif /* __AR3KPSCONFIG_H */
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c
deleted file mode 100644
index b99a11a9dd6..00000000000
--- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c
+++ /dev/null
@@ -1,969 +0,0 @@
1/*
2 * Copyright (c) 2004-2010 Atheros Communications Inc.
3 * All rights reserved.
4 *
5 * This file implements the Atheros PS and patch parser.
6 * It implements APIs to parse data buffer with patch and PS information and convert it to HCI commands.
7 *
8 *
9 *
10 * ar3kpsparser.c
11 *
12 *
13 *
14 * The software source and binaries included in this development package are
15 * licensed, not sold. You, or your company, received the package under one
16 * or more license agreements. The rights granted to you are specifically
17 * listed in these license agreement(s). All other rights remain with Atheros
18 * Communications, Inc., its subsidiaries, or the respective owner including
19 * those listed on the included copyright notices.. Distribution of any
20 * portion of this package must be in strict compliance with the license
21 * agreement(s) terms.
22 *
23 *
24 *
25 */
26
27
28#include "ar3kpsparser.h"
29
30#include <linux/ctype.h>
31#include <linux/kernel.h>
32
33#define BD_ADDR_SIZE 6
34#define WRITE_PATCH 8
35#define ENABLE_PATCH 11
36#define PS_RESET 2
37#define PS_WRITE 1
38#define PS_VERIFY_CRC 9
39#define CHANGE_BDADDR 15
40
41#define HCI_COMMAND_HEADER 7
42
43#define HCI_EVENT_SIZE 7
44
45#define WRITE_PATCH_COMMAND_STATUS_OFFSET 5
46
47#define PS_RAM_SIZE 2048
48
49#define RAM_PS_REGION (1<<0)
50#define RAM_PATCH_REGION (1<<1)
51#define RAMPS_MAX_PS_DATA_PER_TAG 20000
52#define MAX_RADIO_CFG_TABLE_SIZE 244
53#define RAMPS_MAX_PS_TAGS_PER_FILE 50
54
55#define PS_MAX_LEN 500
56#define LINE_SIZE_MAX (PS_MAX_LEN *2)
57
58/* Constant values used by parser */
59#define BYTES_OF_PS_DATA_PER_LINE 16
60#define RAMPS_MAX_PS_DATA_PER_TAG 20000
61
62
63/* Number pf PS/Patch entries in an HCI packet */
64#define MAX_BYTE_LENGTH 244
65
66#define SKIP_BLANKS(str) while (*str == ' ') str++
67
68enum MinBootFileFormatE
69{
70 MB_FILEFORMAT_RADIOTBL,
71 MB_FILEFORMAT_PATCH,
72 MB_FILEFORMAT_COEXCONFIG
73};
74
75enum RamPsSection
76{
77 RAM_PS_SECTION,
78 RAM_PATCH_SECTION,
79 RAM_DYN_MEM_SECTION
80};
81
82enum eType {
83 eHex,
84 edecimal
85};
86
87
88typedef struct tPsTagEntry
89{
90 u32 TagId;
91 u32 TagLen;
92 u8 *TagData;
93} tPsTagEntry, *tpPsTagEntry;
94
95typedef struct tRamPatch
96{
97 u16 Len;
98 u8 *Data;
99} tRamPatch, *ptRamPatch;
100
101
102
103struct st_ps_data_format {
104 enum eType eDataType;
105 bool bIsArray;
106};
107
108struct st_read_status {
109 unsigned uTagID;
110 unsigned uSection;
111 unsigned uLineCount;
112 unsigned uCharCount;
113 unsigned uByteCount;
114};
115
116
117/* Stores the number of PS Tags */
118static u32 Tag_Count = 0;
119
120/* Stores the number of patch commands */
121static u32 Patch_Count = 0;
122static u32 Total_tag_lenght = 0;
123bool BDADDR = false;
124u32 StartTagId;
125
126tPsTagEntry PsTagEntry[RAMPS_MAX_PS_TAGS_PER_FILE];
127tRamPatch RamPatch[MAX_NUM_PATCH_ENTRY];
128
129
130int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat);
131char AthReadChar(u8 *buffer, u32 len,u32 *pos);
132char *AthGetLine(char *buffer, int maxlen, u8 *srcbuffer,u32 len,u32 *pos);
133static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,struct ps_cmd_packet *PSPatchPacket,u32 *index);
134
135/* Function to reads the next character from the input buffer */
136char AthReadChar(u8 *buffer, u32 len,u32 *pos)
137{
138 char Ch;
139 if(buffer == NULL || *pos >=len )
140 {
141 return '\0';
142 } else {
143 Ch = buffer[*pos];
144 (*pos)++;
145 return Ch;
146 }
147}
148/* PS parser helper function */
149unsigned int uGetInputDataFormat(char *pCharLine, struct st_ps_data_format *pstFormat)
150{
151 if(pCharLine[0] != '[') {
152 pstFormat->eDataType = eHex;
153 pstFormat->bIsArray = true;
154 return 0;
155 }
156 switch(pCharLine[1]) {
157 case 'H':
158 case 'h':
159 if(pCharLine[2]==':') {
160 if((pCharLine[3]== 'a') || (pCharLine[3]== 'A')) {
161 if(pCharLine[4] == ']') {
162 pstFormat->eDataType = eHex;
163 pstFormat->bIsArray = true;
164 pCharLine += 5;
165 return 0;
166 }
167 else {
168 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); //[H:A
169 return 1;
170 }
171 }
172 if((pCharLine[3]== 'S') || (pCharLine[3]== 's')) {
173 if(pCharLine[4] == ']') {
174 pstFormat->eDataType = eHex;
175 pstFormat->bIsArray = false;
176 pCharLine += 5;
177 return 0;
178 }
179 else {
180 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); //[H:A
181 return 1;
182 }
183 }
184 else if(pCharLine[3] == ']') { //[H:]
185 pstFormat->eDataType = eHex;
186 pstFormat->bIsArray = true;
187 pCharLine += 4;
188 return 0;
189 }
190 else { //[H:
191 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n"));
192 return 1;
193 }
194 }
195 else if(pCharLine[2]==']') { //[H]
196 pstFormat->eDataType = eHex;
197 pstFormat->bIsArray = true;
198 pCharLine += 3;
199 return 0;
200 }
201 else { //[H
202 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n"));
203 return 1;
204 }
205 break;
206
207 case 'A':
208 case 'a':
209 if(pCharLine[2]==':') {
210 if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) {
211 if(pCharLine[4] == ']') {
212 pstFormat->eDataType = eHex;
213 pstFormat->bIsArray = true;
214 pCharLine += 5;
215 return 0;
216 }
217 else {
218 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 1\n")); //[A:H
219 return 1;
220 }
221 }
222 else if(pCharLine[3]== ']') { //[A:]
223 pstFormat->eDataType = eHex;
224 pstFormat->bIsArray = true;
225 pCharLine += 4;
226 return 0;
227 }
228 else { //[A:
229 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 2\n"));
230 return 1;
231 }
232 }
233 else if(pCharLine[2]==']') { //[H]
234 pstFormat->eDataType = eHex;
235 pstFormat->bIsArray = true;
236 pCharLine += 3;
237 return 0;
238 }
239 else { //[H
240 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 3\n"));
241 return 1;
242 }
243 break;
244
245 case 'S':
246 case 's':
247 if(pCharLine[2]==':') {
248 if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) {
249 if(pCharLine[4] == ']') {
250 pstFormat->eDataType = eHex;
251 pstFormat->bIsArray = true;
252 pCharLine += 5;
253 return 0;
254 }
255 else {
256 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 5\n")); //[A:H
257 return 1;
258 }
259 }
260 else if(pCharLine[3]== ']') { //[A:]
261 pstFormat->eDataType = eHex;
262 pstFormat->bIsArray = true;
263 pCharLine += 4;
264 return 0;
265 }
266 else { //[A:
267 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 6\n"));
268 return 1;
269 }
270 }
271 else if(pCharLine[2]==']') { //[H]
272 pstFormat->eDataType = eHex;
273 pstFormat->bIsArray = true;
274 pCharLine += 3;
275 return 0;
276 }
277 else { //[H
278 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 7\n"));
279 return 1;
280 }
281 break;
282
283 default:
284 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 8\n"));
285 return 1;
286 }
287}
288
289unsigned int uReadDataInSection(char *pCharLine, struct st_ps_data_format stPS_DataFormat)
290{
291 char *pTokenPtr = pCharLine;
292
293 if(pTokenPtr[0] == '[') {
294 while(pTokenPtr[0] != ']' && pTokenPtr[0] != '\0') {
295 pTokenPtr++;
296 }
297 if(pTokenPtr[0] == '\0') {
298 return (0x0FFF);
299 }
300 pTokenPtr++;
301
302
303 }
304 if(stPS_DataFormat.eDataType == eHex) {
305 if(stPS_DataFormat.bIsArray == true) {
306 //Not implemented
307 return (0x0FFF);
308 }
309 else {
310 return (A_STRTOL(pTokenPtr, NULL, 16));
311 }
312 }
313 else {
314 //Not implemented
315 return (0x0FFF);
316 }
317}
318int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat)
319{
320 char *Buffer;
321 char *pCharLine;
322 u8 TagCount;
323 u16 ByteCount;
324 u8 ParseSection=RAM_PS_SECTION;
325 u32 pos;
326
327
328
329 int uReadCount;
330 struct st_ps_data_format stPS_DataFormat;
331 struct st_read_status stReadStatus = {0, 0, 0,0};
332 pos = 0;
333 Buffer = NULL;
334
335 if (srcbuffer == NULL || srclen == 0)
336 {
337 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Could not open .\n"));
338 return A_ERROR;
339 }
340 TagCount = 0;
341 ByteCount = 0;
342 Buffer = A_MALLOC(LINE_SIZE_MAX + 1);
343 if(NULL == Buffer) {
344 return A_ERROR;
345 }
346 if (FileFormat == MB_FILEFORMAT_PATCH)
347 {
348 int LineRead = 0;
349 while((pCharLine = AthGetLine(Buffer, LINE_SIZE_MAX, srcbuffer,srclen,&pos)) != NULL)
350 {
351
352 SKIP_BLANKS(pCharLine);
353
354 // Comment line or empty line
355 if ((pCharLine[0] == '/') && (pCharLine[1] == '/'))
356 {
357 continue;
358 }
359
360 if ((pCharLine[0] == '#')) {
361 if (stReadStatus.uSection != 0)
362 {
363 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("error\n"));
364 if(Buffer != NULL) {
365 kfree(Buffer);
366 }
367 return A_ERROR;
368 }
369 else {
370 stReadStatus.uSection = 1;
371 continue;
372 }
373 }
374 if ((pCharLine[0] == '/') && (pCharLine[1] == '*'))
375 {
376 pCharLine+=2;
377 SKIP_BLANKS(pCharLine);
378
379 if(!strncmp(pCharLine,"PA",2)||!strncmp(pCharLine,"Pa",2)||!strncmp(pCharLine,"pa",2))
380 ParseSection=RAM_PATCH_SECTION;
381
382 if(!strncmp(pCharLine,"DY",2)||!strncmp(pCharLine,"Dy",2)||!strncmp(pCharLine,"dy",2))
383 ParseSection=RAM_DYN_MEM_SECTION;
384
385 if(!strncmp(pCharLine,"PS",2)||!strncmp(pCharLine,"Ps",2)||!strncmp(pCharLine,"ps",2))
386 ParseSection=RAM_PS_SECTION;
387
388 LineRead = 0;
389 stReadStatus.uSection = 0;
390
391 continue;
392 }
393
394 switch(ParseSection)
395 {
396 case RAM_PS_SECTION:
397 {
398 if (stReadStatus.uSection == 1) //TagID
399 {
400 SKIP_BLANKS(pCharLine);
401 if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) {
402 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail\n"));
403 if(Buffer != NULL) {
404 kfree(Buffer);
405 }
406 return A_ERROR;
407 }
408 //pCharLine +=5;
409 PsTagEntry[TagCount].TagId = uReadDataInSection(pCharLine, stPS_DataFormat);
410 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG ID %d \n",PsTagEntry[TagCount].TagId));
411
412 //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("tag # %x\n", PsTagEntry[TagCount].TagId);
413 if (TagCount == 0)
414 {
415 StartTagId = PsTagEntry[TagCount].TagId;
416 }
417 stReadStatus.uSection = 2;
418 }
419 else if (stReadStatus.uSection == 2) //TagLength
420 {
421
422 if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) {
423 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail \n"));
424 if(Buffer != NULL) {
425 kfree(Buffer);
426 }
427 return A_ERROR;
428 }
429 //pCharLine +=5;
430 ByteCount = uReadDataInSection(pCharLine, stPS_DataFormat);
431
432 //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("tag length %x\n", ByteCount));
433 if (ByteCount > LINE_SIZE_MAX/2)
434 {
435 if(Buffer != NULL) {
436 kfree(Buffer);
437 }
438 return A_ERROR;
439 }
440 PsTagEntry[TagCount].TagLen = ByteCount;
441 PsTagEntry[TagCount].TagData = (u8 *)A_MALLOC(ByteCount);
442 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG Length %d Tag Index %d \n",PsTagEntry[TagCount].TagLen,TagCount));
443 stReadStatus.uSection = 3;
444 stReadStatus.uLineCount = 0;
445 }
446 else if( stReadStatus.uSection == 3) { //Data
447
448 if(stReadStatus.uLineCount == 0) {
449 if(uGetInputDataFormat(pCharLine,&stPS_DataFormat)) {
450 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat Fail\n"));
451 if(Buffer != NULL) {
452 kfree(Buffer);
453 }
454 return A_ERROR;
455 }
456 //pCharLine +=5;
457 }
458 SKIP_BLANKS(pCharLine);
459 stReadStatus.uCharCount = 0;
460 if(pCharLine[stReadStatus.uCharCount] == '[') {
461 while(pCharLine[stReadStatus.uCharCount] != ']' && pCharLine[stReadStatus.uCharCount] != '\0' ) {
462 stReadStatus.uCharCount++;
463 }
464 if(pCharLine[stReadStatus.uCharCount] == ']' ) {
465 stReadStatus.uCharCount++;
466 } else {
467 stReadStatus.uCharCount = 0;
468 }
469 }
470 uReadCount = (ByteCount > BYTES_OF_PS_DATA_PER_LINE)? BYTES_OF_PS_DATA_PER_LINE: ByteCount;
471 //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" "));
472 if((stPS_DataFormat.eDataType == eHex) && stPS_DataFormat.bIsArray == true) {
473 while(uReadCount > 0) {
474 PsTagEntry[TagCount].TagData[stReadStatus.uByteCount] =
475 (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount]) << 4)
476 | (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 1]));
477
478 PsTagEntry[TagCount].TagData[stReadStatus.uByteCount+1] =
479 (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 3]) << 4)
480 | (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 4]));
481
482 stReadStatus.uCharCount += 6; // read two bytes, plus a space;
483 stReadStatus.uByteCount += 2;
484 uReadCount -= 2;
485 }
486 if(ByteCount > BYTES_OF_PS_DATA_PER_LINE) {
487 ByteCount -= BYTES_OF_PS_DATA_PER_LINE;
488 }
489 else {
490 ByteCount = 0;
491 }
492 }
493 else {
494 //to be implemented
495 }
496
497 stReadStatus.uLineCount++;
498
499 if(ByteCount == 0) {
500 stReadStatus.uSection = 0;
501 stReadStatus.uCharCount = 0;
502 stReadStatus.uLineCount = 0;
503 stReadStatus.uByteCount = 0;
504 }
505 else {
506 stReadStatus.uCharCount = 0;
507 }
508
509 if((stReadStatus.uSection == 0)&&(++TagCount == RAMPS_MAX_PS_TAGS_PER_FILE))
510 {
511 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n Buffer over flow PS File too big!!!"));
512 if(Buffer != NULL) {
513 kfree(Buffer);
514 }
515 return A_ERROR;
516 //Sleep (3000);
517 //exit(1);
518 }
519
520 }
521 }
522
523 break;
524 default:
525 {
526 if(Buffer != NULL) {
527 kfree(Buffer);
528 }
529 return A_ERROR;
530 }
531 break;
532 }
533 LineRead++;
534 }
535 Tag_Count = TagCount;
536 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Number of Tags %d\n", Tag_Count));
537 }
538
539
540 if (TagCount > RAMPS_MAX_PS_TAGS_PER_FILE)
541 {
542
543 if(Buffer != NULL) {
544 kfree(Buffer);
545 }
546 return A_ERROR;
547 }
548
549 if(Buffer != NULL) {
550 kfree(Buffer);
551 }
552 return 0;
553
554}
555
556
557
558/********************/
559
560
561int GetNextTwoChar(u8 *srcbuffer,u32 len, u32 *pos, char *buffer)
562{
563 unsigned char ch;
564
565 ch = AthReadChar(srcbuffer,len,pos);
566 if(ch != '\0' && isxdigit(ch)) {
567 buffer[0] = ch;
568 } else
569 {
570 return A_ERROR;
571 }
572 ch = AthReadChar(srcbuffer,len,pos);
573 if(ch != '\0' && isxdigit(ch)) {
574 buffer[1] = ch;
575 } else
576 {
577 return A_ERROR;
578 }
579 return 0;
580}
581
582int AthDoParsePatch(u8 *patchbuffer, u32 patchlen)
583{
584
585 char Byte[3];
586 char Line[MAX_BYTE_LENGTH + 1];
587 int ByteCount,ByteCount_Org;
588 int count;
589 int i,j,k;
590 int data;
591 u32 filepos;
592 Byte[2] = '\0';
593 j = 0;
594 filepos = 0;
595 Patch_Count = 0;
596
597 while(NULL != AthGetLine(Line,MAX_BYTE_LENGTH,patchbuffer,patchlen,&filepos)) {
598 if(strlen(Line) <= 1 || !isxdigit(Line[0])) {
599 continue;
600 } else {
601 break;
602 }
603 }
604 ByteCount = A_STRTOL(Line, NULL, 16);
605 ByteCount_Org = ByteCount;
606
607 while(ByteCount > MAX_BYTE_LENGTH){
608
609 /* Handle case when the number of patch buffer is more than the 20K */
610 if(MAX_NUM_PATCH_ENTRY == Patch_Count) {
611 for(i = 0; i < Patch_Count; i++) {
612 kfree(RamPatch[i].Data);
613 }
614 return A_ERROR;
615 }
616 RamPatch[Patch_Count].Len= MAX_BYTE_LENGTH;
617 RamPatch[Patch_Count].Data = (u8 *)A_MALLOC(MAX_BYTE_LENGTH);
618 Patch_Count ++;
619
620
621 ByteCount= ByteCount - MAX_BYTE_LENGTH;
622 }
623
624 RamPatch[Patch_Count].Len= (ByteCount & 0xFF);
625 if(ByteCount != 0) {
626 RamPatch[Patch_Count].Data = (u8 *)A_MALLOC(ByteCount);
627 Patch_Count ++;
628 }
629 count = 0;
630 while(ByteCount_Org > MAX_BYTE_LENGTH){
631 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Index [%d]\n",j));
632 for (i = 0,k=0; i < MAX_BYTE_LENGTH*2; i += 2,k++,count +=2) {
633 if(GetNextTwoChar(patchbuffer,patchlen,&filepos,Byte) == A_ERROR) {
634 return A_ERROR;
635 }
636 data = A_STRTOUL(&Byte[0], NULL, 16);
637 RamPatch[j].Data[k] = (data & 0xFF);
638
639
640 }
641 j++;
642 ByteCount_Org = ByteCount_Org - MAX_BYTE_LENGTH;
643 }
644 if(j == 0){
645 j++;
646 }
647 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Index [%d]\n",j));
648 for (k=0; k < ByteCount_Org; i += 2,k++,count+=2) {
649 if(GetNextTwoChar(patchbuffer,patchlen,&filepos,Byte) == A_ERROR) {
650 return A_ERROR;
651 }
652 data = A_STRTOUL(Byte, NULL, 16);
653 RamPatch[j].Data[k] = (data & 0xFF);
654
655
656 }
657 return 0;
658}
659
660
661/********************/
662int AthDoParsePS(u8 *srcbuffer, u32 srclen)
663{
664 int status;
665 int i;
666 bool BDADDR_Present = false;
667
668 Tag_Count = 0;
669
670 Total_tag_lenght = 0;
671 BDADDR = false;
672
673
674 status = A_ERROR;
675
676 if(NULL != srcbuffer && srclen != 0)
677 {
678 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("File Open Operation Successful\n"));
679
680 status = AthParseFilesUnified(srcbuffer,srclen,MB_FILEFORMAT_PATCH);
681 }
682
683
684
685 if(Tag_Count == 0){
686 Total_tag_lenght = 10;
687
688 }
689 else{
690 for(i=0; i<Tag_Count; i++){
691 if(PsTagEntry[i].TagId == 1){
692 BDADDR_Present = true;
693 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR is present in Patch File \r\n"));
694
695 }
696 if(PsTagEntry[i].TagLen % 2 == 1){
697 Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen + 1;
698 }
699 else{
700 Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen;
701 }
702
703 }
704 }
705
706 if(Tag_Count > 0 && !BDADDR_Present){
707 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR is not present adding 10 extra bytes \r\n"));
708 Total_tag_lenght=Total_tag_lenght + 10;
709 }
710 Total_tag_lenght = Total_tag_lenght+ 10 + (Tag_Count*4);
711 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Total Length %d\n",Total_tag_lenght));
712
713
714 return status;
715}
716char *AthGetLine(char *buffer, int maxlen, u8 *srcbuffer,u32 len,u32 *pos)
717{
718
719 int count;
720 static short flag;
721 char CharRead;
722 count = 0;
723 flag = A_ERROR;
724
725 do
726 {
727 CharRead = AthReadChar(srcbuffer,len,pos);
728 if( CharRead == '\0' ) {
729 buffer[count+1] = '\0';
730 if(count == 0) {
731 return NULL;
732 }
733 else {
734 return buffer;
735 }
736 }
737
738 if(CharRead == 13) {
739 } else if(CharRead == 10) {
740 buffer[count] ='\0';
741 flag = A_ERROR;
742 return buffer;
743 }else {
744 buffer[count++] = CharRead;
745 }
746
747 }
748 while(count < maxlen-1 && CharRead != '\0');
749 buffer[count] = '\0';
750
751 return buffer;
752}
753
754static void LoadHeader(u8 *HCI_PS_Command,u8 opcode,int length,int index){
755
756 HCI_PS_Command[0]= 0x0B;
757 HCI_PS_Command[1]= 0xFC;
758 HCI_PS_Command[2]= length + 4;
759 HCI_PS_Command[3]= opcode;
760 HCI_PS_Command[4]= (index & 0xFF);
761 HCI_PS_Command[5]= ((index>>8) & 0xFF);
762 HCI_PS_Command[6]= length;
763}
764
765/////////////////////////
766//
767int AthCreateCommandList(struct ps_cmd_packet **HciPacketList, u32 *numPackets)
768{
769
770 u8 count;
771 u32 NumcmdEntry = 0;
772
773 u32 Crc = 0;
774 *numPackets = 0;
775
776
777 if(Patch_Count > 0)
778 Crc |= RAM_PATCH_REGION;
779 if(Tag_Count > 0)
780 Crc |= RAM_PS_REGION;
781 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("PS Thread Started CRC %x Patch Count %d Tag Count %d \n",Crc,Patch_Count,Tag_Count));
782
783 if(Patch_Count || Tag_Count ){
784 NumcmdEntry+=(2 + Patch_Count + Tag_Count); /* CRC Packet + PS Reset Packet + Patch List + PS List*/
785 if(Patch_Count > 0) {
786 NumcmdEntry++; /* Patch Enable Command */
787 }
788 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Num Cmd Entries %d Size %d \r\n",NumcmdEntry,(u32)sizeof(struct ps_cmd_packet) * NumcmdEntry));
789 (*HciPacketList) = A_MALLOC(sizeof(struct ps_cmd_packet) * NumcmdEntry);
790 if(NULL == *HciPacketList) {
791 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("memory allocation failed \r\n"));
792 }
793 AthPSCreateHCICommand(PS_VERIFY_CRC,Crc,*HciPacketList,numPackets);
794 if(Patch_Count > 0){
795 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** Write Patch**** \r\n"));
796 AthPSCreateHCICommand(WRITE_PATCH,Patch_Count,*HciPacketList,numPackets);
797 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** Enable Patch**** \r\n"));
798 AthPSCreateHCICommand(ENABLE_PATCH,0,*HciPacketList,numPackets);
799 }
800
801 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** PS Reset**** %d[0x%x] \r\n",PS_RAM_SIZE,PS_RAM_SIZE));
802 AthPSCreateHCICommand(PS_RESET,PS_RAM_SIZE,*HciPacketList,numPackets);
803 if(Tag_Count > 0){
804 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** PS Write**** \r\n"));
805 AthPSCreateHCICommand(PS_WRITE,Tag_Count,*HciPacketList,numPackets);
806 }
807 }
808 if(!BDADDR){
809 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR not present \r\n"));
810
811 }
812 for(count = 0; count < Patch_Count; count++) {
813
814 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing Patch Buffer %d \r\n",count));
815 kfree(RamPatch[count].Data);
816 }
817
818 for(count = 0; count < Tag_Count; count++) {
819
820 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing PS Buffer %d \r\n",count));
821 kfree(PsTagEntry[count].TagData);
822 }
823
824/*
825 * SDIO Transport uses synchronous mode of data transfer
826 * So, AthPSOperations() call returns only after receiving the
827 * command complete event.
828 */
829 return *numPackets;
830}
831
832
833////////////////////////
834
835/////////////
836static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,struct ps_cmd_packet *PSPatchPacket,u32 *index)
837{
838 u8 *HCI_PS_Command;
839 u32 Length;
840 int i,j;
841
842 switch(Opcode)
843 {
844 case WRITE_PATCH:
845
846
847 for(i=0;i< Param1;i++){
848
849 HCI_PS_Command = (u8 *) A_MALLOC(RamPatch[i].Len+HCI_COMMAND_HEADER);
850 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Allocated Buffer Size %d\n",RamPatch[i].Len+HCI_COMMAND_HEADER));
851 if(HCI_PS_Command == NULL){
852 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
853 return A_ERROR;
854 }
855 memset (HCI_PS_Command, 0, RamPatch[i].Len+HCI_COMMAND_HEADER);
856 LoadHeader(HCI_PS_Command,Opcode,RamPatch[i].Len,i);
857 for(j=0;j<RamPatch[i].Len;j++){
858 HCI_PS_Command[HCI_COMMAND_HEADER+j]=RamPatch[i].Data[j];
859 }
860 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
861 PSPatchPacket[*index].packetLen = RamPatch[i].Len+HCI_COMMAND_HEADER;
862 (*index)++;
863
864
865 }
866
867 break;
868
869 case ENABLE_PATCH:
870
871
872 Length = 0;
873 i= 0;
874 HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER);
875 if(HCI_PS_Command == NULL){
876 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
877 return A_ERROR;
878 }
879
880 memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
881 LoadHeader(HCI_PS_Command,Opcode,Length,i);
882 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
883 PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
884 (*index)++;
885
886 break;
887
888 case PS_RESET:
889 Length = 0x06;
890 i=0;
891 HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER);
892 if(HCI_PS_Command == NULL){
893 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
894 return A_ERROR;
895 }
896 memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
897 LoadHeader(HCI_PS_Command,Opcode,Length,i);
898 HCI_PS_Command[7]= 0x00;
899 HCI_PS_Command[Length+HCI_COMMAND_HEADER -2]= (Param1 & 0xFF);
900 HCI_PS_Command[Length+HCI_COMMAND_HEADER -1]= ((Param1 >> 8) & 0xFF);
901 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
902 PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
903 (*index)++;
904
905 break;
906
907 case PS_WRITE:
908 for(i=0;i< Param1;i++){
909 if(PsTagEntry[i].TagId ==1)
910 BDADDR = true;
911
912 HCI_PS_Command = (u8 *) A_MALLOC(PsTagEntry[i].TagLen+HCI_COMMAND_HEADER);
913 if(HCI_PS_Command == NULL){
914 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
915 return A_ERROR;
916 }
917
918 memset (HCI_PS_Command, 0, PsTagEntry[i].TagLen+HCI_COMMAND_HEADER);
919 LoadHeader(HCI_PS_Command,Opcode,PsTagEntry[i].TagLen,PsTagEntry[i].TagId);
920
921 for(j=0;j<PsTagEntry[i].TagLen;j++){
922 HCI_PS_Command[HCI_COMMAND_HEADER+j]=PsTagEntry[i].TagData[j];
923 }
924
925 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
926 PSPatchPacket[*index].packetLen = PsTagEntry[i].TagLen+HCI_COMMAND_HEADER;
927 (*index)++;
928
929 }
930
931 break;
932
933
934 case PS_VERIFY_CRC:
935 Length = 0x0;
936
937 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("VALUE of CRC:%d At index %d\r\n",Param1,*index));
938
939 HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER);
940 if(HCI_PS_Command == NULL){
941 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
942 return A_ERROR;
943 }
944 memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
945 LoadHeader(HCI_PS_Command,Opcode,Length,Param1);
946
947 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
948 PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
949 (*index)++;
950
951 break;
952
953 case CHANGE_BDADDR:
954 break;
955 }
956 return 0;
957}
958int AthFreeCommandList(struct ps_cmd_packet **HciPacketList, u32 numPackets)
959{
960 int i;
961 if(*HciPacketList == NULL) {
962 return A_ERROR;
963 }
964 for(i = 0; i < numPackets;i++) {
965 kfree((*HciPacketList)[i].Hcipacket);
966 }
967 kfree(*HciPacketList);
968 return 0;
969}
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h
deleted file mode 100644
index 4e0f2f713a4..00000000000
--- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h
+++ /dev/null
@@ -1,113 +0,0 @@
1//------------------------------------------------------------------------------
2//
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//
21// This file is the include file for Atheros PS and patch parser.
22// It implements APIs to parse data buffer with patch and PS information and convert it to HCI commands.
23//
24
25#ifndef __AR3KPSPARSER_H
26#define __AR3KPSPARSER_H
27
28
29
30
31#include <linux/fs.h>
32#include <linux/slab.h>
33#include "athdefs.h"
34#ifdef HCI_TRANSPORT_SDIO
35#include "a_config.h"
36#include "a_osapi.h"
37#define ATH_MODULE_NAME misc
38#include "a_debug.h"
39#include "common_drv.h"
40#include "hci_transport_api.h"
41#include "ar3kconfig.h"
42#else
43#ifndef A_PRINTF
44#define A_PRINTF(args...) printk(KERN_ALERT args)
45#endif /* A_PRINTF */
46#include "debug_linux.h"
47
48/* Helper data type declaration */
49
50#define ATH_DEBUG_ERR (1 << 0)
51#define ATH_DEBUG_WARN (1 << 1)
52#define ATH_DEBUG_INFO (1 << 2)
53
54
55
56#define false 0
57#define true 1
58
59#ifndef A_MALLOC
60#define A_MALLOC(size) kmalloc((size),GFP_KERNEL)
61#endif /* A_MALLOC */
62#endif /* HCI_TRANSPORT_UART */
63
64/* String manipulation APIs */
65#ifndef A_STRTOUL
66#define A_STRTOUL simple_strtoul
67#endif /* A_STRTOL */
68
69#ifndef A_STRTOL
70#define A_STRTOL simple_strtol
71#endif /* A_STRTOL */
72
73
74/* The maximum number of bytes possible in a patch entry */
75#define MAX_PATCH_SIZE 20000
76
77/* Maximum HCI packets that will be formed from the Patch file */
78#define MAX_NUM_PATCH_ENTRY (MAX_PATCH_SIZE/MAX_BYTE_LENGTH) + 1
79
80
81
82
83
84
85
86struct ps_cmd_packet
87{
88 u8 *Hcipacket;
89 int packetLen;
90};
91
92/* Parses a Patch information buffer and store it in global structure */
93int AthDoParsePatch(u8 *, u32 );
94
95/* parses a PS information buffer and stores it in a global structure */
96int AthDoParsePS(u8 *, u32 );
97
98/*
99 * Uses the output of Both AthDoParsePS and AthDoParsePatch APIs to form HCI command array with
100 * all the PS and patch commands.
101 * The list will have the below mentioned commands in order.
102 * CRC command packet
103 * Download patch command(s)
104 * Enable patch Command
105 * PS Reset Command
106 * PS Tag Command(s)
107 *
108 */
109int AthCreateCommandList(struct ps_cmd_packet **, u32 *);
110
111/* Cleanup the dynamically allicated HCI command list */
112int AthFreeCommandList(struct ps_cmd_packet **HciPacketList, u32 numPackets);
113#endif /* __AR3KPSPARSER_H */
diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c
deleted file mode 100644
index 1ce539aa019..00000000000
--- a/drivers/staging/ath6kl/miscdrv/common_drv.c
+++ /dev/null
@@ -1,910 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="common_drv.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#include "a_config.h"
25#include "athdefs.h"
26
27#include "hw/mbox_host_reg.h"
28#include "gpio_reg.h"
29#include "hw/rtc_reg.h"
30#include "hw/mbox_reg.h"
31#include "hw/apb_map.h"
32
33#include "a_osapi.h"
34#include "targaddrs.h"
35#include "hif.h"
36#include "htc_api.h"
37#include "wmi.h"
38#include "bmi.h"
39#include "bmi_msg.h"
40#include "common_drv.h"
41#define ATH_MODULE_NAME misc
42#include "a_debug.h"
43#include "ar6000_diag.h"
44
45static ATH_DEBUG_MODULE_DBG_INFO *g_pModuleInfoHead = NULL;
46static A_MUTEX_T g_ModuleListLock;
47static bool g_ModuleDebugInit = false;
48
49#ifdef ATH_DEBUG_MODULE
50
51ATH_DEBUG_INSTANTIATE_MODULE_VAR(misc,
52 "misc",
53 "Common and misc APIs",
54 ATH_DEBUG_MASK_DEFAULTS,
55 0,
56 NULL);
57
58#endif
59
60#define HOST_INTEREST_ITEM_ADDRESS(target, item) \
61 ((((target) == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
62 (((target) == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0)))
63
64
65#define AR6001_LOCAL_COUNT_ADDRESS 0x0c014080
66#define AR6002_LOCAL_COUNT_ADDRESS 0x00018080
67#define AR6003_LOCAL_COUNT_ADDRESS 0x00018080
68#define CPU_DBG_SEL_ADDRESS 0x00000483
69#define CPU_DBG_ADDRESS 0x00000484
70
71static u8 custDataAR6002[AR6002_CUST_DATA_SIZE];
72static u8 custDataAR6003[AR6003_CUST_DATA_SIZE];
73
74/* Compile the 4BYTE version of the window register setup routine,
75 * This mitigates host interconnect issues with non-4byte aligned bus requests, some
76 * interconnects use bus adapters that impose strict limitations.
77 * Since diag window access is not intended for performance critical operations, the 4byte mode should
78 * be satisfactory even though it generates 4X the bus activity. */
79
80#ifdef USE_4BYTE_REGISTER_ACCESS
81
82 /* set the window address register (using 4-byte register access ). */
83int ar6000_SetAddressWindowRegister(struct hif_device *hifDevice, u32 RegisterAddr, u32 Address)
84{
85 int status;
86 u8 addrValue[4];
87 s32 i;
88
89 /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
90 * last to initiate the access cycle */
91
92 for (i = 1; i <= 3; i++) {
93 /* fill the buffer with the address byte value we want to hit 4 times*/
94 addrValue[0] = ((u8 *)&Address)[i];
95 addrValue[1] = addrValue[0];
96 addrValue[2] = addrValue[0];
97 addrValue[3] = addrValue[0];
98
99 /* hit each byte of the register address with a 4-byte write operation to the same address,
100 * this is a harmless operation */
101 status = HIFReadWrite(hifDevice,
102 RegisterAddr+i,
103 addrValue,
104 4,
105 HIF_WR_SYNC_BYTE_FIX,
106 NULL);
107 if (status) {
108 break;
109 }
110 }
111
112 if (status) {
113 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
114 Address, RegisterAddr));
115 return status;
116 }
117
118 /* write the address register again, this time write the whole 4-byte value.
119 * The effect here is that the LSB write causes the cycle to start, the extra
120 * 3 byte write to bytes 1,2,3 has no effect since we are writing the same values again */
121 status = HIFReadWrite(hifDevice,
122 RegisterAddr,
123 (u8 *)(&Address),
124 4,
125 HIF_WR_SYNC_BYTE_INC,
126 NULL);
127
128 if (status) {
129 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
130 Address, RegisterAddr));
131 return status;
132 }
133
134 return 0;
135
136
137
138}
139
140
141#else
142
143 /* set the window address register */
144int ar6000_SetAddressWindowRegister(struct hif_device *hifDevice, u32 RegisterAddr, u32 Address)
145{
146 int status;
147
148 /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
149 * last to initiate the access cycle */
150 status = HIFReadWrite(hifDevice,
151 RegisterAddr+1, /* write upper 3 bytes */
152 ((u8 *)(&Address))+1,
153 sizeof(u32)-1,
154 HIF_WR_SYNC_BYTE_INC,
155 NULL);
156
157 if (status) {
158 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
159 RegisterAddr, Address));
160 return status;
161 }
162
163 /* write the LSB of the register, this initiates the operation */
164 status = HIFReadWrite(hifDevice,
165 RegisterAddr,
166 (u8 *)(&Address),
167 sizeof(u8),
168 HIF_WR_SYNC_BYTE_INC,
169 NULL);
170
171 if (status) {
172 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
173 RegisterAddr, Address));
174 return status;
175 }
176
177 return 0;
178}
179
180#endif
181
182/*
183 * Read from the AR6000 through its diagnostic window.
184 * No cooperation from the Target is required for this.
185 */
186int
187ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data)
188{
189 int status;
190
191 /* set window register to start read cycle */
192 status = ar6000_SetAddressWindowRegister(hifDevice,
193 WINDOW_READ_ADDR_ADDRESS,
194 *address);
195
196 if (status) {
197 return status;
198 }
199
200 /* read the data */
201 status = HIFReadWrite(hifDevice,
202 WINDOW_DATA_ADDRESS,
203 (u8 *)data,
204 sizeof(u32),
205 HIF_RD_SYNC_BYTE_INC,
206 NULL);
207 if (status) {
208 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from WINDOW_DATA_ADDRESS\n"));
209 return status;
210 }
211
212 return status;
213}
214
215
216/*
217 * Write to the AR6000 through its diagnostic window.
218 * No cooperation from the Target is required for this.
219 */
220int
221ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data)
222{
223 int status;
224
225 /* set write data */
226 status = HIFReadWrite(hifDevice,
227 WINDOW_DATA_ADDRESS,
228 (u8 *)data,
229 sizeof(u32),
230 HIF_WR_SYNC_BYTE_INC,
231 NULL);
232 if (status) {
233 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to WINDOW_DATA_ADDRESS\n", *data));
234 return status;
235 }
236
237 /* set window register, which starts the write cycle */
238 return ar6000_SetAddressWindowRegister(hifDevice,
239 WINDOW_WRITE_ADDR_ADDRESS,
240 *address);
241 }
242
243int
244ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address,
245 u8 *data, u32 length)
246{
247 u32 count;
248 int status = 0;
249
250 for (count = 0; count < length; count += 4, address += 4) {
251 if ((status = ar6000_ReadRegDiag(hifDevice, &address,
252 (u32 *)&data[count])) != 0)
253 {
254 break;
255 }
256 }
257
258 return status;
259}
260
261int
262ar6000_WriteDataDiag(struct hif_device *hifDevice, u32 address,
263 u8 *data, u32 length)
264{
265 u32 count;
266 int status = 0;
267
268 for (count = 0; count < length; count += 4, address += 4) {
269 if ((status = ar6000_WriteRegDiag(hifDevice, &address,
270 (u32 *)&data[count])) != 0)
271 {
272 break;
273 }
274 }
275
276 return status;
277}
278
279int
280ar6k_ReadTargetRegister(struct hif_device *hifDevice, int regsel, u32 *regval)
281{
282 int status;
283 u8 vals[4];
284 u8 register_selection[4];
285
286 register_selection[0] = register_selection[1] = register_selection[2] = register_selection[3] = (regsel & 0xff);
287 status = HIFReadWrite(hifDevice,
288 CPU_DBG_SEL_ADDRESS,
289 register_selection,
290 4,
291 HIF_WR_SYNC_BYTE_FIX,
292 NULL);
293
294 if (status) {
295 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write CPU_DBG_SEL (%d)\n", regsel));
296 return status;
297 }
298
299 status = HIFReadWrite(hifDevice,
300 CPU_DBG_ADDRESS,
301 (u8 *)vals,
302 sizeof(vals),
303 HIF_RD_SYNC_BYTE_INC,
304 NULL);
305 if (status) {
306 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from CPU_DBG_ADDRESS\n"));
307 return status;
308 }
309
310 *regval = vals[0]<<0 | vals[1]<<8 | vals[2]<<16 | vals[3]<<24;
311
312 return status;
313}
314
315void
316ar6k_FetchTargetRegs(struct hif_device *hifDevice, u32 *targregs)
317{
318 int i;
319 u32 val;
320
321 for (i=0; i<AR6003_FETCH_TARG_REGS_COUNT; i++) {
322 val=0xffffffff;
323 (void)ar6k_ReadTargetRegister(hifDevice, i, &val);
324 targregs[i] = val;
325 }
326}
327
328#if 0
329static int
330_do_write_diag(struct hif_device *hifDevice, u32 addr, u32 value)
331{
332 int status;
333
334 status = ar6000_WriteRegDiag(hifDevice, &addr, &value);
335 if (status)
336 {
337 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot force Target to execute ROM!\n"));
338 }
339
340 return status;
341}
342#endif
343
344
345/*
346 * Delay up to wait_msecs millisecs to allow Target to enter BMI phase,
347 * which is a good sign that it's alive and well. This is used after
348 * explicitly forcing the Target to reset.
349 *
350 * The wait_msecs time should be sufficiently long to cover any reasonable
351 * boot-time delay. For instance, AR6001 firmware allow one second for a
352 * low frequency crystal to settle before it calibrates the refclk frequency.
353 *
354 * TBD: Might want to add special handling for AR6K_OPTION_BMI_DISABLE.
355 */
356#if 0
357static int
358_delay_until_target_alive(struct hif_device *hifDevice, s32 wait_msecs, u32 TargetType)
359{
360 s32 actual_wait;
361 s32 i;
362 u32 address;
363
364 actual_wait = 0;
365
366 /* Hardcode the address of LOCAL_COUNT_ADDRESS based on the target type */
367 if (TargetType == TARGET_TYPE_AR6002) {
368 address = AR6002_LOCAL_COUNT_ADDRESS;
369 } else if (TargetType == TARGET_TYPE_AR6003) {
370 address = AR6003_LOCAL_COUNT_ADDRESS;
371 } else {
372 A_ASSERT(0);
373 }
374 address += 0x10;
375 for (i=0; actual_wait < wait_msecs; i++) {
376 u32 data;
377
378 A_MDELAY(100);
379 actual_wait += 100;
380
381 data = 0;
382 if (ar6000_ReadRegDiag(hifDevice, &address, &data) != 0) {
383 return A_ERROR;
384 }
385
386 if (data != 0) {
387 /* No need to wait longer -- we have a BMI credit */
388 return 0;
389 }
390 }
391 return A_ERROR; /* timed out */
392}
393#endif
394
395#define AR6001_RESET_CONTROL_ADDRESS 0x0C000000
396#define AR6002_RESET_CONTROL_ADDRESS 0x00004000
397#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
398/* reset device */
399int ar6000_reset_device(struct hif_device *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset)
400{
401 int status = 0;
402 u32 address;
403 u32 data;
404
405 do {
406// Workaround BEGIN
407 // address = RESET_CONTROL_ADDRESS;
408
409 if (coldReset) {
410 data = RESET_CONTROL_COLD_RST_MASK;
411 }
412 else {
413 data = RESET_CONTROL_MBOX_RST_MASK;
414 }
415
416 /* Hardcode the address of RESET_CONTROL_ADDRESS based on the target type */
417 if (TargetType == TARGET_TYPE_AR6002) {
418 address = AR6002_RESET_CONTROL_ADDRESS;
419 } else if (TargetType == TARGET_TYPE_AR6003) {
420 address = AR6003_RESET_CONTROL_ADDRESS;
421 } else {
422 A_ASSERT(0);
423 }
424
425
426 status = ar6000_WriteRegDiag(hifDevice, &address, &data);
427
428 if (status) {
429 break;
430 }
431
432 if (!waitForCompletion) {
433 break;
434 }
435
436#if 0
437 /* Up to 2 second delay to allow things to settle down */
438 (void)_delay_until_target_alive(hifDevice, 2000, TargetType);
439
440 /*
441 * Read back the RESET CAUSE register to ensure that the cold reset
442 * went through.
443 */
444
445 // address = RESET_CAUSE_ADDRESS;
446 /* Hardcode the address of RESET_CAUSE_ADDRESS based on the target type */
447 if (TargetType == TARGET_TYPE_AR6002) {
448 address = 0x000040C0;
449 } else if (TargetType == TARGET_TYPE_AR6003) {
450 address = 0x000040C0;
451 } else {
452 A_ASSERT(0);
453 }
454
455 data = 0;
456 status = ar6000_ReadRegDiag(hifDevice, &address, &data);
457
458 if (status) {
459 break;
460 }
461
462 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data));
463 data &= RESET_CAUSE_LAST_MASK;
464 if (data != 2) {
465 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n"));
466 }
467#endif
468// Workaroud END
469
470 } while (false);
471
472 if (status) {
473 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n"));
474 }
475
476 return 0;
477}
478
479/* This should be called in BMI phase after firmware is downloaded */
480void
481ar6000_copy_cust_data_from_target(struct hif_device *hifDevice, u32 TargetType)
482{
483 u32 eepHeaderAddr;
484 u8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4];
485 s32 i;
486
487 if (BMIReadMemory(hifDevice,
488 HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_board_data),
489 (u8 *)&eepHeaderAddr,
490 4)!= 0)
491 {
492 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadMemory for reading board data address failed \n"));
493 return;
494 }
495
496 if (TargetType == TARGET_TYPE_AR6003) {
497 eepHeaderAddr += 36; /* AR6003 customer data section offset is 37 */
498
499 for (i=0; i<AR6003_CUST_DATA_SIZE+4; i+=4){
500 if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (u32 *)&AR6003CustDataShadow[i])!= 0) {
501 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
502 return ;
503 }
504 eepHeaderAddr +=4;
505 }
506
507 memcpy(custDataAR6003, AR6003CustDataShadow+1, AR6003_CUST_DATA_SIZE);
508 }
509
510 if (TargetType == TARGET_TYPE_AR6002) {
511 eepHeaderAddr += 64; /* AR6002 customer data sectioin offset is 64 */
512
513 for (i=0; i<AR6002_CUST_DATA_SIZE; i+=4){
514 if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (u32 *)&custDataAR6002[i])!= 0) {
515 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
516 return ;
517 }
518 eepHeaderAddr +=4;
519 }
520 }
521
522 return;
523}
524
525/* This is the function to call when need to use the cust data */
526u8 *ar6000_get_cust_data_buffer(u32 TargetType)
527{
528 if (TargetType == TARGET_TYPE_AR6003)
529 return custDataAR6003;
530
531 if (TargetType == TARGET_TYPE_AR6002)
532 return custDataAR6002;
533
534 return NULL;
535}
536
537#define REG_DUMP_COUNT_AR6001 38 /* WORDs, derived from AR600x_regdump.h */
538#define REG_DUMP_COUNT_AR6002 60
539#define REG_DUMP_COUNT_AR6003 60
540#define REGISTER_DUMP_LEN_MAX 60
541#if REG_DUMP_COUNT_AR6001 > REGISTER_DUMP_LEN_MAX
542#error "REG_DUMP_COUNT_AR6001 too large"
543#endif
544#if REG_DUMP_COUNT_AR6002 > REGISTER_DUMP_LEN_MAX
545#error "REG_DUMP_COUNT_AR6002 too large"
546#endif
547#if REG_DUMP_COUNT_AR6003 > REGISTER_DUMP_LEN_MAX
548#error "REG_DUMP_COUNT_AR6003 too large"
549#endif
550
551
552void ar6000_dump_target_assert_info(struct hif_device *hifDevice, u32 TargetType)
553{
554 u32 address;
555 u32 regDumpArea = 0;
556 int status;
557 u32 regDumpValues[REGISTER_DUMP_LEN_MAX];
558 u32 regDumpCount = 0;
559 u32 i;
560
561 do {
562
563 /* the reg dump pointer is copied to the host interest area */
564 address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state);
565 address = TARG_VTOP(TargetType, address);
566
567 if (TargetType == TARGET_TYPE_AR6002) {
568 regDumpCount = REG_DUMP_COUNT_AR6002;
569 } else if (TargetType == TARGET_TYPE_AR6003) {
570 regDumpCount = REG_DUMP_COUNT_AR6003;
571 } else {
572 A_ASSERT(0);
573 }
574
575 /* read RAM location through diagnostic window */
576 status = ar6000_ReadRegDiag(hifDevice, &address, &regDumpArea);
577
578 if (status) {
579 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n"));
580 break;
581 }
582
583 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea));
584
585 if (regDumpArea == 0) {
586 /* no reg dump */
587 break;
588 }
589
590 regDumpArea = TARG_VTOP(TargetType, regDumpArea);
591
592 /* fetch register dump data */
593 status = ar6000_ReadDataDiag(hifDevice,
594 regDumpArea,
595 (u8 *)&regDumpValues[0],
596 regDumpCount * (sizeof(u32)));
597
598 if (status) {
599 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n"));
600 break;
601 }
602 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n"));
603
604 for (i = 0; i < regDumpCount; i++) {
605 //ATHR_DISPLAY_MSG (_T(" %d : 0x%8.8X \n"), i, regDumpValues[i]);
606 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d : 0x%8.8X \n",i, regDumpValues[i]));
607
608#ifdef UNDER_CE
609 /*
610 * For Every logPrintf() Open the File so that in case of Crashes
611 * We will have until the Last Message Flushed on to the File
612 * So use logPrintf Sparingly..!!
613 */
614 tgtassertPrintf (ATH_DEBUG_TRC," %d: 0x%8.8X \n",i, regDumpValues[i]);
615#endif
616 }
617
618 } while (false);
619
620}
621
622/* set HTC/Mbox operational parameters, this can only be called when the target is in the
623 * BMI phase */
624int ar6000_set_htc_params(struct hif_device *hifDevice,
625 u32 TargetType,
626 u32 MboxIsrYieldValue,
627 u8 HtcControlBuffers)
628{
629 int status;
630 u32 blocksizes[HTC_MAILBOX_NUM_MAX];
631
632 do {
633 /* get the block sizes */
634 status = HIFConfigureDevice(hifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
635 blocksizes, sizeof(blocksizes));
636
637 if (status) {
638 AR_DEBUG_PRINTF(ATH_LOG_ERR,("Failed to get block size info from HIF layer...\n"));
639 break;
640 }
641 /* note: we actually get the block size for mailbox 1, for SDIO the block
642 * size on mailbox 0 is artificially set to 1 */
643 /* must be a power of 2 */
644 A_ASSERT((blocksizes[1] & (blocksizes[1] - 1)) == 0);
645
646 if (HtcControlBuffers != 0) {
647 /* set override for number of control buffers to use */
648 blocksizes[1] |= ((u32)HtcControlBuffers) << 16;
649 }
650
651 /* set the host interest area for the block size */
652 status = BMIWriteMemory(hifDevice,
653 HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz),
654 (u8 *)&blocksizes[1],
655 4);
656
657 if (status) {
658 AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for IO block size failed \n"));
659 break;
660 }
661
662 AR_DEBUG_PRINTF(ATH_LOG_INF,("Block Size Set: %d (target address:0x%X)\n",
663 blocksizes[1], HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz)));
664
665 if (MboxIsrYieldValue != 0) {
666 /* set the host interest area for the mbox ISR yield limit */
667 status = BMIWriteMemory(hifDevice,
668 HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_isr_yield_limit),
669 (u8 *)&MboxIsrYieldValue,
670 4);
671
672 if (status) {
673 AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for yield limit failed \n"));
674 break;
675 }
676 }
677
678 } while (false);
679
680 return status;
681}
682
683void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription)
684{
685 char stream[60];
686 char byteOffsetStr[10];
687 u32 i;
688 u16 offset, count, byteOffset;
689
690 A_PRINTF("<---------Dumping %d Bytes : %s ------>\n", length, pDescription);
691
692 count = 0;
693 offset = 0;
694 byteOffset = 0;
695 for(i = 0; i < length; i++) {
696 A_SPRINTF(stream + offset, "%2.2X ", buffer[i]);
697 count ++;
698 offset += 3;
699
700 if(count == 16) {
701 count = 0;
702 offset = 0;
703 A_SPRINTF(byteOffsetStr,"%4.4X",byteOffset);
704 A_PRINTF("[%s]: %s\n", byteOffsetStr, stream);
705 A_MEMZERO(stream, 60);
706 byteOffset += 16;
707 }
708 }
709
710 if(offset != 0) {
711 A_SPRINTF(byteOffsetStr,"%4.4X",byteOffset);
712 A_PRINTF("[%s]: %s\n", byteOffsetStr, stream);
713 }
714
715 A_PRINTF("<------------------------------------------------->\n");
716}
717
718void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo)
719{
720 int i;
721 struct ath_debug_mask_description *pDesc;
722
723 if (pInfo == NULL) {
724 return;
725 }
726
727 pDesc = pInfo->pMaskDescriptions;
728
729 A_PRINTF("========================================================\n\n");
730 A_PRINTF("Module Debug Info => Name : %s \n", pInfo->ModuleName);
731 A_PRINTF(" => Descr. : %s \n", pInfo->ModuleDescription);
732 A_PRINTF("\n Current mask => 0x%8.8X \n", pInfo->CurrentMask);
733 A_PRINTF("\n Avail. Debug Masks :\n\n");
734
735 for (i = 0; i < pInfo->MaxDescriptions; i++,pDesc++) {
736 A_PRINTF(" => 0x%8.8X -- %s \n", pDesc->Mask, pDesc->Description);
737 }
738
739 if (0 == i) {
740 A_PRINTF(" => * none defined * \n");
741 }
742
743 A_PRINTF("\n Standard Debug Masks :\n\n");
744 /* print standard masks */
745 A_PRINTF(" => 0x%8.8X -- Errors \n", ATH_DEBUG_ERR);
746 A_PRINTF(" => 0x%8.8X -- Warnings \n", ATH_DEBUG_WARN);
747 A_PRINTF(" => 0x%8.8X -- Informational \n", ATH_DEBUG_INFO);
748 A_PRINTF(" => 0x%8.8X -- Tracing \n", ATH_DEBUG_TRC);
749 A_PRINTF("\n========================================================\n");
750
751}
752
753
754static ATH_DEBUG_MODULE_DBG_INFO *FindModule(char *module_name)
755{
756 ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
757
758 if (!g_ModuleDebugInit) {
759 return NULL;
760 }
761
762 while (pInfo != NULL) {
763 /* TODO: need to use something other than strlen */
764 if (memcmp(pInfo->ModuleName,module_name,strlen(module_name)) == 0) {
765 break;
766 }
767 pInfo = pInfo->pNext;
768 }
769
770 return pInfo;
771}
772
773
774void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo)
775{
776 if (!g_ModuleDebugInit) {
777 return;
778 }
779
780 A_MUTEX_LOCK(&g_ModuleListLock);
781
782 if (!(pInfo->Flags & ATH_DEBUG_INFO_FLAGS_REGISTERED)) {
783 if (g_pModuleInfoHead == NULL) {
784 g_pModuleInfoHead = pInfo;
785 } else {
786 pInfo->pNext = g_pModuleInfoHead;
787 g_pModuleInfoHead = pInfo;
788 }
789 pInfo->Flags |= ATH_DEBUG_INFO_FLAGS_REGISTERED;
790 }
791
792 A_MUTEX_UNLOCK(&g_ModuleListLock);
793}
794
795void a_dump_module_debug_info_by_name(char *module_name)
796{
797 ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
798
799 if (!g_ModuleDebugInit) {
800 return;
801 }
802
803 if (memcmp(module_name,"all",3) == 0) {
804 /* dump all */
805 while (pInfo != NULL) {
806 a_dump_module_debug_info(pInfo);
807 pInfo = pInfo->pNext;
808 }
809 return;
810 }
811
812 pInfo = FindModule(module_name);
813
814 if (pInfo != NULL) {
815 a_dump_module_debug_info(pInfo);
816 }
817
818}
819
820int a_get_module_mask(char *module_name, u32 *pMask)
821{
822 ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name);
823
824 if (NULL == pInfo) {
825 return A_ERROR;
826 }
827
828 *pMask = pInfo->CurrentMask;
829 return 0;
830}
831
832int a_set_module_mask(char *module_name, u32 Mask)
833{
834 ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name);
835
836 if (NULL == pInfo) {
837 return A_ERROR;
838 }
839
840 pInfo->CurrentMask = Mask;
841 A_PRINTF("Module %s, new mask: 0x%8.8X \n",module_name,pInfo->CurrentMask);
842 return 0;
843}
844
845
846void a_module_debug_support_init(void)
847{
848 if (g_ModuleDebugInit) {
849 return;
850 }
851 A_MUTEX_INIT(&g_ModuleListLock);
852 g_pModuleInfoHead = NULL;
853 g_ModuleDebugInit = true;
854 A_REGISTER_MODULE_DEBUG_INFO(misc);
855}
856
857void a_module_debug_support_cleanup(void)
858{
859 ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
860 ATH_DEBUG_MODULE_DBG_INFO *pCur;
861
862 if (!g_ModuleDebugInit) {
863 return;
864 }
865
866 g_ModuleDebugInit = false;
867
868 A_MUTEX_LOCK(&g_ModuleListLock);
869
870 while (pInfo != NULL) {
871 pCur = pInfo;
872 pInfo = pInfo->pNext;
873 pCur->pNext = NULL;
874 /* clear registered flag */
875 pCur->Flags &= ~ATH_DEBUG_INFO_FLAGS_REGISTERED;
876 }
877
878 A_MUTEX_UNLOCK(&g_ModuleListLock);
879
880 A_MUTEX_DELETE(&g_ModuleListLock);
881 g_pModuleInfoHead = NULL;
882}
883
884 /* can only be called during bmi init stage */
885int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice,
886 u32 TargetType,
887 u32 Flags)
888{
889 int status = 0;
890
891 do {
892
893 if (TargetType != TARGET_TYPE_AR6003) {
894 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Target Type:%d, does not support HCI bridging! \n",
895 TargetType));
896 break;
897 }
898
899 /* set hci bridge flags */
900 status = BMIWriteMemory(hifDevice,
901 HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_hci_bridge_flags),
902 (u8 *)&Flags,
903 4);
904
905
906 } while (false);
907
908 return status;
909}
910
diff --git a/drivers/staging/ath6kl/miscdrv/credit_dist.c b/drivers/staging/ath6kl/miscdrv/credit_dist.c
deleted file mode 100644
index c777e98a756..00000000000
--- a/drivers/staging/ath6kl/miscdrv/credit_dist.c
+++ /dev/null
@@ -1,417 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="credit_dist.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#include "a_config.h"
25#include "athdefs.h"
26#include "a_osapi.h"
27#define ATH_MODULE_NAME misc
28#include "a_debug.h"
29#include "htc_api.h"
30#include "common_drv.h"
31
32/********* CREDIT DISTRIBUTION FUNCTIONS ******************************************/
33
34#define NO_VO_SERVICE 1 /* currently WMI only uses 3 data streams, so we leave VO service inactive */
35#define CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS 1
36
37#ifdef NO_VO_SERVICE
38#define DATA_SVCS_USED 3
39#else
40#define DATA_SVCS_USED 4
41#endif
42
43static void RedistributeCredits(struct common_credit_state_info *pCredInfo,
44 struct htc_endpoint_credit_dist *pEPDistList);
45
46static void SeekCredits(struct common_credit_state_info *pCredInfo,
47 struct htc_endpoint_credit_dist *pEPDistList);
48
49/* reduce an ep's credits back to a set limit */
50static INLINE void ReduceCredits(struct common_credit_state_info *pCredInfo,
51 struct htc_endpoint_credit_dist *pEpDist,
52 int Limit)
53{
54 int credits;
55
56 /* set the new limit */
57 pEpDist->TxCreditsAssigned = Limit;
58
59 if (pEpDist->TxCredits <= Limit) {
60 return;
61 }
62
63 /* figure out how much to take away */
64 credits = pEpDist->TxCredits - Limit;
65 /* take them away */
66 pEpDist->TxCredits -= credits;
67 pCredInfo->CurrentFreeCredits += credits;
68}
69
70/* give an endpoint some credits from the free credit pool */
71#define GiveCredits(pCredInfo,pEpDist,credits) \
72{ \
73 (pEpDist)->TxCredits += (credits); \
74 (pEpDist)->TxCreditsAssigned += (credits); \
75 (pCredInfo)->CurrentFreeCredits -= (credits); \
76}
77
78
79/* default credit init callback.
80 * This function is called in the context of HTCStart() to setup initial (application-specific)
81 * credit distributions */
82static void ar6000_credit_init(void *Context,
83 struct htc_endpoint_credit_dist *pEPList,
84 int TotalCredits)
85{
86 struct htc_endpoint_credit_dist *pCurEpDist;
87 int count;
88 struct common_credit_state_info *pCredInfo = (struct common_credit_state_info *)Context;
89
90 pCredInfo->CurrentFreeCredits = TotalCredits;
91 pCredInfo->TotalAvailableCredits = TotalCredits;
92
93 pCurEpDist = pEPList;
94
95 /* run through the list and initialize */
96 while (pCurEpDist != NULL) {
97
98 /* set minimums for each endpoint */
99 pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg;
100
101#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS
102
103 if (TotalCredits > 4)
104 {
105 if ((pCurEpDist->ServiceID == WMI_DATA_BK_SVC) || (pCurEpDist->ServiceID == WMI_DATA_BE_SVC)){
106 /* assign at least min credits to lower than VO priority services */
107 GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin);
108 /* force active */
109 SET_EP_ACTIVE(pCurEpDist);
110 }
111 }
112
113#endif
114
115 if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) {
116 /* give control service some credits */
117 GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin);
118 /* control service is always marked active, it never goes inactive EVER */
119 SET_EP_ACTIVE(pCurEpDist);
120 } else if (pCurEpDist->ServiceID == WMI_DATA_BK_SVC) {
121 /* this is the lowest priority data endpoint, save this off for easy access */
122 pCredInfo->pLowestPriEpDist = pCurEpDist;
123 }
124
125 /* Streams have to be created (explicit | implicit)for all kinds
126 * of traffic. BE endpoints are also inactive in the beginning.
127 * When BE traffic starts it creates implicit streams that
128 * redistributes credits.
129 */
130
131 /* note, all other endpoints have minimums set but are initially given NO credits.
132 * Credits will be distributed as traffic activity demands */
133 pCurEpDist = pCurEpDist->pNext;
134 }
135
136 if (pCredInfo->CurrentFreeCredits <= 0) {
137 AR_DEBUG_PRINTF(ATH_LOG_INF, ("Not enough credits (%d) to do credit distributions \n", TotalCredits));
138 A_ASSERT(false);
139 return;
140 }
141
142 /* reset list */
143 pCurEpDist = pEPList;
144 /* now run through the list and set max operating credit limits for everyone */
145 while (pCurEpDist != NULL) {
146 if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) {
147 /* control service max is just 1 max message */
148 pCurEpDist->TxCreditsNorm = pCurEpDist->TxCreditsPerMaxMsg;
149 } else {
150 /* for the remaining data endpoints, we assume that each TxCreditsPerMaxMsg are
151 * the same.
152 * We use a simple calculation here, we take the remaining credits and
153 * determine how many max messages this can cover and then set each endpoint's
154 * normal value equal to 3/4 this amount.
155 * */
156 count = (pCredInfo->CurrentFreeCredits/pCurEpDist->TxCreditsPerMaxMsg) * pCurEpDist->TxCreditsPerMaxMsg;
157 count = (count * 3) >> 2;
158 count = max(count,pCurEpDist->TxCreditsPerMaxMsg);
159 /* set normal */
160 pCurEpDist->TxCreditsNorm = count;
161
162 }
163 pCurEpDist = pCurEpDist->pNext;
164 }
165
166}
167
168
169/* default credit distribution callback
170 * This callback is invoked whenever endpoints require credit distributions.
171 * A lock is held while this function is invoked, this function shall NOT block.
172 * The pEPDistList is a list of distribution structures in prioritized order as
173 * defined by the call to the HTCSetCreditDistribution() api.
174 *
175 */
176static void ar6000_credit_distribute(void *Context,
177 struct htc_endpoint_credit_dist *pEPDistList,
178 HTC_CREDIT_DIST_REASON Reason)
179{
180 struct htc_endpoint_credit_dist *pCurEpDist;
181 struct common_credit_state_info *pCredInfo = (struct common_credit_state_info *)Context;
182
183 switch (Reason) {
184 case HTC_CREDIT_DIST_SEND_COMPLETE :
185 pCurEpDist = pEPDistList;
186 /* we are given the start of the endpoint distribution list.
187 * There may be one or more endpoints to service.
188 * Run through the list and distribute credits */
189 while (pCurEpDist != NULL) {
190
191 if (pCurEpDist->TxCreditsToDist > 0) {
192 /* return the credits back to the endpoint */
193 pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist;
194 /* always zero out when we are done */
195 pCurEpDist->TxCreditsToDist = 0;
196
197 if (pCurEpDist->TxCredits > pCurEpDist->TxCreditsAssigned) {
198 /* reduce to the assigned limit, previous credit reductions
199 * could have caused the limit to change */
200 ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsAssigned);
201 }
202
203 if (pCurEpDist->TxCredits > pCurEpDist->TxCreditsNorm) {
204 /* oversubscribed endpoints need to reduce back to normal */
205 ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsNorm);
206 }
207
208 if (!IS_EP_ACTIVE(pCurEpDist)) {
209 /* endpoint is inactive, now check for messages waiting for credits */
210 if (pCurEpDist->TxQueueDepth == 0) {
211 /* EP is inactive and there are no pending messages,
212 * reduce credits back to zero to recover credits */
213 ReduceCredits(pCredInfo, pCurEpDist, 0);
214 }
215 }
216 }
217
218 pCurEpDist = pCurEpDist->pNext;
219 }
220
221 break;
222
223 case HTC_CREDIT_DIST_ACTIVITY_CHANGE :
224 RedistributeCredits(pCredInfo,pEPDistList);
225 break;
226 case HTC_CREDIT_DIST_SEEK_CREDITS :
227 SeekCredits(pCredInfo,pEPDistList);
228 break;
229 case HTC_DUMP_CREDIT_STATE :
230 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Credit Distribution, total : %d, free : %d\n",
231 pCredInfo->TotalAvailableCredits, pCredInfo->CurrentFreeCredits));
232 break;
233 default:
234 break;
235
236 }
237
238 /* sanity checks done after each distribution action */
239 A_ASSERT(pCredInfo->CurrentFreeCredits <= pCredInfo->TotalAvailableCredits);
240 A_ASSERT(pCredInfo->CurrentFreeCredits >= 0);
241
242}
243
244/* redistribute credits based on activity change */
245static void RedistributeCredits(struct common_credit_state_info *pCredInfo,
246 struct htc_endpoint_credit_dist *pEPDistList)
247{
248 struct htc_endpoint_credit_dist *pCurEpDist = pEPDistList;
249
250 /* walk through the list and remove credits from inactive endpoints */
251 while (pCurEpDist != NULL) {
252
253#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS
254
255 if ((pCurEpDist->ServiceID == WMI_DATA_BK_SVC) || (pCurEpDist->ServiceID == WMI_DATA_BE_SVC)) {
256 /* force low priority streams to always be active to retain their minimum credit distribution */
257 SET_EP_ACTIVE(pCurEpDist);
258 }
259#endif
260
261 if (pCurEpDist->ServiceID != WMI_CONTROL_SVC) {
262 if (!IS_EP_ACTIVE(pCurEpDist)) {
263 if (pCurEpDist->TxQueueDepth == 0) {
264 /* EP is inactive and there are no pending messages, reduce credits back to zero */
265 ReduceCredits(pCredInfo, pCurEpDist, 0);
266 } else {
267 /* we cannot zero the credits assigned to this EP, but to keep
268 * the credits available for these leftover packets, reduce to
269 * a minimum */
270 ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsMin);
271 }
272 }
273 }
274
275 /* NOTE in the active case, we do not need to do anything further,
276 * when an EP goes active and needs credits, HTC will call into
277 * our distribution function using a reason code of HTC_CREDIT_DIST_SEEK_CREDITS */
278
279 pCurEpDist = pCurEpDist->pNext;
280 }
281
282}
283
284/* HTC has an endpoint that needs credits, pEPDist is the endpoint in question */
285static void SeekCredits(struct common_credit_state_info *pCredInfo,
286 struct htc_endpoint_credit_dist *pEPDist)
287{
288 struct htc_endpoint_credit_dist *pCurEpDist;
289 int credits = 0;
290 int need;
291
292 do {
293
294 if (pEPDist->ServiceID == WMI_CONTROL_SVC) {
295 /* we never oversubscribe on the control service, this is not
296 * a high performance path and the target never holds onto control
297 * credits for too long */
298 break;
299 }
300
301#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS
302 if (pEPDist->ServiceID == WMI_DATA_VI_SVC) {
303 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm)) {
304 /* limit VI service from oversubscribing */
305 break;
306 }
307 }
308
309 if (pEPDist->ServiceID == WMI_DATA_VO_SVC) {
310 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm)) {
311 /* limit VO service from oversubscribing */
312 break;
313 }
314 }
315#else
316 if (pEPDist->ServiceID == WMI_DATA_VI_SVC) {
317 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) ||
318 (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg)) {
319 /* limit VI service from oversubscribing */
320 /* at least one free credit will not be used by VI */
321 break;
322 }
323 }
324
325 if (pEPDist->ServiceID == WMI_DATA_VO_SVC) {
326 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) ||
327 (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg)) {
328 /* limit VO service from oversubscribing */
329 /* at least one free credit will not be used by VO */
330 break;
331 }
332 }
333#endif
334
335 /* for all other services, we follow a simple algorithm of
336 * 1. checking the free pool for credits
337 * 2. checking lower priority endpoints for credits to take */
338
339 /* give what we can */
340 credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek);
341
342 if (credits >= pEPDist->TxCreditsSeek) {
343 /* we found some to fulfill the seek request */
344 break;
345 }
346
347 /* we don't have enough in the free pool, try taking away from lower priority services
348 *
349 * The rule for taking away credits:
350 * 1. Only take from lower priority endpoints
351 * 2. Only take what is allocated above the minimum (never starve an endpoint completely)
352 * 3. Only take what you need.
353 *
354 * */
355
356 /* starting at the lowest priority */
357 pCurEpDist = pCredInfo->pLowestPriEpDist;
358
359 /* work backwards until we hit the endpoint again */
360 while (pCurEpDist != pEPDist) {
361 /* calculate how many we need so far */
362 need = pEPDist->TxCreditsSeek - pCredInfo->CurrentFreeCredits;
363
364 if ((pCurEpDist->TxCreditsAssigned - need) >= pCurEpDist->TxCreditsMin) {
365 /* the current one has been allocated more than it's minimum and it
366 * has enough credits assigned above it's minimum to fulfill our need
367 * try to take away just enough to fulfill our need */
368 ReduceCredits(pCredInfo,
369 pCurEpDist,
370 pCurEpDist->TxCreditsAssigned - need);
371
372 if (pCredInfo->CurrentFreeCredits >= pEPDist->TxCreditsSeek) {
373 /* we have enough */
374 break;
375 }
376 }
377
378 pCurEpDist = pCurEpDist->pPrev;
379 }
380
381 /* return what we can get */
382 credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek);
383
384 } while (false);
385
386 /* did we find some credits? */
387 if (credits) {
388 /* give what we can */
389 GiveCredits(pCredInfo, pEPDist, credits);
390 }
391
392}
393
394/* initialize and setup credit distribution */
395int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, struct common_credit_state_info *pCredInfo)
396{
397 HTC_SERVICE_ID servicepriority[5];
398
399 A_MEMZERO(pCredInfo,sizeof(struct common_credit_state_info));
400
401 servicepriority[0] = WMI_CONTROL_SVC; /* highest */
402 servicepriority[1] = WMI_DATA_VO_SVC;
403 servicepriority[2] = WMI_DATA_VI_SVC;
404 servicepriority[3] = WMI_DATA_BE_SVC;
405 servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */
406
407 /* set callbacks and priority list */
408 HTCSetCreditDistribution(HTCHandle,
409 pCredInfo,
410 ar6000_credit_distribute,
411 ar6000_credit_init,
412 servicepriority,
413 5);
414
415 return 0;
416}
417
diff --git a/drivers/staging/ath6kl/miscdrv/miscdrv.h b/drivers/staging/ath6kl/miscdrv/miscdrv.h
deleted file mode 100644
index 41be5670db4..00000000000
--- a/drivers/staging/ath6kl/miscdrv/miscdrv.h
+++ /dev/null
@@ -1,42 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="miscdrv.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _MISCDRV_H
24#define _MISCDRV_H
25
26
27#define HOST_INTEREST_ITEM_ADDRESS(target, item) \
28 AR6002_HOST_INTEREST_ITEM_ADDRESS(item)
29
30u32 ar6kRev2Array[][128] = {
31 {0xFFFF, 0xFFFF}, // No Patches
32 };
33
34#define CFG_REV2_ITEMS 0 // no patches so far
35#define AR6K_RESET_ADDR 0x4000
36#define AR6K_RESET_VAL 0x100
37
38#define EEPROM_SZ 768
39#define EEPROM_WAIT_LIMIT 4
40
41#endif
42
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c
deleted file mode 100644
index 9b02895a152..00000000000
--- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c
+++ /dev/null
@@ -1,6267 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24/*
25 * This driver is a pseudo ethernet driver to access the Atheros AR6000
26 * WLAN Device
27 */
28
29#include "ar6000_drv.h"
30#include "cfg80211.h"
31#include "htc.h"
32#include "wmi_filter_linux.h"
33#include "epping_test.h"
34#include "wlan_config.h"
35#include "ar3kconfig.h"
36#include "ar6k_pal.h"
37#include "AR6002/addrs.h"
38
39
40/* LINUX_HACK_FUDGE_FACTOR -- this is used to provide a workaround for linux behavior. When
41 * the meta data was added to the header it was found that linux did not correctly provide
42 * enough headroom. However when more headroom was requested beyond what was truly needed
43 * Linux gave the requested headroom. Therefore to get the necessary headroom from Linux
44 * the driver requests more than is needed by the amount = LINUX_HACK_FUDGE_FACTOR */
45#define LINUX_HACK_FUDGE_FACTOR 16
46#define BDATA_BDADDR_OFFSET 28
47
48u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
49u8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
50
51#ifdef DEBUG
52
53#define ATH_DEBUG_DBG_LOG ATH_DEBUG_MAKE_MODULE_MASK(0)
54#define ATH_DEBUG_WLAN_CONNECT ATH_DEBUG_MAKE_MODULE_MASK(1)
55#define ATH_DEBUG_WLAN_SCAN ATH_DEBUG_MAKE_MODULE_MASK(2)
56#define ATH_DEBUG_WLAN_TX ATH_DEBUG_MAKE_MODULE_MASK(3)
57#define ATH_DEBUG_WLAN_RX ATH_DEBUG_MAKE_MODULE_MASK(4)
58#define ATH_DEBUG_HTC_RAW ATH_DEBUG_MAKE_MODULE_MASK(5)
59#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
60
61static struct ath_debug_mask_description driver_debug_desc[] = {
62 { ATH_DEBUG_DBG_LOG , "Target Debug Logs"},
63 { ATH_DEBUG_WLAN_CONNECT , "WLAN connect"},
64 { ATH_DEBUG_WLAN_SCAN , "WLAN scan"},
65 { ATH_DEBUG_WLAN_TX , "WLAN Tx"},
66 { ATH_DEBUG_WLAN_RX , "WLAN Rx"},
67 { ATH_DEBUG_HTC_RAW , "HTC Raw IF tracing"},
68 { ATH_DEBUG_HCI_BRIDGE , "HCI Bridge Setup"},
69 { ATH_DEBUG_HCI_RECV , "HCI Recv tracing"},
70 { ATH_DEBUG_HCI_DUMP , "HCI Packet dumps"},
71};
72
73ATH_DEBUG_INSTANTIATE_MODULE_VAR(driver,
74 "driver",
75 "Linux Driver Interface",
76 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_WLAN_SCAN |
77 ATH_DEBUG_HCI_BRIDGE,
78 ATH_DEBUG_DESCRIPTION_COUNT(driver_debug_desc),
79 driver_debug_desc);
80
81#endif
82
83
84#define IS_MAC_NULL(mac) (mac[0]==0 && mac[1]==0 && mac[2]==0 && mac[3]==0 && mac[4]==0 && mac[5]==0)
85#define IS_MAC_BCAST(mac) (*mac==0xff)
86
87#define DESCRIPTION "Driver to access the Atheros AR600x Device, version " __stringify(__VER_MAJOR_) "." __stringify(__VER_MINOR_) "." __stringify(__VER_PATCH_) "." __stringify(__BUILD_NUMBER_)
88
89MODULE_AUTHOR("Atheros Communications, Inc.");
90MODULE_DESCRIPTION(DESCRIPTION);
91MODULE_LICENSE("Dual BSD/GPL");
92
93#ifndef REORG_APTC_HEURISTICS
94#undef ADAPTIVE_POWER_THROUGHPUT_CONTROL
95#endif /* REORG_APTC_HEURISTICS */
96
97#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
98#define APTC_TRAFFIC_SAMPLING_INTERVAL 100 /* msec */
99#define APTC_UPPER_THROUGHPUT_THRESHOLD 3000 /* Kbps */
100#define APTC_LOWER_THROUGHPUT_THRESHOLD 2000 /* Kbps */
101
102typedef struct aptc_traffic_record {
103 bool timerScheduled;
104 struct timeval samplingTS;
105 unsigned long bytesReceived;
106 unsigned long bytesTransmitted;
107} APTC_TRAFFIC_RECORD;
108
109A_TIMER aptcTimer;
110APTC_TRAFFIC_RECORD aptcTR;
111#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
112
113#ifdef EXPORT_HCI_BRIDGE_INTERFACE
114// callbacks registered by HCI transport driver
115struct hci_transport_callbacks ar6kHciTransCallbacks = { NULL };
116#endif
117
118unsigned int processDot11Hdr = 0;
119
120char ifname[IFNAMSIZ] = {0,};
121
122int wlaninitmode = WLAN_INIT_MODE_DEFAULT;
123static bool bypasswmi;
124unsigned int debuglevel = 0;
125int tspecCompliance = ATHEROS_COMPLIANCE;
126unsigned int busspeedlow = 0;
127unsigned int onebitmode = 0;
128unsigned int skipflash = 0;
129unsigned int wmitimeout = 2;
130unsigned int wlanNodeCaching = 1;
131unsigned int enableuartprint = ENABLEUARTPRINT_DEFAULT;
132unsigned int logWmiRawMsgs = 0;
133unsigned int enabletimerwar = 0;
134unsigned int num_device = 1;
135unsigned int regscanmode;
136unsigned int fwmode = 1;
137unsigned int mbox_yield_limit = 99;
138unsigned int enablerssicompensation = 0;
139int reduce_credit_dribble = 1 + HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF;
140int allow_trace_signal = 0;
141#ifdef CONFIG_HOST_TCMD_SUPPORT
142unsigned int testmode =0;
143#endif
144
145unsigned int irqprocmode = HIF_DEVICE_IRQ_SYNC_ONLY;//HIF_DEVICE_IRQ_ASYNC_SYNC;
146unsigned int panic_on_assert = 1;
147unsigned int nohifscattersupport = NOHIFSCATTERSUPPORT_DEFAULT;
148
149unsigned int setuphci = SETUPHCI_DEFAULT;
150unsigned int loghci = 0;
151unsigned int setupbtdev = SETUPBTDEV_DEFAULT;
152#ifndef EXPORT_HCI_BRIDGE_INTERFACE
153unsigned int ar3khcibaud = AR3KHCIBAUD_DEFAULT;
154unsigned int hciuartscale = HCIUARTSCALE_DEFAULT;
155unsigned int hciuartstep = HCIUARTSTEP_DEFAULT;
156#endif
157unsigned int csumOffload=0;
158unsigned int csumOffloadTest=0;
159unsigned int eppingtest=0;
160unsigned int mac_addr_method;
161unsigned int firmware_bridge;
162
163module_param_string(ifname, ifname, sizeof(ifname), 0644);
164module_param(wlaninitmode, int, 0644);
165module_param(bypasswmi, bool, 0644);
166module_param(debuglevel, uint, 0644);
167module_param(tspecCompliance, int, 0644);
168module_param(onebitmode, uint, 0644);
169module_param(busspeedlow, uint, 0644);
170module_param(skipflash, uint, 0644);
171module_param(wmitimeout, uint, 0644);
172module_param(wlanNodeCaching, uint, 0644);
173module_param(logWmiRawMsgs, uint, 0644);
174module_param(enableuartprint, uint, 0644);
175module_param(enabletimerwar, uint, 0644);
176module_param(fwmode, uint, 0644);
177module_param(mbox_yield_limit, uint, 0644);
178module_param(reduce_credit_dribble, int, 0644);
179module_param(allow_trace_signal, int, 0644);
180module_param(enablerssicompensation, uint, 0644);
181module_param(processDot11Hdr, uint, 0644);
182module_param(csumOffload, uint, 0644);
183#ifdef CONFIG_HOST_TCMD_SUPPORT
184module_param(testmode, uint, 0644);
185#endif
186module_param(irqprocmode, uint, 0644);
187module_param(nohifscattersupport, uint, 0644);
188module_param(panic_on_assert, uint, 0644);
189module_param(setuphci, uint, 0644);
190module_param(loghci, uint, 0644);
191module_param(setupbtdev, uint, 0644);
192#ifndef EXPORT_HCI_BRIDGE_INTERFACE
193module_param(ar3khcibaud, uint, 0644);
194module_param(hciuartscale, uint, 0644);
195module_param(hciuartstep, uint, 0644);
196#endif
197module_param(eppingtest, uint, 0644);
198
199/* in 2.6.10 and later this is now a pointer to a uint */
200unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX;
201#define mboxnum &_mboxnum
202
203#ifdef DEBUG
204u32 g_dbg_flags = DBG_DEFAULTS;
205unsigned int debugflags = 0;
206int debugdriver = 0;
207unsigned int debughtc = 0;
208unsigned int debugbmi = 0;
209unsigned int debughif = 0;
210unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0};
211unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0};
212unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0};
213unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0};
214module_param(debugflags, uint, 0644);
215module_param(debugdriver, int, 0644);
216module_param(debughtc, uint, 0644);
217module_param(debugbmi, uint, 0644);
218module_param(debughif, uint, 0644);
219module_param_array(txcreditsavailable, uint, mboxnum, 0644);
220module_param_array(txcreditsconsumed, uint, mboxnum, 0644);
221module_param_array(txcreditintrenable, uint, mboxnum, 0644);
222module_param_array(txcreditintrenableaggregate, uint, mboxnum, 0644);
223
224#endif /* DEBUG */
225
226unsigned int resetok = 1;
227unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0};
228unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0};
229unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0};
230unsigned int hifBusRequestNumMax = 40;
231unsigned int war23838_disabled = 0;
232#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
233unsigned int enableAPTCHeuristics = 1;
234#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
235module_param_array(tx_attempt, uint, mboxnum, 0644);
236module_param_array(tx_post, uint, mboxnum, 0644);
237module_param_array(tx_complete, uint, mboxnum, 0644);
238module_param(hifBusRequestNumMax, uint, 0644);
239module_param(war23838_disabled, uint, 0644);
240module_param(resetok, uint, 0644);
241#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
242module_param(enableAPTCHeuristics, uint, 0644);
243#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
244
245#ifdef BLOCK_TX_PATH_FLAG
246int blocktx = 0;
247module_param(blocktx, int, 0644);
248#endif /* BLOCK_TX_PATH_FLAG */
249
250typedef struct user_rssi_compensation_t {
251 u16 customerID;
252 union {
253 u16 a_enable;
254 u16 bg_enable;
255 u16 enable;
256 };
257 s16 bg_param_a;
258 s16 bg_param_b;
259 s16 a_param_a;
260 s16 a_param_b;
261 u32 reserved;
262} USER_RSSI_CPENSATION;
263
264static USER_RSSI_CPENSATION rssi_compensation_param;
265
266static s16 rssi_compensation_table[96];
267
268int reconnect_flag = 0;
269static ar6k_pal_config_t ar6k_pal_config_g;
270
271/* Function declarations */
272static int ar6000_init_module(void);
273static void ar6000_cleanup_module(void);
274
275int ar6000_init(struct net_device *dev);
276static int ar6000_open(struct net_device *dev);
277static int ar6000_close(struct net_device *dev);
278static void ar6000_init_control_info(struct ar6_softc *ar);
279static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev);
280
281void ar6000_destroy(struct net_device *dev, unsigned int unregister);
282static void ar6000_detect_error(unsigned long ptr);
283static void ar6000_set_multicast_list(struct net_device *dev);
284static struct net_device_stats *ar6000_get_stats(struct net_device *dev);
285
286static void disconnect_timer_handler(unsigned long ptr);
287
288void read_rssi_compensation_param(struct ar6_softc *ar);
289
290/*
291 * HTC service connection handlers
292 */
293static int ar6000_avail_ev(void *context, void *hif_handle);
294
295static int ar6000_unavail_ev(void *context, void *hif_handle);
296
297int ar6000_configure_target(struct ar6_softc *ar);
298
299static void ar6000_target_failure(void *Instance, int Status);
300
301static void ar6000_rx(void *Context, struct htc_packet *pPacket);
302
303static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint);
304
305static void ar6000_tx_complete(void *Context, struct htc_packet_queue *pPackets);
306
307static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket);
308
309static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num);
310static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf);
311//static void ar6000_deliver_frames_to_bt_stack(void * dev, void *osbuf);
312
313static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length);
314
315static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count);
316
317static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar);
318
319static ssize_t
320ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj,
321 struct bin_attribute *bin_attr,
322 char *buf, loff_t pos, size_t count);
323
324static ssize_t
325ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj,
326 struct bin_attribute *bin_attr,
327 char *buf, loff_t pos, size_t count);
328
329static int
330ar6000_sysfs_bmi_init(struct ar6_softc *ar);
331
332void ar6k_cleanup_hci_pal(struct ar6_softc *ar);
333
334static void
335ar6000_sysfs_bmi_deinit(struct ar6_softc *ar);
336
337int
338ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode);
339
340/*
341 * Static variables
342 */
343
344struct net_device *ar6000_devices[MAX_AR6000];
345static int is_netdev_registered;
346DECLARE_WAIT_QUEUE_HEAD(arEvent);
347static void ar6000_cookie_init(struct ar6_softc *ar);
348static void ar6000_cookie_cleanup(struct ar6_softc *ar);
349static void ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie);
350static struct ar_cookie *ar6000_alloc_cookie(struct ar6_softc *ar);
351
352static int ar6000_reinstall_keys(struct ar6_softc *ar,u8 key_op_ctrl);
353
354#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
355struct net_device *arApNetDev;
356#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
357
358static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM];
359
360#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
361 (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
362 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))
363
364
365static struct net_device_ops ar6000_netdev_ops = {
366 .ndo_init = NULL,
367 .ndo_open = ar6000_open,
368 .ndo_stop = ar6000_close,
369 .ndo_get_stats = ar6000_get_stats,
370 .ndo_start_xmit = ar6000_data_tx,
371 .ndo_set_rx_mode = ar6000_set_multicast_list,
372};
373
374/* Debug log support */
375
376/*
377 * Flag to govern whether the debug logs should be parsed in the kernel
378 * or reported to the application.
379 */
380#define REPORT_DEBUG_LOGS_TO_APP
381
382int
383ar6000_set_host_app_area(struct ar6_softc *ar)
384{
385 u32 address, data;
386 struct host_app_area_s host_app_area;
387
388 /* Fetch the address of the host_app_area_s instance in the host interest area */
389 address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest));
390 if (ar6000_ReadRegDiag(ar->arHifDevice, &address, &data) != 0) {
391 return A_ERROR;
392 }
393 address = TARG_VTOP(ar->arTargetType, data);
394 host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
395 if (ar6000_WriteDataDiag(ar->arHifDevice, address,
396 (u8 *)&host_app_area,
397 sizeof(struct host_app_area_s)) != 0)
398 {
399 return A_ERROR;
400 }
401
402 return 0;
403}
404
405u32 dbglog_get_debug_hdr_ptr(struct ar6_softc *ar)
406{
407 u32 param;
408 u32 address;
409 int status;
410
411 address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr));
412 if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address,
413 (u8 *)&param, 4)) != 0)
414 {
415 param = 0;
416 }
417
418 return param;
419}
420
421/*
422 * The dbglog module has been initialized. Its ok to access the relevant
423 * data stuctures over the diagnostic window.
424 */
425void
426ar6000_dbglog_init_done(struct ar6_softc *ar)
427{
428 ar->dbglog_init_done = true;
429}
430
431u32 dbglog_get_debug_fragment(s8 *datap, u32 len, u32 limit)
432{
433 s32 *buffer;
434 u32 count;
435 u32 numargs;
436 u32 length;
437 u32 fraglen;
438
439 count = fraglen = 0;
440 buffer = (s32 *)datap;
441 length = (limit >> 2);
442
443 if (len <= limit) {
444 fraglen = len;
445 } else {
446 while (count < length) {
447 numargs = DBGLOG_GET_NUMARGS(buffer[count]);
448 fraglen = (count << 2);
449 count += numargs + 1;
450 }
451 }
452
453 return fraglen;
454}
455
456void
457dbglog_parse_debug_logs(s8 *datap, u32 len)
458{
459 s32 *buffer;
460 u32 count;
461 u32 timestamp;
462 u32 debugid;
463 u32 moduleid;
464 u32 numargs;
465 u32 length;
466
467 count = 0;
468 buffer = (s32 *)datap;
469 length = (len >> 2);
470 while (count < length) {
471 debugid = DBGLOG_GET_DBGID(buffer[count]);
472 moduleid = DBGLOG_GET_MODULEID(buffer[count]);
473 numargs = DBGLOG_GET_NUMARGS(buffer[count]);
474 timestamp = DBGLOG_GET_TIMESTAMP(buffer[count]);
475 switch (numargs) {
476 case 0:
477 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d)\n", moduleid, debugid, timestamp));
478 break;
479
480 case 1:
481 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x\n", moduleid, debugid,
482 timestamp, buffer[count+1]));
483 break;
484
485 case 2:
486 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x, 0x%x\n", moduleid, debugid,
487 timestamp, buffer[count+1], buffer[count+2]));
488 break;
489
490 default:
491 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid args: %d\n", numargs));
492 }
493 count += numargs + 1;
494 }
495}
496
497int
498ar6000_dbglog_get_debug_logs(struct ar6_softc *ar)
499{
500 u32 data[8]; /* Should be able to accommodate struct dbglog_buf_s */
501 u32 address;
502 u32 length;
503 u32 dropped;
504 u32 firstbuf;
505 u32 debug_hdr_ptr;
506
507 if (!ar->dbglog_init_done) return A_ERROR;
508
509
510 AR6000_SPIN_LOCK(&ar->arLock, 0);
511
512 if (ar->dbgLogFetchInProgress) {
513 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
514 return A_EBUSY;
515 }
516
517 /* block out others */
518 ar->dbgLogFetchInProgress = true;
519
520 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
521
522 debug_hdr_ptr = dbglog_get_debug_hdr_ptr(ar);
523 printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr);
524
525 /* Get the contents of the ring buffer */
526 if (debug_hdr_ptr) {
527 address = TARG_VTOP(ar->arTargetType, debug_hdr_ptr);
528 length = 4 /* sizeof(dbuf) */ + 4 /* sizeof(dropped) */;
529 A_MEMZERO(data, sizeof(data));
530 ar6000_ReadDataDiag(ar->arHifDevice, address, (u8 *)data, length);
531 address = TARG_VTOP(ar->arTargetType, data[0] /* dbuf */);
532 firstbuf = address;
533 dropped = data[1]; /* dropped */
534 length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */;
535 A_MEMZERO(data, sizeof(data));
536 ar6000_ReadDataDiag(ar->arHifDevice, address, (u8 *)&data, length);
537
538 do {
539 address = TARG_VTOP(ar->arTargetType, data[1] /* buffer*/);
540 length = data[3]; /* length */
541 if ((length) && (length <= data[2] /* bufsize*/)) {
542 /* Rewind the index if it is about to overrun the buffer */
543 if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) {
544 ar->log_cnt = 0;
545 }
546 if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address,
547 (u8 *)&ar->log_buffer[ar->log_cnt], length))
548 {
549 break;
550 }
551 ar6000_dbglog_event(ar, dropped, (s8 *)&ar->log_buffer[ar->log_cnt], length);
552 ar->log_cnt += length;
553 } else {
554 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("Length: %d (Total size: %d)\n",
555 data[3], data[2]));
556 }
557
558 address = TARG_VTOP(ar->arTargetType, data[0] /* next */);
559 length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */;
560 A_MEMZERO(data, sizeof(data));
561 if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address,
562 (u8 *)&data, length))
563 {
564 break;
565 }
566
567 } while (address != firstbuf);
568 }
569
570 ar->dbgLogFetchInProgress = false;
571
572 return 0;
573}
574
575void
576ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped,
577 s8 *buffer, u32 length)
578{
579#ifdef REPORT_DEBUG_LOGS_TO_APP
580 #define MAX_WIRELESS_EVENT_SIZE 252
581 /*
582 * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages.
583 * There seems to be a limitation on the length of message that could be
584 * transmitted to the user app via this mechanism.
585 */
586 u32 send, sent;
587
588 sent = 0;
589 send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
590 MAX_WIRELESS_EVENT_SIZE);
591 while (send) {
592 sent += send;
593 send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
594 MAX_WIRELESS_EVENT_SIZE);
595 }
596#else
597 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Dropped logs: 0x%x\nDebug info length: %d\n",
598 dropped, length));
599
600 /* Interpret the debug logs */
601 dbglog_parse_debug_logs((s8 *)buffer, length);
602#endif /* REPORT_DEBUG_LOGS_TO_APP */
603}
604
605
606static int __init
607ar6000_init_module(void)
608{
609 static int probed = 0;
610 int r;
611 OSDRV_CALLBACKS osdrvCallbacks;
612
613 a_module_debug_support_init();
614
615#ifdef DEBUG
616 /* check for debug mask overrides */
617 if (debughtc != 0) {
618 ATH_DEBUG_SET_DEBUG_MASK(htc,debughtc);
619 }
620 if (debugbmi != 0) {
621 ATH_DEBUG_SET_DEBUG_MASK(bmi,debugbmi);
622 }
623 if (debughif != 0) {
624 ATH_DEBUG_SET_DEBUG_MASK(hif,debughif);
625 }
626 if (debugdriver != 0) {
627 ATH_DEBUG_SET_DEBUG_MASK(driver,debugdriver);
628 }
629
630#endif
631
632 A_REGISTER_MODULE_DEBUG_INFO(driver);
633
634 A_MEMZERO(&osdrvCallbacks,sizeof(osdrvCallbacks));
635 osdrvCallbacks.deviceInsertedHandler = ar6000_avail_ev;
636 osdrvCallbacks.deviceRemovedHandler = ar6000_unavail_ev;
637#ifdef CONFIG_PM
638 osdrvCallbacks.deviceSuspendHandler = ar6000_suspend_ev;
639 osdrvCallbacks.deviceResumeHandler = ar6000_resume_ev;
640 osdrvCallbacks.devicePowerChangeHandler = ar6000_power_change_ev;
641#endif
642
643#ifdef DEBUG
644 /* Set the debug flags if specified at load time */
645 if(debugflags != 0)
646 {
647 g_dbg_flags = debugflags;
648 }
649#endif
650
651 if (probed) {
652 return -ENODEV;
653 }
654 probed++;
655
656#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
657 memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD));
658#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
659
660 r = HIFInit(&osdrvCallbacks);
661 if (r)
662 return r;
663
664 return 0;
665}
666
667static void __exit
668ar6000_cleanup_module(void)
669{
670 int i = 0;
671 struct net_device *ar6000_netdev;
672
673#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
674 /* Delete the Adaptive Power Control timer */
675 if (timer_pending(&aptcTimer)) {
676 del_timer_sync(&aptcTimer);
677 }
678#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
679
680 for (i=0; i < MAX_AR6000; i++) {
681 if (ar6000_devices[i] != NULL) {
682 ar6000_netdev = ar6000_devices[i];
683 ar6000_devices[i] = NULL;
684 ar6000_destroy(ar6000_netdev, 1);
685 }
686 }
687
688 HIFShutDownDevice(NULL);
689
690 a_module_debug_support_cleanup();
691
692 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_cleanup: success\n"));
693}
694
695#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
696void
697aptcTimerHandler(unsigned long arg)
698{
699 u32 numbytes;
700 u32 throughput;
701 struct ar6_softc *ar;
702 int status;
703
704 ar = (struct ar6_softc *)arg;
705 A_ASSERT(ar != NULL);
706 A_ASSERT(!timer_pending(&aptcTimer));
707
708 AR6000_SPIN_LOCK(&ar->arLock, 0);
709
710 /* Get the number of bytes transferred */
711 numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
712 aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
713
714 /* Calculate and decide based on throughput thresholds */
715 throughput = ((numbytes * 8)/APTC_TRAFFIC_SAMPLING_INTERVAL); /* Kbps */
716 if (throughput < APTC_LOWER_THROUGHPUT_THRESHOLD) {
717 /* Enable Sleep and delete the timer */
718 A_ASSERT(ar->arWmiReady == true);
719 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
720 status = wmi_powermode_cmd(ar->arWmi, REC_POWER);
721 AR6000_SPIN_LOCK(&ar->arLock, 0);
722 A_ASSERT(status == 0);
723 aptcTR.timerScheduled = false;
724 } else {
725 A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
726 }
727
728 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
729}
730#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
731
732static void
733ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num)
734{
735 void * osbuf;
736
737 while(num) {
738 if((osbuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE))) {
739 A_NETBUF_ENQUEUE(q, osbuf);
740 } else {
741 break;
742 }
743 num--;
744 }
745
746 if(num) {
747 A_PRINTF("%s(), allocation of netbuf failed", __func__);
748 }
749}
750
751static struct bin_attribute bmi_attr = {
752 .attr = {.name = "bmi", .mode = 0600},
753 .read = ar6000_sysfs_bmi_read,
754 .write = ar6000_sysfs_bmi_write,
755};
756
757static ssize_t
758ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj,
759 struct bin_attribute *bin_attr,
760 char *buf, loff_t pos, size_t count)
761{
762 int index;
763 struct ar6_softc *ar;
764 struct hif_device_os_device_info *osDevInfo;
765
766 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", (u32)count));
767 for (index=0; index < MAX_AR6000; index++) {
768 ar = (struct ar6_softc *)ar6k_priv(ar6000_devices[index]);
769 osDevInfo = &ar->osDevInfo;
770 if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
771 break;
772 }
773 }
774
775 if (index == MAX_AR6000) return 0;
776
777 if ((BMIRawRead(ar->arHifDevice, (u8*)buf, count, true)) != 0) {
778 return 0;
779 }
780
781 return count;
782}
783
784static ssize_t
785ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj,
786 struct bin_attribute *bin_attr,
787 char *buf, loff_t pos, size_t count)
788{
789 int index;
790 struct ar6_softc *ar;
791 struct hif_device_os_device_info *osDevInfo;
792
793 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", (u32)count));
794 for (index=0; index < MAX_AR6000; index++) {
795 ar = (struct ar6_softc *)ar6k_priv(ar6000_devices[index]);
796 osDevInfo = &ar->osDevInfo;
797 if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
798 break;
799 }
800 }
801
802 if (index == MAX_AR6000) return 0;
803
804 if ((BMIRawWrite(ar->arHifDevice, (u8*)buf, count)) != 0) {
805 return 0;
806 }
807
808 return count;
809}
810
811static int
812ar6000_sysfs_bmi_init(struct ar6_softc *ar)
813{
814 int status;
815
816 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Creating sysfs entry\n"));
817 A_MEMZERO(&ar->osDevInfo, sizeof(struct hif_device_os_device_info));
818
819 /* Get the underlying OS device */
820 status = HIFConfigureDevice(ar->arHifDevice,
821 HIF_DEVICE_GET_OS_DEVICE,
822 &ar->osDevInfo,
823 sizeof(struct hif_device_os_device_info));
824
825 if (status) {
826 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failed to get OS device info from HIF\n"));
827 return A_ERROR;
828 }
829
830 /* Create a bmi entry in the sysfs filesystem */
831 if ((sysfs_create_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr)) < 0)
832 {
833 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to create entry for bmi in sysfs filesystem\n"));
834 return A_ERROR;
835 }
836
837 return 0;
838}
839
840static void
841ar6000_sysfs_bmi_deinit(struct ar6_softc *ar)
842{
843 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Deleting sysfs entry\n"));
844
845 sysfs_remove_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr);
846}
847
848#define bmifn(fn) do { \
849 if ((fn) < 0) { \
850 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); \
851 return A_ERROR; \
852 } \
853} while(0)
854
855#ifdef SOFTMAC_FILE_USED
856#define AR6002_MAC_ADDRESS_OFFSET 0x0A
857#define AR6003_MAC_ADDRESS_OFFSET 0x16
858static
859void calculate_crc(u32 TargetType, u8 *eeprom_data)
860{
861 u16 *ptr_crc;
862 u16 *ptr16_eeprom;
863 u16 checksum;
864 u32 i;
865 u32 eeprom_size;
866
867 if (TargetType == TARGET_TYPE_AR6001)
868 {
869 eeprom_size = 512;
870 ptr_crc = (u16 *)eeprom_data;
871 }
872 else if (TargetType == TARGET_TYPE_AR6003)
873 {
874 eeprom_size = 1024;
875 ptr_crc = (u16 *)((u8 *)eeprom_data + 0x04);
876 }
877 else
878 {
879 eeprom_size = 768;
880 ptr_crc = (u16 *)((u8 *)eeprom_data + 0x04);
881 }
882
883
884 // Clear the crc
885 *ptr_crc = 0;
886
887 // Recalculate new CRC
888 checksum = 0;
889 ptr16_eeprom = (u16 *)eeprom_data;
890 for (i = 0;i < eeprom_size; i += 2)
891 {
892 checksum = checksum ^ (*ptr16_eeprom);
893 ptr16_eeprom++;
894 }
895 checksum = 0xFFFF ^ checksum;
896 *ptr_crc = checksum;
897}
898
899static void
900ar6000_softmac_update(struct ar6_softc *ar, u8 *eeprom_data, size_t size)
901{
902 const char *source = "random generated";
903 const struct firmware *softmac_entry;
904 u8 *ptr_mac;
905 switch (ar->arTargetType) {
906 case TARGET_TYPE_AR6002:
907 ptr_mac = (u8 *)((u8 *)eeprom_data + AR6002_MAC_ADDRESS_OFFSET);
908 break;
909 case TARGET_TYPE_AR6003:
910 ptr_mac = (u8 *)((u8 *)eeprom_data + AR6003_MAC_ADDRESS_OFFSET);
911 break;
912 default:
913 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Target Type\n"));
914 return;
915 }
916 printk(KERN_DEBUG "MAC from EEPROM %pM\n", ptr_mac);
917
918 /* create a random MAC in case we cannot read file from system */
919 ptr_mac[0] = 0;
920 ptr_mac[1] = 0x03;
921 ptr_mac[2] = 0x7F;
922 ptr_mac[3] = random32() & 0xff;
923 ptr_mac[4] = random32() & 0xff;
924 ptr_mac[5] = random32() & 0xff;
925 if ((A_REQUEST_FIRMWARE(&softmac_entry, "softmac", ((struct device *)ar->osDevInfo.pOSDevice))) == 0)
926 {
927 char *macbuf = A_MALLOC_NOWAIT(softmac_entry->size+1);
928 if (macbuf) {
929 unsigned int softmac[6];
930 memcpy(macbuf, softmac_entry->data, softmac_entry->size);
931 macbuf[softmac_entry->size] = '\0';
932 if (sscanf(macbuf, "%02x:%02x:%02x:%02x:%02x:%02x",
933 &softmac[0], &softmac[1], &softmac[2],
934 &softmac[3], &softmac[4], &softmac[5])==6) {
935 int i;
936 for (i=0; i<6; ++i) {
937 ptr_mac[i] = softmac[i] & 0xff;
938 }
939 source = "softmac file";
940 }
941 kfree(macbuf);
942 }
943 A_RELEASE_FIRMWARE(softmac_entry);
944 }
945 printk(KERN_DEBUG "MAC from %s %pM\n", source, ptr_mac);
946 calculate_crc(ar->arTargetType, eeprom_data);
947}
948#endif /* SOFTMAC_FILE_USED */
949
950static int
951ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, bool compressed)
952{
953 int status;
954 const char *filename;
955 const struct firmware *fw_entry;
956 u32 fw_entry_size;
957 u8 **buf;
958 size_t *buf_len;
959
960 switch (file) {
961 case AR6K_OTP_FILE:
962 buf = &ar->fw_otp;
963 buf_len = &ar->fw_otp_len;
964 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
965 filename = AR6003_REV1_OTP_FILE;
966 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
967 filename = AR6003_REV2_OTP_FILE;
968 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
969 filename = AR6003_REV3_OTP_FILE;
970 } else {
971 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
972 return A_ERROR;
973 }
974 break;
975
976 case AR6K_FIRMWARE_FILE:
977 buf = &ar->fw;
978 buf_len = &ar->fw_len;
979 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
980 filename = AR6003_REV1_FIRMWARE_FILE;
981 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
982 filename = AR6003_REV2_FIRMWARE_FILE;
983 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
984 filename = AR6003_REV3_FIRMWARE_FILE;
985 } else {
986 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
987 return A_ERROR;
988 }
989
990 if (eppingtest) {
991 bypasswmi = true;
992 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
993 filename = AR6003_REV1_EPPING_FIRMWARE_FILE;
994 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
995 filename = AR6003_REV2_EPPING_FIRMWARE_FILE;
996 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
997 filename = AR6003_REV3_EPPING_FIRMWARE_FILE;
998 } else {
999 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("eppingtest : unsupported firmware revision: %d\n",
1000 ar->arVersion.target_ver));
1001 return A_ERROR;
1002 }
1003 compressed = false;
1004 }
1005
1006#ifdef CONFIG_HOST_TCMD_SUPPORT
1007 if(testmode) {
1008 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1009 filename = AR6003_REV1_TCMD_FIRMWARE_FILE;
1010 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1011 filename = AR6003_REV2_TCMD_FIRMWARE_FILE;
1012 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
1013 filename = AR6003_REV3_TCMD_FIRMWARE_FILE;
1014 } else {
1015 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1016 return A_ERROR;
1017 }
1018 compressed = false;
1019 }
1020#endif
1021#ifdef HTC_RAW_INTERFACE
1022 if (!eppingtest && bypasswmi) {
1023 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1024 filename = AR6003_REV1_ART_FIRMWARE_FILE;
1025 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1026 filename = AR6003_REV2_ART_FIRMWARE_FILE;
1027 } else {
1028 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1029 return A_ERROR;
1030 }
1031 compressed = false;
1032 }
1033#endif
1034 break;
1035
1036 case AR6K_PATCH_FILE:
1037 buf = &ar->fw_patch;
1038 buf_len = &ar->fw_patch_len;
1039 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1040 filename = AR6003_REV1_PATCH_FILE;
1041 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1042 filename = AR6003_REV2_PATCH_FILE;
1043 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
1044 filename = AR6003_REV3_PATCH_FILE;
1045 } else {
1046 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1047 return A_ERROR;
1048 }
1049 break;
1050
1051 case AR6K_BOARD_DATA_FILE:
1052 buf = &ar->fw_data;
1053 buf_len = &ar->fw_data_len;
1054 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1055 filename = AR6003_REV1_BOARD_DATA_FILE;
1056 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1057 filename = AR6003_REV2_BOARD_DATA_FILE;
1058 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
1059 filename = AR6003_REV3_BOARD_DATA_FILE;
1060 } else {
1061 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1062 return A_ERROR;
1063 }
1064 break;
1065
1066 default:
1067 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file));
1068 return A_ERROR;
1069 }
1070
1071 if (*buf == NULL) {
1072 if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) {
1073 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename));
1074 return A_ENOENT;
1075 }
1076
1077 *buf = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
1078 *buf_len = fw_entry->size;
1079 A_RELEASE_FIRMWARE(fw_entry);
1080 }
1081
1082#ifdef SOFTMAC_FILE_USED
1083 if (file==AR6K_BOARD_DATA_FILE && *buf_len) {
1084 ar6000_softmac_update(ar, *buf, *buf_len);
1085 }
1086#endif
1087
1088
1089 fw_entry_size = *buf_len;
1090
1091 /* Load extended board data for AR6003 */
1092 if ((file==AR6K_BOARD_DATA_FILE) && *buf) {
1093 u32 board_ext_address;
1094 u32 board_ext_data_size;
1095 u32 board_data_size;
1096
1097 board_ext_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_EXT_DATA_SZ : \
1098 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_EXT_DATA_SZ : 0));
1099
1100 board_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_DATA_SZ : \
1101 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_DATA_SZ : 0));
1102
1103 /* Determine where in Target RAM to write Board Data */
1104 bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), (u8 *)&board_ext_address, 4));
1105 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address));
1106
1107 /* check whether the target has allocated memory for extended board data and file contains extended board data */
1108 if ((board_ext_address) && (*buf_len == (board_data_size + board_ext_data_size))) {
1109 u32 param;
1110
1111 status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(*buf + board_data_size), board_ext_data_size);
1112
1113 if (status) {
1114 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
1115 return A_ERROR;
1116 }
1117
1118 /* Record the fact that extended board Data IS initialized */
1119 param = (board_ext_data_size << 16) | 1;
1120 bmifn(BMIWriteMemory(ar->arHifDevice,
1121 HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data_config),
1122 (unsigned char *)&param, 4));
1123 }
1124 fw_entry_size = board_data_size;
1125 }
1126
1127 if (compressed) {
1128 status = BMIFastDownload(ar->arHifDevice, address, *buf, fw_entry_size);
1129 } else {
1130 status = BMIWriteMemory(ar->arHifDevice, address, *buf, fw_entry_size);
1131 }
1132
1133 if (status) {
1134 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
1135 return A_ERROR;
1136 }
1137
1138 return 0;
1139}
1140
1141int
1142ar6000_update_bdaddr(struct ar6_softc *ar)
1143{
1144
1145 if (setupbtdev != 0) {
1146 u32 address;
1147
1148 if (BMIReadMemory(ar->arHifDevice,
1149 HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (u8 *)&address, 4) != 0)
1150 {
1151 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for hi_board_data failed\n"));
1152 return A_ERROR;
1153 }
1154
1155 if (BMIReadMemory(ar->arHifDevice, address + BDATA_BDADDR_OFFSET, (u8 *)ar->bdaddr, 6) != 0)
1156 {
1157 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for BD address failed\n"));
1158 return A_ERROR;
1159 }
1160 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BDADDR 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n", ar->bdaddr[0],
1161 ar->bdaddr[1], ar->bdaddr[2], ar->bdaddr[3],
1162 ar->bdaddr[4], ar->bdaddr[5]));
1163 }
1164
1165return 0;
1166}
1167
1168int
1169ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode)
1170{
1171 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Requesting device specific configuration\n"));
1172
1173 if (mode == WLAN_INIT_MODE_UDEV) {
1174 char version[16];
1175 const struct firmware *fw_entry;
1176
1177 /* Get config using udev through a script in user space */
1178 sprintf(version, "%2.2x", ar->arVersion.target_ver);
1179 if ((A_REQUEST_FIRMWARE(&fw_entry, version, ((struct device *)ar->osDevInfo.pOSDevice))) != 0)
1180 {
1181 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get configuration for target version: %s\n", version));
1182 return A_ERROR;
1183 }
1184
1185 A_RELEASE_FIRMWARE(fw_entry);
1186 } else {
1187 /* The config is contained within the driver itself */
1188 int status;
1189 u32 param, options, sleep, address;
1190
1191 /* Temporarily disable system sleep */
1192 address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1193 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1194 options = param;
1195 param |= AR6K_OPTION_SLEEP_DISABLE;
1196 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1197
1198 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1199 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1200 sleep = param;
1201 param |= WLAN_SYSTEM_SLEEP_DISABLE_SET(1);
1202 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1203 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("old options: %d, old sleep: %d\n", options, sleep));
1204
1205 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1206 /* Program analog PLL register */
1207 bmifn(BMIWriteSOCRegister(ar->arHifDevice, ANALOG_INTF_BASE_ADDRESS + 0x284, 0xF9104001));
1208 /* Run at 80/88MHz by default */
1209 param = CPU_CLOCK_STANDARD_SET(1);
1210 } else {
1211 /* Run at 40/44MHz by default */
1212 param = CPU_CLOCK_STANDARD_SET(0);
1213 }
1214 address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
1215 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1216
1217 param = 0;
1218 if (ar->arTargetType == TARGET_TYPE_AR6002) {
1219 bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (u8 *)&param, 4));
1220 }
1221
1222 /* LPO_CAL.ENABLE = 1 if no external clk is detected */
1223 if (param != 1) {
1224 address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
1225 param = LPO_CAL_ENABLE_SET(1);
1226 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1227 }
1228
1229 /* Venus2.0: Lower SDIO pad drive strength,
1230 * temporary WAR to avoid SDIO CRC error */
1231 if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1232 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6K: Temporary WAR to avoid SDIO CRC error\n"));
1233 param = 0x20;
1234 address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
1235 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1236
1237 address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
1238 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1239
1240 address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
1241 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1242
1243 address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
1244 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1245 }
1246
1247#ifdef FORCE_INTERNAL_CLOCK
1248 /* Ignore external clock, if any, and force use of internal clock */
1249 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1250 /* hi_ext_clk_detected = 0 */
1251 param = 0;
1252 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (u8 *)&param, 4));
1253
1254 /* CLOCK_CONTROL &= ~LF_CLK32 */
1255 address = RTC_BASE_ADDRESS + CLOCK_CONTROL_ADDRESS;
1256 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1257 param &= (~CLOCK_CONTROL_LF_CLK32_SET(1));
1258 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1259 }
1260#endif /* FORCE_INTERNAL_CLOCK */
1261
1262 /* Transfer Board Data from Target EEPROM to Target RAM */
1263 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1264 /* Determine where in Target RAM to write Board Data */
1265 bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (u8 *)&address, 4));
1266 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board Data download address: 0x%x\n", address));
1267
1268 /* Write EEPROM data to Target RAM */
1269 if ((ar6000_transfer_bin_file(ar, AR6K_BOARD_DATA_FILE, address, false)) != 0) {
1270 return A_ERROR;
1271 }
1272
1273 /* Record the fact that Board Data IS initialized */
1274 param = 1;
1275 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data_initialized), (u8 *)&param, 4));
1276
1277 /* Transfer One time Programmable data */
1278 AR6K_APP_LOAD_ADDRESS(address, ar->arVersion.target_ver);
1279 if (ar->arVersion.target_ver == AR6003_REV3_VERSION)
1280 address = 0x1234;
1281 status = ar6000_transfer_bin_file(ar, AR6K_OTP_FILE, address, true);
1282 if (status == 0) {
1283 /* Execute the OTP code */
1284 param = 0;
1285 AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
1286 bmifn(BMIExecute(ar->arHifDevice, address, &param));
1287 } else if (status != A_ENOENT) {
1288 return A_ERROR;
1289 }
1290 } else {
1291 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Programming of board data for chip %d not supported\n", ar->arTargetType));
1292 return A_ERROR;
1293 }
1294
1295 /* Download Target firmware */
1296 AR6K_APP_LOAD_ADDRESS(address, ar->arVersion.target_ver);
1297 if (ar->arVersion.target_ver == AR6003_REV3_VERSION)
1298 address = 0x1234;
1299 if ((ar6000_transfer_bin_file(ar, AR6K_FIRMWARE_FILE, address, true)) != 0) {
1300 return A_ERROR;
1301 }
1302
1303 /* Set starting address for firmware */
1304 AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
1305 bmifn(BMISetAppStart(ar->arHifDevice, address));
1306
1307 if(ar->arTargetType == TARGET_TYPE_AR6003) {
1308 AR6K_DATASET_PATCH_ADDRESS(address, ar->arVersion.target_ver);
1309 if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE,
1310 address, false)) != 0)
1311 return A_ERROR;
1312 param = address;
1313 bmifn(BMIWriteMemory(ar->arHifDevice,
1314 HOST_INTEREST_ITEM_ADDRESS(ar, hi_dset_list_head),
1315 (unsigned char *)&param, 4));
1316 }
1317
1318 /* Restore system sleep */
1319 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1320 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, sleep));
1321
1322 address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1323 param = options | 0x20;
1324 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1325
1326 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1327 /* Configure GPIO AR6003 UART */
1328#ifndef CONFIG_AR600x_DEBUG_UART_TX_PIN
1329#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
1330#endif
1331 param = CONFIG_AR600x_DEBUG_UART_TX_PIN;
1332 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbg_uart_txpin), (u8 *)&param, 4));
1333
1334#if (CONFIG_AR600x_DEBUG_UART_TX_PIN == 23)
1335 {
1336 address = GPIO_BASE_ADDRESS + CLOCK_GPIO_ADDRESS;
1337 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1338 param |= CLOCK_GPIO_BT_CLK_OUT_EN_SET(1);
1339 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1340 }
1341#endif
1342
1343 /* Configure GPIO for BT Reset */
1344#ifdef ATH6KL_CONFIG_GPIO_BT_RESET
1345#define CONFIG_AR600x_BT_RESET_PIN 0x16
1346 param = CONFIG_AR600x_BT_RESET_PIN;
1347 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_support_pins), (u8 *)&param, 4));
1348#endif /* ATH6KL_CONFIG_GPIO_BT_RESET */
1349
1350 /* Configure UART flow control polarity */
1351#ifndef CONFIG_ATH6KL_BT_UART_FC_POLARITY
1352#define CONFIG_ATH6KL_BT_UART_FC_POLARITY 0
1353#endif
1354
1355#if (CONFIG_ATH6KL_BT_UART_FC_POLARITY == 1)
1356 if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1357 param = ((CONFIG_ATH6KL_BT_UART_FC_POLARITY << 1) & 0x2);
1358 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_pwr_mgmt_params), (u8 *)&param, 4));
1359 }
1360#endif /* CONFIG_ATH6KL_BT_UART_FC_POLARITY */
1361 }
1362
1363#ifdef HTC_RAW_INTERFACE
1364 if (!eppingtest && bypasswmi) {
1365 /* Don't run BMIDone for ART mode and force resetok=0 */
1366 resetok = 0;
1367 msleep(1000);
1368 }
1369#endif /* HTC_RAW_INTERFACE */
1370 }
1371
1372 return 0;
1373}
1374
1375int
1376ar6000_configure_target(struct ar6_softc *ar)
1377{
1378 u32 param;
1379 if (enableuartprint) {
1380 param = 1;
1381 if (BMIWriteMemory(ar->arHifDevice,
1382 HOST_INTEREST_ITEM_ADDRESS(ar, hi_serial_enable),
1383 (u8 *)&param,
1384 4)!= 0)
1385 {
1386 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enableuartprint failed \n"));
1387 return A_ERROR;
1388 }
1389 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Serial console prints enabled\n"));
1390 }
1391
1392 /* Tell target which HTC version it is used*/
1393 param = HTC_PROTOCOL_VERSION;
1394 if (BMIWriteMemory(ar->arHifDevice,
1395 HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest),
1396 (u8 *)&param,
1397 4)!= 0)
1398 {
1399 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for htc version failed \n"));
1400 return A_ERROR;
1401 }
1402
1403#ifdef CONFIG_HOST_TCMD_SUPPORT
1404 if(testmode) {
1405 ar->arTargetMode = AR6000_TCMD_MODE;
1406 }else {
1407 ar->arTargetMode = AR6000_WLAN_MODE;
1408 }
1409#endif
1410 if (enabletimerwar) {
1411 u32 param;
1412
1413 if (BMIReadMemory(ar->arHifDevice,
1414 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1415 (u8 *)&param,
1416 4)!= 0)
1417 {
1418 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for enabletimerwar failed \n"));
1419 return A_ERROR;
1420 }
1421
1422 param |= HI_OPTION_TIMER_WAR;
1423
1424 if (BMIWriteMemory(ar->arHifDevice,
1425 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1426 (u8 *)&param,
1427 4) != 0)
1428 {
1429 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enabletimerwar failed \n"));
1430 return A_ERROR;
1431 }
1432 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Timer WAR enabled\n"));
1433 }
1434
1435 /* set the firmware mode to STA/IBSS/AP */
1436 {
1437 u32 param;
1438
1439 if (BMIReadMemory(ar->arHifDevice,
1440 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1441 (u8 *)&param,
1442 4)!= 0)
1443 {
1444 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for setting fwmode failed \n"));
1445 return A_ERROR;
1446 }
1447
1448 param |= (num_device << HI_OPTION_NUM_DEV_SHIFT);
1449 param |= (fwmode << HI_OPTION_FW_MODE_SHIFT);
1450 param |= (mac_addr_method << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
1451 param |= (firmware_bridge << HI_OPTION_FW_BRIDGE_SHIFT);
1452
1453
1454 if (BMIWriteMemory(ar->arHifDevice,
1455 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1456 (u8 *)&param,
1457 4) != 0)
1458 {
1459 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for setting fwmode failed \n"));
1460 return A_ERROR;
1461 }
1462 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
1463 }
1464
1465#ifdef ATH6KL_DISABLE_TARGET_DBGLOGS
1466 {
1467 u32 param;
1468
1469 if (BMIReadMemory(ar->arHifDevice,
1470 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1471 (u8 *)&param,
1472 4)!= 0)
1473 {
1474 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for disabling debug logs failed\n"));
1475 return A_ERROR;
1476 }
1477
1478 param |= HI_OPTION_DISABLE_DBGLOG;
1479
1480 if (BMIWriteMemory(ar->arHifDevice,
1481 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1482 (u8 *)&param,
1483 4) != 0)
1484 {
1485 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for HI_OPTION_DISABLE_DBGLOG\n"));
1486 return A_ERROR;
1487 }
1488 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
1489 }
1490#endif /* ATH6KL_DISABLE_TARGET_DBGLOGS */
1491
1492 /*
1493 * Hardcode the address use for the extended board data
1494 * Ideally this should be pre-allocate by the OS at boot time
1495 * But since it is a new feature and board data is loaded
1496 * at init time, we have to workaround this from host.
1497 * It is difficult to patch the firmware boot code,
1498 * but possible in theory.
1499 */
1500
1501 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1502 u32 ramReservedSz;
1503 if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1504 param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
1505 ramReservedSz = AR6003_REV2_RAM_RESERVE_SIZE;
1506 } else {
1507 param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
1508 ramReservedSz = AR6003_REV3_RAM_RESERVE_SIZE;
1509 }
1510 if (BMIWriteMemory(ar->arHifDevice,
1511 HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data),
1512 (u8 *)&param, 4) != 0) {
1513 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1514 ("BMIWriteMemory for "
1515 "hi_board_ext_data failed\n"));
1516 return A_ERROR;
1517 }
1518 if (BMIWriteMemory(ar->arHifDevice,
1519 HOST_INTEREST_ITEM_ADDRESS(ar,
1520 hi_end_RAM_reserve_sz),
1521 (u8 *)&ramReservedSz, 4) != 0) {
1522 AR_DEBUG_PRINTF(ATH_DEBUG_ERR ,
1523 ("BMIWriteMemory for "
1524 "hi_end_RAM_reserve_sz failed\n"));
1525 return A_ERROR;
1526 }
1527 }
1528
1529 /* since BMIInit is called in the driver layer, we have to set the block
1530 * size here for the target */
1531
1532 if (ar6000_set_htc_params(ar->arHifDevice, ar->arTargetType,
1533 mbox_yield_limit, 0)) {
1534 /* use default number of control buffers */
1535 return A_ERROR;
1536 }
1537
1538 if (setupbtdev != 0) {
1539 if (ar6000_set_hci_bridge_flags(ar->arHifDevice,
1540 ar->arTargetType,
1541 setupbtdev)) {
1542 return A_ERROR;
1543 }
1544 }
1545 return 0;
1546}
1547
1548static void
1549init_netdev(struct net_device *dev, char *name)
1550{
1551 dev->netdev_ops = &ar6000_netdev_ops;
1552 dev->watchdog_timeo = AR6000_TX_TIMEOUT;
1553
1554 /*
1555 * We need the OS to provide us with more headroom in order to
1556 * perform dix to 802.3, WMI header encap, and the HTC header
1557 */
1558 if (processDot11Hdr) {
1559 dev->hard_header_len = sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR;
1560 } else {
1561 dev->hard_header_len = ETH_HLEN + sizeof(ATH_LLC_SNAP_HDR) +
1562 sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR;
1563 }
1564
1565 if (name[0])
1566 {
1567 strcpy(dev->name, name);
1568 }
1569
1570#ifdef CONFIG_CHECKSUM_OFFLOAD
1571 if(csumOffload){
1572 dev->features |= NETIF_F_IP_CSUM; /*advertise kernel capability to do TCP/UDP CSUM offload for IPV4*/
1573 }
1574#endif
1575
1576 return;
1577}
1578
1579static int __ath6kl_init_netdev(struct net_device *dev)
1580{
1581 int r;
1582
1583 rtnl_lock();
1584 r = ar6000_init(dev);
1585 rtnl_unlock();
1586
1587 if (r) {
1588 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n"));
1589 return r;
1590 }
1591
1592 return 0;
1593}
1594
1595#ifdef HTC_RAW_INTERFACE
1596static int ath6kl_init_netdev_wmi(struct net_device *dev)
1597{
1598 if (!eppingtest && bypasswmi)
1599 return 0;
1600
1601 return __ath6kl_init_netdev(dev);
1602}
1603#else
1604static int ath6kl_init_netdev_wmi(struct net_device *dev)
1605{
1606 return __ath6kl_init_netdev(dev);
1607}
1608#endif
1609
1610static int ath6kl_init_netdev(struct ar6_softc *ar)
1611{
1612 int r;
1613
1614 r = ar6000_sysfs_bmi_get_config(ar, wlaninitmode);
1615 if (r) {
1616 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1617 ("ar6000_avail: "
1618 "ar6000_sysfs_bmi_get_config failed\n"));
1619 return r;
1620 }
1621
1622 return ath6kl_init_netdev_wmi(ar->arNetDev);
1623}
1624
1625/*
1626 * HTC Event handlers
1627 */
1628static int
1629ar6000_avail_ev(void *context, void *hif_handle)
1630{
1631 int i;
1632 struct net_device *dev;
1633 void *ar_netif;
1634 struct ar6_softc *ar;
1635 int device_index = 0;
1636 struct htc_init_info htcInfo;
1637 struct wireless_dev *wdev;
1638 int r = 0;
1639 struct hif_device_os_device_info osDevInfo;
1640
1641 memset(&osDevInfo, 0, sizeof(osDevInfo));
1642 if (HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE,
1643 &osDevInfo, sizeof(osDevInfo))) {
1644 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: Failed to get OS device instance\n", __func__));
1645 return A_ERROR;
1646 }
1647
1648 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_available\n"));
1649
1650 for (i=0; i < MAX_AR6000; i++) {
1651 if (ar6000_devices[i] == NULL) {
1652 break;
1653 }
1654 }
1655
1656 if (i == MAX_AR6000) {
1657 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: max devices reached\n"));
1658 return A_ERROR;
1659 }
1660
1661 /* Save this. It gives a bit better readability especially since */
1662 /* we use another local "i" variable below. */
1663 device_index = i;
1664
1665 wdev = ar6k_cfg80211_init(osDevInfo.pOSDevice);
1666 if (IS_ERR(wdev)) {
1667 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ar6k_cfg80211_init failed\n", __func__));
1668 return A_ERROR;
1669 }
1670 ar_netif = wdev_priv(wdev);
1671
1672 if (ar_netif == NULL) {
1673 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Can't allocate ar6k priv memory\n", __func__));
1674 return A_ERROR;
1675 }
1676
1677 A_MEMZERO(ar_netif, sizeof(struct ar6_softc));
1678 ar = (struct ar6_softc *)ar_netif;
1679
1680 ar->wdev = wdev;
1681 wdev->iftype = NL80211_IFTYPE_STATION;
1682
1683 dev = alloc_netdev_mq(0, "wlan%d", ether_setup, 1);
1684 if (!dev) {
1685 printk(KERN_CRIT "AR6K: no memory for network device instance\n");
1686 ar6k_cfg80211_deinit(ar);
1687 return A_ERROR;
1688 }
1689
1690 dev->ieee80211_ptr = wdev;
1691 SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
1692 wdev->netdev = dev;
1693 ar->arNetworkType = INFRA_NETWORK;
1694 ar->smeState = SME_DISCONNECTED;
1695 ar->arAutoAuthStage = AUTH_IDLE;
1696
1697 init_netdev(dev, ifname);
1698
1699
1700 ar->arNetDev = dev;
1701 ar->arHifDevice = hif_handle;
1702 ar->arWlanState = WLAN_ENABLED;
1703 ar->arDeviceIndex = device_index;
1704
1705 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
1706 ar->arWlanOff = false; /* We are in ON state */
1707#ifdef CONFIG_PM
1708 ar->arWowState = WLAN_WOW_STATE_NONE;
1709 ar->arBTOff = true; /* BT chip assumed to be OFF */
1710 ar->arBTSharing = WLAN_CONFIG_BT_SHARING;
1711 ar->arWlanOffConfig = WLAN_CONFIG_WLAN_OFF;
1712 ar->arSuspendConfig = WLAN_CONFIG_PM_SUSPEND;
1713 ar->arWow2Config = WLAN_CONFIG_PM_WOW2;
1714#endif /* CONFIG_PM */
1715
1716 A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev);
1717 ar->arHBChallengeResp.seqNum = 0;
1718 ar->arHBChallengeResp.outstanding = false;
1719 ar->arHBChallengeResp.missCnt = 0;
1720 ar->arHBChallengeResp.frequency = AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT;
1721 ar->arHBChallengeResp.missThres = AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT;
1722
1723 ar6000_init_control_info(ar);
1724 init_waitqueue_head(&arEvent);
1725 sema_init(&ar->arSem, 1);
1726 ar->bIsDestroyProgress = false;
1727
1728 INIT_HTC_PACKET_QUEUE(&ar->amsdu_rx_buffer_queue);
1729
1730#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1731 A_INIT_TIMER(&aptcTimer, aptcTimerHandler, ar);
1732#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1733
1734 A_INIT_TIMER(&ar->disconnect_timer, disconnect_timer_handler, dev);
1735
1736 BMIInit();
1737
1738 ar6000_sysfs_bmi_init(ar);
1739
1740 {
1741 struct bmi_target_info targ_info;
1742
1743 r = BMIGetTargetInfo(ar->arHifDevice, &targ_info);
1744 if (r)
1745 goto avail_ev_failed;
1746
1747 ar->arVersion.target_ver = targ_info.target_ver;
1748 ar->arTargetType = targ_info.target_type;
1749 wdev->wiphy->hw_version = targ_info.target_ver;
1750 }
1751
1752 r = ar6000_configure_target(ar);
1753 if (r)
1754 goto avail_ev_failed;
1755
1756 A_MEMZERO(&htcInfo,sizeof(htcInfo));
1757 htcInfo.pContext = ar;
1758 htcInfo.TargetFailure = ar6000_target_failure;
1759
1760 ar->arHtcTarget = HTCCreate(ar->arHifDevice,&htcInfo);
1761
1762 if (!ar->arHtcTarget) {
1763 r = -ENOMEM;
1764 goto avail_ev_failed;
1765 }
1766
1767 spin_lock_init(&ar->arLock);
1768
1769#ifdef WAPI_ENABLE
1770 ar->arWapiEnable = 0;
1771#endif
1772
1773
1774 if(csumOffload){
1775 /*if external frame work is also needed, change and use an extended rxMetaVerion*/
1776 ar->rxMetaVersion=WMI_META_VERSION_2;
1777 }
1778
1779 ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs);
1780 if (!ar->aggr_cntxt) {
1781 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize aggr.\n", __func__));
1782 r = -ENOMEM;
1783 goto avail_ev_failed;
1784 }
1785
1786 aggr_register_rx_dispatcher(ar->aggr_cntxt, (void *)dev, ar6000_deliver_frames_to_nw_stack);
1787
1788 HIFClaimDevice(ar->arHifDevice, ar);
1789
1790 /* We only register the device in the global list if we succeed. */
1791 /* If the device is in the global list, it will be destroyed */
1792 /* when the module is unloaded. */
1793 ar6000_devices[device_index] = dev;
1794
1795 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode));
1796 if ((wlaninitmode == WLAN_INIT_MODE_UDEV) ||
1797 (wlaninitmode == WLAN_INIT_MODE_DRV)) {
1798 r = ath6kl_init_netdev(ar);
1799 if (r)
1800 goto avail_ev_failed;
1801 }
1802
1803 /* This runs the init function if registered */
1804 r = register_netdev(dev);
1805 if (r) {
1806 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: register_netdev failed\n"));
1807 ar6000_destroy(dev, 0);
1808 return r;
1809 }
1810
1811 is_netdev_registered = 1;
1812
1813#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
1814 arApNetDev = NULL;
1815#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
1816 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_avail: name=%s hifdevice=0x%lx, dev=0x%lx (%d), ar=0x%lx\n",
1817 dev->name, (unsigned long)ar->arHifDevice, (unsigned long)dev, device_index,
1818 (unsigned long)ar));
1819
1820avail_ev_failed :
1821 if (r)
1822 ar6000_sysfs_bmi_deinit(ar);
1823
1824 return r;
1825}
1826
1827static void ar6000_target_failure(void *Instance, int Status)
1828{
1829 struct ar6_softc *ar = (struct ar6_softc *)Instance;
1830 WMI_TARGET_ERROR_REPORT_EVENT errEvent;
1831 static bool sip = false;
1832
1833 if (Status != 0) {
1834
1835 printk(KERN_ERR "ar6000_target_failure: target asserted \n");
1836
1837 if (timer_pending(&ar->arHBChallengeResp.timer)) {
1838 A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
1839 }
1840
1841 /* try dumping target assertion information (if any) */
1842 ar6000_dump_target_assert_info(ar->arHifDevice,ar->arTargetType);
1843
1844 /*
1845 * Fetch the logs from the target via the diagnostic
1846 * window.
1847 */
1848 ar6000_dbglog_get_debug_logs(ar);
1849
1850 /* Report the error only once */
1851 if (!sip) {
1852 sip = true;
1853 errEvent.errorVal = WMI_TARGET_COM_ERR |
1854 WMI_TARGET_FATAL_ERR;
1855 }
1856 }
1857}
1858
1859static int
1860ar6000_unavail_ev(void *context, void *hif_handle)
1861{
1862 struct ar6_softc *ar = (struct ar6_softc *)context;
1863 /* NULL out it's entry in the global list */
1864 ar6000_devices[ar->arDeviceIndex] = NULL;
1865 ar6000_destroy(ar->arNetDev, 1);
1866
1867 return 0;
1868}
1869
1870void
1871ar6000_restart_endpoint(struct net_device *dev)
1872{
1873 int status = 0;
1874 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1875
1876 BMIInit();
1877 do {
1878 if ( (status=ar6000_configure_target(ar))!= 0)
1879 break;
1880 if ( (status=ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != 0)
1881 {
1882 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n"));
1883 break;
1884 }
1885 rtnl_lock();
1886 status = (ar6000_init(dev)==0) ? 0 : A_ERROR;
1887 rtnl_unlock();
1888
1889 if (status) {
1890 break;
1891 }
1892 if (ar->arSsidLen && ar->arWlanState == WLAN_ENABLED) {
1893 ar6000_connect_to_ap(ar);
1894 }
1895 } while (0);
1896
1897 if (status== 0) {
1898 return;
1899 }
1900
1901 ar6000_devices[ar->arDeviceIndex] = NULL;
1902 ar6000_destroy(ar->arNetDev, 1);
1903}
1904
1905void
1906ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs)
1907{
1908 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1909
1910 /* Stop the transmit queues */
1911 netif_stop_queue(dev);
1912
1913 /* Disable the target and the interrupts associated with it */
1914 if (ar->arWmiReady == true)
1915 {
1916 if (!bypasswmi)
1917 {
1918 bool disconnectIssued;
1919
1920 disconnectIssued = (ar->arConnected) || (ar->arConnectPending);
1921 ar6000_disconnect(ar);
1922 if (!keepprofile) {
1923 ar6000_init_profile_info(ar);
1924 }
1925
1926 A_UNTIMEOUT(&ar->disconnect_timer);
1927
1928 if (getdbglogs) {
1929 ar6000_dbglog_get_debug_logs(ar);
1930 }
1931
1932 ar->arWmiReady = false;
1933 wmi_shutdown(ar->arWmi);
1934 ar->arWmiEnabled = false;
1935 ar->arWmi = NULL;
1936 /*
1937 * After wmi_shudown all WMI events will be dropped.
1938 * We need to cleanup the buffers allocated in AP mode
1939 * and give disconnect notification to stack, which usually
1940 * happens in the disconnect_event.
1941 * Simulate the disconnect_event by calling the function directly.
1942 * Sometimes disconnect_event will be received when the debug logs
1943 * are collected.
1944 */
1945 if (disconnectIssued) {
1946 if(ar->arNetworkType & AP_NETWORK) {
1947 ar6000_disconnect_event(ar, DISCONNECT_CMD, bcast_mac, 0, NULL, 0);
1948 } else {
1949 ar6000_disconnect_event(ar, DISCONNECT_CMD, ar->arBssid, 0, NULL, 0);
1950 }
1951 }
1952 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
1953 ar->user_key_ctrl = 0;
1954 }
1955
1956 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI stopped\n", __func__));
1957 }
1958 else
1959 {
1960 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI not ready 0x%lx 0x%lx\n",
1961 __func__, (unsigned long) ar, (unsigned long) ar->arWmi));
1962
1963 /* Shut down WMI if we have started it */
1964 if(ar->arWmiEnabled == true)
1965 {
1966 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Shut down WMI\n", __func__));
1967 wmi_shutdown(ar->arWmi);
1968 ar->arWmiEnabled = false;
1969 ar->arWmi = NULL;
1970 }
1971 }
1972
1973 if (ar->arHtcTarget != NULL) {
1974#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1975 if (NULL != ar6kHciTransCallbacks.cleanupTransport) {
1976 ar6kHciTransCallbacks.cleanupTransport(NULL);
1977 }
1978#else
1979 // FIXME: workaround to reset BT's UART baud rate to default
1980 if (NULL != ar->exitCallback) {
1981 struct ar3k_config_info ar3kconfig;
1982 int status;
1983
1984 A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
1985 ar6000_set_default_ar3kconfig(ar, (void *)&ar3kconfig);
1986 status = ar->exitCallback(&ar3kconfig);
1987 if (0 != status) {
1988 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to reset AR3K baud rate! \n"));
1989 }
1990 }
1991 // END workaround
1992 if (setuphci)
1993 ar6000_cleanup_hci(ar);
1994#endif
1995 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Shutting down HTC .... \n"));
1996 /* stop HTC */
1997 HTCStop(ar->arHtcTarget);
1998 }
1999
2000 if (resetok) {
2001 /* try to reset the device if we can
2002 * The driver may have been configure NOT to reset the target during
2003 * a debug session */
2004 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Attempting to reset target on instance destroy.... \n"));
2005 if (ar->arHifDevice != NULL) {
2006 bool coldReset = (ar->arTargetType == TARGET_TYPE_AR6003) ? true: false;
2007 ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, coldReset);
2008 }
2009 } else {
2010 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Host does not want target reset. \n"));
2011 }
2012 /* Done with cookies */
2013 ar6000_cookie_cleanup(ar);
2014
2015 /* cleanup any allocated AMSDU buffers */
2016 ar6000_cleanup_amsdu_rxbufs(ar);
2017}
2018/*
2019 * We need to differentiate between the surprise and planned removal of the
2020 * device because of the following consideration:
2021 * - In case of surprise removal, the hcd already frees up the pending
2022 * for the device and hence there is no need to unregister the function
2023 * driver inorder to get these requests. For planned removal, the function
2024 * driver has to explicitly unregister itself to have the hcd return all the
2025 * pending requests before the data structures for the devices are freed up.
2026 * Note that as per the current implementation, the function driver will
2027 * end up releasing all the devices since there is no API to selectively
2028 * release a particular device.
2029 * - Certain commands issued to the target can be skipped for surprise
2030 * removal since they will anyway not go through.
2031 */
2032void
2033ar6000_destroy(struct net_device *dev, unsigned int unregister)
2034{
2035 struct ar6_softc *ar;
2036
2037 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("+ar6000_destroy \n"));
2038
2039 if((dev == NULL) || ((ar = ar6k_priv(dev)) == NULL))
2040 {
2041 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): Failed to get device structure.\n", __func__));
2042 return;
2043 }
2044
2045 ar->bIsDestroyProgress = true;
2046
2047 if (down_interruptible(&ar->arSem)) {
2048 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): down_interruptible failed \n", __func__));
2049 return;
2050 }
2051
2052 if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
2053 /* only stop endpoint if we are not stop it in suspend_ev */
2054 ar6000_stop_endpoint(dev, false, true);
2055 }
2056
2057 ar->arWlanState = WLAN_DISABLED;
2058 if (ar->arHtcTarget != NULL) {
2059 /* destroy HTC */
2060 HTCDestroy(ar->arHtcTarget);
2061 }
2062 if (ar->arHifDevice != NULL) {
2063 /*release the device so we do not get called back on remove incase we
2064 * we're explicity destroyed by module unload */
2065 HIFReleaseDevice(ar->arHifDevice);
2066 HIFShutDownDevice(ar->arHifDevice);
2067 }
2068 aggr_module_destroy(ar->aggr_cntxt);
2069
2070 /* Done with cookies */
2071 ar6000_cookie_cleanup(ar);
2072
2073 /* cleanup any allocated AMSDU buffers */
2074 ar6000_cleanup_amsdu_rxbufs(ar);
2075
2076 ar6000_sysfs_bmi_deinit(ar);
2077
2078 /* Cleanup BMI */
2079 BMICleanup();
2080
2081 /* Clear the tx counters */
2082 memset(tx_attempt, 0, sizeof(tx_attempt));
2083 memset(tx_post, 0, sizeof(tx_post));
2084 memset(tx_complete, 0, sizeof(tx_complete));
2085
2086#ifdef HTC_RAW_INTERFACE
2087 if (ar->arRawHtc) {
2088 kfree(ar->arRawHtc);
2089 ar->arRawHtc = NULL;
2090 }
2091#endif
2092 /* Free up the device data structure */
2093 if (unregister && is_netdev_registered) {
2094 unregister_netdev(dev);
2095 is_netdev_registered = 0;
2096 }
2097 free_netdev(dev);
2098
2099 ar6k_cfg80211_deinit(ar);
2100
2101#ifdef CONFIG_AP_VIRTUL_ADAPTER_SUPPORT
2102 ar6000_remove_ap_interface();
2103#endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
2104
2105 kfree(ar->fw_otp);
2106 kfree(ar->fw);
2107 kfree(ar->fw_patch);
2108 kfree(ar->fw_data);
2109
2110 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n"));
2111}
2112
2113static void disconnect_timer_handler(unsigned long ptr)
2114{
2115 struct net_device *dev = (struct net_device *)ptr;
2116 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2117
2118 A_UNTIMEOUT(&ar->disconnect_timer);
2119
2120 ar6000_init_profile_info(ar);
2121 ar6000_disconnect(ar);
2122}
2123
2124static void ar6000_detect_error(unsigned long ptr)
2125{
2126 struct net_device *dev = (struct net_device *)ptr;
2127 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2128 WMI_TARGET_ERROR_REPORT_EVENT errEvent;
2129
2130 AR6000_SPIN_LOCK(&ar->arLock, 0);
2131
2132 if (ar->arHBChallengeResp.outstanding) {
2133 ar->arHBChallengeResp.missCnt++;
2134 } else {
2135 ar->arHBChallengeResp.missCnt = 0;
2136 }
2137
2138 if (ar->arHBChallengeResp.missCnt > ar->arHBChallengeResp.missThres) {
2139 /* Send Error Detect event to the application layer and do not reschedule the error detection module timer */
2140 ar->arHBChallengeResp.missCnt = 0;
2141 ar->arHBChallengeResp.seqNum = 0;
2142 errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR;
2143 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2144 return;
2145 }
2146
2147 /* Generate the sequence number for the next challenge */
2148 ar->arHBChallengeResp.seqNum++;
2149 ar->arHBChallengeResp.outstanding = true;
2150
2151 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2152
2153 /* Send the challenge on the control channel */
2154 if (wmi_get_challenge_resp_cmd(ar->arWmi, ar->arHBChallengeResp.seqNum, DRV_HB_CHALLENGE) != 0) {
2155 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to send heart beat challenge\n"));
2156 }
2157
2158
2159 /* Reschedule the timer for the next challenge */
2160 A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0);
2161}
2162
2163void ar6000_init_profile_info(struct ar6_softc *ar)
2164{
2165 ar->arSsidLen = 0;
2166 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
2167
2168 switch(fwmode) {
2169 case HI_OPTION_FW_MODE_IBSS:
2170 ar->arNetworkType = ar->arNextMode = ADHOC_NETWORK;
2171 break;
2172 case HI_OPTION_FW_MODE_BSS_STA:
2173 ar->arNetworkType = ar->arNextMode = INFRA_NETWORK;
2174 break;
2175 case HI_OPTION_FW_MODE_AP:
2176 ar->arNetworkType = ar->arNextMode = AP_NETWORK;
2177 break;
2178 }
2179
2180 ar->arDot11AuthMode = OPEN_AUTH;
2181 ar->arAuthMode = NONE_AUTH;
2182 ar->arPairwiseCrypto = NONE_CRYPT;
2183 ar->arPairwiseCryptoLen = 0;
2184 ar->arGroupCrypto = NONE_CRYPT;
2185 ar->arGroupCryptoLen = 0;
2186 A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
2187 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
2188 A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
2189 ar->arBssChannel = 0;
2190}
2191
2192static void
2193ar6000_init_control_info(struct ar6_softc *ar)
2194{
2195 ar->arWmiEnabled = false;
2196 ar6000_init_profile_info(ar);
2197 ar->arDefTxKeyIndex = 0;
2198 A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
2199 ar->arChannelHint = 0;
2200 ar->arListenIntervalT = A_DEFAULT_LISTEN_INTERVAL;
2201 ar->arListenIntervalB = 0;
2202 ar->arVersion.host_ver = AR6K_SW_VERSION;
2203 ar->arRssi = 0;
2204 ar->arTxPwr = 0;
2205 ar->arTxPwrSet = false;
2206 ar->arSkipScan = 0;
2207 ar->arBeaconInterval = 0;
2208 ar->arBitRate = 0;
2209 ar->arMaxRetries = 0;
2210 ar->arWmmEnabled = true;
2211 ar->intra_bss = 1;
2212 ar->scan_triggered = 0;
2213 A_MEMZERO(&ar->scParams, sizeof(ar->scParams));
2214 ar->scParams.shortScanRatio = WMI_SHORTSCANRATIO_DEFAULT;
2215 ar->scParams.scanCtrlFlags = DEFAULT_SCAN_CTRL_FLAGS;
2216
2217 /* Initialize the AP mode state info */
2218 {
2219 u8 ctr;
2220 A_MEMZERO((u8 *)ar->sta_list, AP_MAX_NUM_STA * sizeof(sta_t));
2221
2222 /* init the Mutexes */
2223 A_MUTEX_INIT(&ar->mcastpsqLock);
2224
2225 /* Init the PS queues */
2226 for (ctr=0; ctr < AP_MAX_NUM_STA ; ctr++) {
2227 A_MUTEX_INIT(&ar->sta_list[ctr].psqLock);
2228 A_NETBUF_QUEUE_INIT(&ar->sta_list[ctr].psq);
2229 }
2230
2231 ar->ap_profile_flag = 0;
2232 A_NETBUF_QUEUE_INIT(&ar->mcastpsq);
2233
2234 memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
2235 ar->ap_wmode = DEF_AP_WMODE_G;
2236 ar->ap_dtim_period = DEF_AP_DTIM;
2237 ar->ap_beacon_interval = DEF_BEACON_INTERVAL;
2238 }
2239}
2240
2241static int
2242ar6000_open(struct net_device *dev)
2243{
2244 unsigned long flags;
2245 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2246
2247 spin_lock_irqsave(&ar->arLock, flags);
2248
2249 if(ar->arWlanState == WLAN_DISABLED) {
2250 ar->arWlanState = WLAN_ENABLED;
2251 }
2252
2253 if( ar->arConnected || bypasswmi) {
2254 netif_carrier_on(dev);
2255 /* Wake up the queues */
2256 netif_wake_queue(dev);
2257 }
2258 else
2259 netif_carrier_off(dev);
2260
2261 spin_unlock_irqrestore(&ar->arLock, flags);
2262 return 0;
2263}
2264
2265static int
2266ar6000_close(struct net_device *dev)
2267{
2268 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2269 netif_stop_queue(dev);
2270
2271 ar6000_disconnect(ar);
2272
2273 if(ar->arWmiReady == true) {
2274 if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0,
2275 0, 0, 0, 0, 0, 0, 0, 0) != 0) {
2276 return -EIO;
2277 }
2278 ar->arWlanState = WLAN_DISABLED;
2279 }
2280 ar6k_cfg80211_scanComplete_event(ar, A_ECANCELED);
2281
2282 return 0;
2283}
2284
2285/* connect to a service */
2286static int ar6000_connectservice(struct ar6_softc *ar,
2287 struct htc_service_connect_req *pConnect,
2288 char *pDesc)
2289{
2290 int status;
2291 struct htc_service_connect_resp response;
2292
2293 do {
2294
2295 A_MEMZERO(&response,sizeof(response));
2296
2297 status = HTCConnectService(ar->arHtcTarget,
2298 pConnect,
2299 &response);
2300
2301 if (status) {
2302 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Failed to connect to %s service status:%d \n",
2303 pDesc, status));
2304 break;
2305 }
2306 switch (pConnect->ServiceID) {
2307 case WMI_CONTROL_SVC :
2308 if (ar->arWmiEnabled) {
2309 /* set control endpoint for WMI use */
2310 wmi_set_control_ep(ar->arWmi, response.Endpoint);
2311 }
2312 /* save EP for fast lookup */
2313 ar->arControlEp = response.Endpoint;
2314 break;
2315 case WMI_DATA_BE_SVC :
2316 arSetAc2EndpointIDMap(ar, WMM_AC_BE, response.Endpoint);
2317 break;
2318 case WMI_DATA_BK_SVC :
2319 arSetAc2EndpointIDMap(ar, WMM_AC_BK, response.Endpoint);
2320 break;
2321 case WMI_DATA_VI_SVC :
2322 arSetAc2EndpointIDMap(ar, WMM_AC_VI, response.Endpoint);
2323 break;
2324 case WMI_DATA_VO_SVC :
2325 arSetAc2EndpointIDMap(ar, WMM_AC_VO, response.Endpoint);
2326 break;
2327 default:
2328 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ServiceID not mapped %d\n", pConnect->ServiceID));
2329 status = A_EINVAL;
2330 break;
2331 }
2332
2333 } while (false);
2334
2335 return status;
2336}
2337
2338void ar6000_TxDataCleanup(struct ar6_softc *ar)
2339{
2340 /* flush all the data (non-control) streams
2341 * we only flush packets that are tagged as data, we leave any control packets that
2342 * were in the TX queues alone */
2343 HTCFlushEndpoint(ar->arHtcTarget,
2344 arAc2EndpointID(ar, WMM_AC_BE),
2345 AR6K_DATA_PKT_TAG);
2346 HTCFlushEndpoint(ar->arHtcTarget,
2347 arAc2EndpointID(ar, WMM_AC_BK),
2348 AR6K_DATA_PKT_TAG);
2349 HTCFlushEndpoint(ar->arHtcTarget,
2350 arAc2EndpointID(ar, WMM_AC_VI),
2351 AR6K_DATA_PKT_TAG);
2352 HTCFlushEndpoint(ar->arHtcTarget,
2353 arAc2EndpointID(ar, WMM_AC_VO),
2354 AR6K_DATA_PKT_TAG);
2355}
2356
2357HTC_ENDPOINT_ID
2358ar6000_ac2_endpoint_id ( void * devt, u8 ac)
2359{
2360 struct ar6_softc *ar = (struct ar6_softc *) devt;
2361 return(arAc2EndpointID(ar, ac));
2362}
2363
2364u8 ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep )
2365{
2366 struct ar6_softc *ar = (struct ar6_softc *) devt;
2367 return(arEndpoint2Ac(ar, ep ));
2368}
2369
2370#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE)
2371static int ath6kl_config_btcoex_params(struct ar6_softc *ar)
2372{
2373 int r;
2374 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd;
2375 WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd;
2376
2377 /* Configure the type of BT collocated with WLAN */
2378 memset(&sbcb_cmd, 0, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
2379 sbcb_cmd.btcoexCoLocatedBTdev = ATH6KL_BT_DEV;
2380
2381 r = wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd);
2382
2383 if (r) {
2384 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
2385 ("Unable to set collocated BT type\n"));
2386 return r;
2387 }
2388
2389 /* Configure the type of BT collocated with WLAN */
2390 memset(&sbfa_cmd, 0, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
2391
2392 sbfa_cmd.btcoexFeAntType = ATH6KL_BT_ANTENNA;
2393
2394 r = wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd);
2395 if (r) {
2396 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
2397 ("Unable to set fornt end antenna configuration\n"));
2398 return r;
2399 }
2400
2401 return 0;
2402}
2403#else
2404static int ath6kl_config_btcoex_params(struct ar6_softc *ar)
2405{
2406 return 0;
2407}
2408#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */
2409
2410/*
2411 * This function applies WLAN specific configuration defined in wlan_config.h
2412 */
2413int ar6000_target_config_wlan_params(struct ar6_softc *ar)
2414{
2415 int status = 0;
2416
2417#ifdef CONFIG_HOST_TCMD_SUPPORT
2418 if (ar->arTargetMode != AR6000_WLAN_MODE) {
2419 return 0;
2420 }
2421#endif /* CONFIG_HOST_TCMD_SUPPORT */
2422
2423 /*
2424 * configure the device for rx dot11 header rules 0,0 are the default values
2425 * therefore this command can be skipped if the inputs are 0,FALSE,FALSE.Required
2426 * if checksum offload is needed. Set RxMetaVersion to 2
2427 */
2428 if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot11Hdr, processDot11Hdr)) != 0) {
2429 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the rx frame format.\n"));
2430 status = A_ERROR;
2431 }
2432
2433 status = ath6kl_config_btcoex_params(ar);
2434 if (status)
2435 return status;
2436
2437#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
2438 if ((wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
2439 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set power save fail event policy\n"));
2440 status = A_ERROR;
2441 }
2442#endif
2443
2444#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP
2445 if ((wmi_set_lpreamble_cmd(ar->arWmi, 0, WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) {
2446 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set barker preamble policy\n"));
2447 status = A_ERROR;
2448 }
2449#endif
2450
2451 if ((wmi_set_keepalive_cmd(ar->arWmi, WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) != 0) {
2452 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set keep alive interval\n"));
2453 status = A_ERROR;
2454 }
2455
2456#if WLAN_CONFIG_DISABLE_11N
2457 {
2458 WMI_SET_HT_CAP_CMD htCap;
2459
2460 memset(&htCap, 0, sizeof(WMI_SET_HT_CAP_CMD));
2461 htCap.band = 0;
2462 if ((wmi_set_ht_cap_cmd(ar->arWmi, &htCap)) != 0) {
2463 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set ht capabilities \n"));
2464 status = A_ERROR;
2465 }
2466
2467 htCap.band = 1;
2468 if ((wmi_set_ht_cap_cmd(ar->arWmi, &htCap)) != 0) {
2469 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set ht capabilities \n"));
2470 status = A_ERROR;
2471 }
2472 }
2473#endif /* WLAN_CONFIG_DISABLE_11N */
2474
2475#ifdef ATH6K_CONFIG_OTA_MODE
2476 if ((wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER)) != 0) {
2477 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set power mode \n"));
2478 status = A_ERROR;
2479 }
2480#endif
2481
2482 if ((wmi_disctimeout_cmd(ar->arWmi, WLAN_CONFIG_DISCONNECT_TIMEOUT)) != 0) {
2483 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set disconnect timeout \n"));
2484 status = A_ERROR;
2485 }
2486
2487#if WLAN_CONFIG_DISABLE_TX_BURSTING
2488 if ((wmi_set_wmm_txop(ar->arWmi, WMI_TXOP_DISABLED)) != 0) {
2489 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set txop bursting \n"));
2490 status = A_ERROR;
2491 }
2492#endif
2493
2494 return status;
2495}
2496
2497/* This function does one time initialization for the lifetime of the device */
2498int ar6000_init(struct net_device *dev)
2499{
2500 struct ar6_softc *ar;
2501 int status;
2502 s32 timeleft;
2503 s16 i;
2504 int ret = 0;
2505
2506 if((ar = ar6k_priv(dev)) == NULL)
2507 {
2508 return -EIO;
2509 }
2510
2511 if (wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) {
2512
2513 ar6000_update_bdaddr(ar);
2514
2515 if (enablerssicompensation) {
2516 ar6000_copy_cust_data_from_target(ar->arHifDevice, ar->arTargetType);
2517 read_rssi_compensation_param(ar);
2518 for (i=-95; i<=0; i++) {
2519 rssi_compensation_table[0-i] = rssi_compensation_calc(ar,i);
2520 }
2521 }
2522 }
2523
2524 dev_hold(dev);
2525 rtnl_unlock();
2526
2527 /* Do we need to finish the BMI phase */
2528 if ((wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) &&
2529 (BMIDone(ar->arHifDevice) != 0))
2530 {
2531 ret = -EIO;
2532 goto ar6000_init_done;
2533 }
2534
2535 if (!bypasswmi)
2536 {
2537#if 0 /* TBDXXX */
2538 if (ar->arVersion.host_ver != ar->arVersion.target_ver) {
2539 A_PRINTF("WARNING: Host version 0x%x does not match Target "
2540 " version 0x%x!\n",
2541 ar->arVersion.host_ver, ar->arVersion.target_ver);
2542 }
2543#endif
2544
2545 /* Indicate that WMI is enabled (although not ready yet) */
2546 ar->arWmiEnabled = true;
2547 if ((ar->arWmi = wmi_init((void *) ar)) == NULL)
2548 {
2549 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize WMI.\n", __func__));
2550 ret = -EIO;
2551 goto ar6000_init_done;
2552 }
2553
2554 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Got WMI @ 0x%lx.\n", __func__,
2555 (unsigned long) ar->arWmi));
2556 }
2557
2558 do {
2559 struct htc_service_connect_req connect;
2560
2561 /* the reason we have to wait for the target here is that the driver layer
2562 * has to init BMI in order to set the host block size,
2563 */
2564 status = HTCWaitTarget(ar->arHtcTarget);
2565
2566 if (status) {
2567 break;
2568 }
2569
2570 A_MEMZERO(&connect,sizeof(connect));
2571 /* meta data is unused for now */
2572 connect.pMetaData = NULL;
2573 connect.MetaDataLength = 0;
2574 /* these fields are the same for all service endpoints */
2575 connect.EpCallbacks.pContext = ar;
2576 connect.EpCallbacks.EpTxCompleteMultiple = ar6000_tx_complete;
2577 connect.EpCallbacks.EpRecv = ar6000_rx;
2578 connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill;
2579 connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full;
2580 /* set the max queue depth so that our ar6000_tx_queue_full handler gets called.
2581 * Linux has the peculiarity of not providing flow control between the
2582 * NIC and the network stack. There is no API to indicate that a TX packet
2583 * was sent which could provide some back pressure to the network stack.
2584 * Under linux you would have to wait till the network stack consumed all sk_buffs
2585 * before any back-flow kicked in. Which isn't very friendly.
2586 * So we have to manage this ourselves */
2587 connect.MaxSendQueueDepth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
2588 connect.EpCallbacks.RecvRefillWaterMark = AR6000_MAX_RX_BUFFERS / 4; /* set to 25 % */
2589 if (0 == connect.EpCallbacks.RecvRefillWaterMark) {
2590 connect.EpCallbacks.RecvRefillWaterMark++;
2591 }
2592 /* connect to control service */
2593 connect.ServiceID = WMI_CONTROL_SVC;
2594 status = ar6000_connectservice(ar,
2595 &connect,
2596 "WMI CONTROL");
2597 if (status) {
2598 break;
2599 }
2600
2601 connect.LocalConnectionFlags |= HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING;
2602 /* limit the HTC message size on the send path, although we can receive A-MSDU frames of
2603 * 4K, we will only send ethernet-sized (802.3) frames on the send path. */
2604 connect.MaxSendMsgSize = WMI_MAX_TX_DATA_FRAME_LENGTH;
2605
2606 /* to reduce the amount of committed memory for larger A_MSDU frames, use the recv-alloc threshold
2607 * mechanism for larger packets */
2608 connect.EpCallbacks.RecvAllocThreshold = AR6000_BUFFER_SIZE;
2609 connect.EpCallbacks.EpRecvAllocThresh = ar6000_alloc_amsdu_rxbuf;
2610
2611 /* for the remaining data services set the connection flag to reduce dribbling,
2612 * if configured to do so */
2613 if (reduce_credit_dribble) {
2614 connect.ConnectionFlags |= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE;
2615 /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value
2616 * of 0-3 */
2617 connect.ConnectionFlags &= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
2618 connect.ConnectionFlags |=
2619 ((u16)reduce_credit_dribble - 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
2620 }
2621 /* connect to best-effort service */
2622 connect.ServiceID = WMI_DATA_BE_SVC;
2623
2624 status = ar6000_connectservice(ar,
2625 &connect,
2626 "WMI DATA BE");
2627 if (status) {
2628 break;
2629 }
2630
2631 /* connect to back-ground
2632 * map this to WMI LOW_PRI */
2633 connect.ServiceID = WMI_DATA_BK_SVC;
2634 status = ar6000_connectservice(ar,
2635 &connect,
2636 "WMI DATA BK");
2637 if (status) {
2638 break;
2639 }
2640
2641 /* connect to Video service, map this to
2642 * to HI PRI */
2643 connect.ServiceID = WMI_DATA_VI_SVC;
2644 status = ar6000_connectservice(ar,
2645 &connect,
2646 "WMI DATA VI");
2647 if (status) {
2648 break;
2649 }
2650
2651 /* connect to VO service, this is currently not
2652 * mapped to a WMI priority stream due to historical reasons.
2653 * WMI originally defined 3 priorities over 3 mailboxes
2654 * We can change this when WMI is reworked so that priorities are not
2655 * dependent on mailboxes */
2656 connect.ServiceID = WMI_DATA_VO_SVC;
2657 status = ar6000_connectservice(ar,
2658 &connect,
2659 "WMI DATA VO");
2660 if (status) {
2661 break;
2662 }
2663
2664 A_ASSERT(arAc2EndpointID(ar,WMM_AC_BE) != 0);
2665 A_ASSERT(arAc2EndpointID(ar,WMM_AC_BK) != 0);
2666 A_ASSERT(arAc2EndpointID(ar,WMM_AC_VI) != 0);
2667 A_ASSERT(arAc2EndpointID(ar,WMM_AC_VO) != 0);
2668
2669 /* setup access class priority mappings */
2670 ar->arAcStreamPriMap[WMM_AC_BK] = 0; /* lowest */
2671 ar->arAcStreamPriMap[WMM_AC_BE] = 1; /* */
2672 ar->arAcStreamPriMap[WMM_AC_VI] = 2; /* */
2673 ar->arAcStreamPriMap[WMM_AC_VO] = 3; /* highest */
2674
2675#ifdef EXPORT_HCI_BRIDGE_INTERFACE
2676 if (setuphci && (NULL != ar6kHciTransCallbacks.setupTransport)) {
2677 struct hci_transport_misc_handles hciHandles;
2678
2679 hciHandles.netDevice = ar->arNetDev;
2680 hciHandles.hifDevice = ar->arHifDevice;
2681 hciHandles.htcHandle = ar->arHtcTarget;
2682 status = (int)(ar6kHciTransCallbacks.setupTransport(&hciHandles));
2683 }
2684#else
2685 if (setuphci) {
2686 /* setup HCI */
2687 status = ar6000_setup_hci(ar);
2688 }
2689#endif
2690
2691 } while (false);
2692
2693 if (status) {
2694 ret = -EIO;
2695 goto ar6000_init_done;
2696 }
2697
2698 if (regscanmode) {
2699 u32 param;
2700
2701 if (BMIReadMemory(ar->arHifDevice,
2702 HOST_INTEREST_ITEM_ADDRESS(ar,
2703 hi_option_flag),
2704 (u8 *)&param,
2705 4) != 0) {
2706 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
2707 ("BMIReadMemory forsetting "
2708 "regscanmode failed\n"));
2709 return A_ERROR;
2710 }
2711
2712 if (regscanmode == 1)
2713 param |= HI_OPTION_SKIP_REG_SCAN;
2714 else if (regscanmode == 2)
2715 param |= HI_OPTION_INIT_REG_SCAN;
2716
2717 if (BMIWriteMemory(ar->arHifDevice,
2718 HOST_INTEREST_ITEM_ADDRESS(ar,
2719 hi_option_flag),
2720 (u8 *)&param,
2721 4) != 0) {
2722 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
2723 ("BMIWriteMemory forsetting "
2724 "regscanmode failed\n"));
2725 return A_ERROR;
2726 }
2727 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Regulatory scan mode set\n"));
2728 }
2729
2730 /*
2731 * give our connected endpoints some buffers
2732 */
2733
2734 ar6000_rx_refill(ar, ar->arControlEp);
2735 ar6000_rx_refill(ar, arAc2EndpointID(ar,WMM_AC_BE));
2736
2737 /*
2738 * We will post the receive buffers only for SPE or endpoint ping testing so we are
2739 * making it conditional on the 'bypasswmi' flag.
2740 */
2741 if (bypasswmi) {
2742 ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_BK));
2743 ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VI));
2744 ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VO));
2745 }
2746
2747 /* allocate some buffers that handle larger AMSDU frames */
2748 ar6000_refill_amsdu_rxbufs(ar,AR6000_MAX_AMSDU_RX_BUFFERS);
2749
2750 /* setup credit distribution */
2751 ar6000_setup_credit_dist(ar->arHtcTarget, &ar->arCreditStateInfo);
2752
2753 /* Since cookies are used for HTC transports, they should be */
2754 /* initialized prior to enabling HTC. */
2755 ar6000_cookie_init(ar);
2756
2757 /* start HTC */
2758 status = HTCStart(ar->arHtcTarget);
2759
2760 if (status) {
2761 if (ar->arWmiEnabled == true) {
2762 wmi_shutdown(ar->arWmi);
2763 ar->arWmiEnabled = false;
2764 ar->arWmi = NULL;
2765 }
2766 ar6000_cookie_cleanup(ar);
2767 ret = -EIO;
2768 goto ar6000_init_done;
2769 }
2770
2771 if (!bypasswmi) {
2772 /* Wait for Wmi event to be ready */
2773 timeleft = wait_event_interruptible_timeout(arEvent,
2774 (ar->arWmiReady == true), wmitimeout * HZ);
2775
2776 if (ar->arVersion.abi_ver != AR6K_ABI_VERSION) {
2777 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ABI Version mismatch: Host(0x%x), Target(0x%x)\n", AR6K_ABI_VERSION, ar->arVersion.abi_ver));
2778#ifndef ATH6K_SKIP_ABI_VERSION_CHECK
2779 ret = -EIO;
2780 goto ar6000_init_done;
2781#endif /* ATH6K_SKIP_ABI_VERSION_CHECK */
2782 }
2783
2784 if(!timeleft || signal_pending(current))
2785 {
2786 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI is not ready or wait was interrupted\n"));
2787 ret = -EIO;
2788 goto ar6000_init_done;
2789 }
2790
2791 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() WMI is ready\n", __func__));
2792
2793 /* Communicate the wmi protocol verision to the target */
2794 if ((ar6000_set_host_app_area(ar)) != 0) {
2795 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the host app area\n"));
2796 }
2797 ar6000_target_config_wlan_params(ar);
2798 }
2799
2800 ar->arNumDataEndPts = 1;
2801
2802 if (bypasswmi) {
2803 /* for tests like endpoint ping, the MAC address needs to be non-zero otherwise
2804 * the data path through a raw socket is disabled */
2805 dev->dev_addr[0] = 0x00;
2806 dev->dev_addr[1] = 0x01;
2807 dev->dev_addr[2] = 0x02;
2808 dev->dev_addr[3] = 0xAA;
2809 dev->dev_addr[4] = 0xBB;
2810 dev->dev_addr[5] = 0xCC;
2811 }
2812
2813ar6000_init_done:
2814 rtnl_lock();
2815 dev_put(dev);
2816
2817 return ret;
2818}
2819
2820
2821void
2822ar6000_bitrate_rx(void *devt, s32 rateKbps)
2823{
2824 struct ar6_softc *ar = (struct ar6_softc *)devt;
2825
2826 ar->arBitRate = rateKbps;
2827 wake_up(&arEvent);
2828}
2829
2830void
2831ar6000_ratemask_rx(void *devt, u32 ratemask)
2832{
2833 struct ar6_softc *ar = (struct ar6_softc *)devt;
2834
2835 ar->arRateMask = ratemask;
2836 wake_up(&arEvent);
2837}
2838
2839void
2840ar6000_txPwr_rx(void *devt, u8 txPwr)
2841{
2842 struct ar6_softc *ar = (struct ar6_softc *)devt;
2843
2844 ar->arTxPwr = txPwr;
2845 wake_up(&arEvent);
2846}
2847
2848
2849void
2850ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList)
2851{
2852 struct ar6_softc *ar = (struct ar6_softc *)devt;
2853
2854 memcpy(ar->arChannelList, chanList, numChan * sizeof (u16));
2855 ar->arNumChannels = numChan;
2856
2857 wake_up(&arEvent);
2858}
2859
2860u8 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *mapNo)
2861{
2862 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2863 u8 *datap;
2864 ATH_MAC_HDR *macHdr;
2865 u32 i, eptMap;
2866
2867 (*mapNo) = 0;
2868 datap = A_NETBUF_DATA(skb);
2869 macHdr = (ATH_MAC_HDR *)(datap + sizeof(WMI_DATA_HDR));
2870 if (IEEE80211_IS_MULTICAST(macHdr->dstMac)) {
2871 return ENDPOINT_2;
2872 }
2873
2874 eptMap = -1;
2875 for (i = 0; i < ar->arNodeNum; i ++) {
2876 if (IEEE80211_ADDR_EQ(macHdr->dstMac, ar->arNodeMap[i].macAddress)) {
2877 (*mapNo) = i + 1;
2878 ar->arNodeMap[i].txPending ++;
2879 return ar->arNodeMap[i].epId;
2880 }
2881
2882 if ((eptMap == -1) && !ar->arNodeMap[i].txPending) {
2883 eptMap = i;
2884 }
2885 }
2886
2887 if (eptMap == -1) {
2888 eptMap = ar->arNodeNum;
2889 ar->arNodeNum ++;
2890 A_ASSERT(ar->arNodeNum <= MAX_NODE_NUM);
2891 }
2892
2893 memcpy(ar->arNodeMap[eptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LEN);
2894
2895 for (i = ENDPOINT_2; i <= ENDPOINT_5; i ++) {
2896 if (!ar->arTxPending[i]) {
2897 ar->arNodeMap[eptMap].epId = i;
2898 break;
2899 }
2900 // No free endpoint is available, start redistribution on the inuse endpoints.
2901 if (i == ENDPOINT_5) {
2902 ar->arNodeMap[eptMap].epId = ar->arNexEpId;
2903 ar->arNexEpId ++;
2904 if (ar->arNexEpId > ENDPOINT_5) {
2905 ar->arNexEpId = ENDPOINT_2;
2906 }
2907 }
2908 }
2909
2910 (*mapNo) = eptMap + 1;
2911 ar->arNodeMap[eptMap].txPending ++;
2912
2913 return ar->arNodeMap[eptMap].epId;
2914}
2915
2916#ifdef DEBUG
2917static void ar6000_dump_skb(struct sk_buff *skb)
2918{
2919 u_char *ch;
2920 for (ch = A_NETBUF_DATA(skb);
2921 (unsigned long)ch < ((unsigned long)A_NETBUF_DATA(skb) +
2922 A_NETBUF_LEN(skb)); ch++)
2923 {
2924 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("%2.2x ", *ch));
2925 }
2926 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("\n"));
2927}
2928#endif
2929
2930#ifdef HTC_TEST_SEND_PKTS
2931static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *skb);
2932#endif
2933
2934static int
2935ar6000_data_tx(struct sk_buff *skb, struct net_device *dev)
2936{
2937#define AC_NOT_MAPPED 99
2938 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2939 u8 ac = AC_NOT_MAPPED;
2940 HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
2941 u32 mapNo = 0;
2942 int len;
2943 struct ar_cookie *cookie;
2944 bool checkAdHocPsMapping = false,bMoreData = false;
2945 HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG;
2946 u8 dot11Hdr = processDot11Hdr;
2947#ifdef CONFIG_PM
2948 if (ar->arWowState != WLAN_WOW_STATE_NONE) {
2949 A_NETBUF_FREE(skb);
2950 return 0;
2951 }
2952#endif /* CONFIG_PM */
2953
2954 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_data_tx start - skb=0x%lx, data=0x%lx, len=0x%x\n",
2955 (unsigned long)skb, (unsigned long)A_NETBUF_DATA(skb),
2956 A_NETBUF_LEN(skb)));
2957
2958 /* If target is not associated */
2959 if( (!ar->arConnected && !bypasswmi)
2960#ifdef CONFIG_HOST_TCMD_SUPPORT
2961 /* TCMD doesn't support any data, free the buf and return */
2962 || (ar->arTargetMode == AR6000_TCMD_MODE)
2963#endif
2964 ) {
2965 A_NETBUF_FREE(skb);
2966 return 0;
2967 }
2968
2969 do {
2970
2971 if (ar->arWmiReady == false && bypasswmi == 0) {
2972 break;
2973 }
2974
2975#ifdef BLOCK_TX_PATH_FLAG
2976 if (blocktx) {
2977 break;
2978 }
2979#endif /* BLOCK_TX_PATH_FLAG */
2980
2981 /* AP mode Power save processing */
2982 /* If the dst STA is in sleep state, queue the pkt in its PS queue */
2983
2984 if (ar->arNetworkType == AP_NETWORK) {
2985 ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
2986 sta_t *conn = NULL;
2987
2988 /* If the dstMac is a Multicast address & atleast one of the
2989 * associated STA is in PS mode, then queue the pkt to the
2990 * mcastq
2991 */
2992 if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
2993 u8 ctr=0;
2994 bool qMcast=false;
2995
2996
2997 for (ctr=0; ctr<AP_MAX_NUM_STA; ctr++) {
2998 if (STA_IS_PWR_SLEEP((&ar->sta_list[ctr]))) {
2999 qMcast = true;
3000 }
3001 }
3002 if(qMcast) {
3003
3004 /* If this transmit is not because of a Dtim Expiry q it */
3005 if (ar->DTIMExpired == false) {
3006 bool isMcastqEmpty = false;
3007
3008 A_MUTEX_LOCK(&ar->mcastpsqLock);
3009 isMcastqEmpty = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
3010 A_NETBUF_ENQUEUE(&ar->mcastpsq, skb);
3011 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
3012
3013 /* If this is the first Mcast pkt getting queued
3014 * indicate to the target to set the BitmapControl LSB
3015 * of the TIM IE.
3016 */
3017 if (isMcastqEmpty) {
3018 wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 1);
3019 }
3020 return 0;
3021 } else {
3022 /* This transmit is because of Dtim expiry. Determine if
3023 * MoreData bit has to be set.
3024 */
3025 A_MUTEX_LOCK(&ar->mcastpsqLock);
3026 if(!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
3027 bMoreData = true;
3028 }
3029 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
3030 }
3031 }
3032 } else {
3033 conn = ieee80211_find_conn(ar, datap->dstMac);
3034 if (conn) {
3035 if (STA_IS_PWR_SLEEP(conn)) {
3036 /* If this transmit is not because of a PsPoll q it*/
3037 if (!STA_IS_PS_POLLED(conn)) {
3038 bool isPsqEmpty = false;
3039 /* Queue the frames if the STA is sleeping */
3040 A_MUTEX_LOCK(&conn->psqLock);
3041 isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
3042 A_NETBUF_ENQUEUE(&conn->psq, skb);
3043 A_MUTEX_UNLOCK(&conn->psqLock);
3044
3045 /* If this is the first pkt getting queued
3046 * for this STA, update the PVB for this STA
3047 */
3048 if (isPsqEmpty) {
3049 wmi_set_pvb_cmd(ar->arWmi, conn->aid, 1);
3050 }
3051
3052 return 0;
3053 } else {
3054 /* This tx is because of a PsPoll. Determine if
3055 * MoreData bit has to be set
3056 */
3057 A_MUTEX_LOCK(&conn->psqLock);
3058 if (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
3059 bMoreData = true;
3060 }
3061 A_MUTEX_UNLOCK(&conn->psqLock);
3062 }
3063 }
3064 } else {
3065
3066 /* non existent STA. drop the frame */
3067 A_NETBUF_FREE(skb);
3068 return 0;
3069 }
3070 }
3071 }
3072
3073 if (ar->arWmiEnabled) {
3074 u8 csumStart=0;
3075 u8 csumDest=0;
3076 u8 csum=skb->ip_summed;
3077 if(csumOffload && (csum==CHECKSUM_PARTIAL)){
3078 csumStart = (skb->head + skb->csum_start - skb_network_header(skb) +
3079 sizeof(ATH_LLC_SNAP_HDR));
3080 csumDest=skb->csum_offset+csumStart;
3081 }
3082 if (A_NETBUF_HEADROOM(skb) < dev->hard_header_len - LINUX_HACK_FUDGE_FACTOR) {
3083 struct sk_buff *newbuf;
3084
3085 /*
3086 * We really should have gotten enough headroom but sometimes
3087 * we still get packets with not enough headroom. Copy the packet.
3088 */
3089 len = A_NETBUF_LEN(skb);
3090 newbuf = A_NETBUF_ALLOC(len);
3091 if (newbuf == NULL) {
3092 break;
3093 }
3094 A_NETBUF_PUT(newbuf, len);
3095 memcpy(A_NETBUF_DATA(newbuf), A_NETBUF_DATA(skb), len);
3096 A_NETBUF_FREE(skb);
3097 skb = newbuf;
3098 /* fall through and assemble header */
3099 }
3100
3101 if (dot11Hdr) {
3102 if (wmi_dot11_hdr_add(ar->arWmi,skb,ar->arNetworkType) != 0) {
3103 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx-wmi_dot11_hdr_add failed\n"));
3104 break;
3105 }
3106 } else {
3107 if (wmi_dix_2_dot3(ar->arWmi, skb) != 0) {
3108 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_dix_2_dot3 failed\n"));
3109 break;
3110 }
3111 }
3112 if(csumOffload && (csum ==CHECKSUM_PARTIAL)){
3113 WMI_TX_META_V2 metaV2;
3114 metaV2.csumStart =csumStart;
3115 metaV2.csumDest = csumDest;
3116 metaV2.csumFlags = 0x1;/*instruct target to calculate checksum*/
3117 if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,
3118 WMI_META_VERSION_2,&metaV2) != 0) {
3119 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
3120 break;
3121 }
3122
3123 }
3124 else
3125 {
3126 if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,0,NULL) != 0) {
3127 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
3128 break;
3129 }
3130 }
3131
3132
3133 if ((ar->arNetworkType == ADHOC_NETWORK) &&
3134 ar->arIbssPsEnable && ar->arConnected) {
3135 /* flag to check adhoc mapping once we take the lock below: */
3136 checkAdHocPsMapping = true;
3137
3138 } else {
3139 /* get the stream mapping */
3140 ac = wmi_implicit_create_pstream(ar->arWmi, skb, 0, ar->arWmmEnabled);
3141 }
3142
3143 } else {
3144 EPPING_HEADER *eppingHdr;
3145
3146 eppingHdr = A_NETBUF_DATA(skb);
3147
3148 if (IS_EPPING_PACKET(eppingHdr)) {
3149 /* the stream ID is mapped to an access class */
3150 ac = eppingHdr->StreamNo_h;
3151 /* some EPPING packets cannot be dropped no matter what access class it was
3152 * sent on. We can change the packet tag to guarantee it will not get dropped */
3153 if (IS_EPING_PACKET_NO_DROP(eppingHdr)) {
3154 htc_tag = AR6K_CONTROL_PKT_TAG;
3155 }
3156
3157 if (ac == HCI_TRANSPORT_STREAM_NUM) {
3158 /* pass this to HCI */
3159#ifndef EXPORT_HCI_BRIDGE_INTERFACE
3160 if (!hci_test_send(ar,skb)) {
3161 return 0;
3162 }
3163#endif
3164 /* set AC to discard this skb */
3165 ac = AC_NOT_MAPPED;
3166 } else {
3167 /* a quirk of linux, the payload of the frame is 32-bit aligned and thus the addition
3168 * of the HTC header will mis-align the start of the HTC frame, so we add some
3169 * padding which will be stripped off in the target */
3170 if (EPPING_ALIGNMENT_PAD > 0) {
3171 A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD);
3172 }
3173 }
3174
3175 } else {
3176 /* not a ping packet, drop it */
3177 ac = AC_NOT_MAPPED;
3178 }
3179 }
3180
3181 } while (false);
3182
3183 /* did we succeed ? */
3184 if ((ac == AC_NOT_MAPPED) && !checkAdHocPsMapping) {
3185 /* cleanup and exit */
3186 A_NETBUF_FREE(skb);
3187 AR6000_STAT_INC(ar, tx_dropped);
3188 AR6000_STAT_INC(ar, tx_aborted_errors);
3189 return 0;
3190 }
3191
3192 cookie = NULL;
3193
3194 /* take the lock to protect driver data */
3195 AR6000_SPIN_LOCK(&ar->arLock, 0);
3196
3197 do {
3198
3199 if (checkAdHocPsMapping) {
3200 eid = ar6000_ibss_map_epid(skb, dev, &mapNo);
3201 }else {
3202 eid = arAc2EndpointID (ar, ac);
3203 }
3204 /* validate that the endpoint is connected */
3205 if (eid == 0 || eid == ENDPOINT_UNUSED ) {
3206 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" eid %d is NOT mapped!\n", eid));
3207 break;
3208 }
3209 /* allocate resource for this packet */
3210 cookie = ar6000_alloc_cookie(ar);
3211
3212 if (cookie != NULL) {
3213 /* update counts while the lock is held */
3214 ar->arTxPending[eid]++;
3215 ar->arTotalTxDataPending++;
3216 }
3217
3218 } while (false);
3219
3220 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3221
3222 if (cookie != NULL) {
3223 cookie->arc_bp[0] = (unsigned long)skb;
3224 cookie->arc_bp[1] = mapNo;
3225 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
3226 cookie,
3227 A_NETBUF_DATA(skb),
3228 A_NETBUF_LEN(skb),
3229 eid,
3230 htc_tag);
3231
3232#ifdef DEBUG
3233 if (debugdriver >= 3) {
3234 ar6000_dump_skb(skb);
3235 }
3236#endif
3237#ifdef HTC_TEST_SEND_PKTS
3238 DoHTCSendPktsTest(ar,mapNo,eid,skb);
3239#endif
3240 /* HTC interface is asynchronous, if this fails, cleanup will happen in
3241 * the ar6000_tx_complete callback */
3242 HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
3243 } else {
3244 /* no packet to send, cleanup */
3245 A_NETBUF_FREE(skb);
3246 AR6000_STAT_INC(ar, tx_dropped);
3247 AR6000_STAT_INC(ar, tx_aborted_errors);
3248 }
3249
3250 return 0;
3251}
3252
3253int
3254ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev)
3255{
3256 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
3257 struct ar_cookie *cookie;
3258 HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
3259
3260 cookie = NULL;
3261 AR6000_SPIN_LOCK(&ar->arLock, 0);
3262
3263 /* For now we send ACL on BE endpoint: We can also have a dedicated EP */
3264 eid = arAc2EndpointID (ar, 0);
3265 /* allocate resource for this packet */
3266 cookie = ar6000_alloc_cookie(ar);
3267
3268 if (cookie != NULL) {
3269 /* update counts while the lock is held */
3270 ar->arTxPending[eid]++;
3271 ar->arTotalTxDataPending++;
3272 }
3273
3274
3275 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3276
3277 if (cookie != NULL) {
3278 cookie->arc_bp[0] = (unsigned long)skb;
3279 cookie->arc_bp[1] = 0;
3280 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
3281 cookie,
3282 A_NETBUF_DATA(skb),
3283 A_NETBUF_LEN(skb),
3284 eid,
3285 AR6K_DATA_PKT_TAG);
3286
3287 /* HTC interface is asynchronous, if this fails, cleanup will happen in
3288 * the ar6000_tx_complete callback */
3289 HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
3290 } else {
3291 /* no packet to send, cleanup */
3292 A_NETBUF_FREE(skb);
3293 AR6000_STAT_INC(ar, tx_dropped);
3294 AR6000_STAT_INC(ar, tx_aborted_errors);
3295 }
3296 return 0;
3297}
3298
3299
3300#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3301static void
3302tvsub(register struct timeval *out, register struct timeval *in)
3303{
3304 if((out->tv_usec -= in->tv_usec) < 0) {
3305 out->tv_sec--;
3306 out->tv_usec += 1000000;
3307 }
3308 out->tv_sec -= in->tv_sec;
3309}
3310
3311void
3312applyAPTCHeuristics(struct ar6_softc *ar)
3313{
3314 u32 duration;
3315 u32 numbytes;
3316 u32 throughput;
3317 struct timeval ts;
3318 int status;
3319
3320 AR6000_SPIN_LOCK(&ar->arLock, 0);
3321
3322 if ((enableAPTCHeuristics) && (!aptcTR.timerScheduled)) {
3323 do_gettimeofday(&ts);
3324 tvsub(&ts, &aptcTR.samplingTS);
3325 duration = ts.tv_sec * 1000 + ts.tv_usec / 1000; /* ms */
3326 numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
3327
3328 if (duration > APTC_TRAFFIC_SAMPLING_INTERVAL) {
3329 /* Initialize the time stamp and byte count */
3330 aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
3331 do_gettimeofday(&aptcTR.samplingTS);
3332
3333 /* Calculate and decide based on throughput thresholds */
3334 throughput = ((numbytes * 8) / duration);
3335 if (throughput > APTC_UPPER_THROUGHPUT_THRESHOLD) {
3336 /* Disable Sleep and schedule a timer */
3337 A_ASSERT(ar->arWmiReady == true);
3338 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3339 status = wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER);
3340 AR6000_SPIN_LOCK(&ar->arLock, 0);
3341 A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
3342 aptcTR.timerScheduled = true;
3343 }
3344 }
3345 }
3346
3347 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3348}
3349#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3350
3351static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket)
3352{
3353 struct ar6_softc *ar = (struct ar6_softc *)Context;
3354 HTC_SEND_FULL_ACTION action = HTC_SEND_FULL_KEEP;
3355 bool stopNet = false;
3356 HTC_ENDPOINT_ID Endpoint = HTC_GET_ENDPOINT_FROM_PKT(pPacket);
3357
3358 do {
3359
3360 if (bypasswmi) {
3361 int accessClass;
3362
3363 if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
3364 /* don't drop special control packets */
3365 break;
3366 }
3367
3368 accessClass = arEndpoint2Ac(ar,Endpoint);
3369 /* for endpoint ping testing drop Best Effort and Background */
3370 if ((accessClass == WMM_AC_BE) || (accessClass == WMM_AC_BK)) {
3371 action = HTC_SEND_FULL_DROP;
3372 stopNet = false;
3373 } else {
3374 /* keep but stop the netqueues */
3375 stopNet = true;
3376 }
3377 break;
3378 }
3379
3380 if (Endpoint == ar->arControlEp) {
3381 /* under normal WMI if this is getting full, then something is running rampant
3382 * the host should not be exhausting the WMI queue with too many commands
3383 * the only exception to this is during testing using endpointping */
3384 AR6000_SPIN_LOCK(&ar->arLock, 0);
3385 /* set flag to handle subsequent messages */
3386 ar->arWMIControlEpFull = true;
3387 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3388 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI Control Endpoint is FULL!!! \n"));
3389 /* no need to stop the network */
3390 stopNet = false;
3391 break;
3392 }
3393
3394 /* if we get here, we are dealing with data endpoints getting full */
3395
3396 if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
3397 /* don't drop control packets issued on ANY data endpoint */
3398 break;
3399 }
3400
3401 if (ar->arNetworkType == ADHOC_NETWORK) {
3402 /* in adhoc mode, we cannot differentiate traffic priorities so there is no need to
3403 * continue, however we should stop the network */
3404 stopNet = true;
3405 break;
3406 }
3407 /* the last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for the highest
3408 * active stream */
3409 if (ar->arAcStreamPriMap[arEndpoint2Ac(ar,Endpoint)] < ar->arHiAcStreamActivePri &&
3410 ar->arCookieCount <= MAX_HI_COOKIE_NUM) {
3411 /* this stream's priority is less than the highest active priority, we
3412 * give preference to the highest priority stream by directing
3413 * HTC to drop the packet that overflowed */
3414 action = HTC_SEND_FULL_DROP;
3415 /* since we are dropping packets, no need to stop the network */
3416 stopNet = false;
3417 break;
3418 }
3419
3420 } while (false);
3421
3422 if (stopNet) {
3423 AR6000_SPIN_LOCK(&ar->arLock, 0);
3424 ar->arNetQueueStopped = true;
3425 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3426 /* one of the data endpoints queues is getting full..need to stop network stack
3427 * the queue will resume in ar6000_tx_complete() */
3428 netif_stop_queue(ar->arNetDev);
3429 }
3430
3431 return action;
3432}
3433
3434
3435static void
3436ar6000_tx_complete(void *Context, struct htc_packet_queue *pPacketQueue)
3437{
3438 struct ar6_softc *ar = (struct ar6_softc *)Context;
3439 u32 mapNo = 0;
3440 int status;
3441 struct ar_cookie * ar_cookie;
3442 HTC_ENDPOINT_ID eid;
3443 bool wakeEvent = false;
3444 struct sk_buff_head skb_queue;
3445 struct htc_packet *pPacket;
3446 struct sk_buff *pktSkb;
3447 bool flushing = false;
3448
3449 skb_queue_head_init(&skb_queue);
3450
3451 /* lock the driver as we update internal state */
3452 AR6000_SPIN_LOCK(&ar->arLock, 0);
3453
3454 /* reap completed packets */
3455 while (!HTC_QUEUE_EMPTY(pPacketQueue)) {
3456
3457 pPacket = HTC_PACKET_DEQUEUE(pPacketQueue);
3458
3459 ar_cookie = (struct ar_cookie *)pPacket->pPktContext;
3460 A_ASSERT(ar_cookie);
3461
3462 status = pPacket->Status;
3463 pktSkb = (struct sk_buff *)ar_cookie->arc_bp[0];
3464 eid = pPacket->Endpoint;
3465 mapNo = ar_cookie->arc_bp[1];
3466
3467 A_ASSERT(pktSkb);
3468 A_ASSERT(pPacket->pBuffer == A_NETBUF_DATA(pktSkb));
3469
3470 /* add this to the list, use faster non-lock API */
3471 __skb_queue_tail(&skb_queue,pktSkb);
3472
3473 if (!status) {
3474 A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(pktSkb));
3475 }
3476
3477 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_tx_complete skb=0x%lx data=0x%lx len=0x%x eid=%d ",
3478 (unsigned long)pktSkb, (unsigned long)pPacket->pBuffer,
3479 pPacket->ActualLength,
3480 eid));
3481
3482 ar->arTxPending[eid]--;
3483
3484 if ((eid != ar->arControlEp) || bypasswmi) {
3485 ar->arTotalTxDataPending--;
3486 }
3487
3488 if (eid == ar->arControlEp)
3489 {
3490 if (ar->arWMIControlEpFull) {
3491 /* since this packet completed, the WMI EP is no longer full */
3492 ar->arWMIControlEpFull = false;
3493 }
3494
3495 if (ar->arTxPending[eid] == 0) {
3496 wakeEvent = true;
3497 }
3498 }
3499
3500 if (status) {
3501 if (status == A_ECANCELED) {
3502 /* a packet was flushed */
3503 flushing = true;
3504 }
3505 AR6000_STAT_INC(ar, tx_errors);
3506 if (status != A_NO_RESOURCE) {
3507 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() -TX ERROR, status: 0x%x\n", __func__,
3508 status));
3509 }
3510 } else {
3511 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("OK\n"));
3512 flushing = false;
3513 AR6000_STAT_INC(ar, tx_packets);
3514 ar->arNetStats.tx_bytes += A_NETBUF_LEN(pktSkb);
3515#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3516 aptcTR.bytesTransmitted += a_netbuf_to_len(pktSkb);
3517 applyAPTCHeuristics(ar);
3518#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3519 }
3520
3521 // TODO this needs to be looked at
3522 if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable
3523 && (eid != ar->arControlEp) && mapNo)
3524 {
3525 mapNo --;
3526 ar->arNodeMap[mapNo].txPending --;
3527
3528 if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1))) {
3529 u32 i;
3530 for (i = ar->arNodeNum; i > 0; i --) {
3531 if (!ar->arNodeMap[i - 1].txPending) {
3532 A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_mapping));
3533 ar->arNodeNum --;
3534 } else {
3535 break;
3536 }
3537 }
3538 }
3539 }
3540
3541 ar6000_free_cookie(ar, ar_cookie);
3542
3543 if (ar->arNetQueueStopped) {
3544 ar->arNetQueueStopped = false;
3545 }
3546 }
3547
3548 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3549
3550 /* lock is released, we can freely call other kernel APIs */
3551
3552 /* free all skbs in our local list */
3553 while (!skb_queue_empty(&skb_queue)) {
3554 /* use non-lock version */
3555 pktSkb = __skb_dequeue(&skb_queue);
3556 A_NETBUF_FREE(pktSkb);
3557 }
3558
3559 if ((ar->arConnected == true) || bypasswmi) {
3560 if (!flushing) {
3561 /* don't wake the queue if we are flushing, other wise it will just
3562 * keep queueing packets, which will keep failing */
3563 netif_wake_queue(ar->arNetDev);
3564 }
3565 }
3566
3567 if (wakeEvent) {
3568 wake_up(&arEvent);
3569 }
3570
3571}
3572
3573sta_t *
3574ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr)
3575{
3576 sta_t *conn = NULL;
3577 u8 i, max_conn;
3578
3579 switch(ar->arNetworkType) {
3580 case AP_NETWORK:
3581 max_conn = AP_MAX_NUM_STA;
3582 break;
3583 default:
3584 max_conn=0;
3585 break;
3586 }
3587
3588 for (i = 0; i < max_conn; i++) {
3589 if (IEEE80211_ADDR_EQ(node_addr, ar->sta_list[i].mac)) {
3590 conn = &ar->sta_list[i];
3591 break;
3592 }
3593 }
3594
3595 return conn;
3596}
3597
3598sta_t *ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid)
3599{
3600 sta_t *conn = NULL;
3601 u8 ctr;
3602
3603 for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
3604 if (ar->sta_list[ctr].aid == aid) {
3605 conn = &ar->sta_list[ctr];
3606 break;
3607 }
3608 }
3609 return conn;
3610}
3611
3612/*
3613 * Receive event handler. This is called by HTC when a packet is received
3614 */
3615int pktcount;
3616static void
3617ar6000_rx(void *Context, struct htc_packet *pPacket)
3618{
3619 struct ar6_softc *ar = (struct ar6_softc *)Context;
3620 struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext;
3621 int minHdrLen;
3622 u8 containsDot11Hdr = 0;
3623 int status = pPacket->Status;
3624 HTC_ENDPOINT_ID ept = pPacket->Endpoint;
3625
3626 A_ASSERT((status) ||
3627 (pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN)));
3628
3629 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx ar=0x%lx eid=%d, skb=0x%lx, data=0x%lx, len=0x%x status:%d",
3630 (unsigned long)ar, ept, (unsigned long)skb, (unsigned long)pPacket->pBuffer,
3631 pPacket->ActualLength, status));
3632 if (status) {
3633 if (status != A_ECANCELED) {
3634 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("RX ERR (%d) \n",status));
3635 }
3636 }
3637
3638 /* take lock to protect buffer counts
3639 * and adaptive power throughput state */
3640 AR6000_SPIN_LOCK(&ar->arLock, 0);
3641
3642 if (!status) {
3643 AR6000_STAT_INC(ar, rx_packets);
3644 ar->arNetStats.rx_bytes += pPacket->ActualLength;
3645#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3646 aptcTR.bytesReceived += a_netbuf_to_len(skb);
3647 applyAPTCHeuristics(ar);
3648#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3649
3650 A_NETBUF_PUT(skb, pPacket->ActualLength + HTC_HEADER_LEN);
3651 A_NETBUF_PULL(skb, HTC_HEADER_LEN);
3652
3653#ifdef DEBUG
3654 if (debugdriver >= 2) {
3655 ar6000_dump_skb(skb);
3656 }
3657#endif /* DEBUG */
3658 }
3659
3660 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3661
3662 skb->dev = ar->arNetDev;
3663 if (status) {
3664 AR6000_STAT_INC(ar, rx_errors);
3665 A_NETBUF_FREE(skb);
3666 } else if (ar->arWmiEnabled == true) {
3667 if (ept == ar->arControlEp) {
3668 /*
3669 * this is a wmi control msg
3670 */
3671#ifdef CONFIG_PM
3672 ar6000_check_wow_status(ar, skb, true);
3673#endif /* CONFIG_PM */
3674 wmi_control_rx(ar->arWmi, skb);
3675 } else {
3676 WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb);
3677 bool is_amsdu;
3678 u8 tid;
3679
3680 /*
3681 * This check can be removed if after a while we do not
3682 * see the warning. For now we leave it to ensure
3683 * we drop these frames accordingly in case the
3684 * target generates them for some reason. These
3685 * were used for an internal PAL but that's not
3686 * used or supported anymore. These frames should
3687 * not come up from the target.
3688 */
3689 if (WARN_ON(WMI_DATA_HDR_GET_DATA_TYPE(dhdr) ==
3690 WMI_DATA_HDR_DATA_TYPE_ACL)) {
3691 AR6000_STAT_INC(ar, rx_errors);
3692 A_NETBUF_FREE(skb);
3693 return;
3694 }
3695
3696#ifdef CONFIG_PM
3697 ar6000_check_wow_status(ar, NULL, false);
3698#endif /* CONFIG_PM */
3699 /*
3700 * this is a wmi data packet
3701 */
3702 // NWF
3703
3704 if (processDot11Hdr) {
3705 minHdrLen = sizeof(WMI_DATA_HDR) + sizeof(struct ieee80211_frame) + sizeof(ATH_LLC_SNAP_HDR);
3706 } else {
3707 minHdrLen = sizeof (WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) +
3708 sizeof(ATH_LLC_SNAP_HDR);
3709 }
3710
3711 /* In the case of AP mode we may receive NULL data frames
3712 * that do not have LLC hdr. They are 16 bytes in size.
3713 * Allow these frames in the AP mode.
3714 * ACL data frames don't follow ethernet frame bounds for
3715 * min length
3716 */
3717 if (ar->arNetworkType != AP_NETWORK &&
3718 ((pPacket->ActualLength < minHdrLen) ||
3719 (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)))
3720 {
3721 /*
3722 * packet is too short or too long
3723 */
3724 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("TOO SHORT or TOO LONG\n"));
3725 AR6000_STAT_INC(ar, rx_errors);
3726 AR6000_STAT_INC(ar, rx_length_errors);
3727 A_NETBUF_FREE(skb);
3728 } else {
3729 u16 seq_no;
3730 u8 meta_type;
3731
3732#if 0
3733 /* Access RSSI values here */
3734 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("RSSI %d\n",
3735 ((WMI_DATA_HDR *) A_NETBUF_DATA(skb))->rssi));
3736#endif
3737 /* Get the Power save state of the STA */
3738 if (ar->arNetworkType == AP_NETWORK) {
3739 sta_t *conn = NULL;
3740 u8 psState=0,prevPsState;
3741 ATH_MAC_HDR *datap=NULL;
3742 u16 offset;
3743
3744 meta_type = WMI_DATA_HDR_GET_META(dhdr);
3745
3746 psState = (((WMI_DATA_HDR *)A_NETBUF_DATA(skb))->info
3747 >> WMI_DATA_HDR_PS_SHIFT) & WMI_DATA_HDR_PS_MASK;
3748
3749 offset = sizeof(WMI_DATA_HDR);
3750
3751 switch (meta_type) {
3752 case 0:
3753 break;
3754 case WMI_META_VERSION_1:
3755 offset += sizeof(WMI_RX_META_V1);
3756 break;
3757 case WMI_META_VERSION_2:
3758 offset += sizeof(WMI_RX_META_V2);
3759 break;
3760 default:
3761 break;
3762 }
3763
3764 datap = (ATH_MAC_HDR *)(A_NETBUF_DATA(skb)+offset);
3765 conn = ieee80211_find_conn(ar, datap->srcMac);
3766
3767 if (conn) {
3768 /* if there is a change in PS state of the STA,
3769 * take appropriate steps.
3770 * 1. If Sleep-->Awake, flush the psq for the STA
3771 * Clear the PVB for the STA.
3772 * 2. If Awake-->Sleep, Starting queueing frames
3773 * the STA.
3774 */
3775 prevPsState = STA_IS_PWR_SLEEP(conn);
3776 if (psState) {
3777 STA_SET_PWR_SLEEP(conn);
3778 } else {
3779 STA_CLR_PWR_SLEEP(conn);
3780 }
3781
3782 if (prevPsState ^ STA_IS_PWR_SLEEP(conn)) {
3783
3784 if (!STA_IS_PWR_SLEEP(conn)) {
3785
3786 A_MUTEX_LOCK(&conn->psqLock);
3787 while (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
3788 struct sk_buff *skb=NULL;
3789
3790 skb = A_NETBUF_DEQUEUE(&conn->psq);
3791 A_MUTEX_UNLOCK(&conn->psqLock);
3792 ar6000_data_tx(skb,ar->arNetDev);
3793 A_MUTEX_LOCK(&conn->psqLock);
3794 }
3795 A_MUTEX_UNLOCK(&conn->psqLock);
3796 /* Clear the PVB for this STA */
3797 wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
3798 }
3799 }
3800 } else {
3801 /* This frame is from a STA that is not associated*/
3802 A_ASSERT(false);
3803 }
3804
3805 /* Drop NULL data frames here */
3806 if((pPacket->ActualLength < minHdrLen) ||
3807 (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)) {
3808 A_NETBUF_FREE(skb);
3809 goto rx_done;
3810 }
3811 }
3812
3813 is_amsdu = WMI_DATA_HDR_IS_AMSDU(dhdr) ? true : false;
3814 tid = WMI_DATA_HDR_GET_UP(dhdr);
3815 seq_no = WMI_DATA_HDR_GET_SEQNO(dhdr);
3816 meta_type = WMI_DATA_HDR_GET_META(dhdr);
3817 containsDot11Hdr = WMI_DATA_HDR_GET_DOT11(dhdr);
3818
3819 wmi_data_hdr_remove(ar->arWmi, skb);
3820
3821 switch (meta_type) {
3822 case WMI_META_VERSION_1:
3823 {
3824 WMI_RX_META_V1 *pMeta = (WMI_RX_META_V1 *)A_NETBUF_DATA(skb);
3825 A_PRINTF("META %d %d %d %d %x\n", pMeta->status, pMeta->rix, pMeta->rssi, pMeta->channel, pMeta->flags);
3826 A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V1));
3827 break;
3828 }
3829 case WMI_META_VERSION_2:
3830 {
3831 WMI_RX_META_V2 *pMeta = (WMI_RX_META_V2 *)A_NETBUF_DATA(skb);
3832 if(pMeta->csumFlags & 0x1){
3833 skb->ip_summed=CHECKSUM_COMPLETE;
3834 skb->csum=(pMeta->csum);
3835 }
3836 A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V2));
3837 break;
3838 }
3839 default:
3840 break;
3841 }
3842
3843 A_ASSERT(status == 0);
3844
3845 /* NWF: print the 802.11 hdr bytes */
3846 if(containsDot11Hdr) {
3847 status = wmi_dot11_hdr_remove(ar->arWmi,skb);
3848 } else if(!is_amsdu) {
3849 status = wmi_dot3_2_dix(skb);
3850 }
3851
3852 if (status) {
3853 /* Drop frames that could not be processed (lack of memory, etc.) */
3854 A_NETBUF_FREE(skb);
3855 goto rx_done;
3856 }
3857
3858 if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) {
3859 if (ar->arNetworkType == AP_NETWORK) {
3860 struct sk_buff *skb1 = NULL;
3861 ATH_MAC_HDR *datap;
3862
3863 datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
3864 if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
3865 /* Bcast/Mcast frames should be sent to the OS
3866 * stack as well as on the air.
3867 */
3868 skb1 = skb_copy(skb,GFP_ATOMIC);
3869 } else {
3870 /* Search for a connected STA with dstMac as
3871 * the Mac address. If found send the frame to
3872 * it on the air else send the frame up the
3873 * stack
3874 */
3875 sta_t *conn = NULL;
3876 conn = ieee80211_find_conn(ar, datap->dstMac);
3877
3878 if (conn && ar->intra_bss) {
3879 skb1 = skb;
3880 skb = NULL;
3881 } else if(conn && !ar->intra_bss) {
3882 A_NETBUF_FREE(skb);
3883 skb = NULL;
3884 }
3885 }
3886 if (skb1) {
3887 ar6000_data_tx(skb1, ar->arNetDev);
3888 }
3889 }
3890 }
3891 aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no, is_amsdu, (void **)&skb);
3892 ar6000_deliver_frames_to_nw_stack((void *) ar->arNetDev, (void *)skb);
3893 }
3894 }
3895 } else {
3896 if (EPPING_ALIGNMENT_PAD > 0) {
3897 A_NETBUF_PULL(skb, EPPING_ALIGNMENT_PAD);
3898 }
3899 ar6000_deliver_frames_to_nw_stack((void *)ar->arNetDev, (void *)skb);
3900 }
3901
3902rx_done:
3903
3904 return;
3905}
3906
3907static void
3908ar6000_deliver_frames_to_nw_stack(void *dev, void *osbuf)
3909{
3910 struct sk_buff *skb = (struct sk_buff *)osbuf;
3911
3912 if(skb) {
3913 skb->dev = dev;
3914 if ((skb->dev->flags & IFF_UP) == IFF_UP) {
3915#ifdef CONFIG_PM
3916 ar6000_check_wow_status((struct ar6_softc *)ar6k_priv(dev), skb, false);
3917#endif /* CONFIG_PM */
3918 skb->protocol = eth_type_trans(skb, skb->dev);
3919 /*
3920 * If this routine is called on a ISR (Hard IRQ) or DSR (Soft IRQ)
3921 * or tasklet use the netif_rx to deliver the packet to the stack
3922 * netif_rx will queue the packet onto the receive queue and mark
3923 * the softirq thread has a pending action to complete. Kernel will
3924 * schedule the softIrq kernel thread after processing the DSR.
3925 *
3926 * If this routine is called on a process context, use netif_rx_ni
3927 * which will schedle the softIrq kernel thread after queuing the packet.
3928 */
3929 if (in_interrupt()) {
3930 netif_rx(skb);
3931 } else {
3932 netif_rx_ni(skb);
3933 }
3934 } else {
3935 A_NETBUF_FREE(skb);
3936 }
3937 }
3938}
3939
3940#if 0
3941static void
3942ar6000_deliver_frames_to_bt_stack(void *dev, void *osbuf)
3943{
3944 struct sk_buff *skb = (struct sk_buff *)osbuf;
3945
3946 if(skb) {
3947 skb->dev = dev;
3948 if ((skb->dev->flags & IFF_UP) == IFF_UP) {
3949 skb->protocol = htons(ETH_P_CONTROL);
3950 netif_rx(skb);
3951 } else {
3952 A_NETBUF_FREE(skb);
3953 }
3954 }
3955}
3956#endif
3957
3958static void
3959ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint)
3960{
3961 struct ar6_softc *ar = (struct ar6_softc *)Context;
3962 void *osBuf;
3963 int RxBuffers;
3964 int buffersToRefill;
3965 struct htc_packet *pPacket;
3966 struct htc_packet_queue queue;
3967
3968 buffersToRefill = (int)AR6000_MAX_RX_BUFFERS -
3969 HTCGetNumRecvBuffers(ar->arHtcTarget, Endpoint);
3970
3971 if (buffersToRefill <= 0) {
3972 /* fast return, nothing to fill */
3973 return;
3974 }
3975
3976 INIT_HTC_PACKET_QUEUE(&queue);
3977
3978 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n",
3979 buffersToRefill, Endpoint));
3980
3981 for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) {
3982 osBuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE);
3983 if (NULL == osBuf) {
3984 break;
3985 }
3986 /* the HTC packet wrapper is at the head of the reserved area
3987 * in the skb */
3988 pPacket = (struct htc_packet *)(A_NETBUF_HEAD(osBuf));
3989 /* set re-fill info */
3990 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_BUFFER_SIZE,Endpoint);
3991 /* add to queue */
3992 HTC_PACKET_ENQUEUE(&queue,pPacket);
3993 }
3994
3995 if (!HTC_QUEUE_EMPTY(&queue)) {
3996 /* add packets */
3997 HTCAddReceivePktMultiple(ar->arHtcTarget, &queue);
3998 }
3999
4000}
4001
4002 /* clean up our amsdu buffer list */
4003static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar)
4004{
4005 struct htc_packet *pPacket;
4006 void *osBuf;
4007
4008 /* empty AMSDU buffer queue and free OS bufs */
4009 while (true) {
4010
4011 AR6000_SPIN_LOCK(&ar->arLock, 0);
4012 pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
4013 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4014
4015 if (NULL == pPacket) {
4016 break;
4017 }
4018
4019 osBuf = pPacket->pPktContext;
4020 if (NULL == osBuf) {
4021 A_ASSERT(false);
4022 break;
4023 }
4024
4025 A_NETBUF_FREE(osBuf);
4026 }
4027
4028}
4029
4030
4031 /* refill the amsdu buffer list */
4032static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count)
4033{
4034 struct htc_packet *pPacket;
4035 void *osBuf;
4036
4037 while (Count > 0) {
4038 osBuf = A_NETBUF_ALLOC(AR6000_AMSDU_BUFFER_SIZE);
4039 if (NULL == osBuf) {
4040 break;
4041 }
4042 /* the HTC packet wrapper is at the head of the reserved area
4043 * in the skb */
4044 pPacket = (struct htc_packet *)(A_NETBUF_HEAD(osBuf));
4045 /* set re-fill info */
4046 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_AMSDU_BUFFER_SIZE,0);
4047
4048 AR6000_SPIN_LOCK(&ar->arLock, 0);
4049 /* put it in the list */
4050 HTC_PACKET_ENQUEUE(&ar->amsdu_rx_buffer_queue,pPacket);
4051 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4052 Count--;
4053 }
4054
4055}
4056
4057 /* callback to allocate a large receive buffer for a pending packet. This function is called when
4058 * an HTC packet arrives whose length exceeds a threshold value
4059 *
4060 * We use a pre-allocated list of buffers of maximum AMSDU size (4K). Under linux it is more optimal to
4061 * keep the allocation size the same to optimize cached-slab allocations.
4062 *
4063 * */
4064static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length)
4065{
4066 struct htc_packet *pPacket = NULL;
4067 struct ar6_softc *ar = (struct ar6_softc *)Context;
4068 int refillCount = 0;
4069
4070 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_alloc_amsdu_rxbuf: eid=%d, Length:%d\n",Endpoint,Length));
4071
4072 do {
4073
4074 if (Length <= AR6000_BUFFER_SIZE) {
4075 /* shouldn't be getting called on normal sized packets */
4076 A_ASSERT(false);
4077 break;
4078 }
4079
4080 if (Length > AR6000_AMSDU_BUFFER_SIZE) {
4081 A_ASSERT(false);
4082 break;
4083 }
4084
4085 AR6000_SPIN_LOCK(&ar->arLock, 0);
4086 /* allocate a packet from the list */
4087 pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
4088 /* see if we need to refill again */
4089 refillCount = AR6000_MAX_AMSDU_RX_BUFFERS - HTC_PACKET_QUEUE_DEPTH(&ar->amsdu_rx_buffer_queue);
4090 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4091
4092 if (NULL == pPacket) {
4093 break;
4094 }
4095 /* set actual endpoint ID */
4096 pPacket->Endpoint = Endpoint;
4097
4098 } while (false);
4099
4100 if (refillCount >= AR6000_AMSDU_REFILL_THRESHOLD) {
4101 ar6000_refill_amsdu_rxbufs(ar,refillCount);
4102 }
4103
4104 return pPacket;
4105}
4106
4107static void
4108ar6000_set_multicast_list(struct net_device *dev)
4109{
4110 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: Multicast filter not supported\n"));
4111}
4112
4113static struct net_device_stats *
4114ar6000_get_stats(struct net_device *dev)
4115{
4116 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
4117 return &ar->arNetStats;
4118}
4119
4120void
4121ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver)
4122{
4123 struct ar6_softc *ar = (struct ar6_softc *)devt;
4124 struct net_device *dev = ar->arNetDev;
4125
4126 memcpy(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN);
4127 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
4128 dev->dev_addr[0], dev->dev_addr[1],
4129 dev->dev_addr[2], dev->dev_addr[3],
4130 dev->dev_addr[4], dev->dev_addr[5]));
4131
4132 ar->arPhyCapability = phyCap;
4133 ar->arVersion.wlan_ver = sw_ver;
4134 ar->arVersion.abi_ver = abi_ver;
4135
4136 snprintf(ar->wdev->wiphy->fw_version, sizeof(ar->wdev->wiphy->fw_version),
4137 "%u:%u:%u:%u",
4138 (ar->arVersion.wlan_ver & 0xf0000000) >> 28,
4139 (ar->arVersion.wlan_ver & 0x0f000000) >> 24,
4140 (ar->arVersion.wlan_ver & 0x00ff0000) >> 16,
4141 (ar->arVersion.wlan_ver & 0x0000ffff));
4142
4143 /* Indicate to the waiting thread that the ready event was received */
4144 ar->arWmiReady = true;
4145 wake_up(&arEvent);
4146}
4147
4148void ar6000_install_static_wep_keys(struct ar6_softc *ar)
4149{
4150 u8 index;
4151 u8 keyUsage;
4152
4153 for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
4154 if (ar->arWepKeyList[index].arKeyLen) {
4155 keyUsage = GROUP_USAGE;
4156 if (index == ar->arDefTxKeyIndex) {
4157 keyUsage |= TX_USAGE;
4158 }
4159 wmi_addKey_cmd(ar->arWmi,
4160 index,
4161 WEP_CRYPT,
4162 keyUsage,
4163 ar->arWepKeyList[index].arKeyLen,
4164 NULL,
4165 ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
4166 NO_SYNC_WMIFLAG);
4167 }
4168 }
4169}
4170
4171void
4172add_new_sta(struct ar6_softc *ar, u8 *mac, u16 aid, u8 *wpaie,
4173 u8 ielen, u8 keymgmt, u8 ucipher, u8 auth)
4174{
4175 u8 free_slot=aid-1;
4176
4177 memcpy(ar->sta_list[free_slot].mac, mac, ATH_MAC_LEN);
4178 memcpy(ar->sta_list[free_slot].wpa_ie, wpaie, ielen);
4179 ar->sta_list[free_slot].aid = aid;
4180 ar->sta_list[free_slot].keymgmt = keymgmt;
4181 ar->sta_list[free_slot].ucipher = ucipher;
4182 ar->sta_list[free_slot].auth = auth;
4183 ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
4184 ar->arAPStats.sta[free_slot].aid = aid;
4185}
4186
4187void
4188ar6000_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid,
4189 u16 listenInterval, u16 beaconInterval,
4190 NETWORK_TYPE networkType, u8 beaconIeLen,
4191 u8 assocReqLen, u8 assocRespLen,
4192 u8 *assocInfo)
4193{
4194 union iwreq_data wrqu;
4195 int i, beacon_ie_pos, assoc_resp_ie_pos, assoc_req_ie_pos;
4196 static const char *tag1 = "ASSOCINFO(ReqIEs=";
4197 static const char *tag2 = "ASSOCRESPIE=";
4198 static const char *beaconIetag = "BEACONIE=";
4199 char buf[WMI_CONTROL_MSG_MAX_LEN * 2 + strlen(tag1) + 1];
4200 char *pos;
4201 u8 key_op_ctrl;
4202 unsigned long flags;
4203 struct ieee80211req_key *ik;
4204 CRYPTO_TYPE keyType = NONE_CRYPT;
4205
4206 if(ar->arNetworkType & AP_NETWORK) {
4207 struct net_device *dev = ar->arNetDev;
4208 if(memcmp(dev->dev_addr, bssid, ATH_MAC_LEN)==0) {
4209 ar->arACS = channel;
4210 ik = &ar->ap_mode_bkey;
4211
4212 switch(ar->arAuthMode) {
4213 case NONE_AUTH:
4214 if(ar->arPairwiseCrypto == WEP_CRYPT) {
4215 ar6000_install_static_wep_keys(ar);
4216 }
4217#ifdef WAPI_ENABLE
4218 else if(ar->arPairwiseCrypto == WAPI_CRYPT) {
4219 ap_set_wapi_key(ar, ik);
4220 }
4221#endif
4222 break;
4223 case WPA_PSK_AUTH:
4224 case WPA2_PSK_AUTH:
4225 case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
4226 switch (ik->ik_type) {
4227 case IEEE80211_CIPHER_TKIP:
4228 keyType = TKIP_CRYPT;
4229 break;
4230 case IEEE80211_CIPHER_AES_CCM:
4231 keyType = AES_CRYPT;
4232 break;
4233 default:
4234 goto skip_key;
4235 }
4236 wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, GROUP_USAGE,
4237 ik->ik_keylen, (u8 *)&ik->ik_keyrsc,
4238 ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
4239 SYNC_BOTH_WMIFLAG);
4240
4241 break;
4242 }
4243skip_key:
4244 ar->arConnected = true;
4245 return;
4246 }
4247
4248 A_PRINTF("NEW STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n "
4249 " AID=%d \n", bssid[0], bssid[1], bssid[2],
4250 bssid[3], bssid[4], bssid[5], channel);
4251 switch ((listenInterval>>8)&0xFF) {
4252 case OPEN_AUTH:
4253 A_PRINTF("AUTH: OPEN\n");
4254 break;
4255 case SHARED_AUTH:
4256 A_PRINTF("AUTH: SHARED\n");
4257 break;
4258 default:
4259 A_PRINTF("AUTH: Unknown\n");
4260 break;
4261 }
4262 switch (listenInterval&0xFF) {
4263 case WPA_PSK_AUTH:
4264 A_PRINTF("KeyMgmt: WPA-PSK\n");
4265 break;
4266 case WPA2_PSK_AUTH:
4267 A_PRINTF("KeyMgmt: WPA2-PSK\n");
4268 break;
4269 default:
4270 A_PRINTF("KeyMgmt: NONE\n");
4271 break;
4272 }
4273 switch (beaconInterval) {
4274 case AES_CRYPT:
4275 A_PRINTF("Cipher: AES\n");
4276 break;
4277 case TKIP_CRYPT:
4278 A_PRINTF("Cipher: TKIP\n");
4279 break;
4280 case WEP_CRYPT:
4281 A_PRINTF("Cipher: WEP\n");
4282 break;
4283#ifdef WAPI_ENABLE
4284 case WAPI_CRYPT:
4285 A_PRINTF("Cipher: WAPI\n");
4286 break;
4287#endif
4288 default:
4289 A_PRINTF("Cipher: NONE\n");
4290 break;
4291 }
4292
4293 add_new_sta(ar, bssid, channel /*aid*/,
4294 assocInfo /* WPA IE */, assocRespLen /* IE len */,
4295 listenInterval&0xFF /* Keymgmt */, beaconInterval /* cipher */,
4296 (listenInterval>>8)&0xFF /* auth alg */);
4297
4298 /* Send event to application */
4299 A_MEMZERO(&wrqu, sizeof(wrqu));
4300 memcpy(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
4301 wireless_send_event(ar->arNetDev, IWEVREGISTERED, &wrqu, NULL);
4302 /* In case the queue is stopped when we switch modes, this will
4303 * wake it up
4304 */
4305 netif_wake_queue(ar->arNetDev);
4306 return;
4307 }
4308
4309 ar6k_cfg80211_connect_event(ar, channel, bssid,
4310 listenInterval, beaconInterval,
4311 networkType, beaconIeLen,
4312 assocReqLen, assocRespLen,
4313 assocInfo);
4314
4315 memcpy(ar->arBssid, bssid, sizeof(ar->arBssid));
4316 ar->arBssChannel = channel;
4317
4318 A_PRINTF("AR6000 connected event on freq %d ", channel);
4319 A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
4320 " listenInterval=%d, beaconInterval = %d, beaconIeLen = %d assocReqLen=%d"
4321 " assocRespLen =%d\n",
4322 bssid[0], bssid[1], bssid[2],
4323 bssid[3], bssid[4], bssid[5],
4324 listenInterval, beaconInterval,
4325 beaconIeLen, assocReqLen, assocRespLen);
4326 if (networkType & ADHOC_NETWORK) {
4327 if (networkType & ADHOC_CREATOR) {
4328 A_PRINTF("Network: Adhoc (Creator)\n");
4329 } else {
4330 A_PRINTF("Network: Adhoc (Joiner)\n");
4331 }
4332 } else {
4333 A_PRINTF("Network: Infrastructure\n");
4334 }
4335
4336 if ((ar->arNetworkType == INFRA_NETWORK)) {
4337 wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB);
4338 }
4339
4340 if (beaconIeLen && (sizeof(buf) > (9 + beaconIeLen * 2))) {
4341 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nBeaconIEs= "));
4342
4343 beacon_ie_pos = 0;
4344 A_MEMZERO(buf, sizeof(buf));
4345 sprintf(buf, "%s", beaconIetag);
4346 pos = buf + 9;
4347 for (i = beacon_ie_pos; i < beacon_ie_pos + beaconIeLen; i++) {
4348 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4349 sprintf(pos, "%2.2x", assocInfo[i]);
4350 pos += 2;
4351 }
4352 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4353
4354 A_MEMZERO(&wrqu, sizeof(wrqu));
4355 wrqu.data.length = strlen(buf);
4356 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4357 }
4358
4359 if (assocRespLen && (sizeof(buf) > (12 + (assocRespLen * 2))))
4360 {
4361 assoc_resp_ie_pos = beaconIeLen + assocReqLen +
4362 sizeof(u16) + /* capinfo*/
4363 sizeof(u16) + /* status Code */
4364 sizeof(u16) ; /* associd */
4365 A_MEMZERO(buf, sizeof(buf));
4366 sprintf(buf, "%s", tag2);
4367 pos = buf + 12;
4368 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocRespIEs= "));
4369 /*
4370 * The Association Response Frame w.o. the WLAN header is delivered to
4371 * the host, so skip over to the IEs
4372 */
4373 for (i = assoc_resp_ie_pos; i < assoc_resp_ie_pos + assocRespLen - 6; i++)
4374 {
4375 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4376 sprintf(pos, "%2.2x", assocInfo[i]);
4377 pos += 2;
4378 }
4379 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4380
4381 A_MEMZERO(&wrqu, sizeof(wrqu));
4382 wrqu.data.length = strlen(buf);
4383 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4384 }
4385
4386 if (assocReqLen && (sizeof(buf) > (17 + (assocReqLen * 2)))) {
4387 /*
4388 * assoc Request includes capability and listen interval. Skip these.
4389 */
4390 assoc_req_ie_pos = beaconIeLen +
4391 sizeof(u16) + /* capinfo*/
4392 sizeof(u16); /* listen interval */
4393
4394 A_MEMZERO(buf, sizeof(buf));
4395 sprintf(buf, "%s", tag1);
4396 pos = buf + 17;
4397 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AssocReqIEs= "));
4398 for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) {
4399 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4400 sprintf(pos, "%2.2x", assocInfo[i]);
4401 pos += 2;
4402 }
4403 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4404
4405 A_MEMZERO(&wrqu, sizeof(wrqu));
4406 wrqu.data.length = strlen(buf);
4407 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4408 }
4409
4410 if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN &&
4411 ar->user_saved_keys.keyOk == true)
4412 {
4413 key_op_ctrl = KEY_OP_VALID_MASK & ~KEY_OP_INIT_TSC;
4414
4415 if (ar->user_key_ctrl & AR6000_USER_SETKEYS_RSC_UNCHANGED) {
4416 key_op_ctrl &= ~KEY_OP_INIT_RSC;
4417 } else {
4418 key_op_ctrl |= KEY_OP_INIT_RSC;
4419 }
4420 ar6000_reinstall_keys(ar, key_op_ctrl);
4421 }
4422
4423 netif_wake_queue(ar->arNetDev);
4424
4425 /* Update connect & link status atomically */
4426 spin_lock_irqsave(&ar->arLock, flags);
4427 ar->arConnected = true;
4428 ar->arConnectPending = false;
4429 netif_carrier_on(ar->arNetDev);
4430 spin_unlock_irqrestore(&ar->arLock, flags);
4431 /* reset the rx aggr state */
4432 aggr_reset_state(ar->aggr_cntxt);
4433 reconnect_flag = 0;
4434
4435 A_MEMZERO(&wrqu, sizeof(wrqu));
4436 memcpy(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN);
4437 wrqu.addr.sa_family = ARPHRD_ETHER;
4438 wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
4439 if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable) {
4440 A_MEMZERO(ar->arNodeMap, sizeof(ar->arNodeMap));
4441 ar->arNodeNum = 0;
4442 ar->arNexEpId = ENDPOINT_2;
4443 }
4444 if (!ar->arUserBssFilter) {
4445 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4446 }
4447
4448}
4449
4450void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num)
4451{
4452 A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1));
4453 ar->arNumDataEndPts = num;
4454}
4455
4456void
4457sta_cleanup(struct ar6_softc *ar, u8 i)
4458{
4459 struct sk_buff *skb;
4460
4461 /* empty the queued pkts in the PS queue if any */
4462 A_MUTEX_LOCK(&ar->sta_list[i].psqLock);
4463 while (!A_NETBUF_QUEUE_EMPTY(&ar->sta_list[i].psq)) {
4464 skb = A_NETBUF_DEQUEUE(&ar->sta_list[i].psq);
4465 A_NETBUF_FREE(skb);
4466 }
4467 A_MUTEX_UNLOCK(&ar->sta_list[i].psqLock);
4468
4469 /* Zero out the state fields */
4470 A_MEMZERO(&ar->arAPStats.sta[ar->sta_list[i].aid-1], sizeof(WMI_PER_STA_STAT));
4471 A_MEMZERO(&ar->sta_list[i].mac, ATH_MAC_LEN);
4472 A_MEMZERO(&ar->sta_list[i].wpa_ie, IEEE80211_MAX_IE);
4473 ar->sta_list[i].aid = 0;
4474 ar->sta_list[i].flags = 0;
4475
4476 ar->sta_list_index = ar->sta_list_index & ~(1 << i);
4477
4478}
4479
4480u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason)
4481{
4482 u8 i, removed=0;
4483
4484 if(IS_MAC_NULL(mac)) {
4485 return removed;
4486 }
4487
4488 if(IS_MAC_BCAST(mac)) {
4489 A_PRINTF("DEL ALL STA\n");
4490 for(i=0; i < AP_MAX_NUM_STA; i++) {
4491 if(!IS_MAC_NULL(ar->sta_list[i].mac)) {
4492 sta_cleanup(ar, i);
4493 removed = 1;
4494 }
4495 }
4496 } else {
4497 for(i=0; i < AP_MAX_NUM_STA; i++) {
4498 if(memcmp(ar->sta_list[i].mac, mac, ATH_MAC_LEN)==0) {
4499 A_PRINTF("DEL STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
4500 " aid=%d REASON=%d\n", mac[0], mac[1], mac[2],
4501 mac[3], mac[4], mac[5], ar->sta_list[i].aid, reason);
4502
4503 sta_cleanup(ar, i);
4504 removed = 1;
4505 break;
4506 }
4507 }
4508 }
4509 return removed;
4510}
4511
4512void
4513ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, u8 *bssid,
4514 u8 assocRespLen, u8 *assocInfo, u16 protocolReasonStatus)
4515{
4516 u8 i;
4517 unsigned long flags;
4518 union iwreq_data wrqu;
4519
4520 if(ar->arNetworkType & AP_NETWORK) {
4521 union iwreq_data wrqu;
4522 struct sk_buff *skb;
4523
4524 if(!remove_sta(ar, bssid, protocolReasonStatus)) {
4525 return;
4526 }
4527
4528 /* If there are no more associated STAs, empty the mcast PS q */
4529 if (ar->sta_list_index == 0) {
4530 A_MUTEX_LOCK(&ar->mcastpsqLock);
4531 while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
4532 skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
4533 A_NETBUF_FREE(skb);
4534 }
4535 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
4536
4537 /* Clear the LSB of the BitMapCtl field of the TIM IE */
4538 if (ar->arWmiReady) {
4539 wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
4540 }
4541 }
4542
4543 if(!IS_MAC_BCAST(bssid)) {
4544 /* Send event to application */
4545 A_MEMZERO(&wrqu, sizeof(wrqu));
4546 memcpy(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
4547 wireless_send_event(ar->arNetDev, IWEVEXPIRED, &wrqu, NULL);
4548 }
4549
4550 ar->arConnected = false;
4551 return;
4552 }
4553
4554 ar6k_cfg80211_disconnect_event(ar, reason, bssid,
4555 assocRespLen, assocInfo,
4556 protocolReasonStatus);
4557
4558 /* Send disconnect event to supplicant */
4559 A_MEMZERO(&wrqu, sizeof(wrqu));
4560 wrqu.addr.sa_family = ARPHRD_ETHER;
4561 wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
4562
4563 /* it is necessary to clear the host-side rx aggregation state */
4564 aggr_reset_state(ar->aggr_cntxt);
4565
4566 A_UNTIMEOUT(&ar->disconnect_timer);
4567
4568 A_PRINTF("AR6000 disconnected");
4569 if (bssid[0] || bssid[1] || bssid[2] || bssid[3] || bssid[4] || bssid[5]) {
4570 A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
4571 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
4572 }
4573
4574 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nDisconnect Reason is %d", reason));
4575 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nProtocol Reason/Status Code is %d", protocolReasonStatus));
4576 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocResp Frame = %s",
4577 assocRespLen ? " " : "NULL"));
4578 for (i = 0; i < assocRespLen; i++) {
4579 if (!(i % 0x10)) {
4580 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4581 }
4582 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4583 }
4584 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4585 /*
4586 * If the event is due to disconnect cmd from the host, only they the target
4587 * would stop trying to connect. Under any other condition, target would
4588 * keep trying to connect.
4589 *
4590 */
4591 if( reason == DISCONNECT_CMD)
4592 {
4593 if ((!ar->arUserBssFilter) && (ar->arWmiReady)) {
4594 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4595 }
4596 } else {
4597 ar->arConnectPending = true;
4598 if (((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x11)) ||
4599 ((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x0) && (reconnect_flag == 1))) {
4600 ar->arConnected = true;
4601 return;
4602 }
4603 }
4604
4605 if ((reason == NO_NETWORK_AVAIL) && (ar->arWmiReady))
4606 {
4607 bss_t *pWmiSsidnode = NULL;
4608
4609 /* remove the current associated bssid node */
4610 wmi_free_node (ar->arWmi, bssid);
4611
4612 /*
4613 * In case any other same SSID nodes are present
4614 * remove it, since those nodes also not available now
4615 */
4616 do
4617 {
4618 /*
4619 * Find the nodes based on SSID and remove it
4620 * NOTE :: This case will not work out for Hidden-SSID
4621 */
4622 pWmiSsidnode = wmi_find_Ssidnode (ar->arWmi, ar->arSsid, ar->arSsidLen, false, true);
4623
4624 if (pWmiSsidnode)
4625 {
4626 wmi_free_node (ar->arWmi, pWmiSsidnode->ni_macaddr);
4627 }
4628
4629 } while (pWmiSsidnode);
4630 }
4631
4632 /* Update connect & link status atomically */
4633 spin_lock_irqsave(&ar->arLock, flags);
4634 ar->arConnected = false;
4635 netif_carrier_off(ar->arNetDev);
4636 spin_unlock_irqrestore(&ar->arLock, flags);
4637
4638 if( (reason != CSERV_DISCONNECT) || (reconnect_flag != 1) ) {
4639 reconnect_flag = 0;
4640 }
4641
4642 if (reason != CSERV_DISCONNECT)
4643 {
4644 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
4645 ar->user_key_ctrl = 0;
4646 }
4647
4648 netif_stop_queue(ar->arNetDev);
4649 A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
4650 ar->arBssChannel = 0;
4651 ar->arBeaconInterval = 0;
4652
4653 ar6000_TxDataCleanup(ar);
4654}
4655
4656void
4657ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode)
4658{
4659 A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode);
4660 ar->arRegCode = regCode;
4661}
4662
4663void
4664ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *evt)
4665{
4666 if(evt->status == 0) {
4667 aggr_recv_addba_req_evt(ar->aggr_cntxt, evt->tid, evt->st_seq_no, evt->win_sz);
4668 }
4669}
4670
4671void
4672ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *evt)
4673{
4674 A_PRINTF("ADDBA RESP. tid %d status %d, sz %d\n", evt->tid, evt->status, evt->amsdu_sz);
4675 if(evt->status == 0) {
4676 }
4677}
4678
4679void
4680ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *evt)
4681{
4682 aggr_recv_delba_req_evt(ar->aggr_cntxt, evt->tid);
4683}
4684
4685void register_pal_cb(ar6k_pal_config_t *palConfig_p)
4686{
4687 ar6k_pal_config_g = *palConfig_p;
4688}
4689
4690void
4691ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd)
4692{
4693 void *osbuf = NULL;
4694 s8 i;
4695 u8 size, *buf;
4696 int ret = 0;
4697
4698 size = cmd->evt_buf_sz + 4;
4699 osbuf = A_NETBUF_ALLOC(size);
4700 if (osbuf == NULL) {
4701 ret = A_NO_MEMORY;
4702 A_PRINTF("Error in allocating netbuf \n");
4703 return;
4704 }
4705
4706 A_NETBUF_PUT(osbuf, size);
4707 buf = (u8 *)A_NETBUF_DATA(osbuf);
4708 /* First 2-bytes carry HCI event/ACL data type
4709 * the next 2 are free
4710 */
4711 *((short *)buf) = WMI_HCI_EVENT_EVENTID;
4712 buf += sizeof(int);
4713 memcpy(buf, cmd->buf, cmd->evt_buf_sz);
4714
4715 ar6000_deliver_frames_to_nw_stack(ar->arNetDev, osbuf);
4716 if(loghci) {
4717 A_PRINTF_LOG("HCI Event From PAL <-- \n");
4718 for(i = 0; i < cmd->evt_buf_sz; i++) {
4719 A_PRINTF_LOG("0x%02x ", cmd->buf[i]);
4720 if((i % 10) == 0) {
4721 A_PRINTF_LOG("\n");
4722 }
4723 }
4724 A_PRINTF_LOG("\n");
4725 A_PRINTF_LOG("==================================\n");
4726 }
4727}
4728
4729void
4730ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, WMI_NEIGHBOR_INFO *info)
4731{
4732#if WIRELESS_EXT >= 18
4733 struct iw_pmkid_cand *pmkcand;
4734#else /* WIRELESS_EXT >= 18 */
4735 static const char *tag = "PRE-AUTH";
4736 char buf[128];
4737#endif /* WIRELESS_EXT >= 18 */
4738
4739 union iwreq_data wrqu;
4740 int i;
4741
4742 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("AR6000 Neighbor Report Event\n"));
4743 for (i=0; i < numAps; info++, i++) {
4744 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
4745 info->bssid[0], info->bssid[1], info->bssid[2],
4746 info->bssid[3], info->bssid[4], info->bssid[5]));
4747 if (info->bssFlags & WMI_PREAUTH_CAPABLE_BSS) {
4748 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("preauth-cap"));
4749 }
4750 if (info->bssFlags & WMI_PMKID_VALID_BSS) {
4751 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,(" pmkid-valid\n"));
4752 continue; /* we skip bss if the pmkid is already valid */
4753 }
4754 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("\n"));
4755 A_MEMZERO(&wrqu, sizeof(wrqu));
4756#if WIRELESS_EXT >= 18
4757 pmkcand = A_MALLOC_NOWAIT(sizeof(struct iw_pmkid_cand));
4758 A_MEMZERO(pmkcand, sizeof(struct iw_pmkid_cand));
4759 pmkcand->index = i;
4760 pmkcand->flags = info->bssFlags;
4761 memcpy(pmkcand->bssid.sa_data, info->bssid, ATH_MAC_LEN);
4762 wrqu.data.length = sizeof(struct iw_pmkid_cand);
4763 wireless_send_event(ar->arNetDev, IWEVPMKIDCAND, &wrqu, (char *)pmkcand);
4764 kfree(pmkcand);
4765#else /* WIRELESS_EXT >= 18 */
4766 snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
4767 tag,
4768 info->bssid[0], info->bssid[1], info->bssid[2],
4769 info->bssid[3], info->bssid[4], info->bssid[5],
4770 i, info->bssFlags);
4771 wrqu.data.length = strlen(buf);
4772 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4773#endif /* WIRELESS_EXT >= 18 */
4774 }
4775}
4776
4777void
4778ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast)
4779{
4780 static const char *tag = "MLME-MICHAELMICFAILURE.indication";
4781 char buf[128];
4782 union iwreq_data wrqu;
4783
4784 /*
4785 * For AP case, keyid will have aid of STA which sent pkt with
4786 * MIC error. Use this aid to get MAC & send it to hostapd.
4787 */
4788 if (ar->arNetworkType == AP_NETWORK) {
4789 sta_t *s = ieee80211_find_conn_for_aid(ar, (keyid >> 2));
4790 if(!s){
4791 A_PRINTF("AP TKIP MIC error received from Invalid aid / STA not found =%d\n", keyid);
4792 return;
4793 }
4794 A_PRINTF("AP TKIP MIC error received from aid=%d\n", keyid);
4795 snprintf(buf,sizeof(buf), "%s addr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
4796 tag, s->mac[0],s->mac[1],s->mac[2],s->mac[3],s->mac[4],s->mac[5]);
4797 } else {
4798
4799 ar6k_cfg80211_tkip_micerr_event(ar, keyid, ismcast);
4800
4801 A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n",
4802 keyid & 0x3, ismcast ? "multi": "uni");
4803 snprintf(buf, sizeof(buf), "%s(keyid=%d %sicast)", tag, keyid & 0x3,
4804 ismcast ? "mult" : "un");
4805 }
4806
4807 memset(&wrqu, 0, sizeof(wrqu));
4808 wrqu.data.length = strlen(buf);
4809 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4810}
4811
4812void
4813ar6000_scanComplete_event(struct ar6_softc *ar, int status)
4814{
4815
4816 ar6k_cfg80211_scanComplete_event(ar, status);
4817
4818 if (!ar->arUserBssFilter) {
4819 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4820 }
4821 if (ar->scan_triggered) {
4822 if (status== 0) {
4823 union iwreq_data wrqu;
4824 A_MEMZERO(&wrqu, sizeof(wrqu));
4825 wireless_send_event(ar->arNetDev, SIOCGIWSCAN, &wrqu, NULL);
4826 }
4827 ar->scan_triggered = 0;
4828 }
4829
4830 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,( "AR6000 scan complete: %d\n", status));
4831}
4832
4833void
4834ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, u32 len)
4835{
4836 u8 ac;
4837
4838 if(ar->arNetworkType == AP_NETWORK) {
4839 WMI_AP_MODE_STAT *p = (WMI_AP_MODE_STAT *)ptr;
4840 WMI_AP_MODE_STAT *ap = &ar->arAPStats;
4841
4842 if (len < sizeof(*p)) {
4843 return;
4844 }
4845
4846 for(ac=0;ac<AP_MAX_NUM_STA;ac++) {
4847 ap->sta[ac].tx_bytes += p->sta[ac].tx_bytes;
4848 ap->sta[ac].tx_pkts += p->sta[ac].tx_pkts;
4849 ap->sta[ac].tx_error += p->sta[ac].tx_error;
4850 ap->sta[ac].tx_discard += p->sta[ac].tx_discard;
4851 ap->sta[ac].rx_bytes += p->sta[ac].rx_bytes;
4852 ap->sta[ac].rx_pkts += p->sta[ac].rx_pkts;
4853 ap->sta[ac].rx_error += p->sta[ac].rx_error;
4854 ap->sta[ac].rx_discard += p->sta[ac].rx_discard;
4855 }
4856
4857 } else {
4858 WMI_TARGET_STATS *pTarget = (WMI_TARGET_STATS *)ptr;
4859 TARGET_STATS *pStats = &ar->arTargetStats;
4860
4861 if (len < sizeof(*pTarget)) {
4862 return;
4863 }
4864
4865 // Update the RSSI of the connected bss.
4866 if (ar->arConnected) {
4867 bss_t *pConnBss = NULL;
4868
4869 pConnBss = wmi_find_node(ar->arWmi,ar->arBssid);
4870 if (pConnBss)
4871 {
4872 pConnBss->ni_rssi = pTarget->cservStats.cs_aveBeacon_rssi;
4873 pConnBss->ni_snr = pTarget->cservStats.cs_aveBeacon_snr;
4874 wmi_node_return(ar->arWmi, pConnBss);
4875 }
4876 }
4877
4878 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 updating target stats\n"));
4879 pStats->tx_packets += pTarget->txrxStats.tx_stats.tx_packets;
4880 pStats->tx_bytes += pTarget->txrxStats.tx_stats.tx_bytes;
4881 pStats->tx_unicast_pkts += pTarget->txrxStats.tx_stats.tx_unicast_pkts;
4882 pStats->tx_unicast_bytes += pTarget->txrxStats.tx_stats.tx_unicast_bytes;
4883 pStats->tx_multicast_pkts += pTarget->txrxStats.tx_stats.tx_multicast_pkts;
4884 pStats->tx_multicast_bytes += pTarget->txrxStats.tx_stats.tx_multicast_bytes;
4885 pStats->tx_broadcast_pkts += pTarget->txrxStats.tx_stats.tx_broadcast_pkts;
4886 pStats->tx_broadcast_bytes += pTarget->txrxStats.tx_stats.tx_broadcast_bytes;
4887 pStats->tx_rts_success_cnt += pTarget->txrxStats.tx_stats.tx_rts_success_cnt;
4888 for(ac = 0; ac < WMM_NUM_AC; ac++)
4889 pStats->tx_packet_per_ac[ac] += pTarget->txrxStats.tx_stats.tx_packet_per_ac[ac];
4890 pStats->tx_errors += pTarget->txrxStats.tx_stats.tx_errors;
4891 pStats->tx_failed_cnt += pTarget->txrxStats.tx_stats.tx_failed_cnt;
4892 pStats->tx_retry_cnt += pTarget->txrxStats.tx_stats.tx_retry_cnt;
4893 pStats->tx_mult_retry_cnt += pTarget->txrxStats.tx_stats.tx_mult_retry_cnt;
4894 pStats->tx_rts_fail_cnt += pTarget->txrxStats.tx_stats.tx_rts_fail_cnt;
4895 pStats->tx_unicast_rate = wmi_get_rate(pTarget->txrxStats.tx_stats.tx_unicast_rate);
4896
4897 pStats->rx_packets += pTarget->txrxStats.rx_stats.rx_packets;
4898 pStats->rx_bytes += pTarget->txrxStats.rx_stats.rx_bytes;
4899 pStats->rx_unicast_pkts += pTarget->txrxStats.rx_stats.rx_unicast_pkts;
4900 pStats->rx_unicast_bytes += pTarget->txrxStats.rx_stats.rx_unicast_bytes;
4901 pStats->rx_multicast_pkts += pTarget->txrxStats.rx_stats.rx_multicast_pkts;
4902 pStats->rx_multicast_bytes += pTarget->txrxStats.rx_stats.rx_multicast_bytes;
4903 pStats->rx_broadcast_pkts += pTarget->txrxStats.rx_stats.rx_broadcast_pkts;
4904 pStats->rx_broadcast_bytes += pTarget->txrxStats.rx_stats.rx_broadcast_bytes;
4905 pStats->rx_fragment_pkt += pTarget->txrxStats.rx_stats.rx_fragment_pkt;
4906 pStats->rx_errors += pTarget->txrxStats.rx_stats.rx_errors;
4907 pStats->rx_crcerr += pTarget->txrxStats.rx_stats.rx_crcerr;
4908 pStats->rx_key_cache_miss += pTarget->txrxStats.rx_stats.rx_key_cache_miss;
4909 pStats->rx_decrypt_err += pTarget->txrxStats.rx_stats.rx_decrypt_err;
4910 pStats->rx_duplicate_frames += pTarget->txrxStats.rx_stats.rx_duplicate_frames;
4911 pStats->rx_unicast_rate = wmi_get_rate(pTarget->txrxStats.rx_stats.rx_unicast_rate);
4912
4913
4914 pStats->tkip_local_mic_failure
4915 += pTarget->txrxStats.tkipCcmpStats.tkip_local_mic_failure;
4916 pStats->tkip_counter_measures_invoked
4917 += pTarget->txrxStats.tkipCcmpStats.tkip_counter_measures_invoked;
4918 pStats->tkip_replays += pTarget->txrxStats.tkipCcmpStats.tkip_replays;
4919 pStats->tkip_format_errors += pTarget->txrxStats.tkipCcmpStats.tkip_format_errors;
4920 pStats->ccmp_format_errors += pTarget->txrxStats.tkipCcmpStats.ccmp_format_errors;
4921 pStats->ccmp_replays += pTarget->txrxStats.tkipCcmpStats.ccmp_replays;
4922
4923 pStats->power_save_failure_cnt += pTarget->pmStats.power_save_failure_cnt;
4924 pStats->noise_floor_calibation = pTarget->noise_floor_calibation;
4925
4926 pStats->cs_bmiss_cnt += pTarget->cservStats.cs_bmiss_cnt;
4927 pStats->cs_lowRssi_cnt += pTarget->cservStats.cs_lowRssi_cnt;
4928 pStats->cs_connect_cnt += pTarget->cservStats.cs_connect_cnt;
4929 pStats->cs_disconnect_cnt += pTarget->cservStats.cs_disconnect_cnt;
4930 pStats->cs_aveBeacon_snr = pTarget->cservStats.cs_aveBeacon_snr;
4931 pStats->cs_aveBeacon_rssi = pTarget->cservStats.cs_aveBeacon_rssi;
4932
4933 if (enablerssicompensation) {
4934 pStats->cs_aveBeacon_rssi =
4935 rssi_compensation_calc(ar, pStats->cs_aveBeacon_rssi);
4936 }
4937 pStats->cs_lastRoam_msec = pTarget->cservStats.cs_lastRoam_msec;
4938 pStats->cs_snr = pTarget->cservStats.cs_snr;
4939 pStats->cs_rssi = pTarget->cservStats.cs_rssi;
4940
4941 pStats->lq_val = pTarget->lqVal;
4942
4943 pStats->wow_num_pkts_dropped += pTarget->wowStats.wow_num_pkts_dropped;
4944 pStats->wow_num_host_pkt_wakeups += pTarget->wowStats.wow_num_host_pkt_wakeups;
4945 pStats->wow_num_host_event_wakeups += pTarget->wowStats.wow_num_host_event_wakeups;
4946 pStats->wow_num_events_discarded += pTarget->wowStats.wow_num_events_discarded;
4947 pStats->arp_received += pTarget->arpStats.arp_received;
4948 pStats->arp_matched += pTarget->arpStats.arp_matched;
4949 pStats->arp_replied += pTarget->arpStats.arp_replied;
4950
4951 if (ar->statsUpdatePending) {
4952 ar->statsUpdatePending = false;
4953 wake_up(&arEvent);
4954 }
4955 }
4956}
4957
4958void
4959ar6000_rssiThreshold_event(struct ar6_softc *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, s16 rssi)
4960{
4961 USER_RSSI_THOLD userRssiThold;
4962
4963 rssi = rssi + SIGNAL_QUALITY_NOISE_FLOOR;
4964
4965 if (enablerssicompensation) {
4966 rssi = rssi_compensation_calc(ar, rssi);
4967 }
4968
4969 /* Send an event to the app */
4970 userRssiThold.tag = ar->rssi_map[newThreshold].tag;
4971 userRssiThold.rssi = rssi;
4972 A_PRINTF("rssi Threshold range = %d tag = %d rssi = %d\n", newThreshold,
4973 userRssiThold.tag, userRssiThold.rssi);
4974}
4975
4976
4977void
4978ar6000_hbChallengeResp_event(struct ar6_softc *ar, u32 cookie, u32 source)
4979{
4980 if (source != APP_HB_CHALLENGE) {
4981 /* This would ignore the replys that come in after their due time */
4982 if (cookie == ar->arHBChallengeResp.seqNum) {
4983 ar->arHBChallengeResp.outstanding = false;
4984 }
4985 }
4986}
4987
4988
4989void
4990ar6000_reportError_event(struct ar6_softc *ar, WMI_TARGET_ERROR_VAL errorVal)
4991{
4992 static const char * const errString[] = {
4993 [WMI_TARGET_PM_ERR_FAIL] "WMI_TARGET_PM_ERR_FAIL",
4994 [WMI_TARGET_KEY_NOT_FOUND] "WMI_TARGET_KEY_NOT_FOUND",
4995 [WMI_TARGET_DECRYPTION_ERR] "WMI_TARGET_DECRYPTION_ERR",
4996 [WMI_TARGET_BMISS] "WMI_TARGET_BMISS",
4997 [WMI_PSDISABLE_NODE_JOIN] "WMI_PSDISABLE_NODE_JOIN"
4998 };
4999
5000 A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal);
5001
5002 /* One error is reported at a time, and errorval is a bitmask */
5003 if(errorVal & (errorVal - 1))
5004 return;
5005
5006 A_PRINTF("AR6000 Error type = ");
5007 switch(errorVal)
5008 {
5009 case WMI_TARGET_PM_ERR_FAIL:
5010 case WMI_TARGET_KEY_NOT_FOUND:
5011 case WMI_TARGET_DECRYPTION_ERR:
5012 case WMI_TARGET_BMISS:
5013 case WMI_PSDISABLE_NODE_JOIN:
5014 A_PRINTF("%s\n", errString[errorVal]);
5015 break;
5016 default:
5017 A_PRINTF("INVALID\n");
5018 break;
5019 }
5020
5021}
5022
5023
5024void
5025ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cacIndication,
5026 u8 statusCode, u8 *tspecSuggestion)
5027{
5028 WMM_TSPEC_IE *tspecIe;
5029
5030 /*
5031 * This is the TSPEC IE suggestion from AP.
5032 * Suggestion provided by AP under some error
5033 * cases, could be helpful for the host app.
5034 * Check documentation.
5035 */
5036 tspecIe = (WMM_TSPEC_IE *)tspecSuggestion;
5037
5038 /*
5039 * What do we do, if we get TSPEC rejection? One thought
5040 * that comes to mind is implictly delete the pstream...
5041 */
5042 A_PRINTF("AR6000 CAC notification. "
5043 "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n",
5044 ac, cacIndication, statusCode);
5045}
5046
5047void
5048ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel,
5049 u16 newChannel)
5050{
5051 A_PRINTF("Channel Change notification\nOld Channel: %d, New Channel: %d\n",
5052 oldChannel, newChannel);
5053}
5054
5055#define AR6000_PRINT_BSSID(_pBss) do { \
5056 A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\
5057 (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\
5058 (_pBss)[4],(_pBss)[5]); \
5059} while(0)
5060
5061void
5062ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl)
5063{
5064 u8 i;
5065
5066 A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n",
5067 pTbl->numEntries, pTbl->roamMode);
5068 for (i= 0; i < pTbl->numEntries; i++) {
5069 A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i,
5070 pTbl->bssRoamInfo[i].bssid[0], pTbl->bssRoamInfo[i].bssid[1],
5071 pTbl->bssRoamInfo[i].bssid[2],
5072 pTbl->bssRoamInfo[i].bssid[3],
5073 pTbl->bssRoamInfo[i].bssid[4],
5074 pTbl->bssRoamInfo[i].bssid[5]);
5075 A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d"
5076 " BIAS %d\n",
5077 pTbl->bssRoamInfo[i].rssi,
5078 pTbl->bssRoamInfo[i].rssidt,
5079 pTbl->bssRoamInfo[i].last_rssi,
5080 pTbl->bssRoamInfo[i].util,
5081 pTbl->bssRoamInfo[i].roam_util,
5082 pTbl->bssRoamInfo[i].bias);
5083 }
5084}
5085
5086void
5087ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters, WMI_GET_WOW_LIST_REPLY *wow_reply)
5088{
5089 u8 i,j;
5090
5091 /*Each event now contains exactly one filter, see bug 26613*/
5092 A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply->this_filter_num, wow_reply->num_filters);
5093 A_PRINTF("wow mode = %s host mode = %s\n",
5094 (wow_reply->wow_mode == 0? "disabled":"enabled"),
5095 (wow_reply->host_mode == 1 ? "awake":"asleep"));
5096
5097
5098 /*If there are no patterns, the reply will only contain generic
5099 WoW information. Pattern information will exist only if there are
5100 patterns present. Bug 26716*/
5101
5102 /* If this event contains pattern information, display it*/
5103 if (wow_reply->this_filter_num) {
5104 i=0;
5105 A_PRINTF("id=%d size=%d offset=%d\n",
5106 wow_reply->wow_filters[i].wow_filter_id,
5107 wow_reply->wow_filters[i].wow_filter_size,
5108 wow_reply->wow_filters[i].wow_filter_offset);
5109 A_PRINTF("wow pattern = ");
5110 for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
5111 A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_pattern[j]);
5112 }
5113
5114 A_PRINTF("\nwow mask = ");
5115 for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
5116 A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_mask[j]);
5117 }
5118 A_PRINTF("\n");
5119 }
5120}
5121
5122/*
5123 * Report the Roaming related data collected on the target
5124 */
5125void
5126ar6000_display_roam_time(WMI_TARGET_ROAM_TIME *p)
5127{
5128 A_PRINTF("Disconnect Data : BSSID: ");
5129 AR6000_PRINT_BSSID(p->disassoc_bssid);
5130 A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n",
5131 p->disassoc_bss_rssi,p->disassoc_time,
5132 p->no_txrx_time);
5133 A_PRINTF("Connect Data: BSSID: ");
5134 AR6000_PRINT_BSSID(p->assoc_bssid);
5135 A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n",
5136 p->assoc_bss_rssi,p->assoc_time,
5137 p->allow_txrx_time);
5138}
5139
5140void
5141ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p)
5142{
5143 switch (p->roamDataType) {
5144 case ROAM_DATA_TIME:
5145 ar6000_display_roam_time(&p->u.roamTime);
5146 break;
5147 default:
5148 break;
5149 }
5150}
5151
5152void
5153ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *datap, int len)
5154{
5155 struct sk_buff *skb;
5156 WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap;
5157
5158
5159 if (!ar->arMgmtFilter) {
5160 return;
5161 }
5162 if (((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_BEACON) &&
5163 (bih->frameType != BEACON_FTYPE)) ||
5164 ((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_PROBE_RESP) &&
5165 (bih->frameType != PROBERESP_FTYPE)))
5166 {
5167 return;
5168 }
5169
5170 if ((skb = A_NETBUF_ALLOC_RAW(len)) != NULL) {
5171
5172 A_NETBUF_PUT(skb, len);
5173 memcpy(A_NETBUF_DATA(skb), datap, len);
5174 skb->dev = ar->arNetDev;
5175 memcpy(skb_mac_header(skb), A_NETBUF_DATA(skb), 6);
5176 skb->ip_summed = CHECKSUM_NONE;
5177 skb->pkt_type = PACKET_OTHERHOST;
5178 skb->protocol = __constant_htons(0x0019);
5179 netif_rx(skb);
5180 }
5181}
5182
5183u32 wmiSendCmdNum;
5184
5185int
5186ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid)
5187{
5188 struct ar6_softc *ar = (struct ar6_softc *)devt;
5189 int status = 0;
5190 struct ar_cookie *cookie = NULL;
5191 int i;
5192#ifdef CONFIG_PM
5193 if (ar->arWowState != WLAN_WOW_STATE_NONE) {
5194 A_NETBUF_FREE(osbuf);
5195 return A_EACCES;
5196 }
5197#endif /* CONFIG_PM */
5198 /* take lock to protect ar6000_alloc_cookie() */
5199 AR6000_SPIN_LOCK(&ar->arLock, 0);
5200
5201 do {
5202
5203 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar_contrstatus = ol_tx: skb=0x%lx, len=0x%x eid =%d\n",
5204 (unsigned long)osbuf, A_NETBUF_LEN(osbuf), eid));
5205
5206 if (ar->arWMIControlEpFull && (eid == ar->arControlEp)) {
5207 /* control endpoint is full, don't allocate resources, we
5208 * are just going to drop this packet */
5209 cookie = NULL;
5210 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" WMI Control EP full, dropping packet : 0x%lX, len:%d \n",
5211 (unsigned long)osbuf, A_NETBUF_LEN(osbuf)));
5212 } else {
5213 cookie = ar6000_alloc_cookie(ar);
5214 }
5215
5216 if (cookie == NULL) {
5217 status = A_NO_MEMORY;
5218 break;
5219 }
5220
5221 if(logWmiRawMsgs) {
5222 A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum);
5223 for(i = 0; i < a_netbuf_to_len(osbuf); i++)
5224 A_PRINTF("%x ", ((u8 *)a_netbuf_to_data(osbuf))[i]);
5225 A_PRINTF("\n");
5226 }
5227
5228 wmiSendCmdNum++;
5229
5230 } while (false);
5231
5232 if (cookie != NULL) {
5233 /* got a structure to send it out on */
5234 ar->arTxPending[eid]++;
5235
5236 if (eid != ar->arControlEp) {
5237 ar->arTotalTxDataPending++;
5238 }
5239 }
5240
5241 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
5242
5243 if (cookie != NULL) {
5244 cookie->arc_bp[0] = (unsigned long)osbuf;
5245 cookie->arc_bp[1] = 0;
5246 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
5247 cookie,
5248 A_NETBUF_DATA(osbuf),
5249 A_NETBUF_LEN(osbuf),
5250 eid,
5251 AR6K_CONTROL_PKT_TAG);
5252 /* this interface is asynchronous, if there is an error, cleanup will happen in the
5253 * TX completion callback */
5254 HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
5255 status = 0;
5256 }
5257
5258 if (status) {
5259 A_NETBUF_FREE(osbuf);
5260 }
5261 return status;
5262}
5263
5264/* indicate tx activity or inactivity on a WMI stream */
5265void ar6000_indicate_tx_activity(void *devt, u8 TrafficClass, bool Active)
5266{
5267 struct ar6_softc *ar = (struct ar6_softc *)devt;
5268 HTC_ENDPOINT_ID eid ;
5269 int i;
5270
5271 if (ar->arWmiEnabled) {
5272 eid = arAc2EndpointID(ar, TrafficClass);
5273
5274 AR6000_SPIN_LOCK(&ar->arLock, 0);
5275
5276 ar->arAcStreamActive[TrafficClass] = Active;
5277
5278 if (Active) {
5279 /* when a stream goes active, keep track of the active stream with the highest priority */
5280
5281 if (ar->arAcStreamPriMap[TrafficClass] > ar->arHiAcStreamActivePri) {
5282 /* set the new highest active priority */
5283 ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[TrafficClass];
5284 }
5285
5286 } else {
5287 /* when a stream goes inactive, we may have to search for the next active stream
5288 * that is the highest priority */
5289
5290 if (ar->arHiAcStreamActivePri == ar->arAcStreamPriMap[TrafficClass]) {
5291
5292 /* the highest priority stream just went inactive */
5293
5294 /* reset and search for the "next" highest "active" priority stream */
5295 ar->arHiAcStreamActivePri = 0;
5296 for (i = 0; i < WMM_NUM_AC; i++) {
5297 if (ar->arAcStreamActive[i]) {
5298 if (ar->arAcStreamPriMap[i] > ar->arHiAcStreamActivePri) {
5299 /* set the new highest active priority */
5300 ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[i];
5301 }
5302 }
5303 }
5304 }
5305 }
5306
5307 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
5308
5309 } else {
5310 /* for mbox ping testing, the traffic class is mapped directly as a stream ID,
5311 * see handling of AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE in ioctl.c
5312 * convert the stream ID to a endpoint */
5313 eid = arAc2EndpointID(ar, TrafficClass);
5314 }
5315
5316 /* notify HTC, this may cause credit distribution changes */
5317
5318 HTCIndicateActivityChange(ar->arHtcTarget,
5319 eid,
5320 Active);
5321
5322}
5323
5324void
5325ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, u32 len)
5326{
5327
5328 WMI_BTCOEX_CONFIG_EVENT *pBtcoexConfig = (WMI_BTCOEX_CONFIG_EVENT *)ptr;
5329 WMI_BTCOEX_CONFIG_EVENT *pArbtcoexConfig =&ar->arBtcoexConfig;
5330
5331 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
5332
5333 A_PRINTF("received config event\n");
5334 pArbtcoexConfig->btProfileType = pBtcoexConfig->btProfileType;
5335 pArbtcoexConfig->linkId = pBtcoexConfig->linkId;
5336
5337 switch (pBtcoexConfig->btProfileType) {
5338 case WMI_BTCOEX_BT_PROFILE_SCO:
5339 memcpy(&pArbtcoexConfig->info.scoConfigCmd, &pBtcoexConfig->info.scoConfigCmd,
5340 sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
5341 break;
5342 case WMI_BTCOEX_BT_PROFILE_A2DP:
5343 memcpy(&pArbtcoexConfig->info.a2dpConfigCmd, &pBtcoexConfig->info.a2dpConfigCmd,
5344 sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
5345 break;
5346 case WMI_BTCOEX_BT_PROFILE_ACLCOEX:
5347 memcpy(&pArbtcoexConfig->info.aclcoexConfig, &pBtcoexConfig->info.aclcoexConfig,
5348 sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
5349 break;
5350 case WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE:
5351 memcpy(&pArbtcoexConfig->info.btinquiryPageConfigCmd, &pBtcoexConfig->info.btinquiryPageConfigCmd,
5352 sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
5353 break;
5354 }
5355 if (ar->statsUpdatePending) {
5356 ar->statsUpdatePending = false;
5357 wake_up(&arEvent);
5358 }
5359}
5360
5361void
5362ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, u32 len)
5363{
5364 WMI_BTCOEX_STATS_EVENT *pBtcoexStats = (WMI_BTCOEX_STATS_EVENT *)ptr;
5365
5366 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
5367
5368 memcpy(&ar->arBtcoexStats, pBtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT));
5369
5370 if (ar->statsUpdatePending) {
5371 ar->statsUpdatePending = false;
5372 wake_up(&arEvent);
5373 }
5374
5375}
5376module_init(ar6000_init_module);
5377module_exit(ar6000_cleanup_module);
5378
5379/* Init cookie queue */
5380static void
5381ar6000_cookie_init(struct ar6_softc *ar)
5382{
5383 u32 i;
5384
5385 ar->arCookieList = NULL;
5386 ar->arCookieCount = 0;
5387
5388 A_MEMZERO(s_ar_cookie_mem, sizeof(s_ar_cookie_mem));
5389
5390 for (i = 0; i < MAX_COOKIE_NUM; i++) {
5391 ar6000_free_cookie(ar, &s_ar_cookie_mem[i]);
5392 }
5393}
5394
5395/* cleanup cookie queue */
5396static void
5397ar6000_cookie_cleanup(struct ar6_softc *ar)
5398{
5399 /* It is gone .... */
5400 ar->arCookieList = NULL;
5401 ar->arCookieCount = 0;
5402}
5403
5404/* Init cookie queue */
5405static void
5406ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie)
5407{
5408 /* Insert first */
5409 A_ASSERT(ar != NULL);
5410 A_ASSERT(cookie != NULL);
5411
5412 cookie->arc_list_next = ar->arCookieList;
5413 ar->arCookieList = cookie;
5414 ar->arCookieCount++;
5415}
5416
5417/* cleanup cookie queue */
5418static struct ar_cookie *
5419ar6000_alloc_cookie(struct ar6_softc *ar)
5420{
5421 struct ar_cookie *cookie;
5422
5423 cookie = ar->arCookieList;
5424 if(cookie != NULL)
5425 {
5426 ar->arCookieList = cookie->arc_list_next;
5427 ar->arCookieCount--;
5428 }
5429
5430 return cookie;
5431}
5432
5433void
5434ar6000_tx_retry_err_event(void *devt)
5435{
5436 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Tx retries reach maximum!\n"));
5437}
5438
5439void
5440ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, u8 snr)
5441{
5442 WMI_SNR_THRESHOLD_EVENT event;
5443
5444 event.range = newThreshold;
5445 event.snr = snr;
5446}
5447
5448void
5449ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, u8 lq)
5450{
5451 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("lq threshold range %d, lq %d\n", newThreshold, lq));
5452}
5453
5454
5455
5456u32 a_copy_to_user(void *to, const void *from, u32 n)
5457{
5458 return(copy_to_user(to, from, n));
5459}
5460
5461u32 a_copy_from_user(void *to, const void *from, u32 n)
5462{
5463 return(copy_from_user(to, from, n));
5464}
5465
5466
5467int
5468ar6000_get_driver_cfg(struct net_device *dev,
5469 u16 cfgParam,
5470 void *result)
5471{
5472
5473 int ret = 0;
5474
5475 switch(cfgParam)
5476 {
5477 case AR6000_DRIVER_CFG_GET_WLANNODECACHING:
5478 *((u32 *)result) = wlanNodeCaching;
5479 break;
5480 case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS:
5481 *((u32 *)result) = logWmiRawMsgs;
5482 break;
5483 default:
5484 ret = EINVAL;
5485 break;
5486 }
5487
5488 return ret;
5489}
5490
5491void
5492ar6000_keepalive_rx(void *devt, u8 configured)
5493{
5494 struct ar6_softc *ar = (struct ar6_softc *)devt;
5495
5496 ar->arKeepaliveConfigured = configured;
5497 wake_up(&arEvent);
5498}
5499
5500void
5501ar6000_pmkid_list_event(void *devt, u8 numPMKID, WMI_PMKID *pmkidList,
5502 u8 *bssidList)
5503{
5504 u8 i, j;
5505
5506 A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID);
5507
5508 for (i = 0; i < numPMKID; i++) {
5509 A_PRINTF("\nBSSID %d ", i);
5510 for (j = 0; j < ATH_MAC_LEN; j++) {
5511 A_PRINTF("%2.2x", bssidList[j]);
5512 }
5513 bssidList += (ATH_MAC_LEN + WMI_PMKID_LEN);
5514 A_PRINTF("\nPMKID %d ", i);
5515 for (j = 0; j < WMI_PMKID_LEN; j++) {
5516 A_PRINTF("%2.2x", pmkidList->pmkid[j]);
5517 }
5518 pmkidList = (WMI_PMKID *)((u8 *)pmkidList + ATH_MAC_LEN +
5519 WMI_PMKID_LEN);
5520 }
5521}
5522
5523void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid)
5524{
5525 sta_t *conn=NULL;
5526 bool isPsqEmpty = false;
5527
5528 conn = ieee80211_find_conn_for_aid(ar, aid);
5529
5530 /* If the PS q for this STA is not empty, dequeue and send a pkt from
5531 * the head of the q. Also update the More data bit in the WMI_DATA_HDR
5532 * if there are more pkts for this STA in the PS q. If there are no more
5533 * pkts for this STA, update the PVB for this STA.
5534 */
5535 A_MUTEX_LOCK(&conn->psqLock);
5536 isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
5537 A_MUTEX_UNLOCK(&conn->psqLock);
5538
5539 if (isPsqEmpty) {
5540 /* TODO:No buffered pkts for this STA. Send out a NULL data frame */
5541 } else {
5542 struct sk_buff *skb = NULL;
5543
5544 A_MUTEX_LOCK(&conn->psqLock);
5545 skb = A_NETBUF_DEQUEUE(&conn->psq);
5546 A_MUTEX_UNLOCK(&conn->psqLock);
5547 /* Set the STA flag to PSPolled, so that the frame will go out */
5548 STA_SET_PS_POLLED(conn);
5549 ar6000_data_tx(skb, ar->arNetDev);
5550 STA_CLR_PS_POLLED(conn);
5551
5552 /* Clear the PVB for this STA if the queue has become empty */
5553 A_MUTEX_LOCK(&conn->psqLock);
5554 isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
5555 A_MUTEX_UNLOCK(&conn->psqLock);
5556
5557 if (isPsqEmpty) {
5558 wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
5559 }
5560 }
5561}
5562
5563void ar6000_dtimexpiry_event(struct ar6_softc *ar)
5564{
5565 bool isMcastQueued = false;
5566 struct sk_buff *skb = NULL;
5567
5568 /* If there are no associated STAs, ignore the DTIM expiry event.
5569 * There can be potential race conditions where the last associated
5570 * STA may disconnect & before the host could clear the 'Indicate DTIM'
5571 * request to the firmware, the firmware would have just indicated a DTIM
5572 * expiry event. The race is between 'clear DTIM expiry cmd' going
5573 * from the host to the firmware & the DTIM expiry event happening from
5574 * the firmware to the host.
5575 */
5576 if (ar->sta_list_index == 0) {
5577 return;
5578 }
5579
5580 A_MUTEX_LOCK(&ar->mcastpsqLock);
5581 isMcastQueued = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
5582 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5583
5584 A_ASSERT(isMcastQueued == false);
5585
5586 /* Flush the mcast psq to the target */
5587 /* Set the STA flag to DTIMExpired, so that the frame will go out */
5588 ar->DTIMExpired = true;
5589
5590 A_MUTEX_LOCK(&ar->mcastpsqLock);
5591 while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
5592 skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
5593 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5594
5595 ar6000_data_tx(skb, ar->arNetDev);
5596
5597 A_MUTEX_LOCK(&ar->mcastpsqLock);
5598 }
5599 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5600
5601 /* Reset the DTIMExpired flag back to 0 */
5602 ar->DTIMExpired = false;
5603
5604 /* Clear the LSB of the BitMapCtl field of the TIM IE */
5605 wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
5606}
5607
5608void
5609read_rssi_compensation_param(struct ar6_softc *ar)
5610{
5611 u8 *cust_data_ptr;
5612
5613//#define RSSICOMPENSATION_PRINT
5614
5615#ifdef RSSICOMPENSATION_PRINT
5616 s16 i;
5617 cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType);
5618 for (i=0; i<16; i++) {
5619 A_PRINTF("cust_data_%d = %x \n", i, *(u8 *)cust_data_ptr);
5620 cust_data_ptr += 1;
5621 }
5622#endif
5623
5624 cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType);
5625
5626 rssi_compensation_param.customerID = *(u16 *)cust_data_ptr & 0xffff;
5627 rssi_compensation_param.enable = *(u16 *)(cust_data_ptr+2) & 0xffff;
5628 rssi_compensation_param.bg_param_a = *(u16 *)(cust_data_ptr+4) & 0xffff;
5629 rssi_compensation_param.bg_param_b = *(u16 *)(cust_data_ptr+6) & 0xffff;
5630 rssi_compensation_param.a_param_a = *(u16 *)(cust_data_ptr+8) & 0xffff;
5631 rssi_compensation_param.a_param_b = *(u16 *)(cust_data_ptr+10) &0xffff;
5632 rssi_compensation_param.reserved = *(u32 *)(cust_data_ptr+12);
5633
5634#ifdef RSSICOMPENSATION_PRINT
5635 A_PRINTF("customerID = 0x%x \n", rssi_compensation_param.customerID);
5636 A_PRINTF("enable = 0x%x \n", rssi_compensation_param.enable);
5637 A_PRINTF("bg_param_a = 0x%x and %d \n", rssi_compensation_param.bg_param_a, rssi_compensation_param.bg_param_a);
5638 A_PRINTF("bg_param_b = 0x%x and %d \n", rssi_compensation_param.bg_param_b, rssi_compensation_param.bg_param_b);
5639 A_PRINTF("a_param_a = 0x%x and %d \n", rssi_compensation_param.a_param_a, rssi_compensation_param.a_param_a);
5640 A_PRINTF("a_param_b = 0x%x and %d \n", rssi_compensation_param.a_param_b, rssi_compensation_param.a_param_b);
5641 A_PRINTF("Last 4 bytes = 0x%x \n", rssi_compensation_param.reserved);
5642#endif
5643
5644 if (rssi_compensation_param.enable != 0x1) {
5645 rssi_compensation_param.enable = 0;
5646 }
5647
5648 return;
5649}
5650
5651s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt)
5652{
5653
5654 if (freq > 5000)
5655 {
5656 if (rssi_compensation_param.enable)
5657 {
5658 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5659 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d, totalPkt = %d\n", rssi,totalPkt));
5660 rssi = rssi * rssi_compensation_param.a_param_a + totalPkt * rssi_compensation_param.a_param_b;
5661 rssi = (rssi-50) /100;
5662 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5663 }
5664 }
5665 else
5666 {
5667 if (rssi_compensation_param.enable)
5668 {
5669 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5670 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d, totalPkt = %d\n", rssi,totalPkt));
5671 rssi = rssi * rssi_compensation_param.bg_param_a + totalPkt * rssi_compensation_param.bg_param_b;
5672 rssi = (rssi-50) /100;
5673 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5674 }
5675 }
5676
5677 return rssi;
5678}
5679
5680s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi)
5681{
5682 if (ar->arBssChannel > 5000)
5683 {
5684 if (rssi_compensation_param.enable)
5685 {
5686 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5687 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d\n", rssi));
5688 rssi = rssi * rssi_compensation_param.a_param_a + rssi_compensation_param.a_param_b;
5689 rssi = (rssi-50) /100;
5690 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5691 }
5692 }
5693 else
5694 {
5695 if (rssi_compensation_param.enable)
5696 {
5697 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5698 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d\n", rssi));
5699 rssi = rssi * rssi_compensation_param.bg_param_a + rssi_compensation_param.bg_param_b;
5700 rssi = (rssi-50) /100;
5701 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5702 }
5703 }
5704
5705 return rssi;
5706}
5707
5708s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above)
5709{
5710 s16 i;
5711
5712 if (ar->arBssChannel > 5000)
5713 {
5714 if (rssi_compensation_param.enable)
5715 {
5716 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5717 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation = %d\n", rssi));
5718 rssi = rssi * 100;
5719 rssi = (rssi - rssi_compensation_param.a_param_b) / rssi_compensation_param.a_param_a;
5720 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi));
5721 }
5722 }
5723 else
5724 {
5725 if (rssi_compensation_param.enable)
5726 {
5727 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5728 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation = %d\n", rssi));
5729
5730 if (Above) {
5731 for (i=95; i>=0; i--) {
5732 if (rssi <= rssi_compensation_table[i]) {
5733 rssi = 0 - i;
5734 break;
5735 }
5736 }
5737 } else {
5738 for (i=0; i<=95; i++) {
5739 if (rssi >= rssi_compensation_table[i]) {
5740 rssi = 0 - i;
5741 break;
5742 }
5743 }
5744 }
5745 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi));
5746 }
5747 }
5748
5749 return rssi;
5750}
5751
5752#ifdef WAPI_ENABLE
5753void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac)
5754{
5755 union iwreq_data wrqu;
5756 char buf[20];
5757
5758 A_MEMZERO(buf, sizeof(buf));
5759
5760 strcpy(buf, "WAPI_REKEY");
5761 buf[10] = type;
5762 memcpy(&buf[11], mac, ATH_MAC_LEN);
5763
5764 A_MEMZERO(&wrqu, sizeof(wrqu));
5765 wrqu.data.length = 10+1+ATH_MAC_LEN;
5766 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
5767
5768 A_PRINTF("WAPI REKEY - %d - %02x:%02x\n", type, mac[4], mac[5]);
5769}
5770#endif
5771
5772static int
5773ar6000_reinstall_keys(struct ar6_softc *ar, u8 key_op_ctrl)
5774{
5775 int status = 0;
5776 struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik;
5777 struct ieee80211req_key *bik = &ar->user_saved_keys.bcast_ik;
5778 CRYPTO_TYPE keyType = ar->user_saved_keys.keyType;
5779
5780 if (IEEE80211_CIPHER_CCKM_KRK != uik->ik_type) {
5781 if (NONE_CRYPT == keyType) {
5782 goto _reinstall_keys_out;
5783 }
5784
5785 if (uik->ik_keylen) {
5786 status = wmi_addKey_cmd(ar->arWmi, uik->ik_keyix,
5787 ar->user_saved_keys.keyType, PAIRWISE_USAGE,
5788 uik->ik_keylen, (u8 *)&uik->ik_keyrsc,
5789 uik->ik_keydata, key_op_ctrl, uik->ik_macaddr, SYNC_BEFORE_WMIFLAG);
5790 }
5791
5792 } else {
5793 status = wmi_add_krk_cmd(ar->arWmi, uik->ik_keydata);
5794 }
5795
5796 if (IEEE80211_CIPHER_CCKM_KRK != bik->ik_type) {
5797 if (NONE_CRYPT == keyType) {
5798 goto _reinstall_keys_out;
5799 }
5800
5801 if (bik->ik_keylen) {
5802 status = wmi_addKey_cmd(ar->arWmi, bik->ik_keyix,
5803 ar->user_saved_keys.keyType, GROUP_USAGE,
5804 bik->ik_keylen, (u8 *)&bik->ik_keyrsc,
5805 bik->ik_keydata, key_op_ctrl, bik->ik_macaddr, NO_SYNC_WMIFLAG);
5806 }
5807 } else {
5808 status = wmi_add_krk_cmd(ar->arWmi, bik->ik_keydata);
5809 }
5810
5811_reinstall_keys_out:
5812 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
5813 ar->user_key_ctrl = 0;
5814
5815 return status;
5816}
5817
5818
5819void
5820ar6000_dset_open_req(
5821 void *context,
5822 u32 id,
5823 u32 targHandle,
5824 u32 targReplyFn,
5825 u32 targReplyArg)
5826{
5827}
5828
5829void
5830ar6000_dset_close(
5831 void *context,
5832 u32 access_cookie)
5833{
5834 return;
5835}
5836
5837void
5838ar6000_dset_data_req(
5839 void *context,
5840 u32 accessCookie,
5841 u32 offset,
5842 u32 length,
5843 u32 targBuf,
5844 u32 targReplyFn,
5845 u32 targReplyArg)
5846{
5847}
5848
5849int
5850ar6000_ap_mode_profile_commit(struct ar6_softc *ar)
5851{
5852 WMI_CONNECT_CMD p;
5853 unsigned long flags;
5854
5855 /* No change in AP's profile configuration */
5856 if(ar->ap_profile_flag==0) {
5857 A_PRINTF("COMMIT: No change in profile!!!\n");
5858 return -ENODATA;
5859 }
5860
5861 if(!ar->arSsidLen) {
5862 A_PRINTF("SSID not set!!!\n");
5863 return -ECHRNG;
5864 }
5865
5866 switch(ar->arAuthMode) {
5867 case NONE_AUTH:
5868 if((ar->arPairwiseCrypto != NONE_CRYPT) &&
5869#ifdef WAPI_ENABLE
5870 (ar->arPairwiseCrypto != WAPI_CRYPT) &&
5871#endif
5872 (ar->arPairwiseCrypto != WEP_CRYPT)) {
5873 A_PRINTF("Cipher not supported in AP mode Open auth\n");
5874 return -EOPNOTSUPP;
5875 }
5876 break;
5877 case WPA_PSK_AUTH:
5878 case WPA2_PSK_AUTH:
5879 case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
5880 break;
5881 default:
5882 A_PRINTF("This key mgmt type not supported in AP mode\n");
5883 return -EOPNOTSUPP;
5884 }
5885
5886 /* Update the arNetworkType */
5887 ar->arNetworkType = ar->arNextMode;
5888
5889 A_MEMZERO(&p,sizeof(p));
5890 p.ssidLength = ar->arSsidLen;
5891 memcpy(p.ssid,ar->arSsid,p.ssidLength);
5892 p.channel = ar->arChannelHint;
5893 p.networkType = ar->arNetworkType;
5894
5895 p.dot11AuthMode = ar->arDot11AuthMode;
5896 p.authMode = ar->arAuthMode;
5897 p.pairwiseCryptoType = ar->arPairwiseCrypto;
5898 p.pairwiseCryptoLen = ar->arPairwiseCryptoLen;
5899 p.groupCryptoType = ar->arGroupCrypto;
5900 p.groupCryptoLen = ar->arGroupCryptoLen;
5901 p.ctrl_flags = ar->arConnectCtrlFlags;
5902
5903 wmi_ap_profile_commit(ar->arWmi, &p);
5904 spin_lock_irqsave(&ar->arLock, flags);
5905 ar->arConnected = true;
5906 netif_carrier_on(ar->arNetDev);
5907 spin_unlock_irqrestore(&ar->arLock, flags);
5908 ar->ap_profile_flag = 0;
5909 return 0;
5910}
5911
5912int
5913ar6000_connect_to_ap(struct ar6_softc *ar)
5914{
5915 /* The ssid length check prevents second "essid off" from the user,
5916 to be treated as a connect cmd. The second "essid off" is ignored.
5917 */
5918 if((ar->arWmiReady == true) && (ar->arSsidLen > 0) && ar->arNetworkType!=AP_NETWORK)
5919 {
5920 int status;
5921 if((ADHOC_NETWORK != ar->arNetworkType) &&
5922 (NONE_AUTH==ar->arAuthMode) &&
5923 (WEP_CRYPT==ar->arPairwiseCrypto)) {
5924 ar6000_install_static_wep_keys(ar);
5925 }
5926
5927 if (!ar->arUserBssFilter) {
5928 if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) {
5929 return -EIO;
5930 }
5931 }
5932#ifdef WAPI_ENABLE
5933 if (ar->arWapiEnable) {
5934 ar->arPairwiseCrypto = WAPI_CRYPT;
5935 ar->arPairwiseCryptoLen = 0;
5936 ar->arGroupCrypto = WAPI_CRYPT;
5937 ar->arGroupCryptoLen = 0;
5938 ar->arAuthMode = NONE_AUTH;
5939 ar->arConnectCtrlFlags |= CONNECT_IGNORE_WPAx_GROUP_CIPHER;
5940 }
5941#endif
5942 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Connect called with authmode %d dot11 auth %d"\
5943 " PW crypto %d PW crypto Len %d GRP crypto %d"\
5944 " GRP crypto Len %d\n",
5945 ar->arAuthMode, ar->arDot11AuthMode,
5946 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
5947 ar->arGroupCrypto, ar->arGroupCryptoLen));
5948 reconnect_flag = 0;
5949 /* Set the listen interval into 1000TUs or more. This value will be indicated to Ap in the conn.
5950 later set it back locally at the STA to 100/1000 TUs depending on the power mode */
5951 if ((ar->arNetworkType == INFRA_NETWORK)) {
5952 wmi_listeninterval_cmd(ar->arWmi, max(ar->arListenIntervalT, (u16)A_MAX_WOW_LISTEN_INTERVAL), 0);
5953 }
5954 status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
5955 ar->arDot11AuthMode, ar->arAuthMode,
5956 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
5957 ar->arGroupCrypto,ar->arGroupCryptoLen,
5958 ar->arSsidLen, ar->arSsid,
5959 ar->arReqBssid, ar->arChannelHint,
5960 ar->arConnectCtrlFlags);
5961 if (status) {
5962 wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB);
5963 if (!ar->arUserBssFilter) {
5964 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
5965 }
5966 return status;
5967 }
5968
5969 if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
5970 ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
5971 {
5972 A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
5973 }
5974
5975 ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
5976
5977 ar->arConnectPending = true;
5978 return status;
5979 }
5980 return A_ERROR;
5981}
5982
5983int
5984ar6000_disconnect(struct ar6_softc *ar)
5985{
5986 if ((ar->arConnected == true) || (ar->arConnectPending == true)) {
5987 wmi_disconnect_cmd(ar->arWmi);
5988 /*
5989 * Disconnect cmd is issued, clear connectPending.
5990 * arConnected will be cleard in disconnect_event notification.
5991 */
5992 ar->arConnectPending = false;
5993 }
5994
5995 return 0;
5996}
5997
5998int
5999ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie)
6000{
6001 sta_t *conn = NULL;
6002 conn = ieee80211_find_conn(ar, wpaie->wpa_macaddr);
6003
6004 A_MEMZERO(wpaie->wpa_ie, IEEE80211_MAX_IE);
6005 A_MEMZERO(wpaie->rsn_ie, IEEE80211_MAX_IE);
6006
6007 if(conn) {
6008 memcpy(wpaie->wpa_ie, conn->wpa_ie, IEEE80211_MAX_IE);
6009 }
6010
6011 return 0;
6012}
6013
6014int
6015is_iwioctl_allowed(u8 mode, u16 cmd)
6016{
6017 if(cmd >= SIOCSIWCOMMIT && cmd <= SIOCGIWPOWER) {
6018 cmd -= SIOCSIWCOMMIT;
6019 if(sioctl_filter[cmd] == 0xFF) return 0;
6020 if(sioctl_filter[cmd] & mode) return 0;
6021 } else if(cmd >= SIOCIWFIRSTPRIV && cmd <= (SIOCIWFIRSTPRIV+30)) {
6022 cmd -= SIOCIWFIRSTPRIV;
6023 if(pioctl_filter[cmd] == 0xFF) return 0;
6024 if(pioctl_filter[cmd] & mode) return 0;
6025 } else {
6026 return A_ERROR;
6027 }
6028 return A_ENOTSUP;
6029}
6030
6031int
6032is_xioctl_allowed(u8 mode, int cmd)
6033{
6034 if(sizeof(xioctl_filter)-1 < cmd) {
6035 A_PRINTF("Filter for this cmd=%d not defined\n",cmd);
6036 return 0;
6037 }
6038 if(xioctl_filter[cmd] == 0xFF) return 0;
6039 if(xioctl_filter[cmd] & mode) return 0;
6040 return A_ERROR;
6041}
6042
6043#ifdef WAPI_ENABLE
6044int
6045ap_set_wapi_key(struct ar6_softc *ar, void *ikey)
6046{
6047 struct ieee80211req_key *ik = (struct ieee80211req_key *)ikey;
6048 KEY_USAGE keyUsage = 0;
6049 int status;
6050
6051 if (memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN) == 0) {
6052 keyUsage = GROUP_USAGE;
6053 } else {
6054 keyUsage = PAIRWISE_USAGE;
6055 }
6056 A_PRINTF("WAPI_KEY: Type:%d ix:%d mac:%02x:%02x len:%d\n",
6057 keyUsage, ik->ik_keyix, ik->ik_macaddr[4], ik->ik_macaddr[5],
6058 ik->ik_keylen);
6059
6060 status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, WAPI_CRYPT, keyUsage,
6061 ik->ik_keylen, (u8 *)&ik->ik_keyrsc,
6062 ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
6063 SYNC_BOTH_WMIFLAG);
6064
6065 if (0 != status) {
6066 return -EIO;
6067 }
6068 return 0;
6069}
6070#endif
6071
6072void ar6000_peer_event(
6073 void *context,
6074 u8 eventCode,
6075 u8 *macAddr)
6076{
6077 u8 pos;
6078
6079 for (pos=0;pos<6;pos++)
6080 printk("%02x: ",*(macAddr+pos));
6081 printk("\n");
6082}
6083
6084#ifdef HTC_TEST_SEND_PKTS
6085#define HTC_TEST_DUPLICATE 8
6086static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *dupskb)
6087{
6088 struct ar_cookie *cookie;
6089 struct ar_cookie *cookieArray[HTC_TEST_DUPLICATE];
6090 struct sk_buff *new_skb;
6091 int i;
6092 int pkts = 0;
6093 struct htc_packet_queue pktQueue;
6094 EPPING_HEADER *eppingHdr;
6095
6096 eppingHdr = A_NETBUF_DATA(dupskb);
6097
6098 if (eppingHdr->Cmd_h == EPPING_CMD_NO_ECHO) {
6099 /* skip test if this is already a tx perf test */
6100 return;
6101 }
6102
6103 for (i = 0; i < HTC_TEST_DUPLICATE; i++,pkts++) {
6104 AR6000_SPIN_LOCK(&ar->arLock, 0);
6105 cookie = ar6000_alloc_cookie(ar);
6106 if (cookie != NULL) {
6107 ar->arTxPending[eid]++;
6108 ar->arTotalTxDataPending++;
6109 }
6110
6111 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
6112
6113 if (NULL == cookie) {
6114 break;
6115 }
6116
6117 new_skb = A_NETBUF_ALLOC(A_NETBUF_LEN(dupskb));
6118
6119 if (new_skb == NULL) {
6120 AR6000_SPIN_LOCK(&ar->arLock, 0);
6121 ar6000_free_cookie(ar,cookie);
6122 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
6123 break;
6124 }
6125
6126 A_NETBUF_PUT_DATA(new_skb, A_NETBUF_DATA(dupskb), A_NETBUF_LEN(dupskb));
6127 cookie->arc_bp[0] = (unsigned long)new_skb;
6128 cookie->arc_bp[1] = MapNo;
6129 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
6130 cookie,
6131 A_NETBUF_DATA(new_skb),
6132 A_NETBUF_LEN(new_skb),
6133 eid,
6134 AR6K_DATA_PKT_TAG);
6135
6136 cookieArray[i] = cookie;
6137
6138 {
6139 EPPING_HEADER *pHdr = (EPPING_HEADER *)A_NETBUF_DATA(new_skb);
6140 pHdr->Cmd_h = EPPING_CMD_NO_ECHO; /* do not echo the packet */
6141 }
6142 }
6143
6144 if (pkts == 0) {
6145 return;
6146 }
6147
6148 INIT_HTC_PACKET_QUEUE(&pktQueue);
6149
6150 for (i = 0; i < pkts; i++) {
6151 HTC_PACKET_ENQUEUE(&pktQueue,&cookieArray[i]->HtcPkt);
6152 }
6153
6154 HTCSendPktsMultiple(ar->arHtcTarget, &pktQueue);
6155
6156}
6157#endif
6158
6159#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
6160/*
6161 * Add support for adding and removing a virtual adapter for soft AP.
6162 * Some OS requires different adapters names for station and soft AP mode.
6163 * To support these requirement, create and destroy a netdevice instance
6164 * when the AP mode is operational. A full fledged support for virual device
6165 * is not implemented. Rather a virtual interface is created and is linked
6166 * with the existing physical device instance during the operation of the
6167 * AP mode.
6168 */
6169
6170int ar6000_start_ap_interface(struct ar6_softc *ar)
6171{
6172 struct ar_virtual_interface *arApDev;
6173
6174 /* Change net_device to point to AP instance */
6175 arApDev = (struct ar_virtual_interface *)ar->arApDev;
6176 ar->arNetDev = arApDev->arNetDev;
6177
6178 return 0;
6179}
6180
6181int ar6000_stop_ap_interface(struct ar6_softc *ar)
6182{
6183 struct ar_virtual_interface *arApDev;
6184
6185 /* Change net_device to point to sta instance */
6186 arApDev = (struct ar_virtual_interface *)ar->arApDev;
6187 if (arApDev) {
6188 ar->arNetDev = arApDev->arStaNetDev;
6189 }
6190
6191 return 0;
6192}
6193
6194
6195int ar6000_create_ap_interface(struct ar6_softc *ar, char *ap_ifname)
6196{
6197 struct net_device *dev;
6198 struct ar_virtual_interface *arApDev;
6199
6200 dev = alloc_etherdev(sizeof(struct ar_virtual_interface));
6201 if (dev == NULL) {
6202 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: can't alloc etherdev\n"));
6203 return A_ERROR;
6204 }
6205
6206 ether_setup(dev);
6207 init_netdev(dev, ap_ifname);
6208 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
6209
6210 if (register_netdev(dev)) {
6211 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n"));
6212 return A_ERROR;
6213 }
6214
6215 arApDev = netdev_priv(dev);
6216 arApDev->arDev = ar;
6217 arApDev->arNetDev = dev;
6218 arApDev->arStaNetDev = ar->arNetDev;
6219
6220 ar->arApDev = arApDev;
6221 arApNetDev = dev;
6222
6223 /* Copy the MAC address */
6224 memcpy(dev->dev_addr, ar->arNetDev->dev_addr, AR6000_ETH_ADDR_LEN);
6225
6226 return 0;
6227}
6228
6229int ar6000_add_ap_interface(struct ar6_softc *ar, char *ap_ifname)
6230{
6231 /* Interface already added, need not proceed further */
6232 if (ar->arApDev != NULL) {
6233 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_add_ap_interface: interface already present \n"));
6234 return 0;
6235 }
6236
6237 if (ar6000_create_ap_interface(ar, ap_ifname) != 0) {
6238 return A_ERROR;
6239 }
6240
6241 A_PRINTF("Add AP interface %s \n",ap_ifname);
6242
6243 return ar6000_start_ap_interface(ar);
6244}
6245
6246int ar6000_remove_ap_interface(struct ar6_softc *ar)
6247{
6248 if (arApNetDev) {
6249 ar6000_stop_ap_interface(ar);
6250
6251 unregister_netdev(arApNetDev);
6252 free_netdev(apApNetDev);
6253
6254 A_PRINTF("Remove AP interface\n");
6255 }
6256 ar->arApDev = NULL;
6257 arApNetDev = NULL;
6258
6259
6260 return 0;
6261}
6262#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
6263
6264
6265#ifdef EXPORT_HCI_BRIDGE_INTERFACE
6266EXPORT_SYMBOL(setupbtdev);
6267#endif
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c
deleted file mode 100644
index 1e0ace8b6d1..00000000000
--- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c
+++ /dev/null
@@ -1,626 +0,0 @@
1/*
2 *
3 * Copyright (c) 2004-2010 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7//
8// Permission to use, copy, modify, and/or distribute this software for any
9// purpose with or without fee is hereby granted, provided that the above
10// copyright notice and this permission notice appear in all copies.
11//
12// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19//
20//
21 *
22 */
23
24/*
25 * Implementation of system power management
26 */
27
28#include "ar6000_drv.h"
29#include <linux/inetdevice.h>
30#include <linux/platform_device.h>
31#include "wlan_config.h"
32
33#define WOW_ENABLE_MAX_INTERVAL 0
34#define WOW_SET_SCAN_PARAMS 0
35
36extern unsigned int wmitimeout;
37extern wait_queue_head_t arEvent;
38
39#undef ATH_MODULE_NAME
40#define ATH_MODULE_NAME pm
41#define ATH_DEBUG_PM ATH_DEBUG_MAKE_MODULE_MASK(0)
42
43#ifdef DEBUG
44static struct ath_debug_mask_description pm_debug_desc[] = {
45 { ATH_DEBUG_PM , "System power management"},
46};
47
48ATH_DEBUG_INSTANTIATE_MODULE_VAR(pm,
49 "pm",
50 "System Power Management",
51 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_PM,
52 ATH_DEBUG_DESCRIPTION_COUNT(pm_debug_desc),
53 pm_debug_desc);
54
55#endif /* DEBUG */
56
57int ar6000_exit_cut_power_state(struct ar6_softc *ar);
58
59#ifdef CONFIG_PM
60static void ar6k_send_asleep_event_to_app(struct ar6_softc *ar, bool asleep)
61{
62 char buf[128];
63 union iwreq_data wrqu;
64
65 snprintf(buf, sizeof(buf), "HOST_ASLEEP=%s", asleep ? "asleep" : "awake");
66 A_MEMZERO(&wrqu, sizeof(wrqu));
67 wrqu.data.length = strlen(buf);
68 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
69}
70
71static void ar6000_wow_resume(struct ar6_softc *ar)
72{
73 if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
74 u16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
75 u16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period;
76 WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {true, false};
77 ar->arWowState = WLAN_WOW_STATE_NONE;
78 if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!= 0) {
79 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup restore host awake\n"));
80 }
81#if WOW_SET_SCAN_PARAMS
82 wmi_scanparams_cmd(ar->arWmi, fg_start_period,
83 ar->scParams.fg_end_period,
84 bg_period,
85 ar->scParams.minact_chdwell_time,
86 ar->scParams.maxact_chdwell_time,
87 ar->scParams.pas_chdwell_time,
88 ar->scParams.shortScanRatio,
89 ar->scParams.scanCtrlFlags,
90 ar->scParams.max_dfsch_act_time,
91 ar->scParams.maxact_scan_per_ssid);
92#else
93 (void)fg_start_period;
94 (void)bg_period;
95#endif
96
97
98#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
99 if (wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB) == 0) {
100 }
101#endif
102 ar6k_send_asleep_event_to_app(ar, false);
103 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Resume WoW successfully\n"));
104 } else {
105 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WoW does not invoked. skip resume"));
106 }
107 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
108}
109
110static void ar6000_wow_suspend(struct ar6_softc *ar)
111{
112#define WOW_LIST_ID 1
113 if (ar->arNetworkType != AP_NETWORK) {
114 /* Setup WoW for unicast & Arp request for our own IP
115 disable background scan. Set listen interval into 1000 TUs
116 Enable keepliave for 110 seconds
117 */
118 struct in_ifaddr **ifap = NULL;
119 struct in_ifaddr *ifa = NULL;
120 struct in_device *in_dev;
121 u8 macMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
122 int status;
123 WMI_ADD_WOW_PATTERN_CMD addWowCmd = { .filter = { 0 } };
124 WMI_DEL_WOW_PATTERN_CMD delWowCmd;
125 WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {false, true};
126 WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = true,
127 .hostReqDelay = 500 };/*500 ms delay*/
128
129 if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
130 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("System already go into wow mode!\n"));
131 return;
132 }
133
134 ar6000_TxDataCleanup(ar); /* IMPORTANT, otherwise there will be 11mA after listen interval as 1000*/
135
136#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
137 if (wmi_listeninterval_cmd(ar->arWmi, A_MAX_WOW_LISTEN_INTERVAL, 0) == 0) {
138 }
139#endif
140
141#if WOW_SET_SCAN_PARAMS
142 status = wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0xFFFF, 0, 0, 0, 0, 0, 0, 0);
143#endif
144 /* clear up our WoW pattern first */
145 delWowCmd.filter_list_id = WOW_LIST_ID;
146 delWowCmd.filter_id = 0;
147 wmi_del_wow_pattern_cmd(ar->arWmi, &delWowCmd);
148
149 /* setup unicast packet pattern for WoW */
150 if (ar->arNetDev->dev_addr[1]) {
151 addWowCmd.filter_list_id = WOW_LIST_ID;
152 addWowCmd.filter_size = 6; /* MAC address */
153 addWowCmd.filter_offset = 0;
154 status = wmi_add_wow_pattern_cmd(ar->arWmi, &addWowCmd, ar->arNetDev->dev_addr, macMask, addWowCmd.filter_size);
155 if (status) {
156 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to add WoW pattern\n"));
157 }
158 }
159 /* setup ARP request for our own IP */
160 if ((in_dev = __in_dev_get_rtnl(ar->arNetDev)) != NULL) {
161 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) {
162 if (!strcmp(ar->arNetDev->name, ifa->ifa_label)) {
163 break; /* found */
164 }
165 }
166 }
167 if (ifa && ifa->ifa_local) {
168 WMI_SET_IP_CMD ipCmd;
169 memset(&ipCmd, 0, sizeof(ipCmd));
170 ipCmd.ips[0] = ifa->ifa_local;
171 status = wmi_set_ip_cmd(ar->arWmi, &ipCmd);
172 if (status) {
173 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup IP for ARP agent\n"));
174 }
175 }
176
177#ifndef ATH6K_CONFIG_OTA_MODE
178 wmi_powermode_cmd(ar->arWmi, REC_POWER);
179#endif
180
181 status = wmi_set_wow_mode_cmd(ar->arWmi, &wowMode);
182 if (status) {
183 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enable wow mode\n"));
184 }
185 ar6k_send_asleep_event_to_app(ar, true);
186
187 status = wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode);
188 if (status) {
189 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to set host asleep\n"));
190 }
191
192 ar->arWowState = WLAN_WOW_STATE_SUSPENDING;
193 if (ar->arTxPending[ar->arControlEp]) {
194 u32 timeleft = wait_event_interruptible_timeout(arEvent,
195 ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
196 if (!timeleft || signal_pending(current)) {
197 /* what can I do? wow resume at once */
198 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WoW. Pending wmi control data %d\n", ar->arTxPending[ar->arControlEp]));
199 }
200 }
201
202 status = hifWaitForPendingRecv(ar->arHifDevice);
203
204 ar->arWowState = WLAN_WOW_STATE_SUSPENDED;
205 ar->arWlanPowerState = WLAN_POWER_STATE_WOW;
206 } else {
207 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Not allowed to go to WOW at this moment.\n"));
208 }
209}
210
211int ar6000_suspend_ev(void *context)
212{
213 int status = 0;
214 struct ar6_softc *ar = (struct ar6_softc *)context;
215 s16 pmmode = ar->arSuspendConfig;
216wow_not_connected:
217 switch (pmmode) {
218 case WLAN_SUSPEND_WOW:
219 if (ar->arWmiReady && ar->arWlanState==WLAN_ENABLED && ar->arConnected) {
220 ar6000_wow_suspend(ar);
221 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for wow mode %d\n", __func__, ar->arWlanPowerState));
222 } else {
223 pmmode = ar->arWow2Config;
224 goto wow_not_connected;
225 }
226 break;
227 case WLAN_SUSPEND_CUT_PWR:
228 /* fall through */
229 case WLAN_SUSPEND_CUT_PWR_IF_BT_OFF:
230 /* fall through */
231 case WLAN_SUSPEND_DEEP_SLEEP:
232 /* fall through */
233 default:
234 status = ar6000_update_wlan_pwr_state(ar, WLAN_DISABLED, true);
235 if (ar->arWlanPowerState==WLAN_POWER_STATE_ON ||
236 ar->arWlanPowerState==WLAN_POWER_STATE_WOW) {
237 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Strange suspend state for not wow mode %d", ar->arWlanPowerState));
238 }
239 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for %d mode pwr %d status %d\n", __func__, pmmode, ar->arWlanPowerState, status));
240 status = (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) ? 0 : A_EBUSY;
241 break;
242 }
243
244 ar->scan_triggered = 0;
245 return status;
246}
247
248int ar6000_resume_ev(void *context)
249{
250 struct ar6_softc *ar = (struct ar6_softc *)context;
251 u16 powerState = ar->arWlanPowerState;
252
253 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: enter previous state %d wowState %d\n", __func__, powerState, ar->arWowState));
254 switch (powerState) {
255 case WLAN_POWER_STATE_WOW:
256 ar6000_wow_resume(ar);
257 break;
258 case WLAN_POWER_STATE_CUT_PWR:
259 /* fall through */
260 case WLAN_POWER_STATE_DEEP_SLEEP:
261 ar6000_update_wlan_pwr_state(ar, WLAN_ENABLED, true);
262 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Resume for %d mode pwr %d\n", __func__, powerState, ar->arWlanPowerState));
263 break;
264 case WLAN_POWER_STATE_ON:
265 break;
266 default:
267 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange SDIO bus power mode!!\n"));
268 break;
269 }
270 return 0;
271}
272
273void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent)
274{
275 if (ar->arWowState!=WLAN_WOW_STATE_NONE) {
276 if (ar->arWowState==WLAN_WOW_STATE_SUSPENDING) {
277 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("\n%s: Received IRQ while we are wow suspending!!!\n\n", __func__));
278 return;
279 }
280 /* Wow resume from irq interrupt */
281 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: WoW resume from irq thread status %d\n", __func__, ar->arWlanPowerState));
282 ar6000_wow_resume(ar);
283 }
284}
285
286int ar6000_power_change_ev(void *context, u32 config)
287{
288 struct ar6_softc *ar = (struct ar6_softc *)context;
289 int status = 0;
290
291 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: power change event callback %d \n", __func__, config));
292 switch (config) {
293 case HIF_DEVICE_POWER_UP:
294 ar6000_restart_endpoint(ar->arNetDev);
295 status = 0;
296 break;
297 case HIF_DEVICE_POWER_DOWN:
298 case HIF_DEVICE_POWER_CUT:
299 status = 0;
300 break;
301 }
302 return status;
303}
304
305#endif /* CONFIG_PM */
306
307int
308ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
309{
310 int status = 0;
311 HIF_DEVICE_POWER_CHANGE_TYPE config;
312
313 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Cut power %d %d \n", __func__,state, ar->arWlanPowerState));
314#ifdef CONFIG_PM
315 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff));
316#endif
317 do {
318 if (state == WLAN_ENABLED) {
319 /* Not in cut power state.. exit */
320 if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
321 break;
322 }
323
324 /* Change the state to ON */
325 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
326
327
328 /* Indicate POWER_UP to HIF */
329 config = HIF_DEVICE_POWER_UP;
330 status = HIFConfigureDevice(ar->arHifDevice,
331 HIF_DEVICE_POWER_STATE_CHANGE,
332 &config,
333 sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
334
335 if (status == A_PENDING) {
336 } else if (status == 0) {
337 ar6000_restart_endpoint(ar->arNetDev);
338 status = 0;
339 }
340 } else if (state == WLAN_DISABLED) {
341
342
343 /* Already in cut power state.. exit */
344 if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) {
345 break;
346 }
347 ar6000_stop_endpoint(ar->arNetDev, true, false);
348
349 config = HIF_DEVICE_POWER_CUT;
350 status = HIFConfigureDevice(ar->arHifDevice,
351 HIF_DEVICE_POWER_STATE_CHANGE,
352 &config,
353 sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
354
355 ar->arWlanPowerState = WLAN_POWER_STATE_CUT_PWR;
356 }
357 } while (0);
358
359 return status;
360}
361
362int
363ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
364{
365 int status = 0;
366
367 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Deep sleep %d %d \n", __func__,state, ar->arWlanPowerState));
368#ifdef CONFIG_PM
369 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff));
370#endif
371 do {
372 WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode;
373
374 if (state == WLAN_ENABLED) {
375 u16 fg_start_period;
376
377 /* Not in deep sleep state.. exit */
378 if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) {
379 if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) {
380 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we resume from deep sleep %d\n", ar->arWlanPowerState));
381 }
382 break;
383 }
384
385 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
386 hostSleepMode.awake = true;
387 hostSleepMode.asleep = false;
388
389 if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)) != 0) {
390 break;
391 }
392
393 /* Change the state to ON */
394 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
395
396 /* Enable foreground scanning */
397 if ((status=wmi_scanparams_cmd(ar->arWmi, fg_start_period,
398 ar->scParams.fg_end_period,
399 ar->scParams.bg_period,
400 ar->scParams.minact_chdwell_time,
401 ar->scParams.maxact_chdwell_time,
402 ar->scParams.pas_chdwell_time,
403 ar->scParams.shortScanRatio,
404 ar->scParams.scanCtrlFlags,
405 ar->scParams.max_dfsch_act_time,
406 ar->scParams.maxact_scan_per_ssid)) != 0)
407 {
408 break;
409 }
410
411 if (ar->arNetworkType != AP_NETWORK)
412 {
413 if (ar->arSsidLen) {
414 if (ar6000_connect_to_ap(ar) != 0) {
415 /* no need to report error if connection failed */
416 break;
417 }
418 }
419 }
420 } else if (state == WLAN_DISABLED){
421 WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = false };
422
423 /* Already in deep sleep state.. exit */
424 if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) {
425 if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) {
426 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we suspend for deep sleep %d\n", ar->arWlanPowerState));
427 }
428 break;
429 }
430
431 if (ar->arNetworkType != AP_NETWORK)
432 {
433 /* Disconnect from the AP and disable foreground scanning */
434 AR6000_SPIN_LOCK(&ar->arLock, 0);
435 if (ar->arConnected == true || ar->arConnectPending == true) {
436 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
437 wmi_disconnect_cmd(ar->arWmi);
438 } else {
439 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
440 }
441 }
442
443 ar->scan_triggered = 0;
444
445 if ((status=wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != 0) {
446 break;
447 }
448
449 /* make sure we disable wow for deep sleep */
450 if ((status=wmi_set_wow_mode_cmd(ar->arWmi, &wowMode))!= 0)
451 {
452 break;
453 }
454
455 ar6000_TxDataCleanup(ar);
456#ifndef ATH6K_CONFIG_OTA_MODE
457 wmi_powermode_cmd(ar->arWmi, REC_POWER);
458#endif
459
460 hostSleepMode.awake = false;
461 hostSleepMode.asleep = true;
462 if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode))!= 0) {
463 break;
464 }
465 if (ar->arTxPending[ar->arControlEp]) {
466 u32 timeleft = wait_event_interruptible_timeout(arEvent,
467 ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
468 if (!timeleft || signal_pending(current)) {
469 status = A_ERROR;
470 break;
471 }
472 }
473 status = hifWaitForPendingRecv(ar->arHifDevice);
474
475 ar->arWlanPowerState = WLAN_POWER_STATE_DEEP_SLEEP;
476 }
477 } while (0);
478
479 if (status) {
480 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enter/exit deep sleep %d\n", state));
481 }
482
483 return status;
484}
485
486int
487ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool pmEvent)
488{
489 int status = 0;
490 u16 powerState, oldPowerState;
491 AR6000_WLAN_STATE oldstate = ar->arWlanState;
492 bool wlanOff = ar->arWlanOff;
493#ifdef CONFIG_PM
494 bool btOff = ar->arBTOff;
495#endif /* CONFIG_PM */
496
497 if ((state!=WLAN_DISABLED && state!=WLAN_ENABLED)) {
498 return A_ERROR;
499 }
500
501 if (ar->bIsDestroyProgress) {
502 return A_EBUSY;
503 }
504
505 if (down_interruptible(&ar->arSem)) {
506 return A_ERROR;
507 }
508
509 if (ar->bIsDestroyProgress) {
510 up(&ar->arSem);
511 return A_EBUSY;
512 }
513
514 ar->arWlanState = wlanOff ? WLAN_DISABLED : state;
515 oldPowerState = ar->arWlanPowerState;
516 if (state == WLAN_ENABLED) {
517 powerState = ar->arWlanPowerState;
518 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to ENABLE^^\n"));
519 if (!wlanOff) {
520 if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) {
521 status = ar6000_setup_deep_sleep_state(ar, WLAN_ENABLED);
522 } else if (powerState == WLAN_POWER_STATE_CUT_PWR) {
523 status = ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
524 }
525 }
526#ifdef CONFIG_PM
527 else if (pmEvent && wlanOff) {
528 bool allowCutPwr = ((!ar->arBTSharing) || btOff);
529 if ((powerState==WLAN_POWER_STATE_CUT_PWR) && (!allowCutPwr)) {
530 /* Come out of cut power */
531 ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
532 status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED);
533 }
534 }
535#endif /* CONFIG_PM */
536 } else if (state == WLAN_DISABLED) {
537 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to DISABLED~\n"));
538 powerState = WLAN_POWER_STATE_DEEP_SLEEP;
539#ifdef CONFIG_PM
540 if (pmEvent) { /* disable due to suspend */
541 bool suspendCutPwr = (ar->arSuspendConfig == WLAN_SUSPEND_CUT_PWR ||
542 (ar->arSuspendConfig == WLAN_SUSPEND_WOW &&
543 ar->arWow2Config==WLAN_SUSPEND_CUT_PWR));
544 bool suspendCutIfBtOff = ((ar->arSuspendConfig ==
545 WLAN_SUSPEND_CUT_PWR_IF_BT_OFF ||
546 (ar->arSuspendConfig == WLAN_SUSPEND_WOW &&
547 ar->arWow2Config==WLAN_SUSPEND_CUT_PWR_IF_BT_OFF)) &&
548 (!ar->arBTSharing || btOff));
549 if ((suspendCutPwr) ||
550 (suspendCutIfBtOff) ||
551 (ar->arWlanState==WLAN_POWER_STATE_CUT_PWR))
552 {
553 powerState = WLAN_POWER_STATE_CUT_PWR;
554 }
555 } else {
556 if ((wlanOff) &&
557 (ar->arWlanOffConfig == WLAN_OFF_CUT_PWR) &&
558 (!ar->arBTSharing || btOff))
559 {
560 /* For BT clock sharing designs, CUT_POWER depend on BT state */
561 powerState = WLAN_POWER_STATE_CUT_PWR;
562 }
563 }
564#endif /* CONFIG_PM */
565
566 if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) {
567 if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) {
568 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Load firmware before set to deep sleep\n"));
569 ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
570 }
571 status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED);
572 } else if (powerState == WLAN_POWER_STATE_CUT_PWR) {
573 status = ar6000_setup_cut_power_state(ar, WLAN_DISABLED);
574 }
575
576 }
577
578 if (status) {
579 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WLAN state %d\n", ar->arWlanState));
580 ar->arWlanState = oldstate;
581 } else if (status == 0) {
582 WMI_REPORT_SLEEP_STATE_EVENT wmiSleepEvent, *pSleepEvent = NULL;
583 if ((ar->arWlanPowerState == WLAN_POWER_STATE_ON) && (oldPowerState != WLAN_POWER_STATE_ON)) {
584 wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE;
585 pSleepEvent = &wmiSleepEvent;
586 } else if ((ar->arWlanPowerState != WLAN_POWER_STATE_ON) && (oldPowerState == WLAN_POWER_STATE_ON)) {
587 wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP;
588 pSleepEvent = &wmiSleepEvent;
589 }
590 if (pSleepEvent) {
591 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("SENT WLAN Sleep Event %d\n", wmiSleepEvent.sleepState));
592 }
593 }
594 up(&ar->arSem);
595 return status;
596}
597
598int
599ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 enable)
600{
601#ifdef CONFIG_PM
602 bool off = (enable == 0);
603 int status;
604 if (ar->arBTOff == off) {
605 return 0;
606 }
607 ar->arBTOff = off;
608 status = ar6000_update_wlan_pwr_state(ar, ar->arWlanOff ? WLAN_DISABLED : WLAN_ENABLED, false);
609 return status;
610#else
611 return 0;
612#endif
613}
614
615int
616ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
617{
618 int status;
619 bool off = (state == WLAN_DISABLED);
620 if (ar->arWlanOff == off) {
621 return 0;
622 }
623 ar->arWlanOff = off;
624 status = ar6000_update_wlan_pwr_state(ar, state, false);
625 return status;
626}
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c
deleted file mode 100644
index ae7c1dd96d8..00000000000
--- a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c
+++ /dev/null
@@ -1,455 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#include "ar6000_drv.h"
25
26#ifdef HTC_RAW_INTERFACE
27
28static void
29ar6000_htc_raw_read_cb(void *Context, struct htc_packet *pPacket)
30{
31 struct ar6_softc *ar = (struct ar6_softc *)Context;
32 raw_htc_buffer *busy;
33 HTC_RAW_STREAM_ID streamID;
34 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
35
36 busy = (raw_htc_buffer *)pPacket->pPktContext;
37 A_ASSERT(busy != NULL);
38
39 if (pPacket->Status == A_ECANCELED) {
40 /*
41 * HTC provides A_ECANCELED status when it doesn't want to be refilled
42 * (probably due to a shutdown)
43 */
44 return;
45 }
46
47 streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
48 A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
49
50#ifdef CF
51 if (down_trylock(&arRaw->raw_htc_read_sem[streamID])) {
52#else
53 if (down_interruptible(&arRaw->raw_htc_read_sem[streamID])) {
54#endif /* CF */
55 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
56 }
57
58 A_ASSERT((pPacket->Status != 0) ||
59 (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN)));
60
61 busy->length = pPacket->ActualLength + HTC_HEADER_LEN;
62 busy->currPtr = HTC_HEADER_LEN;
63 arRaw->read_buffer_available[streamID] = true;
64 //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("raw read cb: 0x%X 0x%X \n", busy->currPtr,busy->length);
65 up(&arRaw->raw_htc_read_sem[streamID]);
66
67 /* Signal the waiting process */
68 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) read process\n", streamID));
69 wake_up_interruptible(&arRaw->raw_htc_read_queue[streamID]);
70}
71
72static void
73ar6000_htc_raw_write_cb(void *Context, struct htc_packet *pPacket)
74{
75 struct ar6_softc *ar = (struct ar6_softc *)Context;
76 raw_htc_buffer *free;
77 HTC_RAW_STREAM_ID streamID;
78 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
79
80 free = (raw_htc_buffer *)pPacket->pPktContext;
81 A_ASSERT(free != NULL);
82
83 if (pPacket->Status == A_ECANCELED) {
84 /*
85 * HTC provides A_ECANCELED status when it doesn't want to be refilled
86 * (probably due to a shutdown)
87 */
88 return;
89 }
90
91 streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
92 A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
93
94#ifdef CF
95 if (down_trylock(&arRaw->raw_htc_write_sem[streamID])) {
96#else
97 if (down_interruptible(&arRaw->raw_htc_write_sem[streamID])) {
98#endif
99 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
100 }
101
102 A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN));
103
104 free->length = 0;
105 arRaw->write_buffer_available[streamID] = true;
106 up(&arRaw->raw_htc_write_sem[streamID]);
107
108 /* Signal the waiting process */
109 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) write process\n", streamID));
110 wake_up_interruptible(&arRaw->raw_htc_write_queue[streamID]);
111}
112
113/* connect to a service */
114static int ar6000_connect_raw_service(struct ar6_softc *ar,
115 HTC_RAW_STREAM_ID StreamID)
116{
117 int status;
118 struct htc_service_connect_resp response;
119 u8 streamNo;
120 struct htc_service_connect_req connect;
121
122 do {
123
124 A_MEMZERO(&connect,sizeof(connect));
125 /* pass the stream ID as meta data to the RAW streams service */
126 streamNo = (u8)StreamID;
127 connect.pMetaData = &streamNo;
128 connect.MetaDataLength = sizeof(u8);
129 /* these fields are the same for all endpoints */
130 connect.EpCallbacks.pContext = ar;
131 connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb;
132 connect.EpCallbacks.EpRecv = ar6000_htc_raw_read_cb;
133 /* simple interface, we don't need these optional callbacks */
134 connect.EpCallbacks.EpRecvRefill = NULL;
135 connect.EpCallbacks.EpSendFull = NULL;
136 connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM;
137
138 /* connect to the raw streams service, we may be able to get 1 or more
139 * connections, depending on WHAT is running on the target */
140 connect.ServiceID = HTC_RAW_STREAMS_SVC;
141
142 A_MEMZERO(&response,sizeof(response));
143
144 /* try to connect to the raw stream, it is okay if this fails with
145 * status HTC_SERVICE_NO_MORE_EP */
146 status = HTCConnectService(ar->arHtcTarget,
147 &connect,
148 &response);
149
150 if (status) {
151 if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) {
152 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC RAW , No more streams allowed \n"));
153 status = 0;
154 }
155 break;
156 }
157
158 /* set endpoint mapping for the RAW HTC streams */
159 arSetRawStream2EndpointIDMap(ar,StreamID,response.Endpoint);
160
161 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("HTC RAW : stream ID: %d, endpoint: %d\n",
162 StreamID, arRawStream2EndpointID(ar,StreamID)));
163
164 } while (false);
165
166 return status;
167}
168
169int ar6000_htc_raw_open(struct ar6_softc *ar)
170{
171 int status;
172 int streamID, endPt, count2;
173 raw_htc_buffer *buffer;
174 HTC_SERVICE_ID servicepriority;
175 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
176 if (!arRaw) {
177 arRaw = ar->arRawHtc = A_MALLOC(sizeof(AR_RAW_HTC_T));
178 if (arRaw) {
179 A_MEMZERO(arRaw, sizeof(AR_RAW_HTC_T));
180 }
181 }
182 A_ASSERT(ar->arHtcTarget != NULL);
183 if (!arRaw) {
184 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Faile to allocate memory for HTC RAW interface\n"));
185 return -ENOMEM;
186 }
187 /* wait for target */
188 status = HTCWaitTarget(ar->arHtcTarget);
189
190 if (status) {
191 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTCWaitTarget failed (%d)\n", status));
192 return -ENODEV;
193 }
194
195 for (endPt = 0; endPt < ENDPOINT_MAX; endPt++) {
196 arRaw->arEp2RawMapping[endPt] = HTC_RAW_STREAM_NOT_MAPPED;
197 }
198
199 for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) {
200 /* Initialize the data structures */
201 sema_init(&arRaw->raw_htc_read_sem[streamID], 1);
202 sema_init(&arRaw->raw_htc_write_sem[streamID], 1);
203 init_waitqueue_head(&arRaw->raw_htc_read_queue[streamID]);
204 init_waitqueue_head(&arRaw->raw_htc_write_queue[streamID]);
205
206 /* try to connect to the raw service */
207 status = ar6000_connect_raw_service(ar,streamID);
208
209 if (status) {
210 break;
211 }
212
213 if (arRawStream2EndpointID(ar,streamID) == 0) {
214 break;
215 }
216
217 for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) {
218 /* Initialize the receive buffers */
219 buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
220 memset(buffer, 0, sizeof(raw_htc_buffer));
221 buffer = &arRaw->raw_htc_read_buffer[streamID][count2];
222 memset(buffer, 0, sizeof(raw_htc_buffer));
223
224 SET_HTC_PACKET_INFO_RX_REFILL(&buffer->HTCPacket,
225 buffer,
226 buffer->data,
227 HTC_RAW_BUFFER_SIZE,
228 arRawStream2EndpointID(ar,streamID));
229
230 /* Queue buffers to HTC for receive */
231 if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != 0)
232 {
233 BMIInit();
234 return -EIO;
235 }
236 }
237
238 for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) {
239 /* Initialize the receive buffers */
240 buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
241 memset(buffer, 0, sizeof(raw_htc_buffer));
242 }
243
244 arRaw->read_buffer_available[streamID] = false;
245 arRaw->write_buffer_available[streamID] = true;
246 }
247
248 if (status) {
249 return -EIO;
250 }
251
252 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("HTC RAW, number of streams the target supports: %d \n", streamID));
253
254 servicepriority = HTC_RAW_STREAMS_SVC; /* only 1 */
255
256 /* set callbacks and priority list */
257 HTCSetCreditDistribution(ar->arHtcTarget,
258 ar,
259 NULL, /* use default */
260 NULL, /* use default */
261 &servicepriority,
262 1);
263
264 /* Start the HTC component */
265 if ((status = HTCStart(ar->arHtcTarget)) != 0) {
266 BMIInit();
267 return -EIO;
268 }
269
270 (ar)->arRawIfInit = true;
271
272 return 0;
273}
274
275int ar6000_htc_raw_close(struct ar6_softc *ar)
276{
277 A_PRINTF("ar6000_htc_raw_close called \n");
278 HTCStop(ar->arHtcTarget);
279
280 /* reset the device */
281 ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, false);
282 /* Initialize the BMI component */
283 BMIInit();
284
285 return 0;
286}
287
288raw_htc_buffer *
289get_filled_buffer(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID)
290{
291 int count;
292 raw_htc_buffer *busy;
293 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
294
295 /* Check for data */
296 for (count = 0; count < RAW_HTC_READ_BUFFERS_NUM; count ++) {
297 busy = &arRaw->raw_htc_read_buffer[StreamID][count];
298 if (busy->length) {
299 break;
300 }
301 }
302 if (busy->length) {
303 arRaw->read_buffer_available[StreamID] = true;
304 } else {
305 arRaw->read_buffer_available[StreamID] = false;
306 }
307
308 return busy;
309}
310
311ssize_t ar6000_htc_raw_read(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID,
312 char __user *buffer, size_t length)
313{
314 int readPtr;
315 raw_htc_buffer *busy;
316 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
317
318 if (arRawStream2EndpointID(ar,StreamID) == 0) {
319 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
320 return -EFAULT;
321 }
322
323 if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
324 return -ERESTARTSYS;
325 }
326
327 busy = get_filled_buffer(ar,StreamID);
328 while (!arRaw->read_buffer_available[StreamID]) {
329 up(&arRaw->raw_htc_read_sem[StreamID]);
330
331 /* Wait for the data */
332 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) read process\n", StreamID));
333 if (wait_event_interruptible(arRaw->raw_htc_read_queue[StreamID],
334 arRaw->read_buffer_available[StreamID]))
335 {
336 return -EINTR;
337 }
338 if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
339 return -ERESTARTSYS;
340 }
341 busy = get_filled_buffer(ar,StreamID);
342 }
343
344 /* Read the data */
345 readPtr = busy->currPtr;
346 if (length > busy->length - HTC_HEADER_LEN) {
347 length = busy->length - HTC_HEADER_LEN;
348 }
349 if (copy_to_user(buffer, &busy->data[readPtr], length)) {
350 up(&arRaw->raw_htc_read_sem[StreamID]);
351 return -EFAULT;
352 }
353
354 busy->currPtr += length;
355
356 if (busy->currPtr == busy->length)
357 {
358 busy->currPtr = 0;
359 busy->length = 0;
360 HTC_PACKET_RESET_RX(&busy->HTCPacket);
361 //AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("raw read ioctl: ep for packet:%d \n", busy->HTCPacket.Endpoint));
362 HTCAddReceivePkt(ar->arHtcTarget, &busy->HTCPacket);
363 }
364 arRaw->read_buffer_available[StreamID] = false;
365 up(&arRaw->raw_htc_read_sem[StreamID]);
366
367 return length;
368}
369
370static raw_htc_buffer *
371get_free_buffer(struct ar6_softc *ar, HTC_ENDPOINT_ID StreamID)
372{
373 int count;
374 raw_htc_buffer *free;
375 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
376
377 free = NULL;
378 for (count = 0; count < RAW_HTC_WRITE_BUFFERS_NUM; count ++) {
379 free = &arRaw->raw_htc_write_buffer[StreamID][count];
380 if (free->length == 0) {
381 break;
382 }
383 }
384 if (!free->length) {
385 arRaw->write_buffer_available[StreamID] = true;
386 } else {
387 arRaw->write_buffer_available[StreamID] = false;
388 }
389
390 return free;
391}
392
393ssize_t ar6000_htc_raw_write(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID,
394 char __user *buffer, size_t length)
395{
396 int writePtr;
397 raw_htc_buffer *free;
398 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
399 if (arRawStream2EndpointID(ar,StreamID) == 0) {
400 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
401 return -EFAULT;
402 }
403
404 if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
405 return -ERESTARTSYS;
406 }
407
408 /* Search for a free buffer */
409 free = get_free_buffer(ar,StreamID);
410
411 /* Check if there is space to write else wait */
412 while (!arRaw->write_buffer_available[StreamID]) {
413 up(&arRaw->raw_htc_write_sem[StreamID]);
414
415 /* Wait for buffer to become free */
416 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) write process\n", StreamID));
417 if (wait_event_interruptible(arRaw->raw_htc_write_queue[StreamID],
418 arRaw->write_buffer_available[StreamID]))
419 {
420 return -EINTR;
421 }
422 if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
423 return -ERESTARTSYS;
424 }
425 free = get_free_buffer(ar,StreamID);
426 }
427
428 /* Send the data */
429 writePtr = HTC_HEADER_LEN;
430 if (length > (HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN)) {
431 length = HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN;
432 }
433
434 if (copy_from_user(&free->data[writePtr], buffer, length)) {
435 up(&arRaw->raw_htc_read_sem[StreamID]);
436 return -EFAULT;
437 }
438
439 free->length = length;
440
441 SET_HTC_PACKET_INFO_TX(&free->HTCPacket,
442 free,
443 &free->data[writePtr],
444 length,
445 arRawStream2EndpointID(ar,StreamID),
446 AR6K_DATA_PKT_TAG);
447
448 HTCSendPkt(ar->arHtcTarget,&free->HTCPacket);
449
450 arRaw->write_buffer_available[StreamID] = false;
451 up(&arRaw->raw_htc_write_sem[StreamID]);
452
453 return length;
454}
455#endif /* HTC_RAW_INTERFACE */
diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c
deleted file mode 100644
index 5fdda4aa2fe..00000000000
--- a/drivers/staging/ath6kl/os/linux/cfg80211.c
+++ /dev/null
@@ -1,1892 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#include <linux/wireless.h>
25#include <linux/ieee80211.h>
26#include <net/cfg80211.h>
27#include <net/netlink.h>
28
29#include "ar6000_drv.h"
30
31
32extern A_WAITQUEUE_HEAD arEvent;
33extern unsigned int wmitimeout;
34extern int reconnect_flag;
35
36
37#define RATETAB_ENT(_rate, _rateid, _flags) { \
38 .bitrate = (_rate), \
39 .flags = (_flags), \
40 .hw_value = (_rateid), \
41}
42
43#define CHAN2G(_channel, _freq, _flags) { \
44 .band = IEEE80211_BAND_2GHZ, \
45 .hw_value = (_channel), \
46 .center_freq = (_freq), \
47 .flags = (_flags), \
48 .max_antenna_gain = 0, \
49 .max_power = 30, \
50}
51
52#define CHAN5G(_channel, _flags) { \
53 .band = IEEE80211_BAND_5GHZ, \
54 .hw_value = (_channel), \
55 .center_freq = 5000 + (5 * (_channel)), \
56 .flags = (_flags), \
57 .max_antenna_gain = 0, \
58 .max_power = 30, \
59}
60
61static struct
62ieee80211_rate ar6k_rates[] = {
63 RATETAB_ENT(10, 0x1, 0),
64 RATETAB_ENT(20, 0x2, 0),
65 RATETAB_ENT(55, 0x4, 0),
66 RATETAB_ENT(110, 0x8, 0),
67 RATETAB_ENT(60, 0x10, 0),
68 RATETAB_ENT(90, 0x20, 0),
69 RATETAB_ENT(120, 0x40, 0),
70 RATETAB_ENT(180, 0x80, 0),
71 RATETAB_ENT(240, 0x100, 0),
72 RATETAB_ENT(360, 0x200, 0),
73 RATETAB_ENT(480, 0x400, 0),
74 RATETAB_ENT(540, 0x800, 0),
75};
76
77#define ar6k_a_rates (ar6k_rates + 4)
78#define ar6k_a_rates_size 8
79#define ar6k_g_rates (ar6k_rates + 0)
80#define ar6k_g_rates_size 12
81
82static struct
83ieee80211_channel ar6k_2ghz_channels[] = {
84 CHAN2G(1, 2412, 0),
85 CHAN2G(2, 2417, 0),
86 CHAN2G(3, 2422, 0),
87 CHAN2G(4, 2427, 0),
88 CHAN2G(5, 2432, 0),
89 CHAN2G(6, 2437, 0),
90 CHAN2G(7, 2442, 0),
91 CHAN2G(8, 2447, 0),
92 CHAN2G(9, 2452, 0),
93 CHAN2G(10, 2457, 0),
94 CHAN2G(11, 2462, 0),
95 CHAN2G(12, 2467, 0),
96 CHAN2G(13, 2472, 0),
97 CHAN2G(14, 2484, 0),
98};
99
100static struct
101ieee80211_channel ar6k_5ghz_a_channels[] = {
102 CHAN5G(34, 0), CHAN5G(36, 0),
103 CHAN5G(38, 0), CHAN5G(40, 0),
104 CHAN5G(42, 0), CHAN5G(44, 0),
105 CHAN5G(46, 0), CHAN5G(48, 0),
106 CHAN5G(52, 0), CHAN5G(56, 0),
107 CHAN5G(60, 0), CHAN5G(64, 0),
108 CHAN5G(100, 0), CHAN5G(104, 0),
109 CHAN5G(108, 0), CHAN5G(112, 0),
110 CHAN5G(116, 0), CHAN5G(120, 0),
111 CHAN5G(124, 0), CHAN5G(128, 0),
112 CHAN5G(132, 0), CHAN5G(136, 0),
113 CHAN5G(140, 0), CHAN5G(149, 0),
114 CHAN5G(153, 0), CHAN5G(157, 0),
115 CHAN5G(161, 0), CHAN5G(165, 0),
116 CHAN5G(184, 0), CHAN5G(188, 0),
117 CHAN5G(192, 0), CHAN5G(196, 0),
118 CHAN5G(200, 0), CHAN5G(204, 0),
119 CHAN5G(208, 0), CHAN5G(212, 0),
120 CHAN5G(216, 0),
121};
122
123static struct
124ieee80211_supported_band ar6k_band_2ghz = {
125 .n_channels = ARRAY_SIZE(ar6k_2ghz_channels),
126 .channels = ar6k_2ghz_channels,
127 .n_bitrates = ar6k_g_rates_size,
128 .bitrates = ar6k_g_rates,
129};
130
131static struct
132ieee80211_supported_band ar6k_band_5ghz = {
133 .n_channels = ARRAY_SIZE(ar6k_5ghz_a_channels),
134 .channels = ar6k_5ghz_a_channels,
135 .n_bitrates = ar6k_a_rates_size,
136 .bitrates = ar6k_a_rates,
137};
138
139static int
140ar6k_set_wpa_version(struct ar6_softc *ar, enum nl80211_wpa_versions wpa_version)
141{
142
143 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: %u\n", __func__, wpa_version));
144
145 if (!wpa_version) {
146 ar->arAuthMode = NONE_AUTH;
147 } else if (wpa_version & NL80211_WPA_VERSION_1) {
148 ar->arAuthMode = WPA_AUTH;
149 } else if (wpa_version & NL80211_WPA_VERSION_2) {
150 ar->arAuthMode = WPA2_AUTH;
151 } else {
152 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
153 ("%s: %u not spported\n", __func__, wpa_version));
154 return -ENOTSUPP;
155 }
156
157 return 0;
158}
159
160static int
161ar6k_set_auth_type(struct ar6_softc *ar, enum nl80211_auth_type auth_type)
162{
163
164 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, auth_type));
165
166 switch (auth_type) {
167 case NL80211_AUTHTYPE_OPEN_SYSTEM:
168 ar->arDot11AuthMode = OPEN_AUTH;
169 break;
170 case NL80211_AUTHTYPE_SHARED_KEY:
171 ar->arDot11AuthMode = SHARED_AUTH;
172 break;
173 case NL80211_AUTHTYPE_NETWORK_EAP:
174 ar->arDot11AuthMode = LEAP_AUTH;
175 break;
176
177 case NL80211_AUTHTYPE_AUTOMATIC:
178 ar->arDot11AuthMode = OPEN_AUTH;
179 ar->arAutoAuthStage = AUTH_OPEN_IN_PROGRESS;
180 break;
181
182 default:
183 ar->arDot11AuthMode = OPEN_AUTH;
184 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
185 ("%s: 0x%x not spported\n", __func__, auth_type));
186 return -ENOTSUPP;
187 }
188
189 return 0;
190}
191
192static int
193ar6k_set_cipher(struct ar6_softc *ar, u32 cipher, bool ucast)
194{
195 u8 *ar_cipher = ucast ? &ar->arPairwiseCrypto :
196 &ar->arGroupCrypto;
197 u8 *ar_cipher_len = ucast ? &ar->arPairwiseCryptoLen :
198 &ar->arGroupCryptoLen;
199
200 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
201 ("%s: cipher 0x%x, ucast %u\n", __func__, cipher, ucast));
202
203 switch (cipher) {
204 case 0:
205 case IW_AUTH_CIPHER_NONE:
206 *ar_cipher = NONE_CRYPT;
207 *ar_cipher_len = 0;
208 break;
209 case WLAN_CIPHER_SUITE_WEP40:
210 *ar_cipher = WEP_CRYPT;
211 *ar_cipher_len = 5;
212 break;
213 case WLAN_CIPHER_SUITE_WEP104:
214 *ar_cipher = WEP_CRYPT;
215 *ar_cipher_len = 13;
216 break;
217 case WLAN_CIPHER_SUITE_TKIP:
218 *ar_cipher = TKIP_CRYPT;
219 *ar_cipher_len = 0;
220 break;
221 case WLAN_CIPHER_SUITE_CCMP:
222 *ar_cipher = AES_CRYPT;
223 *ar_cipher_len = 0;
224 break;
225 default:
226 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
227 ("%s: cipher 0x%x not supported\n", __func__, cipher));
228 return -ENOTSUPP;
229 }
230
231 return 0;
232}
233
234static void
235ar6k_set_key_mgmt(struct ar6_softc *ar, u32 key_mgmt)
236{
237 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, key_mgmt));
238
239 if (WLAN_AKM_SUITE_PSK == key_mgmt) {
240 if (WPA_AUTH == ar->arAuthMode) {
241 ar->arAuthMode = WPA_PSK_AUTH;
242 } else if (WPA2_AUTH == ar->arAuthMode) {
243 ar->arAuthMode = WPA2_PSK_AUTH;
244 }
245 } else if (WLAN_AKM_SUITE_8021X != key_mgmt) {
246 ar->arAuthMode = NONE_AUTH;
247 }
248}
249
250static int
251ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
252 struct cfg80211_connect_params *sme)
253{
254 struct ar6_softc *ar = ar6k_priv(dev);
255 int status;
256
257 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
258 ar->smeState = SME_CONNECTING;
259
260 if(ar->arWmiReady == false) {
261 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__));
262 return -EIO;
263 }
264
265 if(ar->arWlanState == WLAN_DISABLED) {
266 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
267 return -EIO;
268 }
269
270 if(ar->bIsDestroyProgress) {
271 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: destroy in progress\n", __func__));
272 return -EBUSY;
273 }
274
275 if(!sme->ssid_len || IEEE80211_MAX_SSID_LEN < sme->ssid_len) {
276 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
277 return -EINVAL;
278 }
279
280 if(ar->arSkipScan == true &&
281 ((sme->channel && sme->channel->center_freq == 0) ||
282 (sme->bssid && !sme->bssid[0] && !sme->bssid[1] && !sme->bssid[2] &&
283 !sme->bssid[3] && !sme->bssid[4] && !sme->bssid[5])))
284 {
285 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s:SkipScan: channel or bssid invalid\n", __func__));
286 return -EINVAL;
287 }
288
289 if(down_interruptible(&ar->arSem)) {
290 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
291 return -ERESTARTSYS;
292 }
293
294 if(ar->bIsDestroyProgress) {
295 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
296 up(&ar->arSem);
297 return -EBUSY;
298 }
299
300 if(ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
301 /*
302 * sleep until the command queue drains
303 */
304 wait_event_interruptible_timeout(arEvent,
305 ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
306 if (signal_pending(current)) {
307 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: cmd queue drain timeout\n", __func__));
308 up(&ar->arSem);
309 return -EINTR;
310 }
311 }
312
313 if(ar->arConnected == true &&
314 ar->arSsidLen == sme->ssid_len &&
315 !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) {
316 reconnect_flag = true;
317 status = wmi_reconnect_cmd(ar->arWmi,
318 ar->arReqBssid,
319 ar->arChannelHint);
320
321 up(&ar->arSem);
322 if (status) {
323 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", __func__));
324 return -EIO;
325 }
326 return 0;
327 } else if(ar->arSsidLen == sme->ssid_len &&
328 !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) {
329 ar6000_disconnect(ar);
330 }
331
332 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
333 ar->arSsidLen = sme->ssid_len;
334 memcpy(ar->arSsid, sme->ssid, sme->ssid_len);
335
336 if(sme->channel){
337 ar->arChannelHint = sme->channel->center_freq;
338 }
339
340 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
341 if(sme->bssid){
342 if(memcmp(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
343 memcpy(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid));
344 }
345 }
346
347 ar6k_set_wpa_version(ar, sme->crypto.wpa_versions);
348 ar6k_set_auth_type(ar, sme->auth_type);
349
350 if(sme->crypto.n_ciphers_pairwise) {
351 ar6k_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
352 } else {
353 ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
354 }
355 ar6k_set_cipher(ar, sme->crypto.cipher_group, false);
356
357 if(sme->crypto.n_akm_suites) {
358 ar6k_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
359 }
360
361 if((sme->key_len) &&
362 (NONE_AUTH == ar->arAuthMode) &&
363 (WEP_CRYPT == ar->arPairwiseCrypto)) {
364 struct ar_key *key = NULL;
365
366 if(sme->key_idx < WMI_MIN_KEY_INDEX || sme->key_idx > WMI_MAX_KEY_INDEX) {
367 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
368 ("%s: key index %d out of bounds\n", __func__, sme->key_idx));
369 up(&ar->arSem);
370 return -ENOENT;
371 }
372
373 key = &ar->keys[sme->key_idx];
374 key->key_len = sme->key_len;
375 memcpy(key->key, sme->key, key->key_len);
376 key->cipher = ar->arPairwiseCrypto;
377 ar->arDefTxKeyIndex = sme->key_idx;
378
379 wmi_addKey_cmd(ar->arWmi, sme->key_idx,
380 ar->arPairwiseCrypto,
381 GROUP_USAGE | TX_USAGE,
382 key->key_len,
383 NULL,
384 key->key, KEY_OP_INIT_VAL, NULL,
385 NO_SYNC_WMIFLAG);
386 }
387
388 if (!ar->arUserBssFilter) {
389 if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) {
390 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
391 up(&ar->arSem);
392 return -EIO;
393 }
394 }
395
396 ar->arNetworkType = ar->arNextMode;
397
398 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
399 " PW crypto %d PW crypto Len %d GRP crypto %d"\
400 " GRP crypto Len %d channel hint %u\n",
401 __func__, ar->arAuthMode, ar->arDot11AuthMode,
402 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
403 ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
404
405 reconnect_flag = 0;
406 status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
407 ar->arDot11AuthMode, ar->arAuthMode,
408 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
409 ar->arGroupCrypto,ar->arGroupCryptoLen,
410 ar->arSsidLen, ar->arSsid,
411 ar->arReqBssid, ar->arChannelHint,
412 ar->arConnectCtrlFlags);
413
414 up(&ar->arSem);
415
416 if (A_EINVAL == status) {
417 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
418 ar->arSsidLen = 0;
419 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Invalid request\n", __func__));
420 return -ENOENT;
421 } else if (status) {
422 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_connect_cmd failed\n", __func__));
423 return -EIO;
424 }
425
426 if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
427 ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
428 {
429 A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
430 }
431
432 ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
433 ar->arConnectPending = true;
434
435 return 0;
436}
437
438void
439ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel,
440 u8 *bssid, u16 listenInterval,
441 u16 beaconInterval,NETWORK_TYPE networkType,
442 u8 beaconIeLen, u8 assocReqLen,
443 u8 assocRespLen, u8 *assocInfo)
444{
445 u16 size = 0;
446 u16 capability = 0;
447 struct cfg80211_bss *bss = NULL;
448 struct ieee80211_mgmt *mgmt = NULL;
449 struct ieee80211_channel *ibss_channel = NULL;
450 s32 signal = 50 * 100;
451 u8 ie_buf_len = 0;
452 unsigned char ie_buf[256];
453 unsigned char *ptr_ie_buf = ie_buf;
454 unsigned char *ieeemgmtbuf = NULL;
455 u8 source_mac[ATH_MAC_LEN];
456
457 u8 assocReqIeOffset = sizeof(u16) + /* capinfo*/
458 sizeof(u16); /* listen interval */
459 u8 assocRespIeOffset = sizeof(u16) + /* capinfo*/
460 sizeof(u16) + /* status Code */
461 sizeof(u16); /* associd */
462 u8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset;
463 u8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset;
464
465 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
466
467 assocReqLen -= assocReqIeOffset;
468 assocRespLen -= assocRespIeOffset;
469
470 ar->arAutoAuthStage = AUTH_IDLE;
471
472 if((ADHOC_NETWORK & networkType)) {
473 if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
474 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
475 ("%s: ath6k not in ibss mode\n", __func__));
476 return;
477 }
478 }
479
480 if((INFRA_NETWORK & networkType)) {
481 if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
482 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
483 ("%s: ath6k not in station mode\n", __func__));
484 return;
485 }
486 }
487
488 /* Before informing the join/connect event, make sure that
489 * bss entry is present in scan list, if it not present
490 * construct and insert into scan list, otherwise that
491 * event will be dropped on the way by cfg80211, due to
492 * this keys will not be plumbed in case of WEP and
493 * application will not be aware of join/connect status. */
494 bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
495 ar->wdev->ssid, ar->wdev->ssid_len,
496 ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
497 ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
498
499 /*
500 * Earlier we were updating the cfg about bss by making a beacon frame
501 * only if the entry for bss is not there. This can have some issue if
502 * ROAM event is generated and a heavy traffic is ongoing. The ROAM
503 * event is handled through a work queue and by the time it really gets
504 * handled, BSS would have been aged out. So it is better to update the
505 * cfg about BSS irrespective of its entry being present right now or
506 * not.
507 */
508
509 if (ADHOC_NETWORK & networkType) {
510 /* construct 802.11 mgmt beacon */
511 if(ptr_ie_buf) {
512 *ptr_ie_buf++ = WLAN_EID_SSID;
513 *ptr_ie_buf++ = ar->arSsidLen;
514 memcpy(ptr_ie_buf, ar->arSsid, ar->arSsidLen);
515 ptr_ie_buf +=ar->arSsidLen;
516
517 *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
518 *ptr_ie_buf++ = 2; /* length */
519 *ptr_ie_buf++ = 0; /* ATIM window */
520 *ptr_ie_buf++ = 0; /* ATIM window */
521
522 /* TODO: update ibss params and include supported rates,
523 * DS param set, extened support rates, wmm. */
524
525 ie_buf_len = ptr_ie_buf - ie_buf;
526 }
527
528 capability |= IEEE80211_CAPINFO_IBSS;
529 if(WEP_CRYPT == ar->arPairwiseCrypto) {
530 capability |= IEEE80211_CAPINFO_PRIVACY;
531 }
532 memcpy(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN);
533 ptr_ie_buf = ie_buf;
534 } else {
535 capability = *(u16 *)(&assocInfo[beaconIeLen]);
536 memcpy(source_mac, bssid, ATH_MAC_LEN);
537 ptr_ie_buf = assocReqIe;
538 ie_buf_len = assocReqLen;
539 }
540
541 size = offsetof(struct ieee80211_mgmt, u)
542 + sizeof(mgmt->u.beacon)
543 + ie_buf_len;
544
545 ieeemgmtbuf = A_MALLOC_NOWAIT(size);
546 if(!ieeemgmtbuf) {
547 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
548 ("%s: ieeeMgmtbuf alloc error\n", __func__));
549 cfg80211_put_bss(bss);
550 return;
551 }
552
553 A_MEMZERO(ieeemgmtbuf, size);
554 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
555 mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
556 memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
557 memcpy(mgmt->sa, source_mac, ATH_MAC_LEN);
558 memcpy(mgmt->bssid, bssid, ATH_MAC_LEN);
559 mgmt->u.beacon.beacon_int = beaconInterval;
560 mgmt->u.beacon.capab_info = capability;
561 memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
562
563 ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
564
565 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
566 ("%s: inform bss with bssid %pM channel %d beaconInterval %d "
567 "capability 0x%x\n", __func__, mgmt->bssid,
568 ibss_channel->hw_value, beaconInterval, capability));
569
570 bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
571 ibss_channel, mgmt,
572 le16_to_cpu(size),
573 signal, GFP_KERNEL);
574 kfree(ieeemgmtbuf);
575 cfg80211_put_bss(bss);
576
577 if((ADHOC_NETWORK & networkType)) {
578 cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
579 return;
580 }
581
582 if (false == ar->arConnected) {
583 /* inform connect result to cfg80211 */
584 ar->smeState = SME_DISCONNECTED;
585 cfg80211_connect_result(ar->arNetDev, bssid,
586 assocReqIe, assocReqLen,
587 assocRespIe, assocRespLen,
588 WLAN_STATUS_SUCCESS, GFP_KERNEL);
589 } else {
590 /* inform roam event to cfg80211 */
591 cfg80211_roamed(ar->arNetDev, ibss_channel, bssid,
592 assocReqIe, assocReqLen,
593 assocRespIe, assocRespLen,
594 GFP_KERNEL);
595 }
596}
597
598static int
599ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
600 u16 reason_code)
601{
602 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
603
604 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code));
605
606 if(ar->arWmiReady == false) {
607 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
608 return -EIO;
609 }
610
611 if(ar->arWlanState == WLAN_DISABLED) {
612 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
613 return -EIO;
614 }
615
616 if(ar->bIsDestroyProgress) {
617 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
618 return -EBUSY;
619 }
620
621 if(down_interruptible(&ar->arSem)) {
622 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
623 return -ERESTARTSYS;
624 }
625
626 reconnect_flag = 0;
627 ar6000_disconnect(ar);
628 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
629 ar->arSsidLen = 0;
630
631 if (ar->arSkipScan == false) {
632 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
633 }
634
635 up(&ar->arSem);
636
637 return 0;
638}
639
640void
641ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
642 u8 *bssid, u8 assocRespLen,
643 u8 *assocInfo, u16 protocolReasonStatus)
644{
645
646 u16 status;
647
648 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
649
650 if (ar->scan_request) {
651 cfg80211_scan_done(ar->scan_request, true);
652 ar->scan_request = NULL;
653 }
654 if((ADHOC_NETWORK & ar->arNetworkType)) {
655 if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
656 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
657 ("%s: ath6k not in ibss mode\n", __func__));
658 return;
659 }
660 A_MEMZERO(bssid, ETH_ALEN);
661 cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
662 return;
663 }
664
665 if((INFRA_NETWORK & ar->arNetworkType)) {
666 if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
667 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
668 ("%s: ath6k not in station mode\n", __func__));
669 return;
670 }
671 }
672
673 if(true == ar->arConnectPending) {
674 if(NO_NETWORK_AVAIL == reason) {
675 /* connect cmd failed */
676 wmi_disconnect_cmd(ar->arWmi);
677 } else if (reason == DISCONNECT_CMD) {
678 if (ar->arAutoAuthStage) {
679 /*
680 * If the current auth algorithm is open try shared
681 * and make autoAuthStage idle. We do not make it
682 * leap for now being.
683 */
684 if (ar->arDot11AuthMode == OPEN_AUTH) {
685 struct ar_key *key = NULL;
686 key = &ar->keys[ar->arDefTxKeyIndex];
687 if (down_interruptible(&ar->arSem)) {
688 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
689 return;
690 }
691
692
693 ar->arDot11AuthMode = SHARED_AUTH;
694 ar->arAutoAuthStage = AUTH_IDLE;
695
696 wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
697 ar->arPairwiseCrypto,
698 GROUP_USAGE | TX_USAGE,
699 key->key_len,
700 NULL,
701 key->key, KEY_OP_INIT_VAL, NULL,
702 NO_SYNC_WMIFLAG);
703
704 status = wmi_connect_cmd(ar->arWmi,
705 ar->arNetworkType,
706 ar->arDot11AuthMode,
707 ar->arAuthMode,
708 ar->arPairwiseCrypto,
709 ar->arPairwiseCryptoLen,
710 ar->arGroupCrypto,
711 ar->arGroupCryptoLen,
712 ar->arSsidLen,
713 ar->arSsid,
714 ar->arReqBssid,
715 ar->arChannelHint,
716 ar->arConnectCtrlFlags);
717 up(&ar->arSem);
718
719 } else if (ar->arDot11AuthMode == SHARED_AUTH) {
720 /* should not reach here */
721 }
722 } else {
723 ar->arConnectPending = false;
724 if (ar->smeState == SME_CONNECTING) {
725 cfg80211_connect_result(ar->arNetDev, bssid,
726 NULL, 0,
727 NULL, 0,
728 WLAN_STATUS_UNSPECIFIED_FAILURE,
729 GFP_KERNEL);
730 } else {
731 cfg80211_disconnected(ar->arNetDev,
732 reason,
733 NULL, 0,
734 GFP_KERNEL);
735 }
736 ar->smeState = SME_DISCONNECTED;
737 }
738 }
739 } else {
740 if (reason != DISCONNECT_CMD)
741 wmi_disconnect_cmd(ar->arWmi);
742 }
743}
744
745void
746ar6k_cfg80211_scan_node(void *arg, bss_t *ni)
747{
748 struct wiphy *wiphy = (struct wiphy *)arg;
749 u16 size;
750 unsigned char *ieeemgmtbuf = NULL;
751 struct ieee80211_mgmt *mgmt;
752 struct ieee80211_channel *channel;
753 struct ieee80211_supported_band *band;
754 struct ieee80211_common_ie *cie;
755 s32 signal;
756 int freq;
757
758 cie = &ni->ni_cie;
759
760#define CHAN_IS_11A(x) (!((x >= 2412) && (x <= 2484)))
761 if(CHAN_IS_11A(cie->ie_chan)) {
762 /* 11a */
763 band = wiphy->bands[IEEE80211_BAND_5GHZ];
764 } else if((cie->ie_erp) || (cie->ie_xrates)) {
765 /* 11g */
766 band = wiphy->bands[IEEE80211_BAND_2GHZ];
767 } else {
768 /* 11b */
769 band = wiphy->bands[IEEE80211_BAND_2GHZ];
770 }
771
772 size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
773 ieeemgmtbuf = A_MALLOC_NOWAIT(size);
774 if(!ieeemgmtbuf)
775 {
776 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ieeeMgmtbuf alloc error\n", __func__));
777 return;
778 }
779
780 /* Note:
781 TODO: Update target to include 802.11 mac header while sending bss info.
782 Target removes 802.11 mac header while sending the bss info to host,
783 cfg80211 needs it, for time being just filling the da, sa and bssid fields alone.
784 */
785 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
786 memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
787 memcpy(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN);
788 memcpy(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN);
789 memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
790 ni->ni_buf, ni->ni_framelen);
791
792 freq = cie->ie_chan;
793 channel = ieee80211_get_channel(wiphy, freq);
794 signal = ni->ni_snr * 100;
795
796 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
797 ("%s: bssid %pM channel %d freq %d size %d\n", __func__,
798 mgmt->bssid, channel->hw_value, freq, size));
799 cfg80211_inform_bss_frame(wiphy, channel, mgmt,
800 le16_to_cpu(size),
801 signal, GFP_KERNEL);
802
803 kfree (ieeemgmtbuf);
804}
805
806static int
807ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
808 struct cfg80211_scan_request *request)
809{
810 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
811 int ret = 0;
812 u32 forceFgScan = 0;
813
814 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
815
816 if(ar->arWmiReady == false) {
817 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
818 return -EIO;
819 }
820
821 if(ar->arWlanState == WLAN_DISABLED) {
822 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
823 return -EIO;
824 }
825
826 if (!ar->arUserBssFilter) {
827 if (wmi_bssfilter_cmd(ar->arWmi,
828 (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER),
829 0) != 0) {
830 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
831 return -EIO;
832 }
833 }
834
835 if(request->n_ssids &&
836 request->ssids[0].ssid_len) {
837 u8 i;
838
839 if(request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) {
840 request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
841 }
842
843 for (i = 0; i < request->n_ssids; i++) {
844 wmi_probedSsid_cmd(ar->arWmi, i+1, SPECIFIC_SSID_FLAG,
845 request->ssids[i].ssid_len,
846 request->ssids[i].ssid);
847 }
848 }
849
850 if(ar->arConnected) {
851 forceFgScan = 1;
852 }
853
854 if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, false, \
855 0, 0, 0, NULL) != 0) {
856 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__));
857 ret = -EIO;
858 }
859
860 ar->scan_request = request;
861
862 return ret;
863}
864
865void
866ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status)
867{
868
869 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
870
871 if (!ar->scan_request)
872 return;
873
874 if ((status == A_ECANCELED) || (status == A_EBUSY)) {
875 cfg80211_scan_done(ar->scan_request, true);
876 goto out;
877 }
878
879 /* Translate data to cfg80211 mgmt format */
880 wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
881
882 cfg80211_scan_done(ar->scan_request, false);
883
884 if(ar->scan_request->n_ssids &&
885 ar->scan_request->ssids[0].ssid_len) {
886 u8 i;
887
888 for (i = 0; i < ar->scan_request->n_ssids; i++) {
889 wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG,
890 0, NULL);
891 }
892 }
893
894out:
895 ar->scan_request = NULL;
896}
897
898static int
899ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
900 u8 key_index, bool pairwise, const u8 *mac_addr,
901 struct key_params *params)
902{
903 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
904 struct ar_key *key = NULL;
905 u8 key_usage;
906 u8 key_type;
907 int status = 0;
908
909 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__));
910
911 if(ar->arWmiReady == false) {
912 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
913 return -EIO;
914 }
915
916 if(ar->arWlanState == WLAN_DISABLED) {
917 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
918 return -EIO;
919 }
920
921 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
922 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
923 ("%s: key index %d out of bounds\n", __func__, key_index));
924 return -ENOENT;
925 }
926
927 key = &ar->keys[key_index];
928 A_MEMZERO(key, sizeof(struct ar_key));
929
930 if(!mac_addr || is_broadcast_ether_addr(mac_addr)) {
931 key_usage = GROUP_USAGE;
932 } else {
933 key_usage = PAIRWISE_USAGE;
934 }
935
936 if(params) {
937 if(params->key_len > WLAN_MAX_KEY_LEN ||
938 params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
939 return -EINVAL;
940
941 key->key_len = params->key_len;
942 memcpy(key->key, params->key, key->key_len);
943 key->seq_len = params->seq_len;
944 memcpy(key->seq, params->seq, key->seq_len);
945 key->cipher = params->cipher;
946 }
947
948 switch (key->cipher) {
949 case WLAN_CIPHER_SUITE_WEP40:
950 case WLAN_CIPHER_SUITE_WEP104:
951 key_type = WEP_CRYPT;
952 break;
953
954 case WLAN_CIPHER_SUITE_TKIP:
955 key_type = TKIP_CRYPT;
956 break;
957
958 case WLAN_CIPHER_SUITE_CCMP:
959 key_type = AES_CRYPT;
960 break;
961
962 default:
963 return -ENOTSUPP;
964 }
965
966 if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
967 (GROUP_USAGE & key_usage))
968 {
969 A_UNTIMEOUT(&ar->disconnect_timer);
970 }
971
972 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
973 ("%s: index %d, key_len %d, key_type 0x%x,"\
974 " key_usage 0x%x, seq_len %d\n",
975 __func__, key_index, key->key_len, key_type,
976 key_usage, key->seq_len));
977
978 ar->arDefTxKeyIndex = key_index;
979 status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage,
980 key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
981 (u8 *)mac_addr, SYNC_BOTH_WMIFLAG);
982
983
984 if (status) {
985 return -EIO;
986 }
987
988 return 0;
989}
990
991static int
992ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
993 u8 key_index, bool pairwise, const u8 *mac_addr)
994{
995 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
996
997 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
998
999 if(ar->arWmiReady == false) {
1000 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1001 return -EIO;
1002 }
1003
1004 if(ar->arWlanState == WLAN_DISABLED) {
1005 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1006 return -EIO;
1007 }
1008
1009 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1010 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1011 ("%s: key index %d out of bounds\n", __func__, key_index));
1012 return -ENOENT;
1013 }
1014
1015 if(!ar->keys[key_index].key_len) {
1016 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d is empty\n", __func__, key_index));
1017 return 0;
1018 }
1019
1020 ar->keys[key_index].key_len = 0;
1021
1022 return wmi_deleteKey_cmd(ar->arWmi, key_index);
1023}
1024
1025
1026static int
1027ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1028 u8 key_index, bool pairwise, const u8 *mac_addr,
1029 void *cookie,
1030 void (*callback)(void *cookie, struct key_params*))
1031{
1032 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1033 struct ar_key *key = NULL;
1034 struct key_params params;
1035
1036 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1037
1038 if(ar->arWmiReady == false) {
1039 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1040 return -EIO;
1041 }
1042
1043 if(ar->arWlanState == WLAN_DISABLED) {
1044 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1045 return -EIO;
1046 }
1047
1048 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1049 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1050 ("%s: key index %d out of bounds\n", __func__, key_index));
1051 return -ENOENT;
1052 }
1053
1054 key = &ar->keys[key_index];
1055 A_MEMZERO(&params, sizeof(params));
1056 params.cipher = key->cipher;
1057 params.key_len = key->key_len;
1058 params.seq_len = key->seq_len;
1059 params.seq = key->seq;
1060 params.key = key->key;
1061
1062 callback(cookie, &params);
1063
1064 return key->key_len ? 0 : -ENOENT;
1065}
1066
1067
1068static int
1069ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev,
1070 u8 key_index, bool unicast, bool multicast)
1071{
1072 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1073 struct ar_key *key = NULL;
1074 int status = 0;
1075 u8 key_usage;
1076
1077 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1078
1079 if(ar->arWmiReady == false) {
1080 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1081 return -EIO;
1082 }
1083
1084 if(ar->arWlanState == WLAN_DISABLED) {
1085 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1086 return -EIO;
1087 }
1088
1089 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1090 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1091 ("%s: key index %d out of bounds\n",
1092 __func__, key_index));
1093 return -ENOENT;
1094 }
1095
1096 if(!ar->keys[key_index].key_len) {
1097 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n",
1098 __func__, key_index));
1099 return -EINVAL;
1100 }
1101
1102 ar->arDefTxKeyIndex = key_index;
1103 key = &ar->keys[ar->arDefTxKeyIndex];
1104 key_usage = GROUP_USAGE;
1105 if (WEP_CRYPT == ar->arPairwiseCrypto) {
1106 key_usage |= TX_USAGE;
1107 }
1108
1109 status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
1110 ar->arPairwiseCrypto, key_usage,
1111 key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
1112 NULL, SYNC_BOTH_WMIFLAG);
1113 if (status) {
1114 return -EIO;
1115 }
1116
1117 return 0;
1118}
1119
1120static int
1121ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev,
1122 u8 key_index)
1123{
1124 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1125
1126 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1127
1128 if(ar->arWmiReady == false) {
1129 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1130 return -EIO;
1131 }
1132
1133 if(ar->arWlanState == WLAN_DISABLED) {
1134 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1135 return -EIO;
1136 }
1137
1138 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1139 return -ENOTSUPP;
1140}
1141
1142void
1143ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast)
1144{
1145 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1146 ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast));
1147
1148 cfg80211_michael_mic_failure(ar->arNetDev, ar->arBssid,
1149 (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE),
1150 keyid, NULL, GFP_KERNEL);
1151}
1152
1153static int
1154ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1155{
1156 struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1157
1158 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed));
1159
1160 if(ar->arWmiReady == false) {
1161 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1162 return -EIO;
1163 }
1164
1165 if(ar->arWlanState == WLAN_DISABLED) {
1166 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1167 return -EIO;
1168 }
1169
1170 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1171 if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != 0){
1172 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__));
1173 return -EIO;
1174 }
1175 }
1176
1177 return 0;
1178}
1179
1180static int
1181ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1182 const u8 *peer,
1183 const struct cfg80211_bitrate_mask *mask)
1184{
1185 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n"));
1186 return -EIO;
1187}
1188
1189/* The type nl80211_tx_power_setting replaces the following data type from 2.6.36 onwards */
1190static int
1191ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm)
1192{
1193 struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1194 u8 ar_dbm;
1195
1196 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm));
1197
1198 if(ar->arWmiReady == false) {
1199 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1200 return -EIO;
1201 }
1202
1203 if(ar->arWlanState == WLAN_DISABLED) {
1204 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1205 return -EIO;
1206 }
1207
1208 ar->arTxPwrSet = false;
1209 switch(type) {
1210 case NL80211_TX_POWER_AUTOMATIC:
1211 return 0;
1212 case NL80211_TX_POWER_LIMITED:
1213 ar->arTxPwr = ar_dbm = dbm;
1214 ar->arTxPwrSet = true;
1215 break;
1216 default:
1217 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type));
1218 return -EOPNOTSUPP;
1219 }
1220
1221 wmi_set_txPwr_cmd(ar->arWmi, ar_dbm);
1222
1223 return 0;
1224}
1225
1226static int
1227ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1228{
1229 struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1230
1231 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1232
1233 if(ar->arWmiReady == false) {
1234 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1235 return -EIO;
1236 }
1237
1238 if(ar->arWlanState == WLAN_DISABLED) {
1239 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1240 return -EIO;
1241 }
1242
1243 if((ar->arConnected == true)) {
1244 ar->arTxPwr = 0;
1245
1246 if(wmi_get_txPwr_cmd(ar->arWmi) != 0) {
1247 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__));
1248 return -EIO;
1249 }
1250
1251 wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, 5 * HZ);
1252
1253 if(signal_pending(current)) {
1254 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Target did not respond\n", __func__));
1255 return -EINTR;
1256 }
1257 }
1258
1259 *dbm = ar->arTxPwr;
1260 return 0;
1261}
1262
1263static int
1264ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1265 struct net_device *dev,
1266 bool pmgmt, int timeout)
1267{
1268 struct ar6_softc *ar = ar6k_priv(dev);
1269 WMI_POWER_MODE_CMD pwrMode;
1270
1271 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout));
1272
1273 if(ar->arWmiReady == false) {
1274 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1275 return -EIO;
1276 }
1277
1278 if(ar->arWlanState == WLAN_DISABLED) {
1279 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1280 return -EIO;
1281 }
1282
1283 if(pmgmt) {
1284 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__));
1285 pwrMode.powerMode = REC_POWER;
1286 } else {
1287 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__));
1288 pwrMode.powerMode = MAX_PERF_POWER;
1289 }
1290
1291 if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != 0) {
1292 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__));
1293 return -EIO;
1294 }
1295
1296 return 0;
1297}
1298
1299static struct net_device *
1300ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name,
1301 enum nl80211_iftype type, u32 *flags,
1302 struct vif_params *params)
1303{
1304
1305 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1306
1307 /* Multiple virtual interface is not supported.
1308 * The default interface supports STA and IBSS type
1309 */
1310 return ERR_PTR(-EOPNOTSUPP);
1311}
1312
1313static int
1314ar6k_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
1315{
1316
1317 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1318
1319 /* Multiple virtual interface is not supported.
1320 * The default interface supports STA and IBSS type
1321 */
1322 return -EOPNOTSUPP;
1323}
1324
1325static int
1326ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
1327 enum nl80211_iftype type, u32 *flags,
1328 struct vif_params *params)
1329{
1330 struct ar6_softc *ar = ar6k_priv(ndev);
1331 struct wireless_dev *wdev = ar->wdev;
1332
1333 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type));
1334
1335 if(ar->arWmiReady == false) {
1336 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1337 return -EIO;
1338 }
1339
1340 if(ar->arWlanState == WLAN_DISABLED) {
1341 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1342 return -EIO;
1343 }
1344
1345 switch (type) {
1346 case NL80211_IFTYPE_STATION:
1347 ar->arNextMode = INFRA_NETWORK;
1348 break;
1349 case NL80211_IFTYPE_ADHOC:
1350 ar->arNextMode = ADHOC_NETWORK;
1351 break;
1352 default:
1353 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: type %u\n", __func__, type));
1354 return -EOPNOTSUPP;
1355 }
1356
1357 wdev->iftype = type;
1358
1359 return 0;
1360}
1361
1362static int
1363ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1364 struct cfg80211_ibss_params *ibss_param)
1365{
1366 struct ar6_softc *ar = ar6k_priv(dev);
1367 int status;
1368
1369 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1370
1371 if(ar->arWmiReady == false) {
1372 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1373 return -EIO;
1374 }
1375
1376 if(ar->arWlanState == WLAN_DISABLED) {
1377 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1378 return -EIO;
1379 }
1380
1381 if(!ibss_param->ssid_len || IEEE80211_MAX_SSID_LEN < ibss_param->ssid_len) {
1382 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
1383 return -EINVAL;
1384 }
1385
1386 ar->arSsidLen = ibss_param->ssid_len;
1387 memcpy(ar->arSsid, ibss_param->ssid, ar->arSsidLen);
1388
1389 if(ibss_param->channel) {
1390 ar->arChannelHint = ibss_param->channel->center_freq;
1391 }
1392
1393 if(ibss_param->channel_fixed) {
1394 /* TODO: channel_fixed: The channel should be fixed, do not search for
1395 * IBSSs to join on other channels. Target firmware does not support this
1396 * feature, needs to be updated.*/
1397 }
1398
1399 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
1400 if(ibss_param->bssid) {
1401 if(memcmp(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
1402 memcpy(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid));
1403 }
1404 }
1405
1406 ar6k_set_wpa_version(ar, 0);
1407 ar6k_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1408
1409 if(ibss_param->privacy) {
1410 ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1411 ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1412 } else {
1413 ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
1414 ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, false);
1415 }
1416
1417 ar->arNetworkType = ar->arNextMode;
1418
1419 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
1420 " PW crypto %d PW crypto Len %d GRP crypto %d"\
1421 " GRP crypto Len %d channel hint %u\n",
1422 __func__, ar->arAuthMode, ar->arDot11AuthMode,
1423 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1424 ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
1425
1426 status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
1427 ar->arDot11AuthMode, ar->arAuthMode,
1428 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1429 ar->arGroupCrypto,ar->arGroupCryptoLen,
1430 ar->arSsidLen, ar->arSsid,
1431 ar->arReqBssid, ar->arChannelHint,
1432 ar->arConnectCtrlFlags);
1433 ar->arConnectPending = true;
1434
1435 return 0;
1436}
1437
1438static int
1439ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1440{
1441 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1442
1443 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1444
1445 if(ar->arWmiReady == false) {
1446 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1447 return -EIO;
1448 }
1449
1450 if(ar->arWlanState == WLAN_DISABLED) {
1451 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1452 return -EIO;
1453 }
1454
1455 ar6000_disconnect(ar);
1456 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1457 ar->arSsidLen = 0;
1458
1459 return 0;
1460}
1461
1462#ifdef CONFIG_NL80211_TESTMODE
1463enum ar6k_testmode_attr {
1464 __AR6K_TM_ATTR_INVALID = 0,
1465 AR6K_TM_ATTR_CMD = 1,
1466 AR6K_TM_ATTR_DATA = 2,
1467
1468 /* keep last */
1469 __AR6K_TM_ATTR_AFTER_LAST,
1470 AR6K_TM_ATTR_MAX = __AR6K_TM_ATTR_AFTER_LAST - 1
1471};
1472
1473enum ar6k_testmode_cmd {
1474 AR6K_TM_CMD_TCMD = 0,
1475 AR6K_TM_CMD_RX_REPORT = 1,
1476};
1477
1478#define AR6K_TM_DATA_MAX_LEN 5000
1479
1480static const struct nla_policy ar6k_testmode_policy[AR6K_TM_ATTR_MAX + 1] = {
1481 [AR6K_TM_ATTR_CMD] = { .type = NLA_U32 },
1482 [AR6K_TM_ATTR_DATA] = { .type = NLA_BINARY,
1483 .len = AR6K_TM_DATA_MAX_LEN },
1484};
1485
1486void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf,
1487 int buf_len)
1488{
1489 if (down_interruptible(&ar->arSem))
1490 return;
1491
1492 kfree(ar->tcmd_rx_report);
1493
1494 ar->tcmd_rx_report = kmemdup(buf, buf_len, GFP_KERNEL);
1495 ar->tcmd_rx_report_len = buf_len;
1496
1497 up(&ar->arSem);
1498
1499 wake_up(&arEvent);
1500}
1501
1502static int ar6000_testmode_rx_report(struct ar6_softc *ar, void *buf,
1503 int buf_len, struct sk_buff *skb)
1504{
1505 int ret = 0;
1506 long left;
1507
1508 if (down_interruptible(&ar->arSem))
1509 return -ERESTARTSYS;
1510
1511 if (ar->arWmiReady == false) {
1512 ret = -EIO;
1513 goto out;
1514 }
1515
1516 if (ar->bIsDestroyProgress) {
1517 ret = -EBUSY;
1518 goto out;
1519 }
1520
1521 WARN_ON(ar->tcmd_rx_report != NULL);
1522 WARN_ON(ar->tcmd_rx_report_len > 0);
1523
1524 if (wmi_test_cmd(ar->arWmi, buf, buf_len) < 0) {
1525 up(&ar->arSem);
1526 return -EIO;
1527 }
1528
1529 left = wait_event_interruptible_timeout(arEvent,
1530 ar->tcmd_rx_report != NULL,
1531 wmitimeout * HZ);
1532
1533 if (left == 0) {
1534 ret = -ETIMEDOUT;
1535 goto out;
1536 } else if (left < 0) {
1537 ret = left;
1538 goto out;
1539 }
1540
1541 if (ar->tcmd_rx_report == NULL || ar->tcmd_rx_report_len == 0) {
1542 ret = -EINVAL;
1543 goto out;
1544 }
1545
1546 NLA_PUT(skb, AR6K_TM_ATTR_DATA, ar->tcmd_rx_report_len,
1547 ar->tcmd_rx_report);
1548
1549 kfree(ar->tcmd_rx_report);
1550 ar->tcmd_rx_report = NULL;
1551
1552out:
1553 up(&ar->arSem);
1554
1555 return ret;
1556
1557nla_put_failure:
1558 ret = -ENOBUFS;
1559 goto out;
1560}
1561
1562static int ar6k_testmode_cmd(struct wiphy *wiphy, void *data, int len)
1563{
1564 struct ar6_softc *ar = wiphy_priv(wiphy);
1565 struct nlattr *tb[AR6K_TM_ATTR_MAX + 1];
1566 int err, buf_len, reply_len;
1567 struct sk_buff *skb;
1568 void *buf;
1569
1570 err = nla_parse(tb, AR6K_TM_ATTR_MAX, data, len,
1571 ar6k_testmode_policy);
1572 if (err)
1573 return err;
1574
1575 if (!tb[AR6K_TM_ATTR_CMD])
1576 return -EINVAL;
1577
1578 switch (nla_get_u32(tb[AR6K_TM_ATTR_CMD])) {
1579 case AR6K_TM_CMD_TCMD:
1580 if (!tb[AR6K_TM_ATTR_DATA])
1581 return -EINVAL;
1582
1583 buf = nla_data(tb[AR6K_TM_ATTR_DATA]);
1584 buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]);
1585
1586 wmi_test_cmd(ar->arWmi, buf, buf_len);
1587
1588 return 0;
1589
1590 break;
1591 case AR6K_TM_CMD_RX_REPORT:
1592 if (!tb[AR6K_TM_ATTR_DATA])
1593 return -EINVAL;
1594
1595 buf = nla_data(tb[AR6K_TM_ATTR_DATA]);
1596 buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]);
1597
1598 reply_len = nla_total_size(AR6K_TM_DATA_MAX_LEN);
1599 skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len);
1600 if (!skb)
1601 return -ENOMEM;
1602
1603 err = ar6000_testmode_rx_report(ar, buf, buf_len, skb);
1604 if (err < 0) {
1605 kfree_skb(skb);
1606 return err;
1607 }
1608
1609 return cfg80211_testmode_reply(skb);
1610 default:
1611 return -EOPNOTSUPP;
1612 }
1613}
1614#endif
1615
1616static const
1617u32 cipher_suites[] = {
1618 WLAN_CIPHER_SUITE_WEP40,
1619 WLAN_CIPHER_SUITE_WEP104,
1620 WLAN_CIPHER_SUITE_TKIP,
1621 WLAN_CIPHER_SUITE_CCMP,
1622};
1623
1624bool is_rate_legacy(s32 rate)
1625{
1626 static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1627 6000, 9000, 12000, 18000, 24000,
1628 36000, 48000, 54000 };
1629 u8 i;
1630
1631 for (i = 0; i < ARRAY_SIZE(legacy); i++) {
1632 if (rate == legacy[i])
1633 return true;
1634 }
1635
1636 return false;
1637}
1638
1639bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1640{
1641 static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1642 52000, 58500, 65000, 72200 };
1643 u8 i;
1644
1645 for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1646 if (rate == ht20[i]) {
1647 if (i == ARRAY_SIZE(ht20) - 1)
1648 /* last rate uses sgi */
1649 *sgi = true;
1650 else
1651 *sgi = false;
1652
1653 *mcs = i;
1654 return true;
1655 }
1656 }
1657 return false;
1658}
1659
1660bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1661{
1662 static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1663 81000, 108000, 121500, 135000,
1664 150000 };
1665 u8 i;
1666
1667 for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1668 if (rate == ht40[i]) {
1669 if (i == ARRAY_SIZE(ht40) - 1)
1670 /* last rate uses sgi */
1671 *sgi = true;
1672 else
1673 *sgi = false;
1674
1675 *mcs = i;
1676 return true;
1677 }
1678 }
1679
1680 return false;
1681}
1682
1683static int ar6k_get_station(struct wiphy *wiphy, struct net_device *dev,
1684 u8 *mac, struct station_info *sinfo)
1685{
1686 struct ar6_softc *ar = ar6k_priv(dev);
1687 long left;
1688 bool sgi;
1689 s32 rate;
1690 int ret;
1691 u8 mcs;
1692
1693 if (memcmp(mac, ar->arBssid, ETH_ALEN) != 0)
1694 return -ENOENT;
1695
1696 if (down_interruptible(&ar->arSem))
1697 return -EBUSY;
1698
1699 ar->statsUpdatePending = true;
1700
1701 ret = wmi_get_stats_cmd(ar->arWmi);
1702
1703 if (ret != 0) {
1704 up(&ar->arSem);
1705 return -EIO;
1706 }
1707
1708 left = wait_event_interruptible_timeout(arEvent,
1709 ar->statsUpdatePending == false,
1710 wmitimeout * HZ);
1711
1712 up(&ar->arSem);
1713
1714 if (left == 0)
1715 return -ETIMEDOUT;
1716 else if (left < 0)
1717 return left;
1718
1719 if (ar->arTargetStats.rx_bytes) {
1720 sinfo->rx_bytes = ar->arTargetStats.rx_bytes;
1721 sinfo->filled |= STATION_INFO_RX_BYTES;
1722 sinfo->rx_packets = ar->arTargetStats.rx_packets;
1723 sinfo->filled |= STATION_INFO_RX_PACKETS;
1724 }
1725
1726 if (ar->arTargetStats.tx_bytes) {
1727 sinfo->tx_bytes = ar->arTargetStats.tx_bytes;
1728 sinfo->filled |= STATION_INFO_TX_BYTES;
1729 sinfo->tx_packets = ar->arTargetStats.tx_packets;
1730 sinfo->filled |= STATION_INFO_TX_PACKETS;
1731 }
1732
1733 sinfo->signal = ar->arTargetStats.cs_rssi;
1734 sinfo->filled |= STATION_INFO_SIGNAL;
1735
1736 rate = ar->arTargetStats.tx_unicast_rate;
1737
1738 if (is_rate_legacy(rate)) {
1739 sinfo->txrate.legacy = rate / 100;
1740 } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1741 if (sgi) {
1742 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1743 sinfo->txrate.mcs = mcs - 1;
1744 } else {
1745 sinfo->txrate.mcs = mcs;
1746 }
1747
1748 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1749 } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1750 if (sgi) {
1751 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1752 sinfo->txrate.mcs = mcs - 1;
1753 } else {
1754 sinfo->txrate.mcs = mcs;
1755 }
1756
1757 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1758 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1759 } else {
1760 WARN(1, "invalid rate: %d", rate);
1761 return 0;
1762 }
1763
1764 sinfo->filled |= STATION_INFO_TX_BITRATE;
1765
1766 return 0;
1767}
1768
1769static int ar6k_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1770 struct cfg80211_pmksa *pmksa)
1771{
1772 struct ar6_softc *ar = ar6k_priv(netdev);
1773 return wmi_setPmkid_cmd(ar->arWmi, pmksa->bssid, pmksa->pmkid, true);
1774}
1775
1776static int ar6k_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1777 struct cfg80211_pmksa *pmksa)
1778{
1779 struct ar6_softc *ar = ar6k_priv(netdev);
1780 return wmi_setPmkid_cmd(ar->arWmi, pmksa->bssid, pmksa->pmkid, false);
1781}
1782
1783static int ar6k_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1784{
1785 struct ar6_softc *ar = ar6k_priv(netdev);
1786 if (ar->arConnected)
1787 return wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, false);
1788 return 0;
1789}
1790
1791static struct
1792cfg80211_ops ar6k_cfg80211_ops = {
1793 .change_virtual_intf = ar6k_cfg80211_change_iface,
1794 .add_virtual_intf = ar6k_cfg80211_add_virtual_intf,
1795 .del_virtual_intf = ar6k_cfg80211_del_virtual_intf,
1796 .scan = ar6k_cfg80211_scan,
1797 .connect = ar6k_cfg80211_connect,
1798 .disconnect = ar6k_cfg80211_disconnect,
1799 .add_key = ar6k_cfg80211_add_key,
1800 .get_key = ar6k_cfg80211_get_key,
1801 .del_key = ar6k_cfg80211_del_key,
1802 .set_default_key = ar6k_cfg80211_set_default_key,
1803 .set_default_mgmt_key = ar6k_cfg80211_set_default_mgmt_key,
1804 .set_wiphy_params = ar6k_cfg80211_set_wiphy_params,
1805 .set_bitrate_mask = ar6k_cfg80211_set_bitrate_mask,
1806 .set_tx_power = ar6k_cfg80211_set_txpower,
1807 .get_tx_power = ar6k_cfg80211_get_txpower,
1808 .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
1809 .join_ibss = ar6k_cfg80211_join_ibss,
1810 .leave_ibss = ar6k_cfg80211_leave_ibss,
1811 .get_station = ar6k_get_station,
1812 .set_pmksa = ar6k_set_pmksa,
1813 .del_pmksa = ar6k_del_pmksa,
1814 .flush_pmksa = ar6k_flush_pmksa,
1815 CFG80211_TESTMODE_CMD(ar6k_testmode_cmd)
1816};
1817
1818struct wireless_dev *
1819ar6k_cfg80211_init(struct device *dev)
1820{
1821 int ret = 0;
1822 struct wireless_dev *wdev;
1823
1824 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1825
1826 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1827 if(!wdev) {
1828 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1829 ("%s: Couldn't allocate wireless device\n", __func__));
1830 return ERR_PTR(-ENOMEM);
1831 }
1832
1833 /* create a new wiphy for use with cfg80211 */
1834 wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(struct ar6_softc));
1835 if(!wdev->wiphy) {
1836 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1837 ("%s: Couldn't allocate wiphy device\n", __func__));
1838 kfree(wdev);
1839 return ERR_PTR(-ENOMEM);
1840 }
1841
1842 /* set device pointer for wiphy */
1843 set_wiphy_dev(wdev->wiphy, dev);
1844
1845 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1846 BIT(NL80211_IFTYPE_ADHOC);
1847 /* max num of ssids that can be probed during scanning */
1848 wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1849 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar6k_band_2ghz;
1850 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar6k_band_5ghz;
1851 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1852
1853 wdev->wiphy->cipher_suites = cipher_suites;
1854 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1855
1856 ret = wiphy_register(wdev->wiphy);
1857 if(ret < 0) {
1858 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1859 ("%s: Couldn't register wiphy device\n", __func__));
1860 wiphy_free(wdev->wiphy);
1861 return ERR_PTR(ret);
1862 }
1863
1864 return wdev;
1865}
1866
1867void
1868ar6k_cfg80211_deinit(struct ar6_softc *ar)
1869{
1870 struct wireless_dev *wdev = ar->wdev;
1871
1872 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1873
1874 if(ar->scan_request) {
1875 cfg80211_scan_done(ar->scan_request, true);
1876 ar->scan_request = NULL;
1877 }
1878
1879 if(!wdev)
1880 return;
1881
1882 wiphy_unregister(wdev->wiphy);
1883 wiphy_free(wdev->wiphy);
1884 kfree(wdev);
1885}
1886
1887
1888
1889
1890
1891
1892
diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c
deleted file mode 100644
index 430998edacc..00000000000
--- a/drivers/staging/ath6kl/os/linux/export_hci_transport.c
+++ /dev/null
@@ -1,124 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// HCI bridge implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24#include <a_config.h>
25#include <athdefs.h>
26#include "a_osapi.h"
27#include "htc_api.h"
28#include "a_drv.h"
29#include "hif.h"
30#include "common_drv.h"
31#include "a_debug.h"
32#include "hci_transport_api.h"
33
34#include "AR6002/hw4.0/hw/apb_athr_wlan_map.h"
35#include "AR6002/hw4.0/hw/uart_reg.h"
36#include "AR6002/hw4.0/hw/rtc_wlan_reg.h"
37
38HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo);
39void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans);
40int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue);
41int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous);
42void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans);
43int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans);
44int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
45int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans,
46 struct htc_packet *pPacket,
47 int MaxPollMS);
48int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud);
49int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
50
51extern struct hci_transport_callbacks ar6kHciTransCallbacks;
52
53int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks)
54{
55 ar6kHciTransCallbacks = *hciTransCallbacks;
56
57 _HCI_TransportAttach = HCI_TransportAttach;
58 _HCI_TransportDetach = HCI_TransportDetach;
59 _HCI_TransportAddReceivePkts = HCI_TransportAddReceivePkts;
60 _HCI_TransportSendPkt = HCI_TransportSendPkt;
61 _HCI_TransportStop = HCI_TransportStop;
62 _HCI_TransportStart = HCI_TransportStart;
63 _HCI_TransportEnableDisableAsyncRecv = HCI_TransportEnableDisableAsyncRecv;
64 _HCI_TransportRecvHCIEventSync = HCI_TransportRecvHCIEventSync;
65 _HCI_TransportSetBaudRate = HCI_TransportSetBaudRate;
66 _HCI_TransportEnablePowerMgmt = HCI_TransportEnablePowerMgmt;
67
68 return 0;
69}
70
71int
72ar6000_get_hif_dev(struct hif_device *device, void *config)
73{
74 int status;
75
76 status = HIFConfigureDevice(device,
77 HIF_DEVICE_GET_OS_DEVICE,
78 (struct hif_device_os_device_info *)config,
79 sizeof(struct hif_device_os_device_info));
80 return status;
81}
82
83int ar6000_set_uart_config(struct hif_device *hifDevice,
84 u32 scale,
85 u32 step)
86{
87 u32 regAddress;
88 u32 regVal;
89 int status;
90
91 regAddress = WLAN_UART_BASE_ADDRESS | UART_CLKDIV_ADDRESS;
92 regVal = ((u32)scale << 16) | step;
93 /* change the HCI UART scale/step values through the diagnostic window */
94 status = ar6000_WriteRegDiag(hifDevice, &regAddress, &regVal);
95
96 return status;
97}
98
99int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data)
100{
101 u32 regAddress;
102 int status;
103
104 regAddress = WLAN_RTC_BASE_ADDRESS | WLAN_CPU_CLOCK_ADDRESS;
105 /* read CPU clock settings*/
106 status = ar6000_ReadRegDiag(hifDevice, &regAddress, data);
107
108 return status;
109}
110
111EXPORT_SYMBOL(ar6000_register_hci_transport);
112EXPORT_SYMBOL(ar6000_get_hif_dev);
113EXPORT_SYMBOL(ar6000_set_uart_config);
114EXPORT_SYMBOL(ar6000_get_core_clock_config);
115EXPORT_SYMBOL(_HCI_TransportAttach);
116EXPORT_SYMBOL(_HCI_TransportDetach);
117EXPORT_SYMBOL(_HCI_TransportAddReceivePkts);
118EXPORT_SYMBOL(_HCI_TransportSendPkt);
119EXPORT_SYMBOL(_HCI_TransportStop);
120EXPORT_SYMBOL(_HCI_TransportStart);
121EXPORT_SYMBOL(_HCI_TransportEnableDisableAsyncRecv);
122EXPORT_SYMBOL(_HCI_TransportRecvHCIEventSync);
123EXPORT_SYMBOL(_HCI_TransportSetBaudRate);
124EXPORT_SYMBOL(_HCI_TransportEnablePowerMgmt);
diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c
deleted file mode 100644
index 6087edcb1d6..00000000000
--- a/drivers/staging/ath6kl/os/linux/hci_bridge.c
+++ /dev/null
@@ -1,1141 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// HCI bridge implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25#ifdef EXPORT_HCI_BRIDGE_INTERFACE
26#include <linux/etherdevice.h>
27#include <a_config.h>
28#include <athdefs.h>
29#include "a_osapi.h"
30#include "htc_api.h"
31#include "wmi.h"
32#include "a_drv.h"
33#include "hif.h"
34#include "common_drv.h"
35#include "a_debug.h"
36#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
37#define ATH_DEBUG_HCI_RECV ATH_DEBUG_MAKE_MODULE_MASK(7)
38#define ATH_DEBUG_HCI_SEND ATH_DEBUG_MAKE_MODULE_MASK(8)
39#define ATH_DEBUG_HCI_DUMP ATH_DEBUG_MAKE_MODULE_MASK(9)
40#else
41#include "ar6000_drv.h"
42#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
43
44#ifdef ATH_AR6K_ENABLE_GMBOX
45#ifdef EXPORT_HCI_BRIDGE_INTERFACE
46#include "export_hci_transport.h"
47#else
48#include "hci_transport_api.h"
49#endif
50#include "epping_test.h"
51#include "gmboxif.h"
52#include "ar3kconfig.h"
53#include <net/bluetooth/bluetooth.h>
54#include <net/bluetooth/hci_core.h>
55
56 /* only build on newer kernels which have BT configured */
57#if defined(CONFIG_BT_MODULE) || defined(CONFIG_BT)
58#define CONFIG_BLUEZ_HCI_BRIDGE
59#endif
60
61#ifdef EXPORT_HCI_BRIDGE_INTERFACE
62unsigned int ar3khcibaud = 0;
63unsigned int hciuartscale = 0;
64unsigned int hciuartstep = 0;
65
66module_param(ar3khcibaud, int, 0644);
67module_param(hciuartscale, int, 0644);
68module_param(hciuartstep, int, 0644);
69#else
70extern unsigned int ar3khcibaud;
71extern unsigned int hciuartscale;
72extern unsigned int hciuartstep;
73#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
74
75struct ar6k_hci_bridge_info {
76 void *pHCIDev; /* HCI bridge device */
77 struct hci_transport_properties HCIProps; /* HCI bridge props */
78 struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */
79 bool HciNormalMode; /* Actual HCI mode enabled (non-TEST)*/
80 bool HciRegistered; /* HCI device registered with stack */
81 struct htc_packet_queue HTCPacketStructHead;
82 u8 *pHTCStructAlloc;
83 spinlock_t BridgeLock;
84#ifdef EXPORT_HCI_BRIDGE_INTERFACE
85 struct hci_transport_misc_handles HCITransHdl;
86#else
87 struct ar6_softc *ar;
88#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
89};
90
91#define MAX_ACL_RECV_BUFS 16
92#define MAX_EVT_RECV_BUFS 8
93#define MAX_HCI_WRITE_QUEUE_DEPTH 32
94#define MAX_ACL_RECV_LENGTH 1200
95#define MAX_EVT_RECV_LENGTH 257
96#define TX_PACKET_RSV_OFFSET 32
97#define NUM_HTC_PACKET_STRUCTS ((MAX_ACL_RECV_BUFS + MAX_EVT_RECV_BUFS + MAX_HCI_WRITE_QUEUE_DEPTH) * 2)
98
99#define HCI_GET_OP_CODE(p) (((u16)((p)[1])) << 8) | ((u16)((p)[0]))
100
101extern unsigned int setupbtdev;
102struct ar3k_config_info ar3kconfig;
103
104#ifdef EXPORT_HCI_BRIDGE_INTERFACE
105struct ar6k_hci_bridge_info *g_pHcidevInfo;
106#endif
107
108static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo);
109static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo);
110static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo);
111static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo,
112 HCI_TRANSPORT_PACKET_TYPE Type,
113 struct sk_buff *skb);
114static struct sk_buff *bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length);
115static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb);
116
117#ifdef EXPORT_HCI_BRIDGE_INTERFACE
118int ar6000_setup_hci(void *ar);
119void ar6000_cleanup_hci(void *ar);
120int hci_test_send(void *ar, struct sk_buff *skb);
121#else
122int ar6000_setup_hci(struct ar6_softc *ar);
123void ar6000_cleanup_hci(struct ar6_softc *ar);
124/* HCI bridge testing */
125int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb);
126#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
127
128#define LOCK_BRIDGE(dev) spin_lock_bh(&(dev)->BridgeLock)
129#define UNLOCK_BRIDGE(dev) spin_unlock_bh(&(dev)->BridgeLock)
130
131static inline void FreeBtOsBuf(struct ar6k_hci_bridge_info *pHcidevInfo, void *osbuf)
132{
133 if (pHcidevInfo->HciNormalMode) {
134 bt_free_buffer(pHcidevInfo, (struct sk_buff *)osbuf);
135 } else {
136 /* in test mode, these are just ordinary netbuf allocations */
137 A_NETBUF_FREE(osbuf);
138 }
139}
140
141static void FreeHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo, struct htc_packet *pPacket)
142{
143 LOCK_BRIDGE(pHcidevInfo);
144 HTC_PACKET_ENQUEUE(&pHcidevInfo->HTCPacketStructHead,pPacket);
145 UNLOCK_BRIDGE(pHcidevInfo);
146}
147
148static struct htc_packet * AllocHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo)
149{
150 struct htc_packet *pPacket = NULL;
151 LOCK_BRIDGE(pHcidevInfo);
152 pPacket = HTC_PACKET_DEQUEUE(&pHcidevInfo->HTCPacketStructHead);
153 UNLOCK_BRIDGE(pHcidevInfo);
154 return pPacket;
155}
156
157#define BLOCK_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1))
158
159static void RefillRecvBuffers(struct ar6k_hci_bridge_info *pHcidevInfo,
160 HCI_TRANSPORT_PACKET_TYPE Type,
161 int NumBuffers)
162{
163 int length, i;
164 void *osBuf = NULL;
165 struct htc_packet_queue queue;
166 struct htc_packet *pPacket;
167
168 INIT_HTC_PACKET_QUEUE(&queue);
169
170 if (Type == HCI_ACL_TYPE) {
171 if (pHcidevInfo->HciNormalMode) {
172 length = HCI_MAX_FRAME_SIZE;
173 } else {
174 length = MAX_ACL_RECV_LENGTH;
175 }
176 } else {
177 length = MAX_EVT_RECV_LENGTH;
178 }
179
180 /* add on transport head and tail room */
181 length += pHcidevInfo->HCIProps.HeadRoom + pHcidevInfo->HCIProps.TailRoom;
182 /* round up to the required I/O padding */
183 length = BLOCK_ROUND_UP_PWR2(length,pHcidevInfo->HCIProps.IOBlockPad);
184
185 for (i = 0; i < NumBuffers; i++) {
186
187 if (pHcidevInfo->HciNormalMode) {
188 osBuf = bt_alloc_buffer(pHcidevInfo,length);
189 } else {
190 osBuf = A_NETBUF_ALLOC(length);
191 }
192
193 if (NULL == osBuf) {
194 break;
195 }
196
197 pPacket = AllocHTCStruct(pHcidevInfo);
198 if (NULL == pPacket) {
199 FreeBtOsBuf(pHcidevInfo,osBuf);
200 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
201 break;
202 }
203
204 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),length,Type);
205 /* add to queue */
206 HTC_PACKET_ENQUEUE(&queue,pPacket);
207 }
208
209 if (i > 0) {
210 HCI_TransportAddReceivePkts(pHcidevInfo->pHCIDev, &queue);
211 }
212}
213
214#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
215 (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
216 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))
217static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle,
218 struct hci_transport_properties *pProps,
219 void *pContext)
220{
221 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
222 int status;
223 u32 address, hci_uart_pwr_mgmt_params;
224// struct ar3k_config_info ar3kconfig;
225
226 pHcidevInfo->pHCIDev = HCIHandle;
227
228 memcpy(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps));
229
230 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n",
231 (unsigned long)HCIHandle,
232 pHcidevInfo->HCIProps.HeadRoom,
233 pHcidevInfo->HCIProps.TailRoom,
234 pHcidevInfo->HCIProps.IOBlockPad));
235
236#ifdef EXPORT_HCI_BRIDGE_INTERFACE
237 A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)->hard_header_len);
238#else
239 A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= pHcidevInfo->ar->arNetDev->hard_header_len);
240#endif
241
242 /* provide buffers */
243 RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS);
244 RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS);
245
246 do {
247 /* start transport */
248 status = HCI_TransportStart(pHcidevInfo->pHCIDev);
249
250 if (status) {
251 break;
252 }
253
254 if (!pHcidevInfo->HciNormalMode) {
255 /* in test mode, no need to go any further */
256 break;
257 }
258
259 // The delay is required when AR6K is driving the BT reset line
260 // where time is needed after the BT chip is out of reset (HCI_TransportStart)
261 // and before the first HCI command is issued (AR3KConfigure)
262 // FIXME
263 // The delay should be configurable and be only applied when AR6K driving the BT
264 // reset line. This could be done by some module parameter or based on some HW config
265 // info. For now apply 100ms delay blindly
266 A_MDELAY(100);
267
268 A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
269 ar3kconfig.pHCIDev = pHcidevInfo->pHCIDev;
270 ar3kconfig.pHCIProps = &pHcidevInfo->HCIProps;
271#ifdef EXPORT_HCI_BRIDGE_INTERFACE
272 ar3kconfig.pHIFDevice = (struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice);
273#else
274 ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice;
275#endif
276 ar3kconfig.pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
277
278 if (ar3khcibaud != 0) {
279 /* user wants ar3k baud rate change */
280 ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
281 ar3kconfig.Flags |= AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY;
282 ar3kconfig.AR3KBaudRate = ar3khcibaud;
283 }
284
285 if ((hciuartscale != 0) || (hciuartstep != 0)) {
286 /* user wants to tune HCI bridge UART scale/step values */
287 ar3kconfig.AR6KScale = (u16)hciuartscale;
288 ar3kconfig.AR6KStep = (u16)hciuartstep;
289 ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP;
290 }
291
292 /* Fetch the address of the hi_hci_uart_pwr_mgmt_params instance in the host interest area */
293 address = TARG_VTOP(pHcidevInfo->ar->arTargetType,
294 HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar, hi_hci_uart_pwr_mgmt_params));
295 status = ar6000_ReadRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params);
296 if (0 == status) {
297 ar3kconfig.PwrMgmtEnabled = (hci_uart_pwr_mgmt_params & 0x1);
298 ar3kconfig.IdleTimeout = (hci_uart_pwr_mgmt_params & 0xFFFF0000) >> 16;
299 ar3kconfig.WakeupTimeout = (hci_uart_pwr_mgmt_params & 0xFF00) >> 8;
300 } else {
301 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to read hci_uart_pwr_mgmt_params! \n"));
302 }
303 /* configure the AR3K device */
304 memcpy(ar3kconfig.bdaddr,pHcidevInfo->ar->bdaddr,6);
305 status = AR3KConfigure(&ar3kconfig);
306 if (status) {
307 break;
308 }
309
310 /* Make sure both AR6K and AR3K have power management enabled */
311 if (ar3kconfig.PwrMgmtEnabled) {
312 status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, true);
313 if (status) {
314 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n"));
315 }
316 }
317
318 status = bt_register_hci(pHcidevInfo);
319
320 } while (false);
321
322 return status;
323}
324
325static void ar6000_hci_transport_failure(void *pContext, int Status)
326{
327 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
328
329 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: transport failure! \n"));
330
331 if (pHcidevInfo->HciNormalMode) {
332 /* TODO .. */
333 }
334}
335
336static void ar6000_hci_transport_removed(void *pContext)
337{
338 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
339
340 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: transport removed. \n"));
341
342 A_ASSERT(pHcidevInfo->pHCIDev != NULL);
343
344 HCI_TransportDetach(pHcidevInfo->pHCIDev);
345 bt_cleanup_hci(pHcidevInfo);
346 pHcidevInfo->pHCIDev = NULL;
347}
348
349static void ar6000_hci_send_complete(void *pContext, struct htc_packet *pPacket)
350{
351 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
352 void *osbuf = pPacket->pPktContext;
353 A_ASSERT(osbuf != NULL);
354 A_ASSERT(pHcidevInfo != NULL);
355
356 if (pPacket->Status) {
357 if ((pPacket->Status != A_ECANCELED) && (pPacket->Status != A_NO_RESOURCE)) {
358 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: Send Packet Failed: %d \n",pPacket->Status));
359 }
360 }
361
362 FreeHTCStruct(pHcidevInfo,pPacket);
363 FreeBtOsBuf(pHcidevInfo,osbuf);
364
365}
366
367static void ar6000_hci_pkt_recv(void *pContext, struct htc_packet *pPacket)
368{
369 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
370 struct sk_buff *skb;
371
372 A_ASSERT(pHcidevInfo != NULL);
373 skb = (struct sk_buff *)pPacket->pPktContext;
374 A_ASSERT(skb != NULL);
375
376 do {
377
378 if (pPacket->Status) {
379 break;
380 }
381
382 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV,
383 ("HCI Bridge, packet received type : %d len:%d \n",
384 HCI_GET_PACKET_TYPE(pPacket),pPacket->ActualLength));
385
386 /* set the actual buffer position in the os buffer, HTC recv buffers posted to HCI are set
387 * to fill the front of the buffer */
388 A_NETBUF_PUT(skb,pPacket->ActualLength + pHcidevInfo->HCIProps.HeadRoom);
389 A_NETBUF_PULL(skb,pHcidevInfo->HCIProps.HeadRoom);
390
391 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
392 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("<<< Recv HCI %s packet len:%d \n",
393 (HCI_GET_PACKET_TYPE(pPacket) == HCI_EVENT_TYPE) ? "EVENT" : "ACL",
394 skb->len));
395 AR_DEBUG_PRINTBUF(skb->data, skb->len,"BT HCI RECV Packet Dump");
396 }
397
398 if (pHcidevInfo->HciNormalMode) {
399 /* indicate the packet */
400 if (bt_indicate_recv(pHcidevInfo,HCI_GET_PACKET_TYPE(pPacket),skb)) {
401 /* bt stack accepted the packet */
402 skb = NULL;
403 }
404 break;
405 }
406
407 /* for testing, indicate packet to the network stack */
408#ifdef EXPORT_HCI_BRIDGE_INTERFACE
409 skb->dev = (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice);
410 if ((((struct net_device *)pHcidevInfo->HCITransHdl.netDevice)->flags & IFF_UP) == IFF_UP) {
411 skb->protocol = eth_type_trans(skb, (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice));
412#else
413 skb->dev = pHcidevInfo->ar->arNetDev;
414 if ((pHcidevInfo->ar->arNetDev->flags & IFF_UP) == IFF_UP) {
415 skb->protocol = eth_type_trans(skb, pHcidevInfo->ar->arNetDev);
416#endif
417 netif_rx(skb);
418 skb = NULL;
419 }
420
421 } while (false);
422
423 FreeHTCStruct(pHcidevInfo,pPacket);
424
425 if (skb != NULL) {
426 /* packet was not accepted, free it */
427 FreeBtOsBuf(pHcidevInfo,skb);
428 }
429
430}
431
432static void ar6000_hci_pkt_refill(void *pContext, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable)
433{
434 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
435 int refillCount;
436
437 if (Type == HCI_ACL_TYPE) {
438 refillCount = MAX_ACL_RECV_BUFS - BuffersAvailable;
439 } else {
440 refillCount = MAX_EVT_RECV_BUFS - BuffersAvailable;
441 }
442
443 if (refillCount > 0) {
444 RefillRecvBuffers(pHcidevInfo,Type,refillCount);
445 }
446
447}
448
449static HCI_SEND_FULL_ACTION ar6000_hci_pkt_send_full(void *pContext, struct htc_packet *pPacket)
450{
451 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
452 HCI_SEND_FULL_ACTION action = HCI_SEND_FULL_KEEP;
453
454 if (!pHcidevInfo->HciNormalMode) {
455 /* for epping testing, check packet tag, some epping packets are
456 * special and cannot be dropped */
457 if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_DATA_PKT_TAG) {
458 action = HCI_SEND_FULL_DROP;
459 }
460 }
461
462 return action;
463}
464
465#ifdef EXPORT_HCI_BRIDGE_INTERFACE
466int ar6000_setup_hci(void *ar)
467#else
468int ar6000_setup_hci(struct ar6_softc *ar)
469#endif
470{
471 struct hci_transport_config_info config;
472 int status = 0;
473 int i;
474 struct htc_packet *pPacket;
475 struct ar6k_hci_bridge_info *pHcidevInfo;
476
477
478 do {
479
480 pHcidevInfo = (struct ar6k_hci_bridge_info *)A_MALLOC(sizeof(struct ar6k_hci_bridge_info));
481
482 if (NULL == pHcidevInfo) {
483 status = A_NO_MEMORY;
484 break;
485 }
486
487 A_MEMZERO(pHcidevInfo, sizeof(struct ar6k_hci_bridge_info));
488#ifdef EXPORT_HCI_BRIDGE_INTERFACE
489 g_pHcidevInfo = pHcidevInfo;
490 pHcidevInfo->HCITransHdl = *(struct hci_transport_misc_handles *)ar;
491#else
492 ar->hcidev_info = pHcidevInfo;
493 pHcidevInfo->ar = ar;
494#endif
495 spin_lock_init(&pHcidevInfo->BridgeLock);
496 INIT_HTC_PACKET_QUEUE(&pHcidevInfo->HTCPacketStructHead);
497
498 ar->exitCallback = AR3KConfigureExit;
499
500 status = bt_setup_hci(pHcidevInfo);
501 if (status) {
502 break;
503 }
504
505 if (pHcidevInfo->HciNormalMode) {
506 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in normal mode... \n"));
507 } else {
508 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n"));
509 }
510
511 pHcidevInfo->pHTCStructAlloc = (u8 *)A_MALLOC((sizeof(struct htc_packet)) * NUM_HTC_PACKET_STRUCTS);
512
513 if (NULL == pHcidevInfo->pHTCStructAlloc) {
514 status = A_NO_MEMORY;
515 break;
516 }
517
518 pPacket = (struct htc_packet *)pHcidevInfo->pHTCStructAlloc;
519 for (i = 0; i < NUM_HTC_PACKET_STRUCTS; i++,pPacket++) {
520 FreeHTCStruct(pHcidevInfo,pPacket);
521 }
522
523 A_MEMZERO(&config,sizeof(struct hci_transport_config_info));
524 config.ACLRecvBufferWaterMark = MAX_ACL_RECV_BUFS / 2;
525 config.EventRecvBufferWaterMark = MAX_EVT_RECV_BUFS / 2;
526 config.MaxSendQueueDepth = MAX_HCI_WRITE_QUEUE_DEPTH;
527 config.pContext = pHcidevInfo;
528 config.TransportFailure = ar6000_hci_transport_failure;
529 config.TransportReady = ar6000_hci_transport_ready;
530 config.TransportRemoved = ar6000_hci_transport_removed;
531 config.pHCISendComplete = ar6000_hci_send_complete;
532 config.pHCIPktRecv = ar6000_hci_pkt_recv;
533 config.pHCIPktRecvRefill = ar6000_hci_pkt_refill;
534 config.pHCISendFull = ar6000_hci_pkt_send_full;
535
536#ifdef EXPORT_HCI_BRIDGE_INTERFACE
537 pHcidevInfo->pHCIDev = HCI_TransportAttach(pHcidevInfo->HCITransHdl.htcHandle, &config);
538#else
539 pHcidevInfo->pHCIDev = HCI_TransportAttach(ar->arHtcTarget, &config);
540#endif
541
542 if (NULL == pHcidevInfo->pHCIDev) {
543 status = A_ERROR;
544 }
545
546 } while (false);
547
548 if (status) {
549 if (pHcidevInfo != NULL) {
550 if (NULL == pHcidevInfo->pHCIDev) {
551 /* GMBOX may not be present in older chips */
552 /* just return success */
553 status = 0;
554 }
555 }
556 ar6000_cleanup_hci(ar);
557 }
558
559 return status;
560}
561
562#ifdef EXPORT_HCI_BRIDGE_INTERFACE
563void ar6000_cleanup_hci(void *ar)
564#else
565void ar6000_cleanup_hci(struct ar6_softc *ar)
566#endif
567{
568#ifdef EXPORT_HCI_BRIDGE_INTERFACE
569 struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo;
570#else
571 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info;
572#endif
573
574 if (pHcidevInfo != NULL) {
575 bt_cleanup_hci(pHcidevInfo);
576
577 if (pHcidevInfo->pHCIDev != NULL) {
578 HCI_TransportStop(pHcidevInfo->pHCIDev);
579 HCI_TransportDetach(pHcidevInfo->pHCIDev);
580 pHcidevInfo->pHCIDev = NULL;
581 }
582
583 if (pHcidevInfo->pHTCStructAlloc != NULL) {
584 kfree(pHcidevInfo->pHTCStructAlloc);
585 pHcidevInfo->pHTCStructAlloc = NULL;
586 }
587
588 kfree(pHcidevInfo);
589#ifndef EXPORT_HCI_BRIDGE_INTERFACE
590 ar->hcidev_info = NULL;
591#endif
592 }
593
594
595}
596
597#ifdef EXPORT_HCI_BRIDGE_INTERFACE
598int hci_test_send(void *ar, struct sk_buff *skb)
599#else
600int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb)
601#endif
602{
603 int status = 0;
604 int length;
605 EPPING_HEADER *pHeader;
606 struct htc_packet *pPacket;
607 HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG;
608#ifdef EXPORT_HCI_BRIDGE_INTERFACE
609 struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo;
610#else
611 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info;
612#endif
613
614 do {
615
616 if (NULL == pHcidevInfo) {
617 status = A_ERROR;
618 break;
619 }
620
621 if (NULL == pHcidevInfo->pHCIDev) {
622 status = A_ERROR;
623 break;
624 }
625
626 if (pHcidevInfo->HciNormalMode) {
627 /* this interface cannot run when normal WMI is running */
628 status = A_ERROR;
629 break;
630 }
631
632 pHeader = (EPPING_HEADER *)A_NETBUF_DATA(skb);
633
634 if (!IS_EPPING_PACKET(pHeader)) {
635 status = A_EINVAL;
636 break;
637 }
638
639 if (IS_EPING_PACKET_NO_DROP(pHeader)) {
640 htc_tag = AR6K_CONTROL_PKT_TAG;
641 }
642
643 length = sizeof(EPPING_HEADER) + pHeader->DataLength;
644
645 pPacket = AllocHTCStruct(pHcidevInfo);
646 if (NULL == pPacket) {
647 status = A_NO_MEMORY;
648 break;
649 }
650
651 SET_HTC_PACKET_INFO_TX(pPacket,
652 skb,
653 A_NETBUF_DATA(skb),
654 length,
655 HCI_ACL_TYPE, /* send every thing out as ACL */
656 htc_tag);
657
658 HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false);
659 pPacket = NULL;
660
661 } while (false);
662
663 return status;
664}
665
666void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig)
667{
668 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info;
669 struct ar3k_config_info *config = (struct ar3k_config_info *)ar3kconfig;
670
671 config->pHCIDev = pHcidevInfo->pHCIDev;
672 config->pHCIProps = &pHcidevInfo->HCIProps;
673 config->pHIFDevice = ar->arHifDevice;
674 config->pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
675 config->Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
676 config->AR3KBaudRate = 115200;
677}
678
679#ifdef CONFIG_BLUEZ_HCI_BRIDGE
680/*** BT Stack Entrypoints *******/
681
682/*
683 * bt_open - open a handle to the device
684*/
685static int bt_open(struct hci_dev *hdev)
686{
687
688 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_open - enter - x\n"));
689 set_bit(HCI_RUNNING, &hdev->flags);
690 set_bit(HCI_UP, &hdev->flags);
691 set_bit(HCI_INIT, &hdev->flags);
692 return 0;
693}
694
695/*
696 * bt_close - close handle to the device
697*/
698static int bt_close(struct hci_dev *hdev)
699{
700 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_close - enter\n"));
701 clear_bit(HCI_RUNNING, &hdev->flags);
702 return 0;
703}
704
705/*
706 * bt_send_frame - send data frames
707*/
708static int bt_send_frame(struct sk_buff *skb)
709{
710 struct hci_dev *hdev = (struct hci_dev *)skb->dev;
711 HCI_TRANSPORT_PACKET_TYPE type;
712 struct ar6k_hci_bridge_info *pHcidevInfo;
713 struct htc_packet *pPacket;
714 int status = 0;
715 struct sk_buff *txSkb = NULL;
716
717 if (!hdev) {
718 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_send_frame - no device\n"));
719 return -ENODEV;
720 }
721
722 if (!test_bit(HCI_RUNNING, &hdev->flags)) {
723 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_send_frame - not open\n"));
724 return -EBUSY;
725 }
726
727 pHcidevInfo = (struct ar6k_hci_bridge_info *)hdev->driver_data;
728 A_ASSERT(pHcidevInfo != NULL);
729
730 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("+bt_send_frame type: %d \n",bt_cb(skb)->pkt_type));
731 type = HCI_COMMAND_TYPE;
732
733 switch (bt_cb(skb)->pkt_type) {
734 case HCI_COMMAND_PKT:
735 type = HCI_COMMAND_TYPE;
736 hdev->stat.cmd_tx++;
737 break;
738
739 case HCI_ACLDATA_PKT:
740 type = HCI_ACL_TYPE;
741 hdev->stat.acl_tx++;
742 break;
743
744 case HCI_SCODATA_PKT:
745 /* we don't support SCO over the bridge */
746 kfree_skb(skb);
747 return 0;
748 default:
749 A_ASSERT(false);
750 kfree_skb(skb);
751 return 0;
752 }
753
754 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
755 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(">>> Send HCI %s packet len: %d\n",
756 (type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL",
757 skb->len));
758 if (type == HCI_COMMAND_TYPE) {
759 u16 opcode = HCI_GET_OP_CODE(skb->data);
760 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" HCI Command: OGF:0x%X OCF:0x%X \r\n",
761 opcode >> 10, opcode & 0x3FF));
762 }
763 AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump");
764 }
765
766 do {
767
768 txSkb = bt_skb_alloc(TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom +
769 pHcidevInfo->HCIProps.TailRoom + skb->len,
770 GFP_ATOMIC);
771
772 if (txSkb == NULL) {
773 status = A_NO_MEMORY;
774 break;
775 }
776
777 bt_cb(txSkb)->pkt_type = bt_cb(skb)->pkt_type;
778 txSkb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
779 skb_reserve(txSkb, TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom);
780 memcpy(txSkb->data, skb->data, skb->len);
781 skb_put(txSkb,skb->len);
782
783 pPacket = AllocHTCStruct(pHcidevInfo);
784 if (NULL == pPacket) {
785 status = A_NO_MEMORY;
786 break;
787 }
788
789 /* HCI packet length here doesn't include the 1-byte transport header which
790 * will be handled by the HCI transport layer. Enough headroom has already
791 * been reserved above for the transport header
792 */
793 SET_HTC_PACKET_INFO_TX(pPacket,
794 txSkb,
795 txSkb->data,
796 txSkb->len,
797 type,
798 AR6K_CONTROL_PKT_TAG); /* HCI packets cannot be dropped */
799
800 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: bt_send_frame skb:0x%lX \n",(unsigned long)txSkb));
801 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: type:%d, Total Length:%d Bytes \n",
802 type, txSkb->len));
803
804 status = HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false);
805 pPacket = NULL;
806 txSkb = NULL;
807
808 } while (false);
809
810 if (txSkb != NULL) {
811 kfree_skb(txSkb);
812 }
813
814 kfree_skb(skb);
815
816 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("-bt_send_frame \n"));
817 return 0;
818}
819
820/*
821 * bt_ioctl - ioctl processing
822*/
823static int bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
824{
825 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_ioctl - enter\n"));
826 return -ENOIOCTLCMD;
827}
828
829/*
830 * bt_flush - flush outstandingbpackets
831*/
832static int bt_flush(struct hci_dev *hdev)
833{
834 struct ar6k_hci_bridge_info *pHcidevInfo;
835
836 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_flush - enter\n"));
837
838 pHcidevInfo = (struct ar6k_hci_bridge_info *)hdev->driver_data;
839
840 /* TODO??? */
841
842 return 0;
843}
844
845
846/*
847 * bt_destruct -
848*/
849static void bt_destruct(struct hci_dev *hdev)
850{
851 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_destruct - enter\n"));
852 /* nothing to do here */
853}
854
855static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
856{
857 int status = 0;
858 struct hci_dev *pHciDev = NULL;
859 struct hif_device_os_device_info osDevInfo;
860
861 if (!setupbtdev) {
862 return 0;
863 }
864
865 do {
866
867 A_MEMZERO(&osDevInfo,sizeof(osDevInfo));
868 /* get the underlying OS device */
869#ifdef EXPORT_HCI_BRIDGE_INTERFACE
870 status = ar6000_get_hif_dev((struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice),
871 &osDevInfo);
872#else
873 status = HIFConfigureDevice(pHcidevInfo->ar->arHifDevice,
874 HIF_DEVICE_GET_OS_DEVICE,
875 &osDevInfo,
876 sizeof(osDevInfo));
877#endif
878
879 if (status) {
880 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to OS device info from HIF\n"));
881 break;
882 }
883
884 /* allocate a BT HCI struct for this device */
885 pHciDev = hci_alloc_dev();
886 if (NULL == pHciDev) {
887 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge - failed to allocate bt struct \n"));
888 status = A_NO_MEMORY;
889 break;
890 }
891 /* save the device, we'll register this later */
892 pHcidevInfo->pBtStackHCIDev = pHciDev;
893 SET_HCIDEV_DEV(pHciDev,osDevInfo.pOSDevice);
894 SET_HCI_BUS_TYPE(pHciDev, HCI_VIRTUAL, HCI_BREDR);
895 pHciDev->driver_data = pHcidevInfo;
896 pHciDev->open = bt_open;
897 pHciDev->close = bt_close;
898 pHciDev->send = bt_send_frame;
899 pHciDev->ioctl = bt_ioctl;
900 pHciDev->flush = bt_flush;
901 pHciDev->destruct = bt_destruct;
902 pHciDev->owner = THIS_MODULE;
903 /* driver is running in normal BT mode */
904 pHcidevInfo->HciNormalMode = true;
905
906 } while (false);
907
908 if (status) {
909 bt_cleanup_hci(pHcidevInfo);
910 }
911
912 return status;
913}
914
915static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
916{
917 int err;
918
919 if (pHcidevInfo->HciRegistered) {
920 pHcidevInfo->HciRegistered = false;
921 clear_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags);
922 clear_bit(HCI_UP, &pHcidevInfo->pBtStackHCIDev->flags);
923 clear_bit(HCI_INIT, &pHcidevInfo->pBtStackHCIDev->flags);
924 A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL);
925 /* unregister */
926 if ((err = hci_unregister_dev(pHcidevInfo->pBtStackHCIDev)) < 0) {
927 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to unregister with bluetooth %d\n",err));
928 }
929 }
930
931 kfree(pHcidevInfo->pBtStackHCIDev);
932 pHcidevInfo->pBtStackHCIDev = NULL;
933}
934
935static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
936{
937 int err;
938 int status = 0;
939
940 do {
941 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: registering HCI... \n"));
942 A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL);
943 /* mark that we are registered */
944 pHcidevInfo->HciRegistered = true;
945 if ((err = hci_register_dev(pHcidevInfo->pBtStackHCIDev)) < 0) {
946 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to register with bluetooth %d\n",err));
947 pHcidevInfo->HciRegistered = false;
948 status = A_ERROR;
949 break;
950 }
951
952 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: HCI registered \n"));
953
954 } while (false);
955
956 return status;
957}
958
959static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo,
960 HCI_TRANSPORT_PACKET_TYPE Type,
961 struct sk_buff *skb)
962{
963 u8 btType;
964 int len;
965 bool success = false;
966 BT_HCI_EVENT_HEADER *pEvent;
967
968 do {
969
970 if (!test_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags)) {
971 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_indicate_recv - not running\n"));
972 break;
973 }
974
975 switch (Type) {
976 case HCI_ACL_TYPE:
977 btType = HCI_ACLDATA_PKT;
978 break;
979 case HCI_EVENT_TYPE:
980 btType = HCI_EVENT_PKT;
981 break;
982 default:
983 btType = 0;
984 A_ASSERT(false);
985 break;
986 }
987
988 if (0 == btType) {
989 break;
990 }
991
992 /* set the final type */
993 bt_cb(skb)->pkt_type = btType;
994 /* set dev */
995 skb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
996 len = skb->len;
997
998 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_RECV)) {
999 if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
1000 pEvent = (BT_HCI_EVENT_HEADER *)skb->data;
1001 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV, ("BT HCI EventCode: %d, len:%d \n",
1002 pEvent->EventCode, pEvent->ParamLength));
1003 }
1004 }
1005
1006 /* pass receive packet up the stack */
1007 if (hci_recv_frame(skb) != 0) {
1008 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: hci_recv_frame failed \n"));
1009 break;
1010 } else {
1011 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV,
1012 ("HCI Bridge: Indicated RCV of type:%d, Length:%d \n",btType,len));
1013 }
1014
1015 success = true;
1016
1017 } while (false);
1018
1019 return success;
1020}
1021
1022static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length)
1023{
1024 struct sk_buff *skb;
1025 /* in normal HCI mode we need to alloc from the bt core APIs */
1026 skb = bt_skb_alloc(Length, GFP_ATOMIC);
1027 if (NULL == skb) {
1028 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc bt sk_buff \n"));
1029 }
1030 return skb;
1031}
1032
1033static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb)
1034{
1035 kfree_skb(skb);
1036}
1037
1038#else // { CONFIG_BLUEZ_HCI_BRIDGE
1039
1040 /* stubs when we only want to test the HCI bridging Interface without the HT stack */
1041static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
1042{
1043 return 0;
1044}
1045static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
1046{
1047
1048}
1049static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
1050{
1051 A_ASSERT(false);
1052 return A_ERROR;
1053}
1054
1055static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo,
1056 HCI_TRANSPORT_PACKET_TYPE Type,
1057 struct sk_buff *skb)
1058{
1059 A_ASSERT(false);
1060 return false;
1061}
1062
1063static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length)
1064{
1065 A_ASSERT(false);
1066 return NULL;
1067}
1068static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb)
1069{
1070 A_ASSERT(false);
1071}
1072
1073#endif // } CONFIG_BLUEZ_HCI_BRIDGE
1074
1075#else // { ATH_AR6K_ENABLE_GMBOX
1076
1077 /* stubs when GMBOX support is not needed */
1078
1079#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1080int ar6000_setup_hci(void *ar)
1081#else
1082int ar6000_setup_hci(struct ar6_softc *ar)
1083#endif
1084{
1085 return 0;
1086}
1087
1088#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1089void ar6000_cleanup_hci(void *ar)
1090#else
1091void ar6000_cleanup_hci(struct ar6_softc *ar)
1092#endif
1093{
1094 return;
1095}
1096
1097#ifndef EXPORT_HCI_BRIDGE_INTERFACE
1098void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig)
1099{
1100 return;
1101}
1102#endif
1103
1104#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1105int hci_test_send(void *ar, struct sk_buff *skb)
1106#else
1107int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb)
1108#endif
1109{
1110 return -EOPNOTSUPP;
1111}
1112
1113#endif // } ATH_AR6K_ENABLE_GMBOX
1114
1115
1116#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1117static int __init
1118hcibridge_init_module(void)
1119{
1120 int status;
1121 struct hci_transport_callbacks hciTransCallbacks;
1122
1123 hciTransCallbacks.setupTransport = ar6000_setup_hci;
1124 hciTransCallbacks.cleanupTransport = ar6000_cleanup_hci;
1125
1126 status = ar6000_register_hci_transport(&hciTransCallbacks);
1127 if (status)
1128 return -ENODEV;
1129
1130 return 0;
1131}
1132
1133static void __exit
1134hcibridge_cleanup_module(void)
1135{
1136}
1137
1138module_init(hcibridge_init_module);
1139module_exit(hcibridge_cleanup_module);
1140MODULE_LICENSE("Dual BSD/GPL");
1141#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h
deleted file mode 100644
index 80cef77738f..00000000000
--- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h
+++ /dev/null
@@ -1,776 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _AR6000_H_
25#define _AR6000_H_
26
27#include <linux/init.h>
28#include <linux/sched.h>
29#include <linux/spinlock.h>
30#include <linux/if_ether.h>
31#include <linux/etherdevice.h>
32#include <net/iw_handler.h>
33#include <linux/if_arp.h>
34#include <linux/ip.h>
35#include <linux/wireless.h>
36#include <net/cfg80211.h>
37#include <linux/module.h>
38#include <asm/io.h>
39
40#include <a_config.h>
41#include <athdefs.h>
42#include "a_osapi.h"
43#include "htc_api.h"
44#include "wmi.h"
45#include "a_drv.h"
46#include "bmi.h"
47#include <ieee80211.h>
48#include <ieee80211_ioctl.h>
49#include <wlan_api.h>
50#include <wmi_api.h>
51#include "pkt_log.h"
52#include "aggr_recv_api.h"
53#include <host_version.h>
54#include <linux/rtnetlink.h>
55#include <linux/moduleparam.h>
56#include "ar6000_api.h"
57#ifdef CONFIG_HOST_TCMD_SUPPORT
58#include <testcmd.h>
59#endif
60#include <linux/firmware.h>
61
62#include "targaddrs.h"
63#include "dbglog_api.h"
64#include "ar6000_diag.h"
65#include "common_drv.h"
66#include "roaming.h"
67#include "hci_transport_api.h"
68#define ATH_MODULE_NAME driver
69#include "a_debug.h"
70#include "hw/apb_map.h"
71#include "hw/rtc_reg.h"
72#include "hw/mbox_reg.h"
73#include "gpio_reg.h"
74
75#define ATH_DEBUG_DBG_LOG ATH_DEBUG_MAKE_MODULE_MASK(0)
76#define ATH_DEBUG_WLAN_CONNECT ATH_DEBUG_MAKE_MODULE_MASK(1)
77#define ATH_DEBUG_WLAN_SCAN ATH_DEBUG_MAKE_MODULE_MASK(2)
78#define ATH_DEBUG_WLAN_TX ATH_DEBUG_MAKE_MODULE_MASK(3)
79#define ATH_DEBUG_WLAN_RX ATH_DEBUG_MAKE_MODULE_MASK(4)
80#define ATH_DEBUG_HTC_RAW ATH_DEBUG_MAKE_MODULE_MASK(5)
81#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
82#define ATH_DEBUG_HCI_RECV ATH_DEBUG_MAKE_MODULE_MASK(7)
83#define ATH_DEBUG_HCI_SEND ATH_DEBUG_MAKE_MODULE_MASK(8)
84#define ATH_DEBUG_HCI_DUMP ATH_DEBUG_MAKE_MODULE_MASK(9)
85
86#ifndef __dev_put
87#define __dev_put(dev) dev_put(dev)
88#endif
89
90
91#define USER_SAVEDKEYS_STAT_INIT 0
92#define USER_SAVEDKEYS_STAT_RUN 1
93
94// TODO this needs to move into the AR_SOFTC struct
95struct USER_SAVEDKEYS {
96 struct ieee80211req_key ucast_ik;
97 struct ieee80211req_key bcast_ik;
98 CRYPTO_TYPE keyType;
99 bool keyOk;
100};
101
102#define DBG_INFO 0x00000001
103#define DBG_ERROR 0x00000002
104#define DBG_WARNING 0x00000004
105#define DBG_SDIO 0x00000008
106#define DBG_HIF 0x00000010
107#define DBG_HTC 0x00000020
108#define DBG_WMI 0x00000040
109#define DBG_WMI2 0x00000080
110#define DBG_DRIVER 0x00000100
111
112#define DBG_DEFAULTS (DBG_ERROR|DBG_WARNING)
113
114
115int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
116int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
117
118#ifdef __cplusplus
119extern "C" {
120#endif
121
122#define MAX_AR6000 1
123#define AR6000_MAX_RX_BUFFERS 16
124#define AR6000_BUFFER_SIZE 1664
125#define AR6000_MAX_AMSDU_RX_BUFFERS 4
126#define AR6000_AMSDU_REFILL_THRESHOLD 3
127#define AR6000_AMSDU_BUFFER_SIZE (WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH + 128)
128#define AR6000_MAX_RX_MESSAGE_SIZE (max(WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH,WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH))
129
130#define AR6000_TX_TIMEOUT 10
131#define AR6000_ETH_ADDR_LEN 6
132#define AR6000_MAX_ENDPOINTS 4
133#define MAX_NODE_NUM 15
134/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
135#define MAX_DEF_COOKIE_NUM 180
136#define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */
137#define MAX_COOKIE_NUM (MAX_DEF_COOKIE_NUM + MAX_HI_COOKIE_NUM)
138
139/* MAX_DEFAULT_SEND_QUEUE_DEPTH is used to set the default queue depth for the
140 * WMM send queues. If a queue exceeds this depth htc will query back to the
141 * OS specific layer by calling EpSendFull(). This gives the OS layer the
142 * opportunity to drop the packet if desired. Therefore changing
143 * MAX_DEFAULT_SEND_QUEUE_DEPTH does not affect resource utilization but
144 * does impact the threshold used to identify if a packet should be
145 * dropped. */
146#define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
147
148#define AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT 1
149#define AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT 1
150#define A_DISCONNECT_TIMER_INTERVAL 10 * 1000
151#define A_DEFAULT_LISTEN_INTERVAL 100
152#define A_MAX_WOW_LISTEN_INTERVAL 1000
153
154enum {
155 DRV_HB_CHALLENGE = 0,
156 APP_HB_CHALLENGE
157};
158
159enum {
160 WLAN_INIT_MODE_NONE = 0,
161 WLAN_INIT_MODE_USR,
162 WLAN_INIT_MODE_UDEV,
163 WLAN_INIT_MODE_DRV
164};
165
166/* Suspend - configuration */
167enum {
168 WLAN_SUSPEND_CUT_PWR = 0,
169 WLAN_SUSPEND_DEEP_SLEEP,
170 WLAN_SUSPEND_WOW,
171 WLAN_SUSPEND_CUT_PWR_IF_BT_OFF
172};
173
174/* WiFi OFF - configuration */
175enum {
176 WLAN_OFF_CUT_PWR = 0,
177 WLAN_OFF_DEEP_SLEEP,
178};
179
180/* WLAN low power state */
181enum {
182 WLAN_POWER_STATE_ON = 0,
183 WLAN_POWER_STATE_CUT_PWR = 1,
184 WLAN_POWER_STATE_DEEP_SLEEP,
185 WLAN_POWER_STATE_WOW
186};
187
188/* WLAN WoW State */
189enum {
190 WLAN_WOW_STATE_NONE = 0,
191 WLAN_WOW_STATE_SUSPENDED,
192 WLAN_WOW_STATE_SUSPENDING
193};
194
195
196typedef enum _AR6K_BIN_FILE {
197 AR6K_OTP_FILE,
198 AR6K_FIRMWARE_FILE,
199 AR6K_PATCH_FILE,
200 AR6K_BOARD_DATA_FILE,
201} AR6K_BIN_FILE;
202
203#ifdef SETUPHCI_ENABLED
204#define SETUPHCI_DEFAULT 1
205#else
206#define SETUPHCI_DEFAULT 0
207#endif /* SETUPHCI_ENABLED */
208
209#ifdef SETUPBTDEV_ENABLED
210#define SETUPBTDEV_DEFAULT 1
211#else
212#define SETUPBTDEV_DEFAULT 0
213#endif /* SETUPBTDEV_ENABLED */
214
215#ifdef ENABLEUARTPRINT_SET
216#define ENABLEUARTPRINT_DEFAULT 1
217#else
218#define ENABLEUARTPRINT_DEFAULT 0
219#endif /* ENABLEARTPRINT_SET */
220
221#ifdef ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER
222#define NOHIFSCATTERSUPPORT_DEFAULT 1
223#else /* ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER */
224#define NOHIFSCATTERSUPPORT_DEFAULT 0
225#endif /* ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER */
226
227
228#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE)
229
230#ifdef CONFIG_AR600x_BT_QCOM
231#define ATH6KL_BT_DEV 1
232#elif defined(CONFIG_AR600x_BT_CSR)
233#define ATH6KL_BT_DEV 2
234#else
235#define ATH6KL_BT_DEV 3
236#endif
237
238#ifdef CONFIG_AR600x_DUAL_ANTENNA
239#define ATH6KL_BT_ANTENNA 2
240#else
241#define ATH6KL_BT_ANTENNA 1
242#endif
243
244#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */
245
246#ifdef AR600x_BT_AR3001
247#define AR3KHCIBAUD_DEFAULT 3000000
248#define HCIUARTSCALE_DEFAULT 1
249#define HCIUARTSTEP_DEFAULT 8937
250#else
251#define AR3KHCIBAUD_DEFAULT 0
252#define HCIUARTSCALE_DEFAULT 0
253#define HCIUARTSTEP_DEFAULT 0
254#endif /* AR600x_BT_AR3001 */
255
256#define WLAN_INIT_MODE_DEFAULT WLAN_INIT_MODE_DRV
257
258#define AR6K_PATCH_DOWNLOAD_ADDRESS(_param, _ver) do { \
259 if ((_ver) == AR6003_REV1_VERSION) { \
260 (_param) = AR6003_REV1_PATCH_DOWNLOAD_ADDRESS; \
261 } else if ((_ver) == AR6003_REV2_VERSION) { \
262 (_param) = AR6003_REV2_PATCH_DOWNLOAD_ADDRESS; \
263 } else { \
264 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
265 A_ASSERT(0); \
266 } \
267} while (0)
268
269#define AR6K_DATA_DOWNLOAD_ADDRESS(_param, _ver) do { \
270 if ((_ver) == AR6003_REV1_VERSION) { \
271 (_param) = AR6003_REV1_DATA_DOWNLOAD_ADDRESS; \
272 } else if ((_ver) == AR6003_REV2_VERSION) { \
273 (_param) = AR6003_REV2_DATA_DOWNLOAD_ADDRESS; \
274 } else { \
275 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
276 A_ASSERT(0); \
277 } \
278} while (0)
279
280#define AR6K_DATASET_PATCH_ADDRESS(_param, _ver) do { \
281 if ((_ver) == AR6003_REV2_VERSION) { \
282 (_param) = AR6003_REV2_DATASET_PATCH_ADDRESS; \
283 } else if ((_ver) == AR6003_REV3_VERSION) { \
284 (_param) = AR6003_REV3_DATASET_PATCH_ADDRESS; \
285 } else { \
286 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
287 A_ASSERT(0); \
288 } \
289} while (0)
290
291#define AR6K_APP_LOAD_ADDRESS(_param, _ver) do { \
292 if ((_ver) == AR6003_REV2_VERSION) { \
293 (_param) = AR6003_REV2_APP_LOAD_ADDRESS; \
294 } else if ((_ver) == AR6003_REV3_VERSION) { \
295 (_param) = AR6003_REV3_APP_LOAD_ADDRESS; \
296 } else { \
297 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
298 A_ASSERT(0); \
299 } \
300} while (0)
301
302#define AR6K_APP_START_OVERRIDE_ADDRESS(_param, _ver) do { \
303 if ((_ver) == AR6003_REV2_VERSION) { \
304 (_param) = AR6003_REV2_APP_START_OVERRIDE; \
305 } else if ((_ver) == AR6003_REV3_VERSION) { \
306 (_param) = AR6003_REV3_APP_START_OVERRIDE; \
307 } else { \
308 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
309 A_ASSERT(0); \
310 } \
311} while (0)
312
313/* AR6003 1.0 definitions */
314#define AR6003_REV1_VERSION 0x300002ba
315#define AR6003_REV1_DATA_DOWNLOAD_ADDRESS AR6003_REV1_OTP_DATA_ADDRESS
316#define AR6003_REV1_PATCH_DOWNLOAD_ADDRESS 0x57ea6c
317#define AR6003_REV1_OTP_FILE "ath6k/AR6003/hw1.0/otp.bin.z77"
318#define AR6003_REV1_FIRMWARE_FILE "ath6k/AR6003/hw1.0/athwlan.bin.z77"
319#define AR6003_REV1_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw1.0/athtcmd_ram.bin"
320#define AR6003_REV1_ART_FIRMWARE_FILE "ath6k/AR6003/hw1.0/device.bin"
321#define AR6003_REV1_PATCH_FILE "ath6k/AR6003/hw1.0/data.patch.bin"
322#define AR6003_REV1_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw1.0/endpointping.bin"
323#ifdef CONFIG_AR600x_SD31_XXX
324#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD31.bin"
325#elif defined(CONFIG_AR600x_SD32_XXX)
326#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD32.bin"
327#elif defined(CONFIG_AR600x_WB31_XXX)
328#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.WB31.bin"
329#else
330#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.CUSTOM.bin"
331#endif /* Board Data File */
332
333/* AR6003 2.0 definitions */
334#define AR6003_REV2_VERSION 0x30000384
335#define AR6003_REV2_DATA_DOWNLOAD_ADDRESS AR6003_REV2_OTP_DATA_ADDRESS
336#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910
337#define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77"
338#define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77"
339#define AR6003_REV2_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin"
340#define AR6003_REV2_ART_FIRMWARE_FILE "ath6k/AR6003/hw2.0/device.bin"
341#define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin"
342#define AR6003_REV2_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw2.0/endpointping.bin"
343#ifdef CONFIG_AR600x_SD31_XXX
344#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin"
345#elif defined(CONFIG_AR600x_SD32_XXX)
346#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD32.bin"
347#elif defined(CONFIG_AR600x_WB31_XXX)
348#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.WB31.bin"
349#else
350#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.CUSTOM.bin"
351#endif /* Board Data File */
352
353/* AR6003 3.0 definitions */
354#define AR6003_REV3_VERSION 0x30000582
355#define AR6003_REV3_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin"
356#define AR6003_REV3_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin"
357#define AR6003_REV3_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin"
358#define AR6003_REV3_ART_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/device.bin"
359#define AR6003_REV3_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin"
360#define AR6003_REV3_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/endpointping.bin"
361#ifdef CONFIG_AR600x_SD31_XXX
362#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
363#elif defined(CONFIG_AR600x_SD32_XXX)
364#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.SD32.bin"
365#elif defined(CONFIG_AR600x_WB31_XXX)
366#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.WB31.bin"
367#else
368#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.CUSTOM.bin"
369#endif /* Board Data File */
370
371
372/* Power states */
373enum {
374 WLAN_PWR_CTRL_UP = 0,
375 WLAN_PWR_CTRL_CUT_PWR,
376 WLAN_PWR_CTRL_DEEP_SLEEP,
377 WLAN_PWR_CTRL_WOW,
378 WLAN_PWR_CTRL_DEEP_SLEEP_DISABLED
379};
380
381/* HTC RAW streams */
382typedef enum _HTC_RAW_STREAM_ID {
383 HTC_RAW_STREAM_NOT_MAPPED = -1,
384 HTC_RAW_STREAM_0 = 0,
385 HTC_RAW_STREAM_1 = 1,
386 HTC_RAW_STREAM_2 = 2,
387 HTC_RAW_STREAM_3 = 3,
388 HTC_RAW_STREAM_NUM_MAX
389} HTC_RAW_STREAM_ID;
390
391#define RAW_HTC_READ_BUFFERS_NUM 4
392#define RAW_HTC_WRITE_BUFFERS_NUM 4
393
394#define HTC_RAW_BUFFER_SIZE 1664
395
396typedef struct {
397 int currPtr;
398 int length;
399 unsigned char data[HTC_RAW_BUFFER_SIZE];
400 struct htc_packet HTCPacket;
401} raw_htc_buffer;
402
403#ifdef CONFIG_HOST_TCMD_SUPPORT
404/*
405 * add TCMD_MODE besides wmi and bypasswmi
406 * in TCMD_MODE, only few TCMD releated wmi commands
407 * counld be hanlder
408 */
409enum {
410 AR6000_WMI_MODE = 0,
411 AR6000_BYPASS_MODE,
412 AR6000_TCMD_MODE,
413 AR6000_WLAN_MODE
414};
415#endif /* CONFIG_HOST_TCMD_SUPPORT */
416
417struct ar_wep_key {
418 u8 arKeyIndex;
419 u8 arKeyLen;
420 u8 arKey[64];
421} ;
422
423struct ar_key {
424 u8 key[WLAN_MAX_KEY_LEN];
425 u8 key_len;
426 u8 seq[IW_ENCODE_SEQ_MAX_SIZE];
427 u8 seq_len;
428 u32 cipher;
429};
430
431enum {
432 SME_DISCONNECTED,
433 SME_CONNECTING,
434 SME_CONNECTED
435};
436
437struct ar_node_mapping {
438 u8 macAddress[6];
439 u8 epId;
440 u8 txPending;
441};
442
443struct ar_cookie {
444 unsigned long arc_bp[2]; /* Must be first field */
445 struct htc_packet HtcPkt; /* HTC packet wrapper */
446 struct ar_cookie *arc_list_next;
447};
448
449struct ar_hb_chlng_resp {
450 A_TIMER timer;
451 u32 frequency;
452 u32 seqNum;
453 bool outstanding;
454 u8 missCnt;
455 u8 missThres;
456};
457
458/* Per STA data, used in AP mode */
459/*TODO: All this should move to OS independent dir */
460
461#define STA_PWR_MGMT_MASK 0x1
462#define STA_PWR_MGMT_SHIFT 0x0
463#define STA_PWR_MGMT_AWAKE 0x0
464#define STA_PWR_MGMT_SLEEP 0x1
465
466#define STA_SET_PWR_SLEEP(sta) (sta->flags |= (STA_PWR_MGMT_MASK << STA_PWR_MGMT_SHIFT))
467#define STA_CLR_PWR_SLEEP(sta) (sta->flags &= ~(STA_PWR_MGMT_MASK << STA_PWR_MGMT_SHIFT))
468#define STA_IS_PWR_SLEEP(sta) ((sta->flags >> STA_PWR_MGMT_SHIFT) & STA_PWR_MGMT_MASK)
469
470#define STA_PS_POLLED_MASK 0x1
471#define STA_PS_POLLED_SHIFT 0x1
472#define STA_SET_PS_POLLED(sta) (sta->flags |= (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
473#define STA_CLR_PS_POLLED(sta) (sta->flags &= ~(STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
474#define STA_IS_PS_POLLED(sta) (sta->flags & (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
475
476typedef struct {
477 u16 flags;
478 u8 mac[ATH_MAC_LEN];
479 u8 aid;
480 u8 keymgmt;
481 u8 ucipher;
482 u8 auth;
483 u8 wpa_ie[IEEE80211_MAX_IE];
484 A_NETBUF_QUEUE_T psq; /* power save q */
485 A_MUTEX_T psqLock;
486} sta_t;
487
488typedef struct ar6_raw_htc {
489 HTC_ENDPOINT_ID arRaw2EpMapping[HTC_RAW_STREAM_NUM_MAX];
490 HTC_RAW_STREAM_ID arEp2RawMapping[ENDPOINT_MAX];
491 struct semaphore raw_htc_read_sem[HTC_RAW_STREAM_NUM_MAX];
492 struct semaphore raw_htc_write_sem[HTC_RAW_STREAM_NUM_MAX];
493 wait_queue_head_t raw_htc_read_queue[HTC_RAW_STREAM_NUM_MAX];
494 wait_queue_head_t raw_htc_write_queue[HTC_RAW_STREAM_NUM_MAX];
495 raw_htc_buffer raw_htc_read_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_READ_BUFFERS_NUM];
496 raw_htc_buffer raw_htc_write_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_WRITE_BUFFERS_NUM];
497 bool write_buffer_available[HTC_RAW_STREAM_NUM_MAX];
498 bool read_buffer_available[HTC_RAW_STREAM_NUM_MAX];
499} AR_RAW_HTC_T;
500
501struct ar6_softc {
502 struct net_device *arNetDev; /* net_device pointer */
503 void *arWmi;
504 int arTxPending[ENDPOINT_MAX];
505 int arTotalTxDataPending;
506 u8 arNumDataEndPts;
507 bool arWmiEnabled;
508 bool arWmiReady;
509 bool arConnected;
510 HTC_HANDLE arHtcTarget;
511 void *arHifDevice;
512 spinlock_t arLock;
513 struct semaphore arSem;
514 int arSsidLen;
515 u_char arSsid[32];
516 u8 arNextMode;
517 u8 arNetworkType;
518 u8 arDot11AuthMode;
519 u8 arAuthMode;
520 u8 arPairwiseCrypto;
521 u8 arPairwiseCryptoLen;
522 u8 arGroupCrypto;
523 u8 arGroupCryptoLen;
524 u8 arDefTxKeyIndex;
525 struct ar_wep_key arWepKeyList[WMI_MAX_KEY_INDEX + 1];
526 u8 arBssid[6];
527 u8 arReqBssid[6];
528 u16 arChannelHint;
529 u16 arBssChannel;
530 u16 arListenIntervalB;
531 u16 arListenIntervalT;
532 struct ar6000_version arVersion;
533 u32 arTargetType;
534 s8 arRssi;
535 u8 arTxPwr;
536 bool arTxPwrSet;
537 s32 arBitRate;
538 struct net_device_stats arNetStats;
539 struct iw_statistics arIwStats;
540 s8 arNumChannels;
541 u16 arChannelList[32];
542 u32 arRegCode;
543 bool statsUpdatePending;
544 TARGET_STATS arTargetStats;
545 s8 arMaxRetries;
546 u8 arPhyCapability;
547#ifdef CONFIG_HOST_TCMD_SUPPORT
548 u32 arTargetMode;
549 void *tcmd_rx_report;
550 int tcmd_rx_report_len;
551#endif
552 AR6000_WLAN_STATE arWlanState;
553 struct ar_node_mapping arNodeMap[MAX_NODE_NUM];
554 u8 arIbssPsEnable;
555 u8 arNodeNum;
556 u8 arNexEpId;
557 struct ar_cookie *arCookieList;
558 u32 arCookieCount;
559 u32 arRateMask;
560 u8 arSkipScan;
561 u16 arBeaconInterval;
562 bool arConnectPending;
563 bool arWmmEnabled;
564 struct ar_hb_chlng_resp arHBChallengeResp;
565 u8 arKeepaliveConfigured;
566 u32 arMgmtFilter;
567 HTC_ENDPOINT_ID arAc2EpMapping[WMM_NUM_AC];
568 bool arAcStreamActive[WMM_NUM_AC];
569 u8 arAcStreamPriMap[WMM_NUM_AC];
570 u8 arHiAcStreamActivePri;
571 u8 arEp2AcMapping[ENDPOINT_MAX];
572 HTC_ENDPOINT_ID arControlEp;
573#ifdef HTC_RAW_INTERFACE
574 AR_RAW_HTC_T *arRawHtc;
575#endif
576 bool arNetQueueStopped;
577 bool arRawIfInit;
578 int arDeviceIndex;
579 struct common_credit_state_info arCreditStateInfo;
580 bool arWMIControlEpFull;
581 bool dbgLogFetchInProgress;
582 u8 log_buffer[DBGLOG_HOST_LOG_BUFFER_SIZE];
583 u32 log_cnt;
584 u32 dbglog_init_done;
585 u32 arConnectCtrlFlags;
586 s32 user_savedkeys_stat;
587 u32 user_key_ctrl;
588 struct USER_SAVEDKEYS user_saved_keys;
589 USER_RSSI_THOLD rssi_map[12];
590 u8 arUserBssFilter;
591 u16 ap_profile_flag; /* AP mode */
592 WMI_AP_ACL g_acl; /* AP mode */
593 sta_t sta_list[AP_MAX_NUM_STA]; /* AP mode */
594 u8 sta_list_index; /* AP mode */
595 struct ieee80211req_key ap_mode_bkey; /* AP mode */
596 A_NETBUF_QUEUE_T mcastpsq; /* power save q for Mcast frames */
597 A_MUTEX_T mcastpsqLock;
598 bool DTIMExpired; /* flag to indicate DTIM expired */
599 u8 intra_bss; /* enable/disable intra bss data forward */
600 void *aggr_cntxt;
601#ifndef EXPORT_HCI_BRIDGE_INTERFACE
602 void *hcidev_info;
603#endif
604 WMI_AP_MODE_STAT arAPStats;
605 u8 ap_hidden_ssid;
606 u8 ap_country_code[3];
607 u8 ap_wmode;
608 u8 ap_dtim_period;
609 u16 ap_beacon_interval;
610 u16 arRTS;
611 u16 arACS; /* AP mode - Auto Channel Selection */
612 struct htc_packet_queue amsdu_rx_buffer_queue;
613 bool bIsDestroyProgress; /* flag to indicate ar6k destroy is in progress */
614 A_TIMER disconnect_timer;
615 u8 rxMetaVersion;
616#ifdef WAPI_ENABLE
617 u8 arWapiEnable;
618#endif
619 WMI_BTCOEX_CONFIG_EVENT arBtcoexConfig;
620 WMI_BTCOEX_STATS_EVENT arBtcoexStats;
621 s32 (*exitCallback)(void *config); /* generic callback at AR6K exit */
622 struct hif_device_os_device_info osDevInfo;
623 struct wireless_dev *wdev;
624 struct cfg80211_scan_request *scan_request;
625 struct ar_key keys[WMI_MAX_KEY_INDEX + 1];
626 u32 smeState;
627 u16 arWlanPowerState;
628 bool arWlanOff;
629#ifdef CONFIG_PM
630 u16 arWowState;
631 bool arBTOff;
632 bool arBTSharing;
633 u16 arSuspendConfig;
634 u16 arWlanOffConfig;
635 u16 arWow2Config;
636#endif
637 u8 scan_triggered;
638 WMI_SCAN_PARAMS_CMD scParams;
639#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4
640 u8 mcast_filters[MAC_MAX_FILTERS_PER_LIST][AR_MCAST_FILTER_MAC_ADDR_SIZE];
641 u8 bdaddr[6];
642 bool scanSpecificSsid;
643#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
644 void *arApDev;
645#endif
646 u8 arAutoAuthStage;
647
648 u8 *fw_otp;
649 size_t fw_otp_len;
650 u8 *fw;
651 size_t fw_len;
652 u8 *fw_patch;
653 size_t fw_patch_len;
654 u8 *fw_data;
655 size_t fw_data_len;
656};
657
658#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
659struct ar_virtual_interface {
660 struct net_device *arNetDev; /* net_device pointer */
661 struct ar6_softc *arDev; /* ar device pointer */
662 struct net_device *arStaNetDev; /* net_device pointer */
663};
664#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
665
666static inline void *ar6k_priv(struct net_device *dev)
667{
668 return (wdev_priv(dev->ieee80211_ptr));
669}
670
671#define SET_HCI_BUS_TYPE(pHciDev, __bus, __type) do { \
672 (pHciDev)->bus = (__bus); \
673 (pHciDev)->dev_type = (__type); \
674} while(0)
675
676#define GET_INODE_FROM_FILEP(filp) \
677 (filp)->f_path.dentry->d_inode
678
679#define arAc2EndpointID(ar,ac) (ar)->arAc2EpMapping[(ac)]
680#define arSetAc2EndpointIDMap(ar,ac,ep) \
681{ (ar)->arAc2EpMapping[(ac)] = (ep); \
682 (ar)->arEp2AcMapping[(ep)] = (ac); }
683#define arEndpoint2Ac(ar,ep) (ar)->arEp2AcMapping[(ep)]
684
685#define arRawIfEnabled(ar) (ar)->arRawIfInit
686#define arRawStream2EndpointID(ar,raw) (ar)->arRawHtc->arRaw2EpMapping[(raw)]
687#define arSetRawStream2EndpointIDMap(ar,raw,ep) \
688{ (ar)->arRawHtc->arRaw2EpMapping[(raw)] = (ep); \
689 (ar)->arRawHtc->arEp2RawMapping[(ep)] = (raw); }
690#define arEndpoint2RawStreamID(ar,ep) (ar)->arRawHtc->arEp2RawMapping[(ep)]
691
692struct ar_giwscan_param {
693 char *current_ev;
694 char *end_buf;
695 u32 bytes_needed;
696 struct iw_request_info *info;
697};
698
699#define AR6000_STAT_INC(ar, stat) (ar->arNetStats.stat++)
700
701#define AR6000_SPIN_LOCK(lock, param) do { \
702 if (irqs_disabled()) { \
703 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("IRQs disabled:AR6000_LOCK\n")); \
704 } \
705 spin_lock_bh(lock); \
706} while (0)
707
708#define AR6000_SPIN_UNLOCK(lock, param) do { \
709 if (irqs_disabled()) { \
710 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("IRQs disabled: AR6000_UNLOCK\n")); \
711 } \
712 spin_unlock_bh(lock); \
713} while (0)
714
715void ar6000_init_profile_info(struct ar6_softc *ar);
716void ar6000_install_static_wep_keys(struct ar6_softc *ar);
717int ar6000_init(struct net_device *dev);
718int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar);
719void ar6000_TxDataCleanup(struct ar6_softc *ar);
720int ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev);
721void ar6000_restart_endpoint(struct net_device *dev);
722void ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs);
723
724#ifdef HTC_RAW_INTERFACE
725
726#ifndef __user
727#define __user
728#endif
729
730int ar6000_htc_raw_open(struct ar6_softc *ar);
731int ar6000_htc_raw_close(struct ar6_softc *ar);
732ssize_t ar6000_htc_raw_read(struct ar6_softc *ar,
733 HTC_RAW_STREAM_ID StreamID,
734 char __user *buffer, size_t count);
735ssize_t ar6000_htc_raw_write(struct ar6_softc *ar,
736 HTC_RAW_STREAM_ID StreamID,
737 char __user *buffer, size_t count);
738
739#endif /* HTC_RAW_INTERFACE */
740
741/* AP mode */
742/*TODO: These routines should be moved to a file that is common across OS */
743sta_t *
744ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr);
745
746sta_t *
747ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid);
748
749u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason);
750
751/* HCI support */
752
753#ifndef EXPORT_HCI_BRIDGE_INTERFACE
754int ar6000_setup_hci(struct ar6_softc *ar);
755void ar6000_cleanup_hci(struct ar6_softc *ar);
756void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig);
757
758/* HCI bridge testing */
759int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb);
760#endif
761
762ATH_DEBUG_DECLARE_EXTERN(htc);
763ATH_DEBUG_DECLARE_EXTERN(wmi);
764ATH_DEBUG_DECLARE_EXTERN(bmi);
765ATH_DEBUG_DECLARE_EXTERN(hif);
766ATH_DEBUG_DECLARE_EXTERN(wlan);
767ATH_DEBUG_DECLARE_EXTERN(misc);
768
769extern u8 bcast_mac[];
770extern u8 null_mac[];
771
772#ifdef __cplusplus
773}
774#endif
775
776#endif /* _AR6000_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h
deleted file mode 100644
index 39e0873aff2..00000000000
--- a/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h
+++ /dev/null
@@ -1,36 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4// The software source and binaries included in this development package are
5// licensed, not sold. You, or your company, received the package under one
6// or more license agreements. The rights granted to you are specifically
7// listed in these license agreement(s). All other rights remain with Atheros
8// Communications, Inc., its subsidiaries, or the respective owner including
9// those listed on the included copyright notices. Distribution of any
10// portion of this package must be in strict compliance with the license
11// agreement(s) terms.
12// </copyright>
13//
14// <summary>
15// PAL driver for AR6003
16// </summary>
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22#ifndef _AR6K_PAL_H_
23#define _AR6K_PAL_H_
24#define HCI_GET_OP_CODE(p) (((u16)((p)[1])) << 8) | ((u16)((p)[0]))
25
26/* transmit packet reserve offset */
27#define TX_PACKET_RSV_OFFSET 32
28/* pal specific config structure */
29typedef bool (*ar6k_pal_recv_pkt_t)(void *pHciPalInfo, void *skb);
30typedef struct ar6k_pal_config_s
31{
32 ar6k_pal_recv_pkt_t fpar6k_pal_recv_pkt;
33}ar6k_pal_config_t;
34
35void register_pal_cb(ar6k_pal_config_t *palConfig_p);
36#endif /* _AR6K_PAL_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h
deleted file mode 100644
index 184dbdb5049..00000000000
--- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h
+++ /dev/null
@@ -1,190 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _AR6XAPI_LINUX_H
25#define _AR6XAPI_LINUX_H
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30struct ar6_softc;
31
32void ar6000_ready_event(void *devt, u8 *datap, u8 phyCap,
33 u32 sw_ver, u32 abi_ver);
34int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid);
35void ar6000_connect_event(struct ar6_softc *ar, u16 channel,
36 u8 *bssid, u16 listenInterval,
37 u16 beaconInterval, NETWORK_TYPE networkType,
38 u8 beaconIeLen, u8 assocReqLen,
39 u8 assocRespLen,u8 *assocInfo);
40void ar6000_disconnect_event(struct ar6_softc *ar, u8 reason,
41 u8 *bssid, u8 assocRespLen,
42 u8 *assocInfo, u16 protocolReasonStatus);
43void ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid,
44 bool ismcast);
45void ar6000_bitrate_rx(void *devt, s32 rateKbps);
46void ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList);
47void ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode);
48void ar6000_txPwr_rx(void *devt, u8 txPwr);
49void ar6000_keepalive_rx(void *devt, u8 configured);
50void ar6000_neighborReport_event(struct ar6_softc *ar, int numAps,
51 WMI_NEIGHBOR_INFO *info);
52void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num);
53void ar6000_scanComplete_event(struct ar6_softc *ar, int status);
54void ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, u32 len);
55void ar6000_rssiThreshold_event(struct ar6_softc *ar,
56 WMI_RSSI_THRESHOLD_VAL newThreshold,
57 s16 rssi);
58void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal);
59void ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cac_indication,
60 u8 statusCode, u8 *tspecSuggestion);
61void ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel, u16 newChannel);
62void ar6000_hbChallengeResp_event(struct ar6_softc *, u32 cookie, u32 source);
63void
64ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl);
65
66void
67ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p);
68
69void
70ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters,
71 WMI_GET_WOW_LIST_REPLY *wow_reply);
72
73void ar6000_pmkid_list_event(void *devt, u8 numPMKID,
74 WMI_PMKID *pmkidList, u8 *bssidList);
75
76void ar6000_gpio_intr_rx(u32 intr_mask, u32 input_values);
77void ar6000_gpio_data_rx(u32 reg_id, u32 value);
78void ar6000_gpio_ack_rx(void);
79
80s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt);
81s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi);
82s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above);
83
84void ar6000_dbglog_init_done(struct ar6_softc *ar);
85
86#ifdef CONFIG_HOST_TCMD_SUPPORT
87void ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len);
88#endif
89
90void ar6000_tx_retry_err_event(void *devt);
91
92void ar6000_snrThresholdEvent_rx(void *devt,
93 WMI_SNR_THRESHOLD_VAL newThreshold,
94 u8 snr);
95
96void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, u8 lqVal);
97
98
99void ar6000_ratemask_rx(void *devt, u32 ratemask);
100
101int ar6000_get_driver_cfg(struct net_device *dev,
102 u16 cfgParam,
103 void *result);
104void ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *data, int len);
105
106void ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped,
107 s8 *buffer, u32 length);
108
109int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar);
110
111void ar6000_peer_event(void *devt, u8 eventCode, u8 *bssid);
112
113void ar6000_indicate_tx_activity(void *devt, u8 trafficClass, bool Active);
114HTC_ENDPOINT_ID ar6000_ac2_endpoint_id ( void * devt, u8 ac);
115u8 ar6000_endpoint_id2_ac (void * devt, HTC_ENDPOINT_ID ep );
116
117void ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, u32 len);
118
119void ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, u32 len) ;
120
121void ar6000_dset_open_req(void *devt,
122 u32 id,
123 u32 targ_handle,
124 u32 targ_reply_fn,
125 u32 targ_reply_arg);
126void ar6000_dset_close(void *devt, u32 access_cookie);
127void ar6000_dset_data_req(void *devt,
128 u32 access_cookie,
129 u32 offset,
130 u32 length,
131 u32 targ_buf,
132 u32 targ_reply_fn,
133 u32 targ_reply_arg);
134
135
136#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
137void prof_count_rx(unsigned int addr, unsigned int count);
138#endif
139
140u32 ar6000_getnodeAge (void);
141
142u32 ar6000_getclkfreq (void);
143
144int ar6000_ap_mode_profile_commit(struct ar6_softc *ar);
145
146struct ieee80211req_wpaie;
147int
148ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie);
149
150int is_iwioctl_allowed(u8 mode, u16 cmd);
151
152int is_xioctl_allowed(u8 mode, int cmd);
153
154void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid);
155
156void ar6000_dtimexpiry_event(struct ar6_softc *ar);
157
158void ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *cmd);
159void ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *cmd);
160void ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *cmd);
161void ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd);
162
163#ifdef WAPI_ENABLE
164int ap_set_wapi_key(struct ar6_softc *ar, void *ik);
165void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac);
166#endif
167
168int ar6000_connect_to_ap(struct ar6_softc *ar);
169int ar6000_disconnect(struct ar6_softc *ar);
170int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool suspending);
171int ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state);
172int ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 state);
173
174#ifdef CONFIG_PM
175int ar6000_suspend_ev(void *context);
176int ar6000_resume_ev(void *context);
177int ar6000_power_change_ev(void *context, u32 config);
178void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent);
179#endif
180
181#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
182int ar6000_add_ap_interface(struct ar6_softc *ar, char *ifname);
183int ar6000_remove_ap_interface(struct ar6_softc *ar);
184#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
185
186#ifdef __cplusplus
187}
188#endif
189
190#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h
deleted file mode 100644
index 3d5f01da543..00000000000
--- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h
+++ /dev/null
@@ -1,1217 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _ATHDRV_LINUX_H
25#define _ATHDRV_LINUX_H
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31
32/*
33 * There are two types of ioctl's here: Standard ioctls and
34 * eXtended ioctls. All extended ioctls (XIOCTL) are multiplexed
35 * off of the single ioctl command, AR6000_IOCTL_EXTENDED. The
36 * arguments for every XIOCTL starts with a 32-bit command word
37 * that is used to select which extended ioctl is in use. After
38 * the command word are command-specific arguments.
39 */
40
41/* Linux standard Wireless Extensions, private ioctl interfaces */
42#define IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0)
43#define IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+1)
44#define IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+2)
45#define IEEE80211_IOCTL_SETMLME (SIOCIWFIRSTPRIV+3)
46#define IEEE80211_IOCTL_ADDPMKID (SIOCIWFIRSTPRIV+4)
47#define IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+5)
48//#define IEEE80211_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+6)
49//#define IEEE80211_IOCTL_SETWMMPARAMS (SIOCIWFIRSTPRIV+7)
50//#define IEEE80211_IOCTL_GETWMMPARAMS (SIOCIWFIRSTPRIV+8)
51//#define IEEE80211_IOCTL_GETOPTIE (SIOCIWFIRSTPRIV+9)
52//#define IEEE80211_IOCTL_SETAUTHALG (SIOCIWFIRSTPRIV+10)
53#define IEEE80211_IOCTL_LASTONE (SIOCIWFIRSTPRIV+10)
54
55
56
57/* ====WMI Ioctls==== */
58/*
59 *
60 * Many ioctls simply provide WMI services to application code:
61 * an application makes such an ioctl call with a set of arguments
62 * that are packaged into the corresponding WMI message, and sent
63 * to the Target.
64 */
65
66#define AR6000_IOCTL_WMI_GETREV (SIOCIWFIRSTPRIV+11)
67/*
68 * arguments:
69 * ar6000_version *revision
70 */
71
72#define AR6000_IOCTL_WMI_SETPWR (SIOCIWFIRSTPRIV+12)
73/*
74 * arguments:
75 * WMI_POWER_MODE_CMD pwrModeCmd (see include/wmi.h)
76 * uses: WMI_SET_POWER_MODE_CMDID
77 */
78
79#define AR6000_IOCTL_WMI_SETSCAN (SIOCIWFIRSTPRIV+13)
80/*
81 * arguments:
82 * WMI_SCAN_PARAMS_CMD scanParams (see include/wmi.h)
83 * uses: WMI_SET_SCAN_PARAMS_CMDID
84 */
85
86#define AR6000_IOCTL_WMI_SETLISTENINT (SIOCIWFIRSTPRIV+14)
87/*
88 * arguments:
89 * UINT32 listenInterval
90 * uses: WMI_SET_LISTEN_INT_CMDID
91 */
92
93#define AR6000_IOCTL_WMI_SETBSSFILTER (SIOCIWFIRSTPRIV+15)
94/*
95 * arguments:
96 * WMI_BSS_FILTER filter (see include/wmi.h)
97 * uses: WMI_SET_BSS_FILTER_CMDID
98 */
99
100#define AR6000_IOCTL_WMI_SET_CHANNELPARAMS (SIOCIWFIRSTPRIV+16)
101/*
102 * arguments:
103 * WMI_CHANNEL_PARAMS_CMD chParams
104 * uses: WMI_SET_CHANNEL_PARAMS_CMDID
105 */
106
107#define AR6000_IOCTL_WMI_SET_PROBEDSSID (SIOCIWFIRSTPRIV+17)
108/*
109 * arguments:
110 * WMI_PROBED_SSID_CMD probedSsids (see include/wmi.h)
111 * uses: WMI_SETPROBED_SSID_CMDID
112 */
113
114#define AR6000_IOCTL_WMI_SET_PMPARAMS (SIOCIWFIRSTPRIV+18)
115/*
116 * arguments:
117 * WMI_POWER_PARAMS_CMD powerParams (see include/wmi.h)
118 * uses: WMI_SET_POWER_PARAMS_CMDID
119 */
120
121#define AR6000_IOCTL_WMI_SET_BADAP (SIOCIWFIRSTPRIV+19)
122/*
123 * arguments:
124 * WMI_ADD_BAD_AP_CMD badAPs (see include/wmi.h)
125 * uses: WMI_ADD_BAD_AP_CMDID
126 */
127
128#define AR6000_IOCTL_WMI_GET_QOS_QUEUE (SIOCIWFIRSTPRIV+20)
129/*
130 * arguments:
131 * ar6000_queuereq queueRequest (see below)
132 */
133
134#define AR6000_IOCTL_WMI_CREATE_QOS (SIOCIWFIRSTPRIV+21)
135/*
136 * arguments:
137 * WMI_CREATE_PSTREAM createPstreamCmd (see include/wmi.h)
138 * uses: WMI_CREATE_PSTREAM_CMDID
139 */
140
141#define AR6000_IOCTL_WMI_DELETE_QOS (SIOCIWFIRSTPRIV+22)
142/*
143 * arguments:
144 * WMI_DELETE_PSTREAM_CMD deletePstreamCmd (see include/wmi.h)
145 * uses: WMI_DELETE_PSTREAM_CMDID
146 */
147
148#define AR6000_IOCTL_WMI_SET_SNRTHRESHOLD (SIOCIWFIRSTPRIV+23)
149/*
150 * arguments:
151 * WMI_SNR_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
152 * uses: WMI_SNR_THRESHOLD_PARAMS_CMDID
153 */
154
155#define AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24)
156/*
157 * arguments:
158 * WMI_TARGET_ERROR_REPORT_BITMASK errorReportBitMask (see include/wmi.h)
159 * uses: WMI_TARGET_ERROR_REPORT_BITMASK_CMDID
160 */
161
162#define AR6000_IOCTL_WMI_GET_TARGET_STATS (SIOCIWFIRSTPRIV+25)
163/*
164 * arguments:
165 * TARGET_STATS *targetStats (see below)
166 * uses: WMI_GET_STATISTICS_CMDID
167 */
168
169#define AR6000_IOCTL_WMI_SET_ASSOC_INFO (SIOCIWFIRSTPRIV+26)
170/*
171 * arguments:
172 * WMI_SET_ASSOC_INFO_CMD setAssocInfoCmd
173 * uses: WMI_SET_ASSOC_INFO_CMDID
174 */
175
176#define AR6000_IOCTL_WMI_SET_ACCESS_PARAMS (SIOCIWFIRSTPRIV+27)
177/*
178 * arguments:
179 * WMI_SET_ACCESS_PARAMS_CMD setAccessParams (see include/wmi.h)
180 * uses: WMI_SET_ACCESS_PARAMS_CMDID
181 */
182
183#define AR6000_IOCTL_WMI_SET_BMISS_TIME (SIOCIWFIRSTPRIV+28)
184/*
185 * arguments:
186 * UINT32 beaconMissTime
187 * uses: WMI_SET_BMISS_TIME_CMDID
188 */
189
190#define AR6000_IOCTL_WMI_SET_DISC_TIMEOUT (SIOCIWFIRSTPRIV+29)
191/*
192 * arguments:
193 * WMI_DISC_TIMEOUT_CMD disconnectTimeoutCmd (see include/wmi.h)
194 * uses: WMI_SET_DISC_TIMEOUT_CMDID
195 */
196
197#define AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS (SIOCIWFIRSTPRIV+30)
198/*
199 * arguments:
200 * WMI_IBSS_PM_CAPS_CMD ibssPowerMgmtCapsCmd
201 * uses: WMI_SET_IBSS_PM_CAPS_CMDID
202 */
203
204/*
205 * There is a very small space available for driver-private
206 * wireless ioctls. In order to circumvent this limitation,
207 * we multiplex a bunch of ioctls (XIOCTLs) on top of a
208 * single AR6000_IOCTL_EXTENDED ioctl.
209 */
210#define AR6000_IOCTL_EXTENDED (SIOCIWFIRSTPRIV+31)
211
212
213/* ====BMI Extended Ioctls==== */
214
215#define AR6000_XIOCTL_BMI_DONE 1
216/*
217 * arguments:
218 * UINT32 cmd (AR6000_XIOCTL_BMI_DONE)
219 * uses: BMI_DONE
220 */
221
222#define AR6000_XIOCTL_BMI_READ_MEMORY 2
223/*
224 * arguments:
225 * union {
226 * struct {
227 * UINT32 cmd (AR6000_XIOCTL_BMI_READ_MEMORY)
228 * UINT32 address
229 * UINT32 length
230 * }
231 * char results[length]
232 * }
233 * uses: BMI_READ_MEMORY
234 */
235
236#define AR6000_XIOCTL_BMI_WRITE_MEMORY 3
237/*
238 * arguments:
239 * UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_MEMORY)
240 * UINT32 address
241 * UINT32 length
242 * char data[length]
243 * uses: BMI_WRITE_MEMORY
244 */
245
246#define AR6000_XIOCTL_BMI_EXECUTE 4
247/*
248 * arguments:
249 * UINT32 cmd (AR6000_XIOCTL_BMI_EXECUTE)
250 * UINT32 TargetAddress
251 * UINT32 parameter
252 * uses: BMI_EXECUTE
253 */
254
255#define AR6000_XIOCTL_BMI_SET_APP_START 5
256/*
257 * arguments:
258 * UINT32 cmd (AR6000_XIOCTL_BMI_SET_APP_START)
259 * UINT32 TargetAddress
260 * uses: BMI_SET_APP_START
261 */
262
263#define AR6000_XIOCTL_BMI_READ_SOC_REGISTER 6
264/*
265 * arguments:
266 * union {
267 * struct {
268 * UINT32 cmd (AR6000_XIOCTL_BMI_READ_SOC_REGISTER)
269 * UINT32 TargetAddress, 32-bit aligned
270 * }
271 * UINT32 result
272 * }
273 * uses: BMI_READ_SOC_REGISTER
274 */
275
276#define AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER 7
277/*
278 * arguments:
279 * struct {
280 * UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER)
281 * UINT32 TargetAddress, 32-bit aligned
282 * UINT32 newValue
283 * }
284 * uses: BMI_WRITE_SOC_REGISTER
285 */
286
287#define AR6000_XIOCTL_BMI_TEST 8
288/*
289 * arguments:
290 * UINT32 cmd (AR6000_XIOCTL_BMI_TEST)
291 * UINT32 address
292 * UINT32 length
293 * UINT32 count
294 */
295
296
297
298/* Historical Host-side DataSet support */
299#define AR6000_XIOCTL_UNUSED9 9
300#define AR6000_XIOCTL_UNUSED10 10
301#define AR6000_XIOCTL_UNUSED11 11
302
303/* ====Misc Extended Ioctls==== */
304
305#define AR6000_XIOCTL_FORCE_TARGET_RESET 12
306/*
307 * arguments:
308 * UINT32 cmd (AR6000_XIOCTL_FORCE_TARGET_RESET)
309 */
310
311
312#ifdef HTC_RAW_INTERFACE
313/* HTC Raw Interface Ioctls */
314#define AR6000_XIOCTL_HTC_RAW_OPEN 13
315/*
316 * arguments:
317 * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_OPEN)
318 */
319
320#define AR6000_XIOCTL_HTC_RAW_CLOSE 14
321/*
322 * arguments:
323 * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_CLOSE)
324 */
325
326#define AR6000_XIOCTL_HTC_RAW_READ 15
327/*
328 * arguments:
329 * union {
330 * struct {
331 * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_READ)
332 * UINT32 mailboxID
333 * UINT32 length
334 * }
335 * results[length]
336 * }
337 */
338
339#define AR6000_XIOCTL_HTC_RAW_WRITE 16
340/*
341 * arguments:
342 * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_WRITE)
343 * UINT32 mailboxID
344 * UINT32 length
345 * char buffer[length]
346 */
347#endif /* HTC_RAW_INTERFACE */
348
349#define AR6000_XIOCTL_CHECK_TARGET_READY 17
350/*
351 * arguments:
352 * UINT32 cmd (AR6000_XIOCTL_CHECK_TARGET_READY)
353 */
354
355
356
357/* ====GPIO (General Purpose I/O) Extended Ioctls==== */
358
359#define AR6000_XIOCTL_GPIO_OUTPUT_SET 18
360/*
361 * arguments:
362 * UINT32 cmd (AR6000_XIOCTL_GPIO_OUTPUT_SET)
363 * ar6000_gpio_output_set_cmd_s (see below)
364 * uses: WMIX_GPIO_OUTPUT_SET_CMDID
365 */
366
367#define AR6000_XIOCTL_GPIO_INPUT_GET 19
368/*
369 * arguments:
370 * UINT32 cmd (AR6000_XIOCTL_GPIO_INPUT_GET)
371 * uses: WMIX_GPIO_INPUT_GET_CMDID
372 */
373
374#define AR6000_XIOCTL_GPIO_REGISTER_SET 20
375/*
376 * arguments:
377 * UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_SET)
378 * ar6000_gpio_register_cmd_s (see below)
379 * uses: WMIX_GPIO_REGISTER_SET_CMDID
380 */
381
382#define AR6000_XIOCTL_GPIO_REGISTER_GET 21
383/*
384 * arguments:
385 * UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_GET)
386 * ar6000_gpio_register_cmd_s (see below)
387 * uses: WMIX_GPIO_REGISTER_GET_CMDID
388 */
389
390#define AR6000_XIOCTL_GPIO_INTR_ACK 22
391/*
392 * arguments:
393 * UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_ACK)
394 * ar6000_cpio_intr_ack_cmd_s (see below)
395 * uses: WMIX_GPIO_INTR_ACK_CMDID
396 */
397
398#define AR6000_XIOCTL_GPIO_INTR_WAIT 23
399/*
400 * arguments:
401 * UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_WAIT)
402 */
403
404
405
406/* ====more wireless commands==== */
407
408#define AR6000_XIOCTL_SET_ADHOC_BSSID 24
409/*
410 * arguments:
411 * UINT32 cmd (AR6000_XIOCTL_SET_ADHOC_BSSID)
412 * WMI_SET_ADHOC_BSSID_CMD setAdHocBssidCmd (see include/wmi.h)
413 */
414
415#define AR6000_XIOCTL_SET_OPT_MODE 25
416/*
417 * arguments:
418 * UINT32 cmd (AR6000_XIOCTL_SET_OPT_MODE)
419 * WMI_SET_OPT_MODE_CMD setOptModeCmd (see include/wmi.h)
420 * uses: WMI_SET_OPT_MODE_CMDID
421 */
422
423#define AR6000_XIOCTL_OPT_SEND_FRAME 26
424/*
425 * arguments:
426 * UINT32 cmd (AR6000_XIOCTL_OPT_SEND_FRAME)
427 * WMI_OPT_TX_FRAME_CMD optTxFrameCmd (see include/wmi.h)
428 * uses: WMI_OPT_TX_FRAME_CMDID
429 */
430
431#define AR6000_XIOCTL_SET_BEACON_INTVAL 27
432/*
433 * arguments:
434 * UINT32 cmd (AR6000_XIOCTL_SET_BEACON_INTVAL)
435 * WMI_BEACON_INT_CMD beaconIntCmd (see include/wmi.h)
436 * uses: WMI_SET_BEACON_INT_CMDID
437 */
438
439
440#define IEEE80211_IOCTL_SETAUTHALG 28
441
442
443#define AR6000_XIOCTL_SET_VOICE_PKT_SIZE 29
444/*
445 * arguments:
446 * UINT32 cmd (AR6000_XIOCTL_SET_VOICE_PKT_SIZE)
447 * WMI_SET_VOICE_PKT_SIZE_CMD setVoicePktSizeCmd (see include/wmi.h)
448 * uses: WMI_SET_VOICE_PKT_SIZE_CMDID
449 */
450
451
452#define AR6000_XIOCTL_SET_MAX_SP 30
453/*
454 * arguments:
455 * UINT32 cmd (AR6000_XIOCTL_SET_MAX_SP)
456 * WMI_SET_MAX_SP_LEN_CMD maxSPLen(see include/wmi.h)
457 * uses: WMI_SET_MAX_SP_LEN_CMDID
458 */
459
460#define AR6000_XIOCTL_WMI_GET_ROAM_TBL 31
461
462#define AR6000_XIOCTL_WMI_SET_ROAM_CTRL 32
463
464#define AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS 33
465
466
467/*
468 * arguments:
469 * UINT32 cmd (AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS)
470 * WMI_SET_POWERSAVE_TIMERS_CMD powerSaveTimers(see include/wmi.h)
471 * WMI_SET_POWERSAVE_TIMERS_CMDID
472 */
473
474#define AR6000_XIOCTRL_WMI_GET_POWER_MODE 34
475/*
476 * arguments:
477 * UINT32 cmd (AR6000_XIOCTRL_WMI_GET_POWER_MODE)
478 */
479
480#define AR6000_XIOCTRL_WMI_SET_WLAN_STATE 35
481typedef enum {
482 WLAN_DISABLED,
483 WLAN_ENABLED
484} AR6000_WLAN_STATE;
485/*
486 * arguments:
487 * enable/disable
488 */
489
490#define AR6000_XIOCTL_WMI_GET_ROAM_DATA 36
491
492#define AR6000_XIOCTL_WMI_SETRETRYLIMITS 37
493/*
494 * arguments:
495 * WMI_SET_RETRY_LIMITS_CMD ibssSetRetryLimitsCmd
496 * uses: WMI_SET_RETRY_LIMITS_CMDID
497 */
498
499#ifdef CONFIG_HOST_TCMD_SUPPORT
500/* ====extended commands for radio test ==== */
501
502#define AR6000_XIOCTL_TCMD_CONT_TX 38
503/*
504 * arguments:
505 * UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_TX)
506 * WMI_TCMD_CONT_TX_CMD contTxCmd (see include/wmi.h)
507 * uses: WMI_TCMD_CONT_TX_CMDID
508 */
509
510#define AR6000_XIOCTL_TCMD_CONT_RX 39
511/*
512 * arguments:
513 * UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_RX)
514 * WMI_TCMD_CONT_RX_CMD rxCmd (see include/wmi.h)
515 * uses: WMI_TCMD_CONT_RX_CMDID
516 */
517
518#define AR6000_XIOCTL_TCMD_PM 40
519/*
520 * arguments:
521 * UINT32 cmd (AR6000_XIOCTL_TCMD_PM)
522 * WMI_TCMD_PM_CMD pmCmd (see include/wmi.h)
523 * uses: WMI_TCMD_PM_CMDID
524 */
525
526#endif /* CONFIG_HOST_TCMD_SUPPORT */
527
528#define AR6000_XIOCTL_WMI_STARTSCAN 41
529/*
530 * arguments:
531 * UINT32 cmd (AR6000_XIOCTL_WMI_STARTSCAN)
532 * UINT8 scanType
533 * UINT8 scanConnected
534 * u32 forceFgScan
535 * uses: WMI_START_SCAN_CMDID
536 */
537
538#define AR6000_XIOCTL_WMI_SETFIXRATES 42
539
540#define AR6000_XIOCTL_WMI_GETFIXRATES 43
541
542
543#define AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD 44
544/*
545 * arguments:
546 * WMI_RSSI_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
547 * uses: WMI_RSSI_THRESHOLD_PARAMS_CMDID
548 */
549
550#define AR6000_XIOCTL_WMI_CLR_RSSISNR 45
551/*
552 * arguments:
553 * WMI_CLR_RSSISNR_CMD thresholdParams (see include/wmi.h)
554 * uses: WMI_CLR_RSSISNR_CMDID
555 */
556
557#define AR6000_XIOCTL_WMI_SET_LQTHRESHOLD 46
558/*
559 * arguments:
560 * WMI_LQ_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
561 * uses: WMI_LQ_THRESHOLD_PARAMS_CMDID
562 */
563
564#define AR6000_XIOCTL_WMI_SET_RTS 47
565/*
566 * arguments:
567 * WMI_SET_RTS_MODE_CMD (see include/wmi.h)
568 * uses: WMI_SET_RTS_MODE_CMDID
569 */
570
571#define AR6000_XIOCTL_WMI_SET_LPREAMBLE 48
572
573#define AR6000_XIOCTL_WMI_SET_AUTHMODE 49
574/*
575 * arguments:
576 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_AUTHMODE)
577 * UINT8 mode
578 * uses: WMI_SET_RECONNECT_AUTH_MODE_CMDID
579 */
580
581#define AR6000_XIOCTL_WMI_SET_REASSOCMODE 50
582
583/*
584 * arguments:
585 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_WMM)
586 * UINT8 mode
587 * uses: WMI_SET_WMM_CMDID
588 */
589#define AR6000_XIOCTL_WMI_SET_WMM 51
590
591/*
592 * arguments:
593 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS)
594 * UINT32 frequency
595 * UINT8 threshold
596 */
597#define AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS 52
598
599/*
600 * arguments:
601 * UINT32 cmd (AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP)
602 * UINT32 cookie
603 */
604#define AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP 53
605
606/*
607 * arguments:
608 * UINT32 cmd (AR6000_XIOCTL_WMI_GET_RD)
609 * UINT32 regDomain
610 */
611#define AR6000_XIOCTL_WMI_GET_RD 54
612
613#define AR6000_XIOCTL_DIAG_READ 55
614
615#define AR6000_XIOCTL_DIAG_WRITE 56
616
617/*
618 * arguments cmd (AR6000_XIOCTL_SET_TXOP)
619 * WMI_TXOP_CFG txopEnable
620 */
621#define AR6000_XIOCTL_WMI_SET_TXOP 57
622
623/*
624 * arguments:
625 * UINT32 cmd (AR6000_XIOCTL_USER_SETKEYS)
626 * UINT32 keyOpCtrl
627 * uses struct ar6000_user_setkeys_info
628 */
629#define AR6000_XIOCTL_USER_SETKEYS 58
630
631#define AR6000_XIOCTL_WMI_SET_KEEPALIVE 59
632/*
633 * arguments:
634 * UINT8 cmd (AR6000_XIOCTL_WMI_SET_KEEPALIVE)
635 * UINT8 keepaliveInterval
636 * uses: WMI_SET_KEEPALIVE_CMDID
637 */
638
639#define AR6000_XIOCTL_WMI_GET_KEEPALIVE 60
640/*
641 * arguments:
642 * UINT8 cmd (AR6000_XIOCTL_WMI_GET_KEEPALIVE)
643 * UINT8 keepaliveInterval
644 * u32 configured
645 * uses: WMI_GET_KEEPALIVE_CMDID
646 */
647
648/* ====ROM Patching Extended Ioctls==== */
649
650#define AR6000_XIOCTL_BMI_ROMPATCH_INSTALL 61
651/*
652 * arguments:
653 * union {
654 * struct {
655 * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_INSTALL)
656 * UINT32 ROM Address
657 * UINT32 RAM Address
658 * UINT32 number of bytes
659 * UINT32 activate? (0 or 1)
660 * }
661 * u32 resulting rompatch ID
662 * }
663 * uses: BMI_ROMPATCH_INSTALL
664 */
665
666#define AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL 62
667/*
668 * arguments:
669 * struct {
670 * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL)
671 * UINT32 rompatch ID
672 * }
673 * uses: BMI_ROMPATCH_UNINSTALL
674 */
675
676#define AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE 63
677/*
678 * arguments:
679 * struct {
680 * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE)
681 * UINT32 rompatch count
682 * UINT32 rompatch IDs[rompatch count]
683 * }
684 * uses: BMI_ROMPATCH_ACTIVATE
685 */
686
687#define AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE 64
688/*
689 * arguments:
690 * struct {
691 * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE)
692 * UINT32 rompatch count
693 * UINT32 rompatch IDs[rompatch count]
694 * }
695 * uses: BMI_ROMPATCH_DEACTIVATE
696 */
697
698#define AR6000_XIOCTL_WMI_SET_APPIE 65
699/*
700 * arguments:
701 * struct {
702 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_APPIE)
703 * UINT32 app_frmtype;
704 * UINT32 app_buflen;
705 * UINT8 app_buf[];
706 * }
707 */
708#define AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER 66
709/*
710 * arguments:
711 * u32 filter_type;
712 */
713
714#define AR6000_XIOCTL_DBGLOG_CFG_MODULE 67
715
716#define AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS 68
717
718#define AR6000_XIOCTL_WMI_SET_WSC_STATUS 70
719/*
720 * arguments:
721 * u32 wsc_status;
722 * (WSC_REG_INACTIVE or WSC_REG_ACTIVE)
723 */
724
725/*
726 * arguments:
727 * struct {
728 * u8 streamType;
729 * u8 status;
730 * }
731 * uses: WMI_SET_BT_STATUS_CMDID
732 */
733#define AR6000_XIOCTL_WMI_SET_BT_STATUS 71
734
735/*
736 * arguments:
737 * struct {
738 * u8 paramType;
739 * union {
740 * u8 noSCOPkts;
741 * BT_PARAMS_A2DP a2dpParams;
742 * BT_COEX_REGS regs;
743 * };
744 * }
745 * uses: WMI_SET_BT_PARAM_CMDID
746 */
747#define AR6000_XIOCTL_WMI_SET_BT_PARAMS 72
748
749#define AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE 73
750#define AR6000_XIOCTL_WMI_SET_WOW_MODE 74
751#define AR6000_XIOCTL_WMI_GET_WOW_LIST 75
752#define AR6000_XIOCTL_WMI_ADD_WOW_PATTERN 76
753#define AR6000_XIOCTL_WMI_DEL_WOW_PATTERN 77
754
755
756
757#define AR6000_XIOCTL_TARGET_INFO 78
758/*
759 * arguments:
760 * UINT32 cmd (AR6000_XIOCTL_TARGET_INFO)
761 * u32 TargetVersion (returned)
762 * u32 TargetType (returned)
763 * (See also bmi_msg.h target_ver and target_type)
764 */
765
766#define AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE 79
767/*
768 * arguments:
769 * none
770 */
771
772#define AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE 80
773/*
774 * This ioctl is used to emulate traffic activity
775 * timeouts. Activity/inactivity will trigger the driver
776 * to re-balance credits.
777 *
778 * arguments:
779 * ar6000_traffic_activity_change
780 */
781
782#define AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS 81
783/*
784 * This ioctl is used to set the connect control flags
785 *
786 * arguments:
787 * u32 connectCtrlFlags
788 */
789
790#define AR6000_XIOCTL_WMI_SET_AKMP_PARAMS 82
791/*
792 * This IOCTL sets any Authentication,Key Management and Protection
793 * related parameters. This is used along with the information set in
794 * Connect Command.
795 * Currently this enables Multiple PMKIDs to an AP.
796 *
797 * arguments:
798 * struct {
799 * u32 akmpInfo;
800 * }
801 * uses: WMI_SET_AKMP_PARAMS_CMD
802 */
803
804#define AR6000_XIOCTL_WMI_GET_PMKID_LIST 83
805
806#define AR6000_XIOCTL_WMI_SET_PMKID_LIST 84
807/*
808 * This IOCTL is used to set a list of PMKIDs. This list of
809 * PMKIDs is used in the [Re]AssocReq Frame. This list is used
810 * only if the MultiPMKID option is enabled via the
811 * AR6000_XIOCTL_WMI_SET_AKMP_PARAMS IOCTL.
812 *
813 * arguments:
814 * struct {
815 * u32 numPMKID;
816 * WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE];
817 * }
818 * uses: WMI_SET_PMKIDLIST_CMD
819 */
820
821#define AR6000_XIOCTL_WMI_SET_PARAMS 85
822#define AR6000_XIOCTL_WMI_SET_MCAST_FILTER 86
823#define AR6000_XIOCTL_WMI_DEL_MCAST_FILTER 87
824
825
826/* Historical DSETPATCH support for INI patches */
827#define AR6000_XIOCTL_UNUSED90 90
828
829
830/* Support LZ-compressed firmware download */
831#define AR6000_XIOCTL_BMI_LZ_STREAM_START 91
832/*
833 * arguments:
834 * UINT32 cmd (AR6000_XIOCTL_BMI_LZ_STREAM_START)
835 * UINT32 address
836 * uses: BMI_LZ_STREAM_START
837 */
838
839#define AR6000_XIOCTL_BMI_LZ_DATA 92
840/*
841 * arguments:
842 * UINT32 cmd (AR6000_XIOCTL_BMI_LZ_DATA)
843 * UINT32 length
844 * char data[length]
845 * uses: BMI_LZ_DATA
846 */
847
848#define AR6000_XIOCTL_PROF_CFG 93
849/*
850 * arguments:
851 * u32 period
852 * u32 nbins
853 */
854
855#define AR6000_XIOCTL_PROF_ADDR_SET 94
856/*
857 * arguments:
858 * u32 Target address
859 */
860
861#define AR6000_XIOCTL_PROF_START 95
862
863#define AR6000_XIOCTL_PROF_STOP 96
864
865#define AR6000_XIOCTL_PROF_COUNT_GET 97
866
867#define AR6000_XIOCTL_WMI_ABORT_SCAN 98
868
869/*
870 * AP mode
871 */
872#define AR6000_XIOCTL_AP_GET_STA_LIST 99
873
874#define AR6000_XIOCTL_AP_HIDDEN_SSID 100
875
876#define AR6000_XIOCTL_AP_SET_NUM_STA 101
877
878#define AR6000_XIOCTL_AP_SET_ACL_MAC 102
879
880#define AR6000_XIOCTL_AP_GET_ACL_LIST 103
881
882#define AR6000_XIOCTL_AP_COMMIT_CONFIG 104
883
884#define IEEE80211_IOCTL_GETWPAIE 105
885
886#define AR6000_XIOCTL_AP_CONN_INACT_TIME 106
887
888#define AR6000_XIOCTL_AP_PROT_SCAN_TIME 107
889
890#define AR6000_XIOCTL_AP_SET_COUNTRY 108
891
892#define AR6000_XIOCTL_AP_SET_DTIM 109
893
894
895
896
897#define AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT 110
898
899#define AR6000_XIOCTL_SET_IP 111
900
901#define AR6000_XIOCTL_AP_SET_ACL_POLICY 112
902
903#define AR6000_XIOCTL_AP_INTRA_BSS_COMM 113
904
905#define AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO 114
906
907#define AR6000_XIOCTL_MODULE_DEBUG_SET_MASK 115
908
909#define AR6000_XIOCTL_MODULE_DEBUG_GET_MASK 116
910
911#define AR6000_XIOCTL_DUMP_RCV_AGGR_STATS 117
912
913#define AR6000_XIOCTL_SET_HT_CAP 118
914
915#define AR6000_XIOCTL_SET_HT_OP 119
916
917#define AR6000_XIOCTL_AP_GET_STAT 120
918
919#define AR6000_XIOCTL_SET_TX_SELECT_RATES 121
920
921#define AR6000_XIOCTL_SETUP_AGGR 122
922
923#define AR6000_XIOCTL_ALLOW_AGGR 123
924
925#define AR6000_XIOCTL_AP_GET_HIDDEN_SSID 124
926
927#define AR6000_XIOCTL_AP_GET_COUNTRY 125
928
929#define AR6000_XIOCTL_AP_GET_WMODE 126
930
931#define AR6000_XIOCTL_AP_GET_DTIM 127
932
933#define AR6000_XIOCTL_AP_GET_BINTVL 128
934
935#define AR6000_XIOCTL_AP_GET_RTS 129
936
937#define AR6000_XIOCTL_DELE_AGGR 130
938
939#define AR6000_XIOCTL_FETCH_TARGET_REGS 131
940
941#define AR6000_XIOCTL_HCI_CMD 132
942
943#define AR6000_XIOCTL_ACL_DATA 133 /* used to be used for PAL */
944
945#define AR6000_XIOCTL_WLAN_CONN_PRECEDENCE 134
946
947#define AR6000_XIOCTL_AP_SET_11BG_RATESET 135
948
949/*
950 * arguments:
951 * WMI_AP_PS_CMD apPsCmd
952 * uses: WMI_AP_PS_CMDID
953 */
954
955#define AR6000_XIOCTL_WMI_SET_AP_PS 136
956
957#define AR6000_XIOCTL_WMI_MCAST_FILTER 137
958
959#define AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT 138
960
961#define AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV 139
962
963#define AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG 140
964
965#define AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG 141
966
967#define AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG 142
968
969#define AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG 143
970
971#define AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG 144
972
973#define AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS 145
974
975#define AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG 146
976
977#define AR6000_XIOCTL_WMI_GET_BTCOEX_STATS 147
978/*
979 * arguments:
980 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_QOS_SUPP)
981 * UINT8 mode
982 * uses: WMI_SET_QOS_SUPP_CMDID
983 */
984#define AR6000_XIOCTL_WMI_SET_QOS_SUPP 148
985
986#define AR6000_XIOCTL_GET_WLAN_SLEEP_STATE 149
987
988#define AR6000_XIOCTL_SET_BT_HW_POWER_STATE 150
989
990#define AR6000_XIOCTL_GET_BT_HW_POWER_STATE 151
991
992#define AR6000_XIOCTL_ADD_AP_INTERFACE 152
993
994#define AR6000_XIOCTL_REMOVE_AP_INTERFACE 153
995
996#define AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM 154
997
998#define AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES 161
999
1000/* used by AR6000_IOCTL_WMI_GETREV */
1001struct ar6000_version {
1002 u32 host_ver;
1003 u32 target_ver;
1004 u32 wlan_ver;
1005 u32 abi_ver;
1006};
1007
1008/* used by AR6000_IOCTL_WMI_GET_QOS_QUEUE */
1009struct ar6000_queuereq {
1010 u8 trafficClass;
1011 u16 activeTsids;
1012};
1013
1014/* used by AR6000_IOCTL_WMI_GET_TARGET_STATS */
1015typedef struct targetStats_t {
1016 u64 tx_packets;
1017 u64 tx_bytes;
1018 u64 tx_unicast_pkts;
1019 u64 tx_unicast_bytes;
1020 u64 tx_multicast_pkts;
1021 u64 tx_multicast_bytes;
1022 u64 tx_broadcast_pkts;
1023 u64 tx_broadcast_bytes;
1024 u64 tx_rts_success_cnt;
1025 u64 tx_packet_per_ac[4];
1026
1027 u64 tx_errors;
1028 u64 tx_failed_cnt;
1029 u64 tx_retry_cnt;
1030 u64 tx_mult_retry_cnt;
1031 u64 tx_rts_fail_cnt;
1032
1033 u64 rx_packets;
1034 u64 rx_bytes;
1035 u64 rx_unicast_pkts;
1036 u64 rx_unicast_bytes;
1037 u64 rx_multicast_pkts;
1038 u64 rx_multicast_bytes;
1039 u64 rx_broadcast_pkts;
1040 u64 rx_broadcast_bytes;
1041 u64 rx_fragment_pkt;
1042
1043 u64 rx_errors;
1044 u64 rx_crcerr;
1045 u64 rx_key_cache_miss;
1046 u64 rx_decrypt_err;
1047 u64 rx_duplicate_frames;
1048
1049 u64 tkip_local_mic_failure;
1050 u64 tkip_counter_measures_invoked;
1051 u64 tkip_replays;
1052 u64 tkip_format_errors;
1053 u64 ccmp_format_errors;
1054 u64 ccmp_replays;
1055
1056 u64 power_save_failure_cnt;
1057
1058 u64 cs_bmiss_cnt;
1059 u64 cs_lowRssi_cnt;
1060 u64 cs_connect_cnt;
1061 u64 cs_disconnect_cnt;
1062
1063 s32 tx_unicast_rate;
1064 s32 rx_unicast_rate;
1065
1066 u32 lq_val;
1067
1068 u32 wow_num_pkts_dropped;
1069 u16 wow_num_events_discarded;
1070
1071 s16 noise_floor_calibation;
1072 s16 cs_rssi;
1073 s16 cs_aveBeacon_rssi;
1074 u8 cs_aveBeacon_snr;
1075 u8 cs_lastRoam_msec;
1076 u8 cs_snr;
1077
1078 u8 wow_num_host_pkt_wakeups;
1079 u8 wow_num_host_event_wakeups;
1080
1081 u32 arp_received;
1082 u32 arp_matched;
1083 u32 arp_replied;
1084}TARGET_STATS;
1085
1086typedef struct targetStats_cmd_t {
1087 TARGET_STATS targetStats;
1088 int clearStats;
1089} TARGET_STATS_CMD;
1090
1091/* used by AR6000_XIOCTL_USER_SETKEYS */
1092
1093/*
1094 * Setting this bit to 1 doesnot initialize the RSC on the firmware
1095 */
1096#define AR6000_XIOCTL_USER_SETKEYS_RSC_CTRL 1
1097#define AR6000_USER_SETKEYS_RSC_UNCHANGED 0x00000002
1098
1099struct ar6000_user_setkeys_info {
1100 u32 keyOpCtrl; /* Bit Map of Key Mgmt Ctrl Flags */
1101}; /* XXX: unused !? */
1102
1103/* used by AR6000_XIOCTL_GPIO_OUTPUT_SET */
1104struct ar6000_gpio_output_set_cmd_s {
1105 u32 set_mask;
1106 u32 clear_mask;
1107 u32 enable_mask;
1108 u32 disable_mask;
1109};
1110
1111/*
1112 * used by AR6000_XIOCTL_GPIO_REGISTER_GET and AR6000_XIOCTL_GPIO_REGISTER_SET
1113 */
1114struct ar6000_gpio_register_cmd_s {
1115 u32 gpioreg_id;
1116 u32 value;
1117};
1118
1119/* used by AR6000_XIOCTL_GPIO_INTR_ACK */
1120struct ar6000_gpio_intr_ack_cmd_s {
1121 u32 ack_mask;
1122};
1123
1124/* used by AR6000_XIOCTL_GPIO_INTR_WAIT */
1125struct ar6000_gpio_intr_wait_cmd_s {
1126 u32 intr_mask;
1127 u32 input_values;
1128};
1129
1130/* used by the AR6000_XIOCTL_DBGLOG_CFG_MODULE */
1131typedef struct ar6000_dbglog_module_config_s {
1132 u32 valid;
1133 u16 mmask;
1134 u16 tsr;
1135 u32 rep;
1136 u16 size;
1137} DBGLOG_MODULE_CONFIG;
1138
1139typedef struct user_rssi_thold_t {
1140 s16 tag;
1141 s16 rssi;
1142} USER_RSSI_THOLD;
1143
1144typedef struct user_rssi_params_t {
1145 u8 weight;
1146 u32 pollTime;
1147 USER_RSSI_THOLD tholds[12];
1148} USER_RSSI_PARAMS;
1149
1150typedef struct ar6000_get_btcoex_config_cmd_t{
1151 u32 btProfileType;
1152 u32 linkId;
1153 }AR6000_GET_BTCOEX_CONFIG_CMD;
1154
1155typedef struct ar6000_btcoex_config_t {
1156 AR6000_GET_BTCOEX_CONFIG_CMD configCmd;
1157 u32 *configEvent;
1158} AR6000_BTCOEX_CONFIG;
1159
1160typedef struct ar6000_btcoex_stats_t {
1161 u32 *statsEvent;
1162 }AR6000_BTCOEX_STATS;
1163/*
1164 * Host driver may have some config parameters. Typically, these
1165 * config params are one time config parameters. These could
1166 * correspond to any of the underlying modules. Host driver exposes
1167 * an api for the underlying modules to get this config.
1168 */
1169#define AR6000_DRIVER_CFG_BASE 0x8000
1170
1171/* Should driver perform wlan node caching? */
1172#define AR6000_DRIVER_CFG_GET_WLANNODECACHING 0x8001
1173/*Should we log raw WMI msgs */
1174#define AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS 0x8002
1175
1176/* used by AR6000_XIOCTL_DIAG_READ & AR6000_XIOCTL_DIAG_WRITE */
1177struct ar6000_diag_window_cmd_s {
1178 unsigned int addr;
1179 unsigned int value;
1180};
1181
1182
1183struct ar6000_traffic_activity_change {
1184 u32 StreamID; /* stream ID to indicate activity change */
1185 u32 Active; /* active (1) or inactive (0) */
1186};
1187
1188/* Used with AR6000_XIOCTL_PROF_COUNT_GET */
1189struct prof_count_s {
1190 u32 addr; /* bin start address */
1191 u32 count; /* hit count */
1192};
1193
1194
1195/* used by AR6000_XIOCTL_MODULE_DEBUG_SET_MASK */
1196/* AR6000_XIOCTL_MODULE_DEBUG_GET_MASK */
1197/* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO */
1198struct drv_debug_module_s {
1199 char modulename[128]; /* name of module */
1200 u32 mask; /* new mask to set .. or .. current mask */
1201};
1202
1203
1204/* All HCI related rx events are sent up to the host app
1205 * via a wmi event id. It can contain ACL data or HCI event,
1206 * based on which it will be de-multiplexed.
1207 */
1208typedef enum {
1209 PAL_HCI_EVENT = 0,
1210 PAL_HCI_RX_DATA,
1211} WMI_PAL_EVENT_INFO;
1212
1213
1214#ifdef __cplusplus
1215}
1216#endif
1217#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h
deleted file mode 100644
index d5253207b19..00000000000
--- a/drivers/staging/ath6kl/os/linux/include/cfg80211.h
+++ /dev/null
@@ -1,61 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _AR6K_CFG80211_H_
25#define _AR6K_CFG80211_H_
26
27struct wireless_dev *ar6k_cfg80211_init(struct device *dev);
28void ar6k_cfg80211_deinit(struct ar6_softc *ar);
29
30void ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status);
31
32void ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel,
33 u8 *bssid, u16 listenInterval,
34 u16 beaconInterval,NETWORK_TYPE networkType,
35 u8 beaconIeLen, u8 assocReqLen,
36 u8 assocRespLen, u8 *assocInfo);
37
38void ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
39 u8 *bssid, u8 assocRespLen,
40 u8 *assocInfo, u16 protocolReasonStatus);
41
42void ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast);
43
44#ifdef CONFIG_NL80211_TESTMODE
45void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf,
46 int buf_len);
47#else
48static inline void ar6000_testmode_rx_report_event(struct ar6_softc *ar,
49 void *buf, int buf_len)
50{
51}
52#endif
53
54
55#endif /* _AR6K_CFG80211_H_ */
56
57
58
59
60
61
diff --git a/drivers/staging/ath6kl/os/linux/include/config_linux.h b/drivers/staging/ath6kl/os/linux/include/config_linux.h
deleted file mode 100644
index dbbe1a00b92..00000000000
--- a/drivers/staging/ath6kl/os/linux/include/config_linux.h
+++ /dev/null
@@ -1,51 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _CONFIG_LINUX_H_
25#define _CONFIG_LINUX_H_
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/*
32 * Host side Test Command support
33 */
34#define CONFIG_HOST_TCMD_SUPPORT
35
36#define USE_4BYTE_REGISTER_ACCESS
37
38/* Host-side support for Target-side profiling */
39#undef CONFIG_TARGET_PROFILE_SUPPORT
40
41/* IP/TCP checksum offload */
42/* Checksum offload is currently not supported for 64 bit platforms */
43#ifndef __LP64__
44#define CONFIG_CHECKSUM_OFFLOAD
45#endif /* __LP64__ */
46
47#ifdef __cplusplus
48}
49#endif
50
51#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/debug_linux.h b/drivers/staging/ath6kl/os/linux/include/debug_linux.h
deleted file mode 100644
index b8dba52badc..00000000000
--- a/drivers/staging/ath6kl/os/linux/include/debug_linux.h
+++ /dev/null
@@ -1,50 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _DEBUG_LINUX_H_
25#define _DEBUG_LINUX_H_
26
27 /* macro to remove parens */
28#define ATH_PRINTX_ARG(arg...) arg
29
30#ifdef DEBUG
31 /* NOTE: the AR_DEBUG_PRINTF macro is defined here to handle special handling of variable arg macros
32 * which may be compiler dependent. */
33#define AR_DEBUG_PRINTF(mask, args) do { \
34 if (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (mask)) { \
35 A_LOGGER(mask, ATH_MODULE_NAME, ATH_PRINTX_ARG args); \
36 } \
37} while (0)
38#else
39 /* on non-debug builds, keep in error and warning messages in the driver, all other
40 * message tracing will get compiled out */
41#define AR_DEBUG_PRINTF(mask, args) \
42 if ((mask) & (ATH_DEBUG_ERR | ATH_DEBUG_WARN)) { A_PRINTF(ATH_PRINTX_ARG args); }
43
44#endif
45
46 /* compile specific macro to get the function name string */
47#define _A_FUNCNAME_ __func__
48
49
50#endif /* _DEBUG_LINUX_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h
deleted file mode 100644
index 74f98618334..00000000000
--- a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h
+++ /dev/null
@@ -1,76 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// HCI bridge implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25#include "hci_transport_api.h"
26#include "common_drv.h"
27
28extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo);
29extern void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans);
30extern int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue);
31extern int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous);
32extern void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans);
33extern int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans);
34extern int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
35extern int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans,
36 struct htc_packet *pPacket,
37 int MaxPollMS);
38extern int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud);
39extern int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
40
41
42#define HCI_TransportAttach(HTCHandle, pInfo) \
43 _HCI_TransportAttach((HTCHandle), (pInfo))
44#define HCI_TransportDetach(HciTrans) \
45 _HCI_TransportDetach(HciTrans)
46#define HCI_TransportAddReceivePkts(HciTrans, pQueue) \
47 _HCI_TransportAddReceivePkts((HciTrans), (pQueue))
48#define HCI_TransportSendPkt(HciTrans, pPacket, Synchronous) \
49 _HCI_TransportSendPkt((HciTrans), (pPacket), (Synchronous))
50#define HCI_TransportStop(HciTrans) \
51 _HCI_TransportStop((HciTrans))
52#define HCI_TransportStart(HciTrans) \
53 _HCI_TransportStart((HciTrans))
54#define HCI_TransportEnableDisableAsyncRecv(HciTrans, Enable) \
55 _HCI_TransportEnableDisableAsyncRecv((HciTrans), (Enable))
56#define HCI_TransportRecvHCIEventSync(HciTrans, pPacket, MaxPollMS) \
57 _HCI_TransportRecvHCIEventSync((HciTrans), (pPacket), (MaxPollMS))
58#define HCI_TransportSetBaudRate(HciTrans, Baud) \
59 _HCI_TransportSetBaudRate((HciTrans), (Baud))
60#define HCI_TransportEnablePowerMgmt(HciTrans, Enable) \
61 _HCI_TransportEnablePowerMgmt((HciTrans), (Enable))
62
63
64extern int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks);
65
66extern int ar6000_get_hif_dev(struct hif_device *device, void *config);
67
68extern int ar6000_set_uart_config(struct hif_device *hifDevice, u32 scale, u32 step);
69
70/* get core clock register settings
71 * data: 0 - 40/44MHz
72 * 1 - 80/88MHz
73 * where (5G band/2.4G band)
74 * assume 2.4G band for now
75 */
76extern int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data);
diff --git a/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h b/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h
deleted file mode 100644
index e6e96de3fc6..00000000000
--- a/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h
+++ /dev/null
@@ -1,177 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _IEEE80211_IOCTL_H_
25#define _IEEE80211_IOCTL_H_
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/*
32 * Extracted from the MADWIFI net80211/ieee80211_ioctl.h
33 */
34
35/*
36 * WPA/RSN get/set key request. Specify the key/cipher
37 * type and whether the key is to be used for sending and/or
38 * receiving. The key index should be set only when working
39 * with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
40 * Otherwise a unicast/pairwise key is specified by the bssid
41 * (on a station) or mac address (on an ap). They key length
42 * must include any MIC key data; otherwise it should be no
43 more than IEEE80211_KEYBUF_SIZE.
44 */
45struct ieee80211req_key {
46 u_int8_t ik_type; /* key/cipher type */
47 u_int8_t ik_pad;
48 u_int16_t ik_keyix; /* key index */
49 u_int8_t ik_keylen; /* key length in bytes */
50 u_int8_t ik_flags;
51#define IEEE80211_KEY_XMIT 0x01
52#define IEEE80211_KEY_RECV 0x02
53#define IEEE80211_KEY_DEFAULT 0x80 /* default xmit key */
54 u_int8_t ik_macaddr[IEEE80211_ADDR_LEN];
55 u_int64_t ik_keyrsc; /* key receive sequence counter */
56 u_int64_t ik_keytsc; /* key transmit sequence counter */
57 u_int8_t ik_keydata[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
58};
59/*
60 * Delete a key either by index or address. Set the index
61 * to IEEE80211_KEYIX_NONE when deleting a unicast key.
62 */
63struct ieee80211req_del_key {
64 u_int8_t idk_keyix; /* key index */
65 u_int8_t idk_macaddr[IEEE80211_ADDR_LEN];
66};
67/*
68 * MLME state manipulation request. IEEE80211_MLME_ASSOC
69 * only makes sense when operating as a station. The other
70 * requests can be used when operating as a station or an
71 * ap (to effect a station).
72 */
73struct ieee80211req_mlme {
74 u_int8_t im_op; /* operation to perform */
75#define IEEE80211_MLME_ASSOC 1 /* associate station */
76#define IEEE80211_MLME_DISASSOC 2 /* disassociate station */
77#define IEEE80211_MLME_DEAUTH 3 /* deauthenticate station */
78#define IEEE80211_MLME_AUTHORIZE 4 /* authorize station */
79#define IEEE80211_MLME_UNAUTHORIZE 5 /* unauthorize station */
80 u_int16_t im_reason; /* 802.11 reason code */
81 u_int8_t im_macaddr[IEEE80211_ADDR_LEN];
82};
83
84struct ieee80211req_addpmkid {
85 u_int8_t pi_bssid[IEEE80211_ADDR_LEN];
86 u_int8_t pi_enable;
87 u_int8_t pi_pmkid[16];
88};
89
90#define AUTH_ALG_OPEN_SYSTEM 0x01
91#define AUTH_ALG_SHARED_KEY 0x02
92#define AUTH_ALG_LEAP 0x04
93
94struct ieee80211req_authalg {
95 u_int8_t auth_alg;
96};
97
98/*
99 * Request to add an IE to a Management Frame
100 */
101enum{
102 IEEE80211_APPIE_FRAME_BEACON = 0,
103 IEEE80211_APPIE_FRAME_PROBE_REQ = 1,
104 IEEE80211_APPIE_FRAME_PROBE_RESP = 2,
105 IEEE80211_APPIE_FRAME_ASSOC_REQ = 3,
106 IEEE80211_APPIE_FRAME_ASSOC_RESP = 4,
107 IEEE80211_APPIE_NUM_OF_FRAME = 5
108};
109
110/*
111 * The Maximum length of the IE that can be added to a Management frame
112 */
113#define IEEE80211_APPIE_FRAME_MAX_LEN 200
114
115struct ieee80211req_getset_appiebuf {
116 u_int32_t app_frmtype; /* management frame type for which buffer is added */
117 u_int32_t app_buflen; /*application supplied buffer length */
118 u_int8_t app_buf[];
119};
120
121/*
122 * The following definitions are used by an application to set filter
123 * for receiving management frames
124 */
125enum {
126 IEEE80211_FILTER_TYPE_BEACON = 0x1,
127 IEEE80211_FILTER_TYPE_PROBE_REQ = 0x2,
128 IEEE80211_FILTER_TYPE_PROBE_RESP = 0x4,
129 IEEE80211_FILTER_TYPE_ASSOC_REQ = 0x8,
130 IEEE80211_FILTER_TYPE_ASSOC_RESP = 0x10,
131 IEEE80211_FILTER_TYPE_AUTH = 0x20,
132 IEEE80211_FILTER_TYPE_DEAUTH = 0x40,
133 IEEE80211_FILTER_TYPE_DISASSOC = 0x80,
134 IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */
135};
136
137struct ieee80211req_set_filter {
138 u_int32_t app_filterype; /* management frame filter type */
139};
140
141enum {
142 IEEE80211_PARAM_AUTHMODE = 3, /* Authentication Mode */
143 IEEE80211_PARAM_MCASTCIPHER = 5,
144 IEEE80211_PARAM_MCASTKEYLEN = 6, /* multicast key length */
145 IEEE80211_PARAM_UCASTCIPHER = 8,
146 IEEE80211_PARAM_UCASTKEYLEN = 9, /* unicast key length */
147 IEEE80211_PARAM_WPA = 10, /* WPA mode (0,1,2) */
148 IEEE80211_PARAM_ROAMING = 12, /* roaming mode */
149 IEEE80211_PARAM_PRIVACY = 13, /* privacy invoked */
150 IEEE80211_PARAM_COUNTERMEASURES = 14, /* WPA/TKIP countermeasures */
151 IEEE80211_PARAM_DROPUNENCRYPTED = 15, /* discard unencrypted frames */
152 IEEE80211_PARAM_WAPI = 16, /* WAPI policy from wapid */
153};
154
155/*
156 * Values for IEEE80211_PARAM_WPA
157 */
158#define WPA_MODE_WPA1 1
159#define WPA_MODE_WPA2 2
160#define WPA_MODE_AUTO 3
161#define WPA_MODE_NONE 4
162
163struct ieee80211req_wpaie {
164 u_int8_t wpa_macaddr[IEEE80211_ADDR_LEN];
165 u_int8_t wpa_ie[IEEE80211_MAX_IE];
166 u_int8_t rsn_ie[IEEE80211_MAX_IE];
167};
168
169#ifndef IW_ENCODE_ALG_PMK
170#define IW_ENCODE_ALG_PMK 4
171#endif
172
173#ifdef __cplusplus
174}
175#endif
176
177#endif /* _IEEE80211_IOCTL_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h
deleted file mode 100644
index 41f43730772..00000000000
--- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h
+++ /dev/null
@@ -1,339 +0,0 @@
1//------------------------------------------------------------------------------
2// This file contains the definitions of the basic atheros data types.
3// It is used to map the data types in atheros files to a platform specific
4// type.
5// Copyright (c) 2004-2010 Atheros Communications Inc.
6// All rights reserved.
7//
8//
9//
10// Permission to use, copy, modify, and/or distribute this software for any
11// purpose with or without fee is hereby granted, provided that the above
12// copyright notice and this permission notice appear in all copies.
13//
14// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21//
22//
23//
24// Author(s): ="Atheros"
25//------------------------------------------------------------------------------
26
27#ifndef _OSAPI_LINUX_H_
28#define _OSAPI_LINUX_H_
29
30#ifdef __KERNEL__
31
32#include <linux/types.h>
33#include <linux/kernel.h>
34#include <linux/string.h>
35#include <linux/skbuff.h>
36#include <linux/netdevice.h>
37#include <linux/jiffies.h>
38#include <linux/timer.h>
39#include <linux/delay.h>
40#include <linux/wait.h>
41#include <linux/semaphore.h>
42#include <linux/cache.h>
43
44#ifdef __GNUC__
45#define __ATTRIB_PACK __attribute__ ((packed))
46#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2)))
47#define __ATTRIB_NORETURN __attribute__ ((noreturn))
48#ifndef INLINE
49#define INLINE __inline__
50#endif
51#else /* Not GCC */
52#define __ATTRIB_PACK
53#define __ATTRIB_PRINTF
54#define __ATTRIB_NORETURN
55#ifndef INLINE
56#define INLINE __inline
57#endif
58#endif /* End __GNUC__ */
59
60#define PREPACK
61#define POSTPACK __ATTRIB_PACK
62
63/*
64 * Endianes macros
65 */
66#define A_BE2CPU8(x) ntohb(x)
67#define A_BE2CPU16(x) ntohs(x)
68#define A_BE2CPU32(x) ntohl(x)
69
70#define A_LE2CPU8(x) (x)
71#define A_LE2CPU16(x) (x)
72#define A_LE2CPU32(x) (x)
73
74#define A_CPU2BE8(x) htonb(x)
75#define A_CPU2BE16(x) htons(x)
76#define A_CPU2BE32(x) htonl(x)
77
78#define A_MEMZERO(addr, len) memset(addr, 0, len)
79#define A_MALLOC(size) kmalloc((size), GFP_KERNEL)
80#define A_MALLOC_NOWAIT(size) kmalloc((size), GFP_ATOMIC)
81
82#define A_LOGGER(mask, mod, args...) printk(KERN_ALERT args)
83#define A_PRINTF(args...) printk(KERN_ALERT args)
84
85#define A_PRINTF_LOG(args...) printk(args)
86#define A_SPRINTF(buf, args...) sprintf (buf, args)
87
88/* Mutual Exclusion */
89typedef spinlock_t A_MUTEX_T;
90#define A_MUTEX_INIT(mutex) spin_lock_init(mutex)
91#define A_MUTEX_LOCK(mutex) spin_lock_bh(mutex)
92#define A_MUTEX_UNLOCK(mutex) spin_unlock_bh(mutex)
93#define A_IS_MUTEX_VALID(mutex) true /* okay to return true, since A_MUTEX_DELETE does nothing */
94#define A_MUTEX_DELETE(mutex) /* spin locks are not kernel resources so nothing to free.. */
95
96/* Get current time in ms adding a constant offset (in ms) */
97#define A_GET_MS(offset) \
98 (((jiffies / HZ) * 1000) + (offset))
99
100/*
101 * Timer Functions
102 */
103#define A_MDELAY(msecs) mdelay(msecs)
104typedef struct timer_list A_TIMER;
105
106#define A_INIT_TIMER(pTimer, pFunction, pArg) do { \
107 init_timer(pTimer); \
108 (pTimer)->function = (pFunction); \
109 (pTimer)->data = (unsigned long)(pArg); \
110} while (0)
111
112/*
113 * Start a Timer that elapses after 'periodMSec' milli-seconds
114 * Support is provided for a one-shot timer. The 'repeatFlag' is
115 * ignored.
116 */
117#define A_TIMEOUT_MS(pTimer, periodMSec, repeatFlag) do { \
118 if (repeatFlag) { \
119 printk("\n" __FILE__ ":%d: Timer Repeat requested\n",__LINE__); \
120 panic("Timer Repeat"); \
121 } \
122 mod_timer((pTimer), jiffies + HZ * (periodMSec) / 1000); \
123} while (0)
124
125/*
126 * Cancel the Timer.
127 */
128#define A_UNTIMEOUT(pTimer) do { \
129 del_timer((pTimer)); \
130} while (0)
131
132#define A_DELETE_TIMER(pTimer) do { \
133} while (0)
134
135/*
136 * Wait Queue related functions
137 */
138typedef wait_queue_head_t A_WAITQUEUE_HEAD;
139#define A_INIT_WAITQUEUE_HEAD(head) init_waitqueue_head(head)
140#ifndef wait_event_interruptible_timeout
141#define __wait_event_interruptible_timeout(wq, condition, ret) \
142do { \
143 wait_queue_t __wait; \
144 init_waitqueue_entry(&__wait, current); \
145 \
146 add_wait_queue(&wq, &__wait); \
147 for (;;) { \
148 set_current_state(TASK_INTERRUPTIBLE); \
149 if (condition) \
150 break; \
151 if (!signal_pending(current)) { \
152 ret = schedule_timeout(ret); \
153 if (!ret) \
154 break; \
155 continue; \
156 } \
157 ret = -ERESTARTSYS; \
158 break; \
159 } \
160 current->state = TASK_RUNNING; \
161 remove_wait_queue(&wq, &__wait); \
162} while (0)
163
164#define wait_event_interruptible_timeout(wq, condition, timeout) \
165({ \
166 long __ret = timeout; \
167 if (!(condition)) \
168 __wait_event_interruptible_timeout(wq, condition, __ret); \
169 __ret; \
170})
171#endif /* wait_event_interruptible_timeout */
172
173#define A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(head, condition, timeout) do { \
174 wait_event_interruptible_timeout(head, condition, timeout); \
175} while (0)
176
177#define A_WAKE_UP(head) wake_up(head)
178
179#ifdef DEBUG
180extern unsigned int panic_on_assert;
181#define A_ASSERT(expr) \
182 if (!(expr)) { \
183 printk(KERN_ALERT"Debug Assert Caught, File %s, Line: %d, Test:%s \n",__FILE__, __LINE__,#expr); \
184 if (panic_on_assert) panic(#expr); \
185 }
186#else
187#define A_ASSERT(expr)
188#endif /* DEBUG */
189
190#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) request_firmware(_ppf, _pfile, _dev)
191#define A_RELEASE_FIRMWARE(_pf) release_firmware(_pf)
192
193/*
194 * Initialization of the network buffer subsystem
195 */
196#define A_NETBUF_INIT()
197
198/*
199 * Network buffer queue support
200 */
201typedef struct sk_buff_head A_NETBUF_QUEUE_T;
202
203#define A_NETBUF_QUEUE_INIT(q) \
204 a_netbuf_queue_init(q)
205
206#define A_NETBUF_ENQUEUE(q, pkt) \
207 a_netbuf_enqueue((q), (pkt))
208#define A_NETBUF_PREQUEUE(q, pkt) \
209 a_netbuf_prequeue((q), (pkt))
210#define A_NETBUF_DEQUEUE(q) \
211 (a_netbuf_dequeue(q))
212#define A_NETBUF_QUEUE_SIZE(q) \
213 a_netbuf_queue_size(q)
214#define A_NETBUF_QUEUE_EMPTY(q) \
215 (a_netbuf_queue_empty(q) ? true : false)
216
217/*
218 * Network buffer support
219 */
220#define A_NETBUF_ALLOC(size) \
221 a_netbuf_alloc(size)
222#define A_NETBUF_ALLOC_RAW(size) \
223 a_netbuf_alloc_raw(size)
224#define A_NETBUF_FREE(bufPtr) \
225 a_netbuf_free(bufPtr)
226#define A_NETBUF_DATA(bufPtr) \
227 a_netbuf_to_data(bufPtr)
228#define A_NETBUF_LEN(bufPtr) \
229 a_netbuf_to_len(bufPtr)
230#define A_NETBUF_PUSH(bufPtr, len) \
231 a_netbuf_push(bufPtr, len)
232#define A_NETBUF_PUT(bufPtr, len) \
233 a_netbuf_put(bufPtr, len)
234#define A_NETBUF_TRIM(bufPtr,len) \
235 a_netbuf_trim(bufPtr, len)
236#define A_NETBUF_PULL(bufPtr, len) \
237 a_netbuf_pull(bufPtr, len)
238#define A_NETBUF_HEADROOM(bufPtr)\
239 a_netbuf_headroom(bufPtr)
240#define A_NETBUF_SETLEN(bufPtr,len) \
241 a_netbuf_setlen(bufPtr, len)
242
243/* Add data to end of a buffer */
244#define A_NETBUF_PUT_DATA(bufPtr, srcPtr, len) \
245 a_netbuf_put_data(bufPtr, srcPtr, len)
246
247/* Add data to start of the buffer */
248#define A_NETBUF_PUSH_DATA(bufPtr, srcPtr, len) \
249 a_netbuf_push_data(bufPtr, srcPtr, len)
250
251/* Remove data at start of the buffer */
252#define A_NETBUF_PULL_DATA(bufPtr, dstPtr, len) \
253 a_netbuf_pull_data(bufPtr, dstPtr, len)
254
255/* Remove data from the end of the buffer */
256#define A_NETBUF_TRIM_DATA(bufPtr, dstPtr, len) \
257 a_netbuf_trim_data(bufPtr, dstPtr, len)
258
259/* View data as "size" contiguous bytes of type "t" */
260#define A_NETBUF_VIEW_DATA(bufPtr, t, size) \
261 (t )( ((struct skbuf *)(bufPtr))->data)
262
263/* return the beginning of the headroom for the buffer */
264#define A_NETBUF_HEAD(bufPtr) \
265 ((((struct sk_buff *)(bufPtr))->head))
266
267/*
268 * OS specific network buffer access routines
269 */
270void *a_netbuf_alloc(int size);
271void *a_netbuf_alloc_raw(int size);
272void a_netbuf_free(void *bufPtr);
273void *a_netbuf_to_data(void *bufPtr);
274u32 a_netbuf_to_len(void *bufPtr);
275int a_netbuf_push(void *bufPtr, s32 len);
276int a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len);
277int a_netbuf_put(void *bufPtr, s32 len);
278int a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len);
279int a_netbuf_pull(void *bufPtr, s32 len);
280int a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len);
281int a_netbuf_trim(void *bufPtr, s32 len);
282int a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len);
283int a_netbuf_setlen(void *bufPtr, s32 len);
284s32 a_netbuf_headroom(void *bufPtr);
285void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt);
286void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt);
287void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q);
288int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q);
289int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q);
290int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q);
291void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q);
292
293/*
294 * Kernel v.s User space functions
295 */
296u32 a_copy_to_user(void *to, const void *from, u32 n);
297u32 a_copy_from_user(void *to, const void *from, u32 n);
298
299/* In linux, WLAN Rx and Tx run in different contexts, so no need to check
300 * for any commands/data queued for WLAN */
301#define A_CHECK_DRV_TX()
302
303#define A_GET_CACHE_LINE_BYTES() L1_CACHE_BYTES
304
305#define A_CACHE_LINE_PAD 128
306
307static inline void *A_ALIGN_TO_CACHE_LINE(void *ptr) {
308 return (void *)L1_CACHE_ALIGN((unsigned long)ptr);
309}
310
311#else /* __KERNEL__ */
312
313#ifdef __GNUC__
314#define __ATTRIB_PACK __attribute__ ((packed))
315#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2)))
316#define __ATTRIB_NORETURN __attribute__ ((noreturn))
317#ifndef INLINE
318#define INLINE __inline__
319#endif
320#else /* Not GCC */
321#define __ATTRIB_PACK
322#define __ATTRIB_PRINTF
323#define __ATTRIB_NORETURN
324#ifndef INLINE
325#define INLINE __inline
326#endif
327#endif /* End __GNUC__ */
328
329#define PREPACK
330#define POSTPACK __ATTRIB_PACK
331
332#define A_MEMZERO(addr, len) memset((addr), 0, (len))
333#define A_MALLOC(size) malloc(size)
334
335#include <err.h>
336
337#endif /* __KERNEL__ */
338
339#endif /* _OSAPI_LINUX_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/wlan_config.h b/drivers/staging/ath6kl/os/linux/include/wlan_config.h
deleted file mode 100644
index c1fe0c6e4fa..00000000000
--- a/drivers/staging/ath6kl/os/linux/include/wlan_config.h
+++ /dev/null
@@ -1,108 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// This file contains the tunable configuration items for the WLAN module
21//
22// Author(s): ="Atheros"
23//==============================================================================
24#ifndef _HOST_WLAN_CONFIG_H_
25#define _HOST_WLAN_CONFIG_H_
26
27/* Include definitions here that can be used to tune the WLAN module behavior.
28 * Different customers can tune the behavior as per their needs, here.
29 */
30
31/* This configuration item when defined will consider the barker preamble
32 * mentioned in the ERP IE of the beacons from the AP to determine the short
33 * preamble support sent in the (Re)Assoc request frames.
34 */
35#define WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP 0
36
37/* This config item when defined will not send the power module state transition
38 * failure events that happen during scan, to the host.
39 */
40#define WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN 0
41
42/*
43 * This configuration item enable/disable keepalive support.
44 * Keepalive support: In the absence of any data traffic to AP, null
45 * frames will be sent to the AP at periodic interval, to keep the association
46 * active. This configuration item defines the periodic interval.
47 * Use value of zero to disable keepalive support
48 * Default: 60 seconds
49 */
50#define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60
51
52/*
53 * This configuration item sets the value of disconnect timeout
54 * Firmware delays sending the disconnec event to the host for this
55 * timeout after is gets disconnected from the current AP.
56 * If the firmware successly roams within the disconnect timeout
57 * it sends a new connect event
58 */
59#define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
60
61/*
62 * This configuration item disables 11n support.
63 * 0 - Enable
64 * 1 - Disable
65 */
66#define WLAN_CONFIG_DISABLE_11N 0
67
68/*
69 * This configuration item enable BT clock sharing support
70 * 1 - Enable
71 * 0 - Disable (Default)
72 */
73#define WLAN_CONFIG_BT_SHARING 0
74
75/*
76 * This configuration item sets WIFI OFF policy
77 * 0 - CUT_POWER
78 * 1 - DEEP_SLEEP (Default)
79 */
80#define WLAN_CONFIG_WLAN_OFF 1
81
82/*
83 * This configuration item sets suspend policy
84 * 0 - CUT_POWER (Default)
85 * 1 - DEEP_SLEEP
86 * 2 - WoW
87 * 3 - CUT_POWER if BT OFF (clock sharing designs only)
88 */
89#define WLAN_CONFIG_PM_SUSPEND 0
90
91/*
92 * This configuration item sets suspend policy to use if PM_SUSPEND is
93 * set to WoW and device is not connected at the time of suspend
94 * 0 - CUT_POWER (Default)
95 * 1 - DEEP_SLEEP
96 * 2 - WoW
97 * 3 - CUT_POWER if BT OFF (clock sharing designs only)
98 */
99#define WLAN_CONFIG_PM_WOW2 0
100
101/*
102 * This configuration item enables/disables transmit bursting
103 * 0 - Enable tx Bursting (default)
104 * 1 - Disable tx bursting
105 */
106#define WLAN_CONFIG_DISABLE_TX_BURSTING 0
107
108#endif /* _HOST_WLAN_CONFIG_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h
deleted file mode 100644
index 1eb6f822d64..00000000000
--- a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h
+++ /dev/null
@@ -1,300 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _WMI_FILTER_LINUX_H_
25#define _WMI_FILTER_LINUX_H_
26
27/*
28 * sioctl_filter - Standard ioctl
29 * pioctl_filter - Priv ioctl
30 * xioctl_filter - eXtended ioctl
31 *
32 * ---- Possible values for the WMI filter ---------------
33 * (0) - Block this cmd always (or) not implemented
34 * (INFRA_NETWORK) - Allow this cmd only in STA mode
35 * (ADHOC_NETWORK) - Allow this cmd only in IBSS mode
36 * (AP_NETWORK) - Allow this cmd only in AP mode
37 * (INFRA_NETWORK | ADHOC_NETWORK) - Block this cmd in AP mode
38 * (ADHOC_NETWORK | AP_NETWORK) - Block this cmd in STA mode
39 * (INFRA_NETWORK | AP_NETWORK) - Block this cmd in IBSS mode
40 * (INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK)- allow only when mode is set
41 * (0xFF) - Allow this cmd always irrespective of mode
42 */
43
44u8 sioctl_filter[] = {
45(AP_NETWORK), /* SIOCSIWCOMMIT 0x8B00 */
46(0xFF), /* SIOCGIWNAME 0x8B01 */
47(0), /* SIOCSIWNWID 0x8B02 */
48(0), /* SIOCGIWNWID 0x8B03 */
49(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWFREQ 0x8B04 */
50(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWFREQ 0x8B05 */
51(0xFF), /* SIOCSIWMODE 0x8B06 */
52(0xFF), /* SIOCGIWMODE 0x8B07 */
53(0), /* SIOCSIWSENS 0x8B08 */
54(0), /* SIOCGIWSENS 0x8B09 */
55(0), /* SIOCSIWRANGE 0x8B0A */
56(0xFF), /* SIOCGIWRANGE 0x8B0B */
57(0), /* SIOCSIWPRIV 0x8B0C */
58(0), /* SIOCGIWPRIV 0x8B0D */
59(0), /* SIOCSIWSTATS 0x8B0E */
60(0), /* SIOCGIWSTATS 0x8B0F */
61(0), /* SIOCSIWSPY 0x8B10 */
62(0), /* SIOCGIWSPY 0x8B11 */
63(0), /* SIOCSIWTHRSPY 0x8B12 */
64(0), /* SIOCGIWTHRSPY 0x8B13 */
65(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWAP 0x8B14 */
66(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWAP 0x8B15 */
67#if (WIRELESS_EXT >= 18)
68(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWMLME 0X8B16 */
69#else
70(0), /* Dummy 0 */
71#endif /* WIRELESS_EXT */
72(0), /* SIOCGIWAPLIST 0x8B17 */
73(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWSCAN 0x8B18 */
74(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCGIWSCAN 0x8B19 */
75(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWESSID 0x8B1A */
76(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWESSID 0x8B1B */
77(0), /* SIOCSIWNICKN 0x8B1C */
78(0), /* SIOCGIWNICKN 0x8B1D */
79(0), /* Dummy 0 */
80(0), /* Dummy 0 */
81(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWRATE 0x8B20 */
82(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWRATE 0x8B21 */
83(0), /* SIOCSIWRTS 0x8B22 */
84(0), /* SIOCGIWRTS 0x8B23 */
85(0), /* SIOCSIWFRAG 0x8B24 */
86(0), /* SIOCGIWFRAG 0x8B25 */
87(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWTXPOW 0x8B26 */
88(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWTXPOW 0x8B27 */
89(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWRETRY 0x8B28 */
90(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCGIWRETRY 0x8B29 */
91(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWENCODE 0x8B2A */
92(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWENCODE 0x8B2B */
93(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWPOWER 0x8B2C */
94(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWPOWER 0x8B2D */
95};
96
97
98
99u8 pioctl_filter[] = {
100(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0) */
101(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+1) */
102(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+2) */
103(AP_NETWORK), /* IEEE80211_IOCTL_SETMLME (SIOCIWFIRSTPRIV+3) */
104(INFRA_NETWORK), /* IEEE80211_IOCTL_ADDPMKID (SIOCIWFIRSTPRIV+4) */
105(0), /* IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+5) */
106(0), /* (SIOCIWFIRSTPRIV+6) */
107(0), /* (SIOCIWFIRSTPRIV+7) */
108(0), /* (SIOCIWFIRSTPRIV+8) */
109(0), /* (SIOCIWFIRSTPRIV+9) */
110(0), /* IEEE80211_IOCTL_LASTONE (SIOCIWFIRSTPRIV+10) */
111(0xFF), /* AR6000_IOCTL_WMI_GETREV (SIOCIWFIRSTPRIV+11) */
112(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_IOCTL_WMI_SETPWR (SIOCIWFIRSTPRIV+12) */
113(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETSCAN (SIOCIWFIRSTPRIV+13) */
114(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETLISTENINT (SIOCIWFIRSTPRIV+14) */
115(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETBSSFILTER (SIOCIWFIRSTPRIV+15) */
116(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_IOCTL_WMI_SET_CHANNELPARAMS (SIOCIWFIRSTPRIV+16) */
117(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_PROBEDSSID (SIOCIWFIRSTPRIV+17) */
118(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_PMPARAMS (SIOCIWFIRSTPRIV+18) */
119(INFRA_NETWORK), /* AR6000_IOCTL_WMI_SET_BADAP (SIOCIWFIRSTPRIV+19) */
120(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_GET_QOS_QUEUE (SIOCIWFIRSTPRIV+20) */
121(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_CREATE_QOS (SIOCIWFIRSTPRIV+21) */
122(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_DELETE_QOS (SIOCIWFIRSTPRIV+22) */
123(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_SNRTHRESHOLD (SIOCIWFIRSTPRIV+23) */
124(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24)*/
125(0xFF), /* AR6000_IOCTL_WMI_GET_TARGET_STATS (SIOCIWFIRSTPRIV+25) */
126(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ASSOC_INFO (SIOCIWFIRSTPRIV+26) */
127(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ACCESS_PARAMS (SIOCIWFIRSTPRIV+27) */
128(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_BMISS_TIME (SIOCIWFIRSTPRIV+28) */
129(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_DISC_TIMEOUT (SIOCIWFIRSTPRIV+29) */
130(ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS (SIOCIWFIRSTPRIV+30) */
131};
132
133
134
135u8 xioctl_filter[] = {
136(0xFF), /* Dummy 0 */
137(0xFF), /* AR6000_XIOCTL_BMI_DONE 1 */
138(0xFF), /* AR6000_XIOCTL_BMI_READ_MEMORY 2 */
139(0xFF), /* AR6000_XIOCTL_BMI_WRITE_MEMORY 3 */
140(0xFF), /* AR6000_XIOCTL_BMI_EXECUTE 4 */
141(0xFF), /* AR6000_XIOCTL_BMI_SET_APP_START 5 */
142(0xFF), /* AR6000_XIOCTL_BMI_READ_SOC_REGISTER 6 */
143(0xFF), /* AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER 7 */
144(0xFF), /* AR6000_XIOCTL_BMI_TEST 8 */
145(0xFF), /* AR6000_XIOCTL_UNUSED9 9 */
146(0xFF), /* AR6000_XIOCTL_UNUSED10 10 */
147(0xFF), /* AR6000_XIOCTL_UNUSED11 11 */
148(0xFF), /* AR6000_XIOCTL_FORCE_TARGET_RESET 12 */
149(0xFF), /* AR6000_XIOCTL_HTC_RAW_OPEN 13 */
150(0xFF), /* AR6000_XIOCTL_HTC_RAW_CLOSE 14 */
151(0xFF), /* AR6000_XIOCTL_HTC_RAW_READ 15 */
152(0xFF), /* AR6000_XIOCTL_HTC_RAW_WRITE 16 */
153(0xFF), /* AR6000_XIOCTL_CHECK_TARGET_READY 17 */
154(0xFF), /* AR6000_XIOCTL_GPIO_OUTPUT_SET 18 */
155(0xFF), /* AR6000_XIOCTL_GPIO_INPUT_GET 19 */
156(0xFF), /* AR6000_XIOCTL_GPIO_REGISTER_SET 20 */
157(0xFF), /* AR6000_XIOCTL_GPIO_REGISTER_GET 21 */
158(0xFF), /* AR6000_XIOCTL_GPIO_INTR_ACK 22 */
159(0xFF), /* AR6000_XIOCTL_GPIO_INTR_WAIT 23 */
160(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_ADHOC_BSSID 24 */
161(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_OPT_MODE 25 */
162(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_OPT_SEND_FRAME 26 */
163(ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_SET_BEACON_INTVAL 27 */
164(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETAUTHALG 28 */
165(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_VOICE_PKT_SIZE 29 */
166(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_MAX_SP 30 */
167(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_ROAM_TBL 31 */
168(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_ROAM_CTRL 32 */
169(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS 33 */
170(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTRL_WMI_GET_POWER_MODE 34 */
171(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTRL_WMI_SET_WLAN_STATE 35 */
172(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_ROAM_DATA 36 */
173(0xFF), /* AR6000_XIOCTL_WMI_SETRETRYLIMITS 37 */
174(0xFF), /* AR6000_XIOCTL_TCMD_CONT_TX 38 */
175(0xFF), /* AR6000_XIOCTL_TCMD_CONT_RX 39 */
176(0xFF), /* AR6000_XIOCTL_TCMD_PM 40 */
177(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_STARTSCAN 41 */
178(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SETFIXRATES 42 */
179(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_GETFIXRATES 43 */
180(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD 44 */
181(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_CLR_RSSISNR 45 */
182(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_LQTHRESHOLD 46 */
183(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_RTS 47 */
184(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_LPREAMBLE 48 */
185(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_AUTHMODE 49 */
186(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_REASSOCMODE 50 */
187(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WMM 51 */
188(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS 52 */
189(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP 53 */
190(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_GET_RD 54 */
191(0xFF), /* AR6000_XIOCTL_DIAG_READ 55 */
192(0xFF), /* AR6000_XIOCTL_DIAG_WRITE 56 */
193(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_TXOP 57 */
194(INFRA_NETWORK), /* AR6000_XIOCTL_USER_SETKEYS 58 */
195(INFRA_NETWORK), /* AR6000_XIOCTL_WMI_SET_KEEPALIVE 59 */
196(INFRA_NETWORK), /* AR6000_XIOCTL_WMI_GET_KEEPALIVE 60 */
197(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_INSTALL 61 */
198(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL 62 */
199(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE 63 */
200(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE 64 */
201(0xFF), /* AR6000_XIOCTL_WMI_SET_APPIE 65 */
202(0xFF), /* AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER 66 */
203(0xFF), /* AR6000_XIOCTL_DBGLOG_CFG_MODULE 67 */
204(0xFF), /* AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS 68 */
205(0xFF), /* Dummy 69 */
206(0xFF), /* AR6000_XIOCTL_WMI_SET_WSC_STATUS 70 */
207(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_STATUS 71 */
208(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_PARAMS 72 */
209(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE 73 */
210(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WOW_MODE 74 */
211(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_WOW_LIST 75 */
212(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_ADD_WOW_PATTERN 76 */
213(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_DEL_WOW_PATTERN 77 */
214(0xFF), /* AR6000_XIOCTL_TARGET_INFO 78 */
215(0xFF), /* AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE 79 */
216(0xFF), /* AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE 80 */
217(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS 81 */
218(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_AKMP_PARAMS 82 */
219(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_PMKID_LIST 83 */
220(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_PMKID_LIST 84 */
221(0xFF), /* Dummy 85 */
222(0xFF), /* Dummy 86 */
223(0xFF), /* Dummy 87 */
224(0xFF), /* Dummy 88 */
225(0xFF), /* Dummy 89 */
226(0xFF), /* AR6000_XIOCTL_UNUSED90 90 */
227(0xFF), /* AR6000_XIOCTL_BMI_LZ_STREAM_START 91 */
228(0xFF), /* AR6000_XIOCTL_BMI_LZ_DATA 92 */
229(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_CFG 93 */
230(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_ADDR_SET 94 */
231(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_START 95 */
232(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_STOP 96 */
233(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_COUNT_GET 97 */
234(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_ABORT_SCAN 98 */
235(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_STA_LIST 99 */
236(AP_NETWORK), /* AR6000_XIOCTL_AP_HIDDEN_SSID 100 */
237(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_NUM_STA 101 */
238(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_ACL_MAC 102 */
239(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_ACL_LIST 103 */
240(AP_NETWORK), /* AR6000_XIOCTL_AP_COMMIT_CONFIG 104 */
241(AP_NETWORK), /* IEEE80211_IOCTL_GETWPAIE 105 */
242(AP_NETWORK), /* AR6000_XIOCTL_AP_CONN_INACT_TIME 106 */
243(AP_NETWORK), /* AR6000_XIOCTL_AP_PROT_SCAN_TIME 107 */
244(AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_COUNTRY 108 */
245(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_DTIM 109 */
246(0xFF), /* AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT 110 */
247(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_IP 111 */
248(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_ACL_POLICY 112 */
249(AP_NETWORK), /* AR6000_XIOCTL_AP_INTRA_BSS_COMM 113 */
250(0xFF), /* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO 114 */
251(0xFF), /* AR6000_XIOCTL_MODULE_DEBUG_SET_MASK 115 */
252(0xFF), /* AR6000_XIOCTL_MODULE_DEBUG_GET_MASK 116 */
253(0xFF), /* AR6000_XIOCTL_DUMP_RCV_AGGR_STATS 117 */
254(0xFF), /* AR6000_XIOCTL_SET_HT_CAP 118 */
255(0xFF), /* AR6000_XIOCTL_SET_HT_OP 119 */
256(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_STAT 120 */
257(0xFF), /* AR6000_XIOCTL_SET_TX_SELECT_RATES 121 */
258(0xFF), /* AR6000_XIOCTL_SETUP_AGGR 122 */
259(0xFF), /* AR6000_XIOCTL_ALLOW_AGGR 123 */
260(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_HIDDEN_SSID 124 */
261(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_COUNTRY 125 */
262(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_WMODE 126 */
263(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_DTIM 127 */
264(AP_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_AP_GET_BINTVL 128 */
265(0xFF), /* AR6000_XIOCTL_AP_GET_RTS 129 */
266(0xFF), /* AR6000_XIOCTL_DELE_AGGR 130 */
267(0xFF), /* AR6000_XIOCTL_FETCH_TARGET_REGS 131 */
268(0xFF), /* AR6000_XIOCTL_HCI_CMD 132 */
269(0xFF), /* AR6000_XIOCTL_ACL_DATA(used to be used for PAL) 133 */
270(0xFF), /* AR6000_XIOCTL_WLAN_CONN_PRECEDENCE 134 */
271(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_11BG_RATESET 135 */
272(0xFF),
273(0xFF),
274(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT 138 */
275(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV 139 */
276(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG 140 */
277(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG 141 */
278(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG 142 */
279(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG 143 */
280(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG 144 */
281(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS 145 */
282(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG 146 */
283(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_BTCOEX_GET_STATS 147 */
284(0xFF), /* AR6000_XIOCTL_WMI_SET_QOS_SUPP 148 */
285(0xFF), /* AR6000_XIOCTL_GET_WLAN_SLEEP_STATE 149 */
286(0xFF), /* AR6000_XIOCTL_SET_BT_HW_POWER_STATE 150 */
287(0xFF), /* AR6000_XIOCTL_GET_BT_HW_POWER_STATE 151 */
288(0xFF), /* AR6000_XIOCTL_ADD_AP_INTERFACE 152 */
289(0xFF), /* AR6000_XIOCTL_REMOVE_AP_INTERFACE 153 */
290(0xFF), /* AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM 154 */
291(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WPA_OFFLOAD_STATE 155 */
292(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_PASSPHRASE 156 */
293(0xFF),
294(0xFF),
295(0xFF),
296(0xFF),
297(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES 161 */
298};
299
300#endif /*_WMI_FILTER_LINUX_H_*/
diff --git a/drivers/staging/ath6kl/os/linux/netbuf.c b/drivers/staging/ath6kl/os/linux/netbuf.c
deleted file mode 100644
index 963a2fb76a9..00000000000
--- a/drivers/staging/ath6kl/os/linux/netbuf.c
+++ /dev/null
@@ -1,231 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23#include <a_config.h>
24#include "athdefs.h"
25#include "a_osapi.h"
26#include "htc_packet.h"
27
28#define AR6000_DATA_OFFSET 64
29
30void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt)
31{
32 skb_queue_tail((struct sk_buff_head *) q, (struct sk_buff *) pkt);
33}
34
35void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt)
36{
37 skb_queue_head((struct sk_buff_head *) q, (struct sk_buff *) pkt);
38}
39
40void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q)
41{
42 return((void *) skb_dequeue((struct sk_buff_head *) q));
43}
44
45int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q)
46{
47 return(skb_queue_len((struct sk_buff_head *) q));
48}
49
50int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q)
51{
52 return(skb_queue_empty((struct sk_buff_head *) q));
53}
54
55void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q)
56{
57 skb_queue_head_init((struct sk_buff_head *) q);
58}
59
60void *
61a_netbuf_alloc(int size)
62{
63 struct sk_buff *skb;
64 size += 2 * (A_GET_CACHE_LINE_BYTES()); /* add some cacheline space at front and back of buffer */
65 skb = dev_alloc_skb(AR6000_DATA_OFFSET + sizeof(struct htc_packet) + size);
66 skb_reserve(skb, AR6000_DATA_OFFSET + sizeof(struct htc_packet) + A_GET_CACHE_LINE_BYTES());
67 return ((void *)skb);
68}
69
70/*
71 * Allocate an SKB w.o. any encapsulation requirement.
72 */
73void *
74a_netbuf_alloc_raw(int size)
75{
76 struct sk_buff *skb;
77
78 skb = dev_alloc_skb(size);
79
80 return ((void *)skb);
81}
82
83void
84a_netbuf_free(void *bufPtr)
85{
86 struct sk_buff *skb = (struct sk_buff *)bufPtr;
87
88 dev_kfree_skb(skb);
89}
90
91u32 a_netbuf_to_len(void *bufPtr)
92{
93 return (((struct sk_buff *)bufPtr)->len);
94}
95
96void *
97a_netbuf_to_data(void *bufPtr)
98{
99 return (((struct sk_buff *)bufPtr)->data);
100}
101
102/*
103 * Add len # of bytes to the beginning of the network buffer
104 * pointed to by bufPtr
105 */
106int
107a_netbuf_push(void *bufPtr, s32 len)
108{
109 skb_push((struct sk_buff *)bufPtr, len);
110
111 return 0;
112}
113
114/*
115 * Add len # of bytes to the beginning of the network buffer
116 * pointed to by bufPtr and also fill with data
117 */
118int
119a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len)
120{
121 skb_push((struct sk_buff *) bufPtr, len);
122 memcpy(((struct sk_buff *)bufPtr)->data, srcPtr, len);
123
124 return 0;
125}
126
127/*
128 * Add len # of bytes to the end of the network buffer
129 * pointed to by bufPtr
130 */
131int
132a_netbuf_put(void *bufPtr, s32 len)
133{
134 skb_put((struct sk_buff *)bufPtr, len);
135
136 return 0;
137}
138
139/*
140 * Add len # of bytes to the end of the network buffer
141 * pointed to by bufPtr and also fill with data
142 */
143int
144a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len)
145{
146 char *start = (char*)(((struct sk_buff *)bufPtr)->data +
147 ((struct sk_buff *)bufPtr)->len);
148 skb_put((struct sk_buff *)bufPtr, len);
149 memcpy(start, srcPtr, len);
150
151 return 0;
152}
153
154
155/*
156 * Trim the network buffer pointed to by bufPtr to len # of bytes
157 */
158int
159a_netbuf_setlen(void *bufPtr, s32 len)
160{
161 skb_trim((struct sk_buff *)bufPtr, len);
162
163 return 0;
164}
165
166/*
167 * Chop of len # of bytes from the end of the buffer.
168 */
169int
170a_netbuf_trim(void *bufPtr, s32 len)
171{
172 skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len);
173
174 return 0;
175}
176
177/*
178 * Chop of len # of bytes from the end of the buffer and return the data.
179 */
180int
181a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len)
182{
183 char *start = (char*)(((struct sk_buff *)bufPtr)->data +
184 (((struct sk_buff *)bufPtr)->len - len));
185
186 memcpy(dstPtr, start, len);
187 skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len);
188
189 return 0;
190}
191
192
193/*
194 * Returns the number of bytes available to a a_netbuf_push()
195 */
196s32 a_netbuf_headroom(void *bufPtr)
197{
198 return (skb_headroom((struct sk_buff *)bufPtr));
199}
200
201/*
202 * Removes specified number of bytes from the beginning of the buffer
203 */
204int
205a_netbuf_pull(void *bufPtr, s32 len)
206{
207 skb_pull((struct sk_buff *)bufPtr, len);
208
209 return 0;
210}
211
212/*
213 * Removes specified number of bytes from the beginning of the buffer
214 * and return the data
215 */
216int
217a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len)
218{
219 memcpy(dstPtr, ((struct sk_buff *)bufPtr)->data, len);
220 skb_pull((struct sk_buff *)bufPtr, len);
221
222 return 0;
223}
224
225#ifdef EXPORT_HCI_BRIDGE_INTERFACE
226EXPORT_SYMBOL(a_netbuf_to_data);
227EXPORT_SYMBOL(a_netbuf_put);
228EXPORT_SYMBOL(a_netbuf_pull);
229EXPORT_SYMBOL(a_netbuf_alloc);
230EXPORT_SYMBOL(a_netbuf_free);
231#endif
diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h
deleted file mode 100644
index 11125967d53..00000000000
--- a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h
+++ /dev/null
@@ -1,117 +0,0 @@
1/*
2 *
3 * Copyright (c) 2004-2010 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7//
8// Permission to use, copy, modify, and/or distribute this software for any
9// purpose with or without fee is hereby granted, provided that the above
10// copyright notice and this permission notice appear in all copies.
11//
12// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19//
20//
21 *
22 */
23
24#ifndef __AGGR_RX_INTERNAL_H__
25#define __AGGR_RX_INTERNAL_H__
26
27#include "a_osapi.h"
28#include "aggr_recv_api.h"
29
30#define AGGR_WIN_IDX(x, y) ((x) % (y))
31#define AGGR_INCR_IDX(x, y) AGGR_WIN_IDX(((x)+1), (y))
32#define AGGR_DCRM_IDX(x, y) AGGR_WIN_IDX(((x)-1), (y))
33#define IEEE80211_MAX_SEQ_NO 0xFFF
34#define IEEE80211_NEXT_SEQ_NO(x) (((x) + 1) & IEEE80211_MAX_SEQ_NO)
35
36
37#define NUM_OF_TIDS 8
38#define AGGR_SZ_DEFAULT 8
39
40#define AGGR_WIN_SZ_MIN 2
41#define AGGR_WIN_SZ_MAX 8
42/* TID Window sz is double of what is negotiated. Derive TID_WINDOW_SZ from win_sz, per tid */
43#define TID_WINDOW_SZ(_x) ((_x) << 1)
44
45#define AGGR_NUM_OF_FREE_NETBUFS 16
46
47#define AGGR_GET_RXTID_STATS(_p, _x) (&(_p->stat[(_x)]))
48#define AGGR_GET_RXTID(_p, _x) (&(_p->RxTid[(_x)]))
49
50/* Hold q is a function of win_sz, which is negotiated per tid */
51#define HOLD_Q_SZ(_x) (TID_WINDOW_SZ((_x))*sizeof(struct osbuf_hold_q))
52/* AGGR_RX_TIMEOUT value is important as a (too) small value can cause frames to be
53 * delivered out of order and a (too) large value can cause undesirable latency in
54 * certain situations. */
55#define AGGR_RX_TIMEOUT 400 /* Timeout(in ms) for delivery of frames, if they are stuck */
56
57typedef enum {
58 ALL_SEQNO = 0,
59 CONTIGUOUS_SEQNO = 1,
60}DELIVERY_ORDER;
61
62struct osbuf_hold_q {
63 void *osbuf;
64 bool is_amsdu;
65 u16 seq_no;
66};
67
68
69#if 0
70/* XXX: unused ? */
71struct window_snapshot {
72 u16 seqno_st;
73 u16 seqno_end;
74};
75#endif
76
77struct rxtid {
78 bool aggr; /* is it ON or OFF */
79 bool progress; /* true when frames have arrived after a timer start */
80 bool timerMon; /* true if the timer started for the sake of this TID */
81 u16 win_sz; /* negotiated window size */
82 u16 seq_next; /* Next seq no, in current window */
83 u32 hold_q_sz; /* Num of frames that can be held in hold q */
84 struct osbuf_hold_q *hold_q; /* Hold q for re-order */
85#if 0
86 struct window_snapshot old_win; /* Sliding window snapshot - for timeout */
87#endif
88 A_NETBUF_QUEUE_T q; /* q head for enqueuing frames for dispatch */
89 A_MUTEX_T lock;
90};
91
92struct rxtid_stats {
93 u32 num_into_aggr; /* hitting at the input of this module */
94 u32 num_dups; /* duplicate */
95 u32 num_oow; /* out of window */
96 u32 num_mpdu; /* single payload 802.3/802.11 frame */
97 u32 num_amsdu; /* AMSDU */
98 u32 num_delivered; /* frames delivered to IP stack */
99 u32 num_timeouts; /* num of timeouts, during which frames delivered */
100 u32 num_hole; /* frame not present, when window moved over */
101 u32 num_bar; /* num of resets of seq_num, via BAR */
102};
103
104struct aggr_info {
105 u8 aggr_sz; /* config value of aggregation size */
106 u8 timerScheduled;
107 A_TIMER timer; /* timer for returning held up pkts in re-order que */
108 void *dev; /* dev handle */
109 RX_CALLBACK rx_fn; /* callback function to return frames; to upper layer */
110 struct rxtid RxTid[NUM_OF_TIDS]; /* Per tid window */
111 ALLOC_NETBUFS netbuf_allocator; /* OS netbuf alloc fn */
112 A_NETBUF_QUEUE_T freeQ; /* pre-allocated buffers - for A_MSDU slicing */
113 struct rxtid_stats stat[NUM_OF_TIDS]; /* Tid based statistics */
114 PACKET_LOG pkt_log; /* Log info of the packets */
115};
116
117#endif /* __AGGR_RX_INTERNAL_H__ */
diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c
deleted file mode 100644
index 9b1509ec5a7..00000000000
--- a/drivers/staging/ath6kl/reorder/rcv_aggr.c
+++ /dev/null
@@ -1,661 +0,0 @@
1/*
2 *
3 * Copyright (c) 2010 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7//
8// Permission to use, copy, modify, and/or distribute this software for any
9// purpose with or without fee is hereby granted, provided that the above
10// copyright notice and this permission notice appear in all copies.
11//
12// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19//
20//
21 *
22 */
23
24#include <a_config.h>
25#include <athdefs.h>
26#include <a_osapi.h>
27#include <a_debug.h>
28#include "pkt_log.h"
29#include "aggr_recv_api.h"
30#include "aggr_rx_internal.h"
31#include "wmi.h"
32
33extern int
34wmi_dot3_2_dix(void *osbuf);
35
36static void
37aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf);
38
39static void
40aggr_timeout(unsigned long arg);
41
42static void
43aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order);
44
45static void
46aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q);
47
48static void *
49aggr_get_osbuf(struct aggr_info *p_aggr);
50
51void *
52aggr_init(ALLOC_NETBUFS netbuf_allocator)
53{
54 struct aggr_info *p_aggr = NULL;
55 struct rxtid *rxtid;
56 u8 i;
57 int status = 0;
58
59 A_PRINTF("In aggr_init..\n");
60
61 do {
62 p_aggr = A_MALLOC(sizeof(struct aggr_info));
63 if(!p_aggr) {
64 A_PRINTF("Failed to allocate memory for aggr_node\n");
65 status = A_ERROR;
66 break;
67 }
68
69 /* Init timer and data structures */
70 A_MEMZERO(p_aggr, sizeof(struct aggr_info));
71 p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
72 A_INIT_TIMER(&p_aggr->timer, aggr_timeout, p_aggr);
73 p_aggr->timerScheduled = false;
74 A_NETBUF_QUEUE_INIT(&p_aggr->freeQ);
75
76 p_aggr->netbuf_allocator = netbuf_allocator;
77 p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS);
78
79 for(i = 0; i < NUM_OF_TIDS; i++) {
80 rxtid = AGGR_GET_RXTID(p_aggr, i);
81 rxtid->aggr = false;
82 rxtid->progress = false;
83 rxtid->timerMon = false;
84 A_NETBUF_QUEUE_INIT(&rxtid->q);
85 A_MUTEX_INIT(&rxtid->lock);
86 }
87 }while(false);
88
89 A_PRINTF("going out of aggr_init..status %s\n",
90 (status == 0) ? "OK":"Error");
91
92 if (status) {
93 /* Cleanup */
94 aggr_module_destroy(p_aggr);
95 }
96 return ((status == 0) ? p_aggr : NULL);
97}
98
99/* utility function to clear rx hold_q for a tid */
100static void
101aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
102{
103 struct rxtid *rxtid;
104 struct rxtid_stats *stats;
105
106 A_ASSERT(tid < NUM_OF_TIDS && p_aggr);
107
108 rxtid = AGGR_GET_RXTID(p_aggr, tid);
109 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
110
111 if(rxtid->aggr) {
112 aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
113 }
114
115 rxtid->aggr = false;
116 rxtid->progress = false;
117 rxtid->timerMon = false;
118 rxtid->win_sz = 0;
119 rxtid->seq_next = 0;
120 rxtid->hold_q_sz = 0;
121
122 if(rxtid->hold_q) {
123 kfree(rxtid->hold_q);
124 rxtid->hold_q = NULL;
125 }
126
127 A_MEMZERO(stats, sizeof(struct rxtid_stats));
128}
129
130void
131aggr_module_destroy(void *cntxt)
132{
133 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
134 struct rxtid *rxtid;
135 u8 i, k;
136 A_PRINTF("%s(): aggr = %p\n",_A_FUNCNAME_, p_aggr);
137 A_ASSERT(p_aggr);
138
139 if(p_aggr) {
140 if(p_aggr->timerScheduled) {
141 A_UNTIMEOUT(&p_aggr->timer);
142 p_aggr->timerScheduled = false;
143 }
144
145 for(i = 0; i < NUM_OF_TIDS; i++) {
146 rxtid = AGGR_GET_RXTID(p_aggr, i);
147 /* Free the hold q contents and hold_q*/
148 if(rxtid->hold_q) {
149 for(k = 0; k< rxtid->hold_q_sz; k++) {
150 if(rxtid->hold_q[k].osbuf) {
151 A_NETBUF_FREE(rxtid->hold_q[k].osbuf);
152 }
153 }
154 kfree(rxtid->hold_q);
155 }
156 /* Free the dispatch q contents*/
157 while(A_NETBUF_QUEUE_SIZE(&rxtid->q)) {
158 A_NETBUF_FREE(A_NETBUF_DEQUEUE(&rxtid->q));
159 }
160 if (A_IS_MUTEX_VALID(&rxtid->lock)) {
161 A_MUTEX_DELETE(&rxtid->lock);
162 }
163 }
164 /* free the freeQ and its contents*/
165 while(A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
166 A_NETBUF_FREE(A_NETBUF_DEQUEUE(&p_aggr->freeQ));
167 }
168 kfree(p_aggr);
169 }
170 A_PRINTF("out aggr_module_destroy\n");
171}
172
173
174void
175aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn)
176{
177 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
178
179 A_ASSERT(p_aggr && fn && dev);
180
181 p_aggr->rx_fn = fn;
182 p_aggr->dev = dev;
183}
184
185
186void
187aggr_process_bar(void *cntxt, u8 tid, u16 seq_no)
188{
189 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
190 struct rxtid_stats *stats;
191
192 A_ASSERT(p_aggr);
193 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
194 stats->num_bar++;
195
196 aggr_deque_frms(p_aggr, tid, seq_no, ALL_SEQNO);
197}
198
199
200void
201aggr_recv_addba_req_evt(void *cntxt, u8 tid, u16 seq_no, u8 win_sz)
202{
203 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
204 struct rxtid *rxtid;
205 struct rxtid_stats *stats;
206
207 A_ASSERT(p_aggr);
208 rxtid = AGGR_GET_RXTID(p_aggr, tid);
209 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
210
211 A_PRINTF("%s(): win_sz = %d aggr %d\n", _A_FUNCNAME_, win_sz, rxtid->aggr);
212 if(win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) {
213 A_PRINTF("win_sz %d, tid %d\n", win_sz, tid);
214 }
215
216 if(rxtid->aggr) {
217 /* Just go and deliver all the frames up from this
218 * queue, as if we got DELBA and re-initialize the queue
219 */
220 aggr_delete_tid_state(p_aggr, tid);
221 }
222
223 rxtid->seq_next = seq_no;
224 /* create these queues, only upon receiving of ADDBA for a
225 * tid, reducing memory requirement
226 */
227 rxtid->hold_q = A_MALLOC(HOLD_Q_SZ(win_sz));
228 if((rxtid->hold_q == NULL)) {
229 A_PRINTF("Failed to allocate memory, tid = %d\n", tid);
230 A_ASSERT(0);
231 }
232 A_MEMZERO(rxtid->hold_q, HOLD_Q_SZ(win_sz));
233
234 /* Update rxtid for the window sz */
235 rxtid->win_sz = win_sz;
236 /* hold_q_sz inicates the depth of holding q - which is
237 * a factor of win_sz. Compute once, as it will be used often
238 */
239 rxtid->hold_q_sz = TID_WINDOW_SZ(win_sz);
240 /* There should be no frames on q - even when second ADDBA comes in.
241 * If aggr was previously ON on this tid, we would have cleaned up
242 * the q
243 */
244 if(A_NETBUF_QUEUE_SIZE(&rxtid->q) != 0) {
245 A_PRINTF("ERROR: Frames still on queue ?\n");
246 A_ASSERT(0);
247 }
248
249 rxtid->aggr = true;
250}
251
252void
253aggr_recv_delba_req_evt(void *cntxt, u8 tid)
254{
255 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
256 struct rxtid *rxtid;
257
258 A_ASSERT(p_aggr);
259 A_PRINTF("%s(): tid %d\n", _A_FUNCNAME_, tid);
260
261 rxtid = AGGR_GET_RXTID(p_aggr, tid);
262
263 if(rxtid->aggr) {
264 aggr_delete_tid_state(p_aggr, tid);
265 }
266}
267
268static void
269aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order)
270{
271 struct rxtid *rxtid;
272 struct osbuf_hold_q *node;
273 u16 idx, idx_end, seq_end;
274 struct rxtid_stats *stats;
275
276 A_ASSERT(p_aggr);
277 rxtid = AGGR_GET_RXTID(p_aggr, tid);
278 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
279
280 /* idx is absolute location for first frame */
281 idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
282
283 /* idx_end is typically the last possible frame in the window,
284 * but changes to 'the' seq_no, when BAR comes. If seq_no
285 * is non-zero, we will go up to that and stop.
286 * Note: last seq no in current window will occupy the same
287 * index position as index that is just previous to start.
288 * An imp point : if win_sz is 7, for seq_no space of 4095,
289 * then, there would be holes when sequence wrap around occurs.
290 * Target should judiciously choose the win_sz, based on
291 * this condition. For 4095, (TID_WINDOW_SZ = 2 x win_sz
292 * 2, 4, 8, 16 win_sz works fine).
293 * We must deque from "idx" to "idx_end", including both.
294 */
295 seq_end = (seq_no) ? seq_no : rxtid->seq_next;
296 idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);
297
298 /* Critical section begins */
299 A_MUTEX_LOCK(&rxtid->lock);
300 do {
301
302 node = &rxtid->hold_q[idx];
303
304 if((order == CONTIGUOUS_SEQNO) && (!node->osbuf))
305 break;
306
307 /* chain frames and deliver frames bcos:
308 * 1. either the frames are in order and window is contiguous, OR
309 * 2. we need to deque frames, irrespective of holes
310 */
311 if(node->osbuf) {
312 if(node->is_amsdu) {
313 aggr_slice_amsdu(p_aggr, rxtid, &node->osbuf);
314 } else {
315 A_NETBUF_ENQUEUE(&rxtid->q, node->osbuf);
316 }
317 node->osbuf = NULL;
318 } else {
319 stats->num_hole++;
320 }
321
322 /* window is moving */
323 rxtid->seq_next = IEEE80211_NEXT_SEQ_NO(rxtid->seq_next);
324 idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
325 } while(idx != idx_end);
326 /* Critical section ends */
327 A_MUTEX_UNLOCK(&rxtid->lock);
328
329 stats->num_delivered += A_NETBUF_QUEUE_SIZE(&rxtid->q);
330 aggr_dispatch_frames(p_aggr, &rxtid->q);
331}
332
333static void *
334aggr_get_osbuf(struct aggr_info *p_aggr)
335{
336 void *buf = NULL;
337
338 /* Starving for buffers? get more from OS
339 * check for low netbuffers( < 1/4 AGGR_NUM_OF_FREE_NETBUFS) :
340 * re-allocate bufs if so
341 * allocate a free buf from freeQ
342 */
343 if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ) < (AGGR_NUM_OF_FREE_NETBUFS >> 2)) {
344 p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS);
345 }
346
347 if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
348 buf = A_NETBUF_DEQUEUE(&p_aggr->freeQ);
349 }
350
351 return buf;
352}
353
354
355static void
356aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf)
357{
358 void *new_buf;
359 u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len;
360 u8 *framep;
361
362 /* Frame format at this point:
363 * [DIX hdr | 802.3 | 802.3 | ... | 802.3]
364 *
365 * Strip the DIX header.
366 * Iterate through the osbuf and do:
367 * grab a free netbuf from freeQ
368 * find the start and end of a frame
369 * copy it to netbuf(Vista can do better here)
370 * convert all msdu's(802.3) frames to upper layer format - os routine
371 * -for now lets convert from 802.3 to dix
372 * enque this to dispatch q of tid
373 * repeat
374 * free the osbuf - to OS. It's been sliced.
375 */
376
377 mac_hdr_len = sizeof(ATH_MAC_HDR);
378 framep = A_NETBUF_DATA(*osbuf) + mac_hdr_len;
379 amsdu_len = A_NETBUF_LEN(*osbuf) - mac_hdr_len;
380
381 while(amsdu_len > mac_hdr_len) {
382 /* Begin of a 802.3 frame */
383 payload_8023_len = A_BE2CPU16(((ATH_MAC_HDR *)framep)->typeOrLen);
384#define MAX_MSDU_SUBFRAME_PAYLOAD_LEN 1508
385#define MIN_MSDU_SUBFRAME_PAYLOAD_LEN 46
386 if(payload_8023_len < MIN_MSDU_SUBFRAME_PAYLOAD_LEN || payload_8023_len > MAX_MSDU_SUBFRAME_PAYLOAD_LEN) {
387 A_PRINTF("802.3 AMSDU frame bound check failed. len %d\n", payload_8023_len);
388 break;
389 }
390 frame_8023_len = payload_8023_len + mac_hdr_len;
391 new_buf = aggr_get_osbuf(p_aggr);
392 if(new_buf == NULL) {
393 A_PRINTF("No buffer available \n");
394 break;
395 }
396
397 memcpy(A_NETBUF_DATA(new_buf), framep, frame_8023_len);
398 A_NETBUF_PUT(new_buf, frame_8023_len);
399 if (wmi_dot3_2_dix(new_buf) != 0) {
400 A_PRINTF("dot3_2_dix err..\n");
401 A_NETBUF_FREE(new_buf);
402 break;
403 }
404
405 A_NETBUF_ENQUEUE(&rxtid->q, new_buf);
406
407 /* Is this the last subframe within this aggregate ? */
408 if ((amsdu_len - frame_8023_len) == 0) {
409 break;
410 }
411
412 /* Add the length of A-MSDU subframe padding bytes -
413 * Round to nearest word.
414 */
415 frame_8023_len = ((frame_8023_len + 3) & ~3);
416
417 framep += frame_8023_len;
418 amsdu_len -= frame_8023_len;
419 }
420
421 A_NETBUF_FREE(*osbuf);
422 *osbuf = NULL;
423}
424
425void
426aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf)
427{
428 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
429 struct rxtid *rxtid;
430 struct rxtid_stats *stats;
431 u16 idx, st, cur, end;
432 u16 *log_idx;
433 struct osbuf_hold_q *node;
434 PACKET_LOG *log;
435
436 A_ASSERT(p_aggr);
437 A_ASSERT(tid < NUM_OF_TIDS);
438
439 rxtid = AGGR_GET_RXTID(p_aggr, tid);
440 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
441
442 stats->num_into_aggr++;
443
444 if(!rxtid->aggr) {
445 if(is_amsdu) {
446 aggr_slice_amsdu(p_aggr, rxtid, osbuf);
447 stats->num_amsdu++;
448 aggr_dispatch_frames(p_aggr, &rxtid->q);
449 }
450 return;
451 }
452
453 /* Check the incoming sequence no, if it's in the window */
454 st = rxtid->seq_next;
455 cur = seq_no;
456 end = (st + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;
457 /* Log the pkt info for future analysis */
458 log = &p_aggr->pkt_log;
459 log_idx = &log->last_idx;
460 log->info[*log_idx].cur = cur;
461 log->info[*log_idx].st = st;
462 log->info[*log_idx].end = end;
463 *log_idx = IEEE80211_NEXT_SEQ_NO(*log_idx);
464
465 if(((st < end) && (cur < st || cur > end)) ||
466 ((st > end) && (cur > end) && (cur < st))) {
467 /* the cur frame is outside the window. Since we know
468 * our target would not do this without reason it must
469 * be assumed that the window has moved for some valid reason.
470 * Therefore, we dequeue all frames and start fresh.
471 */
472 u16 extended_end;
473
474 extended_end = (end + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;
475
476 if(((end < extended_end) && (cur < end || cur > extended_end)) ||
477 ((end > extended_end) && (cur > extended_end) && (cur < end))) {
478 // dequeue all frames in queue and shift window to new frame
479 aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
480 //set window start so that new frame is last frame in window
481 if(cur >= rxtid->hold_q_sz-1) {
482 rxtid->seq_next = cur - (rxtid->hold_q_sz-1);
483 }else{
484 rxtid->seq_next = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur);
485 }
486 } else {
487 // dequeue only those frames that are outside the new shifted window
488 if(cur >= rxtid->hold_q_sz-1) {
489 st = cur - (rxtid->hold_q_sz-1);
490 }else{
491 st = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur);
492 }
493
494 aggr_deque_frms(p_aggr, tid, st, ALL_SEQNO);
495 }
496
497 stats->num_oow++;
498 }
499
500 idx = AGGR_WIN_IDX(seq_no, rxtid->hold_q_sz);
501
502 /*enque the frame, in hold_q */
503 node = &rxtid->hold_q[idx];
504
505 A_MUTEX_LOCK(&rxtid->lock);
506 if(node->osbuf) {
507 /* Is the cur frame duplicate or something beyond our
508 * window(hold_q -> which is 2x, already)?
509 * 1. Duplicate is easy - drop incoming frame.
510 * 2. Not falling in current sliding window.
511 * 2a. is the frame_seq_no preceding current tid_seq_no?
512 * -> drop the frame. perhaps sender did not get our ACK.
513 * this is taken care of above.
514 * 2b. is the frame_seq_no beyond window(st, TID_WINDOW_SZ);
515 * -> Taken care of it above, by moving window forward.
516 *
517 */
518 A_NETBUF_FREE(node->osbuf);
519 stats->num_dups++;
520 }
521
522 node->osbuf = *osbuf;
523 node->is_amsdu = is_amsdu;
524 node->seq_no = seq_no;
525 if(node->is_amsdu) {
526 stats->num_amsdu++;
527 } else {
528 stats->num_mpdu++;
529 }
530 A_MUTEX_UNLOCK(&rxtid->lock);
531
532 *osbuf = NULL;
533 aggr_deque_frms(p_aggr, tid, 0, CONTIGUOUS_SEQNO);
534
535 if(p_aggr->timerScheduled) {
536 rxtid->progress = true;
537 }else{
538 for(idx=0 ; idx<rxtid->hold_q_sz ; idx++) {
539 if(rxtid->hold_q[idx].osbuf) {
540 /* there is a frame in the queue and no timer so
541 * start a timer to ensure that the frame doesn't remain
542 * stuck forever. */
543 p_aggr->timerScheduled = true;
544 A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
545 rxtid->progress = false;
546 rxtid->timerMon = true;
547 break;
548 }
549 }
550 }
551}
552
553/*
554 * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate
555 * hold Q state. Examples include when a Connect event or disconnect event is
556 * received.
557 */
558void
559aggr_reset_state(void *cntxt)
560{
561 u8 tid;
562 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
563
564 A_ASSERT(p_aggr);
565
566 for(tid=0 ; tid<NUM_OF_TIDS ; tid++) {
567 aggr_delete_tid_state(p_aggr, tid);
568 }
569}
570
571
572static void
573aggr_timeout(unsigned long arg)
574{
575 u8 i,j;
576 struct aggr_info *p_aggr = (struct aggr_info *)arg;
577 struct rxtid *rxtid;
578 struct rxtid_stats *stats;
579 /*
580 * If the q for which the timer was originally started has
581 * not progressed then it is necessary to dequeue all the
582 * contained frames so that they are not held forever.
583 */
584 for(i = 0; i < NUM_OF_TIDS; i++) {
585 rxtid = AGGR_GET_RXTID(p_aggr, i);
586 stats = AGGR_GET_RXTID_STATS(p_aggr, i);
587
588 if(rxtid->aggr == false ||
589 rxtid->timerMon == false ||
590 rxtid->progress == true) {
591 continue;
592 }
593 // dequeue all frames in for this tid
594 stats->num_timeouts++;
595 A_PRINTF("TO: st %d end %d\n", rxtid->seq_next, ((rxtid->seq_next + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO));
596 aggr_deque_frms(p_aggr, i, 0, ALL_SEQNO);
597 }
598
599 p_aggr->timerScheduled = false;
600 // determine whether a new timer should be started.
601 for(i = 0; i < NUM_OF_TIDS; i++) {
602 rxtid = AGGR_GET_RXTID(p_aggr, i);
603
604 if(rxtid->aggr == true && rxtid->hold_q) {
605 for(j = 0 ; j < rxtid->hold_q_sz ; j++)
606 {
607 if(rxtid->hold_q[j].osbuf)
608 {
609 p_aggr->timerScheduled = true;
610 rxtid->timerMon = true;
611 rxtid->progress = false;
612 break;
613 }
614 }
615
616 if(j >= rxtid->hold_q_sz) {
617 rxtid->timerMon = false;
618 }
619 }
620 }
621
622 if(p_aggr->timerScheduled) {
623 /* Rearm the timer*/
624 A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
625 }
626
627}
628
629static void
630aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q)
631{
632 void *osbuf;
633
634 while((osbuf = A_NETBUF_DEQUEUE(q))) {
635 p_aggr->rx_fn(p_aggr->dev, osbuf);
636 }
637}
638
639void
640aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf)
641{
642 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
643 struct rxtid *rxtid;
644 struct rxtid_stats *stats;
645 u8 i;
646
647 *log_buf = &p_aggr->pkt_log;
648 A_PRINTF("\n\n================================================\n");
649 A_PRINTF("tid: num_into_aggr, dups, oow, mpdu, amsdu, delivered, timeouts, holes, bar, seq_next\n");
650 for(i = 0; i < NUM_OF_TIDS; i++) {
651 stats = AGGR_GET_RXTID_STATS(p_aggr, i);
652 rxtid = AGGR_GET_RXTID(p_aggr, i);
653 A_PRINTF("%d: %d %d %d %d %d %d %d %d %d : %d\n", i, stats->num_into_aggr, stats->num_dups,
654 stats->num_oow, stats->num_mpdu,
655 stats->num_amsdu, stats->num_delivered, stats->num_timeouts,
656 stats->num_hole, stats->num_bar,
657 rxtid->seq_next);
658 }
659 A_PRINTF("================================================\n\n");
660
661}
diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211.h b/drivers/staging/ath6kl/wlan/include/ieee80211.h
deleted file mode 100644
index cf47d0657e7..00000000000
--- a/drivers/staging/ath6kl/wlan/include/ieee80211.h
+++ /dev/null
@@ -1,397 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="ieee80211.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _NET80211_IEEE80211_H_
24#define _NET80211_IEEE80211_H_
25
26/*
27 * 802.11 protocol definitions.
28 */
29#define IEEE80211_WEP_KEYLEN 5 /* 40bit */
30#define IEEE80211_WEP_IVLEN 3 /* 24bit */
31#define IEEE80211_WEP_KIDLEN 1 /* 1 octet */
32#define IEEE80211_WEP_CRCLEN 4 /* CRC-32 */
33#define IEEE80211_WEP_NKID 4 /* number of key ids */
34
35/*
36 * 802.11i defines an extended IV for use with non-WEP ciphers.
37 * When the EXTIV bit is set in the key id byte an additional
38 * 4 bytes immediately follow the IV for TKIP. For CCMP the
39 * EXTIV bit is likewise set but the 8 bytes represent the
40 * CCMP header rather than IV+extended-IV.
41 */
42#define IEEE80211_WEP_EXTIV 0x20
43#define IEEE80211_WEP_EXTIVLEN 4 /* extended IV length */
44#define IEEE80211_WEP_MICLEN 8 /* trailing MIC */
45
46#define IEEE80211_CRC_LEN 4
47
48#ifdef WAPI_ENABLE
49#define IEEE80211_WAPI_EXTIVLEN 10 /* extended IV length */
50#endif /* WAPI ENABLE */
51
52
53#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */
54/* is 802.11 address multicast/broadcast? */
55#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01)
56#define IEEE80211_IS_BROADCAST(_a) (*(_a) == 0xFF)
57#define WEP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN)
58#define WEP_TRAILER IEEE80211_WEP_CRCLEN
59#define CCMP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + \
60 IEEE80211_WEP_EXTIVLEN)
61#define CCMP_TRAILER IEEE80211_WEP_MICLEN
62#define TKIP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + \
63 IEEE80211_WEP_EXTIVLEN)
64#define TKIP_TRAILER IEEE80211_WEP_CRCLEN
65#define TKIP_MICLEN IEEE80211_WEP_MICLEN
66
67
68#define IEEE80211_ADDR_EQ(addr1, addr2) \
69 (memcmp(addr1, addr2, IEEE80211_ADDR_LEN) == 0)
70
71#define IEEE80211_ADDR_COPY(dst,src) memcpy(dst,src,IEEE80211_ADDR_LEN)
72
73#define IEEE80211_KEYBUF_SIZE 16
74#define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx and rx */
75
76/*
77 * NB: these values are ordered carefully; there are lots of
78 * of implications in any reordering. In particular beware
79 * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY.
80 */
81#define IEEE80211_CIPHER_WEP 0
82#define IEEE80211_CIPHER_TKIP 1
83#define IEEE80211_CIPHER_AES_OCB 2
84#define IEEE80211_CIPHER_AES_CCM 3
85#define IEEE80211_CIPHER_CKIP 5
86#define IEEE80211_CIPHER_CCKM_KRK 6
87#define IEEE80211_CIPHER_NONE 7 /* pseudo value */
88
89#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1)
90
91#define IEEE80211_IS_VALID_WEP_CIPHER_LEN(len) \
92 (((len) == 5) || ((len) == 13) || ((len) == 16))
93
94
95
96/*
97 * generic definitions for IEEE 802.11 frames
98 */
99PREPACK struct ieee80211_frame {
100 u8 i_fc[2];
101 u8 i_dur[2];
102 u8 i_addr1[IEEE80211_ADDR_LEN];
103 u8 i_addr2[IEEE80211_ADDR_LEN];
104 u8 i_addr3[IEEE80211_ADDR_LEN];
105 u8 i_seq[2];
106 /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
107 /* see below */
108} POSTPACK;
109
110PREPACK struct ieee80211_qosframe {
111 u8 i_fc[2];
112 u8 i_dur[2];
113 u8 i_addr1[IEEE80211_ADDR_LEN];
114 u8 i_addr2[IEEE80211_ADDR_LEN];
115 u8 i_addr3[IEEE80211_ADDR_LEN];
116 u8 i_seq[2];
117 u8 i_qos[2];
118} POSTPACK;
119
120#define IEEE80211_FC0_VERSION_MASK 0x03
121#define IEEE80211_FC0_VERSION_SHIFT 0
122#define IEEE80211_FC0_VERSION_0 0x00
123#define IEEE80211_FC0_TYPE_MASK 0x0c
124#define IEEE80211_FC0_TYPE_SHIFT 2
125#define IEEE80211_FC0_TYPE_MGT 0x00
126#define IEEE80211_FC0_TYPE_CTL 0x04
127#define IEEE80211_FC0_TYPE_DATA 0x08
128
129#define IEEE80211_FC0_SUBTYPE_MASK 0xf0
130#define IEEE80211_FC0_SUBTYPE_SHIFT 4
131/* for TYPE_MGT */
132#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00
133#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10
134#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20
135#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30
136#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40
137#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50
138#define IEEE80211_FC0_SUBTYPE_BEACON 0x80
139#define IEEE80211_FC0_SUBTYPE_ATIM 0x90
140#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0
141#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0
142#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0
143/* for TYPE_CTL */
144#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0
145#define IEEE80211_FC0_SUBTYPE_RTS 0xb0
146#define IEEE80211_FC0_SUBTYPE_CTS 0xc0
147#define IEEE80211_FC0_SUBTYPE_ACK 0xd0
148#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0
149#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0
150/* for TYPE_DATA (bit combination) */
151#define IEEE80211_FC0_SUBTYPE_DATA 0x00
152#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10
153#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20
154#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30
155#define IEEE80211_FC0_SUBTYPE_NODATA 0x40
156#define IEEE80211_FC0_SUBTYPE_CFACK 0x50
157#define IEEE80211_FC0_SUBTYPE_CFPOLL 0x60
158#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70
159#define IEEE80211_FC0_SUBTYPE_QOS 0x80
160#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0
161
162#define IEEE80211_FC1_DIR_MASK 0x03
163#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */
164#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */
165#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */
166#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */
167
168#define IEEE80211_FC1_MORE_FRAG 0x04
169#define IEEE80211_FC1_RETRY 0x08
170#define IEEE80211_FC1_PWR_MGT 0x10
171#define IEEE80211_FC1_MORE_DATA 0x20
172#define IEEE80211_FC1_WEP 0x40
173#define IEEE80211_FC1_ORDER 0x80
174
175#define IEEE80211_SEQ_FRAG_MASK 0x000f
176#define IEEE80211_SEQ_FRAG_SHIFT 0
177#define IEEE80211_SEQ_SEQ_MASK 0xfff0
178#define IEEE80211_SEQ_SEQ_SHIFT 4
179
180#define IEEE80211_NWID_LEN 32
181
182/*
183 * 802.11 rate set.
184 */
185#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */
186#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */
187
188#define WMM_NUM_AC 4 /* 4 AC categories */
189
190#define WMM_PARAM_ACI_M 0x60 /* Mask for ACI field */
191#define WMM_PARAM_ACI_S 5 /* Shift for ACI field */
192#define WMM_PARAM_ACM_M 0x10 /* Mask for ACM bit */
193#define WMM_PARAM_ACM_S 4 /* Shift for ACM bit */
194#define WMM_PARAM_AIFSN_M 0x0f /* Mask for aifsn field */
195#define WMM_PARAM_LOGCWMIN_M 0x0f /* Mask for CwMin field (in log) */
196#define WMM_PARAM_LOGCWMAX_M 0xf0 /* Mask for CwMax field (in log) */
197#define WMM_PARAM_LOGCWMAX_S 4 /* Shift for CwMax field */
198
199#define WMM_AC_TO_TID(_ac) ( \
200 ((_ac) == WMM_AC_VO) ? 6 : \
201 ((_ac) == WMM_AC_VI) ? 5 : \
202 ((_ac) == WMM_AC_BK) ? 1 : \
203 0)
204
205#define TID_TO_WMM_AC(_tid) ( \
206 ((_tid) < 1) ? WMM_AC_BE : \
207 ((_tid) < 3) ? WMM_AC_BK : \
208 ((_tid) < 6) ? WMM_AC_VI : \
209 WMM_AC_VO)
210/*
211 * Management information element payloads.
212 */
213
214enum {
215 IEEE80211_ELEMID_SSID = 0,
216 IEEE80211_ELEMID_RATES = 1,
217 IEEE80211_ELEMID_FHPARMS = 2,
218 IEEE80211_ELEMID_DSPARMS = 3,
219 IEEE80211_ELEMID_CFPARMS = 4,
220 IEEE80211_ELEMID_TIM = 5,
221 IEEE80211_ELEMID_IBSSPARMS = 6,
222 IEEE80211_ELEMID_COUNTRY = 7,
223 IEEE80211_ELEMID_CHALLENGE = 16,
224 /* 17-31 reserved for challenge text extension */
225 IEEE80211_ELEMID_PWRCNSTR = 32,
226 IEEE80211_ELEMID_PWRCAP = 33,
227 IEEE80211_ELEMID_TPCREQ = 34,
228 IEEE80211_ELEMID_TPCREP = 35,
229 IEEE80211_ELEMID_SUPPCHAN = 36,
230 IEEE80211_ELEMID_CHANSWITCH = 37,
231 IEEE80211_ELEMID_MEASREQ = 38,
232 IEEE80211_ELEMID_MEASREP = 39,
233 IEEE80211_ELEMID_QUIET = 40,
234 IEEE80211_ELEMID_IBSSDFS = 41,
235 IEEE80211_ELEMID_ERP = 42,
236 IEEE80211_ELEMID_HTCAP_ANA = 45, /* Address ANA, and non-ANA story, for interop. CL#171733 */
237 IEEE80211_ELEMID_RSN = 48,
238 IEEE80211_ELEMID_XRATES = 50,
239 IEEE80211_ELEMID_HTINFO_ANA = 61,
240#ifdef WAPI_ENABLE
241 IEEE80211_ELEMID_WAPI = 68,
242#endif
243 IEEE80211_ELEMID_TPC = 150,
244 IEEE80211_ELEMID_CCKM = 156,
245 IEEE80211_ELEMID_VENDOR = 221, /* vendor private */
246};
247
248#define ATH_OUI 0x7f0300 /* Atheros OUI */
249#define ATH_OUI_TYPE 0x01
250#define ATH_OUI_SUBTYPE 0x01
251#define ATH_OUI_VERSION 0x00
252
253#define WPA_OUI 0xf25000
254#define WPA_OUI_TYPE 0x01
255#define WPA_VERSION 1 /* current supported version */
256
257#define WPA_CSE_NULL 0x00
258#define WPA_CSE_WEP40 0x01
259#define WPA_CSE_TKIP 0x02
260#define WPA_CSE_CCMP 0x04
261#define WPA_CSE_WEP104 0x05
262
263#define WPA_ASE_NONE 0x00
264#define WPA_ASE_8021X_UNSPEC 0x01
265#define WPA_ASE_8021X_PSK 0x02
266
267#define RSN_OUI 0xac0f00
268#define RSN_VERSION 1 /* current supported version */
269
270#define RSN_CSE_NULL 0x00
271#define RSN_CSE_WEP40 0x01
272#define RSN_CSE_TKIP 0x02
273#define RSN_CSE_WRAP 0x03
274#define RSN_CSE_CCMP 0x04
275#define RSN_CSE_WEP104 0x05
276
277#define RSN_ASE_NONE 0x00
278#define RSN_ASE_8021X_UNSPEC 0x01
279#define RSN_ASE_8021X_PSK 0x02
280
281#define RSN_CAP_PREAUTH 0x01
282
283#define WMM_OUI 0xf25000
284#define WMM_OUI_TYPE 0x02
285#define WMM_INFO_OUI_SUBTYPE 0x00
286#define WMM_PARAM_OUI_SUBTYPE 0x01
287#define WMM_VERSION 1
288
289/* WMM stream classes */
290#define WMM_NUM_AC 4
291#define WMM_AC_BE 0 /* best effort */
292#define WMM_AC_BK 1 /* background */
293#define WMM_AC_VI 2 /* video */
294#define WMM_AC_VO 3 /* voice */
295
296/* TSPEC related */
297#define ACTION_CATEGORY_CODE_TSPEC 17
298#define ACTION_CODE_TSPEC_ADDTS 0
299#define ACTION_CODE_TSPEC_ADDTS_RESP 1
300#define ACTION_CODE_TSPEC_DELTS 2
301
302typedef enum {
303 TSPEC_STATUS_CODE_ADMISSION_ACCEPTED = 0,
304 TSPEC_STATUS_CODE_ADDTS_INVALID_PARAMS = 0x1,
305 TSPEC_STATUS_CODE_ADDTS_REQUEST_REFUSED = 0x3,
306 TSPEC_STATUS_CODE_UNSPECIFIED_QOS_RELATED_FAILURE = 0xC8,
307 TSPEC_STATUS_CODE_REQUESTED_REFUSED_POLICY_CONFIGURATION = 0xC9,
308 TSPEC_STATUS_CODE_INSUFFCIENT_BANDWIDTH = 0xCA,
309 TSPEC_STATUS_CODE_INVALID_PARAMS = 0xCB,
310 TSPEC_STATUS_CODE_DELTS_SENT = 0x30,
311 TSPEC_STATUS_CODE_DELTS_RECV = 0x31,
312} TSPEC_STATUS_CODE;
313
314#define TSPEC_TSID_MASK 0xF
315#define TSPEC_TSID_S 1
316
317/*
318 * WMM/802.11e Tspec Element
319 */
320typedef PREPACK struct wmm_tspec_ie_t {
321 u8 elementId;
322 u8 len;
323 u8 oui[3];
324 u8 ouiType;
325 u8 ouiSubType;
326 u8 version;
327 u16 tsInfo_info;
328 u8 tsInfo_reserved;
329 u16 nominalMSDU;
330 u16 maxMSDU;
331 u32 minServiceInt;
332 u32 maxServiceInt;
333 u32 inactivityInt;
334 u32 suspensionInt;
335 u32 serviceStartTime;
336 u32 minDataRate;
337 u32 meanDataRate;
338 u32 peakDataRate;
339 u32 maxBurstSize;
340 u32 delayBound;
341 u32 minPhyRate;
342 u16 sba;
343 u16 mediumTime;
344} POSTPACK WMM_TSPEC_IE;
345
346
347/*
348 * BEACON management packets
349 *
350 * octet timestamp[8]
351 * octet beacon interval[2]
352 * octet capability information[2]
353 * information element
354 * octet elemid
355 * octet length
356 * octet information[length]
357 */
358
359#define IEEE80211_BEACON_INTERVAL(beacon) \
360 ((beacon)[8] | ((beacon)[9] << 8))
361#define IEEE80211_BEACON_CAPABILITY(beacon) \
362 ((beacon)[10] | ((beacon)[11] << 8))
363
364#define IEEE80211_CAPINFO_ESS 0x0001
365#define IEEE80211_CAPINFO_IBSS 0x0002
366#define IEEE80211_CAPINFO_CF_POLLABLE 0x0004
367#define IEEE80211_CAPINFO_CF_POLLREQ 0x0008
368#define IEEE80211_CAPINFO_PRIVACY 0x0010
369#define IEEE80211_CAPINFO_SHORT_PREAMBLE 0x0020
370#define IEEE80211_CAPINFO_PBCC 0x0040
371#define IEEE80211_CAPINFO_CHNL_AGILITY 0x0080
372/* bits 8-9 are reserved */
373#define IEEE80211_CAPINFO_SHORT_SLOTTIME 0x0400
374#define IEEE80211_CAPINFO_APSD 0x0800
375/* bit 12 is reserved */
376#define IEEE80211_CAPINFO_DSSSOFDM 0x2000
377/* bits 14-15 are reserved */
378
379/*
380 * Authentication Modes
381 */
382
383enum ieee80211_authmode {
384 IEEE80211_AUTH_NONE = 0,
385 IEEE80211_AUTH_OPEN = 1,
386 IEEE80211_AUTH_SHARED = 2,
387 IEEE80211_AUTH_8021X = 3,
388 IEEE80211_AUTH_AUTO = 4, /* auto-select/accept */
389 /* NB: these are used only for ioctls */
390 IEEE80211_AUTH_WPA = 5, /* WPA/RSN w/ 802.1x */
391 IEEE80211_AUTH_WPA_PSK = 6, /* WPA/RSN w/ PSK */
392 IEEE80211_AUTH_WPA_CCKM = 7, /* WPA/RSN IE w/ CCKM */
393};
394
395#define IEEE80211_PS_MAX_QUEUE 50 /*Maximum no of buffers that can be queues for PS*/
396
397#endif /* _NET80211_IEEE80211_H_ */
diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211_node.h b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h
deleted file mode 100644
index 1cb01671c0d..00000000000
--- a/drivers/staging/ath6kl/wlan/include/ieee80211_node.h
+++ /dev/null
@@ -1,93 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="ieee80211_node.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _IEEE80211_NODE_H_
24#define _IEEE80211_NODE_H_
25
26/*
27 * Node locking definitions.
28 */
29#define IEEE80211_NODE_LOCK_INIT(_nt) A_MUTEX_INIT(&(_nt)->nt_nodelock)
30#define IEEE80211_NODE_LOCK_DESTROY(_nt) if (A_IS_MUTEX_VALID(&(_nt)->nt_nodelock)) { \
31 A_MUTEX_DELETE(&(_nt)->nt_nodelock); }
32
33#define IEEE80211_NODE_LOCK(_nt) A_MUTEX_LOCK(&(_nt)->nt_nodelock)
34#define IEEE80211_NODE_UNLOCK(_nt) A_MUTEX_UNLOCK(&(_nt)->nt_nodelock)
35#define IEEE80211_NODE_LOCK_BH(_nt) A_MUTEX_LOCK(&(_nt)->nt_nodelock)
36#define IEEE80211_NODE_UNLOCK_BH(_nt) A_MUTEX_UNLOCK(&(_nt)->nt_nodelock)
37#define IEEE80211_NODE_LOCK_ASSERT(_nt)
38
39/*
40 * Node reference counting definitions.
41 *
42 * ieee80211_node_initref initialize the reference count to 1
43 * ieee80211_node_incref add a reference
44 * ieee80211_node_decref remove a reference
45 * ieee80211_node_dectestref remove a reference and return 1 if this
46 * is the last reference, otherwise 0
47 * ieee80211_node_refcnt reference count for printing (only)
48 */
49#define ieee80211_node_initref(_ni) ((_ni)->ni_refcnt = 1)
50#define ieee80211_node_incref(_ni) ((_ni)->ni_refcnt++)
51#define ieee80211_node_decref(_ni) ((_ni)->ni_refcnt--)
52#define ieee80211_node_dectestref(_ni) (((_ni)->ni_refcnt--) == 1)
53#define ieee80211_node_refcnt(_ni) ((_ni)->ni_refcnt)
54
55#define IEEE80211_NODE_HASHSIZE 32
56/* simple hash is enough for variation of macaddr */
57#define IEEE80211_NODE_HASH(addr) \
58 (((const u8 *)(addr))[IEEE80211_ADDR_LEN - 1] % \
59 IEEE80211_NODE_HASHSIZE)
60
61/*
62 * Table of ieee80211_node instances. Each ieee80211com
63 * has at least one for holding the scan candidates.
64 * When operating as an access point or in ibss mode there
65 * is a second table for associated stations or neighbors.
66 */
67struct ieee80211_node_table {
68 void *nt_wmip; /* back reference */
69 A_MUTEX_T nt_nodelock; /* on node table */
70 struct bss *nt_node_first; /* information of all nodes */
71 struct bss *nt_node_last; /* information of all nodes */
72 struct bss *nt_hash[IEEE80211_NODE_HASHSIZE];
73 const char *nt_name; /* for debugging */
74 u32 nt_scangen; /* gen# for timeout scan */
75#ifdef THREAD_X
76 A_TIMER nt_inact_timer;
77 u8 isTimerArmed; /* is the node timer armed */
78#endif
79 u32 nt_nodeAge; /* node aging time */
80#ifdef OS_ROAM_MANAGEMENT
81 u32 nt_si_gen; /* gen# for scan indication*/
82#endif
83};
84
85#ifdef THREAD_X
86#define WLAN_NODE_INACT_TIMEOUT_MSEC 20000
87#else
88#define WLAN_NODE_INACT_TIMEOUT_MSEC 120000
89#endif
90
91#define WLAN_NODE_INACT_CNT 4
92
93#endif /* _IEEE80211_NODE_H_ */
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c
deleted file mode 100644
index 0fe5f4b1346..00000000000
--- a/drivers/staging/ath6kl/wlan/src/wlan_node.c
+++ /dev/null
@@ -1,636 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="wlan_node.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// IEEE 802.11 node handling support.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#include <a_config.h>
26#include <athdefs.h>
27#include <a_osapi.h>
28#define ATH_MODULE_NAME wlan
29#include <a_debug.h>
30#include "htc.h"
31#include "htc_api.h"
32#include <wmi.h>
33#include <ieee80211.h>
34#include <wlan_api.h>
35#include <wmi_api.h>
36#include <ieee80211_node.h>
37
38#define ATH_DEBUG_WLAN ATH_DEBUG_MAKE_MODULE_MASK(0)
39
40#ifdef ATH_DEBUG_MODULE
41
42static struct ath_debug_mask_description wlan_debug_desc[] = {
43 { ATH_DEBUG_WLAN , "General WLAN Node Tracing"},
44};
45
46ATH_DEBUG_INSTANTIATE_MODULE_VAR(wlan,
47 "wlan",
48 "WLAN Node Management",
49 ATH_DEBUG_MASK_DEFAULTS,
50 ATH_DEBUG_DESCRIPTION_COUNT(wlan_debug_desc),
51 wlan_debug_desc);
52
53#endif
54
55#ifdef THREAD_X
56static void wlan_node_timeout(unsigned long arg);
57#endif
58
59static bss_t * _ieee80211_find_node (struct ieee80211_node_table *nt,
60 const u8 *macaddr);
61
62bss_t *
63wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size)
64{
65 bss_t *ni;
66
67 ni = A_MALLOC_NOWAIT(sizeof(bss_t));
68
69 if (ni != NULL) {
70 if (wh_size)
71 {
72 ni->ni_buf = A_MALLOC_NOWAIT(wh_size);
73 if (ni->ni_buf == NULL) {
74 kfree(ni);
75 ni = NULL;
76 return ni;
77 }
78 }
79 } else {
80 return ni;
81 }
82
83 /* Make sure our lists are clean */
84 ni->ni_list_next = NULL;
85 ni->ni_list_prev = NULL;
86 ni->ni_hash_next = NULL;
87 ni->ni_hash_prev = NULL;
88
89 //
90 // ni_scangen never initialized before and during suspend/resume of winmobile,
91 // that some junk has been stored in this, due to this scan list didn't properly updated
92 //
93 ni->ni_scangen = 0;
94
95#ifdef OS_ROAM_MANAGEMENT
96 ni->ni_si_gen = 0;
97#endif
98
99 return ni;
100}
101
102void
103wlan_node_free(bss_t *ni)
104{
105 if (ni->ni_buf != NULL) {
106 kfree(ni->ni_buf);
107 }
108 kfree(ni);
109}
110
111void
112wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,
113 const u8 *macaddr)
114{
115 int hash;
116 u32 timeoutValue = 0;
117
118 memcpy(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN);
119 hash = IEEE80211_NODE_HASH (macaddr);
120 ieee80211_node_initref (ni); /* mark referenced */
121
122 timeoutValue = nt->nt_nodeAge;
123
124 ni->ni_tstamp = A_GET_MS (0);
125 ni->ni_actcnt = WLAN_NODE_INACT_CNT;
126
127 IEEE80211_NODE_LOCK_BH(nt);
128
129 /* Insert at the end of the node list */
130 ni->ni_list_next = NULL;
131 ni->ni_list_prev = nt->nt_node_last;
132 if(nt->nt_node_last != NULL)
133 {
134 nt->nt_node_last->ni_list_next = ni;
135 }
136 nt->nt_node_last = ni;
137 if(nt->nt_node_first == NULL)
138 {
139 nt->nt_node_first = ni;
140 }
141
142 /* Insert into the hash list i.e. the bucket */
143 if((ni->ni_hash_next = nt->nt_hash[hash]) != NULL)
144 {
145 nt->nt_hash[hash]->ni_hash_prev = ni;
146 }
147 ni->ni_hash_prev = NULL;
148 nt->nt_hash[hash] = ni;
149
150#ifdef THREAD_X
151 if (!nt->isTimerArmed) {
152 A_TIMEOUT_MS(&nt->nt_inact_timer, timeoutValue, 0);
153 nt->isTimerArmed = true;
154 }
155#endif
156
157 IEEE80211_NODE_UNLOCK_BH(nt);
158}
159
160static bss_t *
161_ieee80211_find_node(struct ieee80211_node_table *nt,
162 const u8 *macaddr)
163{
164 bss_t *ni;
165 int hash;
166
167 IEEE80211_NODE_LOCK_ASSERT(nt);
168
169 hash = IEEE80211_NODE_HASH(macaddr);
170 for(ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
171 if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {
172 ieee80211_node_incref(ni); /* mark referenced */
173 return ni;
174 }
175 }
176 return NULL;
177}
178
179bss_t *
180wlan_find_node(struct ieee80211_node_table *nt, const u8 *macaddr)
181{
182 bss_t *ni;
183
184 IEEE80211_NODE_LOCK(nt);
185 ni = _ieee80211_find_node(nt, macaddr);
186 IEEE80211_NODE_UNLOCK(nt);
187 return ni;
188}
189
190/*
191 * Reclaim a node. If this is the last reference count then
192 * do the normal free work. Otherwise remove it from the node
193 * table and mark it gone by clearing the back-reference.
194 */
195void
196wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni)
197{
198 IEEE80211_NODE_LOCK(nt);
199
200 if(ni->ni_list_prev == NULL)
201 {
202 /* First in list so fix the list head */
203 nt->nt_node_first = ni->ni_list_next;
204 }
205 else
206 {
207 ni->ni_list_prev->ni_list_next = ni->ni_list_next;
208 }
209
210 if(ni->ni_list_next == NULL)
211 {
212 /* Last in list so fix list tail */
213 nt->nt_node_last = ni->ni_list_prev;
214 }
215 else
216 {
217 ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
218 }
219
220 if(ni->ni_hash_prev == NULL)
221 {
222 /* First in list so fix the list head */
223 int hash;
224 hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
225 nt->nt_hash[hash] = ni->ni_hash_next;
226 }
227 else
228 {
229 ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
230 }
231
232 if(ni->ni_hash_next != NULL)
233 {
234 ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
235 }
236 wlan_node_free(ni);
237
238 IEEE80211_NODE_UNLOCK(nt);
239}
240
241static void
242wlan_node_dec_free(bss_t *ni)
243{
244 if (ieee80211_node_dectestref(ni)) {
245 wlan_node_free(ni);
246 }
247}
248
249void
250wlan_free_allnodes(struct ieee80211_node_table *nt)
251{
252 bss_t *ni;
253
254 while ((ni = nt->nt_node_first) != NULL) {
255 wlan_node_reclaim(nt, ni);
256 }
257}
258
259void
260wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,
261 void *arg)
262{
263 bss_t *ni;
264 u32 gen;
265
266 gen = ++nt->nt_scangen;
267
268 IEEE80211_NODE_LOCK(nt);
269 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
270 if (ni->ni_scangen != gen) {
271 ni->ni_scangen = gen;
272 (void) ieee80211_node_incref(ni);
273 (*f)(arg, ni);
274 wlan_node_dec_free(ni);
275 }
276 }
277 IEEE80211_NODE_UNLOCK(nt);
278}
279
280/*
281 * Node table support.
282 */
283void
284wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt)
285{
286 int i;
287
288 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN, ("node table = 0x%lx\n", (unsigned long)nt));
289 IEEE80211_NODE_LOCK_INIT(nt);
290
291 A_REGISTER_MODULE_DEBUG_INFO(wlan);
292
293 nt->nt_node_first = nt->nt_node_last = NULL;
294 for(i = 0; i < IEEE80211_NODE_HASHSIZE; i++)
295 {
296 nt->nt_hash[i] = NULL;
297 }
298
299#ifdef THREAD_X
300 A_INIT_TIMER(&nt->nt_inact_timer, wlan_node_timeout, nt);
301 nt->isTimerArmed = false;
302#endif
303 nt->nt_wmip = wmip;
304 nt->nt_nodeAge = WLAN_NODE_INACT_TIMEOUT_MSEC;
305
306 //
307 // nt_scangen never initialized before and during suspend/resume of winmobile,
308 // that some junk has been stored in this, due to this scan list didn't properly updated
309 //
310 nt->nt_scangen = 0;
311
312#ifdef OS_ROAM_MANAGEMENT
313 nt->nt_si_gen = 0;
314#endif
315}
316
317void
318wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge)
319{
320 nt->nt_nodeAge = nodeAge;
321 return;
322}
323void
324wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt)
325{
326#ifdef THREAD_X
327 bss_t *bss, *nextBss;
328 u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false;
329
330 wmi_get_current_bssid(nt->nt_wmip, myBssid);
331
332 bss = nt->nt_node_first;
333 while (bss != NULL)
334 {
335 nextBss = bss->ni_list_next;
336 if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
337 {
338 /*
339 * free up all but the current bss - if set
340 */
341 wlan_node_reclaim(nt, bss);
342
343 }
344 bss = nextBss;
345 }
346#else
347 bss_t *bss, *nextBss;
348 u8 myBssid[IEEE80211_ADDR_LEN];
349 u32 timeoutValue = 0;
350 u32 now = A_GET_MS(0);
351 timeoutValue = nt->nt_nodeAge;
352
353 wmi_get_current_bssid(nt->nt_wmip, myBssid);
354
355 bss = nt->nt_node_first;
356 while (bss != NULL)
357 {
358 nextBss = bss->ni_list_next;
359 if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
360 {
361
362 if (((now - bss->ni_tstamp) > timeoutValue) || --bss->ni_actcnt == 0)
363 {
364 /*
365 * free up all but the current bss - if set
366 */
367 wlan_node_reclaim(nt, bss);
368 }
369 }
370 bss = nextBss;
371 }
372#endif
373}
374
375#ifdef THREAD_X
376static void
377wlan_node_timeout (unsigned long arg)
378{
379 struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg;
380 bss_t *bss, *nextBss;
381 u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false;
382 u32 timeoutValue = 0;
383 u32 now = A_GET_MS(0);
384
385 timeoutValue = nt->nt_nodeAge;
386
387 wmi_get_current_bssid(nt->nt_wmip, myBssid);
388
389 bss = nt->nt_node_first;
390 while (bss != NULL)
391 {
392 nextBss = bss->ni_list_next;
393 if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
394 {
395
396 if ((now - bss->ni_tstamp) > timeoutValue)
397 {
398 /*
399 * free up all but the current bss - if set
400 */
401 wlan_node_reclaim(nt, bss);
402 }
403 else
404 {
405 /*
406 * Re-arm timer, only when we have a bss other than
407 * current bss AND it is not aged-out.
408 */
409 reArmTimer = true;
410 }
411 }
412 bss = nextBss;
413 }
414
415 if (reArmTimer)
416 A_TIMEOUT_MS (&nt->nt_inact_timer, timeoutValue, 0);
417
418 nt->isTimerArmed = reArmTimer;
419}
420#endif
421
422void
423wlan_node_table_cleanup(struct ieee80211_node_table *nt)
424{
425#ifdef THREAD_X
426 A_UNTIMEOUT(&nt->nt_inact_timer);
427 A_DELETE_TIMER(&nt->nt_inact_timer);
428#endif
429 wlan_free_allnodes(nt);
430 IEEE80211_NODE_LOCK_DESTROY(nt);
431}
432
433bss_t *
434wlan_find_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
435 u32 ssidLength, bool bIsWPA2, bool bMatchSSID)
436{
437 bss_t *ni = NULL;
438 u8 *pIESsid = NULL;
439
440 IEEE80211_NODE_LOCK (nt);
441
442 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
443 pIESsid = ni->ni_cie.ie_ssid;
444 if (pIESsid[1] <= 32) {
445
446 // Step 1 : Check SSID
447 if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) {
448
449 //
450 // Step 2.1 : Check MatchSSID is true, if so, return Matched SSID
451 // Profile, otherwise check whether WPA2 or WPA
452 //
453 if (true == bMatchSSID) {
454 ieee80211_node_incref (ni); /* mark referenced */
455 IEEE80211_NODE_UNLOCK (nt);
456 return ni;
457 }
458
459 // Step 2 : if SSID matches, check WPA or WPA2
460 if (true == bIsWPA2 && NULL != ni->ni_cie.ie_rsn) {
461 ieee80211_node_incref (ni); /* mark referenced */
462 IEEE80211_NODE_UNLOCK (nt);
463 return ni;
464 }
465 if (false == bIsWPA2 && NULL != ni->ni_cie.ie_wpa) {
466 ieee80211_node_incref(ni); /* mark referenced */
467 IEEE80211_NODE_UNLOCK (nt);
468 return ni;
469 }
470 }
471 }
472 }
473
474 IEEE80211_NODE_UNLOCK (nt);
475
476 return NULL;
477}
478
479void
480wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni)
481{
482 IEEE80211_NODE_LOCK (nt);
483 wlan_node_dec_free (ni);
484 IEEE80211_NODE_UNLOCK (nt);
485}
486
487void
488wlan_node_remove_core (struct ieee80211_node_table *nt, bss_t *ni)
489{
490 if(ni->ni_list_prev == NULL)
491 {
492 /* First in list so fix the list head */
493 nt->nt_node_first = ni->ni_list_next;
494 }
495 else
496 {
497 ni->ni_list_prev->ni_list_next = ni->ni_list_next;
498 }
499
500 if(ni->ni_list_next == NULL)
501 {
502 /* Last in list so fix list tail */
503 nt->nt_node_last = ni->ni_list_prev;
504 }
505 else
506 {
507 ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
508 }
509
510 if(ni->ni_hash_prev == NULL)
511 {
512 /* First in list so fix the list head */
513 int hash;
514 hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
515 nt->nt_hash[hash] = ni->ni_hash_next;
516 }
517 else
518 {
519 ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
520 }
521
522 if(ni->ni_hash_next != NULL)
523 {
524 ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
525 }
526}
527
528bss_t *
529wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid)
530{
531 bss_t *bss, *nextBss;
532
533 IEEE80211_NODE_LOCK(nt);
534
535 bss = nt->nt_node_first;
536
537 while (bss != NULL)
538 {
539 nextBss = bss->ni_list_next;
540
541 if (memcmp(bssid, bss->ni_macaddr, 6) == 0)
542 {
543 wlan_node_remove_core (nt, bss);
544 IEEE80211_NODE_UNLOCK(nt);
545 return bss;
546 }
547
548 bss = nextBss;
549 }
550
551 IEEE80211_NODE_UNLOCK(nt);
552 return NULL;
553}
554
555bss_t *
556wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
557 u32 ssidLength, u32 dot11AuthMode, u32 authMode,
558 u32 pairwiseCryptoType, u32 grpwiseCryptoTyp)
559{
560 bss_t *ni = NULL;
561 bss_t *best_ni = NULL;
562 u8 *pIESsid = NULL;
563
564 IEEE80211_NODE_LOCK (nt);
565
566 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
567 pIESsid = ni->ni_cie.ie_ssid;
568 if (pIESsid[1] <= 32) {
569
570 // Step 1 : Check SSID
571 if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) {
572
573 if (ni->ni_cie.ie_capInfo & 0x10)
574 {
575
576 if ((NULL != ni->ni_cie.ie_rsn) && (WPA2_PSK_AUTH == authMode))
577 {
578 /* WPA2 */
579 if (NULL == best_ni)
580 {
581 best_ni = ni;
582 }
583 else if (ni->ni_rssi > best_ni->ni_rssi)
584 {
585 best_ni = ni;
586 }
587 }
588 else if ((NULL != ni->ni_cie.ie_wpa) && (WPA_PSK_AUTH == authMode))
589 {
590 /* WPA */
591 if (NULL == best_ni)
592 {
593 best_ni = ni;
594 }
595 else if (ni->ni_rssi > best_ni->ni_rssi)
596 {
597 best_ni = ni;
598 }
599 }
600 else if (WEP_CRYPT == pairwiseCryptoType)
601 {
602 /* WEP */
603 if (NULL == best_ni)
604 {
605 best_ni = ni;
606 }
607 else if (ni->ni_rssi > best_ni->ni_rssi)
608 {
609 best_ni = ni;
610 }
611 }
612 }
613 else
614 {
615 /* open AP */
616 if ((OPEN_AUTH == authMode) && (NONE_CRYPT == pairwiseCryptoType))
617 {
618 if (NULL == best_ni)
619 {
620 best_ni = ni;
621 }
622 else if (ni->ni_rssi > best_ni->ni_rssi)
623 {
624 best_ni = ni;
625 }
626 }
627 }
628 }
629 }
630 }
631
632 IEEE80211_NODE_UNLOCK (nt);
633
634 return best_ni;
635}
636
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c
deleted file mode 100644
index 07b8313b16e..00000000000
--- a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c
+++ /dev/null
@@ -1,199 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="wlan_recv_beacon.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// IEEE 802.11 input handling.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25
26#include "a_config.h"
27#include "athdefs.h"
28#include "a_osapi.h"
29#include <wmi.h>
30#include <ieee80211.h>
31#include <wlan_api.h>
32
33#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \
34 if ((_len) < (_minlen)) { \
35 return A_EINVAL; \
36 } \
37} while (0)
38
39#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
40 if ((__elem) == NULL) { \
41 return A_EINVAL; \
42 } \
43 if ((__elem)[1] > (__maxlen)) { \
44 return A_EINVAL; \
45 } \
46} while (0)
47
48
49/* unaligned little endian access */
50#define LE_READ_2(p) \
51 ((u16) \
52 ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8)))
53
54#define LE_READ_4(p) \
55 ((u32) \
56 ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \
57 (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24)))
58
59
60static int __inline
61iswpaoui(const u8 *frm)
62{
63 return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
64}
65
66static int __inline
67iswmmoui(const u8 *frm)
68{
69 return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
70}
71
72/* unused functions for now */
73#if 0
74static int __inline
75iswmmparam(const u8 *frm)
76{
77 return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
78}
79
80static int __inline
81iswmminfo(const u8 *frm)
82{
83 return frm[1] > 5 && frm[6] == WMM_INFO_OUI_SUBTYPE;
84}
85#endif
86
87static int __inline
88isatherosoui(const u8 *frm)
89{
90 return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
91}
92
93static int __inline
94iswscoui(const u8 *frm)
95{
96 return frm[1] > 3 && LE_READ_4(frm+2) == ((0x04<<24)|WPA_OUI);
97}
98
99int
100wlan_parse_beacon(u8 *buf, int framelen, struct ieee80211_common_ie *cie)
101{
102 u8 *frm, *efrm;
103 u8 elemid_ssid = false;
104
105 frm = buf;
106 efrm = (u8 *) (frm + framelen);
107
108 /*
109 * beacon/probe response frame format
110 * [8] time stamp
111 * [2] beacon interval
112 * [2] capability information
113 * [tlv] ssid
114 * [tlv] supported rates
115 * [tlv] country information
116 * [tlv] parameter set (FH/DS)
117 * [tlv] erp information
118 * [tlv] extended supported rates
119 * [tlv] WMM
120 * [tlv] WPA or RSN
121 * [tlv] Atheros Advanced Capabilities
122 */
123 IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
124 A_MEMZERO(cie, sizeof(*cie));
125
126 cie->ie_tstamp = frm; frm += 8;
127 cie->ie_beaconInt = A_LE2CPU16(*(u16 *)frm); frm += 2;
128 cie->ie_capInfo = A_LE2CPU16(*(u16 *)frm); frm += 2;
129 cie->ie_chan = 0;
130
131 while (frm < efrm) {
132 switch (*frm) {
133 case IEEE80211_ELEMID_SSID:
134 if (!elemid_ssid) {
135 cie->ie_ssid = frm;
136 elemid_ssid = true;
137 }
138 break;
139 case IEEE80211_ELEMID_RATES:
140 cie->ie_rates = frm;
141 break;
142 case IEEE80211_ELEMID_COUNTRY:
143 cie->ie_country = frm;
144 break;
145 case IEEE80211_ELEMID_FHPARMS:
146 break;
147 case IEEE80211_ELEMID_DSPARMS:
148 cie->ie_chan = frm[2];
149 break;
150 case IEEE80211_ELEMID_TIM:
151 cie->ie_tim = frm;
152 break;
153 case IEEE80211_ELEMID_IBSSPARMS:
154 break;
155 case IEEE80211_ELEMID_XRATES:
156 cie->ie_xrates = frm;
157 break;
158 case IEEE80211_ELEMID_ERP:
159 if (frm[1] != 1) {
160 //A_PRINTF("Discarding ERP Element - Bad Len\n");
161 return A_EINVAL;
162 }
163 cie->ie_erp = frm[2];
164 break;
165 case IEEE80211_ELEMID_RSN:
166 cie->ie_rsn = frm;
167 break;
168 case IEEE80211_ELEMID_HTCAP_ANA:
169 cie->ie_htcap = frm;
170 break;
171 case IEEE80211_ELEMID_HTINFO_ANA:
172 cie->ie_htop = frm;
173 break;
174#ifdef WAPI_ENABLE
175 case IEEE80211_ELEMID_WAPI:
176 cie->ie_wapi = frm;
177 break;
178#endif
179 case IEEE80211_ELEMID_VENDOR:
180 if (iswpaoui(frm)) {
181 cie->ie_wpa = frm;
182 } else if (iswmmoui(frm)) {
183 cie->ie_wmm = frm;
184 } else if (isatherosoui(frm)) {
185 cie->ie_ath = frm;
186 } else if(iswscoui(frm)) {
187 cie->ie_wsc = frm;
188 }
189 break;
190 default:
191 break;
192 }
193 frm += frm[1] + 2;
194 }
195 IEEE80211_VERIFY_ELEMENT(cie->ie_rates, IEEE80211_RATE_MAXSIZE);
196 IEEE80211_VERIFY_ELEMENT(cie->ie_ssid, IEEE80211_NWID_LEN);
197
198 return 0;
199}
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_utils.c b/drivers/staging/ath6kl/wlan/src/wlan_utils.c
deleted file mode 100644
index bc91599d9bf..00000000000
--- a/drivers/staging/ath6kl/wlan/src/wlan_utils.c
+++ /dev/null
@@ -1,58 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="wlan_utils.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This module implements frequently used wlan utilies
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#include <a_config.h>
26#include <athdefs.h>
27#include <a_osapi.h>
28
29/*
30 * converts ieee channel number to frequency
31 */
32u16 wlan_ieee2freq(int chan)
33{
34 if (chan == 14) {
35 return 2484;
36 }
37 if (chan < 14) { /* 0-13 */
38 return (2407 + (chan*5));
39 }
40 if (chan < 27) { /* 15-26 */
41 return (2512 + ((chan-15)*20));
42 }
43 return (5000 + (chan*5));
44}
45
46/*
47 * Converts MHz frequency to IEEE channel number.
48 */
49u32 wlan_freq2ieee(u16 freq)
50{
51 if (freq == 2484)
52 return 14;
53 if (freq < 2484)
54 return (freq - 2407) / 5;
55 if (freq < 5000)
56 return 15 + ((freq - 2512) / 20);
57 return (freq - 5000) / 5;
58}
diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c
deleted file mode 100644
index c7b5e5cf9df..00000000000
--- a/drivers/staging/ath6kl/wmi/wmi.c
+++ /dev/null
@@ -1,6444 +0,0 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// This module implements the hardware independent layer of the
21// Wireless Module Interface (WMI) protocol.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25
26#include <a_config.h>
27#include <athdefs.h>
28#include <a_osapi.h>
29#include "htc.h"
30#include "htc_api.h"
31#include "wmi.h"
32#include <wlan_api.h>
33#include <wmi_api.h>
34#include <ieee80211.h>
35#include <ieee80211_node.h>
36#include "dset_api.h"
37#include "wmi_host.h"
38#include "a_drv.h"
39#include "a_drv_api.h"
40#define ATH_MODULE_NAME wmi
41#include "a_debug.h"
42#include "dbglog_api.h"
43#include "roaming.h"
44#include "cfg80211.h"
45
46#define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0)
47
48#ifdef ATH_DEBUG_MODULE
49
50static struct ath_debug_mask_description wmi_debug_desc[] = {
51 { ATH_DEBUG_WMI , "General WMI Tracing"},
52};
53
54ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi,
55 "wmi",
56 "Wireless Module Interface",
57 ATH_DEBUG_MASK_DEFAULTS,
58 ATH_DEBUG_DESCRIPTION_COUNT(wmi_debug_desc),
59 wmi_debug_desc);
60
61#endif
62
63#ifndef REXOS
64#define DBGARG _A_FUNCNAME_
65#define DBGFMT "%s() : "
66#define DBG_WMI ATH_DEBUG_WMI
67#define DBG_ERROR ATH_DEBUG_ERR
68#define DBG_WMI2 ATH_DEBUG_WMI
69#define A_DPRINTF AR_DEBUG_PRINTF
70#endif
71
72static int wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len);
73
74static int wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap,
75 int len);
76static int wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap,
77 int len);
78
79static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap,
80 int len);
81static int wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap,
82 int len);
83static int wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap,
84 int len);
85static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap,
86 int len);
87static int wmi_sync_point(struct wmi_t *wmip);
88
89static int wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap,
90 int len);
91static int wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap,
92 int len);
93static int wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap,
94 int len);
95static int wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap,
96 int len);
97static int wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len);
98static int wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap,
99 int len);
100
101static int wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap,
102 int len);
103#ifdef CONFIG_HOST_DSET_SUPPORT
104static int wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len);
105static int wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap,
106 int len);
107#endif /* CONFIG_HOST_DSET_SUPPORT */
108
109
110static int wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap,
111 int len);
112static int wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
113static int wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
114static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
115static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len);
116static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
117static int wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len);
118static int wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len);
119static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap,
120 int len);
121static int wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap,
122 int len);
123static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap,
124 int len);
125static int
126wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
127
128static int
129wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
130
131
132#ifdef CONFIG_HOST_TCMD_SUPPORT
133static int
134wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len);
135#endif
136
137static int
138wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
139
140static int
141wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
142
143static int
144wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
145
146static bool
147wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex);
148
149static int
150wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
151
152static int
153wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len);
154
155static int wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len);
156
157int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
158 WMI_SYNC_FLAG syncflag);
159
160u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size);
161u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size);
162
163void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
164void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
165static int wmi_send_rssi_threshold_params(struct wmi_t *wmip,
166 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
167static int wmi_send_snr_threshold_params(struct wmi_t *wmip,
168 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
169#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
170static int
171wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len);
172#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
173
174static int wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap,
175 int len);
176static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,
177 int len);
178
179static int wmi_peer_node_event_rx (struct wmi_t *wmip, u8 *datap,
180 int len);
181static int wmi_addba_req_event_rx(struct wmi_t *, u8 *, int);
182static int wmi_addba_resp_event_rx(struct wmi_t *, u8 *, int);
183static int wmi_delba_req_event_rx(struct wmi_t *, u8 *, int);
184static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len);
185static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, u8 *datap, int len);
186static int wmi_hci_event_rx(struct wmi_t *, u8 *, int);
187
188#ifdef WAPI_ENABLE
189static int wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,
190 int len);
191#endif
192
193#if defined(UNDER_CE)
194#if defined(NDIS51_MINIPORT)
195unsigned int processDot11Hdr = 0;
196#else
197unsigned int processDot11Hdr = 1;
198#endif
199#else
200extern unsigned int processDot11Hdr;
201#endif
202
203int wps_enable;
204static const s32 wmi_rateTable[][2] = {
205 //{W/O SGI, with SGI}
206 {1000, 1000},
207 {2000, 2000},
208 {5500, 5500},
209 {11000, 11000},
210 {6000, 6000},
211 {9000, 9000},
212 {12000, 12000},
213 {18000, 18000},
214 {24000, 24000},
215 {36000, 36000},
216 {48000, 48000},
217 {54000, 54000},
218 {6500, 7200},
219 {13000, 14400},
220 {19500, 21700},
221 {26000, 28900},
222 {39000, 43300},
223 {52000, 57800},
224 {58500, 65000},
225 {65000, 72200},
226 {13500, 15000},
227 {27000, 30000},
228 {40500, 45000},
229 {54000, 60000},
230 {81000, 90000},
231 {108000, 120000},
232 {121500, 135000},
233 {135000, 150000},
234 {0, 0}};
235
236#define MODE_A_SUPPORT_RATE_START ((s32) 4)
237#define MODE_A_SUPPORT_RATE_STOP ((s32) 11)
238
239#define MODE_GONLY_SUPPORT_RATE_START MODE_A_SUPPORT_RATE_START
240#define MODE_GONLY_SUPPORT_RATE_STOP MODE_A_SUPPORT_RATE_STOP
241
242#define MODE_B_SUPPORT_RATE_START ((s32) 0)
243#define MODE_B_SUPPORT_RATE_STOP ((s32) 3)
244
245#define MODE_G_SUPPORT_RATE_START ((s32) 0)
246#define MODE_G_SUPPORT_RATE_STOP ((s32) 11)
247
248#define MODE_GHT20_SUPPORT_RATE_START ((s32) 0)
249#define MODE_GHT20_SUPPORT_RATE_STOP ((s32) 19)
250
251#define MAX_NUMBER_OF_SUPPORT_RATES (MODE_GHT20_SUPPORT_RATE_STOP + 1)
252
253/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
254const u8 up_to_ac[]= {
255 WMM_AC_BE,
256 WMM_AC_BK,
257 WMM_AC_BK,
258 WMM_AC_BE,
259 WMM_AC_VI,
260 WMM_AC_VI,
261 WMM_AC_VO,
262 WMM_AC_VO,
263 };
264
265/* This stuff is used when we want a simple layer-3 visibility */
266typedef PREPACK struct _iphdr {
267 u8 ip_ver_hdrlen; /* version and hdr length */
268 u8 ip_tos; /* type of service */
269 u16 ip_len; /* total length */
270 u16 ip_id; /* identification */
271 s16 ip_off; /* fragment offset field */
272#define IP_DF 0x4000 /* dont fragment flag */
273#define IP_MF 0x2000 /* more fragments flag */
274#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
275 u8 ip_ttl; /* time to live */
276 u8 ip_p; /* protocol */
277 u16 ip_sum; /* checksum */
278 u8 ip_src[4]; /* source and dest address */
279 u8 ip_dst[4];
280} POSTPACK iphdr;
281
282static s16 rssi_event_value = 0;
283static s16 snr_event_value = 0;
284
285bool is_probe_ssid = false;
286
287void *
288wmi_init(void *devt)
289{
290 struct wmi_t *wmip;
291
292 A_REGISTER_MODULE_DEBUG_INFO(wmi);
293
294 wmip = A_MALLOC (sizeof(struct wmi_t));
295 if (wmip == NULL) {
296 return (NULL);
297 }
298 A_MEMZERO(wmip, sizeof(struct wmi_t ));
299#ifdef THREAD_X
300 INIT_WMI_LOCK(wmip);
301#else
302 A_MUTEX_INIT(&wmip->wmi_lock);
303#endif
304 wmip->wmi_devt = devt;
305 wlan_node_table_init(wmip, &wmip->wmi_scan_table);
306 wmi_qos_state_init(wmip);
307
308 wmip->wmi_powerMode = REC_POWER;
309 wmip->wmi_phyMode = WMI_11G_MODE;
310
311 wmip->wmi_pair_crypto_type = NONE_CRYPT;
312 wmip->wmi_grp_crypto_type = NONE_CRYPT;
313
314 wmip->wmi_ht_allowed[A_BAND_24GHZ] = 1;
315 wmip->wmi_ht_allowed[A_BAND_5GHZ] = 1;
316
317 return (wmip);
318}
319
320void
321wmi_qos_state_init(struct wmi_t *wmip)
322{
323 u8 i;
324
325 if (wmip == NULL) {
326 return;
327 }
328 LOCK_WMI(wmip);
329
330 /* Initialize QoS States */
331 wmip->wmi_numQoSStream = 0;
332
333 wmip->wmi_fatPipeExists = 0;
334
335 for (i=0; i < WMM_NUM_AC; i++) {
336 wmip->wmi_streamExistsForAC[i]=0;
337 }
338
339 UNLOCK_WMI(wmip);
340
341 A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1);
342}
343
344void
345wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid)
346{
347 A_ASSERT( eid != ENDPOINT_UNUSED);
348 wmip->wmi_endpoint_id = eid;
349}
350
351HTC_ENDPOINT_ID
352wmi_get_control_ep(struct wmi_t * wmip)
353{
354 return(wmip->wmi_endpoint_id);
355}
356
357void
358wmi_shutdown(struct wmi_t *wmip)
359{
360 if (wmip != NULL) {
361 wlan_node_table_cleanup(&wmip->wmi_scan_table);
362 if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) {
363#ifdef THREAD_X
364 DELETE_WMI_LOCK(&wmip);
365#else
366 A_MUTEX_DELETE(&wmip->wmi_lock);
367#endif
368 }
369 kfree(wmip);
370 }
371}
372
373/*
374 * performs DIX to 802.3 encapsulation for transmit packets.
375 * uses passed in buffer. Returns buffer or NULL if failed.
376 * Assumes the entire DIX header is contigous and that there is
377 * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
378 */
379int
380wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf)
381{
382 u8 *datap;
383 u16 typeorlen;
384 ATH_MAC_HDR macHdr;
385 ATH_LLC_SNAP_HDR *llcHdr;
386
387 A_ASSERT(osbuf != NULL);
388
389 if (A_NETBUF_HEADROOM(osbuf) <
390 (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
391 {
392 return A_NO_MEMORY;
393 }
394
395 datap = A_NETBUF_DATA(osbuf);
396
397 typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
398
399 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
400 /*
401 * packet is already in 802.3 format - return success
402 */
403 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
404 return (0);
405 }
406
407 /*
408 * Save mac fields and length to be inserted later
409 */
410 memcpy(macHdr.dstMac, datap, ATH_MAC_LEN);
411 memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
412 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
413 sizeof(ATH_LLC_SNAP_HDR));
414
415 /*
416 * Make room for LLC+SNAP headers
417 */
418 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
419 return A_NO_MEMORY;
420 }
421 datap = A_NETBUF_DATA(osbuf);
422
423 memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR));
424
425 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
426 llcHdr->dsap = 0xAA;
427 llcHdr->ssap = 0xAA;
428 llcHdr->cntl = 0x03;
429 llcHdr->orgCode[0] = 0x0;
430 llcHdr->orgCode[1] = 0x0;
431 llcHdr->orgCode[2] = 0x0;
432 llcHdr->etherType = typeorlen;
433
434 return (0);
435}
436
437int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS)
438{
439 switch(*pVersion){
440 case 0:
441 return (0);
442 case WMI_META_VERSION_1:
443 {
444 WMI_TX_META_V1 *pV1= NULL;
445 A_ASSERT(osbuf != NULL);
446 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) {
447 return A_NO_MEMORY;
448 }
449
450 pV1 = (WMI_TX_META_V1 *)A_NETBUF_DATA(osbuf);
451 /* the pktID is used in conjunction with txComplete messages
452 * allowing the target to notify which tx requests have been
453 * completed and how. */
454 pV1->pktID = 0;
455 /* the ratePolicyID allows the host to specify which rate policy
456 * to use for transmitting this packet. 0 means use default behavior. */
457 pV1->ratePolicyID = 0;
458 A_ASSERT(pVersion != NULL);
459 /* the version must be used to populate the meta field of the WMI_DATA_HDR */
460 *pVersion = WMI_META_VERSION_1;
461 return (0);
462 }
463 case WMI_META_VERSION_2:
464 {
465 WMI_TX_META_V2 *pV2 ;
466 A_ASSERT(osbuf != NULL);
467 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) {
468 return A_NO_MEMORY;
469 }
470 pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf);
471 memcpy(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2));
472 return (0);
473 }
474 default:
475 return (0);
476 }
477}
478
479/* Adds a WMI data header */
480int
481wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData,
482 WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS)
483{
484 WMI_DATA_HDR *dtHdr;
485// u8 metaVersion = 0;
486 int status;
487
488 A_ASSERT(osbuf != NULL);
489
490 /* adds the meta data field after the wmi data hdr. If metaVersion
491 * is returns 0 then no meta field was added. */
492 if ((status = wmi_meta_add(wmip, osbuf, &metaVersion,pTxMetaS)) != 0) {
493 return status;
494 }
495
496 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) {
497 return A_NO_MEMORY;
498 }
499
500 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
501 A_MEMZERO(dtHdr, sizeof(WMI_DATA_HDR));
502
503 WMI_DATA_HDR_SET_MSG_TYPE(dtHdr, msgType);
504 WMI_DATA_HDR_SET_DATA_TYPE(dtHdr, data_type);
505
506 if (bMoreData) {
507 WMI_DATA_HDR_SET_MORE_BIT(dtHdr);
508 }
509
510 WMI_DATA_HDR_SET_META(dtHdr, metaVersion);
511
512 dtHdr->info3 = 0;
513
514 return (0);
515}
516
517
518u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled)
519{
520 u8 *datap;
521 u8 trafficClass = WMM_AC_BE;
522 u16 ipType = IP_ETHERTYPE;
523 WMI_DATA_HDR *dtHdr;
524 u8 streamExists = 0;
525 u8 userPriority;
526 u32 hdrsize, metasize;
527 ATH_LLC_SNAP_HDR *llcHdr;
528
529 WMI_CREATE_PSTREAM_CMD cmd;
530
531 A_ASSERT(osbuf != NULL);
532
533 //
534 // Initialize header size
535 //
536 hdrsize = 0;
537
538 datap = A_NETBUF_DATA(osbuf);
539 dtHdr = (WMI_DATA_HDR *)datap;
540 metasize = (WMI_DATA_HDR_GET_META(dtHdr))? WMI_MAX_TX_META_SZ : 0;
541
542 if (!wmmEnabled)
543 {
544 /* If WMM is disabled all traffic goes as BE traffic */
545 userPriority = 0;
546 }
547 else
548 {
549 if (processDot11Hdr)
550 {
551 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
552 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
553 hdrsize);
554
555
556 }
557 else
558 {
559 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
560 sizeof(ATH_MAC_HDR));
561 }
562
563 if (llcHdr->etherType == A_CPU2BE16(ipType))
564 {
565 /* Extract the endpoint info from the TOS field in the IP header */
566
567 userPriority = wmi_determine_userPriority (((u8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR),layer2Priority);
568 }
569 else
570 {
571 userPriority = layer2Priority & 0x7;
572 }
573 }
574
575
576 /* workaround for WMM S5 */
577 if ((WMM_AC_VI == wmip->wmi_traffic_class) && ((5 == userPriority) || (4 == userPriority)))
578 {
579 userPriority = 1;
580 }
581
582 trafficClass = convert_userPriority_to_trafficClass(userPriority);
583
584 WMI_DATA_HDR_SET_UP(dtHdr, userPriority);
585 /* lower 3-bits are 802.1d priority */
586 //dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT;
587
588 LOCK_WMI(wmip);
589 streamExists = wmip->wmi_fatPipeExists;
590 UNLOCK_WMI(wmip);
591
592 if (!(streamExists & (1 << trafficClass)))
593 {
594
595 A_MEMZERO(&cmd, sizeof(cmd));
596 cmd.trafficClass = trafficClass;
597 cmd.userPriority = userPriority;
598 cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT;
599 /* Implicit streams are created with TSID 0xFF */
600
601 cmd.tsid = WMI_IMPLICIT_PSTREAM;
602 wmi_create_pstream_cmd(wmip, &cmd);
603 }
604
605 return trafficClass;
606}
607
608int
609wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode)
610{
611 u8 *datap;
612 u16 typeorlen;
613 ATH_MAC_HDR macHdr;
614 ATH_LLC_SNAP_HDR *llcHdr;
615 struct ieee80211_frame *wh;
616 u32 hdrsize;
617
618 A_ASSERT(osbuf != NULL);
619
620 if (A_NETBUF_HEADROOM(osbuf) <
621 (sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
622 {
623 return A_NO_MEMORY;
624 }
625
626 datap = A_NETBUF_DATA(osbuf);
627
628 typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
629
630 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
631/*
632 * packet is already in 802.3 format - return success
633 */
634 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
635 goto AddDot11Hdr;
636 }
637
638 /*
639 * Save mac fields and length to be inserted later
640 */
641 memcpy(macHdr.dstMac, datap, ATH_MAC_LEN);
642 memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
643 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
644 sizeof(ATH_LLC_SNAP_HDR));
645
646 // Remove the Ethernet hdr
647 A_NETBUF_PULL(osbuf, sizeof(ATH_MAC_HDR));
648 /*
649 * Make room for LLC+SNAP headers
650 */
651 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
652 return A_NO_MEMORY;
653 }
654 datap = A_NETBUF_DATA(osbuf);
655
656 llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
657 llcHdr->dsap = 0xAA;
658 llcHdr->ssap = 0xAA;
659 llcHdr->cntl = 0x03;
660 llcHdr->orgCode[0] = 0x0;
661 llcHdr->orgCode[1] = 0x0;
662 llcHdr->orgCode[2] = 0x0;
663 llcHdr->etherType = typeorlen;
664
665AddDot11Hdr:
666 /* Make room for 802.11 hdr */
667 if (wmip->wmi_is_wmm_enabled)
668 {
669 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
670 if (A_NETBUF_PUSH(osbuf, hdrsize) != 0)
671 {
672 return A_NO_MEMORY;
673 }
674 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
675 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_QOS;
676 }
677 else
678 {
679 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(u32));
680 if (A_NETBUF_PUSH(osbuf, hdrsize) != 0)
681 {
682 return A_NO_MEMORY;
683 }
684 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
685 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_DATA;
686 }
687 /* Setup the SA & DA */
688 IEEE80211_ADDR_COPY(wh->i_addr2, macHdr.srcMac);
689
690 if (mode == INFRA_NETWORK) {
691 IEEE80211_ADDR_COPY(wh->i_addr3, macHdr.dstMac);
692 }
693 else if (mode == ADHOC_NETWORK) {
694 IEEE80211_ADDR_COPY(wh->i_addr1, macHdr.dstMac);
695 }
696
697 return (0);
698}
699
700int
701wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf)
702{
703 u8 *datap;
704 struct ieee80211_frame *pwh,wh;
705 u8 type,subtype;
706 ATH_LLC_SNAP_HDR *llcHdr;
707 ATH_MAC_HDR macHdr;
708 u32 hdrsize;
709
710 A_ASSERT(osbuf != NULL);
711 datap = A_NETBUF_DATA(osbuf);
712
713 pwh = (struct ieee80211_frame *)datap;
714 type = pwh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
715 subtype = pwh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
716
717 memcpy((u8 *)&wh, datap, sizeof(struct ieee80211_frame));
718
719 /* strip off the 802.11 hdr*/
720 if (subtype == IEEE80211_FC0_SUBTYPE_QOS) {
721 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
722 A_NETBUF_PULL(osbuf, hdrsize);
723 } else if (subtype == IEEE80211_FC0_SUBTYPE_DATA) {
724 A_NETBUF_PULL(osbuf, sizeof(struct ieee80211_frame));
725 }
726
727 datap = A_NETBUF_DATA(osbuf);
728 llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
729
730 macHdr.typeOrLen = llcHdr->etherType;
731 A_MEMZERO(macHdr.dstMac, sizeof(macHdr.dstMac));
732 A_MEMZERO(macHdr.srcMac, sizeof(macHdr.srcMac));
733
734 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
735 case IEEE80211_FC1_DIR_NODS:
736 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
737 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
738 break;
739 case IEEE80211_FC1_DIR_TODS:
740 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr3);
741 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
742 break;
743 case IEEE80211_FC1_DIR_FROMDS:
744 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
745 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr3);
746 break;
747 case IEEE80211_FC1_DIR_DSTODS:
748 break;
749 }
750
751 // Remove the LLC Hdr.
752 A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR));
753
754 // Insert the ATH MAC hdr.
755
756 A_NETBUF_PUSH(osbuf, sizeof(ATH_MAC_HDR));
757 datap = A_NETBUF_DATA(osbuf);
758
759 memcpy (datap, &macHdr, sizeof(ATH_MAC_HDR));
760
761 return 0;
762}
763
764/*
765 * performs 802.3 to DIX encapsulation for received packets.
766 * Assumes the entire 802.3 header is contigous.
767 */
768int
769wmi_dot3_2_dix(void *osbuf)
770{
771 u8 *datap;
772 ATH_MAC_HDR macHdr;
773 ATH_LLC_SNAP_HDR *llcHdr;
774
775 A_ASSERT(osbuf != NULL);
776 datap = A_NETBUF_DATA(osbuf);
777
778 memcpy(&macHdr, datap, sizeof(ATH_MAC_HDR));
779 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
780 macHdr.typeOrLen = llcHdr->etherType;
781
782 if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
783 return A_NO_MEMORY;
784 }
785
786 datap = A_NETBUF_DATA(osbuf);
787
788 memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR));
789
790 return (0);
791}
792
793/*
794 * Removes a WMI data header
795 */
796int
797wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf)
798{
799 A_ASSERT(osbuf != NULL);
800
801 return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR)));
802}
803
804void
805wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg)
806{
807 wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg);
808}
809
810/*
811 * WMI Extended Event received from Target.
812 */
813int
814wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf)
815{
816 WMIX_CMD_HDR *cmd;
817 u16 id;
818 u8 *datap;
819 u32 len;
820 int status = 0;
821
822 if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) {
823 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
824 wmip->wmi_stats.cmd_len_err++;
825 return A_ERROR;
826 }
827
828 cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
829 id = cmd->commandId;
830
831 if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != 0) {
832 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
833 wmip->wmi_stats.cmd_len_err++;
834 return A_ERROR;
835 }
836
837 datap = A_NETBUF_DATA(osbuf);
838 len = A_NETBUF_LEN(osbuf);
839
840 switch (id) {
841 case (WMIX_DSETOPENREQ_EVENTID):
842 status = wmi_dset_open_req_rx(wmip, datap, len);
843 break;
844#ifdef CONFIG_HOST_DSET_SUPPORT
845 case (WMIX_DSETCLOSE_EVENTID):
846 status = wmi_dset_close_rx(wmip, datap, len);
847 break;
848 case (WMIX_DSETDATAREQ_EVENTID):
849 status = wmi_dset_data_req_rx(wmip, datap, len);
850 break;
851#endif /* CONFIG_HOST_DSET_SUPPORT */
852 case (WMIX_HB_CHALLENGE_RESP_EVENTID):
853 wmi_hbChallengeResp_rx(wmip, datap, len);
854 break;
855 case (WMIX_DBGLOG_EVENTID):
856 wmi_dbglog_event_rx(wmip, datap, len);
857 break;
858#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
859 case (WMIX_PROF_COUNT_EVENTID):
860 wmi_prof_count_rx(wmip, datap, len);
861 break;
862#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
863 default:
864 A_DPRINTF(DBG_WMI|DBG_ERROR,
865 (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
866 wmip->wmi_stats.cmd_id_err++;
867 status = A_ERROR;
868 break;
869 }
870
871 return status;
872}
873
874/*
875 * Control Path
876 */
877u32 cmdRecvNum;
878
879int
880wmi_control_rx(struct wmi_t *wmip, void *osbuf)
881{
882 WMI_CMD_HDR *cmd;
883 u16 id;
884 u8 *datap;
885 u32 len, i, loggingReq;
886 int status = 0;
887
888 A_ASSERT(osbuf != NULL);
889 if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) {
890 A_NETBUF_FREE(osbuf);
891 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
892 wmip->wmi_stats.cmd_len_err++;
893 return A_ERROR;
894 }
895
896 cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
897 id = cmd->commandId;
898
899 if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != 0) {
900 A_NETBUF_FREE(osbuf);
901 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
902 wmip->wmi_stats.cmd_len_err++;
903 return A_ERROR;
904 }
905
906 datap = A_NETBUF_DATA(osbuf);
907 len = A_NETBUF_LEN(osbuf);
908
909 loggingReq = 0;
910
911 ar6000_get_driver_cfg(wmip->wmi_devt,
912 AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS,
913 &loggingReq);
914
915 if(loggingReq) {
916 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI %d \n",id));
917 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI recv, MsgNo %d : ", cmdRecvNum));
918 for(i = 0; i < len; i++)
919 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("%x ", datap[i]));
920 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("\n"));
921 }
922
923 LOCK_WMI(wmip);
924 cmdRecvNum++;
925 UNLOCK_WMI(wmip);
926
927 switch (id) {
928 case (WMI_GET_BITRATE_CMDID):
929 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_BITRATE_CMDID\n", DBGARG));
930 status = wmi_bitrate_reply_rx(wmip, datap, len);
931 break;
932 case (WMI_GET_CHANNEL_LIST_CMDID):
933 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_CHANNEL_LIST_CMDID\n", DBGARG));
934 status = wmi_channelList_reply_rx(wmip, datap, len);
935 break;
936 case (WMI_GET_TX_PWR_CMDID):
937 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_TX_PWR_CMDID\n", DBGARG));
938 status = wmi_txPwr_reply_rx(wmip, datap, len);
939 break;
940 case (WMI_READY_EVENTID):
941 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG));
942 status = wmi_ready_event_rx(wmip, datap, len);
943 A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt);
944 break;
945 case (WMI_CONNECT_EVENTID):
946 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG));
947 status = wmi_connect_event_rx(wmip, datap, len);
948 break;
949 case (WMI_DISCONNECT_EVENTID):
950 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG));
951 status = wmi_disconnect_event_rx(wmip, datap, len);
952 break;
953 case (WMI_PEER_NODE_EVENTID):
954 A_DPRINTF (DBG_WMI, (DBGFMT "WMI_PEER_NODE_EVENTID\n", DBGARG));
955 status = wmi_peer_node_event_rx(wmip, datap, len);
956 break;
957 case (WMI_TKIP_MICERR_EVENTID):
958 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG));
959 status = wmi_tkip_micerr_event_rx(wmip, datap, len);
960 break;
961 case (WMI_BSSINFO_EVENTID):
962 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG));
963 {
964 /*
965 * convert WMI_BSS_INFO_HDR2 to WMI_BSS_INFO_HDR
966 * Take a local copy of the WMI_BSS_INFO_HDR2 from the wmi buffer
967 * and reconstruct the WMI_BSS_INFO_HDR in its place
968 */
969 WMI_BSS_INFO_HDR2 bih2;
970 WMI_BSS_INFO_HDR *bih;
971 memcpy(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2));
972
973 A_NETBUF_PUSH(osbuf, 4);
974 datap = A_NETBUF_DATA(osbuf);
975 len = A_NETBUF_LEN(osbuf);
976 bih = (WMI_BSS_INFO_HDR *)datap;
977
978 bih->channel = bih2.channel;
979 bih->frameType = bih2.frameType;
980 bih->snr = bih2.snr;
981 bih->rssi = bih2.snr - 95;
982 bih->ieMask = bih2.ieMask;
983 memcpy(bih->bssid, bih2.bssid, ATH_MAC_LEN);
984
985 status = wmi_bssInfo_event_rx(wmip, datap, len);
986 }
987 break;
988 case (WMI_REGDOMAIN_EVENTID):
989 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REGDOMAIN_EVENTID\n", DBGARG));
990 status = wmi_regDomain_event_rx(wmip, datap, len);
991 break;
992 case (WMI_PSTREAM_TIMEOUT_EVENTID):
993 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG));
994 status = wmi_pstream_timeout_event_rx(wmip, datap, len);
995 break;
996 case (WMI_NEIGHBOR_REPORT_EVENTID):
997 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG));
998 status = wmi_neighborReport_event_rx(wmip, datap, len);
999 break;
1000 case (WMI_SCAN_COMPLETE_EVENTID):
1001 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG));
1002 status = wmi_scanComplete_rx(wmip, datap, len);
1003 break;
1004 case (WMI_CMDERROR_EVENTID):
1005 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG));
1006 status = wmi_errorEvent_rx(wmip, datap, len);
1007 break;
1008 case (WMI_REPORT_STATISTICS_EVENTID):
1009 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_STATISTICS_EVENTID\n", DBGARG));
1010 status = wmi_statsEvent_rx(wmip, datap, len);
1011 break;
1012 case (WMI_RSSI_THRESHOLD_EVENTID):
1013 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_RSSI_THRESHOLD_EVENTID\n", DBGARG));
1014 status = wmi_rssiThresholdEvent_rx(wmip, datap, len);
1015 break;
1016 case (WMI_ERROR_REPORT_EVENTID):
1017 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG));
1018 status = wmi_reportErrorEvent_rx(wmip, datap, len);
1019 break;
1020 case (WMI_OPT_RX_FRAME_EVENTID):
1021 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG));
1022 status = wmi_opt_frame_event_rx(wmip, datap, len);
1023 break;
1024 case (WMI_REPORT_ROAM_TBL_EVENTID):
1025 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_TBL_EVENTID\n", DBGARG));
1026 status = wmi_roam_tbl_event_rx(wmip, datap, len);
1027 break;
1028 case (WMI_EXTENSION_EVENTID):
1029 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_EXTENSION_EVENTID\n", DBGARG));
1030 status = wmi_control_rx_xtnd(wmip, osbuf);
1031 break;
1032 case (WMI_CAC_EVENTID):
1033 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CAC_EVENTID\n", DBGARG));
1034 status = wmi_cac_event_rx(wmip, datap, len);
1035 break;
1036 case (WMI_CHANNEL_CHANGE_EVENTID):
1037 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CHANNEL_CHANGE_EVENTID\n", DBGARG));
1038 status = wmi_channel_change_event_rx(wmip, datap, len);
1039 break;
1040 case (WMI_REPORT_ROAM_DATA_EVENTID):
1041 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_DATA_EVENTID\n", DBGARG));
1042 status = wmi_roam_data_event_rx(wmip, datap, len);
1043 break;
1044#ifdef CONFIG_HOST_TCMD_SUPPORT
1045 case (WMI_TEST_EVENTID):
1046 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TEST_EVENTID\n", DBGARG));
1047 status = wmi_tcmd_test_report_rx(wmip, datap, len);
1048 break;
1049#endif
1050 case (WMI_GET_FIXRATES_CMDID):
1051 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_FIXRATES_CMDID\n", DBGARG));
1052 status = wmi_ratemask_reply_rx(wmip, datap, len);
1053 break;
1054 case (WMI_TX_RETRY_ERR_EVENTID):
1055 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG));
1056 status = wmi_txRetryErrEvent_rx(wmip, datap, len);
1057 break;
1058 case (WMI_SNR_THRESHOLD_EVENTID):
1059 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG));
1060 status = wmi_snrThresholdEvent_rx(wmip, datap, len);
1061 break;
1062 case (WMI_LQ_THRESHOLD_EVENTID):
1063 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG));
1064 status = wmi_lqThresholdEvent_rx(wmip, datap, len);
1065 break;
1066 case (WMI_APLIST_EVENTID):
1067 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n"));
1068 status = wmi_aplistEvent_rx(wmip, datap, len);
1069 break;
1070 case (WMI_GET_KEEPALIVE_CMDID):
1071 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_KEEPALIVE_CMDID\n", DBGARG));
1072 status = wmi_keepalive_reply_rx(wmip, datap, len);
1073 break;
1074 case (WMI_GET_WOW_LIST_EVENTID):
1075 status = wmi_get_wow_list_event_rx(wmip, datap, len);
1076 break;
1077 case (WMI_GET_PMKID_LIST_EVENTID):
1078 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_PMKID_LIST Event\n", DBGARG));
1079 status = wmi_get_pmkid_list_event_rx(wmip, datap, len);
1080 break;
1081 case (WMI_PSPOLL_EVENTID):
1082 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSPOLL_EVENT\n", DBGARG));
1083 status = wmi_pspoll_event_rx(wmip, datap, len);
1084 break;
1085 case (WMI_DTIMEXPIRY_EVENTID):
1086 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DTIMEXPIRY_EVENT\n", DBGARG));
1087 status = wmi_dtimexpiry_event_rx(wmip, datap, len);
1088 break;
1089 case (WMI_SET_PARAMS_REPLY_EVENTID):
1090 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
1091 status = wmi_set_params_event_rx(wmip, datap, len);
1092 break;
1093 case (WMI_ADDBA_REQ_EVENTID):
1094 status = wmi_addba_req_event_rx(wmip, datap, len);
1095 break;
1096 case (WMI_ADDBA_RESP_EVENTID):
1097 status = wmi_addba_resp_event_rx(wmip, datap, len);
1098 break;
1099 case (WMI_DELBA_REQ_EVENTID):
1100 status = wmi_delba_req_event_rx(wmip, datap, len);
1101 break;
1102 case (WMI_REPORT_BTCOEX_CONFIG_EVENTID):
1103 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_CONFIG_EVENTID", DBGARG));
1104 status = wmi_btcoex_config_event_rx(wmip, datap, len);
1105 break;
1106 case (WMI_REPORT_BTCOEX_STATS_EVENTID):
1107 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_STATS_EVENTID", DBGARG));
1108 status = wmi_btcoex_stats_event_rx(wmip, datap, len);
1109 break;
1110 case (WMI_TX_COMPLETE_EVENTID):
1111 {
1112 int index;
1113 TX_COMPLETE_MSG_V1 *pV1;
1114 WMI_TX_COMPLETE_EVENT *pEv = (WMI_TX_COMPLETE_EVENT *)datap;
1115 A_PRINTF("comp: %d %d %d\n", pEv->numMessages, pEv->msgLen, pEv->msgType);
1116
1117 for(index = 0 ; index < pEv->numMessages ; index++) {
1118 pV1 = (TX_COMPLETE_MSG_V1 *)(datap + sizeof(WMI_TX_COMPLETE_EVENT) + index*sizeof(TX_COMPLETE_MSG_V1));
1119 A_PRINTF("msg: %d %d %d %d\n", pV1->status, pV1->pktID, pV1->rateIdx, pV1->ackFailures);
1120 }
1121 }
1122 break;
1123 case (WMI_HCI_EVENT_EVENTID):
1124 status = wmi_hci_event_rx(wmip, datap, len);
1125 break;
1126#ifdef WAPI_ENABLE
1127 case (WMI_WAPI_REKEY_EVENTID):
1128 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_WAPI_REKEY_EVENTID", DBGARG));
1129 status = wmi_wapi_rekey_event_rx(wmip, datap, len);
1130 break;
1131#endif
1132 default:
1133 A_DPRINTF(DBG_WMI|DBG_ERROR,
1134 (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
1135 wmip->wmi_stats.cmd_id_err++;
1136 status = A_ERROR;
1137 break;
1138 }
1139
1140 A_NETBUF_FREE(osbuf);
1141
1142 return status;
1143}
1144
1145/* Send a "simple" wmi command -- one with no arguments */
1146static int
1147wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid)
1148{
1149 void *osbuf;
1150
1151 osbuf = A_NETBUF_ALLOC(0);
1152 if (osbuf == NULL) {
1153 return A_NO_MEMORY;
1154 }
1155
1156 return (wmi_cmd_send(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
1157}
1158
1159/* Send a "simple" extended wmi command -- one with no arguments.
1160 Enabling this command only if GPIO or profiling support is enabled.
1161 This is to suppress warnings on some platforms */
1162#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
1163static int
1164wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid)
1165{
1166 void *osbuf;
1167
1168 osbuf = A_NETBUF_ALLOC(0);
1169 if (osbuf == NULL) {
1170 return A_NO_MEMORY;
1171 }
1172
1173 return (wmi_cmd_send_xtnd(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
1174}
1175#endif
1176
1177static int
1178wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1179{
1180 WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap;
1181
1182 if (len < sizeof(WMI_READY_EVENT)) {
1183 return A_EINVAL;
1184 }
1185 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1186 wmip->wmi_ready = true;
1187 A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability,
1188 ev->sw_version, ev->abi_version);
1189
1190 return 0;
1191}
1192
1193#define LE_READ_4(p) \
1194 ((u32) \
1195 ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \
1196 (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24)))
1197
1198static int __inline
1199iswmmoui(const u8 *frm)
1200{
1201 return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
1202}
1203
1204static int __inline
1205iswmmparam(const u8 *frm)
1206{
1207 return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
1208}
1209
1210
1211static int
1212wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1213{
1214 WMI_CONNECT_EVENT *ev;
1215 u8 *pie,*peie;
1216
1217 if (len < sizeof(WMI_CONNECT_EVENT))
1218 {
1219 return A_EINVAL;
1220 }
1221 ev = (WMI_CONNECT_EVENT *)datap;
1222
1223 A_DPRINTF(DBG_WMI,
1224 (DBGFMT "freq %d bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
1225 DBGARG, ev->channel,
1226 ev->bssid[0], ev->bssid[1], ev->bssid[2],
1227 ev->bssid[3], ev->bssid[4], ev->bssid[5]));
1228
1229 memcpy(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN);
1230
1231 /* initialize pointer to start of assoc rsp IEs */
1232 pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen +
1233 sizeof(u16) + /* capinfo*/
1234 sizeof(u16) + /* status Code */
1235 sizeof(u16) ; /* associd */
1236
1237 /* initialize pointer to end of assoc rsp IEs */
1238 peie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + ev->assocRespLen;
1239
1240 while (pie < peie)
1241 {
1242 switch (*pie)
1243 {
1244 case IEEE80211_ELEMID_VENDOR:
1245 if (iswmmoui(pie))
1246 {
1247 if(iswmmparam (pie))
1248 {
1249 wmip->wmi_is_wmm_enabled = true;
1250 }
1251 }
1252 break;
1253 }
1254
1255 if (wmip->wmi_is_wmm_enabled)
1256 {
1257 break;
1258 }
1259 pie += pie[1] + 2;
1260 }
1261
1262 A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev->channel, ev->bssid,
1263 ev->listenInterval, ev->beaconInterval,
1264 (NETWORK_TYPE) ev->networkType, ev->beaconIeLen,
1265 ev->assocReqLen, ev->assocRespLen,
1266 ev->assocInfo);
1267
1268 return 0;
1269}
1270
1271static int
1272wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1273{
1274 WMI_REG_DOMAIN_EVENT *ev;
1275
1276 if (len < sizeof(*ev)) {
1277 return A_EINVAL;
1278 }
1279 ev = (WMI_REG_DOMAIN_EVENT *)datap;
1280
1281 A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain);
1282
1283 return 0;
1284}
1285
1286static int
1287wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1288{
1289 WMI_NEIGHBOR_REPORT_EVENT *ev;
1290 int numAps;
1291
1292 if (len < sizeof(*ev)) {
1293 return A_EINVAL;
1294 }
1295 ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap;
1296 numAps = ev->numberOfAps;
1297
1298 if (len < (int)(sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) {
1299 return A_EINVAL;
1300 }
1301
1302 A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor);
1303
1304 return 0;
1305}
1306
1307static int
1308wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1309{
1310 WMI_DISCONNECT_EVENT *ev;
1311 wmip->wmi_traffic_class = 100;
1312
1313 if (len < sizeof(WMI_DISCONNECT_EVENT)) {
1314 return A_EINVAL;
1315 }
1316 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1317
1318 ev = (WMI_DISCONNECT_EVENT *)datap;
1319
1320 A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid));
1321
1322 wmip->wmi_is_wmm_enabled = false;
1323 wmip->wmi_pair_crypto_type = NONE_CRYPT;
1324 wmip->wmi_grp_crypto_type = NONE_CRYPT;
1325
1326 A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid,
1327 ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus);
1328
1329 return 0;
1330}
1331
1332static int
1333wmi_peer_node_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1334{
1335 WMI_PEER_NODE_EVENT *ev;
1336
1337 if (len < sizeof(WMI_PEER_NODE_EVENT)) {
1338 return A_EINVAL;
1339 }
1340 ev = (WMI_PEER_NODE_EVENT *)datap;
1341 if (ev->eventCode == PEER_NODE_JOIN_EVENT) {
1342 A_DPRINTF (DBG_WMI, (DBGFMT "Joined node with Macaddr: ", DBGARG));
1343 } else if(ev->eventCode == PEER_NODE_LEAVE_EVENT) {
1344 A_DPRINTF (DBG_WMI, (DBGFMT "left node with Macaddr: ", DBGARG));
1345 }
1346
1347 A_WMI_PEER_EVENT (wmip->wmi_devt, ev->eventCode, ev->peerMacAddr);
1348
1349 return 0;
1350}
1351
1352static int
1353wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1354{
1355 WMI_TKIP_MICERR_EVENT *ev;
1356
1357 if (len < sizeof(*ev)) {
1358 return A_EINVAL;
1359 }
1360 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1361
1362 ev = (WMI_TKIP_MICERR_EVENT *)datap;
1363 A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast);
1364
1365 return 0;
1366}
1367
1368static int
1369wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1370{
1371 bss_t *bss = NULL;
1372 WMI_BSS_INFO_HDR *bih;
1373 u8 *buf;
1374 u32 nodeCachingAllowed = 1;
1375 u8 cached_ssid_len = 0;
1376 u8 cached_ssid_buf[IEEE80211_NWID_LEN] = {0};
1377 u8 beacon_ssid_len = 0;
1378
1379 if (len <= sizeof(WMI_BSS_INFO_HDR)) {
1380 return A_EINVAL;
1381 }
1382
1383 bih = (WMI_BSS_INFO_HDR *)datap;
1384 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1385
1386 if (bih->rssi > 0) {
1387 if (NULL == bss)
1388 return 0; //no node found in the table, just drop the node with incorrect RSSI
1389 else
1390 bih->rssi = bss->ni_rssi; //Adjust RSSI in datap in case it is used in A_WMI_BSSINFO_EVENT_RX
1391 }
1392
1393 A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len);
1394 /* What is driver config for wlan node caching? */
1395 if(ar6000_get_driver_cfg(wmip->wmi_devt,
1396 AR6000_DRIVER_CFG_GET_WLANNODECACHING,
1397 &nodeCachingAllowed) != 0) {
1398 wmi_node_return(wmip, bss);
1399 return A_EINVAL;
1400 }
1401
1402 if(!nodeCachingAllowed) {
1403 wmi_node_return(wmip, bss);
1404 return 0;
1405 }
1406
1407 buf = datap + sizeof(WMI_BSS_INFO_HDR);
1408 len -= sizeof(WMI_BSS_INFO_HDR);
1409
1410 A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, "
1411 "bssid \"%pM\"\n", DBGARG, bih->channel,
1412 (unsigned char) bih->rssi, bih->bssid));
1413
1414 if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) {
1415 wmi_node_return(wmip, bss);
1416 return 0;
1417 }
1418
1419 if (bss != NULL) {
1420 /*
1421 * Free up the node. Not the most efficient process given
1422 * we are about to allocate a new node but it is simple and should be
1423 * adequate.
1424 */
1425
1426 /* In case of hidden AP, beacon will not have ssid,
1427 * but a directed probe response will have it,
1428 * so cache the probe-resp-ssid if already present. */
1429 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType))
1430 {
1431 u8 *ie_ssid;
1432
1433 ie_ssid = bss->ni_cie.ie_ssid;
1434 if(ie_ssid && (ie_ssid[1] <= IEEE80211_NWID_LEN) && (ie_ssid[2] != 0))
1435 {
1436 cached_ssid_len = ie_ssid[1];
1437 memcpy(cached_ssid_buf, ie_ssid + 2, cached_ssid_len);
1438 }
1439 }
1440
1441 /*
1442 * Use the current average rssi of associated AP base on assumpiton
1443 * 1. Most os with GUI will update RSSI by wmi_get_stats_cmd() periodically
1444 * 2. wmi_get_stats_cmd(..) will be called when calling wmi_startscan_cmd(...)
1445 * The average value of RSSI give end-user better feeling for instance value of scan result
1446 * It also sync up RSSI info in GUI between scan result and RSSI signal icon
1447 */
1448 if (IEEE80211_ADDR_EQ(wmip->wmi_bssid, bih->bssid)) {
1449 bih->rssi = bss->ni_rssi;
1450 bih->snr = bss->ni_snr;
1451 }
1452
1453 wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1454 }
1455
1456 /* beacon/probe response frame format
1457 * [8] time stamp
1458 * [2] beacon interval
1459 * [2] capability information
1460 * [tlv] ssid */
1461 beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
1462
1463 /* If ssid is cached for this hidden AP, then change buffer len accordingly. */
1464 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1465 (0 != cached_ssid_len) &&
1466 (0 == beacon_ssid_len || (cached_ssid_len > beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1467 {
1468 len += (cached_ssid_len - beacon_ssid_len);
1469 }
1470
1471 bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1472 if (bss == NULL) {
1473 return A_NO_MEMORY;
1474 }
1475
1476 bss->ni_snr = bih->snr;
1477 bss->ni_rssi = bih->rssi;
1478 A_ASSERT(bss->ni_buf != NULL);
1479
1480 /* In case of hidden AP, beacon will not have ssid,
1481 * but a directed probe response will have it,
1482 * so place the cached-ssid(probe-resp) in the bssinfo. */
1483 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1484 (0 != cached_ssid_len) &&
1485 (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1486 {
1487 u8 *ni_buf = bss->ni_buf;
1488 int buf_len = len;
1489
1490 /* copy the first 14 bytes such as
1491 * time-stamp(8), beacon-interval(2), cap-info(2), ssid-id(1), ssid-len(1). */
1492 memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
1493
1494 ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
1495 ni_buf += (SSID_IE_LEN_INDEX + 1);
1496
1497 buf += (SSID_IE_LEN_INDEX + 1);
1498 buf_len -= (SSID_IE_LEN_INDEX + 1);
1499
1500 /* copy the cached ssid */
1501 memcpy(ni_buf, cached_ssid_buf, cached_ssid_len);
1502 ni_buf += cached_ssid_len;
1503
1504 buf += beacon_ssid_len;
1505 buf_len -= beacon_ssid_len;
1506
1507 if (cached_ssid_len > beacon_ssid_len)
1508 buf_len -= (cached_ssid_len - beacon_ssid_len);
1509
1510 /* now copy the rest of bytes */
1511 memcpy(ni_buf, buf, buf_len);
1512 }
1513 else
1514 memcpy(bss->ni_buf, buf, len);
1515
1516 bss->ni_framelen = len;
1517 if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != 0) {
1518 wlan_node_free(bss);
1519 return A_EINVAL;
1520 }
1521
1522 /*
1523 * Update the frequency in ie_chan, overwriting of channel number
1524 * which is done in wlan_parse_beacon
1525 */
1526 bss->ni_cie.ie_chan = bih->channel;
1527 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1528
1529 return 0;
1530}
1531
1532static int
1533wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1534{
1535 bss_t *bss;
1536 WMI_OPT_RX_INFO_HDR *bih;
1537 u8 *buf;
1538
1539 if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) {
1540 return A_EINVAL;
1541 }
1542
1543 bih = (WMI_OPT_RX_INFO_HDR *)datap;
1544 buf = datap + sizeof(WMI_OPT_RX_INFO_HDR);
1545 len -= sizeof(WMI_OPT_RX_INFO_HDR);
1546
1547 A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG,
1548 bih->bssid[4], bih->bssid[5]));
1549
1550 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1551 if (bss != NULL) {
1552 /*
1553 * Free up the node. Not the most efficient process given
1554 * we are about to allocate a new node but it is simple and should be
1555 * adequate.
1556 */
1557 wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1558 }
1559
1560 bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1561 if (bss == NULL) {
1562 return A_NO_MEMORY;
1563 }
1564
1565 bss->ni_snr = bih->snr;
1566 bss->ni_cie.ie_chan = bih->channel;
1567 A_ASSERT(bss->ni_buf != NULL);
1568 memcpy(bss->ni_buf, buf, len);
1569 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1570
1571 return 0;
1572}
1573
1574 /* This event indicates inactivity timeout of a fatpipe(pstream)
1575 * at the target
1576 */
1577static int
1578wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1579{
1580 WMI_PSTREAM_TIMEOUT_EVENT *ev;
1581
1582 if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) {
1583 return A_EINVAL;
1584 }
1585
1586 A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG));
1587
1588 ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap;
1589
1590 /* When the pstream (fat pipe == AC) timesout, it means there were no
1591 * thinStreams within this pstream & it got implicitly created due to
1592 * data flow on this AC. We start the inactivity timer only for
1593 * implicitly created pstream. Just reset the host state.
1594 */
1595 /* Set the activeTsids for this AC to 0 */
1596 LOCK_WMI(wmip);
1597 wmip->wmi_streamExistsForAC[ev->trafficClass]=0;
1598 wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass);
1599 UNLOCK_WMI(wmip);
1600
1601 /*Indicate inactivity to driver layer for this fatpipe (pstream)*/
1602 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass);
1603
1604 return 0;
1605}
1606
1607static int
1608wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1609{
1610 WMI_BIT_RATE_REPLY *reply;
1611 s32 rate;
1612 u32 sgi,index;
1613 /* 54149:
1614 * WMI_BIT_RATE_CMD structure is changed to WMI_BIT_RATE_REPLY.
1615 * since there is difference in the length and to avoid returning
1616 * error value.
1617 */
1618 if (len < sizeof(WMI_BIT_RATE_REPLY)) {
1619 return A_EINVAL;
1620 }
1621 reply = (WMI_BIT_RATE_REPLY *)datap;
1622 A_DPRINTF(DBG_WMI,
1623 (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex));
1624
1625 if (reply->rateIndex == (s8) RATE_AUTO) {
1626 rate = RATE_AUTO;
1627 } else {
1628 // the SGI state is stored as the MSb of the rateIndex
1629 index = reply->rateIndex & 0x7f;
1630 sgi = (reply->rateIndex & 0x80)? 1:0;
1631 rate = wmi_rateTable[index][sgi];
1632 }
1633
1634 A_WMI_BITRATE_RX(wmip->wmi_devt, rate);
1635 return 0;
1636}
1637
1638static int
1639wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1640{
1641 WMI_FIX_RATES_REPLY *reply;
1642
1643 if (len < sizeof(WMI_FIX_RATES_REPLY)) {
1644 return A_EINVAL;
1645 }
1646 reply = (WMI_FIX_RATES_REPLY *)datap;
1647 A_DPRINTF(DBG_WMI,
1648 (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask));
1649
1650 A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask);
1651
1652 return 0;
1653}
1654
1655static int
1656wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1657{
1658 WMI_CHANNEL_LIST_REPLY *reply;
1659
1660 if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) {
1661 return A_EINVAL;
1662 }
1663 reply = (WMI_CHANNEL_LIST_REPLY *)datap;
1664 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1665
1666 A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels,
1667 reply->channelList);
1668
1669 return 0;
1670}
1671
1672static int
1673wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1674{
1675 WMI_TX_PWR_REPLY *reply;
1676
1677 if (len < sizeof(*reply)) {
1678 return A_EINVAL;
1679 }
1680 reply = (WMI_TX_PWR_REPLY *)datap;
1681 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1682
1683 A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM);
1684
1685 return 0;
1686}
1687static int
1688wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1689{
1690 WMI_GET_KEEPALIVE_CMD *reply;
1691
1692 if (len < sizeof(*reply)) {
1693 return A_EINVAL;
1694 }
1695 reply = (WMI_GET_KEEPALIVE_CMD *)datap;
1696 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1697
1698 A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured);
1699
1700 return 0;
1701}
1702
1703
1704static int
1705wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap, int len)
1706{
1707 WMIX_DSETOPENREQ_EVENT *dsetopenreq;
1708
1709 if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) {
1710 return A_EINVAL;
1711 }
1712 dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap;
1713 A_DPRINTF(DBG_WMI,
1714 (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id));
1715 A_WMI_DSET_OPEN_REQ(wmip->wmi_devt,
1716 dsetopenreq->dset_id,
1717 dsetopenreq->targ_dset_handle,
1718 dsetopenreq->targ_reply_fn,
1719 dsetopenreq->targ_reply_arg);
1720
1721 return 0;
1722}
1723
1724#ifdef CONFIG_HOST_DSET_SUPPORT
1725static int
1726wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len)
1727{
1728 WMIX_DSETCLOSE_EVENT *dsetclose;
1729
1730 if (len < sizeof(WMIX_DSETCLOSE_EVENT)) {
1731 return A_EINVAL;
1732 }
1733 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1734
1735 dsetclose = (WMIX_DSETCLOSE_EVENT *)datap;
1736 A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie);
1737
1738 return 0;
1739}
1740
1741static int
1742wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap, int len)
1743{
1744 WMIX_DSETDATAREQ_EVENT *dsetdatareq;
1745
1746 if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) {
1747 return A_EINVAL;
1748 }
1749 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1750
1751 dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap;
1752 A_WMI_DSET_DATA_REQ(wmip->wmi_devt,
1753 dsetdatareq->access_cookie,
1754 dsetdatareq->offset,
1755 dsetdatareq->length,
1756 dsetdatareq->targ_buf,
1757 dsetdatareq->targ_reply_fn,
1758 dsetdatareq->targ_reply_arg);
1759
1760 return 0;
1761}
1762#endif /* CONFIG_HOST_DSET_SUPPORT */
1763
1764static int
1765wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap, int len)
1766{
1767 WMI_SCAN_COMPLETE_EVENT *ev;
1768
1769 ev = (WMI_SCAN_COMPLETE_EVENT *)datap;
1770 if ((int)ev->status == 0) {
1771 wlan_refresh_inactive_nodes(&wmip->wmi_scan_table);
1772 }
1773 A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (int) ev->status);
1774 is_probe_ssid = false;
1775
1776 return 0;
1777}
1778
1779/*
1780 * Target is reporting a programming error. This is for
1781 * developer aid only. Target only checks a few common violations
1782 * and it is responsibility of host to do all error checking.
1783 * Behavior of target after wmi error event is undefined.
1784 * A reset is recommended.
1785 */
1786static int
1787wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1788{
1789 WMI_CMD_ERROR_EVENT *ev;
1790
1791 ev = (WMI_CMD_ERROR_EVENT *)datap;
1792 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId));
1793 switch (ev->errorCode) {
1794 case (INVALID_PARAM):
1795 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n"));
1796 break;
1797 case (ILLEGAL_STATE):
1798 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n"));
1799 break;
1800 case (INTERNAL_ERROR):
1801 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n"));
1802 break;
1803 }
1804
1805 return 0;
1806}
1807
1808
1809static int
1810wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1811{
1812 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1813
1814 A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, datap, len);
1815
1816 return 0;
1817}
1818
1819static int
1820wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1821{
1822 WMI_RSSI_THRESHOLD_EVENT *reply;
1823 WMI_RSSI_THRESHOLD_VAL newThreshold;
1824 WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
1825 SQ_THRESHOLD_PARAMS *sq_thresh =
1826 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
1827 u8 upper_rssi_threshold, lower_rssi_threshold;
1828 s16 rssi;
1829
1830 if (len < sizeof(*reply)) {
1831 return A_EINVAL;
1832 }
1833 reply = (WMI_RSSI_THRESHOLD_EVENT *)datap;
1834 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1835 newThreshold = (WMI_RSSI_THRESHOLD_VAL) reply->range;
1836 rssi = reply->rssi;
1837
1838 /*
1839 * Identify the threshold breached and communicate that to the app. After
1840 * that install a new set of thresholds based on the signal quality
1841 * reported by the target
1842 */
1843 if (newThreshold) {
1844 /* Upper threshold breached */
1845 if (rssi < sq_thresh->upper_threshold[0]) {
1846 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper RSSI threshold event: "
1847 " %d\n", DBGARG, rssi));
1848 } else if ((rssi < sq_thresh->upper_threshold[1]) &&
1849 (rssi >= sq_thresh->upper_threshold[0]))
1850 {
1851 newThreshold = WMI_RSSI_THRESHOLD1_ABOVE;
1852 } else if ((rssi < sq_thresh->upper_threshold[2]) &&
1853 (rssi >= sq_thresh->upper_threshold[1]))
1854 {
1855 newThreshold = WMI_RSSI_THRESHOLD2_ABOVE;
1856 } else if ((rssi < sq_thresh->upper_threshold[3]) &&
1857 (rssi >= sq_thresh->upper_threshold[2]))
1858 {
1859 newThreshold = WMI_RSSI_THRESHOLD3_ABOVE;
1860 } else if ((rssi < sq_thresh->upper_threshold[4]) &&
1861 (rssi >= sq_thresh->upper_threshold[3]))
1862 {
1863 newThreshold = WMI_RSSI_THRESHOLD4_ABOVE;
1864 } else if ((rssi < sq_thresh->upper_threshold[5]) &&
1865 (rssi >= sq_thresh->upper_threshold[4]))
1866 {
1867 newThreshold = WMI_RSSI_THRESHOLD5_ABOVE;
1868 } else if (rssi >= sq_thresh->upper_threshold[5]) {
1869 newThreshold = WMI_RSSI_THRESHOLD6_ABOVE;
1870 }
1871 } else {
1872 /* Lower threshold breached */
1873 if (rssi > sq_thresh->lower_threshold[0]) {
1874 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower RSSI threshold event: "
1875 "%d %d\n", DBGARG, rssi, sq_thresh->lower_threshold[0]));
1876 } else if ((rssi > sq_thresh->lower_threshold[1]) &&
1877 (rssi <= sq_thresh->lower_threshold[0]))
1878 {
1879 newThreshold = WMI_RSSI_THRESHOLD6_BELOW;
1880 } else if ((rssi > sq_thresh->lower_threshold[2]) &&
1881 (rssi <= sq_thresh->lower_threshold[1]))
1882 {
1883 newThreshold = WMI_RSSI_THRESHOLD5_BELOW;
1884 } else if ((rssi > sq_thresh->lower_threshold[3]) &&
1885 (rssi <= sq_thresh->lower_threshold[2]))
1886 {
1887 newThreshold = WMI_RSSI_THRESHOLD4_BELOW;
1888 } else if ((rssi > sq_thresh->lower_threshold[4]) &&
1889 (rssi <= sq_thresh->lower_threshold[3]))
1890 {
1891 newThreshold = WMI_RSSI_THRESHOLD3_BELOW;
1892 } else if ((rssi > sq_thresh->lower_threshold[5]) &&
1893 (rssi <= sq_thresh->lower_threshold[4]))
1894 {
1895 newThreshold = WMI_RSSI_THRESHOLD2_BELOW;
1896 } else if (rssi <= sq_thresh->lower_threshold[5]) {
1897 newThreshold = WMI_RSSI_THRESHOLD1_BELOW;
1898 }
1899 }
1900 /* Calculate and install the next set of thresholds */
1901 lower_rssi_threshold = ar6000_get_lower_threshold(rssi, sq_thresh,
1902 sq_thresh->lower_threshold_valid_count);
1903 upper_rssi_threshold = ar6000_get_upper_threshold(rssi, sq_thresh,
1904 sq_thresh->upper_threshold_valid_count);
1905 /* Issue a wmi command to install the thresholds */
1906 cmd.thresholdAbove1_Val = upper_rssi_threshold;
1907 cmd.thresholdBelow1_Val = lower_rssi_threshold;
1908 cmd.weight = sq_thresh->weight;
1909 cmd.pollTime = sq_thresh->polling_interval;
1910
1911 rssi_event_value = rssi;
1912
1913 if (wmi_send_rssi_threshold_params(wmip, &cmd) != 0) {
1914 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the RSSI thresholds\n",
1915 DBGARG));
1916 }
1917
1918 A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, newThreshold, reply->rssi);
1919
1920 return 0;
1921}
1922
1923
1924static int
1925wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1926{
1927 WMI_TARGET_ERROR_REPORT_EVENT *reply;
1928
1929 if (len < sizeof(*reply)) {
1930 return A_EINVAL;
1931 }
1932 reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap;
1933 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1934
1935 A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, (WMI_TARGET_ERROR_VAL) reply->errorVal);
1936
1937 return 0;
1938}
1939
1940static int
1941wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1942{
1943 WMI_CAC_EVENT *reply;
1944 WMM_TSPEC_IE *tspec_ie;
1945 u16 activeTsids;
1946
1947 if (len < sizeof(*reply)) {
1948 return A_EINVAL;
1949 }
1950 reply = (WMI_CAC_EVENT *)datap;
1951
1952 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1953
1954 if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
1955 (reply->statusCode != TSPEC_STATUS_CODE_ADMISSION_ACCEPTED)) {
1956 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
1957
1958 wmi_delete_pstream_cmd(wmip, reply->ac,
1959 (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
1960 }
1961 else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
1962 u8 i;
1963
1964 /* following assumes that there is only one outstanding ADDTS request
1965 when this event is received */
1966 LOCK_WMI(wmip);
1967 activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
1968 UNLOCK_WMI(wmip);
1969
1970 for (i = 0; i < sizeof(activeTsids) * 8; i++) {
1971 if ((activeTsids >> i) & 1) {
1972 break;
1973 }
1974 }
1975 if (i < (sizeof(activeTsids) * 8)) {
1976 wmi_delete_pstream_cmd(wmip, reply->ac, i);
1977 }
1978 }
1979 /*
1980 * Ev#72990: Clear active tsids and Add missing handling
1981 * for delete qos stream from AP
1982 */
1983 else if (reply->cac_indication == CAC_INDICATION_DELETE) {
1984 u8 tsid = 0;
1985
1986 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
1987 tsid= ((tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
1988 LOCK_WMI(wmip);
1989 wmip->wmi_streamExistsForAC[reply->ac] &= ~(1<<tsid);
1990 activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
1991 UNLOCK_WMI(wmip);
1992
1993
1994 /* Indicate stream inactivity to driver layer only if all tsids
1995 * within this AC are deleted.
1996 */
1997 if (!activeTsids) {
1998 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, reply->ac);
1999 wmip->wmi_fatPipeExists &= ~(1 << reply->ac);
2000 }
2001 }
2002
2003 A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac,
2004 reply->cac_indication, reply->statusCode,
2005 reply->tspecSuggestion);
2006
2007 return 0;
2008}
2009
2010static int
2011wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2012{
2013 WMI_CHANNEL_CHANGE_EVENT *reply;
2014
2015 if (len < sizeof(*reply)) {
2016 return A_EINVAL;
2017 }
2018 reply = (WMI_CHANNEL_CHANGE_EVENT *)datap;
2019 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2020
2021 A_WMI_CHANNEL_CHANGE_EVENT(wmip->wmi_devt, reply->oldChannel,
2022 reply->newChannel);
2023
2024 return 0;
2025}
2026
2027static int
2028wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len)
2029{
2030 WMIX_HB_CHALLENGE_RESP_EVENT *reply;
2031
2032 if (len < sizeof(*reply)) {
2033 return A_EINVAL;
2034 }
2035 reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap;
2036 A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG));
2037
2038 A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source);
2039
2040 return 0;
2041}
2042
2043static int
2044wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2045{
2046 WMI_TARGET_ROAM_TBL *reply;
2047
2048 if (len < sizeof(*reply)) {
2049 return A_EINVAL;
2050 }
2051 reply = (WMI_TARGET_ROAM_TBL *)datap;
2052 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2053
2054 A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply);
2055
2056 return 0;
2057}
2058
2059static int
2060wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2061{
2062 WMI_TARGET_ROAM_DATA *reply;
2063
2064 if (len < sizeof(*reply)) {
2065 return A_EINVAL;
2066 }
2067 reply = (WMI_TARGET_ROAM_DATA *)datap;
2068 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2069
2070 A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply);
2071
2072 return 0;
2073}
2074
2075static int
2076wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2077{
2078 if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) {
2079 return A_EINVAL;
2080 }
2081 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2082
2083 A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt);
2084
2085 return 0;
2086}
2087
2088static int
2089wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2090{
2091 WMI_SNR_THRESHOLD_EVENT *reply;
2092 SQ_THRESHOLD_PARAMS *sq_thresh =
2093 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
2094 WMI_SNR_THRESHOLD_VAL newThreshold;
2095 WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
2096 u8 upper_snr_threshold, lower_snr_threshold;
2097 s16 snr;
2098
2099 if (len < sizeof(*reply)) {
2100 return A_EINVAL;
2101 }
2102 reply = (WMI_SNR_THRESHOLD_EVENT *)datap;
2103 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2104
2105 newThreshold = (WMI_SNR_THRESHOLD_VAL) reply->range;
2106 snr = reply->snr;
2107 /*
2108 * Identify the threshold breached and communicate that to the app. After
2109 * that install a new set of thresholds based on the signal quality
2110 * reported by the target
2111 */
2112 if (newThreshold) {
2113 /* Upper threshold breached */
2114 if (snr < sq_thresh->upper_threshold[0]) {
2115 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper SNR threshold event: "
2116 "%d\n", DBGARG, snr));
2117 } else if ((snr < sq_thresh->upper_threshold[1]) &&
2118 (snr >= sq_thresh->upper_threshold[0]))
2119 {
2120 newThreshold = WMI_SNR_THRESHOLD1_ABOVE;
2121 } else if ((snr < sq_thresh->upper_threshold[2]) &&
2122 (snr >= sq_thresh->upper_threshold[1]))
2123 {
2124 newThreshold = WMI_SNR_THRESHOLD2_ABOVE;
2125 } else if ((snr < sq_thresh->upper_threshold[3]) &&
2126 (snr >= sq_thresh->upper_threshold[2]))
2127 {
2128 newThreshold = WMI_SNR_THRESHOLD3_ABOVE;
2129 } else if (snr >= sq_thresh->upper_threshold[3]) {
2130 newThreshold = WMI_SNR_THRESHOLD4_ABOVE;
2131 }
2132 } else {
2133 /* Lower threshold breached */
2134 if (snr > sq_thresh->lower_threshold[0]) {
2135 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower SNR threshold event: "
2136 "%d %d\n", DBGARG, snr, sq_thresh->lower_threshold[0]));
2137 } else if ((snr > sq_thresh->lower_threshold[1]) &&
2138 (snr <= sq_thresh->lower_threshold[0]))
2139 {
2140 newThreshold = WMI_SNR_THRESHOLD4_BELOW;
2141 } else if ((snr > sq_thresh->lower_threshold[2]) &&
2142 (snr <= sq_thresh->lower_threshold[1]))
2143 {
2144 newThreshold = WMI_SNR_THRESHOLD3_BELOW;
2145 } else if ((snr > sq_thresh->lower_threshold[3]) &&
2146 (snr <= sq_thresh->lower_threshold[2]))
2147 {
2148 newThreshold = WMI_SNR_THRESHOLD2_BELOW;
2149 } else if (snr <= sq_thresh->lower_threshold[3]) {
2150 newThreshold = WMI_SNR_THRESHOLD1_BELOW;
2151 }
2152 }
2153
2154 /* Calculate and install the next set of thresholds */
2155 lower_snr_threshold = ar6000_get_lower_threshold(snr, sq_thresh,
2156 sq_thresh->lower_threshold_valid_count);
2157 upper_snr_threshold = ar6000_get_upper_threshold(snr, sq_thresh,
2158 sq_thresh->upper_threshold_valid_count);
2159
2160 /* Issue a wmi command to install the thresholds */
2161 cmd.thresholdAbove1_Val = upper_snr_threshold;
2162 cmd.thresholdBelow1_Val = lower_snr_threshold;
2163 cmd.weight = sq_thresh->weight;
2164 cmd.pollTime = sq_thresh->polling_interval;
2165
2166 A_DPRINTF(DBG_WMI, (DBGFMT "snr: %d, threshold: %d, lower: %d, upper: %d\n"
2167 ,DBGARG, snr, newThreshold, lower_snr_threshold,
2168 upper_snr_threshold));
2169
2170 snr_event_value = snr;
2171
2172 if (wmi_send_snr_threshold_params(wmip, &cmd) != 0) {
2173 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the SNR thresholds\n",
2174 DBGARG));
2175 }
2176 A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, newThreshold, reply->snr);
2177
2178 return 0;
2179}
2180
2181static int
2182wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2183{
2184 WMI_LQ_THRESHOLD_EVENT *reply;
2185
2186 if (len < sizeof(*reply)) {
2187 return A_EINVAL;
2188 }
2189 reply = (WMI_LQ_THRESHOLD_EVENT *)datap;
2190 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2191
2192 A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt,
2193 (WMI_LQ_THRESHOLD_VAL) reply->range,
2194 reply->lq);
2195
2196 return 0;
2197}
2198
2199static int
2200wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2201{
2202 u16 ap_info_entry_size;
2203 WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap;
2204 WMI_AP_INFO_V1 *ap_info_v1;
2205 u8 i;
2206
2207 if (len < sizeof(WMI_APLIST_EVENT)) {
2208 return A_EINVAL;
2209 }
2210
2211 if (ev->apListVer == APLIST_VER1) {
2212 ap_info_entry_size = sizeof(WMI_AP_INFO_V1);
2213 ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList;
2214 } else {
2215 return A_EINVAL;
2216 }
2217
2218 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev->numAP));
2219 if (len < (int)(sizeof(WMI_APLIST_EVENT) +
2220 (ev->numAP - 1) * ap_info_entry_size))
2221 {
2222 return A_EINVAL;
2223 }
2224
2225 /*
2226 * AP List Ver1 Contents
2227 */
2228 for (i = 0; i < ev->numAP; i++) {
2229 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "\
2230 "Channel %d\n", i,
2231 ap_info_v1->bssid[0], ap_info_v1->bssid[1],
2232 ap_info_v1->bssid[2], ap_info_v1->bssid[3],
2233 ap_info_v1->bssid[4], ap_info_v1->bssid[5],
2234 ap_info_v1->channel));
2235 ap_info_v1++;
2236 }
2237 return 0;
2238}
2239
2240static int
2241wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2242{
2243 u32 dropped;
2244
2245 dropped = *((u32 *)datap);
2246 datap += sizeof(dropped);
2247 len -= sizeof(dropped);
2248 A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (s8 *)datap, len);
2249 return 0;
2250}
2251
2252/*
2253 * Called to send a wmi command. Command specific data is already built
2254 * on osbuf and current osbuf->data points to it.
2255 */
2256int
2257wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
2258 WMI_SYNC_FLAG syncflag)
2259{
2260 int status;
2261#define IS_OPT_TX_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID))
2262 WMI_CMD_HDR *cHdr;
2263 HTC_ENDPOINT_ID eid = wmip->wmi_endpoint_id;
2264
2265 A_ASSERT(osbuf != NULL);
2266
2267 if (syncflag >= END_WMIFLAG) {
2268 A_NETBUF_FREE(osbuf);
2269 return A_EINVAL;
2270 }
2271
2272 if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2273 /*
2274 * We want to make sure all data currently queued is transmitted before
2275 * the cmd execution. Establish a new sync point.
2276 */
2277 wmi_sync_point(wmip);
2278 }
2279
2280 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != 0) {
2281 A_NETBUF_FREE(osbuf);
2282 return A_NO_MEMORY;
2283 }
2284
2285 cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
2286 cHdr->commandId = (u16) cmdId;
2287 cHdr->info1 = 0; // added for virtual interface
2288
2289 /*
2290 * Only for OPT_TX_CMD, use BE endpoint.
2291 */
2292 if (IS_OPT_TX_CMD(cmdId)) {
2293 if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, false, false,0,NULL)) != 0) {
2294 A_NETBUF_FREE(osbuf);
2295 return status;
2296 }
2297 eid = A_WMI_Ac2EndpointID(wmip->wmi_devt, WMM_AC_BE);
2298 }
2299 A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid);
2300
2301 if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2302 /*
2303 * We want to make sure all new data queued waits for the command to
2304 * execute. Establish a new sync point.
2305 */
2306 wmi_sync_point(wmip);
2307 }
2308 return (0);
2309#undef IS_OPT_TX_CMD
2310}
2311
2312int
2313wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
2314 WMI_SYNC_FLAG syncflag)
2315{
2316 WMIX_CMD_HDR *cHdr;
2317
2318 if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != 0) {
2319 A_NETBUF_FREE(osbuf);
2320 return A_NO_MEMORY;
2321 }
2322
2323 cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
2324 cHdr->commandId = (u32) cmdId;
2325
2326 return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag);
2327}
2328
2329int
2330wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
2331 DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode,
2332 CRYPTO_TYPE pairwiseCrypto, u8 pairwiseCryptoLen,
2333 CRYPTO_TYPE groupCrypto, u8 groupCryptoLen,
2334 int ssidLength, u8 *ssid,
2335 u8 *bssid, u16 channel, u32 ctrl_flags)
2336{
2337 void *osbuf;
2338 WMI_CONNECT_CMD *cc;
2339 wmip->wmi_traffic_class = 100;
2340
2341 if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
2342 return A_EINVAL;
2343 }
2344 if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) {
2345 return A_EINVAL;
2346 }
2347
2348 osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD));
2349 if (osbuf == NULL) {
2350 return A_NO_MEMORY;
2351 }
2352
2353 A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD));
2354
2355 cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2356 A_MEMZERO(cc, sizeof(*cc));
2357
2358 if (ssidLength)
2359 {
2360 memcpy(cc->ssid, ssid, ssidLength);
2361 }
2362
2363 cc->ssidLength = ssidLength;
2364 cc->networkType = netType;
2365 cc->dot11AuthMode = dot11AuthMode;
2366 cc->authMode = authMode;
2367 cc->pairwiseCryptoType = pairwiseCrypto;
2368 cc->pairwiseCryptoLen = pairwiseCryptoLen;
2369 cc->groupCryptoType = groupCrypto;
2370 cc->groupCryptoLen = groupCryptoLen;
2371 cc->channel = channel;
2372 cc->ctrl_flags = ctrl_flags;
2373
2374 if (bssid != NULL) {
2375 memcpy(cc->bssid, bssid, ATH_MAC_LEN);
2376 }
2377
2378 wmip->wmi_pair_crypto_type = pairwiseCrypto;
2379 wmip->wmi_grp_crypto_type = groupCrypto;
2380
2381 return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG));
2382}
2383
2384int
2385wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, u16 channel)
2386{
2387 void *osbuf;
2388 WMI_RECONNECT_CMD *cc;
2389 wmip->wmi_traffic_class = 100;
2390
2391 osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD));
2392 if (osbuf == NULL) {
2393 return A_NO_MEMORY;
2394 }
2395
2396 A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD));
2397
2398 cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2399 A_MEMZERO(cc, sizeof(*cc));
2400
2401 cc->channel = channel;
2402
2403 if (bssid != NULL) {
2404 memcpy(cc->bssid, bssid, ATH_MAC_LEN);
2405 }
2406
2407 return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG));
2408}
2409
2410int
2411wmi_disconnect_cmd(struct wmi_t *wmip)
2412{
2413 int status;
2414 wmip->wmi_traffic_class = 100;
2415
2416 /* Bug fix for 24817(elevator bug) - the disconnect command does not
2417 need to do a SYNC before.*/
2418 status = wmi_simple_cmd(wmip, WMI_DISCONNECT_CMDID);
2419
2420 return status;
2421}
2422
2423int
2424wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
2425 u32 forceFgScan, u32 isLegacy,
2426 u32 homeDwellTime, u32 forceScanInterval,
2427 s8 numChan, u16 *channelList)
2428{
2429 void *osbuf;
2430 WMI_START_SCAN_CMD *sc;
2431 s8 size;
2432
2433 size = sizeof (*sc);
2434
2435 if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) {
2436 return A_EINVAL;
2437 }
2438
2439 if (numChan) {
2440 if (numChan > WMI_MAX_CHANNELS) {
2441 return A_EINVAL;
2442 }
2443 size += sizeof(u16) * (numChan - 1);
2444 }
2445
2446 osbuf = A_NETBUF_ALLOC(size);
2447 if (osbuf == NULL) {
2448 return A_NO_MEMORY;
2449 }
2450
2451 A_NETBUF_PUT(osbuf, size);
2452
2453 sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf));
2454 sc->scanType = scanType;
2455 sc->forceFgScan = forceFgScan;
2456 sc->isLegacy = isLegacy;
2457 sc->homeDwellTime = homeDwellTime;
2458 sc->forceScanInterval = forceScanInterval;
2459 sc->numChannels = numChan;
2460 if (numChan) {
2461 memcpy(sc->channelList, channelList, numChan * sizeof(u16));
2462 }
2463
2464 return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG));
2465}
2466
2467int
2468wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec,
2469 u16 fg_end_sec, u16 bg_sec,
2470 u16 minact_chdw_msec, u16 maxact_chdw_msec,
2471 u16 pas_chdw_msec,
2472 u8 shScanRatio, u8 scanCtrlFlags,
2473 u32 max_dfsch_act_time, u16 maxact_scan_per_ssid)
2474{
2475 void *osbuf;
2476 WMI_SCAN_PARAMS_CMD *sc;
2477
2478 osbuf = A_NETBUF_ALLOC(sizeof(*sc));
2479 if (osbuf == NULL) {
2480 return A_NO_MEMORY;
2481 }
2482
2483 A_NETBUF_PUT(osbuf, sizeof(*sc));
2484
2485 sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2486 A_MEMZERO(sc, sizeof(*sc));
2487 sc->fg_start_period = fg_start_sec;
2488 sc->fg_end_period = fg_end_sec;
2489 sc->bg_period = bg_sec;
2490 sc->minact_chdwell_time = minact_chdw_msec;
2491 sc->maxact_chdwell_time = maxact_chdw_msec;
2492 sc->pas_chdwell_time = pas_chdw_msec;
2493 sc->shortScanRatio = shScanRatio;
2494 sc->scanCtrlFlags = scanCtrlFlags;
2495 sc->max_dfsch_act_time = max_dfsch_act_time;
2496 sc->maxact_scan_per_ssid = maxact_scan_per_ssid;
2497
2498 return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID,
2499 NO_SYNC_WMIFLAG));
2500}
2501
2502int
2503wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask)
2504{
2505 void *osbuf;
2506 WMI_BSS_FILTER_CMD *cmd;
2507
2508 if (filter >= LAST_BSS_FILTER) {
2509 return A_EINVAL;
2510 }
2511
2512 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2513 if (osbuf == NULL) {
2514 return A_NO_MEMORY;
2515 }
2516
2517 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2518
2519 cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
2520 A_MEMZERO(cmd, sizeof(*cmd));
2521 cmd->bssFilter = filter;
2522 cmd->ieMask = ieMask;
2523
2524 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID,
2525 NO_SYNC_WMIFLAG));
2526}
2527
2528int
2529wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag,
2530 u8 ssidLength, u8 *ssid)
2531{
2532 void *osbuf;
2533 WMI_PROBED_SSID_CMD *cmd;
2534
2535 if (index > MAX_PROBED_SSID_INDEX) {
2536 return A_EINVAL;
2537 }
2538 if (ssidLength > sizeof(cmd->ssid)) {
2539 return A_EINVAL;
2540 }
2541 if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) {
2542 return A_EINVAL;
2543 }
2544 if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) {
2545 return A_EINVAL;
2546 }
2547
2548 if (flag & SPECIFIC_SSID_FLAG) {
2549 is_probe_ssid = true;
2550 }
2551
2552 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2553 if (osbuf == NULL) {
2554 return A_NO_MEMORY;
2555 }
2556
2557 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2558
2559 cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf));
2560 A_MEMZERO(cmd, sizeof(*cmd));
2561 cmd->entryIndex = index;
2562 cmd->flag = flag;
2563 cmd->ssidLength = ssidLength;
2564 memcpy(cmd->ssid, ssid, ssidLength);
2565
2566 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID,
2567 NO_SYNC_WMIFLAG));
2568}
2569
2570int
2571wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons)
2572{
2573 void *osbuf;
2574 WMI_LISTEN_INT_CMD *cmd;
2575
2576 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2577 if (osbuf == NULL) {
2578 return A_NO_MEMORY;
2579 }
2580
2581 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2582
2583 cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf));
2584 A_MEMZERO(cmd, sizeof(*cmd));
2585 cmd->listenInterval = listenInterval;
2586 cmd->numBeacons = listenBeacons;
2587
2588 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID,
2589 NO_SYNC_WMIFLAG));
2590}
2591
2592int
2593wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmissTime, u16 bmissBeacons)
2594{
2595 void *osbuf;
2596 WMI_BMISS_TIME_CMD *cmd;
2597
2598 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2599 if (osbuf == NULL) {
2600 return A_NO_MEMORY;
2601 }
2602
2603 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2604
2605 cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf));
2606 A_MEMZERO(cmd, sizeof(*cmd));
2607 cmd->bmissTime = bmissTime;
2608 cmd->numBeacons = bmissBeacons;
2609
2610 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID,
2611 NO_SYNC_WMIFLAG));
2612}
2613
2614int
2615wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType,
2616 u8 ieLen, u8 *ieInfo)
2617{
2618 void *osbuf;
2619 WMI_SET_ASSOC_INFO_CMD *cmd;
2620 u16 cmdLen;
2621
2622 cmdLen = sizeof(*cmd) + ieLen - 1;
2623 osbuf = A_NETBUF_ALLOC(cmdLen);
2624 if (osbuf == NULL) {
2625 return A_NO_MEMORY;
2626 }
2627
2628 A_NETBUF_PUT(osbuf, cmdLen);
2629
2630 cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf));
2631 A_MEMZERO(cmd, cmdLen);
2632 cmd->ieType = ieType;
2633 cmd->bufferSize = ieLen;
2634 memcpy(cmd->assocInfo, ieInfo, ieLen);
2635
2636 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID,
2637 NO_SYNC_WMIFLAG));
2638}
2639
2640int
2641wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode)
2642{
2643 void *osbuf;
2644 WMI_POWER_MODE_CMD *cmd;
2645
2646 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2647 if (osbuf == NULL) {
2648 return A_NO_MEMORY;
2649 }
2650
2651 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2652
2653 cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf));
2654 A_MEMZERO(cmd, sizeof(*cmd));
2655 cmd->powerMode = powerMode;
2656 wmip->wmi_powerMode = powerMode;
2657
2658 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID,
2659 NO_SYNC_WMIFLAG));
2660}
2661
2662int
2663wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl,
2664 u16 atim_windows, u16 timeout_value)
2665{
2666 void *osbuf;
2667 WMI_IBSS_PM_CAPS_CMD *cmd;
2668
2669 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2670 if (osbuf == NULL) {
2671 return A_NO_MEMORY;
2672 }
2673
2674 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2675
2676 cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf));
2677 A_MEMZERO(cmd, sizeof(*cmd));
2678 cmd->power_saving = pmEnable;
2679 cmd->ttl = ttl;
2680 cmd->atim_windows = atim_windows;
2681 cmd->timeout_value = timeout_value;
2682
2683 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID,
2684 NO_SYNC_WMIFLAG));
2685}
2686
2687int
2688wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time,
2689 u32 ps_period, u8 sleep_period)
2690{
2691 void *osbuf;
2692 WMI_AP_PS_CMD *cmd;
2693
2694 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2695 if (osbuf == NULL) {
2696 return A_NO_MEMORY;
2697 }
2698
2699 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2700
2701 cmd = (WMI_AP_PS_CMD *)(A_NETBUF_DATA(osbuf));
2702 A_MEMZERO(cmd, sizeof(*cmd));
2703 cmd->psType = psType;
2704 cmd->idle_time = idle_time;
2705 cmd->ps_period = ps_period;
2706 cmd->sleep_period = sleep_period;
2707
2708 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AP_PS_CMDID,
2709 NO_SYNC_WMIFLAG));
2710}
2711
2712int
2713wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod,
2714 u16 psPollNum, u16 dtimPolicy,
2715 u16 tx_wakeup_policy, u16 num_tx_to_wakeup,
2716 u16 ps_fail_event_policy)
2717{
2718 void *osbuf;
2719 WMI_POWER_PARAMS_CMD *pm;
2720
2721 osbuf = A_NETBUF_ALLOC(sizeof(*pm));
2722 if (osbuf == NULL) {
2723 return A_NO_MEMORY;
2724 }
2725
2726 A_NETBUF_PUT(osbuf, sizeof(*pm));
2727
2728 pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2729 A_MEMZERO(pm, sizeof(*pm));
2730 pm->idle_period = idlePeriod;
2731 pm->pspoll_number = psPollNum;
2732 pm->dtim_policy = dtimPolicy;
2733 pm->tx_wakeup_policy = tx_wakeup_policy;
2734 pm->num_tx_to_wakeup = num_tx_to_wakeup;
2735 pm->ps_fail_event_policy = ps_fail_event_policy;
2736
2737 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID,
2738 NO_SYNC_WMIFLAG));
2739}
2740
2741int
2742wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout)
2743{
2744 void *osbuf;
2745 WMI_DISC_TIMEOUT_CMD *cmd;
2746
2747 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2748 if (osbuf == NULL) {
2749 return A_NO_MEMORY;
2750 }
2751
2752 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2753
2754 cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf));
2755 A_MEMZERO(cmd, sizeof(*cmd));
2756 cmd->disconnectTimeout = timeout;
2757
2758 return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID,
2759 NO_SYNC_WMIFLAG));
2760}
2761
2762int
2763wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex, CRYPTO_TYPE keyType,
2764 u8 keyUsage, u8 keyLength, u8 *keyRSC,
2765 u8 *keyMaterial, u8 key_op_ctrl, u8 *macAddr,
2766 WMI_SYNC_FLAG sync_flag)
2767{
2768 void *osbuf;
2769 WMI_ADD_CIPHER_KEY_CMD *cmd;
2770
2771 if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) ||
2772 (keyMaterial == NULL))
2773 {
2774 return A_EINVAL;
2775 }
2776
2777 if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) {
2778 return A_EINVAL;
2779 }
2780
2781 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2782 if (osbuf == NULL) {
2783 return A_NO_MEMORY;
2784 }
2785
2786 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2787
2788 cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2789 A_MEMZERO(cmd, sizeof(*cmd));
2790 cmd->keyIndex = keyIndex;
2791 cmd->keyType = keyType;
2792 cmd->keyUsage = keyUsage;
2793 cmd->keyLength = keyLength;
2794 memcpy(cmd->key, keyMaterial, keyLength);
2795#ifdef WAPI_ENABLE
2796 if (NULL != keyRSC && key_op_ctrl != KEY_OP_INIT_WAPIPN) {
2797#else
2798 if (NULL != keyRSC) {
2799#endif // WAPI_ENABLE
2800 memcpy(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC));
2801 }
2802 cmd->key_op_ctrl = key_op_ctrl;
2803
2804 if(macAddr) {
2805 memcpy(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN);
2806 }
2807
2808 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag));
2809}
2810
2811int
2812wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk)
2813{
2814 void *osbuf;
2815 WMI_ADD_KRK_CMD *cmd;
2816
2817 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2818 if (osbuf == NULL) {
2819 return A_NO_MEMORY;
2820 }
2821
2822 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2823
2824 cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf));
2825 A_MEMZERO(cmd, sizeof(*cmd));
2826 memcpy(cmd->krk, krk, WMI_KRK_LEN);
2827
2828 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG));
2829}
2830
2831int
2832wmi_delete_krk_cmd(struct wmi_t *wmip)
2833{
2834 return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID);
2835}
2836
2837int
2838wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex)
2839{
2840 void *osbuf;
2841 WMI_DELETE_CIPHER_KEY_CMD *cmd;
2842
2843 if (keyIndex > WMI_MAX_KEY_INDEX) {
2844 return A_EINVAL;
2845 }
2846
2847 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2848 if (osbuf == NULL) {
2849 return A_NO_MEMORY;
2850 }
2851
2852 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2853
2854 cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2855 A_MEMZERO(cmd, sizeof(*cmd));
2856 cmd->keyIndex = keyIndex;
2857
2858 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID,
2859 NO_SYNC_WMIFLAG));
2860}
2861
2862int
2863wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId,
2864 bool set)
2865{
2866 void *osbuf;
2867 WMI_SET_PMKID_CMD *cmd;
2868
2869 if (bssid == NULL) {
2870 return A_EINVAL;
2871 }
2872
2873 if ((set == true) && (pmkId == NULL)) {
2874 return A_EINVAL;
2875 }
2876
2877 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2878 if (osbuf == NULL) {
2879 return A_NO_MEMORY;
2880 }
2881
2882 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2883
2884 cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf));
2885 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
2886 if (set == true) {
2887 memcpy(cmd->pmkid, pmkId, sizeof(cmd->pmkid));
2888 cmd->enable = PMKID_ENABLE;
2889 } else {
2890 A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid));
2891 cmd->enable = PMKID_DISABLE;
2892 }
2893
2894 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG));
2895}
2896
2897int
2898wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en)
2899{
2900 void *osbuf;
2901 WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd;
2902
2903 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2904 if (osbuf == NULL) {
2905 return A_NO_MEMORY;
2906 }
2907
2908 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2909
2910 cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf));
2911 cmd->cm_en = (en == true)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE;
2912
2913 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID,
2914 NO_SYNC_WMIFLAG));
2915}
2916
2917int
2918wmi_set_akmp_params_cmd(struct wmi_t *wmip,
2919 WMI_SET_AKMP_PARAMS_CMD *akmpParams)
2920{
2921 void *osbuf;
2922 WMI_SET_AKMP_PARAMS_CMD *cmd;
2923
2924 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2925 if (osbuf == NULL) {
2926 return A_NO_MEMORY;
2927 }
2928
2929 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2930 cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2931 cmd->akmpInfo = akmpParams->akmpInfo;
2932
2933 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID,
2934 NO_SYNC_WMIFLAG));
2935}
2936
2937int
2938wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
2939 WMI_SET_PMKID_LIST_CMD *pmkInfo)
2940{
2941 void *osbuf;
2942 WMI_SET_PMKID_LIST_CMD *cmd;
2943 u16 cmdLen;
2944 u8 i;
2945
2946 cmdLen = sizeof(pmkInfo->numPMKID) +
2947 pmkInfo->numPMKID * sizeof(WMI_PMKID);
2948
2949 osbuf = A_NETBUF_ALLOC(cmdLen);
2950 if (osbuf == NULL) {
2951 return A_NO_MEMORY;
2952 }
2953
2954 A_NETBUF_PUT(osbuf, cmdLen);
2955 cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf));
2956 cmd->numPMKID = pmkInfo->numPMKID;
2957
2958 for (i = 0; i < cmd->numPMKID; i++) {
2959 memcpy(&cmd->pmkidList[i], &pmkInfo->pmkidList[i],
2960 WMI_PMKID_LEN);
2961 }
2962
2963 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID,
2964 NO_SYNC_WMIFLAG));
2965}
2966
2967int
2968wmi_get_pmkid_list_cmd(struct wmi_t *wmip)
2969{
2970 return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID);
2971}
2972
2973int
2974wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid)
2975{
2976 WMI_DATA_HDR *dtHdr;
2977
2978 A_ASSERT( eid != wmip->wmi_endpoint_id);
2979 A_ASSERT(osbuf != NULL);
2980
2981 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) {
2982 return A_NO_MEMORY;
2983 }
2984
2985 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
2986 dtHdr->info =
2987 (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT;
2988
2989 dtHdr->info3 = 0;
2990 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid));
2991
2992 return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid));
2993}
2994
2995typedef struct _WMI_DATA_SYNC_BUFS {
2996 u8 trafficClass;
2997 void *osbuf;
2998}WMI_DATA_SYNC_BUFS;
2999
3000static int
3001wmi_sync_point(struct wmi_t *wmip)
3002{
3003 void *cmd_osbuf;
3004 WMI_SYNC_CMD *cmd;
3005 WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC];
3006 u8 i,numPriStreams=0;
3007 int status = 0;
3008
3009 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
3010
3011 memset(dataSyncBufs,0,sizeof(dataSyncBufs));
3012
3013 /* lock out while we walk through the priority list and assemble our local array */
3014 LOCK_WMI(wmip);
3015
3016 for (i=0; i < WMM_NUM_AC ; i++) {
3017 if (wmip->wmi_fatPipeExists & (1 << i)) {
3018 numPriStreams++;
3019 dataSyncBufs[numPriStreams-1].trafficClass = i;
3020 }
3021 }
3022
3023 UNLOCK_WMI(wmip);
3024
3025 /* dataSyncBufs is now filled with entries (starting at index 0) containing valid streamIDs */
3026
3027 do {
3028 /*
3029 * We allocate all network buffers needed so we will be able to
3030 * send all required frames.
3031 */
3032 cmd_osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3033 if (cmd_osbuf == NULL) {
3034 status = A_NO_MEMORY;
3035 break;
3036 }
3037
3038 A_NETBUF_PUT(cmd_osbuf, sizeof(*cmd));
3039
3040 cmd = (WMI_SYNC_CMD *)(A_NETBUF_DATA(cmd_osbuf));
3041 A_MEMZERO(cmd, sizeof(*cmd));
3042
3043 /* In the SYNC cmd sent on the control Ep, send a bitmap of the data
3044 * eps on which the Data Sync will be sent
3045 */
3046 cmd->dataSyncMap = wmip->wmi_fatPipeExists;
3047
3048 for (i=0; i < numPriStreams ; i++) {
3049 dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0);
3050 if (dataSyncBufs[i].osbuf == NULL) {
3051 status = A_NO_MEMORY;
3052 break;
3053 }
3054 } //end for
3055
3056 /* if Buffer allocation for any of the dataSync fails, then do not
3057 * send the Synchronize cmd on the control ep
3058 */
3059 if (status) {
3060 break;
3061 }
3062
3063 /*
3064 * Send sync cmd followed by sync data messages on all endpoints being
3065 * used
3066 */
3067 status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID,
3068 NO_SYNC_WMIFLAG);
3069
3070 if (status) {
3071 break;
3072 }
3073 /* cmd buffer sent, we no longer own it */
3074 cmd_osbuf = NULL;
3075
3076 for(i=0; i < numPriStreams; i++) {
3077 A_ASSERT(dataSyncBufs[i].osbuf != NULL);
3078 status = wmi_dataSync_send(wmip,
3079 dataSyncBufs[i].osbuf,
3080 A_WMI_Ac2EndpointID(wmip->wmi_devt,
3081 dataSyncBufs[i].
3082 trafficClass)
3083 );
3084
3085 if (status) {
3086 break;
3087 }
3088 /* we don't own this buffer anymore, NULL it out of the array so it
3089 * won't get cleaned up */
3090 dataSyncBufs[i].osbuf = NULL;
3091 } //end for
3092
3093 } while(false);
3094
3095 /* free up any resources left over (possibly due to an error) */
3096
3097 if (cmd_osbuf != NULL) {
3098 A_NETBUF_FREE(cmd_osbuf);
3099 }
3100
3101 for (i = 0; i < numPriStreams; i++) {
3102 if (dataSyncBufs[i].osbuf != NULL) {
3103 A_NETBUF_FREE(dataSyncBufs[i].osbuf);
3104 }
3105 }
3106
3107 return (status);
3108}
3109
3110int
3111wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params)
3112{
3113 void *osbuf;
3114 WMI_CREATE_PSTREAM_CMD *cmd;
3115 u8 fatPipeExistsForAC=0;
3116 s32 minimalPHY = 0;
3117 s32 nominalPHY = 0;
3118
3119 /* Validate all the parameters. */
3120 if( !((params->userPriority < 8) &&
3121 (params->userPriority <= 0x7) &&
3122 (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass) &&
3123 (params->trafficDirection == UPLINK_TRAFFIC ||
3124 params->trafficDirection == DNLINK_TRAFFIC ||
3125 params->trafficDirection == BIDIR_TRAFFIC) &&
3126 (params->trafficType == TRAFFIC_TYPE_APERIODIC ||
3127 params->trafficType == TRAFFIC_TYPE_PERIODIC ) &&
3128 (params->voicePSCapability == DISABLE_FOR_THIS_AC ||
3129 params->voicePSCapability == ENABLE_FOR_THIS_AC ||
3130 params->voicePSCapability == ENABLE_FOR_ALL_AC) &&
3131 (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINSTREAM)) )
3132 {
3133 return A_EINVAL;
3134 }
3135
3136 //
3137 // check nominal PHY rate is >= minimalPHY, so that DUT
3138 // can allow TSRS IE
3139 //
3140
3141 // get the physical rate
3142 minimalPHY = ((params->minPhyRate / 1000)/1000); // unit of bps
3143
3144 // check minimal phy < nominal phy rate
3145 //
3146 if (params->nominalPHY >= minimalPHY)
3147 {
3148 nominalPHY = (params->nominalPHY * 1000)/500; // unit of 500 kbps
3149 A_DPRINTF(DBG_WMI,
3150 (DBGFMT "TSRS IE Enabled::MinPhy %x->NominalPhy ===> %x\n", DBGARG,
3151 minimalPHY, nominalPHY));
3152
3153 params->nominalPHY = nominalPHY;
3154 }
3155 else
3156 {
3157 params->nominalPHY = 0;
3158 }
3159
3160 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3161 if (osbuf == NULL) {
3162 return A_NO_MEMORY;
3163 }
3164
3165 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3166
3167 A_DPRINTF(DBG_WMI,
3168 (DBGFMT "Sending create_pstream_cmd: ac=%d tsid:%d\n", DBGARG,
3169 params->trafficClass, params->tsid));
3170
3171 cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3172 A_MEMZERO(cmd, sizeof(*cmd));
3173 memcpy(cmd, params, sizeof(*cmd));
3174
3175 /* this is an implicitly created Fat pipe */
3176 if ((u32)params->tsid == (u32)WMI_IMPLICIT_PSTREAM) {
3177 LOCK_WMI(wmip);
3178 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3179 wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3180 UNLOCK_WMI(wmip);
3181 } else {
3182 /* this is an explicitly created thin stream within a fat pipe */
3183 LOCK_WMI(wmip);
3184 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3185 wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid);
3186 /* if a thinstream becomes active, the fat pipe automatically
3187 * becomes active
3188 */
3189 wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3190 UNLOCK_WMI(wmip);
3191 }
3192
3193 /* Indicate activty change to driver layer only if this is the
3194 * first TSID to get created in this AC explicitly or an implicit
3195 * fat pipe is getting created.
3196 */
3197 if (!fatPipeExistsForAC) {
3198 A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass);
3199 }
3200
3201 /* mike: should be SYNC_BEFORE_WMIFLAG */
3202 return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID,
3203 NO_SYNC_WMIFLAG));
3204}
3205
3206int
3207wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 tsid)
3208{
3209 void *osbuf;
3210 WMI_DELETE_PSTREAM_CMD *cmd;
3211 int status;
3212 u16 activeTsids=0;
3213
3214 /* validate the parameters */
3215 if (trafficClass > 3) {
3216 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid trafficClass: %d\n", DBGARG, trafficClass));
3217 return A_EINVAL;
3218 }
3219
3220 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3221 if (osbuf == NULL) {
3222 return A_NO_MEMORY;
3223 }
3224
3225 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3226
3227 cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3228 A_MEMZERO(cmd, sizeof(*cmd));
3229
3230 cmd->trafficClass = trafficClass;
3231 cmd->tsid = tsid;
3232
3233 LOCK_WMI(wmip);
3234 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3235 UNLOCK_WMI(wmip);
3236
3237 /* Check if the tsid was created & exists */
3238 if (!(activeTsids & (1<<tsid))) {
3239
3240 A_NETBUF_FREE(osbuf);
3241 A_DPRINTF(DBG_WMI,
3242 (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, trafficClass));
3243 /* TODO: return a more appropriate err code */
3244 return A_ERROR;
3245 }
3246
3247 A_DPRINTF(DBG_WMI,
3248 (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG, trafficClass, tsid));
3249
3250 status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID,
3251 SYNC_BEFORE_WMIFLAG));
3252
3253 LOCK_WMI(wmip);
3254 wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid);
3255 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3256 UNLOCK_WMI(wmip);
3257
3258
3259 /* Indicate stream inactivity to driver layer only if all tsids
3260 * within this AC are deleted.
3261 */
3262 if(!activeTsids) {
3263 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass);
3264 wmip->wmi_fatPipeExists &= ~(1<<trafficClass);
3265 }
3266
3267 return status;
3268}
3269
3270int
3271wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask)
3272{
3273 void *osbuf;
3274 WMI_FRAME_RATES_CMD *cmd;
3275 u8 frameType;
3276
3277 A_DPRINTF(DBG_WMI,
3278 (DBGFMT " type %02X, subType %02X, rateMask %04x\n", DBGARG, type, subType, rateMask));
3279
3280 if((type != IEEE80211_FRAME_TYPE_MGT && type != IEEE80211_FRAME_TYPE_CTL) ||
3281 (subType > 15)){
3282
3283 return A_EINVAL;
3284 }
3285
3286 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3287 if (osbuf == NULL) {
3288 return A_NO_MEMORY;
3289 }
3290
3291 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3292
3293 cmd = (WMI_FRAME_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3294 A_MEMZERO(cmd, sizeof(*cmd));
3295
3296 frameType = (u8)((subType << 4) | type);
3297
3298 cmd->bEnableMask = bEnable;
3299 cmd->frameType = frameType;
3300 cmd->frameRateMask = rateMask;
3301
3302 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FRAMERATES_CMDID, NO_SYNC_WMIFLAG));
3303}
3304
3305/*
3306 * used to set the bit rate. rate is in Kbps. If rate == -1
3307 * then auto selection is used.
3308 */
3309int
3310wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate)
3311{
3312 void *osbuf;
3313 WMI_BIT_RATE_CMD *cmd;
3314 s8 drix, mrix, crix, ret_val;
3315
3316 if (dataRate != -1) {
3317 ret_val = wmi_validate_bitrate(wmip, dataRate, &drix);
3318 if(ret_val == A_EINVAL){
3319 return A_EINVAL;
3320 }
3321 } else {
3322 drix = -1;
3323 }
3324
3325 if (mgmtRate != -1) {
3326 ret_val = wmi_validate_bitrate(wmip, mgmtRate, &mrix);
3327 if(ret_val == A_EINVAL){
3328 return A_EINVAL;
3329 }
3330 } else {
3331 mrix = -1;
3332 }
3333 if (ctlRate != -1) {
3334 ret_val = wmi_validate_bitrate(wmip, ctlRate, &crix);
3335 if(ret_val == A_EINVAL){
3336 return A_EINVAL;
3337 }
3338 } else {
3339 crix = -1;
3340 }
3341 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3342 if (osbuf == NULL) {
3343 return A_NO_MEMORY;
3344 }
3345
3346 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3347
3348 cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf));
3349 A_MEMZERO(cmd, sizeof(*cmd));
3350
3351 cmd->rateIndex = drix;
3352 cmd->mgmtRateIndex = mrix;
3353 cmd->ctlRateIndex = crix;
3354
3355
3356 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
3357}
3358
3359int
3360wmi_get_bitrate_cmd(struct wmi_t *wmip)
3361{
3362 return wmi_simple_cmd(wmip, WMI_GET_BITRATE_CMDID);
3363}
3364
3365/*
3366 * Returns true iff the given rate index is legal in the current PHY mode.
3367 */
3368bool
3369wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex)
3370{
3371 WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode;
3372 bool isValid = true;
3373 switch(phyMode) {
3374 case WMI_11A_MODE:
3375 if (wmip->wmi_ht_allowed[A_BAND_5GHZ]){
3376 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3377 isValid = false;
3378 }
3379 } else {
3380 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) {
3381 isValid = false;
3382 }
3383 }
3384 break;
3385
3386 case WMI_11B_MODE:
3387 if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) {
3388 isValid = false;
3389 }
3390 break;
3391
3392 case WMI_11GONLY_MODE:
3393 if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3394 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3395 isValid = false;
3396 }
3397 } else {
3398 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) {
3399 isValid = false;
3400 }
3401 }
3402 break;
3403
3404 case WMI_11G_MODE:
3405 case WMI_11AG_MODE:
3406 if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3407 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3408 isValid = false;
3409 }
3410 } else {
3411 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) {
3412 isValid = false;
3413 }
3414 }
3415 break;
3416 default:
3417 A_ASSERT(false);
3418 break;
3419 }
3420
3421 return isValid;
3422}
3423
3424s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx)
3425{
3426 s8 i;
3427
3428 for (i=0;;i++)
3429 {
3430 if (wmi_rateTable[(u32) i][0] == 0) {
3431 return A_EINVAL;
3432 }
3433 if (wmi_rateTable[(u32) i][0] == rate) {
3434 break;
3435 }
3436 }
3437
3438 if(wmi_is_bitrate_index_valid(wmip, (s32) i) != true) {
3439 return A_EINVAL;
3440 }
3441
3442 *rate_idx = i;
3443 return 0;
3444}
3445
3446int
3447wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask)
3448{
3449 void *osbuf;
3450 WMI_FIX_RATES_CMD *cmd;
3451#if 0
3452 s32 rateIndex;
3453/* This check does not work for AR6003 as the HT modes are enabled only when
3454 * the STA is connected to a HT_BSS and is not based only on channel. It is
3455 * safe to skip this check however because rate control will only use rates
3456 * that are permitted by the valid rate mask and the fix rate mask. Meaning
3457 * the fix rate mask is not sufficient by itself to cause an invalid rate
3458 * to be used. */
3459 /* Make sure all rates in the mask are valid in the current PHY mode */
3460 for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) {
3461 if((1 << rateIndex) & (u32)fixRatesMask) {
3462 if(wmi_is_bitrate_index_valid(wmip, rateIndex) != true) {
3463 A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG));
3464 return A_EINVAL;
3465 }
3466 }
3467 }
3468#endif
3469
3470
3471 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3472 if (osbuf == NULL) {
3473 return A_NO_MEMORY;
3474 }
3475
3476 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3477
3478 cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3479 A_MEMZERO(cmd, sizeof(*cmd));
3480
3481 cmd->fixRateMask = fixRatesMask;
3482
3483 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG));
3484}
3485
3486int
3487wmi_get_ratemask_cmd(struct wmi_t *wmip)
3488{
3489 return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID);
3490}
3491
3492int
3493wmi_get_channelList_cmd(struct wmi_t *wmip)
3494{
3495 return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID);
3496}
3497
3498/*
3499 * used to generate a wmi sey channel Parameters cmd.
3500 * mode should always be specified and corresponds to the phy mode of the
3501 * wlan.
3502 * numChan should alway sbe specified. If zero indicates that all available
3503 * channels should be used.
3504 * channelList is an array of channel frequencies (in Mhz) which the radio
3505 * should limit its operation to. It should be NULL if numChan == 0. Size of
3506 * array should correspond to numChan entries.
3507 */
3508int
3509wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam,
3510 WMI_PHY_MODE mode, s8 numChan,
3511 u16 *channelList)
3512{
3513 void *osbuf;
3514 WMI_CHANNEL_PARAMS_CMD *cmd;
3515 s8 size;
3516
3517 size = sizeof (*cmd);
3518
3519 if (numChan) {
3520 if (numChan > WMI_MAX_CHANNELS) {
3521 return A_EINVAL;
3522 }
3523 size += sizeof(u16) * (numChan - 1);
3524 }
3525
3526 osbuf = A_NETBUF_ALLOC(size);
3527 if (osbuf == NULL) {
3528 return A_NO_MEMORY;
3529 }
3530
3531 A_NETBUF_PUT(osbuf, size);
3532
3533 cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3534 A_MEMZERO(cmd, size);
3535
3536 wmip->wmi_phyMode = mode;
3537 cmd->scanParam = scanParam;
3538 cmd->phyMode = mode;
3539 cmd->numChannels = numChan;
3540 memcpy(cmd->channelList, channelList, numChan * sizeof(u16));
3541
3542 return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
3543 NO_SYNC_WMIFLAG));
3544}
3545
3546void
3547wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3548{
3549 SQ_THRESHOLD_PARAMS *sq_thresh =
3550 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
3551 /*
3552 * Parse the command and store the threshold values here. The checks
3553 * for valid values can be put here
3554 */
3555 sq_thresh->weight = rssiCmd->weight;
3556 sq_thresh->polling_interval = rssiCmd->pollTime;
3557
3558 sq_thresh->upper_threshold[0] = rssiCmd->thresholdAbove1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3559 sq_thresh->upper_threshold[1] = rssiCmd->thresholdAbove2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3560 sq_thresh->upper_threshold[2] = rssiCmd->thresholdAbove3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3561 sq_thresh->upper_threshold[3] = rssiCmd->thresholdAbove4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3562 sq_thresh->upper_threshold[4] = rssiCmd->thresholdAbove5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3563 sq_thresh->upper_threshold[5] = rssiCmd->thresholdAbove6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3564 sq_thresh->upper_threshold_valid_count = 6;
3565
3566 /* List sorted in descending order */
3567 sq_thresh->lower_threshold[0] = rssiCmd->thresholdBelow6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3568 sq_thresh->lower_threshold[1] = rssiCmd->thresholdBelow5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3569 sq_thresh->lower_threshold[2] = rssiCmd->thresholdBelow4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3570 sq_thresh->lower_threshold[3] = rssiCmd->thresholdBelow3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3571 sq_thresh->lower_threshold[4] = rssiCmd->thresholdBelow2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3572 sq_thresh->lower_threshold[5] = rssiCmd->thresholdBelow1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3573 sq_thresh->lower_threshold_valid_count = 6;
3574
3575 if (!rssi_event_value) {
3576 /*
3577 * Configuring the thresholds to their extremes allows the host to get an
3578 * event from the target which is used for the configuring the correct
3579 * thresholds
3580 */
3581 rssiCmd->thresholdAbove1_Val = sq_thresh->upper_threshold[0];
3582 rssiCmd->thresholdBelow1_Val = sq_thresh->lower_threshold[0];
3583 } else {
3584 /*
3585 * In case the user issues multiple times of rssi_threshold_setting,
3586 * we should not use the extreames anymore, the target does not expect that.
3587 */
3588 rssiCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(rssi_event_value, sq_thresh,
3589 sq_thresh->upper_threshold_valid_count);
3590 rssiCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(rssi_event_value, sq_thresh,
3591 sq_thresh->lower_threshold_valid_count);
3592}
3593}
3594
3595int
3596wmi_set_rssi_threshold_params(struct wmi_t *wmip,
3597 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3598{
3599
3600 /* Check these values are in ascending order */
3601 if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val ||
3602 rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val ||
3603 rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val ||
3604 rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val ||
3605 rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val ||
3606 rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val ||
3607 rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val ||
3608 rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val ||
3609 rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val ||
3610 rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val)
3611 {
3612 return A_EINVAL;
3613 }
3614
3615 wmi_cache_configure_rssithreshold(wmip, rssiCmd);
3616
3617 return (wmi_send_rssi_threshold_params(wmip, rssiCmd));
3618}
3619
3620int
3621wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd)
3622{
3623 void *osbuf;
3624 WMI_SET_IP_CMD *cmd;
3625
3626 /* Multicast address are not valid */
3627 if((*((u8 *)&ipCmd->ips[0]) >= 0xE0) ||
3628 (*((u8 *)&ipCmd->ips[1]) >= 0xE0)) {
3629 return A_EINVAL;
3630 }
3631
3632 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_IP_CMD));
3633 if (osbuf == NULL) {
3634 return A_NO_MEMORY;
3635 }
3636
3637 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD));
3638 cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf));
3639 memcpy(cmd, ipCmd, sizeof(WMI_SET_IP_CMD));
3640
3641 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID,
3642 NO_SYNC_WMIFLAG));
3643}
3644
3645int
3646wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip,
3647 WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd)
3648{
3649 void *osbuf;
3650 s8 size;
3651 WMI_SET_HOST_SLEEP_MODE_CMD *cmd;
3652 u16 activeTsids=0;
3653 u8 streamExists=0;
3654 u8 i;
3655
3656 if( hostModeCmd->awake == hostModeCmd->asleep) {
3657 return A_EINVAL;
3658 }
3659
3660 size = sizeof (*cmd);
3661
3662 osbuf = A_NETBUF_ALLOC(size);
3663 if (osbuf == NULL) {
3664 return A_NO_MEMORY;
3665 }
3666
3667 A_NETBUF_PUT(osbuf, size);
3668
3669 cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3670 A_MEMZERO(cmd, size);
3671 memcpy(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD));
3672
3673 if(hostModeCmd->asleep) {
3674 /*
3675 * Relinquish credits from all implicitly created pstreams since when we
3676 * go to sleep. If user created explicit thinstreams exists with in a
3677 * fatpipe leave them intact for the user to delete
3678 */
3679 LOCK_WMI(wmip);
3680 streamExists = wmip->wmi_fatPipeExists;
3681 UNLOCK_WMI(wmip);
3682
3683 for(i=0;i< WMM_NUM_AC;i++) {
3684 if (streamExists & (1<<i)) {
3685 LOCK_WMI(wmip);
3686 activeTsids = wmip->wmi_streamExistsForAC[i];
3687 UNLOCK_WMI(wmip);
3688 /* If there are no user created thin streams delete the fatpipe */
3689 if(!activeTsids) {
3690 streamExists &= ~(1<<i);
3691 /*Indicate inactivity to drv layer for this fatpipe(pstream)*/
3692 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt,i);
3693 }
3694 }
3695 }
3696
3697 /* Update the fatpipes that exists*/
3698 LOCK_WMI(wmip);
3699 wmip->wmi_fatPipeExists = streamExists;
3700 UNLOCK_WMI(wmip);
3701 }
3702
3703 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID,
3704 NO_SYNC_WMIFLAG));
3705}
3706
3707int
3708wmi_set_wow_mode_cmd(struct wmi_t *wmip,
3709 WMI_SET_WOW_MODE_CMD *wowModeCmd)
3710{
3711 void *osbuf;
3712 s8 size;
3713 WMI_SET_WOW_MODE_CMD *cmd;
3714
3715 size = sizeof (*cmd);
3716
3717 osbuf = A_NETBUF_ALLOC(size);
3718 if (osbuf == NULL) {
3719 return A_NO_MEMORY;
3720 }
3721
3722 A_NETBUF_PUT(osbuf, size);
3723
3724 cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3725 A_MEMZERO(cmd, size);
3726 memcpy(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD));
3727
3728 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID,
3729 NO_SYNC_WMIFLAG));
3730
3731}
3732
3733int
3734wmi_get_wow_list_cmd(struct wmi_t *wmip,
3735 WMI_GET_WOW_LIST_CMD *wowListCmd)
3736{
3737 void *osbuf;
3738 s8 size;
3739 WMI_GET_WOW_LIST_CMD *cmd;
3740
3741 size = sizeof (*cmd);
3742
3743 osbuf = A_NETBUF_ALLOC(size);
3744 if (osbuf == NULL) {
3745 return A_NO_MEMORY;
3746 }
3747
3748 A_NETBUF_PUT(osbuf, size);
3749
3750 cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf));
3751 A_MEMZERO(cmd, size);
3752 memcpy(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD));
3753
3754 return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID,
3755 NO_SYNC_WMIFLAG));
3756
3757}
3758
3759static int
3760wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, int len)
3761{
3762 WMI_GET_WOW_LIST_REPLY *reply;
3763
3764 if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) {
3765 return A_EINVAL;
3766 }
3767 reply = (WMI_GET_WOW_LIST_REPLY *)datap;
3768
3769 A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters,
3770 reply);
3771
3772 return 0;
3773}
3774
3775int wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
3776 WMI_ADD_WOW_PATTERN_CMD *addWowCmd,
3777 u8 *pattern, u8 *mask,
3778 u8 pattern_size)
3779{
3780 void *osbuf;
3781 s8 size;
3782 WMI_ADD_WOW_PATTERN_CMD *cmd;
3783 u8 *filter_mask = NULL;
3784
3785 size = sizeof (*cmd);
3786
3787 size += ((2 * addWowCmd->filter_size)* sizeof(u8));
3788 osbuf = A_NETBUF_ALLOC(size);
3789 if (osbuf == NULL) {
3790 return A_NO_MEMORY;
3791 }
3792
3793 A_NETBUF_PUT(osbuf, size);
3794
3795 cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3796 cmd->filter_list_id = addWowCmd->filter_list_id;
3797 cmd->filter_offset = addWowCmd->filter_offset;
3798 cmd->filter_size = addWowCmd->filter_size;
3799
3800 memcpy(cmd->filter, pattern, addWowCmd->filter_size);
3801
3802 filter_mask = (u8 *)(cmd->filter + cmd->filter_size);
3803 memcpy(filter_mask, mask, addWowCmd->filter_size);
3804
3805
3806 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID,
3807 NO_SYNC_WMIFLAG));
3808}
3809
3810int
3811wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
3812 WMI_DEL_WOW_PATTERN_CMD *delWowCmd)
3813{
3814 void *osbuf;
3815 s8 size;
3816 WMI_DEL_WOW_PATTERN_CMD *cmd;
3817
3818 size = sizeof (*cmd);
3819
3820 osbuf = A_NETBUF_ALLOC(size);
3821 if (osbuf == NULL) {
3822 return A_NO_MEMORY;
3823 }
3824
3825 A_NETBUF_PUT(osbuf, size);
3826
3827 cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3828 A_MEMZERO(cmd, size);
3829 memcpy(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD));
3830
3831 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID,
3832 NO_SYNC_WMIFLAG));
3833
3834}
3835
3836void
3837wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3838{
3839 SQ_THRESHOLD_PARAMS *sq_thresh =
3840 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
3841 /*
3842 * Parse the command and store the threshold values here. The checks
3843 * for valid values can be put here
3844 */
3845 sq_thresh->weight = snrCmd->weight;
3846 sq_thresh->polling_interval = snrCmd->pollTime;
3847
3848 sq_thresh->upper_threshold[0] = snrCmd->thresholdAbove1_Val;
3849 sq_thresh->upper_threshold[1] = snrCmd->thresholdAbove2_Val;
3850 sq_thresh->upper_threshold[2] = snrCmd->thresholdAbove3_Val;
3851 sq_thresh->upper_threshold[3] = snrCmd->thresholdAbove4_Val;
3852 sq_thresh->upper_threshold_valid_count = 4;
3853
3854 /* List sorted in descending order */
3855 sq_thresh->lower_threshold[0] = snrCmd->thresholdBelow4_Val;
3856 sq_thresh->lower_threshold[1] = snrCmd->thresholdBelow3_Val;
3857 sq_thresh->lower_threshold[2] = snrCmd->thresholdBelow2_Val;
3858 sq_thresh->lower_threshold[3] = snrCmd->thresholdBelow1_Val;
3859 sq_thresh->lower_threshold_valid_count = 4;
3860
3861 if (!snr_event_value) {
3862 /*
3863 * Configuring the thresholds to their extremes allows the host to get an
3864 * event from the target which is used for the configuring the correct
3865 * thresholds
3866 */
3867 snrCmd->thresholdAbove1_Val = (u8)sq_thresh->upper_threshold[0];
3868 snrCmd->thresholdBelow1_Val = (u8)sq_thresh->lower_threshold[0];
3869 } else {
3870 /*
3871 * In case the user issues multiple times of snr_threshold_setting,
3872 * we should not use the extreames anymore, the target does not expect that.
3873 */
3874 snrCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(snr_event_value, sq_thresh,
3875 sq_thresh->upper_threshold_valid_count);
3876 snrCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(snr_event_value, sq_thresh,
3877 sq_thresh->lower_threshold_valid_count);
3878 }
3879
3880}
3881int
3882wmi_set_snr_threshold_params(struct wmi_t *wmip,
3883 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3884{
3885 if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val ||
3886 snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val ||
3887 snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val ||
3888 snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val ||
3889 snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val ||
3890 snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val)
3891 {
3892 return A_EINVAL;
3893 }
3894 wmi_cache_configure_snrthreshold(wmip, snrCmd);
3895 return (wmi_send_snr_threshold_params(wmip, snrCmd));
3896}
3897
3898int
3899wmi_clr_rssi_snr(struct wmi_t *wmip)
3900{
3901 void *osbuf;
3902
3903 osbuf = A_NETBUF_ALLOC(sizeof(int));
3904 if (osbuf == NULL) {
3905 return A_NO_MEMORY;
3906 }
3907
3908 return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID,
3909 NO_SYNC_WMIFLAG));
3910}
3911
3912int
3913wmi_set_lq_threshold_params(struct wmi_t *wmip,
3914 WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd)
3915{
3916 void *osbuf;
3917 s8 size;
3918 WMI_LQ_THRESHOLD_PARAMS_CMD *cmd;
3919 /* These values are in ascending order */
3920 if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val ||
3921 lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val ||
3922 lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val ||
3923 lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val ||
3924 lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val ||
3925 lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) {
3926
3927 return A_EINVAL;
3928 }
3929
3930 size = sizeof (*cmd);
3931
3932 osbuf = A_NETBUF_ALLOC(size);
3933 if (osbuf == NULL) {
3934 return A_NO_MEMORY;
3935 }
3936
3937 A_NETBUF_PUT(osbuf, size);
3938
3939 cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3940 A_MEMZERO(cmd, size);
3941 memcpy(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD));
3942
3943 return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID,
3944 NO_SYNC_WMIFLAG));
3945}
3946
3947int
3948wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 mask)
3949{
3950 void *osbuf;
3951 s8 size;
3952 WMI_TARGET_ERROR_REPORT_BITMASK *cmd;
3953
3954 size = sizeof (*cmd);
3955
3956 osbuf = A_NETBUF_ALLOC(size);
3957 if (osbuf == NULL) {
3958 return A_NO_MEMORY;
3959 }
3960
3961 A_NETBUF_PUT(osbuf, size);
3962
3963 cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf));
3964 A_MEMZERO(cmd, size);
3965
3966 cmd->bitmask = mask;
3967
3968 return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
3969 NO_SYNC_WMIFLAG));
3970}
3971
3972int
3973wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie, u32 source)
3974{
3975 void *osbuf;
3976 WMIX_HB_CHALLENGE_RESP_CMD *cmd;
3977
3978 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3979 if (osbuf == NULL) {
3980 return A_NO_MEMORY;
3981 }
3982
3983 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3984
3985 cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf));
3986 cmd->cookie = cookie;
3987 cmd->source = source;
3988
3989 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID,
3990 NO_SYNC_WMIFLAG));
3991}
3992
3993int
3994wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask,
3995 u16 tsr, bool rep, u16 size,
3996 u32 valid)
3997{
3998 void *osbuf;
3999 WMIX_DBGLOG_CFG_MODULE_CMD *cmd;
4000
4001 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4002 if (osbuf == NULL) {
4003 return A_NO_MEMORY;
4004 }
4005
4006 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4007
4008 cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf));
4009 cmd->config.cfgmmask = mmask;
4010 cmd->config.cfgtsr = tsr;
4011 cmd->config.cfgrep = rep;
4012 cmd->config.cfgsize = size;
4013 cmd->config.cfgvalid = valid;
4014
4015 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID,
4016 NO_SYNC_WMIFLAG));
4017}
4018
4019int
4020wmi_get_stats_cmd(struct wmi_t *wmip)
4021{
4022 return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID);
4023}
4024
4025int
4026wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid)
4027{
4028 void *osbuf;
4029 WMI_ADD_BAD_AP_CMD *cmd;
4030
4031 if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) {
4032 return A_EINVAL;
4033 }
4034
4035 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4036 if (osbuf == NULL) {
4037 return A_NO_MEMORY;
4038 }
4039
4040 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4041
4042 cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4043 cmd->badApIndex = apIndex;
4044 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
4045
4046 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG));
4047}
4048
4049int
4050wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex)
4051{
4052 void *osbuf;
4053 WMI_DELETE_BAD_AP_CMD *cmd;
4054
4055 if (apIndex > WMI_MAX_BAD_AP_INDEX) {
4056 return A_EINVAL;
4057 }
4058
4059 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4060 if (osbuf == NULL) {
4061 return A_NO_MEMORY;
4062 }
4063
4064 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4065
4066 cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4067 cmd->badApIndex = apIndex;
4068
4069 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID,
4070 NO_SYNC_WMIFLAG));
4071}
4072
4073int
4074wmi_abort_scan_cmd(struct wmi_t *wmip)
4075{
4076 return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID);
4077}
4078
4079int
4080wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM)
4081{
4082 void *osbuf;
4083 WMI_SET_TX_PWR_CMD *cmd;
4084
4085 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4086 if (osbuf == NULL) {
4087 return A_NO_MEMORY;
4088 }
4089
4090 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4091
4092 cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf));
4093 cmd->dbM = dbM;
4094
4095 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
4096}
4097
4098int
4099wmi_get_txPwr_cmd(struct wmi_t *wmip)
4100{
4101 return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID);
4102}
4103
4104u16 wmi_get_mapped_qos_queue(struct wmi_t *wmip, u8 trafficClass)
4105{
4106 u16 activeTsids=0;
4107
4108 LOCK_WMI(wmip);
4109 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
4110 UNLOCK_WMI(wmip);
4111
4112 return activeTsids;
4113}
4114
4115int
4116wmi_get_roam_tbl_cmd(struct wmi_t *wmip)
4117{
4118 return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID);
4119}
4120
4121int
4122wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType)
4123{
4124 void *osbuf;
4125 u32 size = sizeof(u8);
4126 WMI_TARGET_ROAM_DATA *cmd;
4127
4128 osbuf = A_NETBUF_ALLOC(size); /* no payload */
4129 if (osbuf == NULL) {
4130 return A_NO_MEMORY;
4131 }
4132
4133 A_NETBUF_PUT(osbuf, size);
4134
4135 cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf));
4136 cmd->roamDataType = roamDataType;
4137
4138 return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID,
4139 NO_SYNC_WMIFLAG));
4140}
4141
4142int
4143wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
4144 u8 size)
4145{
4146 void *osbuf;
4147 WMI_SET_ROAM_CTRL_CMD *cmd;
4148
4149 osbuf = A_NETBUF_ALLOC(size);
4150 if (osbuf == NULL) {
4151 return A_NO_MEMORY;
4152 }
4153
4154 A_NETBUF_PUT(osbuf, size);
4155
4156 cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf));
4157 A_MEMZERO(cmd, size);
4158
4159 memcpy(cmd, p, size);
4160
4161 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID,
4162 NO_SYNC_WMIFLAG));
4163}
4164
4165int
4166wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
4167 WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
4168 u8 size)
4169{
4170 void *osbuf;
4171 WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd;
4172
4173 /* These timers can't be zero */
4174 if(!pCmd->psPollTimeout || !pCmd->triggerTimeout ||
4175 !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD ||
4176 pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) ||
4177 !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD ||
4178 pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD))
4179 return A_EINVAL;
4180
4181 osbuf = A_NETBUF_ALLOC(size);
4182 if (osbuf == NULL) {
4183 return A_NO_MEMORY;
4184 }
4185
4186 A_NETBUF_PUT(osbuf, size);
4187
4188 cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
4189 A_MEMZERO(cmd, size);
4190
4191 memcpy(cmd, pCmd, size);
4192
4193 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
4194 NO_SYNC_WMIFLAG));
4195}
4196
4197int
4198wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop, u8 eCWmin,
4199 u8 eCWmax, u8 aifsn)
4200{
4201 void *osbuf;
4202 WMI_SET_ACCESS_PARAMS_CMD *cmd;
4203
4204 if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) ||
4205 (aifsn > WMI_MAX_AIFSN_ACPARAM) || (ac >= WMM_NUM_AC))
4206 {
4207 return A_EINVAL;
4208 }
4209
4210 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4211 if (osbuf == NULL) {
4212 return A_NO_MEMORY;
4213 }
4214
4215 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4216
4217 cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4218 cmd->txop = txop;
4219 cmd->eCWmin = eCWmin;
4220 cmd->eCWmax = eCWmax;
4221 cmd->aifsn = aifsn;
4222 cmd->ac = ac;
4223
4224 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID,
4225 NO_SYNC_WMIFLAG));
4226}
4227
4228int
4229wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType,
4230 u8 trafficClass, u8 maxRetries,
4231 u8 enableNotify)
4232{
4233 void *osbuf;
4234 WMI_SET_RETRY_LIMITS_CMD *cmd;
4235
4236 if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) &&
4237 (frameType != DATA_FRAMETYPE))
4238 {
4239 return A_EINVAL;
4240 }
4241
4242 if (maxRetries > WMI_MAX_RETRIES) {
4243 return A_EINVAL;
4244 }
4245
4246 if (frameType != DATA_FRAMETYPE) {
4247 trafficClass = 0;
4248 }
4249
4250 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4251 if (osbuf == NULL) {
4252 return A_NO_MEMORY;
4253 }
4254
4255 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4256
4257 cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf));
4258 cmd->frameType = frameType;
4259 cmd->trafficClass = trafficClass;
4260 cmd->maxRetries = maxRetries;
4261 cmd->enableNotify = enableNotify;
4262
4263 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID,
4264 NO_SYNC_WMIFLAG));
4265}
4266
4267void
4268wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid)
4269{
4270 if (bssid != NULL) {
4271 memcpy(bssid, wmip->wmi_bssid, ATH_MAC_LEN);
4272 }
4273}
4274
4275int
4276wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode)
4277{
4278 void *osbuf;
4279 WMI_SET_OPT_MODE_CMD *cmd;
4280
4281 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4282 if (osbuf == NULL) {
4283 return A_NO_MEMORY;
4284 }
4285
4286 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4287
4288 cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4289 A_MEMZERO(cmd, sizeof(*cmd));
4290 cmd->optMode = optMode;
4291
4292 return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID,
4293 SYNC_BOTH_WMIFLAG));
4294}
4295
4296int
4297wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
4298 u8 frmType,
4299 u8 *dstMacAddr,
4300 u8 *bssid,
4301 u16 optIEDataLen,
4302 u8 *optIEData)
4303{
4304 void *osbuf;
4305 WMI_OPT_TX_FRAME_CMD *cmd;
4306 osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd));
4307 if (osbuf == NULL) {
4308 return A_NO_MEMORY;
4309 }
4310
4311 A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd)));
4312
4313 cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf));
4314 A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1));
4315
4316 cmd->frmType = frmType;
4317 cmd->optIEDataLen = optIEDataLen;
4318 //cmd->optIEData = (u8 *)((int)cmd + sizeof(*cmd));
4319 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
4320 memcpy(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr));
4321 memcpy(&cmd->optIEData[0], optIEData, optIEDataLen);
4322
4323 return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID,
4324 NO_SYNC_WMIFLAG));
4325}
4326
4327int
4328wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl)
4329{
4330 void *osbuf;
4331 WMI_BEACON_INT_CMD *cmd;
4332
4333 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4334 if (osbuf == NULL) {
4335 return A_NO_MEMORY;
4336 }
4337
4338 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4339
4340 cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf));
4341 A_MEMZERO(cmd, sizeof(*cmd));
4342 cmd->beaconInterval = intvl;
4343
4344 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID,
4345 NO_SYNC_WMIFLAG));
4346}
4347
4348
4349int
4350wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize)
4351{
4352 void *osbuf;
4353 WMI_SET_VOICE_PKT_SIZE_CMD *cmd;
4354
4355 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4356 if (osbuf == NULL) {
4357 return A_NO_MEMORY;
4358 }
4359
4360 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4361
4362 cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf));
4363 A_MEMZERO(cmd, sizeof(*cmd));
4364 cmd->voicePktSize = voicePktSize;
4365
4366 return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID,
4367 NO_SYNC_WMIFLAG));
4368}
4369
4370
4371int
4372wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSPLen)
4373{
4374 void *osbuf;
4375 WMI_SET_MAX_SP_LEN_CMD *cmd;
4376
4377 /* maxSPLen is a two-bit value. If user trys to set anything
4378 * other than this, then its invalid
4379 */
4380 if(maxSPLen & ~0x03)
4381 return A_EINVAL;
4382
4383 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4384 if (osbuf == NULL) {
4385 return A_NO_MEMORY;
4386 }
4387
4388 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4389
4390 cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf));
4391 A_MEMZERO(cmd, sizeof(*cmd));
4392 cmd->maxSPLen = maxSPLen;
4393
4394 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID,
4395 NO_SYNC_WMIFLAG));
4396}
4397
4398u8 wmi_determine_userPriority(
4399 u8 *pkt,
4400 u32 layer2Pri)
4401{
4402 u8 ipPri;
4403 iphdr *ipHdr = (iphdr *)pkt;
4404
4405 /* Determine IPTOS priority */
4406 /*
4407 * IP Tos format :
4408 * (Refer Pg 57 WMM-test-plan-v1.2)
4409 * IP-TOS - 8bits
4410 * : DSCP(6-bits) ECN(2-bits)
4411 * : DSCP - P2 P1 P0 X X X
4412 * where (P2 P1 P0) form 802.1D
4413 */
4414 ipPri = ipHdr->ip_tos >> 5;
4415 ipPri &= 0x7;
4416
4417 if ((layer2Pri & 0x7) > ipPri)
4418 return ((u8)layer2Pri & 0x7);
4419 else
4420 return ipPri;
4421}
4422
4423u8 convert_userPriority_to_trafficClass(u8 userPriority)
4424{
4425 return (up_to_ac[userPriority & 0x7]);
4426}
4427
4428u8 wmi_get_power_mode_cmd(struct wmi_t *wmip)
4429{
4430 return wmip->wmi_powerMode;
4431}
4432
4433int
4434wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance)
4435{
4436 int ret = 0;
4437
4438#define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0)
4439#define TSPEC_SERVICE_START_TIME_ATHEROS_DEF 0
4440#define TSPEC_MAX_BURST_SIZE_ATHEROS_DEF 0
4441#define TSPEC_DELAY_BOUND_ATHEROS_DEF 0
4442#define TSPEC_MEDIUM_TIME_ATHEROS_DEF 0
4443#define TSPEC_SBA_ATHEROS_DEF 0x2000 /* factor is 1 */
4444
4445 /* Verify TSPEC params for ATHEROS compliance */
4446 if(tspecCompliance == ATHEROS_COMPLIANCE) {
4447 if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF) ||
4448 (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_ATHEROS_DEF) ||
4449 (pCmd->minDataRate != pCmd->meanDataRate) ||
4450 (pCmd->minDataRate != pCmd->peakDataRate) ||
4451 (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_ATHEROS_DEF) ||
4452 (pCmd->delayBound != TSPEC_DELAY_BOUND_ATHEROS_DEF) ||
4453 (pCmd->sba != TSPEC_SBA_ATHEROS_DEF) ||
4454 (pCmd->mediumTime != TSPEC_MEDIUM_TIME_ATHEROS_DEF)) {
4455
4456 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid TSPEC params\n", DBGARG));
4457 //A_PRINTF("%s: Invalid TSPEC params\n", __func__);
4458 ret = A_EINVAL;
4459 }
4460 }
4461
4462 return ret;
4463}
4464
4465#ifdef CONFIG_HOST_TCMD_SUPPORT
4466static int
4467wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len)
4468{
4469 ar6000_testmode_rx_report_event(wmip->wmi_devt, datap, len);
4470
4471 return 0;
4472}
4473
4474#endif /* CONFIG_HOST_TCMD_SUPPORT*/
4475
4476int
4477wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode)
4478{
4479 void *osbuf;
4480 WMI_SET_AUTH_MODE_CMD *cmd;
4481
4482 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4483 if (osbuf == NULL) {
4484 return A_NO_MEMORY;
4485 }
4486
4487 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4488
4489 cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4490 A_MEMZERO(cmd, sizeof(*cmd));
4491 cmd->mode = mode;
4492
4493 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID,
4494 NO_SYNC_WMIFLAG));
4495}
4496
4497int
4498wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode)
4499{
4500 void *osbuf;
4501 WMI_SET_REASSOC_MODE_CMD *cmd;
4502
4503 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4504 if (osbuf == NULL) {
4505 return A_NO_MEMORY;
4506 }
4507
4508 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4509
4510 cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4511 A_MEMZERO(cmd, sizeof(*cmd));
4512 cmd->mode = mode;
4513
4514 return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID,
4515 NO_SYNC_WMIFLAG));
4516}
4517
4518int
4519wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy)
4520{
4521 void *osbuf;
4522 WMI_SET_LPREAMBLE_CMD *cmd;
4523
4524 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4525 if (osbuf == NULL) {
4526 return A_NO_MEMORY;
4527 }
4528
4529 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4530
4531 cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf));
4532 A_MEMZERO(cmd, sizeof(*cmd));
4533 cmd->status = status;
4534 cmd->preamblePolicy = preamblePolicy;
4535
4536 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID,
4537 NO_SYNC_WMIFLAG));
4538}
4539
4540int
4541wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold)
4542{
4543 void *osbuf;
4544 WMI_SET_RTS_CMD *cmd;
4545
4546 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4547 if (osbuf == NULL) {
4548 return A_NO_MEMORY;
4549 }
4550
4551 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4552
4553 cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf));
4554 A_MEMZERO(cmd, sizeof(*cmd));
4555 cmd->threshold = threshold;
4556
4557 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID,
4558 NO_SYNC_WMIFLAG));
4559}
4560
4561int
4562wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status)
4563{
4564 void *osbuf;
4565 WMI_SET_WMM_CMD *cmd;
4566
4567 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4568 if (osbuf == NULL) {
4569 return A_NO_MEMORY;
4570 }
4571
4572 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4573
4574 cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf));
4575 A_MEMZERO(cmd, sizeof(*cmd));
4576 cmd->status = status;
4577
4578 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID,
4579 NO_SYNC_WMIFLAG));
4580
4581}
4582
4583int
4584wmi_set_qos_supp_cmd(struct wmi_t *wmip, u8 status)
4585{
4586 void *osbuf;
4587 WMI_SET_QOS_SUPP_CMD *cmd;
4588
4589 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4590 if (osbuf == NULL) {
4591 return A_NO_MEMORY;
4592 }
4593
4594 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4595
4596 cmd = (WMI_SET_QOS_SUPP_CMD*)(A_NETBUF_DATA(osbuf));
4597 A_MEMZERO(cmd, sizeof(*cmd));
4598 cmd->status = status;
4599 return (wmi_cmd_send(wmip, osbuf, WMI_SET_QOS_SUPP_CMDID,
4600 NO_SYNC_WMIFLAG));
4601}
4602
4603
4604int
4605wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg)
4606{
4607 void *osbuf;
4608 WMI_SET_WMM_TXOP_CMD *cmd;
4609
4610 if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) )
4611 return A_EINVAL;
4612
4613 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4614 if (osbuf == NULL) {
4615 return A_NO_MEMORY;
4616 }
4617
4618 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4619
4620 cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf));
4621 A_MEMZERO(cmd, sizeof(*cmd));
4622 cmd->txopEnable = cfg;
4623
4624 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID,
4625 NO_SYNC_WMIFLAG));
4626
4627}
4628
4629int
4630wmi_set_country(struct wmi_t *wmip, u8 *countryCode)
4631{
4632 void *osbuf;
4633 WMI_AP_SET_COUNTRY_CMD *cmd;
4634
4635 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4636 if (osbuf == NULL) {
4637 return A_NO_MEMORY;
4638 }
4639
4640 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4641
4642 cmd = (WMI_AP_SET_COUNTRY_CMD *)(A_NETBUF_DATA(osbuf));
4643 A_MEMZERO(cmd, sizeof(*cmd));
4644 memcpy(cmd->countryCode,countryCode,3);
4645
4646 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_COUNTRY_CMDID,
4647 NO_SYNC_WMIFLAG));
4648}
4649
4650#ifdef CONFIG_HOST_TCMD_SUPPORT
4651/* WMI layer doesn't need to know the data type of the test cmd.
4652 This would be beneficial for customers like Qualcomm, who might
4653 have different test command requirements from different manufacturers
4654 */
4655int
4656wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len)
4657{
4658 void *osbuf;
4659 char *data;
4660
4661 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4662
4663 osbuf= A_NETBUF_ALLOC(len);
4664 if(osbuf == NULL)
4665 {
4666 return A_NO_MEMORY;
4667 }
4668 A_NETBUF_PUT(osbuf, len);
4669 data = A_NETBUF_DATA(osbuf);
4670 memcpy(data, buf, len);
4671
4672 return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID,
4673 NO_SYNC_WMIFLAG));
4674}
4675
4676#endif
4677
4678int
4679wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status)
4680{
4681 void *osbuf;
4682 WMI_SET_BT_STATUS_CMD *cmd;
4683
4684 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Enter - streamType=%d, status=%d\n", streamType, status));
4685
4686 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4687 if (osbuf == NULL) {
4688 return A_NO_MEMORY;
4689 }
4690
4691 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4692
4693 cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
4694 A_MEMZERO(cmd, sizeof(*cmd));
4695 cmd->streamType = streamType;
4696 cmd->status = status;
4697
4698 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID,
4699 NO_SYNC_WMIFLAG));
4700}
4701
4702int
4703wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd)
4704{
4705 void *osbuf;
4706 WMI_SET_BT_PARAMS_CMD* alloc_cmd;
4707
4708 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("cmd params is %d\n", cmd->paramType));
4709
4710 if (cmd->paramType == BT_PARAM_SCO) {
4711 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("sco params %d %d %d %d %d %d %d %d %d %d %d %d\n", cmd->info.scoParams.numScoCyclesForceTrigger,
4712 cmd->info.scoParams.dataResponseTimeout,
4713 cmd->info.scoParams.stompScoRules,
4714 cmd->info.scoParams.scoOptFlags,
4715 cmd->info.scoParams.stompDutyCyleVal,
4716 cmd->info.scoParams.stompDutyCyleMaxVal,
4717 cmd->info.scoParams.psPollLatencyFraction,
4718 cmd->info.scoParams.noSCOSlots,
4719 cmd->info.scoParams.noIdleSlots,
4720 cmd->info.scoParams.scoOptOffRssi,
4721 cmd->info.scoParams.scoOptOnRssi,
4722 cmd->info.scoParams.scoOptRtsCount));
4723 }
4724 else if (cmd->paramType == BT_PARAM_A2DP) {
4725 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("A2DP params %d %d %d %d %d %d %d %d\n", cmd->info.a2dpParams.a2dpWlanUsageLimit,
4726 cmd->info.a2dpParams.a2dpBurstCntMin,
4727 cmd->info.a2dpParams.a2dpDataRespTimeout,
4728 cmd->info.a2dpParams.a2dpOptFlags,
4729 cmd->info.a2dpParams.isCoLocatedBtRoleMaster,
4730 cmd->info.a2dpParams.a2dpOptOffRssi,
4731 cmd->info.a2dpParams.a2dpOptOnRssi,
4732 cmd->info.a2dpParams.a2dpOptRtsCount));
4733 }
4734 else if (cmd->paramType == BT_PARAM_ANTENNA_CONFIG) {
4735 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Ant config %d\n", cmd->info.antType));
4736 }
4737 else if (cmd->paramType == BT_PARAM_COLOCATED_BT_DEVICE) {
4738 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("co-located BT %d\n", cmd->info.coLocatedBtDev));
4739 }
4740 else if (cmd->paramType == BT_PARAM_ACLCOEX) {
4741 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("ACL params %d %d %d\n", cmd->info.aclCoexParams.aclWlanMediumUsageTime,
4742 cmd->info.aclCoexParams.aclBtMediumUsageTime,
4743 cmd->info.aclCoexParams.aclDataRespTimeout));
4744 }
4745 else if (cmd->paramType == BT_PARAM_11A_SEPARATE_ANT) {
4746 A_DPRINTF(DBG_WMI, (DBGFMT "11A ant\n", DBGARG));
4747 }
4748
4749 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4750 if (osbuf == NULL) {
4751 return A_NO_MEMORY;
4752 }
4753
4754 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4755
4756 alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4757 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4758 memcpy(alloc_cmd, cmd, sizeof(*cmd));
4759
4760 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID,
4761 NO_SYNC_WMIFLAG));
4762}
4763
4764int
4765wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd)
4766{
4767 void *osbuf;
4768 WMI_SET_BTCOEX_FE_ANT_CMD *alloc_cmd;
4769
4770 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4771 if (osbuf == NULL) {
4772 return A_NO_MEMORY;
4773 }
4774 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4775 alloc_cmd = (WMI_SET_BTCOEX_FE_ANT_CMD *)(A_NETBUF_DATA(osbuf));
4776 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4777 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
4778 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_FE_ANT_CMDID,
4779 NO_SYNC_WMIFLAG));
4780
4781}
4782
4783
4784int
4785wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
4786 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd)
4787{
4788 void *osbuf;
4789 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *alloc_cmd;
4790
4791 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4792 if (osbuf == NULL) {
4793 return A_NO_MEMORY;
4794 }
4795 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4796 alloc_cmd = (WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *)(A_NETBUF_DATA(osbuf));
4797 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4798 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
4799 A_PRINTF("colocated bt = %d\n", alloc_cmd->btcoexCoLocatedBTdev);
4800 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
4801 NO_SYNC_WMIFLAG));
4802
4803}
4804
4805int
4806wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
4807 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD* cmd)
4808{
4809 void *osbuf;
4810 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *alloc_cmd;
4811
4812 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4813 if (osbuf == NULL) {
4814 return A_NO_MEMORY;
4815 }
4816 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4817 alloc_cmd = (WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4818 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4819 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD));
4820 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
4821 NO_SYNC_WMIFLAG));
4822
4823}
4824
4825int
4826wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
4827 WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd)
4828{
4829 void *osbuf;
4830 WMI_SET_BTCOEX_SCO_CONFIG_CMD *alloc_cmd;
4831
4832 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4833 if (osbuf == NULL) {
4834 return A_NO_MEMORY;
4835 }
4836 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4837 alloc_cmd = (WMI_SET_BTCOEX_SCO_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4838 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4839 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
4840 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_SCO_CONFIG_CMDID ,
4841 NO_SYNC_WMIFLAG));
4842
4843}
4844
4845int
4846wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
4847 WMI_SET_BTCOEX_A2DP_CONFIG_CMD * cmd)
4848{
4849 void *osbuf;
4850 WMI_SET_BTCOEX_A2DP_CONFIG_CMD *alloc_cmd;
4851
4852 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4853 if (osbuf == NULL) {
4854 return A_NO_MEMORY;
4855 }
4856 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4857 alloc_cmd = (WMI_SET_BTCOEX_A2DP_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4858 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4859 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
4860 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_A2DP_CONFIG_CMDID ,
4861 NO_SYNC_WMIFLAG));
4862
4863}
4864
4865int
4866wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip,
4867 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD * cmd)
4868{
4869 void *osbuf;
4870 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *alloc_cmd;
4871
4872 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4873 if (osbuf == NULL) {
4874 return A_NO_MEMORY;
4875 }
4876 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4877 alloc_cmd = (WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4878 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4879 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
4880 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID ,
4881 NO_SYNC_WMIFLAG));
4882
4883}
4884
4885int
4886wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd)
4887{
4888 void *osbuf;
4889 WMI_SET_BTCOEX_DEBUG_CMD *alloc_cmd;
4890
4891 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4892 if (osbuf == NULL) {
4893 return A_NO_MEMORY;
4894 }
4895 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4896 alloc_cmd = (WMI_SET_BTCOEX_DEBUG_CMD *)(A_NETBUF_DATA(osbuf));
4897 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4898 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD));
4899 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_DEBUG_CMDID ,
4900 NO_SYNC_WMIFLAG));
4901
4902}
4903
4904int
4905wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
4906 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd)
4907{
4908 void *osbuf;
4909 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *alloc_cmd;
4910
4911 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4912 if (osbuf == NULL) {
4913 return A_NO_MEMORY;
4914 }
4915 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4916 alloc_cmd = (WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
4917 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4918 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD));
4919 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ,
4920 NO_SYNC_WMIFLAG));
4921
4922}
4923
4924int
4925wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd)
4926{
4927 void *osbuf;
4928 WMI_GET_BTCOEX_CONFIG_CMD *alloc_cmd;
4929
4930 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4931 if (osbuf == NULL) {
4932 return A_NO_MEMORY;
4933 }
4934 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4935 alloc_cmd = (WMI_GET_BTCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4936 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4937 memcpy(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD));
4938 return (wmi_cmd_send(wmip, osbuf, WMI_GET_BTCOEX_CONFIG_CMDID ,
4939 NO_SYNC_WMIFLAG));
4940
4941}
4942
4943int
4944wmi_get_btcoex_stats_cmd(struct wmi_t *wmip)
4945{
4946
4947 return wmi_simple_cmd(wmip, WMI_GET_BTCOEX_STATS_CMDID);
4948
4949}
4950
4951int
4952wmi_get_keepalive_configured(struct wmi_t *wmip)
4953{
4954 void *osbuf;
4955 WMI_GET_KEEPALIVE_CMD *cmd;
4956 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4957 if (osbuf == NULL) {
4958 return A_NO_MEMORY;
4959 }
4960 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4961 cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
4962 A_MEMZERO(cmd, sizeof(*cmd));
4963 return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID,
4964 NO_SYNC_WMIFLAG));
4965}
4966
4967u8 wmi_get_keepalive_cmd(struct wmi_t *wmip)
4968{
4969 return wmip->wmi_keepaliveInterval;
4970}
4971
4972int
4973wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval)
4974{
4975 void *osbuf;
4976 WMI_SET_KEEPALIVE_CMD *cmd;
4977
4978 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4979 if (osbuf == NULL) {
4980 return A_NO_MEMORY;
4981 }
4982
4983 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4984
4985 cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
4986 A_MEMZERO(cmd, sizeof(*cmd));
4987 cmd->keepaliveInterval = keepaliveInterval;
4988 wmip->wmi_keepaliveInterval = keepaliveInterval;
4989
4990 return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID,
4991 NO_SYNC_WMIFLAG));
4992}
4993
4994int
4995wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer)
4996{
4997 void *osbuf;
4998 WMI_SET_PARAMS_CMD *cmd;
4999
5000 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + length);
5001 if (osbuf == NULL) {
5002 return A_NO_MEMORY;
5003 }
5004
5005 A_NETBUF_PUT(osbuf, sizeof(*cmd) + length);
5006
5007 cmd = (WMI_SET_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5008 A_MEMZERO(cmd, sizeof(*cmd));
5009 cmd->opcode = opcode;
5010 cmd->length = length;
5011 memcpy(cmd->buffer, buffer, length);
5012
5013 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PARAMS_CMDID,
5014 NO_SYNC_WMIFLAG));
5015}
5016
5017
5018int
5019wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4)
5020{
5021 void *osbuf;
5022 WMI_SET_MCAST_FILTER_CMD *cmd;
5023
5024 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5025 if (osbuf == NULL) {
5026 return A_NO_MEMORY;
5027 }
5028
5029 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5030
5031 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5032 cmd->multicast_mac[0] = 0x01;
5033 cmd->multicast_mac[1] = 0x00;
5034 cmd->multicast_mac[2] = 0x5e;
5035 cmd->multicast_mac[3] = dot2&0x7F;
5036 cmd->multicast_mac[4] = dot3;
5037 cmd->multicast_mac[5] = dot4;
5038
5039 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MCAST_FILTER_CMDID,
5040 NO_SYNC_WMIFLAG));
5041}
5042
5043
5044int
5045wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4)
5046{
5047 void *osbuf;
5048 WMI_SET_MCAST_FILTER_CMD *cmd;
5049
5050 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5051 if (osbuf == NULL) {
5052 return A_NO_MEMORY;
5053 }
5054
5055 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5056
5057 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5058 cmd->multicast_mac[0] = 0x01;
5059 cmd->multicast_mac[1] = 0x00;
5060 cmd->multicast_mac[2] = 0x5e;
5061 cmd->multicast_mac[3] = dot2&0x7F;
5062 cmd->multicast_mac[4] = dot3;
5063 cmd->multicast_mac[5] = dot4;
5064
5065 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_MCAST_FILTER_CMDID,
5066 NO_SYNC_WMIFLAG));
5067}
5068
5069int
5070wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable)
5071{
5072 void *osbuf;
5073 WMI_MCAST_FILTER_CMD *cmd;
5074
5075 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5076 if (osbuf == NULL) {
5077 return A_NO_MEMORY;
5078 }
5079
5080 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5081
5082 cmd = (WMI_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5083 cmd->enable = enable;
5084
5085 return (wmi_cmd_send(wmip, osbuf, WMI_MCAST_FILTER_CMDID,
5086 NO_SYNC_WMIFLAG));
5087}
5088
5089int
5090wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, u8 ieLen,
5091 u8 *ieInfo)
5092{
5093 void *osbuf;
5094 WMI_SET_APPIE_CMD *cmd;
5095 u16 cmdLen;
5096
5097 cmdLen = sizeof(*cmd) + ieLen - 1;
5098 osbuf = A_NETBUF_ALLOC(cmdLen);
5099 if (osbuf == NULL) {
5100 return A_NO_MEMORY;
5101 }
5102
5103 A_NETBUF_PUT(osbuf, cmdLen);
5104
5105 cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf));
5106 A_MEMZERO(cmd, cmdLen);
5107
5108 cmd->mgmtFrmType = mgmtFrmType;
5109 cmd->ieLen = ieLen;
5110 memcpy(cmd->ieInfo, ieInfo, ieLen);
5111
5112 return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG));
5113}
5114
5115int
5116wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen)
5117{
5118 void *osbuf;
5119 u8 *data;
5120
5121 osbuf = A_NETBUF_ALLOC(dataLen);
5122 if (osbuf == NULL) {
5123 return A_NO_MEMORY;
5124 }
5125
5126 A_NETBUF_PUT(osbuf, dataLen);
5127
5128 data = A_NETBUF_DATA(osbuf);
5129
5130 memcpy(data, cmd, dataLen);
5131
5132 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG));
5133}
5134
5135s32 wmi_get_rate(s8 rateindex)
5136{
5137 if (rateindex == RATE_AUTO) {
5138 return 0;
5139 } else {
5140 return(wmi_rateTable[(u32) rateindex][0]);
5141 }
5142}
5143
5144void
5145wmi_node_return (struct wmi_t *wmip, bss_t *bss)
5146{
5147 if (NULL != bss)
5148 {
5149 wlan_node_return (&wmip->wmi_scan_table, bss);
5150 }
5151}
5152
5153void
5154wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge)
5155{
5156 wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge);
5157}
5158
5159bss_t *
5160wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
5161 u32 ssidLength, bool bIsWPA2, bool bMatchSSID)
5162{
5163 bss_t *node = NULL;
5164 node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid,
5165 ssidLength, bIsWPA2, bMatchSSID);
5166 return node;
5167}
5168
5169
5170#ifdef THREAD_X
5171void
5172wmi_refresh_scan_table (struct wmi_t *wmip)
5173{
5174 wlan_refresh_inactive_nodes (&wmip->wmi_scan_table);
5175}
5176#endif
5177
5178void
5179wmi_free_allnodes(struct wmi_t *wmip)
5180{
5181 wlan_free_allnodes(&wmip->wmi_scan_table);
5182}
5183
5184bss_t *
5185wmi_find_node(struct wmi_t *wmip, const u8 *macaddr)
5186{
5187 bss_t *ni=NULL;
5188 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5189 return ni;
5190}
5191
5192void
5193wmi_free_node(struct wmi_t *wmip, const u8 *macaddr)
5194{
5195 bss_t *ni=NULL;
5196
5197 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5198 if (ni != NULL) {
5199 wlan_node_reclaim(&wmip->wmi_scan_table, ni);
5200 }
5201
5202 return;
5203}
5204
5205int
5206wmi_dset_open_reply(struct wmi_t *wmip,
5207 u32 status,
5208 u32 access_cookie,
5209 u32 dset_size,
5210 u32 dset_version,
5211 u32 targ_handle,
5212 u32 targ_reply_fn,
5213 u32 targ_reply_arg)
5214{
5215 void *osbuf;
5216 WMIX_DSETOPEN_REPLY_CMD *open_reply;
5217
5218 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%lx\n", DBGARG, (unsigned long)wmip));
5219
5220 osbuf = A_NETBUF_ALLOC(sizeof(*open_reply));
5221 if (osbuf == NULL) {
5222 return A_NO_MEMORY;
5223 }
5224
5225 A_NETBUF_PUT(osbuf, sizeof(*open_reply));
5226 open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5227
5228 open_reply->status = status;
5229 open_reply->targ_dset_handle = targ_handle;
5230 open_reply->targ_reply_fn = targ_reply_fn;
5231 open_reply->targ_reply_arg = targ_reply_arg;
5232 open_reply->access_cookie = access_cookie;
5233 open_reply->size = dset_size;
5234 open_reply->version = dset_version;
5235
5236 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID,
5237 NO_SYNC_WMIFLAG));
5238}
5239
5240static int
5241wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
5242{
5243 WMI_PMKID_LIST_REPLY *reply;
5244 u32 expected_len;
5245
5246 if (len < sizeof(WMI_PMKID_LIST_REPLY)) {
5247 return A_EINVAL;
5248 }
5249 reply = (WMI_PMKID_LIST_REPLY *)datap;
5250 expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN;
5251
5252 if (len < expected_len) {
5253 return A_EINVAL;
5254 }
5255
5256 A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID,
5257 reply->pmkidList, reply->bssidList[0]);
5258
5259 return 0;
5260}
5261
5262
5263static int
5264wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
5265{
5266 WMI_SET_PARAMS_REPLY *reply;
5267
5268 if (len < sizeof(WMI_SET_PARAMS_REPLY)) {
5269 return A_EINVAL;
5270 }
5271 reply = (WMI_SET_PARAMS_REPLY *)datap;
5272
5273 if (0 == reply->status)
5274 {
5275
5276 }
5277 else
5278 {
5279
5280 }
5281
5282 return 0;
5283}
5284
5285
5286#ifdef CONFIG_HOST_DSET_SUPPORT
5287int
5288wmi_dset_data_reply(struct wmi_t *wmip,
5289 u32 status,
5290 u8 *user_buf,
5291 u32 length,
5292 u32 targ_buf,
5293 u32 targ_reply_fn,
5294 u32 targ_reply_arg)
5295{
5296 void *osbuf;
5297 WMIX_DSETDATA_REPLY_CMD *data_reply;
5298 u32 size;
5299
5300 size = sizeof(*data_reply) + length;
5301
5302 if (size <= length) {
5303 return A_ERROR;
5304 }
5305
5306 A_DPRINTF(DBG_WMI,
5307 (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status));
5308
5309 osbuf = A_NETBUF_ALLOC(size);
5310 if (osbuf == NULL) {
5311 return A_NO_MEMORY;
5312 }
5313 A_NETBUF_PUT(osbuf, size);
5314 data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5315
5316 data_reply->status = status;
5317 data_reply->targ_buf = targ_buf;
5318 data_reply->targ_reply_fn = targ_reply_fn;
5319 data_reply->targ_reply_arg = targ_reply_arg;
5320 data_reply->length = length;
5321
5322 if (status == 0) {
5323 if (a_copy_from_user(data_reply->buf, user_buf, length)) {
5324 A_NETBUF_FREE(osbuf);
5325 return A_ERROR;
5326 }
5327 }
5328
5329 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID,
5330 NO_SYNC_WMIFLAG));
5331}
5332#endif /* CONFIG_HOST_DSET_SUPPORT */
5333
5334int
5335wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status)
5336{
5337 void *osbuf;
5338 char *cmd;
5339
5340 wps_enable = status;
5341
5342 osbuf = a_netbuf_alloc(sizeof(1));
5343 if (osbuf == NULL) {
5344 return A_NO_MEMORY;
5345 }
5346
5347 a_netbuf_put(osbuf, sizeof(1));
5348
5349 cmd = (char *)(a_netbuf_to_data(osbuf));
5350
5351 A_MEMZERO(cmd, sizeof(*cmd));
5352 cmd[0] = (status?1:0);
5353 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID,
5354 NO_SYNC_WMIFLAG));
5355}
5356
5357#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
5358int
5359wmi_prof_cfg_cmd(struct wmi_t *wmip,
5360 u32 period,
5361 u32 nbins)
5362{
5363 void *osbuf;
5364 WMIX_PROF_CFG_CMD *cmd;
5365
5366 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5367 if (osbuf == NULL) {
5368 return A_NO_MEMORY;
5369 }
5370
5371 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5372
5373 cmd = (WMIX_PROF_CFG_CMD *)(A_NETBUF_DATA(osbuf));
5374 A_MEMZERO(cmd, sizeof(*cmd));
5375 cmd->period = period;
5376 cmd->nbins = nbins;
5377
5378 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_CFG_CMDID, NO_SYNC_WMIFLAG));
5379}
5380
5381int
5382wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr)
5383{
5384 void *osbuf;
5385 WMIX_PROF_ADDR_SET_CMD *cmd;
5386
5387 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5388 if (osbuf == NULL) {
5389 return A_NO_MEMORY;
5390 }
5391
5392 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5393
5394 cmd = (WMIX_PROF_ADDR_SET_CMD *)(A_NETBUF_DATA(osbuf));
5395 A_MEMZERO(cmd, sizeof(*cmd));
5396 cmd->addr = addr;
5397
5398 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_ADDR_SET_CMDID, NO_SYNC_WMIFLAG));
5399}
5400
5401int
5402wmi_prof_start_cmd(struct wmi_t *wmip)
5403{
5404 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID);
5405}
5406
5407int
5408wmi_prof_stop_cmd(struct wmi_t *wmip)
5409{
5410 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID);
5411}
5412
5413int
5414wmi_prof_count_get_cmd(struct wmi_t *wmip)
5415{
5416 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_COUNT_GET_CMDID);
5417}
5418
5419/* Called to handle WMIX_PROF_CONT_EVENTID */
5420static int
5421wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len)
5422{
5423 WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap;
5424
5425 A_DPRINTF(DBG_WMI,
5426 (DBGFMT "Enter - addr=0x%x count=%d\n", DBGARG,
5427 prof_data->addr, prof_data->count));
5428
5429 A_WMI_PROF_COUNT_RX(prof_data->addr, prof_data->count);
5430
5431 return 0;
5432}
5433#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
5434
5435#ifdef OS_ROAM_MANAGEMENT
5436
5437#define ETHERNET_MAC_ADDRESS_LENGTH 6
5438
5439void
5440wmi_scan_indication (struct wmi_t *wmip)
5441{
5442 struct ieee80211_node_table *nt;
5443 u32 gen;
5444 u32 size;
5445 u32 bsssize;
5446 bss_t *bss;
5447 u32 numbss;
5448 PNDIS_802_11_BSSID_SCAN_INFO psi;
5449 PBYTE pie;
5450 NDIS_802_11_FIXED_IEs *pFixed;
5451 NDIS_802_11_VARIABLE_IEs *pVar;
5452 u32 RateSize;
5453
5454 struct ar6kScanIndication
5455 {
5456 NDIS_802_11_STATUS_INDICATION ind;
5457 NDIS_802_11_BSSID_SCAN_INFO_LIST slist;
5458 } *pAr6kScanIndEvent;
5459
5460 nt = &wmip->wmi_scan_table;
5461
5462 ++nt->nt_si_gen;
5463
5464
5465 gen = nt->nt_si_gen;
5466
5467 size = offsetof(struct ar6kScanIndication, slist) +
5468 offsetof(NDIS_802_11_BSSID_SCAN_INFO_LIST, BssidScanInfo);
5469
5470 numbss = 0;
5471
5472 IEEE80211_NODE_LOCK(nt);
5473
5474 //calc size
5475 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5476 if (bss->ni_si_gen != gen) {
5477 bsssize = offsetof(NDIS_802_11_BSSID_SCAN_INFO, Bssid) + offsetof(NDIS_WLAN_BSSID_EX, IEs);
5478 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5479
5480#ifdef SUPPORT_WPA2
5481 if (bss->ni_cie.ie_rsn) {
5482 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5483 }
5484#endif
5485 if (bss->ni_cie.ie_wpa) {
5486 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5487 }
5488
5489 // bsssize must be a multiple of 4 to maintain alignment.
5490 bsssize = (bsssize + 3) & ~3;
5491
5492 size += bsssize;
5493
5494 numbss++;
5495 }
5496 }
5497
5498 if (0 == numbss)
5499 {
5500// RETAILMSG(1, (L"AR6K: scan indication: 0 bss\n"));
5501 ar6000_scan_indication (wmip->wmi_devt, NULL, 0);
5502 IEEE80211_NODE_UNLOCK (nt);
5503 return;
5504 }
5505
5506 pAr6kScanIndEvent = A_MALLOC(size);
5507
5508 if (NULL == pAr6kScanIndEvent)
5509 {
5510 IEEE80211_NODE_UNLOCK(nt);
5511 return;
5512 }
5513
5514 A_MEMZERO(pAr6kScanIndEvent, size);
5515
5516 //copy data
5517 pAr6kScanIndEvent->ind.StatusType = Ndis802_11StatusType_BssidScanInfoList;
5518 pAr6kScanIndEvent->slist.Version = 1;
5519 pAr6kScanIndEvent->slist.NumItems = numbss;
5520
5521 psi = &pAr6kScanIndEvent->slist.BssidScanInfo[0];
5522
5523 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5524 if (bss->ni_si_gen != gen) {
5525
5526 bss->ni_si_gen = gen;
5527
5528 //Set scan time
5529 psi->ScanTime = bss->ni_tstamp - WLAN_NODE_INACT_TIMEOUT_MSEC;
5530
5531 // Copy data to bssid_ex
5532 bsssize = offsetof(NDIS_WLAN_BSSID_EX, IEs);
5533 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5534
5535#ifdef SUPPORT_WPA2
5536 if (bss->ni_cie.ie_rsn) {
5537 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5538 }
5539#endif
5540 if (bss->ni_cie.ie_wpa) {
5541 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5542 }
5543
5544 // bsssize must be a multiple of 4 to maintain alignment.
5545 bsssize = (bsssize + 3) & ~3;
5546
5547 psi->Bssid.Length = bsssize;
5548
5549 memcpy (psi->Bssid.MacAddress, bss->ni_macaddr, ETHERNET_MAC_ADDRESS_LENGTH);
5550
5551
5552//if (((bss->ni_macaddr[3] == 0xCE) && (bss->ni_macaddr[4] == 0xF0) && (bss->ni_macaddr[5] == 0xE7)) ||
5553// ((bss->ni_macaddr[3] == 0x03) && (bss->ni_macaddr[4] == 0xE2) && (bss->ni_macaddr[5] == 0x70)))
5554// RETAILMSG (1, (L"%x\n",bss->ni_macaddr[5]));
5555
5556 psi->Bssid.Ssid.SsidLength = 0;
5557 pie = bss->ni_cie.ie_ssid;
5558
5559 if (pie) {
5560 // Format of SSID IE is:
5561 // Type (1 octet)
5562 // Length (1 octet)
5563 // SSID (Length octets)
5564 //
5565 // Validation of the IE should have occurred within WMI.
5566 //
5567 if (pie[1] <= 32) {
5568 psi->Bssid.Ssid.SsidLength = pie[1];
5569 memcpy(psi->Bssid.Ssid.Ssid, &pie[2], psi->Bssid.Ssid.SsidLength);
5570 }
5571 }
5572 psi->Bssid.Privacy = (bss->ni_cie.ie_capInfo & 0x10) ? 1 : 0;
5573
5574 //Post the RSSI value relative to the Standard Noise floor value.
5575 psi->Bssid.Rssi = bss->ni_rssi;
5576
5577 if (bss->ni_cie.ie_chan >= 2412 && bss->ni_cie.ie_chan <= 2484) {
5578
5579 if (bss->ni_cie.ie_rates && bss->ni_cie.ie_xrates) {
5580 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM24;
5581 }
5582 else {
5583 psi->Bssid.NetworkTypeInUse = Ndis802_11DS;
5584 }
5585 }
5586 else {
5587 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM5;
5588 }
5589
5590 psi->Bssid.Configuration.Length = sizeof(psi->Bssid.Configuration);
5591 psi->Bssid.Configuration.BeaconPeriod = bss->ni_cie.ie_beaconInt; // Units are Kmicroseconds (1024 us)
5592 psi->Bssid.Configuration.ATIMWindow = 0;
5593 psi->Bssid.Configuration.DSConfig = bss->ni_cie.ie_chan * 1000;
5594 psi->Bssid.InfrastructureMode = ((bss->ni_cie.ie_capInfo & 0x03) == 0x01 ) ? Ndis802_11Infrastructure : Ndis802_11IBSS;
5595
5596 RateSize = 0;
5597 pie = bss->ni_cie.ie_rates;
5598 if (pie) {
5599 RateSize = (pie[1] < NDIS_802_11_LENGTH_RATES_EX) ? pie[1] : NDIS_802_11_LENGTH_RATES_EX;
5600 memcpy(psi->Bssid.SupportedRates, &pie[2], RateSize);
5601 }
5602 pie = bss->ni_cie.ie_xrates;
5603 if (pie && RateSize < NDIS_802_11_LENGTH_RATES_EX) {
5604 memcpy(psi->Bssid.SupportedRates + RateSize, &pie[2],
5605 (pie[1] < (NDIS_802_11_LENGTH_RATES_EX - RateSize)) ? pie[1] : (NDIS_802_11_LENGTH_RATES_EX - RateSize));
5606 }
5607
5608 // Copy the fixed IEs
5609 psi->Bssid.IELength = sizeof(NDIS_802_11_FIXED_IEs);
5610
5611 pFixed = (NDIS_802_11_FIXED_IEs *)psi->Bssid.IEs;
5612 memcpy(pFixed->Timestamp, bss->ni_cie.ie_tstamp, sizeof(pFixed->Timestamp));
5613 pFixed->BeaconInterval = bss->ni_cie.ie_beaconInt;
5614 pFixed->Capabilities = bss->ni_cie.ie_capInfo;
5615
5616 // Copy selected variable IEs
5617
5618 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pFixed + sizeof(NDIS_802_11_FIXED_IEs));
5619
5620#ifdef SUPPORT_WPA2
5621 // Copy the WPAv2 IE
5622 if (bss->ni_cie.ie_rsn) {
5623 pie = bss->ni_cie.ie_rsn;
5624 psi->Bssid.IELength += pie[1] + 2;
5625 memcpy(pVar, pie, pie[1] + 2);
5626 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5627 }
5628#endif
5629 // Copy the WPAv1 IE
5630 if (bss->ni_cie.ie_wpa) {
5631 pie = bss->ni_cie.ie_wpa;
5632 psi->Bssid.IELength += pie[1] + 2;
5633 memcpy(pVar, pie, pie[1] + 2);
5634 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5635 }
5636
5637 // Advance buffer pointer
5638 psi = (PNDIS_802_11_BSSID_SCAN_INFO)((BYTE*)psi + bsssize + FIELD_OFFSET(NDIS_802_11_BSSID_SCAN_INFO, Bssid));
5639 }
5640 }
5641
5642 IEEE80211_NODE_UNLOCK(nt);
5643
5644// wmi_free_allnodes(wmip);
5645
5646// RETAILMSG(1, (L"AR6K: scan indication: %u bss\n", numbss));
5647
5648 ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size);
5649
5650 kfree(pAr6kScanIndEvent);
5651}
5652#endif
5653
5654u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5655 u32 size)
5656{
5657 u32 index;
5658 u8 threshold = (u8)sq_thresh->upper_threshold[size - 1];
5659
5660 /* The list is already in sorted order. Get the next lower value */
5661 for (index = 0; index < size; index ++) {
5662 if (rssi < sq_thresh->upper_threshold[index]) {
5663 threshold = (u8)sq_thresh->upper_threshold[index];
5664 break;
5665 }
5666 }
5667
5668 return threshold;
5669}
5670
5671u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5672 u32 size)
5673{
5674 u32 index;
5675 u8 threshold = (u8)sq_thresh->lower_threshold[size - 1];
5676
5677 /* The list is already in sorted order. Get the next lower value */
5678 for (index = 0; index < size; index ++) {
5679 if (rssi > sq_thresh->lower_threshold[index]) {
5680 threshold = (u8)sq_thresh->lower_threshold[index];
5681 break;
5682 }
5683 }
5684
5685 return threshold;
5686}
5687static int
5688wmi_send_rssi_threshold_params(struct wmi_t *wmip,
5689 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
5690{
5691 void *osbuf;
5692 s8 size;
5693 WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;
5694
5695 size = sizeof (*cmd);
5696
5697 osbuf = A_NETBUF_ALLOC(size);
5698 if (osbuf == NULL) {
5699 return A_NO_MEMORY;
5700 }
5701
5702 A_NETBUF_PUT(osbuf, size);
5703
5704 cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5705 A_MEMZERO(cmd, size);
5706 memcpy(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD));
5707
5708 return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
5709 NO_SYNC_WMIFLAG));
5710}
5711static int
5712wmi_send_snr_threshold_params(struct wmi_t *wmip,
5713 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
5714{
5715 void *osbuf;
5716 s8 size;
5717 WMI_SNR_THRESHOLD_PARAMS_CMD *cmd;
5718
5719 size = sizeof (*cmd);
5720
5721 osbuf = A_NETBUF_ALLOC(size);
5722 if (osbuf == NULL) {
5723 return A_NO_MEMORY;
5724 }
5725
5726 A_NETBUF_PUT(osbuf, size);
5727 cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5728 A_MEMZERO(cmd, size);
5729 memcpy(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD));
5730
5731 return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID,
5732 NO_SYNC_WMIFLAG));
5733}
5734
5735int
5736wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd)
5737{
5738 void *osbuf;
5739 WMI_SET_TARGET_EVENT_REPORT_CMD* alloc_cmd;
5740
5741 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5742 if (osbuf == NULL) {
5743 return A_NO_MEMORY;
5744 }
5745
5746 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5747
5748 alloc_cmd = (WMI_SET_TARGET_EVENT_REPORT_CMD *)(A_NETBUF_DATA(osbuf));
5749 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5750 memcpy(alloc_cmd, cmd, sizeof(*cmd));
5751
5752 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TARGET_EVENT_REPORT_CMDID,
5753 NO_SYNC_WMIFLAG));
5754}
5755
5756bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id)
5757{
5758 wmi_get_current_bssid (wmip, id);
5759 return wlan_node_remove (&wmip->wmi_scan_table, id);
5760}
5761
5762int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss)
5763{
5764 wlan_setup_node (&wmip->wmi_scan_table, bss, id);
5765 return 0;
5766}
5767
5768static int
5769wmi_addba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5770{
5771 WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap;
5772
5773 A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, cmd);
5774
5775 return 0;
5776}
5777
5778
5779static int
5780wmi_addba_resp_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5781{
5782 WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap;
5783
5784 A_WMI_AGGR_RECV_ADDBA_RESP_EVT(wmip->wmi_devt, cmd);
5785
5786 return 0;
5787}
5788
5789static int
5790wmi_delba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5791{
5792 WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap;
5793
5794 A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, cmd);
5795
5796 return 0;
5797}
5798
5799int
5800wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5801{
5802 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
5803
5804 A_WMI_BTCOEX_CONFIG_EVENT(wmip->wmi_devt, datap, len);
5805
5806 return 0;
5807}
5808
5809
5810int
5811wmi_btcoex_stats_event_rx(struct wmi_t * wmip,u8 *datap,int len)
5812{
5813 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
5814
5815 A_WMI_BTCOEX_STATS_EVENT(wmip->wmi_devt, datap, len);
5816
5817 return 0;
5818
5819}
5820
5821static int
5822wmi_hci_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5823{
5824 WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap;
5825 A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd);
5826
5827 return 0;
5828}
5829
5830////////////////////////////////////////////////////////////////////////////////
5831//// ////
5832//// AP mode functions ////
5833//// ////
5834////////////////////////////////////////////////////////////////////////////////
5835/*
5836 * IOCTL: AR6000_XIOCTL_AP_COMMIT_CONFIG
5837 *
5838 * When AR6K in AP mode, This command will be called after
5839 * changing ssid, channel etc. It will pass the profile to
5840 * target with a flag which will indicate which parameter changed,
5841 * also if this flag is 0, there was no change in parametes, so
5842 * commit cmd will not be sent to target. Without calling this IOCTL
5843 * the changes will not take effect.
5844 */
5845int
5846wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p)
5847{
5848 void *osbuf;
5849 WMI_CONNECT_CMD *cm;
5850
5851 osbuf = A_NETBUF_ALLOC(sizeof(*cm));
5852 if (osbuf == NULL) {
5853 return A_NO_MEMORY;
5854 }
5855
5856 A_NETBUF_PUT(osbuf, sizeof(*cm));
5857 cm = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
5858 A_MEMZERO(cm, sizeof(*cm));
5859
5860 memcpy(cm,p,sizeof(*cm));
5861
5862 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG));
5863}
5864
5865/*
5866 * IOCTL: AR6000_XIOCTL_AP_HIDDEN_SSID
5867 *
5868 * This command will be used to enable/disable hidden ssid functioanlity of
5869 * beacon. If it is enabled, ssid will be NULL in beacon.
5870 */
5871int
5872wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid)
5873{
5874 void *osbuf;
5875 WMI_AP_HIDDEN_SSID_CMD *hs;
5876
5877 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_HIDDEN_SSID_CMD));
5878 if (osbuf == NULL) {
5879 return A_NO_MEMORY;
5880 }
5881
5882 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_HIDDEN_SSID_CMD));
5883 hs = (WMI_AP_HIDDEN_SSID_CMD *)(A_NETBUF_DATA(osbuf));
5884 A_MEMZERO(hs, sizeof(*hs));
5885
5886 hs->hidden_ssid = hidden_ssid;
5887
5888 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_HIDDEN_SSID %d\n", DBGARG , hidden_ssid));
5889 return (wmi_cmd_send(wmip, osbuf, WMI_AP_HIDDEN_SSID_CMDID, NO_SYNC_WMIFLAG));
5890}
5891
5892/*
5893 * IOCTL: AR6000_XIOCTL_AP_SET_MAX_NUM_STA
5894 *
5895 * This command is used to limit max num of STA that can connect
5896 * with this AP. This value should not exceed AP_MAX_NUM_STA (this
5897 * is max num of STA supported by AP). Value was already validated
5898 * in ioctl.c
5899 */
5900int
5901wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta)
5902{
5903 void *osbuf;
5904 WMI_AP_SET_NUM_STA_CMD *ns;
5905
5906 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_NUM_STA_CMD));
5907 if (osbuf == NULL) {
5908 return A_NO_MEMORY;
5909 }
5910
5911 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_NUM_STA_CMD));
5912 ns = (WMI_AP_SET_NUM_STA_CMD *)(A_NETBUF_DATA(osbuf));
5913 A_MEMZERO(ns, sizeof(*ns));
5914
5915 ns->num_sta = num_sta;
5916
5917 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_SET_MAX_NUM_STA %d\n", DBGARG , num_sta));
5918 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_NUM_STA_CMDID, NO_SYNC_WMIFLAG));
5919}
5920
5921/*
5922 * IOCTL: AR6000_XIOCTL_AP_SET_ACL_MAC
5923 *
5924 * This command is used to send list of mac of STAs which will
5925 * be allowed to connect with this AP. When this list is empty
5926 * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
5927 */
5928int
5929wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl)
5930{
5931 void *osbuf;
5932 WMI_AP_ACL_MAC_CMD *a;
5933
5934 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_MAC_CMD));
5935 if (osbuf == NULL) {
5936 return A_NO_MEMORY;
5937 }
5938
5939 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_MAC_CMD));
5940 a = (WMI_AP_ACL_MAC_CMD *)(A_NETBUF_DATA(osbuf));
5941 A_MEMZERO(a, sizeof(*a));
5942 memcpy(a,acl,sizeof(*acl));
5943
5944 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_MAC_LIST_CMDID, NO_SYNC_WMIFLAG));
5945}
5946
5947/*
5948 * IOCTL: AR6000_XIOCTL_AP_SET_MLME
5949 *
5950 * This command is used to send list of mac of STAs which will
5951 * be allowed to connect with this AP. When this list is empty
5952 * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
5953 */
5954int
5955wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason)
5956{
5957 void *osbuf;
5958 WMI_AP_SET_MLME_CMD *mlme;
5959
5960 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_MLME_CMD));
5961 if (osbuf == NULL) {
5962 return A_NO_MEMORY;
5963 }
5964
5965 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_MLME_CMD));
5966 mlme = (WMI_AP_SET_MLME_CMD *)(A_NETBUF_DATA(osbuf));
5967 A_MEMZERO(mlme, sizeof(*mlme));
5968
5969 mlme->cmd = cmd;
5970 memcpy(mlme->mac, mac, ATH_MAC_LEN);
5971 mlme->reason = reason;
5972
5973 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG));
5974}
5975
5976static int
5977wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5978{
5979 WMI_PSPOLL_EVENT *ev;
5980
5981 if (len < sizeof(WMI_PSPOLL_EVENT)) {
5982 return A_EINVAL;
5983 }
5984 ev = (WMI_PSPOLL_EVENT *)datap;
5985
5986 A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid);
5987 return 0;
5988}
5989
5990static int
5991wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,int len)
5992{
5993 A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt);
5994 return 0;
5995}
5996
5997#ifdef WAPI_ENABLE
5998static int
5999wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,int len)
6000{
6001 u8 *ev;
6002
6003 if (len < 7) {
6004 return A_EINVAL;
6005 }
6006 ev = (u8 *)datap;
6007
6008 A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]);
6009 return 0;
6010}
6011#endif
6012
6013int
6014wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag)
6015{
6016 WMI_AP_SET_PVB_CMD *cmd;
6017 void *osbuf = NULL;
6018
6019 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_PVB_CMD));
6020 if (osbuf == NULL) {
6021 return A_NO_MEMORY;
6022 }
6023
6024 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_PVB_CMD));
6025 cmd = (WMI_AP_SET_PVB_CMD *)(A_NETBUF_DATA(osbuf));
6026 A_MEMZERO(cmd, sizeof(*cmd));
6027
6028 cmd->aid = aid;
6029 cmd->flag = flag;
6030
6031 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG));
6032}
6033
6034int
6035wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period)
6036{
6037 WMI_AP_CONN_INACT_CMD *cmd;
6038 void *osbuf = NULL;
6039
6040 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_CONN_INACT_CMD));
6041 if (osbuf == NULL) {
6042 return A_NO_MEMORY;
6043 }
6044
6045 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_CONN_INACT_CMD));
6046 cmd = (WMI_AP_CONN_INACT_CMD *)(A_NETBUF_DATA(osbuf));
6047 A_MEMZERO(cmd, sizeof(*cmd));
6048
6049 cmd->period = period;
6050
6051 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONN_INACT_CMDID, NO_SYNC_WMIFLAG));
6052}
6053
6054int
6055wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell)
6056{
6057 WMI_AP_PROT_SCAN_TIME_CMD *cmd;
6058 void *osbuf = NULL;
6059
6060 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6061 if (osbuf == NULL) {
6062 return A_NO_MEMORY;
6063 }
6064
6065 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6066 cmd = (WMI_AP_PROT_SCAN_TIME_CMD *)(A_NETBUF_DATA(osbuf));
6067 A_MEMZERO(cmd, sizeof(*cmd));
6068
6069 cmd->period_min = period;
6070 cmd->dwell_ms = dwell;
6071
6072 return (wmi_cmd_send(wmip, osbuf, WMI_AP_PROT_SCAN_TIME_CMDID, NO_SYNC_WMIFLAG));
6073}
6074
6075int
6076wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim)
6077{
6078 WMI_AP_SET_DTIM_CMD *cmd;
6079 void *osbuf = NULL;
6080
6081 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_DTIM_CMD));
6082 if (osbuf == NULL) {
6083 return A_NO_MEMORY;
6084 }
6085
6086 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_DTIM_CMD));
6087 cmd = (WMI_AP_SET_DTIM_CMD *)(A_NETBUF_DATA(osbuf));
6088 A_MEMZERO(cmd, sizeof(*cmd));
6089
6090 cmd->dtim = dtim;
6091
6092 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG));
6093}
6094
6095/*
6096 * IOCTL: AR6000_XIOCTL_AP_SET_ACL_POLICY
6097 *
6098 * This command is used to set ACL policay. While changing policy, if you
6099 * want to retain the existing MAC addresses in the ACL list, policy should be
6100 * OR with AP_ACL_RETAIN_LIST_MASK, else the existing list will be cleared.
6101 * If there is no chage in policy, the list will be intact.
6102 */
6103int
6104wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy)
6105{
6106 void *osbuf;
6107 WMI_AP_ACL_POLICY_CMD *po;
6108
6109 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_POLICY_CMD));
6110 if (osbuf == NULL) {
6111 return A_NO_MEMORY;
6112}
6113
6114 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_POLICY_CMD));
6115 po = (WMI_AP_ACL_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
6116 A_MEMZERO(po, sizeof(*po));
6117
6118 po->policy = policy;
6119
6120 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_POLICY_CMDID, NO_SYNC_WMIFLAG));
6121}
6122
6123int
6124wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset)
6125{
6126 void *osbuf;
6127 WMI_AP_SET_11BG_RATESET_CMD *rs;
6128
6129 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6130 if (osbuf == NULL) {
6131 return A_NO_MEMORY;
6132 }
6133
6134 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6135 rs = (WMI_AP_SET_11BG_RATESET_CMD *)(A_NETBUF_DATA(osbuf));
6136 A_MEMZERO(rs, sizeof(*rs));
6137
6138 rs->rateset = rateset;
6139
6140 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMIFLAG));
6141}
6142
6143int
6144wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd)
6145{
6146 void *osbuf;
6147 WMI_SET_HT_CAP_CMD *htCap;
6148 u8 band;
6149
6150 osbuf = A_NETBUF_ALLOC(sizeof(*htCap));
6151 if (osbuf == NULL) {
6152 return A_NO_MEMORY;
6153 }
6154
6155 A_NETBUF_PUT(osbuf, sizeof(*htCap));
6156
6157 band = (cmd->band)? A_BAND_5GHZ : A_BAND_24GHZ;
6158 wmip->wmi_ht_allowed[band] = (cmd->enable)? 1:0;
6159
6160 htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf));
6161 A_MEMZERO(htCap, sizeof(*htCap));
6162 memcpy(htCap, cmd, sizeof(*htCap));
6163
6164 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID,
6165 NO_SYNC_WMIFLAG));
6166}
6167
6168int
6169wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width)
6170{
6171 void *osbuf;
6172 WMI_SET_HT_OP_CMD *htInfo;
6173
6174 osbuf = A_NETBUF_ALLOC(sizeof(*htInfo));
6175 if (osbuf == NULL) {
6176 return A_NO_MEMORY;
6177 }
6178
6179 A_NETBUF_PUT(osbuf, sizeof(*htInfo));
6180
6181 htInfo = (WMI_SET_HT_OP_CMD *)(A_NETBUF_DATA(osbuf));
6182 A_MEMZERO(htInfo, sizeof(*htInfo));
6183 htInfo->sta_chan_width = sta_chan_width;
6184
6185 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID,
6186 NO_SYNC_WMIFLAG));
6187}
6188
6189int
6190wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray)
6191{
6192 void *osbuf;
6193 WMI_SET_TX_SELECT_RATES_CMD *pData;
6194
6195 osbuf = A_NETBUF_ALLOC(sizeof(*pData));
6196 if (osbuf == NULL) {
6197 return A_NO_MEMORY;
6198 }
6199
6200 A_NETBUF_PUT(osbuf, sizeof(*pData));
6201
6202 pData = (WMI_SET_TX_SELECT_RATES_CMD *)(A_NETBUF_DATA(osbuf));
6203 memcpy(pData, pMaskArray, sizeof(*pData));
6204
6205 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SELECT_RATES_CMDID,
6206 NO_SYNC_WMIFLAG));
6207}
6208
6209
6210int
6211wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz)
6212{
6213 void *osbuf;
6214 WMI_HCI_CMD *cmd;
6215
6216 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + sz);
6217 if (osbuf == NULL) {
6218 return A_NO_MEMORY;
6219 }
6220
6221 A_NETBUF_PUT(osbuf, sizeof(*cmd) + sz);
6222 cmd = (WMI_HCI_CMD *)(A_NETBUF_DATA(osbuf));
6223
6224 cmd->cmd_buf_sz = sz;
6225 memcpy(cmd->buf, buf, sz);
6226 return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG));
6227}
6228
6229int
6230wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask)
6231{
6232 void *osbuf;
6233 WMI_ALLOW_AGGR_CMD *cmd;
6234
6235 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6236 if (osbuf == NULL) {
6237 return A_NO_MEMORY;
6238 }
6239
6240 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6241
6242 cmd = (WMI_ALLOW_AGGR_CMD *)(A_NETBUF_DATA(osbuf));
6243 cmd->tx_allow_aggr = tx_tidmask;
6244 cmd->rx_allow_aggr = rx_tidmask;
6245
6246 return (wmi_cmd_send(wmip, osbuf, WMI_ALLOW_AGGR_CMDID, NO_SYNC_WMIFLAG));
6247}
6248
6249int
6250wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid)
6251{
6252 void *osbuf;
6253 WMI_ADDBA_REQ_CMD *cmd;
6254
6255 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6256 if (osbuf == NULL) {
6257 return A_NO_MEMORY;
6258 }
6259
6260 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6261
6262 cmd = (WMI_ADDBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6263 cmd->tid = tid;
6264
6265 return (wmi_cmd_send(wmip, osbuf, WMI_ADDBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6266}
6267
6268int
6269wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink)
6270{
6271 void *osbuf;
6272 WMI_DELBA_REQ_CMD *cmd;
6273
6274 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6275 if (osbuf == NULL) {
6276 return A_NO_MEMORY;
6277 }
6278
6279 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6280
6281 cmd = (WMI_DELBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6282 cmd->tid = tid;
6283 cmd->is_sender_initiator = uplink; /* uplink =1 - uplink direction, 0=downlink direction */
6284
6285 /* Delete the local aggr state, on host */
6286 return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6287}
6288
6289int
6290wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion,
6291 bool rxDot11Hdr, bool defragOnHost)
6292{
6293 void *osbuf;
6294 WMI_RX_FRAME_FORMAT_CMD *cmd;
6295
6296 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6297 if (osbuf == NULL) {
6298 return A_NO_MEMORY;
6299 }
6300
6301 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6302
6303 cmd = (WMI_RX_FRAME_FORMAT_CMD *)(A_NETBUF_DATA(osbuf));
6304 cmd->dot11Hdr = (rxDot11Hdr==true)? 1:0;
6305 cmd->defragOnHost = (defragOnHost==true)? 1:0;
6306 cmd->metaVersion = rxMetaVersion; /* */
6307
6308 /* Delete the local aggr state, on host */
6309 return (wmi_cmd_send(wmip, osbuf, WMI_RX_FRAME_FORMAT_CMDID, NO_SYNC_WMIFLAG));
6310}
6311
6312
6313int
6314wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode)
6315{
6316 void *osbuf;
6317 WMI_SET_THIN_MODE_CMD *cmd;
6318
6319 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6320 if (osbuf == NULL) {
6321 return A_NO_MEMORY;
6322 }
6323
6324 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6325
6326 cmd = (WMI_SET_THIN_MODE_CMD *)(A_NETBUF_DATA(osbuf));
6327 cmd->enable = (bThinMode==true)? 1:0;
6328
6329 /* Delete the local aggr state, on host */
6330 return (wmi_cmd_send(wmip, osbuf, WMI_SET_THIN_MODE_CMDID, NO_SYNC_WMIFLAG));
6331}
6332
6333
6334int
6335wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence)
6336{
6337 void *osbuf;
6338 WMI_SET_BT_WLAN_CONN_PRECEDENCE *cmd;
6339
6340 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6341 if (osbuf == NULL) {
6342 return A_NO_MEMORY;
6343 }
6344
6345 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6346
6347 cmd = (WMI_SET_BT_WLAN_CONN_PRECEDENCE *)(A_NETBUF_DATA(osbuf));
6348 A_MEMZERO(cmd, sizeof(*cmd));
6349 cmd->precedence = precedence;
6350
6351 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
6352 NO_SYNC_WMIFLAG));
6353}
6354
6355int
6356wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk)
6357{
6358 void *osbuf;
6359 WMI_SET_PMK_CMD *p;
6360
6361 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_PMK_CMD));
6362 if (osbuf == NULL) {
6363 return A_NO_MEMORY;
6364 }
6365
6366 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_PMK_CMD));
6367
6368 p = (WMI_SET_PMK_CMD *)(A_NETBUF_DATA(osbuf));
6369 A_MEMZERO(p, sizeof(*p));
6370
6371 memcpy(p->pmk, pmk, WMI_PMK_LEN);
6372
6373 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG));
6374}
6375
6376int
6377wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd)
6378{
6379 void *osbuf;
6380 WMI_SET_EXCESS_TX_RETRY_THRES_CMD *p;
6381
6382 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD));
6383 if (osbuf == NULL) {
6384 return A_NO_MEMORY;
6385 }
6386
6387 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD));
6388
6389 p = (WMI_SET_EXCESS_TX_RETRY_THRES_CMD *)(A_NETBUF_DATA(osbuf));
6390 memset(p, 0, sizeof(*p));
6391
6392 p->threshold = cmd->threshold;
6393
6394 return (wmi_cmd_send(wmip, osbuf, WMI_SET_EXCESS_TX_RETRY_THRES_CMDID, NO_SYNC_WMIFLAG));
6395}
6396
6397int
6398wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold)
6399{
6400 void *osbuf;
6401 WMI_SET_TX_SGI_PARAM_CMD *cmd;
6402
6403 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6404 if (osbuf == NULL) {
6405 return A_NO_MEMORY ;
6406 }
6407
6408 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6409
6410 cmd = (WMI_SET_TX_SGI_PARAM_CMD *)(A_NETBUF_DATA(osbuf));
6411 A_MEMZERO(cmd, sizeof(*cmd));
6412 cmd->sgiMask = sgiMask;
6413 cmd->sgiPERThreshold = sgiPERThreshold;
6414 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SGI_PARAM_CMDID,
6415 NO_SYNC_WMIFLAG));
6416}
6417
6418bss_t *
6419wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
6420 u32 ssidLength,
6421 u32 dot11AuthMode, u32 authMode,
6422 u32 pairwiseCryptoType, u32 grpwiseCryptoTyp)
6423{
6424 bss_t *node = NULL;
6425 node = wlan_find_matching_Ssidnode (&wmip->wmi_scan_table, pSsid,
6426 ssidLength, dot11AuthMode, authMode, pairwiseCryptoType, grpwiseCryptoTyp);
6427
6428 return node;
6429}
6430
6431u16 wmi_ieee2freq (int chan)
6432{
6433 u16 freq = 0;
6434 freq = wlan_ieee2freq (chan);
6435 return freq;
6436
6437}
6438
6439u32 wmi_freq2ieee (u16 freq)
6440{
6441 u16 chan = 0;
6442 chan = wlan_freq2ieee (freq);
6443 return chan;
6444}
diff --git a/drivers/staging/ath6kl/wmi/wmi_host.h b/drivers/staging/ath6kl/wmi/wmi_host.h
deleted file mode 100644
index 53e4f085dfe..00000000000
--- a/drivers/staging/ath6kl/wmi/wmi_host.h
+++ /dev/null
@@ -1,102 +0,0 @@
1//------------------------------------------------------------------------------
2// <copyright file="wmi_host.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains local definitios for the wmi host module.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _WMI_HOST_H_
26#define _WMI_HOST_H_
27
28#include "roaming.h"
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33struct wmi_stats {
34 u32 cmd_len_err;
35 u32 cmd_id_err;
36};
37
38#define SSID_IE_LEN_INDEX 13
39
40/* Host side link management data structures */
41#define SIGNAL_QUALITY_THRESHOLD_LEVELS 6
42#define SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS SIGNAL_QUALITY_THRESHOLD_LEVELS
43#define SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS SIGNAL_QUALITY_THRESHOLD_LEVELS
44typedef struct sq_threshold_params_s {
45 s16 upper_threshold[SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS];
46 s16 lower_threshold[SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS];
47 u32 upper_threshold_valid_count;
48 u32 lower_threshold_valid_count;
49 u32 polling_interval;
50 u8 weight;
51 u8 last_rssi; //normally you would expect this to be bss specific but we keep only one instance because its only valid when the device is in a connected state. Not sure if it belongs to host or target.
52 u8 last_rssi_poll_event; //Not sure if it belongs to host or target
53} SQ_THRESHOLD_PARAMS;
54
55/*
56 * These constants are used with A_WLAN_BAND_SET.
57 */
58#define A_BAND_24GHZ 0
59#define A_BAND_5GHZ 1
60#define A_NUM_BANDS 2
61
62struct wmi_t {
63 bool wmi_ready;
64 bool wmi_numQoSStream;
65 u16 wmi_streamExistsForAC[WMM_NUM_AC];
66 u8 wmi_fatPipeExists;
67 void *wmi_devt;
68 struct wmi_stats wmi_stats;
69 struct ieee80211_node_table wmi_scan_table;
70 u8 wmi_bssid[ATH_MAC_LEN];
71 u8 wmi_powerMode;
72 u8 wmi_phyMode;
73 u8 wmi_keepaliveInterval;
74#ifdef THREAD_X
75 A_CSECT_T wmi_lock;
76#else
77 A_MUTEX_T wmi_lock;
78#endif
79 HTC_ENDPOINT_ID wmi_endpoint_id;
80 SQ_THRESHOLD_PARAMS wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_NUM_MAX];
81 CRYPTO_TYPE wmi_pair_crypto_type;
82 CRYPTO_TYPE wmi_grp_crypto_type;
83 bool wmi_is_wmm_enabled;
84 u8 wmi_ht_allowed[A_NUM_BANDS];
85 u8 wmi_traffic_class;
86};
87
88#ifdef THREAD_X
89#define INIT_WMI_LOCK(w) A_CSECT_INIT(&(w)->wmi_lock)
90#define LOCK_WMI(w) A_CSECT_ENTER(&(w)->wmi_lock);
91#define UNLOCK_WMI(w) A_CSECT_LEAVE(&(w)->wmi_lock);
92#define DELETE_WMI_LOCK(w) A_CSECT_DELETE(&(w)->wmi_lock);
93#else
94#define LOCK_WMI(w) A_MUTEX_LOCK(&(w)->wmi_lock);
95#define UNLOCK_WMI(w) A_MUTEX_UNLOCK(&(w)->wmi_lock);
96#endif
97
98#ifdef __cplusplus
99}
100#endif
101
102#endif /* _WMI_HOST_H_ */
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index bd44417c84d..5c5f4b14fd0 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -54,12 +54,35 @@ static atomic_t ticks;
54static inline void bcm47xx_wdt_hw_start(void) 54static inline void bcm47xx_wdt_hw_start(void)
55{ 55{
56 /* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */ 56 /* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */
57 ssb_watchdog_timer_set(&ssb_bcm47xx, 0xfffffff); 57 switch (bcm47xx_bus_type) {
58#ifdef CONFIG_BCM47XX_SSB
59 case BCM47XX_BUS_TYPE_SSB:
60 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
61 break;
62#endif
63#ifdef CONFIG_BCM47XX_BCMA
64 case BCM47XX_BUS_TYPE_BCMA:
65 bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc,
66 0xfffffff);
67 break;
68#endif
69 }
58} 70}
59 71
60static inline int bcm47xx_wdt_hw_stop(void) 72static inline int bcm47xx_wdt_hw_stop(void)
61{ 73{
62 return ssb_watchdog_timer_set(&ssb_bcm47xx, 0); 74 switch (bcm47xx_bus_type) {
75#ifdef CONFIG_BCM47XX_SSB
76 case BCM47XX_BUS_TYPE_SSB:
77 return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
78#endif
79#ifdef CONFIG_BCM47XX_BCMA
80 case BCM47XX_BUS_TYPE_BCMA:
81 bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
82 return 0;
83#endif
84 }
85 return -EINVAL;
63} 86}
64 87
65static void bcm47xx_timer_tick(unsigned long unused) 88static void bcm47xx_timer_tick(unsigned long unused)